diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 95d673cd30..0b20da7c16 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,15 +1,19 @@ { "name": "Gitea DevContainer", - "image": "mcr.microsoft.com/devcontainers/go:1.24-bookworm", + "image": "mcr.microsoft.com/devcontainers/go:1.25-trixie", + "containerEnv": { + // override "local" from packaged version + "GOTOOLCHAIN": "auto" + }, "features": { // installs nodejs into container "ghcr.io/devcontainers/features/node:1": { - "version": "lts" + "version": "latest" }, - "ghcr.io/devcontainers/features/git-lfs:1.2.2": {}, + "ghcr.io/devcontainers/features/git-lfs:1.2.5": {}, "ghcr.io/jsburckhardt/devcontainer-features/uv:1": {}, "ghcr.io/devcontainers/features/python:1": { - "version": "3.12" + "version": "3.13" }, "ghcr.io/warrenbuckley/codespace-features/sqlite:1": {} }, diff --git a/.dockerignore b/.dockerignore index 843f12a7be..8e0d6b3666 100644 --- a/.dockerignore +++ b/.dockerignore @@ -65,6 +65,7 @@ cpu.out /yarn.lock /yarn-error.log /npm-debug.log* +/pnpm-debug.log* /public/assets/js /public/assets/css /public/assets/fonts diff --git a/.eslintrc.cjs b/.eslintrc.cjs index e2609922da..0af524b143 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -831,7 +831,6 @@ module.exports = { 'sonarjs/no-inverted-boolean-check': [2], 'sonarjs/no-nested-switch': [0], 'sonarjs/no-nested-template-literals': [0], - 'sonarjs/no-one-iteration-loop': [2], 'sonarjs/no-redundant-boolean': [2], 'sonarjs/no-redundant-jump': [2], 'sonarjs/no-same-line-conditional': [2], diff --git a/.github/labeler.yml b/.github/labeler.yml index a82bf0c2b2..49679d28cf 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -59,7 +59,7 @@ modifies/dependencies: - changed-files: - any-glob-to-any-file: - "package.json" - - "package-lock.json" + - "pnpm-lock.yaml" - "pyproject.toml" - "uv.lock" - "go.mod" diff --git a/.github/workflows/files-changed.yml b/.github/workflows/files-changed.yml index 21d3ea7393..edceef0092 100644 --- a/.github/workflows/files-changed.yml +++ b/.github/workflows/files-changed.yml @@ -58,7 +58,7 @@ jobs: - "tools/*.ts" - "assets/emoji.json" - "package.json" - - "package-lock.json" + - "pnpm-lock.yaml" - "Makefile" - ".eslintrc.cjs" - ".npmrc" @@ -67,7 +67,7 @@ jobs: - "**/*.md" - ".markdownlint.yaml" - "package.json" - - "package-lock.json" + - "pnpm-lock.yaml" actions: - ".github/workflows/*" @@ -90,7 +90,7 @@ jobs: - "templates/swagger/v1_input.json" - "Makefile" - "package.json" - - "package-lock.json" + - "pnpm-lock.yaml" - ".spectral.yaml" yaml: diff --git a/.github/workflows/pull-compliance.yml b/.github/workflows/pull-compliance.yml index 56685ffb46..6f8991ed4e 100644 --- a/.github/workflows/pull-compliance.yml +++ b/.github/workflows/pull-compliance.yml @@ -34,11 +34,10 @@ jobs: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v6 - run: uv python install 3.12 - - uses: actions/setup-node@v4 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v5 with: node-version: 24 - cache: npm - cache-dependency-path: package-lock.json - run: make deps-py - run: make deps-frontend - run: make lint-templates @@ -60,11 +59,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v5 with: node-version: 24 - cache: npm - cache-dependency-path: package-lock.json - run: make deps-frontend - run: make lint-swagger @@ -131,11 +129,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v5 with: node-version: 24 - cache: npm - cache-dependency-path: package-lock.json - run: make deps-frontend - run: make lint-frontend - run: make checks-frontend @@ -180,11 +177,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v5 with: node-version: 24 - cache: npm - cache-dependency-path: package-lock.json - run: make deps-frontend - run: make lint-md diff --git a/.github/workflows/pull-db-tests.yml b/.github/workflows/pull-db-tests.yml index 55c2d2bf5e..faf6a90e1b 100644 --- a/.github/workflows/pull-db-tests.yml +++ b/.github/workflows/pull-db-tests.yml @@ -31,7 +31,7 @@ jobs: minio: # as github actions doesn't support "entrypoint", we need to use a non-official image # that has a custom entrypoint set to "minio server /data" - image: bitnami/minio:2023.8.31 + image: bitnamilegacy/minio:2023.8.31 env: MINIO_ROOT_USER: 123456 MINIO_ROOT_PASSWORD: 12345678 @@ -113,7 +113,7 @@ jobs: ports: - 6379:6379 minio: - image: bitnami/minio:2021.3.17 + image: bitnamilegacy/minio:2021.3.17 env: MINIO_ACCESS_KEY: 123456 MINIO_SECRET_KEY: 12345678 @@ -155,7 +155,7 @@ jobs: services: mysql: # the bitnami mysql image has more options than the official one, it's easier to customize - image: bitnami/mysql:8.0 + image: bitnamilegacy/mysql:8.0 env: ALLOW_EMPTY_PASSWORD: true MYSQL_DATABASE: testgitea diff --git a/.github/workflows/pull-e2e-tests.yml b/.github/workflows/pull-e2e-tests.yml index cc3fbd9c34..89b32260ca 100644 --- a/.github/workflows/pull-e2e-tests.yml +++ b/.github/workflows/pull-e2e-tests.yml @@ -23,13 +23,12 @@ jobs: with: go-version-file: go.mod check-latest: true - - uses: actions/setup-node@v4 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v5 with: node-version: 24 - cache: npm - cache-dependency-path: package-lock.json - run: make deps-frontend frontend deps-backend - - run: npx playwright install --with-deps + - run: pnpm exec playwright install --with-deps - run: make test-e2e-sqlite timeout-minutes: 40 env: diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml index c2cc14f771..3d652e4ad8 100644 --- a/.github/workflows/release-nightly.yml +++ b/.github/workflows/release-nightly.yml @@ -20,11 +20,10 @@ jobs: with: go-version-file: go.mod check-latest: true - - uses: actions/setup-node@v4 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v5 with: node-version: 24 - cache: npm - cache-dependency-path: package-lock.json - run: make deps-frontend deps-backend # xgo build - run: make release @@ -75,11 +74,6 @@ jobs: - name: Get cleaned branch name id: clean_name run: | - # if main then say nightly otherwise cleanup name - if [ "${{ github.ref }}" = "refs/heads/main" ]; then - echo "branch=nightly" >> "$GITHUB_OUTPUT" - exit 0 - fi REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//') echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT" - name: Login to Docker Hub @@ -122,11 +116,6 @@ jobs: - name: Get cleaned branch name id: clean_name run: | - # if main then say nightly otherwise cleanup name - if [ "${{ github.ref }}" = "refs/heads/main" ]; then - echo "branch=nightly" >> "$GITHUB_OUTPUT" - exit 0 - fi REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//') echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT" - name: Login to Docker Hub diff --git a/.github/workflows/release-tag-rc.yml b/.github/workflows/release-tag-rc.yml index c9c15c31a0..f4776a9ed8 100644 --- a/.github/workflows/release-tag-rc.yml +++ b/.github/workflows/release-tag-rc.yml @@ -21,11 +21,10 @@ jobs: with: go-version-file: go.mod check-latest: true - - uses: actions/setup-node@v4 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v5 with: node-version: 24 - cache: npm - cache-dependency-path: package-lock.json - run: make deps-frontend deps-backend # xgo build - run: make release diff --git a/.github/workflows/release-tag-version.yml b/.github/workflows/release-tag-version.yml index ae717c7cec..ad0820f31f 100644 --- a/.github/workflows/release-tag-version.yml +++ b/.github/workflows/release-tag-version.yml @@ -25,11 +25,10 @@ jobs: with: go-version-file: go.mod check-latest: true - - uses: actions/setup-node@v4 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v5 with: node-version: 24 - cache: npm - cache-dependency-path: package-lock.json - run: make deps-frontend deps-backend # xgo build - run: make release diff --git a/.gitignore b/.gitignore index fc2d74a33a..a580861a51 100644 --- a/.gitignore +++ b/.gitignore @@ -78,6 +78,7 @@ cpu.out /yarn.lock /yarn-error.log /npm-debug.log* +/.pnpm-store /public/assets/js /public/assets/css /public/assets/fonts diff --git a/.npmrc b/.npmrc index d9207e7f82..790a49a6eb 100644 --- a/.npmrc +++ b/.npmrc @@ -1,6 +1,7 @@ audit=false fund=false update-notifier=false -package-lock=true save-exact=true -lockfile-version=3 +auto-install-peers=true +dedupe-peer-dependents=false +enable-pre-post-scripts=true diff --git a/Dockerfile b/Dockerfile index f852cf4235..78a556497a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build stage -FROM docker.io/library/golang:1.24-alpine3.22 AS build-env +FROM docker.io/library/golang:1.25-alpine3.22 AS build-env ARG GOPROXY ENV GOPROXY=${GOPROXY:-direct} @@ -15,6 +15,7 @@ RUN apk --no-cache add \ git \ nodejs \ npm \ + && npm install -g pnpm@10 \ && rm -rf /var/cache/apk/* # Setup repo diff --git a/Dockerfile.rootless b/Dockerfile.rootless index f955edc667..e83c1af33b 100644 --- a/Dockerfile.rootless +++ b/Dockerfile.rootless @@ -1,5 +1,5 @@ # Build stage -FROM docker.io/library/golang:1.24-alpine3.22 AS build-env +FROM docker.io/library/golang:1.25-alpine3.22 AS build-env ARG GOPROXY ENV GOPROXY=${GOPROXY:-direct} @@ -15,6 +15,7 @@ RUN apk --no-cache add \ git \ nodejs \ npm \ + && npm install -g pnpm@10 \ && rm -rf /var/cache/apk/* # Setup repo diff --git a/MAINTAINERS b/MAINTAINERS index 63da471f9b..1c7afc6f6c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -63,3 +63,4 @@ hiifong (@hiifong) metiftikci (@metiftikci) Christopher Homberger (@ChristopherHX) Tobias Balle-Petersen (@tobiasbp) +TheFox (@TheFox0x7) diff --git a/Makefile b/Makefile index 53671e9927..1fb4a40d71 100644 --- a/Makefile +++ b/Makefile @@ -23,15 +23,15 @@ SHASUM ?= shasum -a 256 HAS_GO := $(shell hash $(GO) > /dev/null 2>&1 && echo yes) COMMA := , -XGO_VERSION := go-1.24.x +XGO_VERSION := go-1.25.x AIR_PACKAGE ?= github.com/air-verse/air@v1 EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3 -GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.8.0 -GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6 -GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.12 +GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.9.1 +GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.4.0 +GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.15 MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.7.0 -SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.32.3 +SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@717e3cb29becaaf00e56953556c6d80f8a01b286 XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1 GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 @@ -96,6 +96,15 @@ STORED_VERSION_FILE := VERSION GITHUB_REF_TYPE ?= branch GITHUB_REF_NAME ?= $(shell git rev-parse --abbrev-ref HEAD) +# Enable typescript support in Node.js before 22.18 +# TODO: Remove this once we can raise the minimum Node.js version to 22.18 (alpine >= 3.23) +NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell node -v 2>/dev/null | cut -c2- | tr '.' ' ')) +ifeq ($(shell test "$(NODE_VERSION)" -lt "022018000"; echo $$?),0) + NODE_VARS := NODE_OPTIONS="--experimental-strip-types" +else + NODE_VARS := +endif + ifneq ($(GITHUB_REF_TYPE),branch) VERSION ?= $(subst v,,$(GITHUB_REF_NAME)) GITEA_VERSION ?= $(VERSION) @@ -127,7 +136,7 @@ GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/m MIGRATE_TEST_PACKAGES ?= $(shell $(GO) list code.gitea.io/gitea/models/migrations/...) WEBPACK_SOURCES := $(shell find web_src/js web_src/css -type f) -WEBPACK_CONFIGS := webpack.config.js tailwind.config.js +WEBPACK_CONFIGS := webpack.config.ts tailwind.config.ts WEBPACK_DEST := public/assets/js/index.js public/assets/css/index.css WEBPACK_DEST_ENTRIES := public/assets/js public/assets/css public/assets/fonts @@ -153,9 +162,9 @@ TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(DIST) GO_DIRS := build cmd models modules routers services tests WEB_DIRS := web_src/js web_src/css -ESLINT_FILES := web_src/js tools *.js *.ts *.cjs tests/e2e +ESLINT_FILES := web_src/js tools *.ts *.cjs tests/e2e STYLELINT_FILES := web_src/css web_src/js/components/*.vue -SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) templates options/locale/locale_en-US.ini .github $(filter-out CHANGELOG.md, $(wildcard *.go *.js *.md *.yml *.yaml *.toml)) $(filter-out tools/misspellings.csv, $(wildcard tools/*)) +SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) templates options/locale/locale_en-US.ini .github $(filter-out CHANGELOG.md, $(wildcard *.go *.md *.yml *.yaml *.toml)) $(filter-out tools/misspellings.csv, $(wildcard tools/*)) EDITORCONFIG_FILES := templates .github/workflows options/locale/locale_en-US.ini GO_SOURCES := $(wildcard *.go) @@ -217,10 +226,13 @@ git-check: node-check: $(eval MIN_NODE_VERSION_STR := $(shell grep -Eo '"node":.*[0-9.]+"' package.json | sed -n 's/.*[^0-9.]\([0-9.]*\)"/\1/p')) $(eval MIN_NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell echo '$(MIN_NODE_VERSION_STR)' | tr '.' ' '))) - $(eval NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell node -v | cut -c2- | tr '.' ' ');)) - $(eval NPM_MISSING := $(shell hash npm > /dev/null 2>&1 || echo 1)) - @if [ "$(NODE_VERSION)" -lt "$(MIN_NODE_VERSION)" -o "$(NPM_MISSING)" = "1" ]; then \ - echo "Gitea requires Node.js $(MIN_NODE_VERSION_STR) or greater and npm to build. You can get it at https://nodejs.org/en/download/"; \ + $(eval PNPM_MISSING := $(shell hash pnpm > /dev/null 2>&1 || echo 1)) + @if [ "$(NODE_VERSION)" -lt "$(MIN_NODE_VERSION)" ]; then \ + echo "Gitea requires Node.js $(MIN_NODE_VERSION_STR) or greater to build. You can get it at https://nodejs.org/en/download/"; \ + exit 1; \ + fi + @if [ "$(PNPM_MISSING)" = "1" ]; then \ + echo "Gitea requires pnpm to build. You can install it at https://pnpm.io/installation"; \ exit 1; \ fi @@ -334,29 +346,29 @@ lint-backend-fix: lint-go-fix lint-go-gitea-vet lint-editorconfig ## lint backen .PHONY: lint-js lint-js: node_modules ## lint js files - npx eslint --color --max-warnings=0 --ext js,ts,vue $(ESLINT_FILES) - npx vue-tsc + $(NODE_VARS) pnpm exec eslint --color --max-warnings=0 --ext js,ts,vue $(ESLINT_FILES) + $(NODE_VARS) pnpm exec vue-tsc .PHONY: lint-js-fix lint-js-fix: node_modules ## lint js files and fix issues - npx eslint --color --max-warnings=0 --ext js,ts,vue $(ESLINT_FILES) --fix - npx vue-tsc + $(NODE_VARS) pnpm exec eslint --color --max-warnings=0 --ext js,ts,vue $(ESLINT_FILES) --fix + $(NODE_VARS) pnpm exec vue-tsc .PHONY: lint-css lint-css: node_modules ## lint css files - npx stylelint --color --max-warnings=0 $(STYLELINT_FILES) + $(NODE_VARS) pnpm exec stylelint --color --max-warnings=0 $(STYLELINT_FILES) .PHONY: lint-css-fix lint-css-fix: node_modules ## lint css files and fix issues - npx stylelint --color --max-warnings=0 $(STYLELINT_FILES) --fix + $(NODE_VARS) pnpm exec stylelint --color --max-warnings=0 $(STYLELINT_FILES) --fix .PHONY: lint-swagger lint-swagger: node_modules ## lint swagger files - npx spectral lint -q -F hint $(SWAGGER_SPEC) + $(NODE_VARS) pnpm exec spectral lint -q -F hint $(SWAGGER_SPEC) .PHONY: lint-md lint-md: node_modules ## lint markdown files - npx markdownlint *.md + $(NODE_VARS) pnpm exec markdownlint *.md .PHONY: lint-spell lint-spell: ## lint spelling @@ -403,7 +415,7 @@ lint-actions: ## lint action workflow files .PHONY: lint-templates lint-templates: .venv node_modules ## lint template files - @node tools/lint-templates-svg.js + @node tools/lint-templates-svg.ts @uv run --frozen djlint $(shell find templates -type f -iname '*.tmpl') .PHONY: lint-yaml @@ -417,7 +429,7 @@ watch: ## watch everything and continuously rebuild .PHONY: watch-frontend watch-frontend: node-check node_modules ## watch frontend files and continuously rebuild @rm -rf $(WEBPACK_DEST_ENTRIES) - NODE_ENV=development npx webpack --watch --progress + NODE_ENV=development $(NODE_VARS) pnpm exec webpack --watch --progress --disable-interpret .PHONY: watch-backend watch-backend: go-check ## watch backend files and continuously rebuild @@ -433,7 +445,7 @@ test-backend: ## test backend files .PHONY: test-frontend test-frontend: node_modules ## test frontend files - npx vitest + $(NODE_VARS) pnpm exec vitest .PHONY: test-check test-check: @@ -576,7 +588,7 @@ test-mssql-migration: migrations.mssql.test migrations.individual.mssql.test .PHONY: playwright playwright: deps-frontend - npx playwright install $(PLAYWRIGHT_FLAGS) + $(NODE_VARS) pnpm exec playwright install $(PLAYWRIGHT_FLAGS) .PHONY: test-e2e% test-e2e%: TEST_TYPE ?= e2e @@ -839,8 +851,8 @@ deps-tools: ## install tool dependencies $(GO) install $(GOPLS_MODERNIZE_PACKAGE) & \ wait -node_modules: package-lock.json - npm install --no-save +node_modules: pnpm-lock.yaml + $(NODE_VARS) pnpm install --frozen-lockfile @touch node_modules .venv: uv.lock @@ -852,16 +864,16 @@ update: update-js update-py ## update js and py dependencies .PHONY: update-js update-js: node-check | node_modules ## update js dependencies - npx updates -u -f package.json - rm -rf node_modules package-lock.json - npm install --package-lock - npx nolyfill install - npm install --package-lock + $(NODE_VARS) pnpm exec updates -u -f package.json + rm -rf node_modules pnpm-lock.yaml + $(NODE_VARS) pnpm install + $(NODE_VARS) pnpm exec nolyfill install + $(NODE_VARS) pnpm install @touch node_modules .PHONY: update-py update-py: node-check | node_modules ## update py dependencies - npx updates -u -f pyproject.toml + $(NODE_VARS) pnpm exec updates -u -f pyproject.toml rm -rf .venv uv.lock uv sync @touch .venv @@ -869,17 +881,17 @@ update-py: node-check | node_modules ## update py dependencies .PHONY: webpack webpack: $(WEBPACK_DEST) ## build webpack files -$(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json +$(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) pnpm-lock.yaml @$(MAKE) -s node-check node_modules @rm -rf $(WEBPACK_DEST_ENTRIES) @echo "Running webpack..." - @BROWSERSLIST_IGNORE_OLD_DATA=true npx webpack + @BROWSERSLIST_IGNORE_OLD_DATA=true $(NODE_VARS) pnpm exec webpack --disable-interpret @touch $(WEBPACK_DEST) .PHONY: svg svg: node-check | node_modules ## build svg files rm -rf $(SVG_DEST_DIR) - node tools/generate-svg.js + node tools/generate-svg.ts .PHONY: svg-check svg-check: svg @@ -893,11 +905,11 @@ svg-check: svg .PHONY: lockfile-check lockfile-check: - npm install --package-lock-only - @diff=$$(git diff --color=always package-lock.json); \ + $(NODE_VARS) pnpm install --frozen-lockfile + @diff=$$(git diff --color=always pnpm-lock.yaml); \ if [ -n "$$diff" ]; then \ - echo "package-lock.json is inconsistent with package.json"; \ - echo "Please run 'npm install --package-lock-only' and commit the result:"; \ + echo "pnpm-lock.yaml is inconsistent with package.json"; \ + echo "Please run 'pnpm install --frozen-lockfile' and commit the result:"; \ printf "%s" "$${diff}"; \ exit 1; \ fi @@ -917,9 +929,8 @@ generate-gitignore: ## update gitignore files $(GO) run build/generate-gitignores.go .PHONY: generate-images -generate-images: | node_modules - npm install --no-save fabric@6 imagemin-zopfli@7 - node tools/generate-images.js $(TAGS) +generate-images: | node_modules ## generate images + cd tools && node generate-images.ts $(TAGS) .PHONY: generate-manpage generate-manpage: ## generate manpage diff --git a/README.md b/README.md index aa2c6010fa..ed000971a7 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ or if SQLite support is required: The `build` target is split into two sub-targets: - `make backend` which requires [Go Stable](https://go.dev/dl/), the required version is defined in [go.mod](/go.mod). -- `make frontend` which requires [Node.js LTS](https://nodejs.org/en/download/) or greater. +- `make frontend` which requires [Node.js LTS](https://nodejs.org/en/download/) or greater and [pnpm](https://pnpm.io/installation). Internet connectivity is required to download the go and npm modules. When building from the official source tarballs which include pre-built frontend files, the `frontend` target will not be triggered, making it possible to build without Node.js. diff --git a/assets/go-licenses.json b/assets/go-licenses.json index d961444239..d645009d90 100644 --- a/assets/go-licenses.json +++ b/assets/go-licenses.json @@ -119,6 +119,11 @@ "path": "github.com/RoaringBitmap/roaring/v2/LICENSE", "licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright 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\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright 2016 by the authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations 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\n notice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\n copyright notice, this list of conditions and the following disclaimer\n in the documentation and/or other materials provided with the\n distribution.\n * Neither the name of Google Inc. nor the names of its\n contributors may be used to endorse or promote products derived from\n this 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/STARRY-S/zip", + "path": "github.com/STARRY-S/zip/LICENSE", + "licenseText": "BSD 3-Clause License\n\nCopyright (c) 2023, Starry\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its\n contributors may be used to endorse or promote products derived from\n 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/SaveTheRbtz/zstd-seekable-format-go/pkg", "path": "github.com/SaveTheRbtz/zstd-seekable-format-go/pkg/LICENSE", @@ -294,6 +299,21 @@ "path": "github.com/bmatcuk/doublestar/v4/LICENSE", "licenseText": "The MIT License (MIT)\n\nCopyright (c) 2014 Bob Matcuk\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/bodgit/plumbing", + "path": "github.com/bodgit/plumbing/LICENSE", + "licenseText": "BSD 3-Clause License\n\nCopyright (c) 2019, Matt Dainty\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\n list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n contributors may be used to endorse or promote products derived from\n 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\n" + }, + { + "name": "github.com/bodgit/sevenzip", + "path": "github.com/bodgit/sevenzip/LICENSE", + "licenseText": "BSD 3-Clause License\n\nCopyright (c) 2020, Matt Dainty\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\n list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n contributors may be used to endorse or promote products derived from\n 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/bodgit/windows", + "path": "github.com/bodgit/windows/LICENSE", + "licenseText": "BSD 3-Clause License\n\nCopyright (c) 2020, Matt Dainty\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\n list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n contributors may be used to endorse or promote products derived from\n 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\n" + }, { "name": "github.com/bohde/codel", "path": "github.com/bohde/codel/LICENSE", @@ -625,8 +645,8 @@ "licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright 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\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [yyyy] [name of copyright owner]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n" }, { - "name": "github.com/google/go-github/v71/github", - "path": "github.com/google/go-github/v71/github/LICENSE", + "name": "github.com/google/go-github/v74/github", + "path": "github.com/google/go-github/v74/github/LICENSE", "licenseText": "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" }, { @@ -845,8 +865,8 @@ "licenseText": " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright 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\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [yyyy] [name of copyright owner]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n" }, { - "name": "github.com/mholt/archiver/v3", - "path": "github.com/mholt/archiver/v3/LICENSE", + "name": "github.com/mholt/archives", + "path": "github.com/mholt/archives/LICENSE", "licenseText": "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." }, { @@ -869,6 +889,11 @@ "path": "github.com/miekg/dns/LICENSE", "licenseText": "BSD 3-Clause License\n\nCopyright (c) 2009, The Go Authors. Extensions copyright (c) 2011, Miek Gieben. \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\n1. Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its\n contributors may be used to endorse or promote products derived from\n 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/mikelolasagasti/xz", + "path": "github.com/mikelolasagasti/xz/LICENSE", + "licenseText": "Copyright (C) 2015-2017 Michael Cross \u003chttps://github.com/xi2\u003e\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n" + }, { "name": "github.com/minio/crc64nvme", "path": "github.com/minio/crc64nvme/LICENSE", @@ -884,6 +909,11 @@ "path": "github.com/minio/minio-go/v7/LICENSE", "licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright 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\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [yyyy] [name of copyright owner]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n" }, + { + "name": "github.com/minio/minlz", + "path": "github.com/minio/minlz/LICENSE", + "licenseText": "\r\n Apache License\r\n Version 2.0, January 2004\r\n http://www.apache.org/licenses/\r\n\r\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r\n\r\n 1. Definitions.\r\n\r\n \"License\" shall mean the terms and conditions for use, reproduction,\r\n and distribution as defined by Sections 1 through 9 of this document.\r\n\r\n \"Licensor\" shall mean the copyright owner or entity authorized by\r\n the copyright owner that is granting the License.\r\n\r\n \"Legal Entity\" shall mean the union of the acting entity and all\r\n other entities that control, are controlled by, or are under common\r\n control with that entity. For the purposes of this definition,\r\n \"control\" means (i) the power, direct or indirect, to cause the\r\n direction or management of such entity, whether by contract or\r\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\r\n outstanding shares, or (iii) beneficial ownership of such entity.\r\n\r\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\r\n exercising permissions granted by this License.\r\n\r\n \"Source\" form shall mean the preferred form for making modifications,\r\n including but not limited to software source code, documentation\r\n source, and configuration files.\r\n\r\n \"Object\" form shall mean any form resulting from mechanical\r\n transformation or translation of a Source form, including but\r\n not limited to compiled object code, generated documentation,\r\n and conversions to other media types.\r\n\r\n \"Work\" shall mean the work of authorship, whether in Source or\r\n Object form, made available under the License, as indicated by a\r\n copyright notice that is included in or attached to the work\r\n (an example is provided in the Appendix below).\r\n\r\n \"Derivative Works\" shall mean any work, whether in Source or Object\r\n form, that is based on (or derived from) the Work and for which the\r\n editorial revisions, annotations, elaborations, or other modifications\r\n represent, as a whole, an original work of authorship. For the purposes\r\n of this License, Derivative Works shall not include works that remain\r\n separable from, or merely link (or bind by name) to the interfaces of,\r\n the Work and Derivative Works thereof.\r\n\r\n \"Contribution\" shall mean any work of authorship, including\r\n the original version of the Work and any modifications or additions\r\n to that Work or Derivative Works thereof, that is intentionally\r\n submitted to Licensor for inclusion in the Work by the copyright owner\r\n or by an individual or Legal Entity authorized to submit on behalf of\r\n the copyright owner. For the purposes of this definition, \"submitted\"\r\n means any form of electronic, verbal, or written communication sent\r\n to the Licensor or its representatives, including but not limited to\r\n communication on electronic mailing lists, source code control systems,\r\n and issue tracking systems that are managed by, or on behalf of, the\r\n Licensor for the purpose of discussing and improving the Work, but\r\n excluding communication that is conspicuously marked or otherwise\r\n designated in writing by the copyright owner as \"Not a Contribution.\"\r\n\r\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\r\n on behalf of whom a Contribution has been received by Licensor and\r\n subsequently incorporated within the Work.\r\n\r\n 2. Grant of Copyright License. Subject to the terms and conditions of\r\n this License, each Contributor hereby grants to You a perpetual,\r\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n copyright license to reproduce, prepare Derivative Works of,\r\n publicly display, publicly perform, sublicense, and distribute the\r\n Work and such Derivative Works in Source or Object form.\r\n\r\n 3. Grant of Patent License. Subject to the terms and conditions of\r\n this License, each Contributor hereby grants to You a perpetual,\r\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n (except as stated in this section) patent license to make, have made,\r\n use, offer to sell, sell, import, and otherwise transfer the Work,\r\n where such license applies only to those patent claims licensable\r\n by such Contributor that are necessarily infringed by their\r\n Contribution(s) alone or by combination of their Contribution(s)\r\n with the Work to which such Contribution(s) was submitted. If You\r\n institute patent litigation against any entity (including a\r\n cross-claim or counterclaim in a lawsuit) alleging that the Work\r\n or a Contribution incorporated within the Work constitutes direct\r\n or contributory patent infringement, then any patent licenses\r\n granted to You under this License for that Work shall terminate\r\n as of the date such litigation is filed.\r\n\r\n 4. Redistribution. You may reproduce and distribute copies of the\r\n Work or Derivative Works thereof in any medium, with or without\r\n modifications, and in Source or Object form, provided that You\r\n meet the following conditions:\r\n\r\n (a) You must give any other recipients of the Work or\r\n Derivative Works a copy of this License; and\r\n\r\n (b) You must cause any modified files to carry prominent notices\r\n stating that You changed the files; and\r\n\r\n (c) You must retain, in the Source form of any Derivative Works\r\n that You distribute, all copyright, patent, trademark, and\r\n attribution notices from the Source form of the Work,\r\n excluding those notices that do not pertain to any part of\r\n the Derivative Works; and\r\n\r\n (d) If the Work includes a \"NOTICE\" text file as part of its\r\n distribution, then any Derivative Works that You distribute must\r\n include a readable copy of the attribution notices contained\r\n within such NOTICE file, excluding those notices that do not\r\n pertain to any part of the Derivative Works, in at least one\r\n of the following places: within a NOTICE text file distributed\r\n as part of the Derivative Works; within the Source form or\r\n documentation, if provided along with the Derivative Works; or,\r\n within a display generated by the Derivative Works, if and\r\n wherever such third-party notices normally appear. The contents\r\n of the NOTICE file are for informational purposes only and\r\n do not modify the License. You may add Your own attribution\r\n notices within Derivative Works that You distribute, alongside\r\n or as an addendum to the NOTICE text from the Work, provided\r\n that such additional attribution notices cannot be construed\r\n as modifying the License.\r\n\r\n You may add Your own copyright statement to Your modifications and\r\n may provide additional or different license terms and conditions\r\n for use, reproduction, or distribution of Your modifications, or\r\n for any such Derivative Works as a whole, provided Your use,\r\n reproduction, and distribution of the Work otherwise complies with\r\n the conditions stated in this License.\r\n\r\n 5. Submission of Contributions. Unless You explicitly state otherwise,\r\n any Contribution intentionally submitted for inclusion in the Work\r\n by You to the Licensor shall be under the terms and conditions of\r\n this License, without any additional terms or conditions.\r\n Notwithstanding the above, nothing herein shall supersede or modify\r\n the terms of any separate license agreement you may have executed\r\n with Licensor regarding such Contributions.\r\n\r\n 6. Trademarks. This License does not grant permission to use the trade\r\n names, trademarks, service marks, or product names of the Licensor,\r\n except as required for reasonable and customary use in describing the\r\n origin of the Work and reproducing the content of the NOTICE file.\r\n\r\n 7. Disclaimer of Warranty. Unless required by applicable law or\r\n agreed to in writing, Licensor provides the Work (and each\r\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\r\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r\n implied, including, without limitation, any warranties or conditions\r\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r\n PARTICULAR PURPOSE. You are solely responsible for determining the\r\n appropriateness of using or redistributing the Work and assume any\r\n risks associated with Your exercise of permissions under this License.\r\n\r\n 8. Limitation of Liability. In no event and under no legal theory,\r\n whether in tort (including negligence), contract, or otherwise,\r\n unless required by applicable law (such as deliberate and grossly\r\n negligent acts) or agreed to in writing, shall any Contributor be\r\n liable to You for damages, including any direct, indirect, special,\r\n incidental, or consequential damages of any character arising as a\r\n result of this License or out of the use or inability to use the\r\n Work (including but not limited to damages for loss of goodwill,\r\n work stoppage, computer failure or malfunction, or any and all\r\n other commercial damages or losses), even if such Contributor\r\n has been advised of the possibility of such damages.\r\n\r\n 9. Accepting Warranty or Additional Liability. While redistributing\r\n the Work or Derivative Works thereof, You may choose to offer,\r\n and charge a fee for, acceptance of support, warranty, indemnity,\r\n or other liability obligations and/or rights consistent with this\r\n License. However, in accepting such obligations, You may act only\r\n on Your own behalf and on Your sole responsibility, not on behalf\r\n of any other Contributor, and only if You agree to indemnify,\r\n defend, and hold each Contributor harmless for any liability\r\n incurred by, or claims asserted against, such Contributor by reason\r\n of your accepting any such warranty or additional liability.\r\n\r\nEND OF TERMS AND CONDITIONS" + }, { "name": "github.com/mitchellh/mapstructure", "path": "github.com/mitchellh/mapstructure/LICENSE", @@ -915,10 +945,25 @@ "licenseText": "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", - "path": "github.com/nwaples/rardecode/LICENSE", + "name": "github.com/nwaples/rardecode/v2", + "path": "github.com/nwaples/rardecode/v2/LICENSE", "licenseText": "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\n list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/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/cat", + "path": "github.com/olekukonko/cat/LICENSE", + "licenseText": "MIT License\n\nCopyright (c) 2025 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 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/olekukonko/errors", + "path": "github.com/olekukonko/errors/LICENSE", + "licenseText": "MIT License\n\nCopyright (c) 2025 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 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/olekukonko/ll", + "path": "github.com/olekukonko/ll/LICENSE", + "licenseText": "MIT License\n\nCopyright (c) 2025 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 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/olekukonko/tablewriter", "path": "github.com/olekukonko/tablewriter/LICENSE.md", @@ -944,6 +989,11 @@ "path": "github.com/opencontainers/image-spec/specs-go/LICENSE", "licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright 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\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n Copyright 2016 The Linux Foundation.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n" }, + { + "name": "github.com/philhofer/fwd", + "path": "github.com/philhofer/fwd/LICENSE.md", + "licenseText": "Copyright (c) 2014-2015, Philip Hofer\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + }, { "name": "github.com/pierrec/lz4/v4", "path": "github.com/pierrec/lz4/v4/LICENSE", @@ -1049,6 +1099,11 @@ "path": "github.com/skeema/knownhosts/LICENSE", "licenseText": " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright 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\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"{}\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright {yyyy} {name of copyright owner}\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n" }, + { + "name": "github.com/sorairolake/lzip-go", + "path": "github.com/sorairolake/lzip-go/LICENSE", + "licenseText": " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright 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\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [yyyy] [name of copyright owner]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n---\n\nMIT License\n\nCopyright (c) 2024 Shun Sakai\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/ssor/bom", "path": "github.com/ssor/bom/LICENSE", @@ -1064,6 +1119,11 @@ "path": "github.com/syndtr/goleveldb/leveldb/LICENSE", "licenseText": "Copyright 2012 Suryandaru Triandana \u003csyndtr@gmail.com\u003e\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/tinylib/msgp/msgp", + "path": "github.com/tinylib/msgp/msgp/LICENSE", + "licenseText": "Copyright (c) 2014 Philip Hofer\nPortions Copyright (c) 2009 The Go Authors (license at http://golang.org) where indicated\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + }, { "name": "github.com/tstranex/u2f", "path": "github.com/tstranex/u2f/LICENSE", @@ -1169,6 +1229,11 @@ "path": "go.uber.org/zap/exp/zapslog/LICENSE", "licenseText": "Copyright (c) 2016-2024 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": "go4.org", + "path": "go4.org/LICENSE", + "licenseText": " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright 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\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"{}\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright {yyyy} {name of copyright owner}\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n" + }, { "name": "golang.org/x/crypto", "path": "golang.org/x/crypto/LICENSE", diff --git a/build/code-batch-process.go b/build/code-batch-process.go index cc2ab68026..16d1273d96 100644 --- a/build/code-batch-process.go +++ b/build/code-batch-process.go @@ -181,7 +181,7 @@ func parseArgs() (mainOptions map[string]string, subCmd string, subArgs []string break } } - return + return mainOptions, subCmd, subArgs } func showUsage() { diff --git a/cmd/admin.go b/cmd/admin.go index 559544edd3..5c58a40ca2 100644 --- a/cmd/admin.go +++ b/cmd/admin.go @@ -100,7 +100,7 @@ func runRepoSyncReleases(ctx context.Context, _ *cli.Command) error { return err } - if err := git.InitSimple(ctx); err != nil { + if err := git.InitSimple(); err != nil { return err } diff --git a/cmd/admin_user_change_password_test.go b/cmd/admin_user_change_password_test.go index 17d0382af7..902632f3e4 100644 --- a/cmd/admin_user_change_password_test.go +++ b/cmd/admin_user_change_password_test.go @@ -18,12 +18,12 @@ func TestChangePasswordCommand(t *testing.T) { ctx := t.Context() defer func() { - require.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.User{})) + require.NoError(t, db.TruncateBeans(t.Context(), &user_model.User{})) }() t.Run("change password successfully", func(t *testing.T) { // defer func() { - // require.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.User{})) + // require.NoError(t, db.TruncateBeans(t.Context(), &user_model.User{})) // }() // Prepare test user unittest.AssertNotExistsBean(t, &user_model.User{LowerName: "testuser"}) diff --git a/cmd/admin_user_create_test.go b/cmd/admin_user_create_test.go index 437e07d9a2..dbe949ff8d 100644 --- a/cmd/admin_user_create_test.go +++ b/cmd/admin_user_create_test.go @@ -19,9 +19,9 @@ import ( func TestAdminUserCreate(t *testing.T) { reset := func() { - require.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.User{})) - require.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.EmailAddress{})) - require.NoError(t, db.TruncateBeans(db.DefaultContext, &auth_model.AccessToken{})) + require.NoError(t, db.TruncateBeans(t.Context(), &user_model.User{})) + require.NoError(t, db.TruncateBeans(t.Context(), &user_model.EmailAddress{})) + require.NoError(t, db.TruncateBeans(t.Context(), &auth_model.AccessToken{})) } t.Run("MustChangePassword", func(t *testing.T) { diff --git a/cmd/admin_user_delete_test.go b/cmd/admin_user_delete_test.go index d0330582d7..b68b358152 100644 --- a/cmd/admin_user_delete_test.go +++ b/cmd/admin_user_delete_test.go @@ -19,9 +19,9 @@ import ( func TestAdminUserDelete(t *testing.T) { ctx := t.Context() defer func() { - require.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.User{})) - require.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.EmailAddress{})) - require.NoError(t, db.TruncateBeans(db.DefaultContext, &auth_model.AccessToken{})) + require.NoError(t, db.TruncateBeans(t.Context(), &user_model.User{})) + require.NoError(t, db.TruncateBeans(t.Context(), &user_model.EmailAddress{})) + require.NoError(t, db.TruncateBeans(t.Context(), &auth_model.AccessToken{})) }() setupTestUser := func(t *testing.T) { @@ -104,8 +104,8 @@ func TestAdminUserDeleteFailure(t *testing.T) { require.Contains(t, err.Error(), tc.expectedErr) }) - require.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.User{})) - require.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.EmailAddress{})) - require.NoError(t, db.TruncateBeans(db.DefaultContext, &auth_model.AccessToken{})) + require.NoError(t, db.TruncateBeans(t.Context(), &user_model.User{})) + require.NoError(t, db.TruncateBeans(t.Context(), &user_model.EmailAddress{})) + require.NoError(t, db.TruncateBeans(t.Context(), &auth_model.AccessToken{})) } } diff --git a/cmd/admin_user_must_change_password_test.go b/cmd/admin_user_must_change_password_test.go index a6611fdc04..efdbe3a9ee 100644 --- a/cmd/admin_user_must_change_password_test.go +++ b/cmd/admin_user_must_change_password_test.go @@ -16,7 +16,7 @@ import ( func TestMustChangePassword(t *testing.T) { defer func() { - require.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.User{})) + require.NoError(t, db.TruncateBeans(t.Context(), &user_model.User{})) }() err := microcmdUserCreate().Run(t.Context(), []string{"create", "--username", "testuser", "--email", "testuser@gitea.local", "--random-password"}) require.NoError(t, err) diff --git a/cmd/doctor.go b/cmd/doctor.go index 9e0fcbf877..596dd61178 100644 --- a/cmd/doctor.go +++ b/cmd/doctor.go @@ -128,7 +128,7 @@ func runRecreateTable(ctx context.Context, cmd *cli.Command) error { } recreateTables := migrate_base.RecreateTables(beans...) - return db.InitEngineWithMigration(ctx, func(ctx context.Context, x *xorm.Engine) error { + return db.InitEngineWithMigration(context.Background(), func(ctx context.Context, x *xorm.Engine) error { if err := migrations.EnsureUpToDate(ctx, x); err != nil { return err } diff --git a/cmd/dump.go b/cmd/dump.go index ed19e3d4bf..fa135079c0 100644 --- a/cmd/dump.go +++ b/cmd/dump.go @@ -20,7 +20,6 @@ import ( "code.gitea.io/gitea/modules/util" "gitea.com/go-chi/session" - "github.com/mholt/archiver/v3" "github.com/urfave/cli/v3" ) @@ -146,22 +145,18 @@ func runDump(ctx context.Context, cmd *cli.Command) error { return err } - archiverGeneric, err := archiver.ByExtension("." + outType) + dumper, err := dump.NewDumper(ctx, outType, outFile) if err != nil { - fatal("Unable to get archiver for extension: %v", err) - } - - archiverWriter := archiverGeneric.(archiver.Writer) - if err := archiverWriter.Create(outFile); err != nil { - fatal("Creating archiver.Writer failed: %v", err) - } - defer archiverWriter.Close() - - dumper := &dump.Dumper{ - Writer: archiverWriter, - Verbose: verbose, + fatal("Failed to create archive %q: %v", outFile, err) + return err } + dumper.Verbose = verbose dumper.GlobalExcludeAbsPath(outFileName) + defer func() { + if err := dumper.Close(); err != nil { + fatal("Failed to save archive %q: %v", outFileName, err) + } + }() if cmd.IsSet("skip-repository") && cmd.Bool("skip-repository") { log.Info("Skip dumping local repositories") @@ -180,7 +175,7 @@ func runDump(ctx context.Context, cmd *cli.Command) error { if err != nil { return err } - return dumper.AddReader(object, info, path.Join("data", "lfs", objPath)) + return dumper.AddFileByReader(object, info, path.Join("data", "lfs", objPath)) }); err != nil { fatal("Failed to dump LFS objects: %v", err) } @@ -218,13 +213,13 @@ func runDump(ctx context.Context, cmd *cli.Command) error { fatal("Failed to dump database: %v", err) } - if err = dumper.AddFile("gitea-db.sql", dbDump.Name()); err != nil { + if err = dumper.AddFileByPath("gitea-db.sql", dbDump.Name()); err != nil { fatal("Failed to include gitea-db.sql: %v", err) } } log.Info("Adding custom configuration file from %s", setting.CustomConf) - if err = dumper.AddFile("app.ini", setting.CustomConf); err != nil { + if err = dumper.AddFileByPath("app.ini", setting.CustomConf); err != nil { fatal("Failed to include specified app.ini: %v", err) } @@ -283,7 +278,7 @@ func runDump(ctx context.Context, cmd *cli.Command) error { if err != nil { return err } - return dumper.AddReader(object, info, path.Join("data", "attachments", objPath)) + return dumper.AddFileByReader(object, info, path.Join("data", "attachments", objPath)) }); err != nil { fatal("Failed to dump attachments: %v", err) } @@ -297,7 +292,7 @@ func runDump(ctx context.Context, cmd *cli.Command) error { if err != nil { return err } - return dumper.AddReader(object, info, path.Join("data", "packages", objPath)) + return dumper.AddFileByReader(object, info, path.Join("data", "packages", objPath)) }); err != nil { fatal("Failed to dump packages: %v", err) } @@ -322,10 +317,6 @@ func runDump(ctx context.Context, cmd *cli.Command) error { if outFileName == "-" { log.Info("Finish dumping to stdout") } else { - if err = archiverWriter.Close(); err != nil { - _ = os.Remove(outFileName) - fatal("Failed to save %q: %v", outFileName, err) - } if err = os.Chmod(outFileName, 0o600); err != nil { log.Info("Can't change file access permissions mask to 0600: %v", err) } diff --git a/cmd/dump_repo.go b/cmd/dump_repo.go index a75b2d1b94..beda305c85 100644 --- a/cmd/dump_repo.go +++ b/cmd/dump_repo.go @@ -90,7 +90,7 @@ func runDumpRepository(ctx context.Context, cmd *cli.Command) error { } // migrations.GiteaLocalUploader depends on git module - if err := git.InitSimple(context.Background()); err != nil { + if err := git.InitSimple(); err != nil { return err } @@ -179,7 +179,7 @@ func runDumpRepository(ctx context.Context, cmd *cli.Command) error { } if err := migrations.DumpRepository( - context.Background(), + ctx, repoDir, cmd.String("owner_name"), opts, diff --git a/cmd/migrate_storage_test.go b/cmd/migrate_storage_test.go index 6817867e28..3ea193eb1e 100644 --- a/cmd/migrate_storage_test.go +++ b/cmd/migrate_storage_test.go @@ -8,7 +8,6 @@ import ( "strings" "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -30,7 +29,7 @@ func TestMigratePackages(t *testing.T) { assert.NoError(t, err) defer buf.Close() - v, f, err := packages_service.CreatePackageAndAddFile(db.DefaultContext, &packages_service.PackageCreationInfo{ + v, f, err := packages_service.CreatePackageAndAddFile(t.Context(), &packages_service.PackageCreationInfo{ PackageInfo: packages_service.PackageInfo{ Owner: creator, PackageType: packages.TypeGeneric, diff --git a/cmd/serv.go b/cmd/serv.go index 38c79f68cd..60f7fb92ff 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -65,7 +65,7 @@ func setup(ctx context.Context, debug bool) { _ = fail(ctx, "Unable to access repository path", "Unable to access repository path %q, err: %v", setting.RepoRootPath, err) return } - if err := git.InitSimple(context.Background()); err != nil { + if err := git.InitSimple(); err != nil { _ = fail(ctx, "Failed to init git", "Failed to init git, err: %v", err) } } @@ -229,11 +229,6 @@ func runServ(ctx context.Context, c *cli.Command) error { username := repoPathFields[0] reponame := strings.TrimSuffix(repoPathFields[1], ".git") // “the-repo-name" or "the-repo-name.wiki" - // LowerCase and trim the repoPath as that's how they are stored. - // This should be done after splitting the repoPath into username and reponame - // so that username and reponame are not affected. - repoPath = strings.ToLower(strings.TrimSpace(repoPath)) - if !repo.IsValidSSHAccessRepoName(reponame) { return fail(ctx, "Invalid repo name", "Invalid repo name: %s", reponame) } @@ -280,6 +275,11 @@ func runServ(ctx context.Context, c *cli.Command) error { return fail(ctx, extra.UserMsg, "ServCommand failed: %s", extra.Error) } + // LowerCase and trim the repoPath as that's how they are stored. + // This should be done after splitting the repoPath into username and reponame + // so that username and reponame are not affected. + repoPath = strings.ToLower(results.OwnerName + "/" + results.RepoName + ".git") + // LFS SSH protocol if verb == git.CmdVerbLfsTransfer { token, err := getLFSAuthToken(ctx, lfsVerb, results) diff --git a/cmd/web.go b/cmd/web.go index 61ee3cbc20..4723ddbbdd 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -236,15 +236,16 @@ func serveInstalled(c *cli.Command) error { } func servePprof() { + // FIXME: it shouldn't use the global DefaultServeMux, and it should use a proper context http.DefaultServeMux.Handle("/debug/fgprof", fgprof.Handler()) - _, _, finished := process.GetManager().AddTypedContext(context.Background(), "Web: PProf Server", process.SystemProcessType, true) - // The pprof server is for debug purpose only, it shouldn't be exposed on public network. At the moment it's not worth to introduce a configurable option for it. + _, _, finished := process.GetManager().AddTypedContext(context.TODO(), "Web: PProf Server", process.SystemProcessType, true) + // The pprof server is for debug purpose only, it shouldn't be exposed on public network. At the moment, it's not worth introducing a configurable option for it. log.Info("Starting pprof server on localhost:6060") log.Info("Stopped pprof server: %v", http.ListenAndServe("localhost:6060", nil)) finished() } -func runWeb(_ context.Context, cmd *cli.Command) error { +func runWeb(ctx context.Context, cmd *cli.Command) error { defer func() { if panicked := recover(); panicked != nil { log.Fatal("PANIC: %v\n%s", panicked, log.Stack(2)) @@ -255,7 +256,7 @@ func runWeb(_ context.Context, cmd *cli.Command) error { return fmt.Errorf("unknown command: %s", subCmdName) } - managerCtx, cancel := context.WithCancel(context.Background()) + managerCtx, cancel := context.WithCancel(ctx) graceful.InitManager(managerCtx) defer cancel() diff --git a/contrib/backport/backport.go b/contrib/backport/backport.go index 2052295fb1..5811291b42 100644 --- a/contrib/backport/backport.go +++ b/contrib/backport/backport.go @@ -16,7 +16,7 @@ import ( "strconv" "strings" - "github.com/google/go-github/v71/github" + "github.com/google/go-github/v74/github" "github.com/urfave/cli/v3" "gopkg.in/yaml.v3" ) diff --git a/contrib/upgrade.sh b/contrib/upgrade.sh index 4b166a02a0..e5e296ea8b 100755 --- a/contrib/upgrade.sh +++ b/contrib/upgrade.sh @@ -85,7 +85,7 @@ fi # confirm update echo "Checking currently installed version..." current=$(giteacmd --version | cut -d ' ' -f 3) -[[ "$current" == "$giteaversion" ]] && echo "$current is already installed, stopping." && exit 1 +[[ "$current" == "$giteaversion" ]] && echo "$current is already installed, stopping." && exit 0 if [[ -z "${no_confirm:-}" ]]; then echo "Make sure to read the changelog first: https://github.com/go-gitea/gitea/blob/main/CHANGELOG.md" echo "Are you ready to update Gitea from ${current} to ${giteaversion}? (y/N)" diff --git a/flake.lock b/flake.lock index 67f87dfaf6..16a487ba13 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1752480373, - "narHash": "sha256-JHQbm+OcGp32wAsXTE/FLYGNpb+4GLi5oTvCxwSoBOA=", + "lastModified": 1755186698, + "narHash": "sha256-wNO3+Ks2jZJ4nTHMuks+cxAiVBGNuEBXsT29Bz6HASo=", "owner": "nixos", "repo": "nixpkgs", - "rev": "62e0f05ede1da0d54515d4ea8ce9c733f12d9f08", + "rev": "fbcf476f790d8a217c3eab4e12033dc4a0f6d23c", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 13aa5008e6..588f608ffc 100644 --- a/flake.nix +++ b/flake.nix @@ -15,41 +15,59 @@ with pkgs; let # only bump toolchain versions here - go = go_1_24; + go = go_1_25; nodejs = nodejs_24; python3 = python312; - in - pkgs.mkShell { - buildInputs = [ - # generic - git - git-lfs - gnumake - gnused - gnutar - gzip + pnpm = pnpm_10; - # frontend - nodejs - - # linting - python3 - uv - - # backend - go + # Platform-specific dependencies + linuxOnlyInputs = lib.optionals pkgs.stdenv.isLinux [ glibc.static - gofumpt - sqlite ]; - CFLAGS = "-I${glibc.static.dev}/include"; - LDFLAGS = "-L ${glibc.static}/lib"; - GO = "${go}/bin/go"; - GOROOT = "${go}/share/go"; - TAGS = "sqlite sqlite_unlock_notify"; - STATIC = "true"; - }; + linuxOnlyEnv = lib.optionalAttrs pkgs.stdenv.isLinux { + CFLAGS = "-I${glibc.static.dev}/include"; + LDFLAGS = "-L ${glibc.static}/lib"; + }; + in + pkgs.mkShell ( + { + buildInputs = [ + # generic + git + git-lfs + gnumake + gnused + gnutar + gzip + zip + + # frontend + nodejs + pnpm + cairo + pixman + pkg-config + + # linting + python3 + uv + + # backend + go + gofumpt + sqlite + ] + ++ linuxOnlyInputs; + + GO = "${go}/bin/go"; + GOROOT = "${go}/share/go"; + + TAGS = "sqlite sqlite_unlock_notify"; + STATIC = "true"; + } + // linuxOnlyEnv + ); } ); } diff --git a/go.mod b/go.mod index 5fc7473df7..eb871e24ae 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module code.gitea.io/gitea -go 1.24.6 +go 1.25.1 // rfc5280 said: "The serial number is an integer assigned by the CA to each certificate." // But some CAs use negative serial number, just relax the check. related: @@ -10,7 +10,7 @@ godebug x509negativeserial=1 require ( code.gitea.io/actions-proto-go v0.4.1 code.gitea.io/gitea-vet v0.2.3 - code.gitea.io/sdk/gitea v0.21.0 + code.gitea.io/sdk/gitea v0.22.0 codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 connectrpc.com/connect v1.18.1 gitea.com/go-chi/binding v0.0.0-20240430071103-39a851e106ed @@ -19,28 +19,28 @@ require ( gitea.com/go-chi/session v0.0.0-20240316035857-16768d98ec96 gitea.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4 - github.com/42wim/httpsig v1.2.2 - github.com/42wim/sshsig v0.0.0-20240818000253-e3a6333df815 - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 - github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.0 + github.com/42wim/httpsig v1.2.3 + github.com/42wim/sshsig v0.0.0-20250502153856-5100632e8920 + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0 + github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.2 github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 - github.com/ProtonMail/go-crypto v1.2.0 + github.com/ProtonMail/go-crypto v1.3.0 github.com/PuerkitoBio/goquery v1.10.3 - github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.3 - github.com/alecthomas/chroma/v2 v2.17.0 - github.com/aws/aws-sdk-go-v2/credentials v1.17.67 - github.com/aws/aws-sdk-go-v2/service/codecommit v1.28.2 + github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.8.0 + github.com/alecthomas/chroma/v2 v2.20.0 + github.com/aws/aws-sdk-go-v2/credentials v1.18.10 + github.com/aws/aws-sdk-go-v2/service/codecommit v1.32.2 github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb - github.com/blevesearch/bleve/v2 v2.5.0 + github.com/blevesearch/bleve/v2 v2.5.3 github.com/bohde/codel v0.2.0 github.com/buildkite/terminal-to-html/v3 v3.16.8 - github.com/caddyserver/certmagic v0.23.0 + github.com/caddyserver/certmagic v0.24.0 github.com/charmbracelet/git-lfs-transfer v0.2.0 github.com/chi-middleware/proxy v1.1.1 github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21 github.com/djherbis/buffer v1.2.0 github.com/djherbis/nio/v3 v3.0.1 - github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 + github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 github.com/dustin/go-humanize v1.0.1 github.com/editorconfig/editorconfig-core-go/v2 v2.6.3 github.com/emersion/go-imap v1.2.1 @@ -49,25 +49,25 @@ require ( github.com/felixge/fgprof v0.9.5 github.com/fsnotify/fsnotify v1.9.0 github.com/gliderlabs/ssh v0.3.8 - github.com/go-ap/activitypub v0.0.0-20250409143848-7113328b1f3d + github.com/go-ap/activitypub v0.0.0-20250810115208-cb73b20a1742 github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73 - github.com/go-chi/chi/v5 v5.2.2 - github.com/go-chi/cors v1.2.1 + github.com/go-chi/chi/v5 v5.2.3 + github.com/go-chi/cors v1.2.2 github.com/go-co-op/gocron v1.37.0 github.com/go-enry/go-enry/v2 v2.9.2 github.com/go-git/go-billy/v5 v5.6.2 - github.com/go-git/go-git/v5 v5.16.0 + github.com/go-git/go-git/v5 v5.16.2 github.com/go-ldap/ldap/v3 v3.4.11 github.com/go-redsync/redsync/v4 v4.13.0 - github.com/go-sql-driver/mysql v1.9.2 - github.com/go-webauthn/webauthn v0.12.3 + github.com/go-sql-driver/mysql v1.9.3 + github.com/go-webauthn/webauthn v0.13.4 github.com/gobwas/glob v0.2.3 github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 - github.com/golang-jwt/jwt/v5 v5.2.2 - github.com/google/go-github/v71 v71.0.0 + github.com/golang-jwt/jwt/v5 v5.3.0 + github.com/google/go-github/v74 v74.0.0 github.com/google/licenseclassifier/v2 v2.0.0 - github.com/google/pprof v0.0.0-20250422154841-e1f9c1950416 + github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 github.com/google/uuid v1.6.0 github.com/gorilla/feeds v1.2.0 github.com/gorilla/sessions v1.4.0 @@ -79,53 +79,53 @@ require ( github.com/json-iterator/go v1.1.12 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/klauspost/compress v1.18.0 - github.com/klauspost/cpuid/v2 v2.2.10 + github.com/klauspost/cpuid/v2 v2.3.0 github.com/lib/pq v1.10.9 - github.com/markbates/goth v1.81.0 + github.com/markbates/goth v1.82.0 github.com/mattn/go-isatty v0.0.20 - github.com/mattn/go-sqlite3 v1.14.28 - github.com/meilisearch/meilisearch-go v0.31.0 - github.com/mholt/archiver/v3 v3.5.1 + github.com/mattn/go-sqlite3 v1.14.32 + github.com/meilisearch/meilisearch-go v0.33.2 + github.com/mholt/archives v0.1.3 github.com/microcosm-cc/bluemonday v1.0.27 - github.com/microsoft/go-mssqldb v1.8.0 - github.com/minio/minio-go/v7 v7.0.91 + github.com/microsoft/go-mssqldb v1.9.3 + github.com/minio/minio-go/v7 v7.0.95 github.com/msteinert/pam v1.2.0 github.com/nektos/act v0.2.63 - github.com/niklasfasching/go-org v1.8.0 + github.com/niklasfasching/go-org v1.9.1 github.com/olivere/elastic/v7 v7.0.32 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.1 github.com/pkg/errors v0.9.1 - github.com/pquerna/otp v1.4.0 - github.com/prometheus/client_golang v1.22.0 + github.com/pquerna/otp v1.5.0 + github.com/prometheus/client_golang v1.23.0 github.com/quasoft/websspi v1.1.2 - github.com/redis/go-redis/v9 v9.7.3 + github.com/redis/go-redis/v9 v9.12.1 github.com/robfig/cron/v3 v3.0.1 github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 github.com/sassoftware/go-rpmutils v0.4.0 - github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 - github.com/stretchr/testify v1.10.0 + github.com/sergi/go-diff v1.4.0 + github.com/stretchr/testify v1.11.1 github.com/syndtr/goleveldb v1.0.0 github.com/tstranex/u2f v1.0.0 - github.com/ulikunitz/xz v0.5.12 + github.com/ulikunitz/xz v0.5.15 github.com/urfave/cli-docs/v3 v3.0.0-alpha6 - github.com/urfave/cli/v3 v3.3.3 + github.com/urfave/cli/v3 v3.4.1 github.com/wneessen/go-mail v0.6.2 github.com/xeipuuv/gojsonschema v1.2.0 github.com/yohcop/openid-go v1.0.1 - github.com/yuin/goldmark v1.7.10 + github.com/yuin/goldmark v1.7.13 github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc github.com/yuin/goldmark-meta v1.1.0 - gitlab.com/gitlab-org/api/client-go v0.127.0 - golang.org/x/crypto v0.39.0 - golang.org/x/image v0.26.0 - golang.org/x/net v0.40.0 - golang.org/x/oauth2 v0.29.0 - golang.org/x/sync v0.15.0 - golang.org/x/sys v0.33.0 - golang.org/x/text v0.26.0 - google.golang.org/grpc v1.72.0 - google.golang.org/protobuf v1.36.6 + gitlab.com/gitlab-org/api/client-go v0.142.4 + golang.org/x/crypto v0.41.0 + golang.org/x/image v0.30.0 + golang.org/x/net v0.43.0 + golang.org/x/oauth2 v0.30.0 + golang.org/x/sync v0.16.0 + golang.org/x/sys v0.35.0 + golang.org/x/text v0.28.0 + google.golang.org/grpc v1.75.0 + google.golang.org/protobuf v1.36.8 gopkg.in/ini.v1 v1.67.0 gopkg.in/yaml.v3 v3.0.1 mvdan.cc/xurls/v2 v2.6.0 @@ -135,43 +135,47 @@ require ( ) require ( - cloud.google.com/go/compute/metadata v0.6.0 // indirect - dario.cat/mergo v1.0.1 // indirect + cloud.google.com/go/compute/metadata v0.8.0 // indirect + dario.cat/mergo v1.0.2 // indirect filippo.io/edwards25519 v1.1.0 // indirect git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect github.com/DataDog/zstd v1.5.7 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/RoaringBitmap/roaring/v2 v2.4.5 // indirect - github.com/andybalholm/brotli v1.1.1 // indirect + github.com/RoaringBitmap/roaring/v2 v2.10.0 // indirect + github.com/STARRY-S/zip v0.2.1 // indirect + github.com/andybalholm/brotli v1.2.0 // indirect github.com/andybalholm/cascadia v1.3.3 // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect - github.com/aws/aws-sdk-go-v2 v1.36.3 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect - github.com/aws/smithy-go v1.22.3 // indirect + github.com/aws/aws-sdk-go-v2 v1.38.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.6 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.6 // indirect + github.com/aws/smithy-go v1.23.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.22.0 // indirect - github.com/blevesearch/bleve_index_api v1.2.8 // indirect - github.com/blevesearch/geo v0.2.0 // indirect + github.com/bits-and-blooms/bitset v1.24.0 // indirect + github.com/blevesearch/bleve_index_api v1.2.9 // indirect + github.com/blevesearch/geo v0.2.4 // indirect github.com/blevesearch/go-faiss v1.0.25 // indirect github.com/blevesearch/go-porterstemmer v1.0.3 // indirect github.com/blevesearch/gtreap v0.1.1 // indirect github.com/blevesearch/mmap-go v1.0.4 // indirect - github.com/blevesearch/scorch_segment_api/v2 v2.3.10 // indirect + github.com/blevesearch/scorch_segment_api/v2 v2.3.11 // indirect github.com/blevesearch/segment v0.9.1 // indirect github.com/blevesearch/snowballstem v0.9.0 // indirect github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect github.com/blevesearch/vellum v1.1.0 // indirect - github.com/blevesearch/zapx/v11 v11.4.1 // indirect - github.com/blevesearch/zapx/v12 v12.4.1 // indirect - github.com/blevesearch/zapx/v13 v13.4.1 // indirect - github.com/blevesearch/zapx/v14 v14.4.1 // indirect - github.com/blevesearch/zapx/v15 v15.4.1 // indirect - github.com/blevesearch/zapx/v16 v16.2.3 // indirect - github.com/bmatcuk/doublestar/v4 v4.8.1 // indirect - github.com/boombuler/barcode v1.0.2 // indirect + github.com/blevesearch/zapx/v11 v11.4.2 // indirect + github.com/blevesearch/zapx/v12 v12.4.2 // indirect + github.com/blevesearch/zapx/v13 v13.4.2 // indirect + github.com/blevesearch/zapx/v14 v14.4.2 // indirect + github.com/blevesearch/zapx/v15 v15.4.2 // indirect + github.com/blevesearch/zapx/v16 v16.2.4 // indirect + github.com/bmatcuk/doublestar/v4 v4.9.1 // indirect + github.com/bodgit/plumbing v1.3.0 // indirect + github.com/bodgit/sevenzip v1.6.0 // indirect + github.com/bodgit/windows v1.0.1 // indirect + github.com/boombuler/barcode v1.1.0 // indirect github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // indirect github.com/caddyserver/zerossl v0.1.3 // indirect github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect @@ -180,7 +184,7 @@ require ( github.com/couchbase/go-couchbase v0.1.1 // indirect github.com/couchbase/gomemcached v0.3.3 // indirect github.com/couchbase/goutils v0.1.2 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect github.com/cyphar/filepath-securejoin v0.4.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidmz/go-pageant v1.0.2 // indirect @@ -188,15 +192,15 @@ require ( github.com/dlclark/regexp2 v1.11.5 // indirect github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 // indirect github.com/fatih/color v1.18.0 // indirect - github.com/fxamacker/cbor/v2 v2.8.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/git-lfs/pktline v0.0.0-20230103162542-ca444d533ef1 // indirect - github.com/go-ap/errors v0.0.0-20250409143711-5686c11ae650 // indirect + github.com/go-ap/errors v0.0.0-20250527110557-c8db454e53fd // indirect github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect github.com/go-enry/go-oniguruma v1.2.1 // indirect github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-ini/ini v1.67.0 // indirect - github.com/go-webauthn/x v0.1.20 // indirect + github.com/go-webauthn/x v0.1.24 // indirect github.com/goccy/go-json v0.10.5 // indirect github.com/golang-jwt/jwt/v4 v4.5.2 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect @@ -207,50 +211,58 @@ require ( github.com/google/btree v1.1.3 // indirect github.com/google/flatbuffers v25.2.10+incompatible // indirect github.com/google/go-querystring v1.1.0 // indirect - github.com/google/go-tpm v0.9.3 // indirect + github.com/google/go-tpm v0.9.5 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/securecookie v1.1.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-retryablehttp v0.7.7 // indirect + github.com/hashicorp/go-retryablehttp v0.7.8 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/kevinburke/ssh_config v1.4.0 // indirect github.com/klauspost/pgzip v1.2.6 // indirect - github.com/libdns/libdns v1.0.0-beta.1 // indirect + github.com/libdns/libdns v1.1.1 // indirect github.com/mailru/easyjson v0.9.0 // indirect github.com/markbates/going v1.0.3 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect github.com/mholt/acmez/v3 v3.1.2 // indirect - github.com/miekg/dns v1.1.65 // indirect - github.com/minio/crc64nvme v1.0.1 // indirect + github.com/miekg/dns v1.1.68 // indirect + github.com/mikelolasagasti/xz v1.0.1 // indirect + github.com/minio/crc64nvme v1.1.1 // indirect github.com/minio/md5-simd v1.1.2 // indirect + github.com/minio/minlz v1.0.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // 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 github.com/mschoch/smat v0.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/nwaples/rardecode v1.1.3 // indirect - github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/nwaples/rardecode/v2 v2.1.0 // indirect + github.com/olekukonko/cat v0.0.0-20250817074551-3280053e4e00 // indirect + github.com/olekukonko/errors v1.1.0 // indirect + github.com/olekukonko/ll v0.1.0 // indirect + github.com/olekukonko/tablewriter v1.0.9 // indirect github.com/onsi/ginkgo v1.16.5 // indirect + github.com/philhofer/fwd v1.2.0 // indirect github.com/pierrec/lz4/v4 v4.1.22 // indirect - github.com/pjbgf/sha1cd v0.3.2 // indirect + github.com/pjbgf/sha1cd v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.63.0 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.65.0 // indirect + github.com/prometheus/procfs v0.17.0 // indirect github.com/rhysd/actionlint v1.7.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rs/xid v1.6.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/skeema/knownhosts v1.3.1 // indirect + github.com/sorairolake/lzip-go v0.3.5 // indirect github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect + github.com/tinylib/msgp v1.4.0 // indirect github.com/unknwon/com v1.0.1 // indirect github.com/valyala/fastjson v1.6.4 // indirect github.com/x448/float16 v0.8.4 // indirect @@ -260,20 +272,28 @@ require ( github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/zeebo/assert v1.3.0 // indirect github.com/zeebo/blake3 v0.2.4 // indirect - go.etcd.io/bbolt v1.4.0 // indirect + go.etcd.io/bbolt v1.4.3 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go.uber.org/zap/exp v0.3.0 // indirect + go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect - golang.org/x/mod v0.25.0 // indirect - golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.33.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250422160041-2d3770c4ea7f // indirect + golang.org/x/mod v0.27.0 // indirect + golang.org/x/time v0.12.0 // indirect + golang.org/x/tools v0.36.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) +ignore ( + ./.venv + ./node_modules +) + +replace github.com/jaytaylor/html2text => github.com/Necoro/html2text v0.0.0-20250804200300-7bf1ce1c7347 + replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1 replace github.com/nektos/act => gitea.com/gitea/act v0.261.6 @@ -281,9 +301,6 @@ replace github.com/nektos/act => gitea.com/gitea/act v0.261.6 // TODO: the only difference is in `PutObject`: the fork doesn't use `NewVerifyingReader(r, sha256.New(), oid, expectedSize)`, need to figure out why replace github.com/charmbracelet/git-lfs-transfer => gitea.com/gitea/git-lfs-transfer v0.2.0 -// TODO: This could be removed after https://github.com/mholt/archiver/pull/396 merged -replace github.com/mholt/archiver/v3 => github.com/anchore/archiver/v3 v3.5.2 - replace git.sr.ht/~mariusor/go-xsd-duration => gitea.com/gitea/go-xsd-duration v0.0.0-20220703122237-02e73435a078 exclude github.com/gofrs/uuid v3.2.0+incompatible diff --git a/go.sum b/go.sum index 2ccdc64d77..b69b380cfe 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,34 @@ -cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= -cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +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/compute/metadata v0.8.0 h1:HxMRIbao8w17ZX6wBnjhcDkW6lTFpgcaobyVfZWqRLA= +cloud.google.com/go/compute/metadata v0.8.0/go.mod h1:sYOGTp851OV9bOFJ9CH7elVvyzopvWQFNNghtDQ/Biw= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +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/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= code.gitea.io/actions-proto-go v0.4.1 h1:l0EYhjsgpUe/1VABo2eK7zcoNX2W44WOnb0MSLrKfls= code.gitea.io/actions-proto-go v0.4.1/go.mod h1:mn7Wkqz6JbnTOHQpot3yDeHx+O5C9EGhMEE+htvHBas= code.gitea.io/gitea-vet v0.2.3 h1:gdFmm6WOTM65rE8FUBTRzeQZYzXePKSSB1+r574hWwI= code.gitea.io/gitea-vet v0.2.3/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= -code.gitea.io/sdk/gitea v0.21.0 h1:69n6oz6kEVHRo1+APQQyizkhrZrLsTLXey9142pfkD4= -code.gitea.io/sdk/gitea v0.21.0/go.mod h1:tnBjVhuKJCn8ibdyyhvUyxrR1Ca2KHEoTWoukNhXQPA= +code.gitea.io/sdk/gitea v0.22.0 h1:HCKq7bX/HQ85Nw7c/HAhWgRye+vBp5nQOE8Md1+9Ef0= +code.gitea.io/sdk/gitea v0.22.0/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM= codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 h1:TXbikPqa7YRtfU9vS6QJBg77pUvbEb6StRdZO8t1bEY= codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570/go.mod h1:IIAjsijsd8q1isWX8MACefDEgTQslQ4stk2AeeTt3kM= connectrpc.com/connect v1.18.1 h1:PAg7CjSAGvscaf6YZKUefjoih5Z/qYkyaTrBW8xvYPw= connectrpc.com/connect v1.18.1/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8= -dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= -dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= +dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= gitea.com/gitea/act v0.261.6 h1:CjZwKOyejonNFDmsXOw3wGm5Vet573hHM6VMLsxtvPY= @@ -34,62 +51,64 @@ gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4 h1:IFT+hup2xejHq gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= -github.com/42wim/httpsig v1.2.2 h1:ofAYoHUNs/MJOLqQ8hIxeyz2QxOz8qdSVvp3PX/oPgA= -github.com/42wim/httpsig v1.2.2/go.mod h1:P/UYo7ytNBFwc+dg35IubuAUIs8zj5zzFIgUCEl55WY= -github.com/42wim/sshsig v0.0.0-20240818000253-e3a6333df815 h1:5EoemV++kUK2Sw98yWP/RWyduvP7IaBgWWHe+4BWcSw= -github.com/42wim/sshsig v0.0.0-20240818000253-e3a6333df815/go.mod h1:zjsWZdDLrcDojDIfpQg7A6J4YZLT0cbwuAD26AppDBo= +github.com/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs= +github.com/42wim/httpsig v1.2.3/go.mod h1:nZq9OlYKDrUBhptd77IHx4/sZZD+IxTBADvAPI9G/EM= +github.com/42wim/sshsig v0.0.0-20250502153856-5100632e8920 h1:mWAVGlovzUfREJBhm0GwJnDNu21yRrL9QH9NIzAU3rg= +github.com/42wim/sshsig v0.0.0-20250502153856-5100632e8920/go.mod h1:zWxcT7BIWOe05xVJL0VMvO/PJ6RpoCux10heb77H6Q8= github.com/6543/go-version v1.3.1 h1:HvOp+Telns7HWJ2Xo/05YXQSB2bE0WmVgbHqwMPZT4U= github.com/6543/go-version v1.3.1/go.mod h1:oqFAHCwtLVUTLdhQmVZWYvaHXTdsbB4SY85at64SQEo= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 h1:F0gBpfdPLGsw+nsgk6aqqkZS1jiixa5WwFe3fk/T3Ys= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2/go.mod h1:SqINnQ9lVVdRlyC8cd1lCI0SdX4n2paeABd2K8ggfnE= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0 h1:PiSrjRPpkQNjrM8H0WwKMnZUdu1RGMtd/LdGKUrOo+c= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0/go.mod h1:oDrbWx4ewMylP7xHivfgixbfGBT6APAwsSoHRKotnIc= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1 h1:MyVTgWR8qd/Jw1Le0NZebGBUCLbtak3bJ3z1OlqZBpw= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1/go.mod h1:GpPjLhVR9dnUoJMyHWSPy71xY9/lcmpzIPZXmF0FCVY= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 h1:D3occbWoio4EBLkbkevetNMAVX197GkzbUMtqjGWn80= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0/go.mod h1:bTSOgj05NGRuHHhQwAdPnYr9TOdNmKlZTgGLL6nyAdI= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.0 h1:UXT0o77lXQrikd1kgwIPQOUect7EoR/+sbP4wQKdzxM= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.0/go.mod h1:cTvi54pg19DoT07ekoeMgE/taAwNtCShVeZqA+Iv2xI= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0 h1:ci6Yd6nysBRLEodoziB6ah1+YOzZbZk+NYneoA6q+6E= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0/go.mod h1:QyVsSSN64v5TGltphKLQ2sQxe4OBQg0J1eKRcVBnfgE= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 h1:B+blDbyVIG3WaikNxPnhPiJ1MThR03b3vKGtER95TP4= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1/go.mod h1:JdM5psgjfBf5fo2uWOZhflPWyDBZ/O/CNAH9CtsuZE4= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.8.1 h1:/Zt+cDPnpC3OVDm/JKLOs7M2DKmLRIIp3XIx9pHHiig= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.8.1/go.mod h1:Ng3urmn6dYe8gnbCMoHHVl5APYz2txho3koEkV2o2HA= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1 h1:Wgf5rZba3YZqeTNJPtvqZoBu1sBN/L4sry+u2U3Y75w= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1/go.mod h1:xxCBG/f/4Vbmh2XQJBsOmNdxWUY5j/s27jujKPbQf14= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 h1:bFWuoEKg+gImo7pvkiQEFAc8ocibADgXeiLAxWhWmkI= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1/go.mod h1:Vih/3yc6yac2JzU4hzpaDupBJP0Flaia9rXXrU8xyww= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.2 h1:FwladfywkNirM+FZYLBR2kBz5C8Tg0fw5w5Y7meRXWI= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.2/go.mod h1:vv5Ad0RrIoT1lJFdWBZwt4mB1+j+V8DUroixmKDTCdk= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs= github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= 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/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/ProtonMail/go-crypto v1.2.0 h1:+PhXXn4SPGd+qk76TlEePBfOfivE0zkWFenhGhFLzWs= -github.com/ProtonMail/go-crypto v1.2.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= +github.com/Necoro/html2text v0.0.0-20250804200300-7bf1ce1c7347 h1:3JhDl+JysaO8nhNU1XMaw35VSGjV4IEQAefaG4Lyok4= +github.com/Necoro/html2text v0.0.0-20250804200300-7bf1ce1c7347/go.mod h1:2ErI0aycD43Ufr6CFK5lT/NrHGmoZuVbn1nlPThw69o= +github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= +github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= github.com/PuerkitoBio/goquery v1.10.3 h1:pFYcNSqHxBD06Fpj/KsbStFRsgRATgnf3LeXiUkhzPo= github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y= github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo= github.com/RoaringBitmap/roaring v0.7.1/go.mod h1:jdT9ykXwHFNdJbEtxePexlFYH9LXucApeS0/+/g+p1I= -github.com/RoaringBitmap/roaring/v2 v2.4.5 h1:uGrrMreGjvAtTBobc0g5IrW1D5ldxDQYe2JW2gggRdg= -github.com/RoaringBitmap/roaring/v2 v2.4.5/go.mod h1:FiJcsfkGje/nZBZgCu0ZxCPOKD/hVXDS2dXi7/eUFE0= -github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.3 h1:BP0HiyNT3AQEYi+if3wkRcIdQFHtsw6xX3Kx0glckgA= -github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.3/go.mod h1:hMNtySovKkn2gdDuLqnqveP+mfhUSaBdoBcr2I7Zt0E= +github.com/RoaringBitmap/roaring/v2 v2.10.0 h1:HbJ8Cs71lfCJyvmSptxeMX2PtvOC8yonlU0GQcy2Ak0= +github.com/RoaringBitmap/roaring/v2 v2.10.0/go.mod h1:FiJcsfkGje/nZBZgCu0ZxCPOKD/hVXDS2dXi7/eUFE0= +github.com/STARRY-S/zip v0.2.1 h1:pWBd4tuSGm3wtpoqRZZ2EAwOmcHK6XFf7bU9qcJXyFg= +github.com/STARRY-S/zip v0.2.1/go.mod h1:xNvshLODWtC4EJ702g7cTYn13G53o1+X9BWnPFpcWV4= +github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.8.0 h1:tgjwQrDH5m6jIYB7kac5IQZmfUzQNseac/e3H4VoCNE= +github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.8.0/go.mod h1:1HmmMEVsr+0R1QWahSeMJkjSkq6CYAZu1aIbYSpfJ4o= github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs= -github.com/alecthomas/chroma/v2 v2.17.0 h1:3r2Cgk+nXNICMBxIFGnTRTbQFUwMiLisW+9uos0TtUI= -github.com/alecthomas/chroma/v2 v2.17.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk= +github.com/alecthomas/chroma/v2 v2.20.0 h1:sfIHpxPyR07/Oylvmcai3X/exDlE8+FA820NTz+9sGw= +github.com/alecthomas/chroma/v2 v2.20.0/go.mod h1:e7tViK0xh/Nf4BYHl00ycY6rV7b8iXBksI9E359yNmA= github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= -github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= -github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/alecthomas/repr v0.5.1 h1:E3G4t2QbHTSNpPKBgMTln5KLkZHLOcU7r37J4pXBuIg= +github.com/alecthomas/repr v0.5.1/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= -github.com/anchore/archiver/v3 v3.5.2 h1:Bjemm2NzuRhmHy3m0lRe5tNoClB9A4zYyDV58PaB6aA= -github.com/anchore/archiver/v3 v3.5.2/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= -github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= -github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= -github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= +github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= +github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM= github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= @@ -97,18 +116,18 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuW github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= 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/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM= -github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg= -github.com/aws/aws-sdk-go-v2/credentials v1.17.67 h1:9KxtdcIA/5xPNQyZRgUSpYOE6j9Bc4+D7nZua0KGYOM= -github.com/aws/aws-sdk-go-v2/credentials v1.17.67/go.mod h1:p3C44m+cfnbv763s52gCqrjaqyPikj9Sg47kUVaNZQQ= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q= -github.com/aws/aws-sdk-go-v2/service/codecommit v1.28.2 h1:enL75gIdaPAoBztv/GDuMgOocEUpO2jYc45qp2Uweqs= -github.com/aws/aws-sdk-go-v2/service/codecommit v1.28.2/go.mod h1:JsdLne5QNlqJdCQFm2DbHLNmNfEWSU7HnTuvi8SIl+E= -github.com/aws/smithy-go v1.22.3 h1:Z//5NuZCSW6R4PhQ93hShNbyBbn8BWCmCVCt+Q8Io5k= -github.com/aws/smithy-go v1.22.3/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/aws/aws-sdk-go-v2 v1.38.3 h1:B6cV4oxnMs45fql4yRH+/Po/YU+597zgWqvDpYMturk= +github.com/aws/aws-sdk-go-v2 v1.38.3/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= +github.com/aws/aws-sdk-go-v2/credentials v1.18.10 h1:xdJnXCouCx8Y0NncgoptztUocIYLKeQxrCgN6x9sdhg= +github.com/aws/aws-sdk-go-v2/credentials v1.18.10/go.mod h1:7tQk08ntj914F/5i9jC4+2HQTAuJirq7m1vZVIhEkWs= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.6 h1:uF68eJA6+S9iVr9WgX1NaRGyQ/6MdIyc4JNUo6TN1FA= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.6/go.mod h1:qlPeVZCGPiobx8wb1ft0GHT5l+dc6ldnwInDFaMvC7Y= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.6 h1:pa1DEC6JoI0zduhZePp3zmhWvk/xxm4NB8Hy/Tlsgos= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.6/go.mod h1:gxEjPebnhWGJoaDdtDkA0JX46VRg1wcTHYe63OfX5pE= +github.com/aws/aws-sdk-go-v2/service/codecommit v1.32.2 h1:qIySgaSYDLcInLpY0e7HPCi+AVeD/LTsl9EL1b692oA= +github.com/aws/aws-sdk-go-v2/service/codecommit v1.32.2/go.mod h1:SobWM1535Mn1WuThoIVLiLa/C1rRbxbbq5PZW2QFCIM= +github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE= +github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -116,18 +135,18 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bits-and-blooms/bitset v1.1.10/go.mod h1:w0XsmFg8qg6cmpTtJ0z3pKgjTDBMMnI/+I2syrE6XBE= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/bits-and-blooms/bitset v1.22.0 h1:Tquv9S8+SGaS3EhyA+up3FXzmkhxPGjQQCkcs2uw7w4= -github.com/bits-and-blooms/bitset v1.22.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.24.0 h1:H4x4TuulnokZKvHLfzVRTHJfFfnHEeSYJizujEZvmAM= +github.com/bits-and-blooms/bitset v1.24.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= github.com/blevesearch/bleve/v2 v2.0.5/go.mod h1:ZjWibgnbRX33c+vBRgla9QhPb4QOjD6fdVJ+R1Bk8LM= -github.com/blevesearch/bleve/v2 v2.5.0 h1:HzYqBy/5/M9Ul9ESEmXzN/3Jl7YpmWBdHM/+zzv/3k4= -github.com/blevesearch/bleve/v2 v2.5.0/go.mod h1:PcJzTPnEynO15dCf9isxOga7YFRa/cMSsbnRwnszXUk= +github.com/blevesearch/bleve/v2 v2.5.3 h1:9l1xtKaETv64SZc1jc4Sy0N804laSa/LeMbYddq1YEM= +github.com/blevesearch/bleve/v2 v2.5.3/go.mod h1:Z/e8aWjiq8HeX+nW8qROSxiE0830yQA071dwR3yoMzw= github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4= -github.com/blevesearch/bleve_index_api v1.2.8 h1:Y98Pu5/MdlkRyLM0qDHostYo7i+Vv1cDNhqTeR4Sy6Y= -github.com/blevesearch/bleve_index_api v1.2.8/go.mod h1:rKQDl4u51uwafZxFrPD1R7xFOwKnzZW7s/LSeK4lgo0= -github.com/blevesearch/geo v0.2.0 h1:f+IE3/C3mGeXDyhtMbWel6BgqBqaOUz43GtWg26GlB0= -github.com/blevesearch/geo v0.2.0/go.mod h1:k8Hyfz12kM8QmeWLhgX7VMMCoVFmttBnr62V5zniXak= +github.com/blevesearch/bleve_index_api v1.2.9 h1:WqD3kvYwnlYLv8sTdH+AF7n/L4v969Cek68+wZnYj4Q= +github.com/blevesearch/bleve_index_api v1.2.9/go.mod h1:rKQDl4u51uwafZxFrPD1R7xFOwKnzZW7s/LSeK4lgo0= +github.com/blevesearch/geo v0.2.4 h1:ECIGQhw+QALCZaDcogRTNSJYQXRtC8/m8IKiA706cqk= +github.com/blevesearch/geo v0.2.4/go.mod h1:K56Q33AzXt2YExVHGObtmRSFYZKYGv0JEN5mdacJJR8= github.com/blevesearch/go-faiss v1.0.25 h1:lel1rkOUGbT1CJ0YgzKwC7k+XH0XVBHnCVWahdCXk4U= github.com/blevesearch/go-faiss v1.0.25/go.mod h1:OMGQwOaRRYxrmeNdMrXJPvVx8gBnvE5RYrr0BahNnkk= github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo= @@ -138,8 +157,8 @@ github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+ github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc= github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs= github.com/blevesearch/scorch_segment_api/v2 v2.0.1/go.mod h1:lq7yK2jQy1yQjtjTfU931aVqz7pYxEudHaDwOt1tXfU= -github.com/blevesearch/scorch_segment_api/v2 v2.3.10 h1:Yqk0XD1mE0fDZAJXTjawJ8If/85JxnLd8v5vG/jWE/s= -github.com/blevesearch/scorch_segment_api/v2 v2.3.10/go.mod h1:Z3e6ChN3qyN35yaQpl00MfI5s8AxUJbpTR/DL8QOQ+8= +github.com/blevesearch/scorch_segment_api/v2 v2.3.11 h1:bYuEgsyGqgU/gy0/Vk6g1eCUqGBs2r+3bRCv+Cnq2kc= +github.com/blevesearch/scorch_segment_api/v2 v2.3.11/go.mod h1:aAWoeQ3DdoZ3Z5138jXVSd1T/klGwvg11z0pSxrJSEk= github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ= github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU= github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw= @@ -153,30 +172,36 @@ github.com/blevesearch/vellum v1.0.4/go.mod h1:cMhywHI0de50f7Nj42YgvyD6bFJ2WkNRv github.com/blevesearch/vellum v1.1.0 h1:CinkGyIsgVlYf8Y2LUQHvdelgXr6PYuvoDIajq6yR9w= github.com/blevesearch/vellum v1.1.0/go.mod h1:QgwWryE8ThtNPxtgWJof5ndPfx0/YMBh+W2weHKPw8Y= github.com/blevesearch/zapx/v11 v11.2.0/go.mod h1:gN/a0alGw1FZt/YGTo1G6Z6XpDkeOfujX5exY9sCQQM= -github.com/blevesearch/zapx/v11 v11.4.1 h1:qFCPlFbsEdwbbckJkysptSQOsHn4s6ZOHL5GMAIAVHA= -github.com/blevesearch/zapx/v11 v11.4.1/go.mod h1:qNOGxIqdPC1MXauJCD9HBG487PxviTUUbmChFOAosGs= +github.com/blevesearch/zapx/v11 v11.4.2 h1:l46SV+b0gFN+Rw3wUI1YdMWdSAVhskYuvxlcgpQFljs= +github.com/blevesearch/zapx/v11 v11.4.2/go.mod h1:4gdeyy9oGa/lLa6D34R9daXNUvfMPZqUYjPwiLmekwc= github.com/blevesearch/zapx/v12 v12.2.0/go.mod h1:fdjwvCwWWwJW/EYTYGtAp3gBA0geCYGLcVTtJEZnY6A= -github.com/blevesearch/zapx/v12 v12.4.1 h1:K77bhypII60a4v8mwvav7r4IxWA8qxhNjgF9xGdb9eQ= -github.com/blevesearch/zapx/v12 v12.4.1/go.mod h1:QRPrlPOzAxBNMI0MkgdD+xsTqx65zbuPr3Ko4Re49II= +github.com/blevesearch/zapx/v12 v12.4.2 h1:fzRbhllQmEMUuAQ7zBuMvKRlcPA5ESTgWlDEoB9uQNE= +github.com/blevesearch/zapx/v12 v12.4.2/go.mod h1:TdFmr7afSz1hFh/SIBCCZvcLfzYvievIH6aEISCte58= github.com/blevesearch/zapx/v13 v13.2.0/go.mod h1:o5rAy/lRS5JpAbITdrOHBS/TugWYbkcYZTz6VfEinAQ= -github.com/blevesearch/zapx/v13 v13.4.1 h1:EnkEMZFUK0lsW/jOJJF2xOcp+W8TjEsyeN5BeAZEYYE= -github.com/blevesearch/zapx/v13 v13.4.1/go.mod h1:e6duBMlCvgbH9rkzNMnUa9hRI9F7ri2BRcHfphcmGn8= +github.com/blevesearch/zapx/v13 v13.4.2 h1:46PIZCO/ZuKZYgxI8Y7lOJqX3Irkc3N8W82QTK3MVks= +github.com/blevesearch/zapx/v13 v13.4.2/go.mod h1:knK8z2NdQHlb5ot/uj8wuvOq5PhDGjNYQQy0QDnopZk= github.com/blevesearch/zapx/v14 v14.2.0/go.mod h1:GNgZusc1p4ot040cBQMRGEZobvwjCquiEKYh1xLFK9g= -github.com/blevesearch/zapx/v14 v14.4.1 h1:G47kGCshknBZzZAtjcnIAMn3oNx8XBLxp8DMq18ogyE= -github.com/blevesearch/zapx/v14 v14.4.1/go.mod h1:O7sDxiaL2r2PnCXbhh1Bvm7b4sP+jp4unE9DDPWGoms= +github.com/blevesearch/zapx/v14 v14.4.2 h1:2SGHakVKd+TrtEqpfeq8X+So5PShQ5nW6GNxT7fWYz0= +github.com/blevesearch/zapx/v14 v14.4.2/go.mod h1:rz0XNb/OZSMjNorufDGSpFpjoFKhXmppH9Hi7a877D8= github.com/blevesearch/zapx/v15 v15.2.0/go.mod h1:MmQceLpWfME4n1WrBFIwplhWmaQbQqLQARpaKUEOs/A= -github.com/blevesearch/zapx/v15 v15.4.1 h1:B5IoTMUCEzFdc9FSQbhVOxAY+BO17c05866fNruiI7g= -github.com/blevesearch/zapx/v15 v15.4.1/go.mod h1:b/MreHjYeQoLjyY2+UaM0hGZZUajEbE0xhnr1A2/Q6Y= -github.com/blevesearch/zapx/v16 v16.2.3 h1:7Y0r+a3diEvlazsncexq1qoFOcBd64xwMS7aDm4lo1s= -github.com/blevesearch/zapx/v16 v16.2.3/go.mod h1:wVJ+GtURAaRG9KQAMNYyklq0egV+XJlGcXNCE0OFjjA= -github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38= -github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/blevesearch/zapx/v15 v15.4.2 h1:sWxpDE0QQOTjyxYbAVjt3+0ieu8NCE0fDRaFxEsp31k= +github.com/blevesearch/zapx/v15 v15.4.2/go.mod h1:1pssev/59FsuWcgSnTa0OeEpOzmhtmr/0/11H0Z8+Nw= +github.com/blevesearch/zapx/v16 v16.2.4 h1:tGgfvleXTAkwsD5mEzgM3zCS/7pgocTCnO1oyAUjlww= +github.com/blevesearch/zapx/v16 v16.2.4/go.mod h1:Rti/REtuuMmzwsI8/C/qIzRaEoSK/wiFYw5e5ctUKKs= +github.com/bmatcuk/doublestar/v4 v4.9.1 h1:X8jg9rRZmJd4yRy7ZeNDRnM+T3ZfHv15JiBJ/avrEXE= +github.com/bmatcuk/doublestar/v4 v4.9.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bmizerany/perks v0.0.0-20141205001514-d9a9656a3a4b/go.mod h1:ac9efd0D1fsDb3EJvhqgXRbFx7bs2wqZ10HQPeU8U/Q= +github.com/bodgit/plumbing v1.3.0 h1:pf9Itz1JOQgn7vEOE7v7nlEfBykYqvUYioC61TwWCFU= +github.com/bodgit/plumbing v1.3.0/go.mod h1:JOTb4XiRu5xfnmdnDJo6GmSbSbtSyufrsyZFByMtKEs= +github.com/bodgit/sevenzip v1.6.0 h1:a4R0Wu6/P1o1pP/3VV++aEOcyeBxeO/xE2Y9NSTrr6A= +github.com/bodgit/sevenzip v1.6.0/go.mod h1:zOBh9nJUof7tcrlqJFv1koWRrhz3LbDbUNngkuZxLMc= +github.com/bodgit/windows v1.0.1 h1:tF7K6KOluPYygXa3Z2594zxlkbKPAOvqr97etrGNIz4= +github.com/bodgit/windows v1.0.1/go.mod h1:a6JLwrB4KrTR5hBpp8FI9/9W9jJfeQ2h4XDXU74ZCdM= github.com/bohde/codel v0.2.0 h1:fzF7ibgKmCfQbOzQCblmQcwzDRmV7WO7VMLm/hDvD3E= github.com/bohde/codel v0.2.0/go.mod h1:Idb1IRvTdwkRjIjguLIo+FXhIBhcpGl94o7xra6ggWk= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/boombuler/barcode v1.0.2 h1:79yrbttoZrLGkL/oOI8hBrUKucwOL0oOjUgEguGMcJ4= -github.com/boombuler/barcode v1.0.2/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boombuler/barcode v1.1.0 h1:ChaYjBR63fr4LFyGn8E8nt7dBSt3MiU3zMOZqFvVkHo= +github.com/boombuler/barcode v1.1.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I= github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= @@ -185,10 +210,11 @@ github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/buildkite/terminal-to-html/v3 v3.16.8 h1:QN/daUob6cmK8GcdKnwn9+YTlPr1vNj+oeAIiJK6fPc= github.com/buildkite/terminal-to-html/v3 v3.16.8/go.mod h1:+k1KVKROZocrTLsEQ9PEf9A+8+X8uaVV5iO1ZIOwKYM= -github.com/caddyserver/certmagic v0.23.0 h1:CfpZ/50jMfG4+1J/u2LV6piJq4HOfO6ppOnOf7DkFEU= -github.com/caddyserver/certmagic v0.23.0/go.mod h1:9mEZIWqqWoI+Gf+4Trh04MOVPD0tGSxtqsxg87hAIH4= +github.com/caddyserver/certmagic v0.24.0 h1:EfXTWpxHAUKgDfOj6MHImJN8Jm4AMFfMT6ITuKhrDF0= +github.com/caddyserver/certmagic v0.24.0/go.mod h1:xPT7dC1DuHHnS2yuEQCEyks+b89sUkMENh8dJF+InLE= github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA= github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a h1:MISbI8sU/PSK/ztvmWKFcI7UGb5/HQT7B+i3a2myKgI= github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a/go.mod h1:2GxOXOlEPAMFPfp014mK1SWq8G8BN8o7/dfYqJrVGn8= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -198,9 +224,13 @@ github.com/chi-middleware/proxy v1.1.1/go.mod h1:jQwMEJct2tz9VmtCELxvnXoMfa+SOdi github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs= github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -215,8 +245,8 @@ github.com/couchbase/goutils v0.1.2 h1:gWr8B6XNWPIhfalHNog3qQKfGiYyh4K4VhO3P2o9B github.com/couchbase/goutils v0.1.2/go.mod h1:h89Ek/tiOxxqjz30nPPlwZdQbdB8BwgnuBxeoUe/ViE= github.com/couchbase/moss v0.1.0/go.mod h1:9MaHIaRuy9pvLPUJxB8sh8OrLfyDczECVL37grCIubs= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= -github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= +github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= @@ -240,8 +270,8 @@ github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55k github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -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/compress v0.0.2-0.20230904184137-39efe44ab707 h1:2tV76y6Q9BB+NEBasnqvs7e49aEBFI8ejC89PSnWH+4= +github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s= github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= @@ -260,6 +290,8 @@ github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6/go.mod h1:iL2twTe github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ethantkoenig/rupture v1.0.1 h1:6aAXghmvtnngMgQzy7SMGdicMvkV86V4n9fT0meE5E4= github.com/ethantkoenig/rupture v1.0.1/go.mod h1:Sjqo/nbffZp1pVVXNGhpugIjsWmuS9KiIB4GtpEBur4= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= @@ -272,27 +304,27 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU= -github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/git-lfs/pktline v0.0.0-20230103162542-ca444d533ef1 h1:mtDjlmloH7ytdblogrMz1/8Hqua1y8B4ID+bh3rvod0= github.com/git-lfs/pktline v0.0.0-20230103162542-ca444d533ef1/go.mod h1:fenKRzpXDjNpsIBhuhUzvjCKlDjKam0boRAenTE0Q6A= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= 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/activitypub v0.0.0-20250409143848-7113328b1f3d h1:IWrWGnmKzpHqginJ18ljKkty/X8glxM8Mg3pk6bkb8g= -github.com/go-ap/activitypub v0.0.0-20250409143848-7113328b1f3d/go.mod h1:EUtZuXtHo4yKkTJmcbAZYW+X1G2poeT8icmBh24eq7o= -github.com/go-ap/errors v0.0.0-20250409143711-5686c11ae650 h1:tlwla5IQUea0CuktkBd2FLDwVzts4OeTWPPkhQPSK5Q= -github.com/go-ap/errors v0.0.0-20250409143711-5686c11ae650/go.mod h1:Vkh+Z3f24K8nMsJKXo1FHn5ebPsXvB/WDH5JRtYqdNo= +github.com/go-ap/activitypub v0.0.0-20250810115208-cb73b20a1742 h1:X+SsQlZSgJO0A4d1+nI7+g4axZ8u3iUKPirYb5nB5ic= +github.com/go-ap/activitypub v0.0.0-20250810115208-cb73b20a1742/go.mod h1:0rgUaERG5qjYenwz4oN5OnUjvkdRuHRjb+2c8FRjz+w= +github.com/go-ap/errors v0.0.0-20250527110557-c8db454e53fd h1:fM5mNIWTPoxoOYoTLd6ifkKXSlXa830l5MYXsrt1UmE= +github.com/go-ap/errors v0.0.0-20250527110557-c8db454e53fd/go.mod h1:Vkh+Z3f24K8nMsJKXo1FHn5ebPsXvB/WDH5JRtYqdNo= github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73 h1:GMKIYXyXPGIp+hYiWOhfqK4A023HdgisDT4YGgf99mw= github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73/go.mod h1:jyveZeGw5LaADntW+UEsMjl3IlIwk+DxlYNsbofQkGA= github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo= github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618= -github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= -github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= -github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= +github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE= +github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= +github.com/go-chi/cors v1.2.2 h1:Jmey33TE+b+rB7fT8MUy1u0I4L+NARQlK6LhzKPSyQE= +github.com/go-chi/cors v1.2.2/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0= github.com/go-co-op/gocron v1.37.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY= github.com/go-enry/go-enry/v2 v2.9.2 h1:giOQAtCgBX08kosrX818DCQJTCNtKwoPBGu0qb6nKTY= @@ -307,8 +339,10 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.16.0 h1:k3kuOEpkc0DeY7xlL6NaaNg39xdgQbtH5mwCafHO9AQ= -github.com/go-git/go-git/v5 v5.16.0/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= +github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM= +github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= +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-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-ldap/ldap/v3 v3.4.11 h1:4k0Yxweg+a3OyBLjdYn5OKglv18JNvfDykSoI8bW0gU= @@ -321,15 +355,15 @@ github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-redsync/redsync/v4 v4.13.0 h1:49X6GJfnbLGaIpBBREM/zA4uIMDXKAh1NDkvQ1EkZKA= github.com/go-redsync/redsync/v4 v4.13.0/go.mod h1:HMW4Q224GZQz6x1Xc7040Yfgacukdzu7ifTDAKiyErQ= -github.com/go-sql-driver/mysql v1.9.2 h1:4cNKDYQ1I84SXslGddlsrMhc8k4LeDVj6Ad6WRjiHuU= -github.com/go-sql-driver/mysql v1.9.2/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= +github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= +github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/go-webauthn/webauthn v0.12.3 h1:hHQl1xkUuabUU9uS+ISNCMLs9z50p9mDUZI/FmkayNE= -github.com/go-webauthn/webauthn v0.12.3/go.mod h1:4JRe8Z3W7HIw8NGEWn2fnUwecoDzkkeach/NnvhkqGY= -github.com/go-webauthn/x v0.1.20 h1:brEBDqfiPtNNCdS/peu8gARtq8fIPsHz0VzpPjGvgiw= -github.com/go-webauthn/x v0.1.20/go.mod h1:n/gAc8ssZJGATM0qThE+W+vfgXiMedsWi3wf/C4lld0= +github.com/go-webauthn/webauthn v0.13.4 h1:q68qusWPcqHbg9STSxBLBHnsKaLxNO0RnVKaAqMuAuQ= +github.com/go-webauthn/webauthn v0.13.4/go.mod h1:MglN6OH9ECxvhDqoq1wMoF6P6JRYDiQpC9nc5OomQmI= +github.com/go-webauthn/x v0.1.24 h1:6LaWf2zzWqbyKT8IyQkhje1/1KCGhlEkMz4V1tDnt/A= +github.com/go-webauthn/x v0.1.24/go.mod h1:2o5XKJ+X1AKqYKGgHdKflGnoQFQZ6flJ2IFCBKSbSOw= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= @@ -341,19 +375,28 @@ github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f h1:3BSP1Tbs2djlpprl7w github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14= 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.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= -github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= 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.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/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -364,16 +407,18 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws= github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -382,23 +427,30 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-github/v71 v71.0.0 h1:Zi16OymGKZZMm8ZliffVVJ/Q9YZreDKONCr+WUd0Z30= -github.com/google/go-github/v71 v71.0.0/go.mod h1:URZXObp2BLlMjwu0O8g4y6VBneUj2bCHgnI8FfgZ51M= +github.com/google/go-github/v74 v74.0.0 h1:yZcddTUn8DPbj11GxnMrNiAnXH14gNs559AsUpNpPgM= +github.com/google/go-github/v74 v74.0.0/go.mod h1:ubn/YdyftV80VPSI26nSJvaEsTOnsjrxG3o9kJhcyak= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/go-tpm v0.9.3 h1:+yx0/anQuGzi+ssRqeD6WpXjW2L/V0dItUayO0i9sRc= -github.com/google/go-tpm v0.9.3/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm v0.9.5 h1:ocUmnDebX54dnW+MQWGQRbdaAcJELsa6PqZhJ48KwVU= +github.com/google/go-tpm v0.9.5/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/licenseclassifier/v2 v2.0.0 h1:1Y57HHILNf4m0ABuMVb6xk4vAJYEUO0gDxNpog0pyeA= github.com/google/licenseclassifier/v2 v2.0.0/go.mod h1:cOjbdH0kyC9R22sdQbYsFkto4NGCAc+ZSwbeThazEtM= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/google/pprof v0.0.0-20250422154841-e1f9c1950416 h1:1/qwHx8P72glDXdyCKesJ+/c40x71SY4q2avOxJ2iYQ= -github.com/google/pprof v0.0.0-20250422154841-e1f9c1950416/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA= +github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 h1:EEHtgt9IwisQ2AZ4pIsMjahcegHh6rmhqxzIRQIyepY= +github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/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/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99 h1:twflg0XRTjwKpxb/jFExr4HGq6on2dEOmnL6FV+fgPw= github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -427,10 +479,12 @@ github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB1 github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= -github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= +github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48= +github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= @@ -439,10 +493,9 @@ github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSo github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 h1:iCHtR9CQyktQ5+f3dMVZfwD2KWJUgm7M0gdL9NGr8KA= -github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= @@ -463,22 +516,23 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= -github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kevinburke/ssh_config v1.4.0 h1:6xxtP5bZ2E4NF5tuQulISpTO2z8XbtH8cg1PWkxoFkQ= +github.com/kevinburke/ssh_config v1.4.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= 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.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= -github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= -github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/kljensen/snowball v0.6.0/go.mod h1:27N7E8fVU5H68RlUmnWwZCfxgt4POBJfENGMvNRhldw= @@ -496,43 +550,48 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+ github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/libdns/libdns v1.0.0-beta.1 h1:KIf4wLfsrEpXpZ3vmc/poM8zCATXT2klbdPe6hyOBjQ= -github.com/libdns/libdns v1.0.0-beta.1/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= +github.com/libdns/libdns v1.1.1 h1:wPrHrXILoSHKWJKGd0EiAVmiJbFShguILTg9leS/P/U= +github.com/libdns/libdns v1.1.1/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/markbates/going v1.0.3 h1:mY45T5TvW+Xz5A6jY7lf4+NLg9D8+iuStIHyR7M8qsE= github.com/markbates/going v1.0.3/go.mod h1:fQiT6v6yQar9UD6bd/D4Z5Afbk9J6BBVBtLiyY4gp2o= -github.com/markbates/goth v1.81.0 h1:XVcCkeGWokynPV7MXvgb8pd2s3r7DS40P7931w6kdnE= -github.com/markbates/goth v1.81.0/go.mod h1:+6z31QyUms84EHmuBY7iuqYSxyoN3njIgg9iCF/lR1k= +github.com/markbates/goth v1.82.0 h1:8j/c34AjBSTNzO7zTsOyP5IYCQCMBTRBHAbBt/PI0bQ= +github.com/markbates/goth v1.82.0/go.mod h1:/DRlcq0pyqkKToyZjsL2KgiA1zbF1HIjE7u2uC79rUk= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A= -github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/meilisearch/meilisearch-go v0.31.0 h1:yZRhY1qJqdH8h6GFZALGtkDLyj8f9v5aJpsNMyrUmnY= -github.com/meilisearch/meilisearch-go v0.31.0/go.mod h1:aNtyuwurDg/ggxQIcKqWH6G9g2ptc8GyY7PLY4zMn/g= +github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= +github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/meilisearch/meilisearch-go v0.33.2 h1:YgsQSLYhAkRN2ias6I1KNRTjdYCN5w2uHbLUQ+xgrws= +github.com/meilisearch/meilisearch-go v0.33.2/go.mod h1:6eOPcQ+OAuwXvnONlfSgfgvr7TIAWM/6OdhcVHg8cF0= github.com/mholt/acmez/v3 v3.1.2 h1:auob8J/0FhmdClQicvJvuDavgd5ezwLBfKuYmynhYzc= github.com/mholt/acmez/v3 v3.1.2/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= +github.com/mholt/archives v0.1.3 h1:aEAaOtNra78G+TvV5ohmXrJOAzf++dIlYeDW3N9q458= +github.com/mholt/archives v0.1.3/go.mod h1:LUCGp++/IbV/I0Xq4SzcIR6uwgeh2yjnQWamjRQfLTU= github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= -github.com/microsoft/go-mssqldb v1.8.0 h1:7cyZ/AT7ycDsEoWPIXibd+aVKFtteUNhDGf3aobP+tw= -github.com/microsoft/go-mssqldb v1.8.0/go.mod h1:6znkekS3T2vp0waiMhen4GPU1BiAsrP+iXHcE7a7rFo= -github.com/miekg/dns v1.1.65 h1:0+tIPHzUW0GCge7IiK3guGP57VAw7hoPDfApjkMD1Fc= -github.com/miekg/dns v1.1.65/go.mod h1:Dzw9769uoKVaLuODMDZz9M6ynFU6Em65csPuoi8G0ck= -github.com/minio/crc64nvme v1.0.1 h1:DHQPrYPdqK7jQG/Ls5CTBZWeex/2FMS3G5XGkycuFrY= -github.com/minio/crc64nvme v1.0.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg= +github.com/microsoft/go-mssqldb v1.9.3 h1:hy4p+LDC8LIGvI3JATnLVmBOLMJbmn5X400mr5j0lPs= +github.com/microsoft/go-mssqldb v1.9.3/go.mod h1:GBbW9ASTiDC+mpgWDGKdm3FnFLTUsLYN3iFL90lQ+PA= +github.com/miekg/dns v1.1.68 h1:jsSRkNozw7G/mnmXULynzMNIsgY2dHC8LO6U6Ij2JEA= +github.com/miekg/dns v1.1.68/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps= +github.com/mikelolasagasti/xz v1.0.1 h1:Q2F2jX0RYJUG3+WsM+FJknv+6eVjsjXNDV0KJXZzkD0= +github.com/mikelolasagasti/xz v1.0.1/go.mod h1:muAirjiOUxPRXwm9HdDtB3uoRPrGnL85XHtokL9Hcgc= +github.com/minio/crc64nvme v1.1.1 h1:8dwx/Pz49suywbO+auHCBpCtlW1OfpcLN7wYgVR6wAI= +github.com/minio/crc64nvme v1.1.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg= 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.91 h1:tWLZnEfo3OZl5PoXQwcwTAPNNrjyWwOh6cbZitW5JQc= -github.com/minio/minio-go/v7 v7.0.91/go.mod h1:uvMUcGrpgeSAAI6+sD3818508nUyMULw94j2Nxku/Go= +github.com/minio/minio-go/v7 v7.0.95 h1:ywOUPg+PebTMTzn9VDsoFJy32ZuARN9zhB+K3IYEvYU= +github.com/minio/minio-go/v7 v7.0.95/go.mod h1:wOOX3uxS334vImCNRVyIDdXX9OsXDm89ToynKgqUKlo= +github.com/minio/minlz v1.0.0 h1:Kj7aJZ1//LlTP1DM8Jm7lNKvvJS2m74gyyXXn3+uJWQ= +github.com/minio/minlz v1.0.0/go.mod h1:qT0aEB35q79LLornSzeDH75LBf3aH1MV+jB5w9Wasec= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -551,16 +610,21 @@ github.com/msteinert/pam v1.2.0 h1:mYfjlvN2KYs2Pb9G6nb/1f/nPfAttT/Jee5Sq9r3bGE= github.com/msteinert/pam v1.2.0/go.mod h1:d2n0DCUK8rGecChV3JzvmsDjOY4R7AYbsNxAT+ftQl0= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/niklasfasching/go-org v1.8.0 h1:WyGLaajLLp8JbQzkmapZ1y0MOzKuKV47HkZRloi+HGY= -github.com/niklasfasching/go-org v1.8.0/go.mod h1:e2A9zJs7cdONrEGs3gvxCcaAEpwwPNPG7csDpXckMNg= -github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= -github.com/nwaples/rardecode v1.1.3 h1:cWCaZwfM5H7nAD6PyEdcVnczzV8i/JtotnyW/dD9lEc= -github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= +github.com/niklasfasching/go-org v1.9.1 h1:/3s4uTPOF06pImGa2Yvlp24yKXZoTYM+nsIlMzfpg/0= +github.com/niklasfasching/go-org v1.9.1/go.mod h1:ZAGFFkWvUQcpazmi/8nHqwvARpr1xpb+Es67oUGX/48= +github.com/nwaples/rardecode/v2 v2.1.0 h1:JQl9ZoBPDy+nIZGb1mx8+anfHp/LV3NE2MjMiv0ct/U= +github.com/nwaples/rardecode/v2 v2.1.0/go.mod h1:7uz379lSxPe6j9nvzxUZ+n7mnJNgjsRNb6IbvGVHRmw= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/olekukonko/cat v0.0.0-20250817074551-3280053e4e00 h1:ZCnkxe9GgWqqBxAk3cIKlQJuaqgOUF/nUtQs8flVTHM= +github.com/olekukonko/cat v0.0.0-20250817074551-3280053e4e00/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0= +github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM= +github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y= +github.com/olekukonko/ll v0.1.0 h1:7nX5bgpvfyxsvI90IJpOIU5zd4MBV6nRkD49e/dEx98= +github.com/olekukonko/ll v0.1.0/go.mod h1:2dJo+hYZcJMLMbKwHEWvxCUbAOLc/CXWS9noET22Mdo= +github.com/olekukonko/tablewriter v1.0.9 h1:XGwRsYLC2bY7bNd93Dk51bcPZksWZmLYuaTHR0FqfL8= +github.com/olekukonko/tablewriter v1.0.9/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo= github.com/olivere/elastic/v7 v7.0.32 h1:R7CXvbu8Eq+WlsLgxmKVKPox0oOwAE/2T9Si5BnvK6E= github.com/olivere/elastic/v7 v7.0.32/go.mod h1:c7PVmLe3Fxq77PIfY/bZmxY/TAamBhCzZ8xDOE09a9k= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -580,11 +644,12 @@ github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgr github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= +github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= -github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= +github.com/pjbgf/sha1cd v0.4.0 h1:NXzbL1RvjTUi6kgYZCX3fPwwl27Q1LJndxtUDVfJGRY= +github.com/pjbgf/sha1cd v0.4.0/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -593,21 +658,22 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg= -github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= -github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= -github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= +github.com/pquerna/otp v1.5.0 h1:NMMR+WrmaqXU4EzdGJEE1aUUI0AMRzsp96fFFWNPwxs= +github.com/pquerna/otp v1.5.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= +github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc= +github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= -github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE= +github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= +github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= +github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= github.com/quasoft/websspi v1.1.2 h1:/mA4w0LxWlE3novvsoEL6BBA1WnjJATbjkh1kFrTidw= github.com/quasoft/websspi v1.1.2/go.mod h1:HmVdl939dQ0WIXZhyik+ARdI03M6bQzaSEKcgpFmewk= github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM= -github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA= +github.com/redis/go-redis/v9 v9.12.1 h1:k5iquqv27aBtnTm2tIkROUDp8JBXhXZIVu1InSgvovg= +github.com/redis/go-redis/v9 v9.12.1/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= github.com/redis/rueidis v1.0.19 h1:s65oWtotzlIFN8eMPhyYwxlwLR1lUdhza2KtWprKYSo= github.com/redis/rueidis v1.0.19/go.mod h1:8B+r5wdnjwK3lTFml5VtxjzGOQAC+5UmujoD12pDrEo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= @@ -620,6 +686,7 @@ github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= +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/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -629,14 +696,15 @@ github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= 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/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sassoftware/go-rpmutils v0.4.0 h1:ojND82NYBxgwrV+mX1CWsd5QJvvEZTKddtCdFLPWhpg= github.com/sassoftware/go-rpmutils v0.4.0/go.mod h1:3goNWi7PGAT3/dlql2lv3+MSN5jNYPjT5mVcQcIsYzI= github.com/serenize/snaker v0.0.0-20171204205717-a683aaf2d516/go.mod h1:Yow6lPLSAXx2ifx470yD/nUe22Dv5vBvxK/UK9UUTVs= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= +github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= @@ -648,6 +716,8 @@ github.com/smartystreets/assertions v1.1.1/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYl github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/sorairolake/lzip-go v0.3.5 h1:ms5Xri9o1JBIWvOFAorYtUNik6HI3HgBTkISiqu0Cwg= +github.com/sorairolake/lzip-go v0.3.5/go.mod h1:N0KYq5iWrMXI0ZEXKXaS9hCyOjZUQdBDEIbXfoUwbdk= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= @@ -672,26 +742,28 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203 h1:QVqDTf3h2WHt08YuiTGPZLls0Wq99X9bWd0Q5ZSBesM= github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203/go.mod h1:oqN97ltKNihBbwlX8dLpwxCl3+HnXKV/R0e+sRLd9C8= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tinylib/msgp v1.4.0 h1:SYOeDRiydzOw9kSiwdYp9UcBgPFtLU2WDHaJXyHruf8= +github.com/tinylib/msgp v1.4.0/go.mod h1:cvjFkb4RiC8qSBOPMGPSzSAx47nAsfhLVTCZZNuHv5o= github.com/tstranex/u2f v1.0.0 h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ= github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGBSayo= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= -github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY= +github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= 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/urfave/cli-docs/v3 v3.0.0-alpha6 h1:w/l/N0xw1rO/aHRIGXJ0lDwwYFOzilup1qGvIytP3BI= github.com/urfave/cli-docs/v3 v3.0.0-alpha6/go.mod h1:p7Z4lg8FSTrPB9GTaNyTrK3ygffHZcK3w0cU2VE+mzU= -github.com/urfave/cli/v3 v3.3.3 h1:byCBaVdIXuLPIDm5CYZRVG6NvT7tv1ECqdU4YzlEa3I= -github.com/urfave/cli/v3 v3.3.3/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo= +github.com/urfave/cli/v3 v3.4.1 h1:1M9UOCy5bLmGnuu1yn3t3CB4rG79Rtoxuv1sPhnm6qM= +github.com/urfave/cli/v3 v3.4.1/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo= github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ= github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= @@ -719,8 +791,8 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/goldmark v1.7.10 h1:S+LrtBjRmqMac2UdtB6yyCEJm+UILZ2fefI4p7o0QpI= -github.com/yuin/goldmark v1.7.10/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= +github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= +github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+IAOyRda+RLrxa1WC7umKOZRsGq4QrFFMYApOeHzQwQ= github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I= github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc= @@ -731,11 +803,15 @@ github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= -gitlab.com/gitlab-org/api/client-go v0.127.0 h1:8xnxcNKGF2gDazEoMs+hOZfOspSSw8D0vAoWhQk9U+U= -gitlab.com/gitlab-org/api/client-go v0.127.0/go.mod h1:bYC6fPORKSmtuPRyD9Z2rtbAjE7UeNatu2VWHRf4/LE= +gitlab.com/gitlab-org/api/client-go v0.142.4 h1:tTm+hUPrOcTavmKpM9YIP503IE0EdAkg4TG3t6QGbiw= +gitlab.com/gitlab-org/api/client-go v0.142.4/go.mod h1:Ru5IRauphXt9qwmTzJD7ou1dH7Gc6pnsdFWEiMMpmB0= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= -go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk= -go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk= +go.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo= +go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= @@ -747,8 +823,12 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.uber.org/zap/exp v0.3.0 h1:6JYzdifzYkGmTdRR59oYH+Ng7k49H9qVpWwNSsGJj3U= go.uber.org/zap/exp v0.3.0/go.mod h1:5I384qq7XGxYyByIhHm6jg5CHkGY0nsTfbDLgDDlgJQ= +go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc= +go4.org v0.0.0-20230225012048-214862532bf5/go.mod h1:F57wTi5Lrj6WLyswp5EYV1ncrEbFGHD4hhz6S1ZYeaU= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/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-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= @@ -760,13 +840,36 @@ golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= -golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= -golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= +golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw= golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM= -golang.org/x/image v0.26.0 h1:4XjIFEZWQmCZi6Wv8BoxsDhRU3RVnLX04dToTDAEPlY= -golang.org/x/image v0.26.0/go.mod h1:lcxbMFAovzpnJxzXS3nyL83K27tmqtKzIJpctK8YO5c= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.30.0 h1:jD5RhkmVAnjqaCUXfbGBrn3lpxbknfN9w2UhHHU+5B4= +golang.org/x/image v0.30.0/go.mod h1:SAEUTxCCMWSrJcCy/4HwavEsfZZJlYxeHLc6tTiAe/c= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -775,11 +878,22 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= -golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= +golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -794,11 +908,19 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= -golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98= -golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -811,20 +933,30 @@ golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= -golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/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-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -845,8 +977,8 @@ golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -858,9 +990,12 @@ golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= -golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= -golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= +golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= +golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +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= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -871,13 +1006,36 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200928182047-19e03678916f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -885,24 +1043,57 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= -golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= +golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= +golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= 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= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250422160041-2d3770c4ea7f h1:N/PrbTw4kdkqNRzVfWPrBekzLuarFREcbFOiOLkXon4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250422160041-2d3770c4ea7f/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.72.0 h1:S7UkcVa60b5AAQTaO6ZKamFp1zMZSU0fGDK2WZLbBnM= -google.golang.org/grpc v1.72.0/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1 h1:pmJpJEvT846VzausCQ5d7KreSROcDqmO388w5YbnltA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -927,6 +1118,11 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C 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-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw= @@ -951,6 +1147,9 @@ mvdan.cc/xurls/v2 v2.6.0 h1:3NTZpeTxYVWNSokW3MKeyVkz/j7uYXYiMtXRUfmjbgI= mvdan.cc/xurls/v2 v2.6.0/go.mod h1:bCvEZ1XvdA6wDnxY7jPPjEmigDtvtvPXAD/Exa9IMSk= pgregory.net/rapid v0.4.2 h1:lsi9jhvZTYvzVpeG93WWgimPRmiJQfGFRNTEZh1dtY0= pgregory.net/rapid v0.4.2/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 h1:mUcz5b3FJbP5Cvdq7Khzn6J9OCUQJaBwgBkCR+MOwSs= strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:FJGmPh3vz9jSos1L/F91iAgnC/aejc0wIIrF2ZwJxdY= xorm.io/builder v0.3.13 h1:a3jmiVVL19psGeXx8GIurTp7p0IIgqeDmwhcR6BAOAo= diff --git a/models/actions/runner_token_test.go b/models/actions/runner_token_test.go index 21614b7086..243d6716a0 100644 --- a/models/actions/runner_token_test.go +++ b/models/actions/runner_token_test.go @@ -6,7 +6,6 @@ package actions import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert" @@ -15,16 +14,16 @@ import ( func TestGetLatestRunnerToken(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) token := unittest.AssertExistsAndLoadBean(t, &ActionRunnerToken{ID: 3}) - expectedToken, err := GetLatestRunnerToken(db.DefaultContext, 1, 0) + expectedToken, err := GetLatestRunnerToken(t.Context(), 1, 0) assert.NoError(t, err) assert.Equal(t, expectedToken, token) } func TestNewRunnerToken(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - token, err := NewRunnerToken(db.DefaultContext, 1, 0) + token, err := NewRunnerToken(t.Context(), 1, 0) assert.NoError(t, err) - expectedToken, err := GetLatestRunnerToken(db.DefaultContext, 1, 0) + expectedToken, err := GetLatestRunnerToken(t.Context(), 1, 0) assert.NoError(t, err) assert.Equal(t, expectedToken, token) } @@ -33,8 +32,8 @@ func TestUpdateRunnerToken(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) token := unittest.AssertExistsAndLoadBean(t, &ActionRunnerToken{ID: 3}) token.IsActive = true - assert.NoError(t, UpdateRunnerToken(db.DefaultContext, token)) - expectedToken, err := GetLatestRunnerToken(db.DefaultContext, 1, 0) + assert.NoError(t, UpdateRunnerToken(t.Context(), token)) + expectedToken, err := GetLatestRunnerToken(t.Context(), 1, 0) assert.NoError(t, err) assert.Equal(t, expectedToken, token) } diff --git a/models/activities/action.go b/models/activities/action.go index 1a0dfe6412..8e589eda88 100644 --- a/models/activities/action.go +++ b/models/activities/action.go @@ -320,7 +320,7 @@ func (a *Action) GetCommentHTMLURL(ctx context.Context) string { return "#" } - return a.Issue.HTMLURL() + return a.Issue.HTMLURL(ctx) } // GetCommentLink returns link to action comment. diff --git a/models/activities/action_test.go b/models/activities/action_test.go index ff311ac891..9447f39d62 100644 --- a/models/activities/action_test.go +++ b/models/activities/action_test.go @@ -25,7 +25,7 @@ func TestAction_GetRepoPath(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) action := &activities_model.Action{RepoID: repo.ID} - assert.Equal(t, path.Join(owner.Name, repo.Name), action.GetRepoPath(db.DefaultContext)) + assert.Equal(t, path.Join(owner.Name, repo.Name), action.GetRepoPath(t.Context())) } func TestAction_GetRepoLink(t *testing.T) { @@ -37,9 +37,9 @@ func TestAction_GetRepoLink(t *testing.T) { defer test.MockVariableValue(&setting.AppURL, "https://try.gitea.io/suburl/")() defer test.MockVariableValue(&setting.AppSubURL, "/suburl")() expected := path.Join(setting.AppSubURL, owner.Name, repo.Name) - assert.Equal(t, expected, action.GetRepoLink(db.DefaultContext)) - assert.Equal(t, repo.HTMLURL(), action.GetRepoAbsoluteLink(db.DefaultContext)) - assert.Equal(t, comment.HTMLURL(db.DefaultContext), action.GetCommentHTMLURL(db.DefaultContext)) + assert.Equal(t, expected, action.GetRepoLink(t.Context())) + assert.Equal(t, repo.HTMLURL(), action.GetRepoAbsoluteLink(t.Context())) + assert.Equal(t, comment.HTMLURL(t.Context()), action.GetCommentHTMLURL(t.Context())) } func TestActivityReadable(t *testing.T) { @@ -91,37 +91,37 @@ func TestConsistencyUpdateAction(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ ID: int64(id), }) - _, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = '' WHERE id = ?`, id) + _, err := db.GetEngine(t.Context()).Exec(`UPDATE action SET created_unix = '' WHERE id = ?`, id) assert.NoError(t, err) actions := make([]*activities_model.Action, 0, 1) // // XORM returns an error when created_unix is a string // - err = db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions) + err = db.GetEngine(t.Context()).Where("id = ?", id).Find(&actions) if assert.Error(t, err) { assert.Contains(t, err.Error(), "type string to a int64: invalid syntax") } // // Get rid of incorrectly set created_unix // - count, err := activities_model.CountActionCreatedUnixString(db.DefaultContext) + count, err := activities_model.CountActionCreatedUnixString(t.Context()) assert.NoError(t, err) assert.EqualValues(t, 1, count) - count, err = activities_model.FixActionCreatedUnixString(db.DefaultContext) + count, err = activities_model.FixActionCreatedUnixString(t.Context()) assert.NoError(t, err) assert.EqualValues(t, 1, count) - count, err = activities_model.CountActionCreatedUnixString(db.DefaultContext) + count, err = activities_model.CountActionCreatedUnixString(t.Context()) assert.NoError(t, err) assert.EqualValues(t, 0, count) - count, err = activities_model.FixActionCreatedUnixString(db.DefaultContext) + count, err = activities_model.FixActionCreatedUnixString(t.Context()) assert.NoError(t, err) assert.EqualValues(t, 0, count) // // XORM must be happy now // - assert.NoError(t, db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions)) + assert.NoError(t, db.GetEngine(t.Context()).Where("id = ?", id).Find(&actions)) unittest.CheckConsistencyFor(t, &activities_model.Action{}) } @@ -133,19 +133,19 @@ func TestDeleteIssueActions(t *testing.T) { assert.NotEqual(t, issue.ID, issue.Index) // it needs to use different ID/Index to test the DeleteIssueActions to delete some actions by IssueIndex // insert a comment - err := db.Insert(db.DefaultContext, &issue_model.Comment{Type: issue_model.CommentTypeComment, IssueID: issue.ID}) + err := db.Insert(t.Context(), &issue_model.Comment{Type: issue_model.CommentTypeComment, IssueID: issue.ID}) assert.NoError(t, err) comment := unittest.AssertExistsAndLoadBean(t, &issue_model.Comment{Type: issue_model.CommentTypeComment, IssueID: issue.ID}) // truncate action table and insert some actions - err = db.TruncateBeans(db.DefaultContext, &activities_model.Action{}) + err = db.TruncateBeans(t.Context(), &activities_model.Action{}) assert.NoError(t, err) - err = db.Insert(db.DefaultContext, &activities_model.Action{ + err = db.Insert(t.Context(), &activities_model.Action{ OpType: activities_model.ActionCommentIssue, CommentID: comment.ID, }) assert.NoError(t, err) - err = db.Insert(db.DefaultContext, &activities_model.Action{ + err = db.Insert(t.Context(), &activities_model.Action{ OpType: activities_model.ActionCreateIssue, RepoID: issue.RepoID, Content: fmt.Sprintf("%d|content...", issue.Index), @@ -154,6 +154,6 @@ func TestDeleteIssueActions(t *testing.T) { // assert that the actions exist, then delete them unittest.AssertCount(t, &activities_model.Action{}, 2) - assert.NoError(t, activities_model.DeleteIssueActions(db.DefaultContext, issue.RepoID, issue.ID, issue.Index)) + assert.NoError(t, activities_model.DeleteIssueActions(t.Context(), issue.RepoID, issue.ID, issue.Index)) unittest.AssertCount(t, &activities_model.Action{}, 0) } diff --git a/models/activities/notification.go b/models/activities/notification.go index 6dde26fd53..b482e6020a 100644 --- a/models/activities/notification.go +++ b/models/activities/notification.go @@ -280,11 +280,11 @@ func (n *Notification) HTMLURL(ctx context.Context) string { if n.Comment != nil { return n.Comment.HTMLURL(ctx) } - return n.Issue.HTMLURL() + return n.Issue.HTMLURL(ctx) case NotificationSourceCommit: - return n.Repository.HTMLURL() + "/commit/" + url.PathEscape(n.CommitID) + return n.Repository.HTMLURL(ctx) + "/commit/" + url.PathEscape(n.CommitID) case NotificationSourceRepository: - return n.Repository.HTMLURL() + return n.Repository.HTMLURL(ctx) } return "" } diff --git a/models/activities/notification_test.go b/models/activities/notification_test.go index 5d2a29bc36..6f2253c815 100644 --- a/models/activities/notification_test.go +++ b/models/activities/notification_test.go @@ -20,7 +20,7 @@ func TestCreateOrUpdateIssueNotifications(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) - assert.NoError(t, activities_model.CreateOrUpdateIssueNotifications(db.DefaultContext, issue.ID, 0, 2, 0)) + assert.NoError(t, activities_model.CreateOrUpdateIssueNotifications(t.Context(), issue.ID, 0, 2, 0)) // User 9 is inactive, thus notifications for user 1 and 4 are created notf := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{UserID: 1, IssueID: issue.ID}) @@ -34,7 +34,7 @@ func TestCreateOrUpdateIssueNotifications(t *testing.T) { func TestNotificationsForUser(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - notfs, err := db.Find[activities_model.Notification](db.DefaultContext, activities_model.FindNotificationOptions{ + notfs, err := db.Find[activities_model.Notification](t.Context(), activities_model.FindNotificationOptions{ UserID: user.ID, Status: []activities_model.NotificationStatus{ activities_model.NotificationStatusRead, @@ -55,7 +55,7 @@ func TestNotificationsForUser(t *testing.T) { func TestNotification_GetRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) notf := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{RepoID: 1}) - repo, err := notf.GetRepo(db.DefaultContext) + repo, err := notf.GetRepo(t.Context()) assert.NoError(t, err) assert.Equal(t, repo, notf.Repository) assert.Equal(t, notf.RepoID, repo.ID) @@ -64,7 +64,7 @@ func TestNotification_GetRepo(t *testing.T) { func TestNotification_GetIssue(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) notf := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{RepoID: 1}) - issue, err := notf.GetIssue(db.DefaultContext) + issue, err := notf.GetIssue(t.Context()) assert.NoError(t, err) assert.Equal(t, issue, notf.Issue) assert.Equal(t, notf.IssueID, issue.ID) @@ -73,7 +73,7 @@ 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 := db.Count[activities_model.Notification](db.DefaultContext, activities_model.FindNotificationOptions{ + cnt, err := db.Count[activities_model.Notification](t.Context(), activities_model.FindNotificationOptions{ UserID: user.ID, Status: []activities_model.NotificationStatus{ activities_model.NotificationStatusRead, @@ -82,7 +82,7 @@ func TestGetNotificationCount(t *testing.T) { assert.NoError(t, err) assert.EqualValues(t, 0, cnt) - cnt, err = db.Count[activities_model.Notification](db.DefaultContext, activities_model.FindNotificationOptions{ + cnt, err = db.Count[activities_model.Notification](t.Context(), activities_model.FindNotificationOptions{ UserID: user.ID, Status: []activities_model.NotificationStatus{ activities_model.NotificationStatusUnread, @@ -97,14 +97,14 @@ func TestSetNotificationStatus(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) notf := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusRead}) - _, err := activities_model.SetNotificationStatus(db.DefaultContext, notf.ID, user, activities_model.NotificationStatusPinned) + _, err := activities_model.SetNotificationStatus(t.Context(), notf.ID, user, activities_model.NotificationStatusPinned) assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: notf.ID, Status: activities_model.NotificationStatusPinned}) - _, err = activities_model.SetNotificationStatus(db.DefaultContext, 1, user, activities_model.NotificationStatusRead) + _, err = activities_model.SetNotificationStatus(t.Context(), 1, user, activities_model.NotificationStatusRead) assert.Error(t, err) - _, err = activities_model.SetNotificationStatus(db.DefaultContext, unittest.NonexistentID, user, activities_model.NotificationStatusRead) + _, err = activities_model.SetNotificationStatus(t.Context(), unittest.NonexistentID, user, activities_model.NotificationStatusRead) assert.Error(t, err) } @@ -117,7 +117,7 @@ func TestUpdateNotificationStatuses(t *testing.T) { &activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusRead}) notfPinned := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusPinned}) - assert.NoError(t, activities_model.UpdateNotificationStatuses(db.DefaultContext, user, activities_model.NotificationStatusUnread, activities_model.NotificationStatusRead)) + assert.NoError(t, activities_model.UpdateNotificationStatuses(t.Context(), user, activities_model.NotificationStatusUnread, activities_model.NotificationStatusRead)) unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: notfUnread.ID, Status: activities_model.NotificationStatusRead}) unittest.AssertExistsAndLoadBean(t, @@ -130,11 +130,11 @@ func TestSetIssueReadBy(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) - assert.NoError(t, db.WithTx(db.DefaultContext, func(ctx context.Context) error { + assert.NoError(t, db.WithTx(t.Context(), func(ctx context.Context) error { return activities_model.SetIssueReadBy(ctx, issue.ID, user.ID) })) - nt, err := activities_model.GetIssueNotification(db.DefaultContext, user.ID, issue.ID) + nt, err := activities_model.GetIssueNotification(t.Context(), user.ID, issue.ID) assert.NoError(t, err) assert.Equal(t, activities_model.NotificationStatusRead, nt.Status) } diff --git a/models/activities/user_heatmap_test.go b/models/activities/user_heatmap_test.go index 380045d3c5..66087325b1 100644 --- a/models/activities/user_heatmap_test.go +++ b/models/activities/user_heatmap_test.go @@ -8,7 +8,6 @@ import ( "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" "code.gitea.io/gitea/modules/json" @@ -70,7 +69,7 @@ func TestGetUserHeatmapDataByUser(t *testing.T) { } // get the action for comparison - actions, count, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ + actions, count, err := activities_model.GetFeeds(t.Context(), activities_model.GetFeedsOptions{ RequestedUser: user, Actor: doer, IncludePrivate: true, @@ -80,7 +79,7 @@ func TestGetUserHeatmapDataByUser(t *testing.T) { assert.NoError(t, err) // Get the heatmap and compare - heatmap, err := activities_model.GetUserHeatmapDataByUser(db.DefaultContext, user, doer) + heatmap, err := activities_model.GetUserHeatmapDataByUser(t.Context(), user, doer) var contributions int for _, hm := range heatmap { contributions += int(hm.Contributions) diff --git a/models/asymkey/gpg_key_add.go b/models/asymkey/gpg_key_add.go index 1c7d2c1da2..3969edcc86 100644 --- a/models/asymkey/gpg_key_add.go +++ b/models/asymkey/gpg_key_add.go @@ -72,96 +72,90 @@ func AddGPGKey(ctx context.Context, ownerID int64, content, token, signature str return nil, err } - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return nil, err - } - defer committer.Close() + return db.WithTx2(ctx, func(ctx context.Context) ([]*GPGKey, error) { + keys := make([]*GPGKey, 0, len(ekeys)) - keys := make([]*GPGKey, 0, len(ekeys)) - - verified := false - // Handle provided signature - if signature != "" { - signer, err := openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token), strings.NewReader(signature), nil) - if err != nil { - signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\n"), strings.NewReader(signature), nil) - } - if err != nil { - signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\r\n"), strings.NewReader(signature), nil) - } - if err != nil { - log.Debug("AddGPGKey CheckArmoredDetachedSignature failed: %v", err) - return nil, ErrGPGInvalidTokenSignature{ - ID: ekeys[0].PrimaryKey.KeyIdString(), - Wrapped: err, + verified := false + // Handle provided signature + if signature != "" { + signer, err := openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token), strings.NewReader(signature), nil) + if err != nil { + signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\n"), strings.NewReader(signature), nil) } + if err != nil { + signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\r\n"), strings.NewReader(signature), nil) + } + if err != nil { + log.Debug("AddGPGKey CheckArmoredDetachedSignature failed: %v", err) + return nil, ErrGPGInvalidTokenSignature{ + ID: ekeys[0].PrimaryKey.KeyIdString(), + Wrapped: err, + } + } + ekeys = []*openpgp.Entity{signer} + verified = true } - ekeys = []*openpgp.Entity{signer} - verified = true - } - if len(ekeys) > 1 { - id2key := map[string]*openpgp.Entity{} - newEKeys := make([]*openpgp.Entity, 0, len(ekeys)) - for _, ekey := range ekeys { - id := ekey.PrimaryKey.KeyIdString() - if original, has := id2key[id]; has { - // Coalesce this with the other one - for _, subkey := range ekey.Subkeys { - if subkey.PublicKey == nil { - continue - } - found := false - - for _, originalSubkey := range original.Subkeys { - if originalSubkey.PublicKey == nil { + if len(ekeys) > 1 { + id2key := map[string]*openpgp.Entity{} + newEKeys := make([]*openpgp.Entity, 0, len(ekeys)) + for _, ekey := range ekeys { + id := ekey.PrimaryKey.KeyIdString() + if original, has := id2key[id]; has { + // Coalesce this with the other one + for _, subkey := range ekey.Subkeys { + if subkey.PublicKey == nil { continue } - if originalSubkey.PublicKey.KeyId == subkey.PublicKey.KeyId { - found = true - break + found := false + + for _, originalSubkey := range original.Subkeys { + if originalSubkey.PublicKey == nil { + continue + } + if originalSubkey.PublicKey.KeyId == subkey.PublicKey.KeyId { + found = true + break + } + } + if !found { + original.Subkeys = append(original.Subkeys, subkey) } } - if !found { - original.Subkeys = append(original.Subkeys, subkey) + for name, identity := range ekey.Identities { + if _, has := original.Identities[name]; has { + continue + } + original.Identities[name] = identity } + continue } - for name, identity := range ekey.Identities { - if _, has := original.Identities[name]; has { - continue - } - original.Identities[name] = identity - } - continue + id2key[id] = ekey + newEKeys = append(newEKeys, ekey) } - id2key[id] = ekey - newEKeys = append(newEKeys, ekey) - } - ekeys = newEKeys - } - - for _, ekey := range ekeys { - // Key ID cannot be duplicated. - has, err := db.GetEngine(ctx).Where("key_id=?", ekey.PrimaryKey.KeyIdString()). - Get(new(GPGKey)) - if err != nil { - return nil, err - } else if has { - return nil, ErrGPGKeyIDAlreadyUsed{ekey.PrimaryKey.KeyIdString()} + ekeys = newEKeys } - // Get DB session + for _, ekey := range ekeys { + // Key ID cannot be duplicated. + has, err := db.GetEngine(ctx).Where("key_id=?", ekey.PrimaryKey.KeyIdString()). + Get(new(GPGKey)) + if err != nil { + return nil, err + } else if has { + return nil, ErrGPGKeyIDAlreadyUsed{ekey.PrimaryKey.KeyIdString()} + } - key, err := parseGPGKey(ctx, ownerID, ekey, verified) - if err != nil { - return nil, err - } + key, err := parseGPGKey(ctx, ownerID, ekey, verified) + if err != nil { + return nil, err + } - if err = addGPGKey(ctx, key, content); err != nil { - return nil, err + if err = addGPGKey(ctx, key, content); err != nil { + return nil, err + } + keys = append(keys, key) } - keys = append(keys, key) - } - return keys, committer.Commit() + return keys, nil + }) } diff --git a/models/asymkey/gpg_key_test.go b/models/asymkey/gpg_key_test.go index 408cf15763..4621337f11 100644 --- a/models/asymkey/gpg_key_test.go +++ b/models/asymkey/gpg_key_test.go @@ -232,7 +232,7 @@ Q0KHb+QcycSgbDx0ZAvdIacuKvBBcbxrsmFUI4LR+oIup0G9gUc0roPvr014jYQL =zHo9 -----END PGP PUBLIC KEY BLOCK-----` - keys, err := AddGPGKey(db.DefaultContext, 1, testEmailWithUpperCaseLetters, "", "") + keys, err := AddGPGKey(t.Context(), 1, testEmailWithUpperCaseLetters, "", "") assert.NoError(t, err) if assert.NotEmpty(t, keys) { key := keys[0] @@ -407,12 +407,12 @@ func TestTryGetKeyIDFromSignature(t *testing.T) { func TestParseGPGKey(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.NoError(t, db.Insert(db.DefaultContext, &user_model.EmailAddress{UID: 1, Email: "email1@example.com", IsActivated: true})) + assert.NoError(t, db.Insert(t.Context(), &user_model.EmailAddress{UID: 1, Email: "email1@example.com", IsActivated: true})) // create a key for test email e, err := openpgp.NewEntity("name", "comment", "email1@example.com", nil) require.NoError(t, err) - k, err := parseGPGKey(db.DefaultContext, 1, e, true) + k, err := parseGPGKey(t.Context(), 1, e, true) require.NoError(t, err) assert.NotEmpty(t, k.KeyID) assert.NotEmpty(t, k.Emails) // the key is valid, matches the email @@ -421,7 +421,7 @@ func TestParseGPGKey(t *testing.T) { for _, id := range e.Identities { id.Revocations = append(id.Revocations, &packet.Signature{RevocationReason: util.ToPointer(packet.KeyCompromised)}) } - k, err = parseGPGKey(db.DefaultContext, 1, e, true) + k, err = parseGPGKey(t.Context(), 1, e, true) require.NoError(t, err) assert.NotEmpty(t, k.KeyID) assert.Empty(t, k.Emails) // the key is revoked, matches no email diff --git a/models/asymkey/ssh_key_test.go b/models/asymkey/ssh_key_test.go index 21e4ddf62e..d7f48ada03 100644 --- a/models/asymkey/ssh_key_test.go +++ b/models/asymkey/ssh_key_test.go @@ -12,7 +12,6 @@ import ( "strings" "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/setting" @@ -476,7 +475,7 @@ func runErr(t *testing.T, stdin []byte, args ...string) { func Test_PublicKeysAreExternallyManaged(t *testing.T) { key1 := unittest.AssertExistsAndLoadBean(t, &PublicKey{ID: 1}) - externals, err := PublicKeysAreExternallyManaged(db.DefaultContext, []*PublicKey{key1}) + externals, err := PublicKeysAreExternallyManaged(t.Context(), []*PublicKey{key1}) assert.NoError(t, err) assert.Len(t, externals, 1) assert.False(t, externals[0]) diff --git a/models/auth/access_token_test.go b/models/auth/access_token_test.go index 4360f1a214..9ae072cc5f 100644 --- a/models/auth/access_token_test.go +++ b/models/auth/access_token_test.go @@ -19,7 +19,7 @@ func TestNewAccessToken(t *testing.T) { UID: 3, Name: "Token C", } - assert.NoError(t, auth_model.NewAccessToken(db.DefaultContext, token)) + assert.NoError(t, auth_model.NewAccessToken(t.Context(), token)) unittest.AssertExistsAndLoadBean(t, token) invalidToken := &auth_model.AccessToken{ @@ -27,7 +27,7 @@ func TestNewAccessToken(t *testing.T) { UID: 2, Name: "Token F", } - assert.Error(t, auth_model.NewAccessToken(db.DefaultContext, invalidToken)) + assert.Error(t, auth_model.NewAccessToken(t.Context(), invalidToken)) } func TestAccessTokenByNameExists(t *testing.T) { @@ -40,16 +40,16 @@ func TestAccessTokenByNameExists(t *testing.T) { } // Check to make sure it doesn't exists already - exist, err := auth_model.AccessTokenByNameExists(db.DefaultContext, token) + exist, err := auth_model.AccessTokenByNameExists(t.Context(), token) assert.NoError(t, err) assert.False(t, exist) // Save it to the database - assert.NoError(t, auth_model.NewAccessToken(db.DefaultContext, token)) + assert.NoError(t, auth_model.NewAccessToken(t.Context(), token)) unittest.AssertExistsAndLoadBean(t, token) // This token must be found by name in the DB now - exist, err = auth_model.AccessTokenByNameExists(db.DefaultContext, token) + exist, err = auth_model.AccessTokenByNameExists(t.Context(), token) assert.NoError(t, err) assert.True(t, exist) @@ -60,32 +60,32 @@ func TestAccessTokenByNameExists(t *testing.T) { // Name matches but different user ID, this shouldn't exists in the // database - exist, err = auth_model.AccessTokenByNameExists(db.DefaultContext, user4Token) + exist, err = auth_model.AccessTokenByNameExists(t.Context(), user4Token) assert.NoError(t, err) assert.False(t, exist) } func TestGetAccessTokenBySHA(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - token, err := auth_model.GetAccessTokenBySHA(db.DefaultContext, "d2c6c1ba3890b309189a8e618c72a162e4efbf36") + token, err := auth_model.GetAccessTokenBySHA(t.Context(), "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 = auth_model.GetAccessTokenBySHA(db.DefaultContext, "notahash") + _, err = auth_model.GetAccessTokenBySHA(t.Context(), "notahash") assert.Error(t, err) assert.True(t, auth_model.IsErrAccessTokenNotExist(err)) - _, err = auth_model.GetAccessTokenBySHA(db.DefaultContext, "") + _, err = auth_model.GetAccessTokenBySHA(t.Context(), "") assert.Error(t, err) assert.True(t, auth_model.IsErrAccessTokenEmpty(err)) } func TestListAccessTokens(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - tokens, err := db.Find[auth_model.AccessToken](db.DefaultContext, auth_model.ListAccessTokensOptions{UserID: 1}) + tokens, err := db.Find[auth_model.AccessToken](t.Context(), auth_model.ListAccessTokensOptions{UserID: 1}) assert.NoError(t, err) if assert.Len(t, tokens, 2) { assert.Equal(t, int64(1), tokens[0].UID) @@ -94,39 +94,39 @@ func TestListAccessTokens(t *testing.T) { assert.Contains(t, []string{tokens[0].Name, tokens[1].Name}, "Token B") } - tokens, err = db.Find[auth_model.AccessToken](db.DefaultContext, auth_model.ListAccessTokensOptions{UserID: 2}) + tokens, err = db.Find[auth_model.AccessToken](t.Context(), 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 = db.Find[auth_model.AccessToken](db.DefaultContext, auth_model.ListAccessTokensOptions{UserID: 100}) + tokens, err = db.Find[auth_model.AccessToken](t.Context(), 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 := auth_model.GetAccessTokenBySHA(db.DefaultContext, "4c6f36e6cf498e2a448662f915d932c09c5a146c") + token, err := auth_model.GetAccessTokenBySHA(t.Context(), "4c6f36e6cf498e2a448662f915d932c09c5a146c") assert.NoError(t, err) token.Name = "Token Z" - assert.NoError(t, auth_model.UpdateAccessToken(db.DefaultContext, token)) + assert.NoError(t, auth_model.UpdateAccessToken(t.Context(), token)) unittest.AssertExistsAndLoadBean(t, token) } func TestDeleteAccessTokenByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - token, err := auth_model.GetAccessTokenBySHA(db.DefaultContext, "4c6f36e6cf498e2a448662f915d932c09c5a146c") + token, err := auth_model.GetAccessTokenBySHA(t.Context(), "4c6f36e6cf498e2a448662f915d932c09c5a146c") assert.NoError(t, err) assert.Equal(t, int64(1), token.UID) - assert.NoError(t, auth_model.DeleteAccessTokenByID(db.DefaultContext, token.ID, 1)) + assert.NoError(t, auth_model.DeleteAccessTokenByID(t.Context(), token.ID, 1)) unittest.AssertNotExistsBean(t, token) - err = auth_model.DeleteAccessTokenByID(db.DefaultContext, 100, 100) + err = auth_model.DeleteAccessTokenByID(t.Context(), 100, 100) assert.Error(t, err) assert.True(t, auth_model.IsErrAccessTokenNotExist(err)) } diff --git a/models/auth/oauth2_test.go b/models/auth/oauth2_test.go index c6626b283e..97f750755a 100644 --- a/models/auth/oauth2_test.go +++ b/models/auth/oauth2_test.go @@ -7,7 +7,6 @@ import ( "testing" auth_model "code.gitea.io/gitea/models/auth" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert" @@ -16,7 +15,7 @@ import ( func TestOAuth2Application_GenerateClientSecret(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1}) - secret, err := app.GenerateClientSecret(db.DefaultContext) + secret, err := app.GenerateClientSecret(t.Context()) assert.NoError(t, err) assert.NotEmpty(t, secret) unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1, ClientSecret: app.ClientSecret}) @@ -26,7 +25,7 @@ func BenchmarkOAuth2Application_GenerateClientSecret(b *testing.B) { assert.NoError(b, unittest.PrepareTestDatabase()) app := unittest.AssertExistsAndLoadBean(b, &auth_model.OAuth2Application{ID: 1}) for b.Loop() { - _, _ = app.GenerateClientSecret(db.DefaultContext) + _, _ = app.GenerateClientSecret(b.Context()) } } @@ -76,7 +75,7 @@ func TestOAuth2Application_ContainsRedirect_Slash(t *testing.T) { func TestOAuth2Application_ValidateClientSecret(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1}) - secret, err := app.GenerateClientSecret(db.DefaultContext) + secret, err := app.GenerateClientSecret(t.Context()) assert.NoError(t, err) assert.True(t, app.ValidateClientSecret([]byte(secret))) assert.False(t, app.ValidateClientSecret([]byte("fewijfowejgfiowjeoifew"))) @@ -84,18 +83,18 @@ func TestOAuth2Application_ValidateClientSecret(t *testing.T) { func TestGetOAuth2ApplicationByClientID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - app, err := auth_model.GetOAuth2ApplicationByClientID(db.DefaultContext, "da7da3ba-9a13-4167-856f-3899de0b0138") + app, err := auth_model.GetOAuth2ApplicationByClientID(t.Context(), "da7da3ba-9a13-4167-856f-3899de0b0138") assert.NoError(t, err) assert.Equal(t, "da7da3ba-9a13-4167-856f-3899de0b0138", app.ClientID) - app, err = auth_model.GetOAuth2ApplicationByClientID(db.DefaultContext, "invalid client id") + app, err = auth_model.GetOAuth2ApplicationByClientID(t.Context(), "invalid client id") assert.Error(t, err) assert.Nil(t, app) } func TestCreateOAuth2Application(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - app, err := auth_model.CreateOAuth2Application(db.DefaultContext, auth_model.CreateOAuth2ApplicationOptions{Name: "newapp", UserID: 1}) + app, err := auth_model.CreateOAuth2Application(t.Context(), auth_model.CreateOAuth2ApplicationOptions{Name: "newapp", UserID: 1}) assert.NoError(t, err) assert.Equal(t, "newapp", app.Name) assert.Len(t, app.ClientID, 36) @@ -109,11 +108,11 @@ func TestOAuth2Application_TableName(t *testing.T) { func TestOAuth2Application_GetGrantByUserID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1}) - grant, err := app.GetGrantByUserID(db.DefaultContext, 1) + grant, err := app.GetGrantByUserID(t.Context(), 1) assert.NoError(t, err) assert.Equal(t, int64(1), grant.UserID) - grant, err = app.GetGrantByUserID(db.DefaultContext, 34923458) + grant, err = app.GetGrantByUserID(t.Context(), 34923458) assert.NoError(t, err) assert.Nil(t, grant) } @@ -121,7 +120,7 @@ func TestOAuth2Application_GetGrantByUserID(t *testing.T) { func TestOAuth2Application_CreateGrant(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1}) - grant, err := app.CreateGrant(db.DefaultContext, 2, "") + grant, err := app.CreateGrant(t.Context(), 2, "") assert.NoError(t, err) assert.NotNil(t, grant) assert.Equal(t, int64(2), grant.UserID) @@ -133,11 +132,11 @@ func TestOAuth2Application_CreateGrant(t *testing.T) { func TestGetOAuth2GrantByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - grant, err := auth_model.GetOAuth2GrantByID(db.DefaultContext, 1) + grant, err := auth_model.GetOAuth2GrantByID(t.Context(), 1) assert.NoError(t, err) assert.Equal(t, int64(1), grant.ID) - grant, err = auth_model.GetOAuth2GrantByID(db.DefaultContext, 34923458) + grant, err = auth_model.GetOAuth2GrantByID(t.Context(), 34923458) assert.NoError(t, err) assert.Nil(t, grant) } @@ -145,7 +144,7 @@ func TestGetOAuth2GrantByID(t *testing.T) { func TestOAuth2Grant_IncreaseCounter(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) grant := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1, Counter: 1}) - assert.NoError(t, grant.IncreaseCounter(db.DefaultContext)) + assert.NoError(t, grant.IncreaseCounter(t.Context())) assert.Equal(t, int64(2), grant.Counter) unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1, Counter: 2}) } @@ -162,7 +161,7 @@ func TestOAuth2Grant_ScopeContains(t *testing.T) { func TestOAuth2Grant_GenerateNewAuthorizationCode(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) grant := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1}) - code, err := grant.GenerateNewAuthorizationCode(db.DefaultContext, "https://example2.com/callback", "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg", "S256") + code, err := grant.GenerateNewAuthorizationCode(t.Context(), "https://example2.com/callback", "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg", "S256") assert.NoError(t, err) assert.NotNil(t, code) assert.Greater(t, len(code.Code), 32) // secret length > 32 @@ -174,20 +173,20 @@ func TestOAuth2Grant_TableName(t *testing.T) { func TestGetOAuth2GrantsByUserID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - result, err := auth_model.GetOAuth2GrantsByUserID(db.DefaultContext, 1) + result, err := auth_model.GetOAuth2GrantsByUserID(t.Context(), 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 = auth_model.GetOAuth2GrantsByUserID(db.DefaultContext, 34134) + result, err = auth_model.GetOAuth2GrantsByUserID(t.Context(), 34134) assert.NoError(t, err) assert.Empty(t, result) } func TestRevokeOAuth2Grant(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.NoError(t, auth_model.RevokeOAuth2Grant(db.DefaultContext, 1, 1)) + assert.NoError(t, auth_model.RevokeOAuth2Grant(t.Context(), 1, 1)) unittest.AssertNotExistsBean(t, &auth_model.OAuth2Grant{ID: 1, UserID: 1}) } @@ -195,13 +194,13 @@ func TestRevokeOAuth2Grant(t *testing.T) { func TestGetOAuth2AuthorizationByCode(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - code, err := auth_model.GetOAuth2AuthorizationByCode(db.DefaultContext, "authcode") + code, err := auth_model.GetOAuth2AuthorizationByCode(t.Context(), "authcode") assert.NoError(t, err) assert.NotNil(t, code) assert.Equal(t, "authcode", code.Code) assert.Equal(t, int64(1), code.ID) - code, err = auth_model.GetOAuth2AuthorizationByCode(db.DefaultContext, "does not exist") + code, err = auth_model.GetOAuth2AuthorizationByCode(t.Context(), "does not exist") assert.NoError(t, err) assert.Nil(t, code) } @@ -256,7 +255,7 @@ func TestOAuth2AuthorizationCode_GenerateRedirectURI(t *testing.T) { func TestOAuth2AuthorizationCode_Invalidate(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) code := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2AuthorizationCode{Code: "authcode"}) - assert.NoError(t, code.Invalidate(db.DefaultContext)) + assert.NoError(t, code.Invalidate(t.Context())) unittest.AssertNotExistsBean(t, &auth_model.OAuth2AuthorizationCode{Code: "authcode"}) } diff --git a/models/auth/session.go b/models/auth/session.go index 0378d0ec6f..dbdcde03a0 100644 --- a/models/auth/session.go +++ b/models/auth/session.go @@ -86,7 +86,7 @@ func RegenerateSession(ctx context.Context, oldKey, newKey string) (*Session, er } } - if _, err := db.Exec(ctx, "UPDATE "+db.TableName(&Session{})+" SET `key` = ? WHERE `key`=?", newKey, oldKey); err != nil { + if _, err := db.Exec(ctx, "UPDATE `session` SET `key` = ? WHERE `key`=?", newKey, oldKey); err != nil { return nil, err } diff --git a/models/auth/source_test.go b/models/auth/source_test.go index 64c7460b64..ebc462c581 100644 --- a/models/auth/source_test.go +++ b/models/auth/source_test.go @@ -8,13 +8,11 @@ import ( "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" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "xorm.io/xorm" "xorm.io/xorm/schemas" ) @@ -41,12 +39,12 @@ func (source *TestSource) ToDB() ([]byte, error) { func TestDumpAuthSource(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - authSourceSchema, err := db.TableInfo(new(auth_model.Source)) + authSourceSchema, err := unittest.GetXORMEngine().TableInfo(new(auth_model.Source)) assert.NoError(t, err) auth_model.RegisterTypeConfig(auth_model.OAuth2, new(TestSource)) - auth_model.CreateSource(db.DefaultContext, &auth_model.Source{ + auth_model.CreateSource(t.Context(), &auth_model.Source{ Type: auth_model.OAuth2, Name: "TestSource", IsActive: false, @@ -59,7 +57,7 @@ func TestDumpAuthSource(t *testing.T) { sb := new(strings.Builder) // TODO: this test is quite hacky, it should use a low-level "select" (without model processors) but not a database dump - engine := db.GetEngine(db.DefaultContext).(*xorm.Engine) + engine := unittest.GetXORMEngine() require.NoError(t, engine.DumpTables([]*schemas.Table{authSourceSchema}, sb)) assert.Contains(t, sb.String(), `"Provider":"ConvertibleSourceName"`) } diff --git a/models/auth/webauthn_test.go b/models/auth/webauthn_test.go index 654427e974..41c5f6de94 100644 --- a/models/auth/webauthn_test.go +++ b/models/auth/webauthn_test.go @@ -7,7 +7,6 @@ import ( "testing" auth_model "code.gitea.io/gitea/models/auth" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" "github.com/go-webauthn/webauthn/webauthn" @@ -17,11 +16,11 @@ import ( func TestGetWebAuthnCredentialByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - res, err := auth_model.GetWebAuthnCredentialByID(db.DefaultContext, 1) + res, err := auth_model.GetWebAuthnCredentialByID(t.Context(), 1) assert.NoError(t, err) assert.Equal(t, "WebAuthn credential", res.Name) - _, err = auth_model.GetWebAuthnCredentialByID(db.DefaultContext, 342432) + _, err = auth_model.GetWebAuthnCredentialByID(t.Context(), 342432) assert.Error(t, err) assert.True(t, auth_model.IsErrWebAuthnCredentialNotExist(err)) } @@ -29,7 +28,7 @@ func TestGetWebAuthnCredentialByID(t *testing.T) { func TestGetWebAuthnCredentialsByUID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - res, err := auth_model.GetWebAuthnCredentialsByUID(db.DefaultContext, 32) + res, err := auth_model.GetWebAuthnCredentialsByUID(t.Context(), 32) assert.NoError(t, err) assert.Len(t, res, 1) assert.Equal(t, "WebAuthn credential", res[0].Name) @@ -43,7 +42,7 @@ func TestWebAuthnCredential_UpdateSignCount(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) cred := unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{ID: 1}) cred.SignCount = 1 - assert.NoError(t, cred.UpdateSignCount(db.DefaultContext)) + assert.NoError(t, cred.UpdateSignCount(t.Context())) unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{ID: 1, SignCount: 1}) } @@ -51,14 +50,14 @@ func TestWebAuthnCredential_UpdateLargeCounter(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) cred := unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{ID: 1}) cred.SignCount = 0xffffffff - assert.NoError(t, cred.UpdateSignCount(db.DefaultContext)) + assert.NoError(t, cred.UpdateSignCount(t.Context())) unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{ID: 1, SignCount: 0xffffffff}) } func TestCreateCredential(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - res, err := auth_model.CreateCredential(db.DefaultContext, 1, "WebAuthn Created Credential", &webauthn.Credential{ID: []byte("Test")}) + res, err := auth_model.CreateCredential(t.Context(), 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) diff --git a/models/avatars/avatar_test.go b/models/avatars/avatar_test.go index c8f7a6574b..43a062cc2a 100644 --- a/models/avatars/avatar_test.go +++ b/models/avatars/avatar_test.go @@ -7,7 +7,6 @@ import ( "testing" avatars_model "code.gitea.io/gitea/models/avatars" - "code.gitea.io/gitea/models/db" system_model "code.gitea.io/gitea/models/system" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting/config" @@ -18,14 +17,14 @@ import ( const gravatarSource = "https://secure.gravatar.com/avatar/" func disableGravatar(t *testing.T) { - err := system_model.SetSettings(db.DefaultContext, map[string]string{setting.Config().Picture.EnableFederatedAvatar.DynKey(): "false"}) + err := system_model.SetSettings(t.Context(), map[string]string{setting.Config().Picture.EnableFederatedAvatar.DynKey(): "false"}) assert.NoError(t, err) - err = system_model.SetSettings(db.DefaultContext, map[string]string{setting.Config().Picture.DisableGravatar.DynKey(): "true"}) + err = system_model.SetSettings(t.Context(), map[string]string{setting.Config().Picture.DisableGravatar.DynKey(): "true"}) assert.NoError(t, err) } func enableGravatar(t *testing.T) { - err := system_model.SetSettings(db.DefaultContext, map[string]string{setting.Config().Picture.DisableGravatar.DynKey(): "false"}) + err := system_model.SetSettings(t.Context(), map[string]string{setting.Config().Picture.DisableGravatar.DynKey(): "false"}) assert.NoError(t, err) setting.GravatarSource = gravatarSource } @@ -47,12 +46,12 @@ func TestSizedAvatarLink(t *testing.T) { disableGravatar(t) config.GetDynGetter().InvalidateCache() assert.Equal(t, "/testsuburl/assets/img/avatar_default.png", - avatars_model.GenerateEmailAvatarFastLink(db.DefaultContext, "gitea@example.com", 100)) + avatars_model.GenerateEmailAvatarFastLink(t.Context(), "gitea@example.com", 100)) enableGravatar(t) config.GetDynGetter().InvalidateCache() assert.Equal(t, "https://secure.gravatar.com/avatar/353cbad9b58e69c96154ad99f92bedc7?d=identicon&s=100", - avatars_model.GenerateEmailAvatarFastLink(db.DefaultContext, "gitea@example.com", 100), + avatars_model.GenerateEmailAvatarFastLink(t.Context(), "gitea@example.com", 100), ) } diff --git a/models/db/context.go b/models/db/context.go index ad99ada8c8..8bb14f1389 100644 --- a/models/db/context.go +++ b/models/db/context.go @@ -17,35 +17,12 @@ import ( "xorm.io/xorm" ) -// DefaultContext is the default context to run xorm queries in -// will be overwritten by Init with HammerContext -var DefaultContext context.Context - type engineContextKeyType struct{} var engineContextKey = engineContextKeyType{} -// Context represents a db context -type Context struct { - context.Context - engine Engine -} - -func newContext(ctx context.Context, e Engine) *Context { - return &Context{Context: ctx, engine: e} -} - -// Value shadows Value for context.Context but allows us to get ourselves and an Engined object -func (ctx *Context) Value(key any) any { - if key == engineContextKey { - return ctx - } - return ctx.Context.Value(key) -} - -// WithContext returns this engine tied to this context -func (ctx *Context) WithContext(other context.Context) *Context { - return newContext(ctx, ctx.engine.Context(other)) +func withContextEngine(ctx context.Context, e Engine) context.Context { + return context.WithValue(ctx, engineContextKey, e) } var ( @@ -84,29 +61,24 @@ func contextSafetyCheck(e Engine) { callerNum := runtime.Callers(3, callers) // skip 3: runtime.Callers, contextSafetyCheck, GetEngine for i := range callerNum { if slices.Contains(contextSafetyDeniedFuncPCs, callers[i]) { - panic(errors.New("using database context in an iterator would cause corrupted results")) + panic(errors.New("using session context in an iterator would cause corrupted results")) } } } // GetEngine gets an existing db Engine/Statement or creates a new Session func GetEngine(ctx context.Context) Engine { - if e := getExistingEngine(ctx); e != nil { - return e + if engine, ok := ctx.Value(engineContextKey).(Engine); ok { + // if reusing the existing session, need to do "contextSafetyCheck" because the Iterate creates a "autoResetStatement=false" session + contextSafetyCheck(engine) + return engine } + // no need to do "contextSafetyCheck" because it's a new Session return xormEngine.Context(ctx) } -// getExistingEngine gets an existing db Engine/Statement from this context or returns nil -func getExistingEngine(ctx context.Context) (e Engine) { - defer func() { contextSafetyCheck(e) }() - if engined, ok := ctx.(*Context); ok { - return engined.engine - } - if engined, ok := ctx.Value(engineContextKey).(*Context); ok { - return engined.engine - } - return nil +func GetXORMEngineForTesting() *xorm.Engine { + return xormEngine } // Committer represents an interface to Commit or Close the Context @@ -150,9 +122,9 @@ func (c *halfCommitter) Close() error { // So calling `Commit()` will do nothing, but calling `Close()` without calling `Commit()` will rollback the transaction. // And all operations submitted by the caller stack will be rollbacked as well, not only the operations in the current function. // d. It doesn't mean rollback is forbidden, but always do it only when there is an error, and you do want to rollback. -func TxContext(parentCtx context.Context) (*Context, Committer, error) { - if sess, ok := inTransaction(parentCtx); ok { - return newContext(parentCtx, sess), &halfCommitter{committer: sess}, nil +func TxContext(parentCtx context.Context) (context.Context, Committer, error) { + if sess := getTransactionSession(parentCtx); sess != nil { + return withContextEngine(parentCtx, sess), &halfCommitter{committer: sess}, nil } sess := xormEngine.NewSession() @@ -160,15 +132,14 @@ func TxContext(parentCtx context.Context) (*Context, Committer, error) { _ = sess.Close() return nil, nil, err } - - return newContext(DefaultContext, sess), sess, nil + return withContextEngine(parentCtx, sess), sess, nil } // WithTx represents executing database operations on a transaction, if the transaction exist, // this function will reuse it otherwise will create a new one and close it when finished. func WithTx(parentCtx context.Context, f func(ctx context.Context) error) error { - if sess, ok := inTransaction(parentCtx); ok { - err := f(newContext(parentCtx, sess)) + if sess := getTransactionSession(parentCtx); sess != nil { + err := f(withContextEngine(parentCtx, sess)) if err != nil { // rollback immediately, in case the caller ignores returned error and tries to commit the transaction. _ = sess.Close() @@ -194,7 +165,7 @@ func txWithNoCheck(parentCtx context.Context, f func(ctx context.Context) error) return err } - if err := f(newContext(parentCtx, sess)); err != nil { + if err := f(withContextEngine(parentCtx, sess)); err != nil { return err } @@ -332,32 +303,15 @@ func CountByBean(ctx context.Context, bean any) (int64, error) { return GetEngine(ctx).Count(bean) } -// TableName returns the table name according a bean object -func TableName(bean any) string { - return xormEngine.TableName(bean) -} - // InTransaction returns true if the engine is in a transaction otherwise return false func InTransaction(ctx context.Context) bool { - _, ok := inTransaction(ctx) - return ok + return getTransactionSession(ctx) != nil } -func inTransaction(ctx context.Context) (*xorm.Session, bool) { - e := getExistingEngine(ctx) - if e == nil { - return nil, false - } - - switch t := e.(type) { - case *xorm.Engine: - return nil, false - case *xorm.Session: - if t.IsInTx() { - return t, true - } - return nil, false - default: - return nil, false +func getTransactionSession(ctx context.Context) *xorm.Session { + e, _ := ctx.Value(engineContextKey).(Engine) + if sess, ok := e.(*xorm.Session); ok && sess.IsInTx() { + return sess } + return nil } diff --git a/models/db/context_committer_test.go b/models/db/context_committer_test.go index 849c5dea41..90f6aaefa1 100644 --- a/models/db/context_committer_test.go +++ b/models/db/context_committer_test.go @@ -39,7 +39,7 @@ func Test_halfCommitter(t *testing.T) { /* Do something like: - ctx, committer, err := db.TxContext(db.DefaultContext) + ctx, committer, err := db.TxContext(t.Context()) if err != nil { return nil } diff --git a/models/db/context_test.go b/models/db/context_test.go index a6bd11d2ae..1719a7bfe8 100644 --- a/models/db/context_test.go +++ b/models/db/context_test.go @@ -15,13 +15,13 @@ import ( func TestInTransaction(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.False(t, db.InTransaction(db.DefaultContext)) - assert.NoError(t, db.WithTx(db.DefaultContext, func(ctx context.Context) error { + assert.False(t, db.InTransaction(t.Context())) + assert.NoError(t, db.WithTx(t.Context(), func(ctx context.Context) error { assert.True(t, db.InTransaction(ctx)) return nil })) - ctx, committer, err := db.TxContext(db.DefaultContext) + ctx, committer, err := db.TxContext(t.Context()) assert.NoError(t, err) defer committer.Close() assert.True(t, db.InTransaction(ctx)) @@ -35,14 +35,14 @@ func TestTxContext(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) { // create new transaction - ctx, committer, err := db.TxContext(db.DefaultContext) + ctx, committer, err := db.TxContext(t.Context()) assert.NoError(t, err) assert.True(t, db.InTransaction(ctx)) assert.NoError(t, committer.Commit()) } { // reuse the transaction created by TxContext and commit it - ctx, committer, err := db.TxContext(db.DefaultContext) + ctx, committer, err := db.TxContext(t.Context()) engine := db.GetEngine(ctx) assert.NoError(t, err) assert.True(t, db.InTransaction(ctx)) @@ -57,7 +57,7 @@ func TestTxContext(t *testing.T) { } { // reuse the transaction created by TxContext and close it - ctx, committer, err := db.TxContext(db.DefaultContext) + ctx, committer, err := db.TxContext(t.Context()) engine := db.GetEngine(ctx) assert.NoError(t, err) assert.True(t, db.InTransaction(ctx)) @@ -72,7 +72,7 @@ func TestTxContext(t *testing.T) { } { // reuse the transaction created by WithTx - assert.NoError(t, db.WithTx(db.DefaultContext, func(ctx context.Context) error { + assert.NoError(t, db.WithTx(t.Context(), func(ctx context.Context) error { assert.True(t, db.InTransaction(ctx)) { ctx, committer, err := db.TxContext(ctx) @@ -93,38 +93,43 @@ func TestContextSafety(t *testing.T) { ID int64 } assert.NoError(t, unittest.GetXORMEngine().Sync(&TestModel1{}, &TestModel2{})) - assert.NoError(t, db.TruncateBeans(db.DefaultContext, &TestModel1{}, &TestModel2{})) + assert.NoError(t, db.TruncateBeans(t.Context(), &TestModel1{}, &TestModel2{})) testCount := 10 for i := 1; i <= testCount; i++ { - assert.NoError(t, db.Insert(db.DefaultContext, &TestModel1{ID: int64(i)})) - assert.NoError(t, db.Insert(db.DefaultContext, &TestModel2{ID: int64(-i)})) + assert.NoError(t, db.Insert(t.Context(), &TestModel1{ID: int64(i)})) + assert.NoError(t, db.Insert(t.Context(), &TestModel2{ID: int64(-i)})) } - actualCount := 0 - // here: db.GetEngine(db.DefaultContext) is a new *Session created from *Engine - _ = db.WithTx(db.DefaultContext, func(ctx context.Context) error { - _ = db.GetEngine(ctx).Iterate(&TestModel1{}, func(i int, bean any) error { - // here: db.GetEngine(ctx) is always the unclosed "Iterate" *Session with autoResetStatement=false, - // and the internal states (including "cond" and others) are always there and not be reset in this callback. - m1 := bean.(*TestModel1) - assert.EqualValues(t, i+1, m1.ID) + t.Run("Show-XORM-Bug", func(t *testing.T) { + actualCount := 0 + // here: db.GetEngine(t.Context()) is a new *Session created from *Engine + _ = db.WithTx(t.Context(), func(ctx context.Context) error { + _ = db.GetEngine(ctx).Iterate(&TestModel1{}, func(i int, bean any) error { + // here: db.GetEngine(ctx) is always the unclosed "Iterate" *Session with autoResetStatement=false, + // and the internal states (including "cond" and others) are always there and not be reset in this callback. + m1 := bean.(*TestModel1) + assert.EqualValues(t, i+1, m1.ID) - // here: XORM bug, it fails because the SQL becomes "WHERE id=-1", "WHERE id=-1 AND id=-2", "WHERE id=-1 AND id=-2 AND id=-3" ... - // and it conflicts with the "Iterate"'s internal states. - // has, err := db.GetEngine(ctx).Get(&TestModel2{ID: -m1.ID}) + // here: XORM bug, it fails because the SQL becomes "WHERE id=-1", "WHERE id=-1 AND id=-2", "WHERE id=-1 AND id=-2 AND id=-3" ... + // and it conflicts with the "Iterate"'s internal states. + // has, err := db.GetEngine(ctx).Get(&TestModel2{ID: -m1.ID}) - actualCount++ + actualCount++ + return nil + }) return nil }) - return nil + assert.Equal(t, testCount, actualCount) }) - assert.Equal(t, testCount, actualCount) - // deny the bad usages - assert.PanicsWithError(t, "using database context in an iterator would cause corrupted results", func() { - _ = unittest.GetXORMEngine().Iterate(&TestModel1{}, func(i int, bean any) error { - _ = db.GetEngine(db.DefaultContext) - return nil + t.Run("DenyBadUsage", func(t *testing.T) { + assert.PanicsWithError(t, "using session context in an iterator would cause corrupted results", func() { + _ = db.WithTx(t.Context(), func(ctx context.Context) error { + return db.GetEngine(ctx).Iterate(&TestModel1{}, func(i int, bean any) error { + _ = db.GetEngine(ctx) + return nil + }) + }) }) }) } diff --git a/models/db/engine.go b/models/db/engine.go index ba287d58f0..b08799210e 100755 --- a/models/db/engine.go +++ b/models/db/engine.go @@ -12,7 +12,6 @@ import ( "strings" "xorm.io/xorm" - "xorm.io/xorm/schemas" _ "github.com/go-sql-driver/mysql" // Needed for the MySQL driver _ "github.com/lib/pq" // Needed for the Postgresql driver @@ -59,12 +58,13 @@ type Engine interface { Cols(...string) *xorm.Session Context(ctx context.Context) *xorm.Session Ping() error + IsTableExist(tableNameOrBean any) (bool, error) } -// TableInfo returns table's information via an object -func TableInfo(v any) (*schemas.Table, error) { - return xormEngine.TableInfo(v) -} +var ( + _ Engine = (*xorm.Engine)(nil) + _ Engine = (*xorm.Session)(nil) +) // RegisterModel registers model, if initFuncs provided, it will be invoked after data model sync func RegisterModel(bean any, initFunc ...func() error) { diff --git a/models/db/engine_init.go b/models/db/engine_init.go index bb02aff274..f26189b805 100644 --- a/models/db/engine_init.go +++ b/models/db/engine_init.go @@ -52,7 +52,7 @@ func newXORMEngine() (*xorm.Engine, error) { return engine, nil } -// InitEngine initializes the xorm.Engine and sets it as db.DefaultContext +// InitEngine initializes the xorm.Engine and sets it as XORM's default context func InitEngine(ctx context.Context) error { xe, err := newXORMEngine() if err != nil { @@ -70,7 +70,6 @@ func InitEngine(ctx context.Context) error { xe.SetMaxOpenConns(setting.Database.MaxOpenConns) xe.SetMaxIdleConns(setting.Database.MaxIdleConns) xe.SetConnMaxLifetime(setting.Database.ConnMaxLifetime) - xe.SetDefaultContext(ctx) if setting.Database.SlowQueryThreshold > 0 { xe.AddHook(&EngineHook{ @@ -86,22 +85,21 @@ func InitEngine(ctx context.Context) error { // SetDefaultEngine sets the default engine for db func SetDefaultEngine(ctx context.Context, eng *xorm.Engine) { xormEngine = eng - DefaultContext = &Context{Context: ctx, engine: xormEngine} + xormEngine.SetDefaultContext(ctx) } // UnsetDefaultEngine closes and unsets the default engine // We hope the SetDefaultEngine and UnsetDefaultEngine can be paired, but it's impossible now, -// there are many calls to InitEngine -> SetDefaultEngine directly to overwrite the `xormEngine` and DefaultContext without close +// there are many calls to InitEngine -> SetDefaultEngine directly to overwrite the `xormEngine` and `xormContext` without close // Global database engine related functions are all racy and there is no graceful close right now. func UnsetDefaultEngine() { if xormEngine != nil { _ = xormEngine.Close() xormEngine = nil } - DefaultContext = nil } -// InitEngineWithMigration initializes a new xorm.Engine and sets it as the db.DefaultContext +// InitEngineWithMigration initializes a new xorm.Engine and sets it as the XORM's default context // This function must never call .Sync() if the provided migration function fails. // When called from the "doctor" command, the migration function is a version check // that prevents the doctor from fixing anything in the database if the migration level diff --git a/models/db/engine_test.go b/models/db/engine_test.go index a236f83735..1c218df77f 100644 --- a/models/db/engine_test.go +++ b/models/db/engine_test.go @@ -27,7 +27,7 @@ func TestDumpDatabase(t *testing.T) { ID int64 `xorm:"pk autoincr"` Version int64 } - assert.NoError(t, db.GetEngine(db.DefaultContext).Sync(new(Version))) + assert.NoError(t, db.GetEngine(t.Context()).Sync(new(Version))) for _, dbType := range setting.SupportedDatabaseTypes { assert.NoError(t, db.DumpDatabase(filepath.Join(dir, dbType+".sql"), dbType)) @@ -37,20 +37,20 @@ func TestDumpDatabase(t *testing.T) { func TestDeleteOrphanedObjects(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - countBefore, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{}) + countBefore, err := db.GetEngine(t.Context()).Count(&issues_model.PullRequest{}) assert.NoError(t, err) - _, err = db.GetEngine(db.DefaultContext).Insert(&issues_model.PullRequest{IssueID: 1000}, &issues_model.PullRequest{IssueID: 1001}, &issues_model.PullRequest{IssueID: 1003}) + _, err = db.GetEngine(t.Context()).Insert(&issues_model.PullRequest{IssueID: 1000}, &issues_model.PullRequest{IssueID: 1001}, &issues_model.PullRequest{IssueID: 1003}) assert.NoError(t, err) - orphaned, err := db.CountOrphanedObjects(db.DefaultContext, "pull_request", "issue", "pull_request.issue_id=issue.id") + orphaned, err := db.CountOrphanedObjects(t.Context(), "pull_request", "issue", "pull_request.issue_id=issue.id") assert.NoError(t, err) assert.EqualValues(t, 3, orphaned) - err = db.DeleteOrphanedObjects(db.DefaultContext, "pull_request", "issue", "pull_request.issue_id=issue.id") + err = db.DeleteOrphanedObjects(t.Context(), "pull_request", "issue", "pull_request.issue_id=issue.id") assert.NoError(t, err) - countAfter, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{}) + countAfter, err := db.GetEngine(t.Context()).Count(&issues_model.PullRequest{}) assert.NoError(t, err) assert.Equal(t, countBefore, countAfter) } @@ -70,7 +70,7 @@ func TestPrimaryKeys(t *testing.T) { } for _, bean := range beans { - table, err := db.TableInfo(bean) + table, err := db.GetXORMEngineForTesting().TableInfo(bean) if err != nil { t.Fatal(err) } diff --git a/models/db/index.go b/models/db/index.go index 29254b1f07..7a11645bd4 100644 --- a/models/db/index.go +++ b/models/db/index.go @@ -19,12 +19,7 @@ type ResourceIndex struct { MaxIndex int64 `xorm:"index"` } -var ( - // ErrResouceOutdated represents an error when request resource outdated - ErrResouceOutdated = errors.New("resource outdated") - // ErrGetResourceIndexFailed represents an error when resource index retries 3 times - ErrGetResourceIndexFailed = errors.New("get resource index failed") -) +var ErrGetResourceIndexFailed = errors.New("get resource index failed") // SyncMaxResourceIndex sync the max index with the resource func SyncMaxResourceIndex(ctx context.Context, tableName string, groupID, maxIndex int64) (err error) { diff --git a/models/db/index_test.go b/models/db/index_test.go index 5fce0a6012..e2af7f35bb 100644 --- a/models/db/index_test.go +++ b/models/db/index_test.go @@ -35,30 +35,30 @@ func TestSyncMaxResourceIndex(t *testing.T) { xe := unittest.GetXORMEngine() assert.NoError(t, xe.Sync(&TestIndex{})) - err := db.SyncMaxResourceIndex(db.DefaultContext, "test_index", 10, 51) + err := db.SyncMaxResourceIndex(t.Context(), "test_index", 10, 51) assert.NoError(t, err) // sync new max index - maxIndex, err := getCurrentResourceIndex(db.DefaultContext, "test_index", 10) + maxIndex, err := getCurrentResourceIndex(t.Context(), "test_index", 10) assert.NoError(t, err) assert.EqualValues(t, 51, maxIndex) // smaller index doesn't change - err = db.SyncMaxResourceIndex(db.DefaultContext, "test_index", 10, 30) + err = db.SyncMaxResourceIndex(t.Context(), "test_index", 10, 30) assert.NoError(t, err) - maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10) + maxIndex, err = getCurrentResourceIndex(t.Context(), "test_index", 10) assert.NoError(t, err) assert.EqualValues(t, 51, maxIndex) // larger index changes - err = db.SyncMaxResourceIndex(db.DefaultContext, "test_index", 10, 62) + err = db.SyncMaxResourceIndex(t.Context(), "test_index", 10, 62) assert.NoError(t, err) - maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10) + maxIndex, err = getCurrentResourceIndex(t.Context(), "test_index", 10) assert.NoError(t, err) assert.EqualValues(t, 62, maxIndex) // commit transaction - err = db.WithTx(db.DefaultContext, func(ctx context.Context) error { + err = db.WithTx(t.Context(), func(ctx context.Context) error { err = db.SyncMaxResourceIndex(ctx, "test_index", 10, 73) assert.NoError(t, err) maxIndex, err = getCurrentResourceIndex(ctx, "test_index", 10) @@ -67,12 +67,12 @@ func TestSyncMaxResourceIndex(t *testing.T) { return nil }) assert.NoError(t, err) - maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10) + maxIndex, err = getCurrentResourceIndex(t.Context(), "test_index", 10) assert.NoError(t, err) assert.EqualValues(t, 73, maxIndex) // rollback transaction - err = db.WithTx(db.DefaultContext, func(ctx context.Context) error { + err = db.WithTx(t.Context(), func(ctx context.Context) error { err = db.SyncMaxResourceIndex(ctx, "test_index", 10, 84) maxIndex, err = getCurrentResourceIndex(ctx, "test_index", 10) assert.NoError(t, err) @@ -80,7 +80,7 @@ func TestSyncMaxResourceIndex(t *testing.T) { return errors.New("test rollback") }) assert.Error(t, err) - maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10) + maxIndex, err = getCurrentResourceIndex(t.Context(), "test_index", 10) assert.NoError(t, err) assert.EqualValues(t, 73, maxIndex) // the max index doesn't change because the transaction was rolled back } @@ -91,36 +91,36 @@ func TestGetNextResourceIndex(t *testing.T) { assert.NoError(t, xe.Sync(&TestIndex{})) // create a new record - maxIndex, err := db.GetNextResourceIndex(db.DefaultContext, "test_index", 20) + maxIndex, err := db.GetNextResourceIndex(t.Context(), "test_index", 20) assert.NoError(t, err) assert.EqualValues(t, 1, maxIndex) // increase the existing record - maxIndex, err = db.GetNextResourceIndex(db.DefaultContext, "test_index", 20) + maxIndex, err = db.GetNextResourceIndex(t.Context(), "test_index", 20) assert.NoError(t, err) assert.EqualValues(t, 2, maxIndex) // commit transaction - err = db.WithTx(db.DefaultContext, func(ctx context.Context) error { + err = db.WithTx(t.Context(), func(ctx context.Context) error { maxIndex, err = db.GetNextResourceIndex(ctx, "test_index", 20) assert.NoError(t, err) assert.EqualValues(t, 3, maxIndex) return nil }) assert.NoError(t, err) - maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 20) + maxIndex, err = getCurrentResourceIndex(t.Context(), "test_index", 20) assert.NoError(t, err) assert.EqualValues(t, 3, maxIndex) // rollback transaction - err = db.WithTx(db.DefaultContext, func(ctx context.Context) error { + err = db.WithTx(t.Context(), func(ctx context.Context) error { maxIndex, err = db.GetNextResourceIndex(ctx, "test_index", 20) assert.NoError(t, err) assert.EqualValues(t, 4, maxIndex) return errors.New("test rollback") }) assert.Error(t, err) - maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 20) + maxIndex, err = getCurrentResourceIndex(t.Context(), "test_index", 20) assert.NoError(t, err) assert.EqualValues(t, 3, maxIndex) // the max index doesn't change because the transaction was rolled back } diff --git a/models/db/install/db.go b/models/db/install/db.go index 1b3b2ec3e9..a84e5e54fe 100644 --- a/models/db/install/db.go +++ b/models/db/install/db.go @@ -4,27 +4,22 @@ package install import ( + "context" + "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/setting" - - "xorm.io/xorm" ) -func getXORMEngine() *xorm.Engine { - return db.GetEngine(db.DefaultContext).(*xorm.Engine) -} - // CheckDatabaseConnection checks the database connection -func CheckDatabaseConnection() error { - e := db.GetEngine(db.DefaultContext) - _, err := e.Exec("SELECT 1") +func CheckDatabaseConnection(ctx context.Context) error { + _, err := db.GetEngine(ctx).Exec("SELECT 1") return err } // GetMigrationVersion gets the database migration version -func GetMigrationVersion() (int64, error) { +func GetMigrationVersion(ctx context.Context) (int64, error) { var installedDbVersion int64 - x := getXORMEngine() + x := db.GetEngine(ctx) exist, err := x.IsTableExist("version") if err != nil { return 0, err @@ -40,8 +35,8 @@ func GetMigrationVersion() (int64, error) { } // HasPostInstallationUsers checks whether there are users after installation -func HasPostInstallationUsers() (bool, error) { - x := getXORMEngine() +func HasPostInstallationUsers(ctx context.Context) (bool, error) { + x := db.GetEngine(ctx) exist, err := x.IsTableExist("user") if err != nil { return false, err diff --git a/models/db/iterate_test.go b/models/db/iterate_test.go index e9f2790671..21bb0c0b4b 100644 --- a/models/db/iterate_test.go +++ b/models/db/iterate_test.go @@ -19,18 +19,18 @@ func TestIterate(t *testing.T) { xe := unittest.GetXORMEngine() assert.NoError(t, xe.Sync(&repo_model.RepoUnit{})) - cnt, err := db.GetEngine(db.DefaultContext).Count(&repo_model.RepoUnit{}) + cnt, err := db.GetEngine(t.Context()).Count(&repo_model.RepoUnit{}) assert.NoError(t, err) var repoUnitCnt int - err = db.Iterate(db.DefaultContext, nil, func(ctx context.Context, repo *repo_model.RepoUnit) error { + err = db.Iterate(t.Context(), nil, func(ctx context.Context, repo *repo_model.RepoUnit) error { repoUnitCnt++ return nil }) assert.NoError(t, err) assert.EqualValues(t, cnt, repoUnitCnt) - err = db.Iterate(db.DefaultContext, nil, func(ctx context.Context, repoUnit *repo_model.RepoUnit) error { + err = db.Iterate(t.Context(), nil, func(ctx context.Context, repoUnit *repo_model.RepoUnit) error { has, err := db.ExistByID[repo_model.RepoUnit](ctx, repoUnit.ID) if err != nil { return err diff --git a/models/db/list_test.go b/models/db/list_test.go index 170473a968..ddcfff1f88 100644 --- a/models/db/list_test.go +++ b/models/db/list_test.go @@ -32,20 +32,20 @@ func TestFind(t *testing.T) { assert.NoError(t, xe.Sync(&repo_model.RepoUnit{})) var repoUnitCount int - _, err := db.GetEngine(db.DefaultContext).SQL("SELECT COUNT(*) FROM repo_unit").Get(&repoUnitCount) + _, err := db.GetEngine(t.Context()).SQL("SELECT COUNT(*) FROM repo_unit").Get(&repoUnitCount) assert.NoError(t, err) assert.NotEmpty(t, repoUnitCount) opts := mockListOptions{} - repoUnits, err := db.Find[repo_model.RepoUnit](db.DefaultContext, opts) + repoUnits, err := db.Find[repo_model.RepoUnit](t.Context(), opts) assert.NoError(t, err) assert.Len(t, repoUnits, repoUnitCount) - cnt, err := db.Count[repo_model.RepoUnit](db.DefaultContext, opts) + cnt, err := db.Count[repo_model.RepoUnit](t.Context(), opts) assert.NoError(t, err) assert.EqualValues(t, repoUnitCount, cnt) - repoUnits, newCnt, err := db.FindAndCount[repo_model.RepoUnit](db.DefaultContext, opts) + repoUnits, newCnt, err := db.FindAndCount[repo_model.RepoUnit](t.Context(), opts) assert.NoError(t, err) assert.Equal(t, cnt, newCnt) assert.Len(t, repoUnits, repoUnitCount) diff --git a/models/dbfs/dbfs_test.go b/models/dbfs/dbfs_test.go index 0257d2bd15..e1ecd871e4 100644 --- a/models/dbfs/dbfs_test.go +++ b/models/dbfs/dbfs_test.go @@ -9,8 +9,6 @@ import ( "os" "testing" - "code.gitea.io/gitea/models/db" - "github.com/stretchr/testify/assert" ) @@ -26,7 +24,7 @@ func TestDbfsBasic(t *testing.T) { defer changeDefaultFileBlockSize(4)() // test basic write/read - f, err := OpenFile(db.DefaultContext, "test.txt", os.O_RDWR|os.O_CREATE) + f, err := OpenFile(t.Context(), "test.txt", os.O_RDWR|os.O_CREATE) assert.NoError(t, err) n, err := f.Write([]byte("0123456789")) // blocks: 0123 4567 89 @@ -95,25 +93,25 @@ func TestDbfsBasic(t *testing.T) { assert.NoError(t, f.Close()) // test rename - err = Rename(db.DefaultContext, "test.txt", "test2.txt") + err = Rename(t.Context(), "test.txt", "test2.txt") assert.NoError(t, err) - _, err = OpenFile(db.DefaultContext, "test.txt", os.O_RDONLY) + _, err = OpenFile(t.Context(), "test.txt", os.O_RDONLY) assert.Error(t, err) - f, err = OpenFile(db.DefaultContext, "test2.txt", os.O_RDONLY) + f, err = OpenFile(t.Context(), "test2.txt", os.O_RDONLY) assert.NoError(t, err) assert.NoError(t, f.Close()) // test remove - err = Remove(db.DefaultContext, "test2.txt") + err = Remove(t.Context(), "test2.txt") assert.NoError(t, err) - _, err = OpenFile(db.DefaultContext, "test2.txt", os.O_RDONLY) + _, err = OpenFile(t.Context(), "test2.txt", os.O_RDONLY) assert.Error(t, err) // test stat - f, err = OpenFile(db.DefaultContext, "test/test.txt", os.O_RDWR|os.O_CREATE) + f, err = OpenFile(t.Context(), "test/test.txt", os.O_RDWR|os.O_CREATE) assert.NoError(t, err) stat, err := f.Stat() assert.NoError(t, err) @@ -129,11 +127,11 @@ func TestDbfsBasic(t *testing.T) { func TestDbfsReadWrite(t *testing.T) { defer changeDefaultFileBlockSize(4)() - f1, err := OpenFile(db.DefaultContext, "test.log", os.O_RDWR|os.O_CREATE) + f1, err := OpenFile(t.Context(), "test.log", os.O_RDWR|os.O_CREATE) assert.NoError(t, err) defer f1.Close() - f2, err := OpenFile(db.DefaultContext, "test.log", os.O_RDONLY) + f2, err := OpenFile(t.Context(), "test.log", os.O_RDONLY) assert.NoError(t, err) defer f2.Close() @@ -161,7 +159,7 @@ func TestDbfsReadWrite(t *testing.T) { func TestDbfsSeekWrite(t *testing.T) { defer changeDefaultFileBlockSize(4)() - f, err := OpenFile(db.DefaultContext, "test2.log", os.O_RDWR|os.O_CREATE) + f, err := OpenFile(t.Context(), "test2.log", os.O_RDWR|os.O_CREATE) assert.NoError(t, err) defer f.Close() @@ -180,7 +178,7 @@ func TestDbfsSeekWrite(t *testing.T) { _, err = f.Write([]byte("333")) assert.NoError(t, err) - fr, err := OpenFile(db.DefaultContext, "test2.log", os.O_RDONLY) + fr, err := OpenFile(t.Context(), "test2.log", os.O_RDONLY) assert.NoError(t, err) defer f.Close() diff --git a/models/fixtures/user_redirect.yml b/models/fixtures/user_redirect.yml index 8ff7993398..c668cb6c3b 100644 --- a/models/fixtures/user_redirect.yml +++ b/models/fixtures/user_redirect.yml @@ -2,3 +2,7 @@ id: 1 lower_name: olduser1 redirect_user_id: 1 +- + id: 2 + lower_name: olduser2 + redirect_user_id: 2 diff --git a/models/git/branch.go b/models/git/branch.go index 6021e1101f..54351649cc 100644 --- a/models/git/branch.go +++ b/models/git/branch.go @@ -334,122 +334,111 @@ func FindRenamedBranch(ctx context.Context, repoID int64, from string) (branch * // RenameBranch rename a branch func RenameBranch(ctx context.Context, repo *repo_model.Repository, from, to string, gitAction func(ctx context.Context, isDefault bool) error) (err error) { - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return err - } - defer committer.Close() + return db.WithTx(ctx, func(ctx context.Context) error { + sess := db.GetEngine(ctx) - sess := db.GetEngine(ctx) - - // check whether from branch exist - var branch Branch - exist, err := db.GetEngine(ctx).Where("repo_id=? AND name=?", repo.ID, from).Get(&branch) - if err != nil { - return err - } else if !exist || branch.IsDeleted { - return ErrBranchNotExist{ - RepoID: repo.ID, - BranchName: from, - } - } - - // check whether to branch exist or is_deleted - var dstBranch Branch - exist, err = db.GetEngine(ctx).Where("repo_id=? AND name=?", repo.ID, to).Get(&dstBranch) - if err != nil { - return err - } - if exist { - if !dstBranch.IsDeleted { - return ErrBranchAlreadyExists{ - BranchName: to, + // check whether from branch exist + var branch Branch + exist, err := db.GetEngine(ctx).Where("repo_id=? AND name=?", repo.ID, from).Get(&branch) + if err != nil { + return err + } else if !exist || branch.IsDeleted { + return ErrBranchNotExist{ + RepoID: repo.ID, + BranchName: from, } } - if _, err := db.GetEngine(ctx).ID(dstBranch.ID).NoAutoCondition().Delete(&dstBranch); err != nil { - return err - } - } - - // 1. update branch in database - if n, err := sess.Where("repo_id=? AND name=?", repo.ID, from).Update(&Branch{ - Name: to, - }); err != nil { - return err - } else if n <= 0 { - return ErrBranchNotExist{ - RepoID: repo.ID, - BranchName: from, - } - } - - // 2. update default branch if needed - isDefault := repo.DefaultBranch == from - if isDefault { - repo.DefaultBranch = to - _, err = sess.ID(repo.ID).Cols("default_branch").Update(repo) + // check whether to branch exist or is_deleted + var dstBranch Branch + exist, err = db.GetEngine(ctx).Where("repo_id=? AND name=?", repo.ID, to).Get(&dstBranch) if err != nil { return err } - } + if exist { + if !dstBranch.IsDeleted { + return ErrBranchAlreadyExists{ + BranchName: to, + } + } - // 3. Update protected branch if needed - protectedBranch, err := GetProtectedBranchRuleByName(ctx, repo.ID, from) - if err != nil { - return err - } + if _, err := db.GetEngine(ctx).ID(dstBranch.ID).NoAutoCondition().Delete(&dstBranch); err != nil { + return err + } + } - if protectedBranch != nil { - // there is a protect rule for this branch - protectedBranch.RuleName = to - _, err = sess.ID(protectedBranch.ID).Cols("branch_name").Update(protectedBranch) + // 1. update branch in database + if n, err := sess.Where("repo_id=? AND name=?", repo.ID, from).Update(&Branch{ + Name: to, + }); err != nil { + return err + } else if n <= 0 { + return ErrBranchNotExist{ + RepoID: repo.ID, + BranchName: from, + } + } + + // 2. update default branch if needed + isDefault := repo.DefaultBranch == from + if isDefault { + repo.DefaultBranch = to + _, err = sess.ID(repo.ID).Cols("default_branch").Update(repo) + if err != nil { + return err + } + } + + // 3. Update protected branch if needed + protectedBranch, err := GetProtectedBranchRuleByName(ctx, repo.ID, from) if err != nil { return err } - } else { - // some glob protect rules may match this branch - protected, err := IsBranchProtected(ctx, repo.ID, from) + + if protectedBranch != nil { + // there is a protect rule for this branch + protectedBranch.RuleName = to + if _, err = sess.ID(protectedBranch.ID).Cols("branch_name").Update(protectedBranch); err != nil { + return err + } + } else { + // some glob protect rules may match this branch + protected, err := IsBranchProtected(ctx, repo.ID, from) + if err != nil { + return err + } + if protected { + return ErrBranchIsProtected + } + } + + // 4. Update all not merged pull request base branch name + _, err = sess.Table("pull_request").Where("base_repo_id=? AND base_branch=? AND has_merged=?", + repo.ID, from, false). + Update(map[string]any{"base_branch": to}) if err != nil { return err } - if protected { - return ErrBranchIsProtected + + // 4.1 Update all not merged pull request head branch name + if _, err = sess.Table("pull_request").Where("head_repo_id=? AND head_branch=? AND has_merged=?", + repo.ID, from, false). + Update(map[string]any{"head_branch": to}); err != nil { + return err } - } - // 4. Update all not merged pull request base branch name - _, err = sess.Table("pull_request").Where("base_repo_id=? AND base_branch=? AND has_merged=?", - repo.ID, from, false). - Update(map[string]any{"base_branch": to}) - if err != nil { - return err - } + // 5. insert renamed branch record + if err = db.Insert(ctx, &RenamedBranch{ + RepoID: repo.ID, + From: from, + To: to, + }); err != nil { + return err + } - // 4.1 Update all not merged pull request head branch name - if _, err = sess.Table("pull_request").Where("head_repo_id=? AND head_branch=? AND has_merged=?", - repo.ID, from, false). - Update(map[string]any{"head_branch": to}); err != nil { - return err - } - - // 5. insert renamed branch record - renamedBranch := &RenamedBranch{ - RepoID: repo.ID, - From: from, - To: to, - } - err = db.Insert(ctx, renamedBranch) - if err != nil { - return err - } - - // 6. do git action - if err = gitAction(ctx, isDefault); err != nil { - return err - } - - return committer.Commit() + // 6. do git action + return gitAction(ctx, isDefault) + }) } type FindRecentlyPushedNewBranchesOptions struct { diff --git a/models/git/branch_test.go b/models/git/branch_test.go index 252dcc5690..5be435172b 100644 --- a/models/git/branch_test.go +++ b/models/git/branch_test.go @@ -25,8 +25,8 @@ func TestAddDeletedBranch(t *testing.T) { firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{ID: 1}) assert.True(t, firstBranch.IsDeleted) - assert.NoError(t, git_model.AddDeletedBranch(db.DefaultContext, repo.ID, firstBranch.Name, firstBranch.DeletedByID)) - assert.NoError(t, git_model.AddDeletedBranch(db.DefaultContext, repo.ID, "branch2", int64(1))) + assert.NoError(t, git_model.AddDeletedBranch(t.Context(), repo.ID, firstBranch.Name, firstBranch.DeletedByID)) + assert.NoError(t, git_model.AddDeletedBranch(t.Context(), repo.ID, "branch2", int64(1))) secondBranch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{RepoID: repo.ID, Name: "branch2"}) assert.True(t, secondBranch.IsDeleted) @@ -39,7 +39,7 @@ func TestAddDeletedBranch(t *testing.T) { }, } - _, err := git_model.UpdateBranch(db.DefaultContext, repo.ID, secondBranch.PusherID, secondBranch.Name, commit) + _, err := git_model.UpdateBranch(t.Context(), repo.ID, secondBranch.PusherID, secondBranch.Name, commit) assert.NoError(t, err) } @@ -47,7 +47,7 @@ func TestGetDeletedBranches(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - branches, err := db.Find[git_model.Branch](db.DefaultContext, git_model.FindBranchOptions{ + branches, err := db.Find[git_model.Branch](t.Context(), git_model.FindBranchOptions{ ListOptions: db.ListOptionsAll, RepoID: repo.ID, IsDeletedBranch: optional.Some(true), @@ -71,13 +71,13 @@ func TestDeletedBranchLoadUser(t *testing.T) { branch := getDeletedBranch(t, firstBranch) assert.Nil(t, branch.DeletedBy) - branch.LoadDeletedBy(db.DefaultContext) + branch.LoadDeletedBy(t.Context()) assert.NotNil(t, branch.DeletedBy) assert.Equal(t, "user1", branch.DeletedBy.Name) branch = getDeletedBranch(t, secondBranch) assert.Nil(t, branch.DeletedBy) - branch.LoadDeletedBy(db.DefaultContext) + branch.LoadDeletedBy(t.Context()) assert.NotNil(t, branch.DeletedBy) assert.Equal(t, "Ghost", branch.DeletedBy.Name) } @@ -88,7 +88,7 @@ func TestRemoveDeletedBranch(t *testing.T) { firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{ID: 1}) - err := git_model.RemoveDeletedBranchByID(db.DefaultContext, repo.ID, 1) + err := git_model.RemoveDeletedBranchByID(t.Context(), repo.ID, 1) assert.NoError(t, err) unittest.AssertNotExistsBean(t, firstBranch) unittest.AssertExistsAndLoadBean(t, &git_model.Branch{ID: 2}) @@ -97,7 +97,7 @@ func TestRemoveDeletedBranch(t *testing.T) { func getDeletedBranch(t *testing.T, branch *git_model.Branch) *git_model.Branch { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - deletedBranch, err := git_model.GetDeletedBranchByID(db.DefaultContext, repo.ID, branch.ID) + deletedBranch, err := git_model.GetDeletedBranchByID(t.Context(), repo.ID, branch.ID) assert.NoError(t, err) assert.Equal(t, branch.ID, deletedBranch.ID) assert.Equal(t, branch.Name, deletedBranch.Name) @@ -109,12 +109,12 @@ func getDeletedBranch(t *testing.T, branch *git_model.Branch) *git_model.Branch func TestFindRenamedBranch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - branch, exist, err := git_model.FindRenamedBranch(db.DefaultContext, 1, "dev") + branch, exist, err := git_model.FindRenamedBranch(t.Context(), 1, "dev") assert.NoError(t, err) assert.True(t, exist) assert.Equal(t, "master", branch.To) - _, exist, err = git_model.FindRenamedBranch(db.DefaultContext, 1, "unknow") + _, exist, err = git_model.FindRenamedBranch(t.Context(), 1, "unknow") assert.NoError(t, err) assert.False(t, exist) } @@ -124,7 +124,7 @@ func TestRenameBranch(t *testing.T) { repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) _isDefault := false - ctx, committer, err := db.TxContext(db.DefaultContext) + ctx, committer, err := db.TxContext(t.Context()) defer committer.Close() assert.NoError(t, err) assert.NoError(t, git_model.UpdateProtectBranch(ctx, repo1, &git_model.ProtectedBranch{ @@ -133,7 +133,7 @@ func TestRenameBranch(t *testing.T) { }, git_model.WhitelistOptions{})) assert.NoError(t, committer.Commit()) - assert.NoError(t, git_model.RenameBranch(db.DefaultContext, repo1, "master", "main", func(ctx context.Context, isDefault bool) error { + assert.NoError(t, git_model.RenameBranch(t.Context(), repo1, "master", "main", func(ctx context.Context, isDefault bool) error { _isDefault = isDefault return nil })) @@ -167,7 +167,7 @@ func TestOnlyGetDeletedBranchOnCorrectRepo(t *testing.T) { // is actually on repo with ID 1. repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) - deletedBranch, err := git_model.GetDeletedBranchByID(db.DefaultContext, repo2.ID, 1) + deletedBranch, err := git_model.GetDeletedBranchByID(t.Context(), repo2.ID, 1) // Expect error, and the returned branch is nil. assert.Error(t, err) @@ -177,7 +177,7 @@ func TestOnlyGetDeletedBranchOnCorrectRepo(t *testing.T) { // This should return the deletedBranch. repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - deletedBranch, err = git_model.GetDeletedBranchByID(db.DefaultContext, repo1.ID, 1) + deletedBranch, err = git_model.GetDeletedBranchByID(t.Context(), repo1.ID, 1) // Expect no error, and the returned branch to be not nil. assert.NoError(t, err) diff --git a/models/git/commit_status_test.go b/models/git/commit_status_test.go index 4c0f5e891b..d1b9dfc3bf 100644 --- a/models/git/commit_status_test.go +++ b/models/git/commit_status_test.go @@ -15,7 +15,6 @@ import ( "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/commitstatus" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "github.com/stretchr/testify/assert" @@ -28,7 +27,7 @@ func TestGetCommitStatuses(t *testing.T) { sha1 := "1234123412341234123412341234123412341234" // the mocked commit ID in test fixtures - statuses, maxResults, err := db.FindAndCount[git_model.CommitStatus](db.DefaultContext, &git_model.CommitStatusOptions{ + statuses, maxResults, err := db.FindAndCount[git_model.CommitStatus](t.Context(), &git_model.CommitStatusOptions{ ListOptions: db.ListOptions{Page: 1, PageSize: 50}, RepoID: repo1.ID, SHA: sha1, @@ -39,25 +38,25 @@ func TestGetCommitStatuses(t *testing.T) { assert.Equal(t, "ci/awesomeness", statuses[0].Context) assert.Equal(t, commitstatus.CommitStatusPending, statuses[0].State) - assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[0].APIURL(db.DefaultContext)) + assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[0].APIURL(t.Context())) assert.Equal(t, "cov/awesomeness", statuses[1].Context) assert.Equal(t, commitstatus.CommitStatusWarning, statuses[1].State) - assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[1].APIURL(db.DefaultContext)) + assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[1].APIURL(t.Context())) assert.Equal(t, "cov/awesomeness", statuses[2].Context) assert.Equal(t, commitstatus.CommitStatusSuccess, statuses[2].State) - assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[2].APIURL(db.DefaultContext)) + assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[2].APIURL(t.Context())) assert.Equal(t, "ci/awesomeness", statuses[3].Context) assert.Equal(t, commitstatus.CommitStatusFailure, statuses[3].State) - assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[3].APIURL(db.DefaultContext)) + assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[3].APIURL(t.Context())) assert.Equal(t, "deploy/awesomeness", statuses[4].Context) assert.Equal(t, commitstatus.CommitStatusError, statuses[4].State) - assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[4].APIURL(db.DefaultContext)) + assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[4].APIURL(t.Context())) - statuses, maxResults, err = db.FindAndCount[git_model.CommitStatus](db.DefaultContext, &git_model.CommitStatusOptions{ + statuses, maxResults, err = db.FindAndCount[git_model.CommitStatus](t.Context(), &git_model.CommitStatusOptions{ ListOptions: db.ListOptions{Page: 2, PageSize: 50}, RepoID: repo1.ID, SHA: sha1, @@ -187,7 +186,7 @@ func TestFindRepoRecentCommitStatusContexts(t *testing.T) { repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo2) + gitRepo, err := gitrepo.OpenRepository(t.Context(), repo2) assert.NoError(t, err) defer gitRepo.Close() @@ -195,7 +194,7 @@ func TestFindRepoRecentCommitStatusContexts(t *testing.T) { assert.NoError(t, err) defer func() { - _, err := db.DeleteByBean(db.DefaultContext, &git_model.CommitStatus{ + _, err := db.DeleteByBean(t.Context(), &git_model.CommitStatus{ RepoID: repo2.ID, CreatorID: user2.ID, SHA: commit.ID.String(), @@ -203,7 +202,7 @@ func TestFindRepoRecentCommitStatusContexts(t *testing.T) { assert.NoError(t, err) }() - err = git_model.NewCommitStatus(db.DefaultContext, git_model.NewCommitStatusOptions{ + err = git_model.NewCommitStatus(t.Context(), git_model.NewCommitStatusOptions{ Repo: repo2, Creator: user2, SHA: commit.ID, @@ -215,7 +214,7 @@ func TestFindRepoRecentCommitStatusContexts(t *testing.T) { }) assert.NoError(t, err) - err = git_model.NewCommitStatus(db.DefaultContext, git_model.NewCommitStatusOptions{ + err = git_model.NewCommitStatus(t.Context(), git_model.NewCommitStatusOptions{ Repo: repo2, Creator: user2, SHA: commit.ID, @@ -227,7 +226,7 @@ func TestFindRepoRecentCommitStatusContexts(t *testing.T) { }) assert.NoError(t, err) - contexts, err := git_model.FindRepoRecentCommitStatusContexts(db.DefaultContext, repo2.ID, time.Hour) + contexts, err := git_model.FindRepoRecentCommitStatusContexts(t.Context(), repo2.ID, time.Hour) assert.NoError(t, err) if assert.Len(t, contexts, 1) { assert.Equal(t, "compliance/lint-backend", contexts[0]) @@ -239,7 +238,7 @@ func TestCommitStatusesHideActionsURL(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{ID: 791, RepoID: repo.ID}) - assert.NoError(t, run.LoadAttributes(db.DefaultContext)) + assert.NoError(t, run.LoadAttributes(t.Context())) statuses := []*git_model.CommitStatus{ { @@ -252,7 +251,7 @@ func TestCommitStatusesHideActionsURL(t *testing.T) { }, } - git_model.CommitStatusesHideActionsURL(db.DefaultContext, statuses) + git_model.CommitStatusesHideActionsURL(t.Context(), statuses) assert.Empty(t, statuses[0].TargetURL) assert.Equal(t, "https://mycicd.org/1", statuses[1].TargetURL) } @@ -264,7 +263,7 @@ func TestGetCountLatestCommitStatus(t *testing.T) { sha1 := "1234123412341234123412341234123412341234" // the mocked commit ID in test fixtures - commitStatuses, err := git_model.GetLatestCommitStatus(db.DefaultContext, repo1.ID, sha1, db.ListOptions{ + commitStatuses, err := git_model.GetLatestCommitStatus(t.Context(), repo1.ID, sha1, db.ListOptions{ Page: 1, PageSize: 2, }) @@ -275,7 +274,7 @@ func TestGetCountLatestCommitStatus(t *testing.T) { assert.Equal(t, commitstatus.CommitStatusError, commitStatuses[1].State) assert.Equal(t, "deploy/awesomeness", commitStatuses[1].Context) - count, err := git_model.CountLatestCommitStatus(db.DefaultContext, repo1.ID, sha1) + count, err := git_model.CountLatestCommitStatus(t.Context(), repo1.ID, sha1) assert.NoError(t, err) assert.EqualValues(t, 3, count) } diff --git a/models/git/lfs.go b/models/git/lfs.go index c471baf588..8bba060ff9 100644 --- a/models/git/lfs.go +++ b/models/git/lfs.go @@ -180,29 +180,25 @@ func RemoveLFSMetaObjectByOidFn(ctx context.Context, repoID int64, oid string, f return 0, ErrLFSObjectNotExist } - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return 0, err - } - defer committer.Close() + return db.WithTx2(ctx, func(ctx context.Context) (int64, error) { + m := &LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}, RepositoryID: repoID} + if _, err := db.DeleteByBean(ctx, m); err != nil { + return -1, err + } - m := &LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}, RepositoryID: repoID} - if _, err := db.DeleteByBean(ctx, m); err != nil { - return -1, err - } - - count, err := db.CountByBean(ctx, &LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}}) - if err != nil { - return count, err - } - - if fn != nil { - if err := fn(count); err != nil { + count, err := db.CountByBean(ctx, &LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}}) + if err != nil { return count, err } - } - return count, committer.Commit() + if fn != nil { + if err := fn(count); err != nil { + return count, err + } + } + + return count, nil + }) } // GetLFSMetaObjects returns all LFSMetaObjects associated with a repository @@ -243,56 +239,46 @@ func ExistsLFSObject(ctx context.Context, oid string) (bool, error) { // LFSAutoAssociate auto associates accessible LFSMetaObjects func LFSAutoAssociate(ctx context.Context, metas []*LFSMetaObject, user *user_model.User, repoID int64) error { - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return err - } - defer committer.Close() + return db.WithTx(ctx, func(ctx context.Context) error { + oids := make([]any, len(metas)) + oidMap := make(map[string]*LFSMetaObject, len(metas)) + for i, meta := range metas { + oids[i] = meta.Oid + oidMap[meta.Oid] = meta + } - sess := db.GetEngine(ctx) + if !user.IsAdmin { + newMetas := make([]*LFSMetaObject, 0, len(metas)) + cond := builder.In( + "`lfs_meta_object`.repository_id", + builder.Select("`repository`.id").From("repository").Where(repo_model.AccessibleRepositoryCondition(user, unit.TypeInvalid)), + ) + if err := db.GetEngine(ctx).Cols("oid").Where(cond).In("oid", oids...).GroupBy("oid").Find(&newMetas); err != nil { + return err + } + if len(newMetas) != len(oidMap) { + return fmt.Errorf("unable collect all LFS objects from database, expected %d, actually %d", len(oidMap), len(newMetas)) + } + for i := range newMetas { + newMetas[i].Size = oidMap[newMetas[i].Oid].Size + newMetas[i].RepositoryID = repoID + } + return db.Insert(ctx, newMetas) + } - oids := make([]any, len(metas)) - oidMap := make(map[string]*LFSMetaObject, len(metas)) - for i, meta := range metas { - oids[i] = meta.Oid - oidMap[meta.Oid] = meta - } - - if !user.IsAdmin { - newMetas := make([]*LFSMetaObject, 0, len(metas)) - cond := builder.In( - "`lfs_meta_object`.repository_id", - builder.Select("`repository`.id").From("repository").Where(repo_model.AccessibleRepositoryCondition(user, unit.TypeInvalid)), - ) - err = sess.Cols("oid").Where(cond).In("oid", oids...).GroupBy("oid").Find(&newMetas) - if err != nil { - return err - } - if len(newMetas) != len(oidMap) { - return fmt.Errorf("unable collect all LFS objects from database, expected %d, actually %d", len(oidMap), len(newMetas)) - } - for i := range newMetas { - newMetas[i].Size = oidMap[newMetas[i].Oid].Size - newMetas[i].RepositoryID = repoID - } - if err = db.Insert(ctx, newMetas); err != nil { - return err - } - } else { // admin can associate any LFS object to any repository, and we do not care about errors (eg: duplicated unique key), // even if error occurs, it won't hurt users and won't make things worse for i := range metas { p := lfs.Pointer{Oid: metas[i].Oid, Size: metas[i].Size} - _, err = sess.Insert(&LFSMetaObject{ + if err := db.Insert(ctx, &LFSMetaObject{ Pointer: p, RepositoryID: repoID, - }) - if err != nil { + }); err != nil { log.Warn("failed to insert LFS meta object %-v for repo_id: %d into database, err=%v", p, repoID, err) } } - } - return committer.Commit() + return nil + }) } // CopyLFS copies LFS data from one repo to another diff --git a/models/git/protected_branch_test.go b/models/git/protected_branch_test.go index 367992081d..3aa1d7daa8 100644 --- a/models/git/protected_branch_test.go +++ b/models/git/protected_branch_test.go @@ -105,17 +105,17 @@ func TestUpdateProtectBranchPriorities(t *testing.T) { } for _, pb := range protectedBranches { - _, err := db.GetEngine(db.DefaultContext).Insert(pb) + _, err := db.GetEngine(t.Context()).Insert(pb) assert.NoError(t, err) } // Test updating priorities newPriorities := []int64{protectedBranches[2].ID, protectedBranches[0].ID, protectedBranches[1].ID} - err := UpdateProtectBranchPriorities(db.DefaultContext, repo, newPriorities) + err := UpdateProtectBranchPriorities(t.Context(), repo, newPriorities) assert.NoError(t, err) // Verify new priorities - pbs, err := FindRepoProtectedBranchRules(db.DefaultContext, repo.ID) + pbs, err := FindRepoProtectedBranchRules(t.Context(), repo.ID) assert.NoError(t, err) expectedPriorities := map[string]int64{ @@ -133,7 +133,7 @@ func TestNewProtectBranchPriority(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - err := UpdateProtectBranch(db.DefaultContext, repo, &ProtectedBranch{ + err := UpdateProtectBranch(t.Context(), repo, &ProtectedBranch{ RepoID: repo.ID, RuleName: "branch-1", Priority: 1, @@ -146,10 +146,10 @@ func TestNewProtectBranchPriority(t *testing.T) { // Priority intentionally omitted } - err = UpdateProtectBranch(db.DefaultContext, repo, newPB, WhitelistOptions{}) + err = UpdateProtectBranch(t.Context(), repo, newPB, WhitelistOptions{}) assert.NoError(t, err) - savedPB2, err := GetFirstMatchProtectedBranchRule(db.DefaultContext, repo.ID, "branch-2") + savedPB2, err := GetFirstMatchProtectedBranchRule(t.Context(), repo.ID, "branch-2") assert.NoError(t, err) assert.Equal(t, int64(2), savedPB2.Priority) } diff --git a/models/git/protected_tag_test.go b/models/git/protected_tag_test.go index 164c33e28f..252eaf1bba 100644 --- a/models/git/protected_tag_test.go +++ b/models/git/protected_tag_test.go @@ -6,7 +6,6 @@ package git_test import ( "testing" - "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" "code.gitea.io/gitea/models/unittest" @@ -17,29 +16,29 @@ func TestIsUserAllowed(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) pt := &git_model.ProtectedTag{} - allowed, err := git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 1) + allowed, err := git_model.IsUserAllowedModifyTag(t.Context(), pt, 1) assert.NoError(t, err) assert.False(t, allowed) pt = &git_model.ProtectedTag{ AllowlistUserIDs: []int64{1}, } - allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 1) + allowed, err = git_model.IsUserAllowedModifyTag(t.Context(), pt, 1) assert.NoError(t, err) assert.True(t, allowed) - allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 2) + allowed, err = git_model.IsUserAllowedModifyTag(t.Context(), pt, 2) assert.NoError(t, err) assert.False(t, allowed) pt = &git_model.ProtectedTag{ AllowlistTeamIDs: []int64{1}, } - allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 1) + allowed, err = git_model.IsUserAllowedModifyTag(t.Context(), pt, 1) assert.NoError(t, err) assert.False(t, allowed) - allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 2) + allowed, err = git_model.IsUserAllowedModifyTag(t.Context(), pt, 2) assert.NoError(t, err) assert.True(t, allowed) @@ -47,11 +46,11 @@ func TestIsUserAllowed(t *testing.T) { AllowlistUserIDs: []int64{1}, AllowlistTeamIDs: []int64{1}, } - allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 1) + allowed, err = git_model.IsUserAllowedModifyTag(t.Context(), pt, 1) assert.NoError(t, err) assert.True(t, allowed) - allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 2) + allowed, err = git_model.IsUserAllowedModifyTag(t.Context(), pt, 2) assert.NoError(t, err) assert.True(t, allowed) } @@ -135,7 +134,7 @@ func TestIsUserAllowedToControlTag(t *testing.T) { } for n, c := range cases { - isAllowed, err := git_model.IsUserAllowedToControlTag(db.DefaultContext, protectedTags, c.name, c.userid) + isAllowed, err := git_model.IsUserAllowedToControlTag(t.Context(), protectedTags, c.name, c.userid) assert.NoError(t, err) assert.Equal(t, c.allowed, isAllowed, "case %d: error should match", n) } @@ -157,7 +156,7 @@ func TestIsUserAllowedToControlTag(t *testing.T) { } for n, c := range cases { - isAllowed, err := git_model.IsUserAllowedToControlTag(db.DefaultContext, protectedTags, c.name, c.userid) + isAllowed, err := git_model.IsUserAllowedToControlTag(t.Context(), protectedTags, c.name, c.userid) assert.NoError(t, err) assert.Equal(t, c.allowed, isAllowed, "case %d: error should match", n) } diff --git a/models/issues/assignees.go b/models/issues/assignees.go index efd992cda2..54f995dd2e 100644 --- a/models/issues/assignees.go +++ b/models/issues/assignees.go @@ -91,18 +91,10 @@ func GetAssignedIssues(ctx context.Context, opts *AssignedIssuesOptions) ([]*Iss // ToggleIssueAssignee changes a user between assigned and not assigned for this issue, and make issue comment for it. func ToggleIssueAssignee(ctx context.Context, issue *Issue, doer *user_model.User, assigneeID int64) (removed bool, comment *Comment, err error) { - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return false, nil, err - } - defer committer.Close() - - removed, comment, err = toggleIssueAssignee(ctx, issue, doer, assigneeID, false) - if err != nil { - return false, nil, err - } - - if err := committer.Commit(); err != nil { + if err := db.WithTx(ctx, func(ctx context.Context) error { + removed, comment, err = toggleIssueAssignee(ctx, issue, doer, assigneeID, false) + return err + }); err != nil { return false, nil, err } diff --git a/models/issues/assignees_test.go b/models/issues/assignees_test.go index 2c33efd99e..13922899dc 100644 --- a/models/issues/assignees_test.go +++ b/models/issues/assignees_test.go @@ -6,7 +6,6 @@ package issues_test import ( "testing" - "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -18,35 +17,35 @@ func TestUpdateAssignee(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // Fake issue with assignees - issue, err := issues_model.GetIssueByID(db.DefaultContext, 1) + issue, err := issues_model.GetIssueByID(t.Context(), 1) assert.NoError(t, err) - err = issue.LoadAttributes(db.DefaultContext) + err = issue.LoadAttributes(t.Context()) assert.NoError(t, err) // Assign multiple users - user2, err := user_model.GetUserByID(db.DefaultContext, 2) + user2, err := user_model.GetUserByID(t.Context(), 2) assert.NoError(t, err) - _, _, err = issues_model.ToggleIssueAssignee(db.DefaultContext, issue, &user_model.User{ID: 1}, user2.ID) + _, _, err = issues_model.ToggleIssueAssignee(t.Context(), issue, &user_model.User{ID: 1}, user2.ID) assert.NoError(t, err) - org3, err := user_model.GetUserByID(db.DefaultContext, 3) + org3, err := user_model.GetUserByID(t.Context(), 3) assert.NoError(t, err) - _, _, err = issues_model.ToggleIssueAssignee(db.DefaultContext, issue, &user_model.User{ID: 1}, org3.ID) + _, _, err = issues_model.ToggleIssueAssignee(t.Context(), issue, &user_model.User{ID: 1}, org3.ID) assert.NoError(t, err) - user1, err := user_model.GetUserByID(db.DefaultContext, 1) // This user is already assigned (see the definition in fixtures), so running UpdateAssignee should unassign him + user1, err := user_model.GetUserByID(t.Context(), 1) // This user is already assigned (see the definition in fixtures), so running UpdateAssignee should unassign him assert.NoError(t, err) - _, _, err = issues_model.ToggleIssueAssignee(db.DefaultContext, issue, &user_model.User{ID: 1}, user1.ID) + _, _, err = issues_model.ToggleIssueAssignee(t.Context(), issue, &user_model.User{ID: 1}, user1.ID) assert.NoError(t, err) // Check if he got removed - isAssigned, err := issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, user1) + isAssigned, err := issues_model.IsUserAssignedToIssue(t.Context(), issue, user1) assert.NoError(t, err) assert.False(t, isAssigned) // Check if they're all there - err = issue.LoadAssignees(db.DefaultContext) + err = issue.LoadAssignees(t.Context()) assert.NoError(t, err) var expectedAssignees []*user_model.User @@ -57,12 +56,12 @@ func TestUpdateAssignee(t *testing.T) { } // Check if the user is assigned - isAssigned, err = issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, user2) + isAssigned, err = issues_model.IsUserAssignedToIssue(t.Context(), issue, user2) assert.NoError(t, err) assert.True(t, isAssigned) // This user should not be assigned - isAssigned, err = issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, &user_model.User{ID: 4}) + isAssigned, err = issues_model.IsUserAssignedToIssue(t.Context(), issue, &user_model.User{ID: 4}) assert.NoError(t, err) assert.False(t, isAssigned) } @@ -73,22 +72,22 @@ func TestMakeIDsFromAPIAssigneesToAdd(t *testing.T) { _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - IDs, err := issues_model.MakeIDsFromAPIAssigneesToAdd(db.DefaultContext, "", []string{""}) + IDs, err := issues_model.MakeIDsFromAPIAssigneesToAdd(t.Context(), "", []string{""}) assert.NoError(t, err) assert.Equal(t, []int64{}, IDs) - _, err = issues_model.MakeIDsFromAPIAssigneesToAdd(db.DefaultContext, "", []string{"none_existing_user"}) + _, err = issues_model.MakeIDsFromAPIAssigneesToAdd(t.Context(), "", []string{"none_existing_user"}) assert.Error(t, err) - IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(db.DefaultContext, "user1", []string{"user1"}) + IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(t.Context(), "user1", []string{"user1"}) assert.NoError(t, err) assert.Equal(t, []int64{1}, IDs) - IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(db.DefaultContext, "user2", []string{""}) + IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(t.Context(), "user2", []string{""}) assert.NoError(t, err) assert.Equal(t, []int64{2}, IDs) - IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(db.DefaultContext, "", []string{"user1", "user2"}) + IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(t.Context(), "", []string{"user1", "user2"}) assert.NoError(t, err) assert.Equal(t, []int64{1, 2}, IDs) } diff --git a/models/issues/comment.go b/models/issues/comment.go index d22f08fa87..3a4049700d 100644 --- a/models/issues/comment.go +++ b/models/issues/comment.go @@ -279,8 +279,8 @@ type Comment struct { DependentIssue *Issue `xorm:"-"` CommitID int64 - Line int64 // - previous line / + proposed line - TreePath string + Line int64 // - previous line / + proposed line + TreePath string `xorm:"VARCHAR(4000)"` // SQLServer only supports up to 4000 Content string `xorm:"LONGTEXT"` ContentVersion int `xorm:"NOT NULL DEFAULT 0"` RenderedContent template.HTML `xorm:"-"` @@ -414,7 +414,7 @@ func (c *Comment) HTMLURL(ctx context.Context) string { log.Error("loadRepo(%d): %v", c.Issue.RepoID, err) return "" } - return c.Issue.HTMLURL() + c.hashLink(ctx) + return c.Issue.HTMLURL(ctx) + c.hashLink(ctx) } // Link formats a relative URL-string to the issue-comment @@ -483,7 +483,7 @@ func (c *Comment) IssueURL(ctx context.Context) string { log.Error("loadRepo(%d): %v", c.Issue.RepoID, err) return "" } - return c.Issue.HTMLURL() + return c.Issue.HTMLURL(ctx) } // PRURL formats a URL-string to the pull-request @@ -503,7 +503,7 @@ func (c *Comment) PRURL(ctx context.Context) string { if !c.Issue.IsPull { return "" } - return c.Issue.HTMLURL() + return c.Issue.HTMLURL(ctx) } // CommentHashTag returns unique hash tag for comment id. diff --git a/models/issues/comment_test.go b/models/issues/comment_test.go index c08e3b970d..3660f9c939 100644 --- a/models/issues/comment_test.go +++ b/models/issues/comment_test.go @@ -24,7 +24,7 @@ func TestCreateComment(t *testing.T) { doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) now := time.Now().Unix() - comment, err := issues_model.CreateComment(db.DefaultContext, &issues_model.CreateCommentOptions{ + comment, err := issues_model.CreateComment(t.Context(), &issues_model.CreateCommentOptions{ Type: issues_model.CommentTypeComment, Doer: doer, Repo: repo, @@ -52,9 +52,9 @@ func Test_UpdateCommentAttachment(t *testing.T) { attachment := repo_model.Attachment{ Name: "test.txt", } - assert.NoError(t, db.Insert(db.DefaultContext, &attachment)) + assert.NoError(t, db.Insert(t.Context(), &attachment)) - err := issues_model.UpdateCommentAttachments(db.DefaultContext, comment, []string{attachment.UUID}) + err := issues_model.UpdateCommentAttachments(t.Context(), comment, []string{attachment.UUID}) assert.NoError(t, err) attachment2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{ID: attachment.ID}) @@ -68,7 +68,7 @@ func TestFetchCodeComments(t *testing.T) { issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - res, err := issues_model.FetchCodeComments(db.DefaultContext, issue, user, false) + res, err := issues_model.FetchCodeComments(t.Context(), issue, user, false) assert.NoError(t, err) assert.Contains(t, res, "README.md") assert.Contains(t, res["README.md"], int64(4)) @@ -76,7 +76,7 @@ func TestFetchCodeComments(t *testing.T) { assert.Equal(t, int64(4), res["README.md"][4][0].ID) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - res, err = issues_model.FetchCodeComments(db.DefaultContext, issue, user2, false) + res, err = issues_model.FetchCodeComments(t.Context(), issue, user2, false) assert.NoError(t, err) assert.Len(t, res, 1) } @@ -92,7 +92,7 @@ func TestAsCommentType(t *testing.T) { func TestMigrate_InsertIssueComments(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) - _ = issue.LoadRepo(db.DefaultContext) + _ = issue.LoadRepo(t.Context()) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}) reaction := &issues_model.Reaction{ Type: "heart", @@ -107,7 +107,7 @@ func TestMigrate_InsertIssueComments(t *testing.T) { Reactions: []*issues_model.Reaction{reaction}, } - err := issues_model.InsertIssueComments(db.DefaultContext, []*issues_model.Comment{comment}) + err := issues_model.InsertIssueComments(t.Context(), []*issues_model.Comment{comment}) assert.NoError(t, err) issueModified := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) @@ -120,7 +120,7 @@ func Test_UpdateIssueNumComments(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) - assert.NoError(t, issues_model.UpdateIssueNumComments(db.DefaultContext, issue2.ID)) + assert.NoError(t, issues_model.UpdateIssueNumComments(t.Context(), issue2.ID)) issue2 = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) assert.Equal(t, 1, issue2.NumComments) } diff --git a/models/issues/content_history_test.go b/models/issues/content_history_test.go index 1caa73a948..d2fcc82b1d 100644 --- a/models/issues/content_history_test.go +++ b/models/issues/content_history_test.go @@ -17,7 +17,7 @@ import ( func TestContentHistory(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - dbCtx := db.DefaultContext + dbCtx := t.Context() timeStampNow := timeutil.TimeStampNow() _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 0, timeStampNow, "i-a", true) @@ -82,18 +82,18 @@ func TestContentHistory(t *testing.T) { func TestHasIssueContentHistoryForCommentOnly(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - _ = db.TruncateBeans(db.DefaultContext, &issues_model.ContentHistory{}) + _ = db.TruncateBeans(t.Context(), &issues_model.ContentHistory{}) - hasHistory1, _ := issues_model.HasIssueContentHistory(db.DefaultContext, 10, 0) + hasHistory1, _ := issues_model.HasIssueContentHistory(t.Context(), 10, 0) assert.False(t, hasHistory1) - hasHistory2, _ := issues_model.HasIssueContentHistory(db.DefaultContext, 10, 100) + hasHistory2, _ := issues_model.HasIssueContentHistory(t.Context(), 10, 100) assert.False(t, hasHistory2) - _ = issues_model.SaveIssueContentHistory(db.DefaultContext, 1, 10, 100, timeutil.TimeStampNow(), "c-a", true) - _ = issues_model.SaveIssueContentHistory(db.DefaultContext, 1, 10, 100, timeutil.TimeStampNow().Add(5), "c-b", false) + _ = issues_model.SaveIssueContentHistory(t.Context(), 1, 10, 100, timeutil.TimeStampNow(), "c-a", true) + _ = issues_model.SaveIssueContentHistory(t.Context(), 1, 10, 100, timeutil.TimeStampNow().Add(5), "c-b", false) - hasHistory1, _ = issues_model.HasIssueContentHistory(db.DefaultContext, 10, 0) + hasHistory1, _ = issues_model.HasIssueContentHistory(t.Context(), 10, 0) assert.False(t, hasHistory1) - hasHistory2, _ = issues_model.HasIssueContentHistory(db.DefaultContext, 10, 100) + hasHistory2, _ = issues_model.HasIssueContentHistory(t.Context(), 10, 100) assert.True(t, hasHistory2) } diff --git a/models/issues/dependency_test.go b/models/issues/dependency_test.go index 67418039de..0e6a870ff9 100644 --- a/models/issues/dependency_test.go +++ b/models/issues/dependency_test.go @@ -6,7 +6,6 @@ package issues_test import ( "testing" - "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -18,56 +17,56 @@ func TestCreateIssueDependency(t *testing.T) { // Prepare assert.NoError(t, unittest.PrepareTestDatabase()) - user1, err := user_model.GetUserByID(db.DefaultContext, 1) + user1, err := user_model.GetUserByID(t.Context(), 1) assert.NoError(t, err) - issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1) + issue1, err := issues_model.GetIssueByID(t.Context(), 1) assert.NoError(t, err) - issue2, err := issues_model.GetIssueByID(db.DefaultContext, 2) + issue2, err := issues_model.GetIssueByID(t.Context(), 2) assert.NoError(t, err) // Create a dependency and check if it was successful - err = issues_model.CreateIssueDependency(db.DefaultContext, user1, issue1, issue2) + err = issues_model.CreateIssueDependency(t.Context(), user1, issue1, issue2) assert.NoError(t, err) // Do it again to see if it will check if the dependency already exists - err = issues_model.CreateIssueDependency(db.DefaultContext, user1, issue1, issue2) + err = issues_model.CreateIssueDependency(t.Context(), user1, issue1, issue2) assert.Error(t, err) assert.True(t, issues_model.IsErrDependencyExists(err)) // Check for circular dependencies - err = issues_model.CreateIssueDependency(db.DefaultContext, user1, issue2, issue1) + err = issues_model.CreateIssueDependency(t.Context(), user1, issue2, issue1) assert.Error(t, err) assert.True(t, issues_model.IsErrCircularDependency(err)) _ = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeAddDependency, PosterID: user1.ID, IssueID: issue1.ID}) // Check if dependencies left is correct - left, err := issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1) + left, err := issues_model.IssueNoDependenciesLeft(t.Context(), issue1) assert.NoError(t, err) assert.False(t, left) // Close #2 and check again - _, err = issues_model.CloseIssue(db.DefaultContext, issue2, user1) + _, err = issues_model.CloseIssue(t.Context(), issue2, user1) assert.NoError(t, err) - issue2Closed, err := issues_model.GetIssueByID(db.DefaultContext, 2) + issue2Closed, err := issues_model.GetIssueByID(t.Context(), 2) assert.NoError(t, err) assert.True(t, issue2Closed.IsClosed) - left, err = issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1) + left, err = issues_model.IssueNoDependenciesLeft(t.Context(), issue1) assert.NoError(t, err) assert.True(t, left) // Test removing the dependency - err = issues_model.RemoveIssueDependency(db.DefaultContext, user1, issue1, issue2, issues_model.DependencyTypeBlockedBy) + err = issues_model.RemoveIssueDependency(t.Context(), user1, issue1, issue2, issues_model.DependencyTypeBlockedBy) assert.NoError(t, err) - _, err = issues_model.ReopenIssue(db.DefaultContext, issue2, user1) + _, err = issues_model.ReopenIssue(t.Context(), issue2, user1) assert.NoError(t, err) - issue2Reopened, err := issues_model.GetIssueByID(db.DefaultContext, 2) + issue2Reopened, err := issues_model.GetIssueByID(t.Context(), 2) assert.NoError(t, err) assert.False(t, issue2Reopened.IsClosed) } diff --git a/models/issues/issue.go b/models/issues/issue.go index ef651359ab..053b96dceb 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -405,14 +405,14 @@ func (issue *Issue) APIURL(ctx context.Context) string { } // HTMLURL returns the absolute URL to this issue. -func (issue *Issue) HTMLURL() string { +func (issue *Issue) HTMLURL(ctx context.Context) string { var path string if issue.IsPull { path = "pulls" } else { path = "issues" } - return fmt.Sprintf("%s/%s/%d", issue.Repo.HTMLURL(), path, issue.Index) + return fmt.Sprintf("%s/%s/%d", issue.Repo.HTMLURL(ctx), path, issue.Index) } // Link returns the issue's relative URL. diff --git a/models/issues/issue_label_test.go b/models/issues/issue_label_test.go index 0470b99e24..6ccf6debae 100644 --- a/models/issues/issue_label_test.go +++ b/models/issues/issue_label_test.go @@ -6,7 +6,6 @@ package issues_test import ( "testing" - "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -22,7 +21,7 @@ func TestNewIssueLabelsScope(t *testing.T) { label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 8}) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - assert.NoError(t, issues_model.NewIssueLabels(db.DefaultContext, issue, []*issues_model.Label{label1, label2}, doer)) + assert.NoError(t, issues_model.NewIssueLabels(t.Context(), issue, []*issues_model.Label{label1, label2}, doer)) assert.Len(t, issue.Labels, 1) assert.Equal(t, label2.ID, issue.Labels[0].ID) diff --git a/models/issues/issue_list_test.go b/models/issues/issue_list_test.go index 5b4d2ca5ab..e9dc412331 100644 --- a/models/issues/issue_list_test.go +++ b/models/issues/issue_list_test.go @@ -6,7 +6,6 @@ package issues_test import ( "testing" - "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/setting" @@ -23,7 +22,7 @@ func TestIssueList_LoadRepositories(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}), } - repos, err := issueList.LoadRepositories(db.DefaultContext) + repos, err := issueList.LoadRepositories(t.Context()) assert.NoError(t, err) assert.Len(t, repos, 2) for _, issue := range issueList { @@ -39,7 +38,7 @@ func TestIssueList_LoadAttributes(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}), } - assert.NoError(t, issueList.LoadAttributes(db.DefaultContext)) + assert.NoError(t, issueList.LoadAttributes(t.Context())) for _, issue := range issueList { assert.Equal(t, issue.RepoID, issue.Repo.ID) for _, label := range issue.Labels { diff --git a/models/issues/issue_search.go b/models/issues/issue_search.go index 79bd6a19b0..466e788d6c 100644 --- a/models/issues/issue_search.go +++ b/models/issues/issue_search.go @@ -106,8 +106,8 @@ func applySorts(sess *xorm.Session, sortType string, priorityRepoID int64) { "WHEN milestone.deadline_unix = 0 OR milestone.deadline_unix IS NULL THEN issue.deadline_unix " + "WHEN milestone.deadline_unix < issue.deadline_unix OR issue.deadline_unix = 0 THEN milestone.deadline_unix " + "ELSE issue.deadline_unix END ASC"). - Desc("issue.created_unix"). - Desc("issue.id") + Asc("issue.created_unix"). + Asc("issue.id") case "farduedate": sess.Join("LEFT", "milestone", "issue.milestone_id = milestone.id"). OrderBy("CASE " + diff --git a/models/issues/issue_test.go b/models/issues/issue_test.go index 1c5db55bbc..09fd492667 100644 --- a/models/issues/issue_test.go +++ b/models/issues/issue_test.go @@ -34,7 +34,7 @@ func TestIssue_ReplaceLabels(t *testing.T) { for i, labelID := range labelIDs { labels[i] = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID, RepoID: repo.ID}) } - assert.NoError(t, issues_model.ReplaceIssueLabels(db.DefaultContext, issue, labels, doer)) + assert.NoError(t, issues_model.ReplaceIssueLabels(t.Context(), issue, labels, doer)) unittest.AssertCount(t, &issues_model.IssueLabel{IssueID: issueID}, len(expectedLabelIDs)) for _, labelID := range expectedLabelIDs { unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issueID, LabelID: labelID}) @@ -54,7 +54,7 @@ func TestIssue_ReplaceLabels(t *testing.T) { func Test_GetIssueIDsByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - ids, err := issues_model.GetIssueIDsByRepoID(db.DefaultContext, 1) + ids, err := issues_model.GetIssueIDsByRepoID(t.Context(), 1) assert.NoError(t, err) assert.Len(t, ids, 5) } @@ -62,16 +62,16 @@ func Test_GetIssueIDsByRepoID(t *testing.T) { func TestIssueAPIURL(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) - err := issue.LoadAttributes(db.DefaultContext) + err := issue.LoadAttributes(t.Context()) assert.NoError(t, err) - assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/issues/1", issue.APIURL(db.DefaultContext)) + assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/issues/1", issue.APIURL(t.Context())) } func TestGetIssuesByIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(expectedIssueIDs, nonExistentIssueIDs []int64) { - issues, err := issues_model.GetIssuesByIDs(db.DefaultContext, append(expectedIssueIDs, nonExistentIssueIDs...), true) + issues, err := issues_model.GetIssuesByIDs(t.Context(), append(expectedIssueIDs, nonExistentIssueIDs...), true) assert.NoError(t, err) actualIssueIDs := make([]int64, len(issues)) for i, issue := range issues { @@ -88,9 +88,9 @@ func TestGetParticipantIDsByIssue(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) checkParticipants := func(issueID int64, userIDs []int) { - issue, err := issues_model.GetIssueByID(db.DefaultContext, issueID) + issue, err := issues_model.GetIssueByID(t.Context(), issueID) assert.NoError(t, err) - participants, err := issue.GetParticipantIDsByIssue(db.DefaultContext) + participants, err := issue.GetParticipantIDsByIssue(t.Context()) if assert.NoError(t, err) { participantsIDs := make([]int, len(participants)) for i, uid := range participants { @@ -122,7 +122,7 @@ func TestIssue_ClearLabels(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}) - assert.NoError(t, issues_model.ClearIssueLabels(db.DefaultContext, issue, doer)) + assert.NoError(t, issues_model.ClearIssueLabels(t.Context(), issue, doer)) unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: test.issueID}) } } @@ -138,7 +138,7 @@ func TestUpdateIssueCols(t *testing.T) { issue.Content = "This should have no effect" now := time.Now().Unix() - assert.NoError(t, issues_model.UpdateIssueCols(db.DefaultContext, issue, "name")) + assert.NoError(t, issues_model.UpdateIssueCols(t.Context(), issue, "name")) then := time.Now().Unix() updatedIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID}) @@ -198,7 +198,7 @@ func TestIssues(t *testing.T) { []int64{2}, }, } { - issues, err := issues_model.Issues(db.DefaultContext, &test.Opts) + issues, err := issues_model.Issues(t.Context(), &test.Opts) assert.NoError(t, err) if assert.Len(t, issues, len(test.ExpectedIssueIDs)) { for i, issue := range issues { @@ -210,9 +210,9 @@ func TestIssues(t *testing.T) { func TestIssue_loadTotalTimes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - ms, err := issues_model.GetIssueByID(db.DefaultContext, 2) + ms, err := issues_model.GetIssueByID(t.Context(), 2) assert.NoError(t, err) - assert.NoError(t, ms.LoadTotalTimes(db.DefaultContext)) + assert.NoError(t, ms.LoadTotalTimes(t.Context())) assert.Equal(t, int64(3682), ms.TotalTrackedTime) } @@ -229,10 +229,10 @@ func testInsertIssue(t *testing.T, title, content string, expectIndex int64) *is Title: title, Content: content, } - err := issues_model.NewIssue(db.DefaultContext, repo, &issue, nil, nil) + err := issues_model.NewIssue(t.Context(), repo, &issue, nil, nil) assert.NoError(t, err) - has, err := db.GetEngine(db.DefaultContext).ID(issue.ID).Get(&newIssue) + has, err := db.GetEngine(t.Context()).ID(issue.ID).Get(&newIssue) assert.NoError(t, err) assert.True(t, has) assert.Equal(t, issue.Title, newIssue.Title) @@ -249,11 +249,11 @@ func TestIssue_InsertIssue(t *testing.T) { // there are 5 issues and max index is 5 on repository 1, so this one should 6 issue := testInsertIssue(t, "my issue1", "special issue's comments?", 6) - _, err := db.DeleteByID[issues_model.Issue](db.DefaultContext, issue.ID) + _, err := db.DeleteByID[issues_model.Issue](t.Context(), issue.ID) assert.NoError(t, err) issue = testInsertIssue(t, `my issue2, this is my son's love \n \r \ `, "special issue's '' comments?", 7) - _, err = db.DeleteByID[issues_model.Issue](db.DefaultContext, issue.ID) + _, err = db.DeleteByID[issues_model.Issue](t.Context(), issue.ID) assert.NoError(t, err) } @@ -265,7 +265,7 @@ func TestIssue_ResolveMentions(t *testing.T) { r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: o.ID, LowerName: repo}) issue := &issues_model.Issue{RepoID: r.ID} d := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: doer}) - resolved, err := issues_model.ResolveIssueMentionsByVisibility(db.DefaultContext, issue, d, mentions) + resolved, err := issues_model.ResolveIssueMentionsByVisibility(t.Context(), issue, d, mentions) assert.NoError(t, err) ids := make([]int64, len(resolved)) for i, user := range resolved { @@ -345,7 +345,7 @@ func TestCorrectIssueStats(t *testing.T) { // Now we will call the GetIssueStats with these IDs and if working, // get the correct stats back. - issueStats, err := issues_model.GetIssueStats(db.DefaultContext, &issues_model.IssuesOptions{ + issueStats, err := issues_model.GetIssueStats(t.Context(), &issues_model.IssuesOptions{ RepoIDs: []int64{1}, IssueIDs: ids, }) @@ -361,7 +361,7 @@ func TestMilestoneList_LoadTotalTrackedTimes(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}), } - assert.NoError(t, miles.LoadTotalTrackedTimes(db.DefaultContext)) + assert.NoError(t, miles.LoadTotalTrackedTimes(t.Context())) assert.Equal(t, int64(3682), miles[0].TotalTrackedTime) } @@ -370,14 +370,14 @@ func TestLoadTotalTrackedTime(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}) - assert.NoError(t, milestone.LoadTotalTrackedTime(db.DefaultContext)) + assert.NoError(t, milestone.LoadTotalTrackedTime(t.Context())) assert.Equal(t, int64(3682), milestone.TotalTrackedTime) } func TestCountIssues(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - count, err := issues_model.CountIssues(db.DefaultContext, &issues_model.IssuesOptions{}) + count, err := issues_model.CountIssues(t.Context(), &issues_model.IssuesOptions{}) assert.NoError(t, err) assert.EqualValues(t, 22, count) } @@ -392,7 +392,7 @@ func TestIssueLoadAttributes(t *testing.T) { } for _, issue := range issueList { - assert.NoError(t, issue.LoadAttributes(db.DefaultContext)) + assert.NoError(t, issue.LoadAttributes(t.Context())) assert.Equal(t, issue.RepoID, issue.Repo.ID) for _, label := range issue.Labels { assert.Equal(t, issue.RepoID, label.RepoID) @@ -453,7 +453,7 @@ func assertCreateIssues(t *testing.T, isPull bool) { Labels: []*issues_model.Label{label}, Reactions: []*issues_model.Reaction{reaction}, } - err := issues_model.InsertIssues(db.DefaultContext, is) + err := issues_model.InsertIssues(t.Context(), is) assert.NoError(t, err) i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: title}) diff --git a/models/issues/issue_update.go b/models/issues/issue_update.go index 1c16817491..553e99aece 100644 --- a/models/issues/issue_update.go +++ b/models/issues/issue_update.go @@ -415,37 +415,28 @@ func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssue // NewIssue creates new issue with labels for repository. // The title will be cut off at 255 characters if it's longer than 255 characters. func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) { - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return err - } - defer committer.Close() - - idx, err := db.GetNextResourceIndex(ctx, "issue_index", repo.ID) - if err != nil { - return fmt.Errorf("generate issue index failed: %w", err) - } - - issue.Index = idx - issue.Title = util.EllipsisDisplayString(issue.Title, 255) - - if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{ - Repo: repo, - Issue: issue, - LabelIDs: labelIDs, - Attachments: uuids, - }); err != nil { - if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) { - return err + return db.WithTx(ctx, func(ctx context.Context) error { + idx, err := db.GetNextResourceIndex(ctx, "issue_index", repo.ID) + if err != nil { + return fmt.Errorf("generate issue index failed: %w", err) } - return fmt.Errorf("newIssue: %w", err) - } - if err = committer.Commit(); err != nil { - return fmt.Errorf("Commit: %w", err) - } + issue.Index = idx + issue.Title = util.EllipsisDisplayString(issue.Title, 255) - return nil + if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{ + Repo: repo, + Issue: issue, + LabelIDs: labelIDs, + Attachments: uuids, + }); err != nil { + if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) { + return err + } + return fmt.Errorf("newIssue: %w", err) + } + return nil + }) } // UpdateIssueMentions updates issue-user relations for mentioned users. diff --git a/models/issues/issue_user_test.go b/models/issues/issue_user_test.go index 7c21aa15ee..ec6d85c2bb 100644 --- a/models/issues/issue_user_test.go +++ b/models/issues/issue_user_test.go @@ -28,8 +28,8 @@ func Test_NewIssueUsers(t *testing.T) { } // artificially insert new issue - require.NoError(t, db.Insert(db.DefaultContext, newIssue)) - require.NoError(t, issues_model.NewIssueUsers(db.DefaultContext, repo, newIssue)) + require.NoError(t, db.Insert(t.Context(), newIssue)) + require.NoError(t, issues_model.NewIssueUsers(t.Context(), repo, newIssue)) // issue_user table should now have entries for new issue unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: newIssue.ID, UID: newIssue.PosterID}) @@ -40,13 +40,13 @@ func TestUpdateIssueUserByRead(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) - assert.NoError(t, issues_model.UpdateIssueUserByRead(db.DefaultContext, 4, issue.ID)) + assert.NoError(t, issues_model.UpdateIssueUserByRead(t.Context(), 4, issue.ID)) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: issue.ID, UID: 4}, "is_read=1") - assert.NoError(t, issues_model.UpdateIssueUserByRead(db.DefaultContext, 4, issue.ID)) + assert.NoError(t, issues_model.UpdateIssueUserByRead(t.Context(), 4, issue.ID)) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: issue.ID, UID: 4}, "is_read=1") - assert.NoError(t, issues_model.UpdateIssueUserByRead(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)) + assert.NoError(t, issues_model.UpdateIssueUserByRead(t.Context(), unittest.NonexistentID, unittest.NonexistentID)) } func TestUpdateIssueUsersByMentions(t *testing.T) { @@ -54,7 +54,7 @@ func TestUpdateIssueUsersByMentions(t *testing.T) { issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) uids := []int64{2, 5} - assert.NoError(t, issues_model.UpdateIssueUsersByMentions(db.DefaultContext, issue.ID, uids)) + assert.NoError(t, issues_model.UpdateIssueUsersByMentions(t.Context(), issue.ID, uids)) for _, uid := range uids { unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: issue.ID, UID: uid}, "is_mentioned=1") } diff --git a/models/issues/issue_watch_test.go b/models/issues/issue_watch_test.go index fad94e243e..c860e8b8ca 100644 --- a/models/issues/issue_watch_test.go +++ b/models/issues/issue_watch_test.go @@ -16,11 +16,11 @@ import ( func TestCreateOrUpdateIssueWatch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.NoError(t, issues_model.CreateOrUpdateIssueWatch(db.DefaultContext, 3, 1, true)) + assert.NoError(t, issues_model.CreateOrUpdateIssueWatch(t.Context(), 3, 1, true)) iw := unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 3, IssueID: 1}) assert.True(t, iw.IsWatching) - assert.NoError(t, issues_model.CreateOrUpdateIssueWatch(db.DefaultContext, 1, 1, false)) + assert.NoError(t, issues_model.CreateOrUpdateIssueWatch(t.Context(), 1, 1, false)) iw = unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 1, IssueID: 1}) assert.False(t, iw.IsWatching) } @@ -28,16 +28,16 @@ func TestCreateOrUpdateIssueWatch(t *testing.T) { func TestGetIssueWatch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - _, exists, err := issues_model.GetIssueWatch(db.DefaultContext, 9, 1) + _, exists, err := issues_model.GetIssueWatch(t.Context(), 9, 1) assert.True(t, exists) assert.NoError(t, err) - iw, exists, err := issues_model.GetIssueWatch(db.DefaultContext, 2, 2) + iw, exists, err := issues_model.GetIssueWatch(t.Context(), 2, 2) assert.True(t, exists) assert.NoError(t, err) assert.False(t, iw.IsWatching) - _, exists, err = issues_model.GetIssueWatch(db.DefaultContext, 3, 1) + _, exists, err = issues_model.GetIssueWatch(t.Context(), 3, 1) assert.False(t, exists) assert.NoError(t, err) } @@ -45,22 +45,22 @@ func TestGetIssueWatch(t *testing.T) { func TestGetIssueWatchers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - iws, err := issues_model.GetIssueWatchers(db.DefaultContext, 1, db.ListOptions{}) + iws, err := issues_model.GetIssueWatchers(t.Context(), 1, db.ListOptions{}) assert.NoError(t, err) // Watcher is inactive, thus 0 assert.Empty(t, iws) - iws, err = issues_model.GetIssueWatchers(db.DefaultContext, 2, db.ListOptions{}) + iws, err = issues_model.GetIssueWatchers(t.Context(), 2, db.ListOptions{}) assert.NoError(t, err) // Watcher is explicit not watching assert.Empty(t, iws) - iws, err = issues_model.GetIssueWatchers(db.DefaultContext, 5, db.ListOptions{}) + iws, err = issues_model.GetIssueWatchers(t.Context(), 5, db.ListOptions{}) assert.NoError(t, err) // Issue has no Watchers assert.Empty(t, iws) - iws, err = issues_model.GetIssueWatchers(db.DefaultContext, 7, db.ListOptions{}) + iws, err = issues_model.GetIssueWatchers(t.Context(), 7, db.ListOptions{}) assert.NoError(t, err) // Issue has one watcher assert.Len(t, iws, 1) diff --git a/models/issues/issue_xref_test.go b/models/issues/issue_xref_test.go index 7f257330b7..b25a704bec 100644 --- a/models/issues/issue_xref_test.go +++ b/models/issues/issue_xref_test.go @@ -83,7 +83,7 @@ func TestXRef_NeuterCrossReferences(t *testing.T) { d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) i.Title = "title2, no mentions" - assert.NoError(t, issues_model.ChangeIssueTitle(db.DefaultContext, i, d, title)) + assert.NoError(t, issues_model.ChangeIssueTitle(t.Context(), i, d, title)) ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}) assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type) @@ -98,7 +98,7 @@ func TestXRef_ResolveCrossReferences(t *testing.T) { i1 := testCreateIssue(t, 1, 2, "title1", "content1", false) i2 := testCreateIssue(t, 1, 2, "title2", "content2", false) i3 := testCreateIssue(t, 1, 2, "title3", "content3", false) - _, err := issues_model.CloseIssue(db.DefaultContext, i3, d) + _, err := issues_model.CloseIssue(t.Context(), i3, d) assert.NoError(t, err) pr := testCreatePR(t, 1, 2, "titlepr", fmt.Sprintf("closes #%d", i1.Index)) @@ -118,7 +118,7 @@ func TestXRef_ResolveCrossReferences(t *testing.T) { c4 := testCreateComment(t, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i3.Index)) r4 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c4.ID}) - refs, err := pr.ResolveCrossReferences(db.DefaultContext) + refs, err := pr.ResolveCrossReferences(t.Context()) assert.NoError(t, err) assert.Len(t, refs, 3) assert.Equal(t, rp.ID, refs[0].ID, "bad ref rp: %+v", refs[0]) @@ -130,7 +130,7 @@ func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispu r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo}) d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}) - ctx, committer, err := db.TxContext(db.DefaultContext) + ctx, committer, err := db.TxContext(t.Context()) assert.NoError(t, err) defer committer.Close() @@ -163,7 +163,7 @@ func testCreatePR(t *testing.T, repo, doer int64, title, content string) *issues d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}) i := &issues_model.Issue{RepoID: r.ID, PosterID: d.ID, Poster: d, Title: title, Content: content, IsPull: true} pr := &issues_model.PullRequest{HeadRepoID: repo, BaseRepoID: repo, HeadBranch: "head", BaseBranch: "base", Status: issues_model.PullRequestStatusMergeable} - assert.NoError(t, issues_model.NewPullRequest(db.DefaultContext, r, i, nil, nil, pr)) + assert.NoError(t, issues_model.NewPullRequest(t.Context(), r, i, nil, nil, pr)) pr.Issue = i return pr } @@ -173,7 +173,7 @@ func testCreateComment(t *testing.T, doer, issue int64, content string) *issues_ i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue}) c := &issues_model.Comment{Type: issues_model.CommentTypeComment, PosterID: doer, Poster: d, IssueID: issue, Issue: i, Content: content} - ctx, committer, err := db.TxContext(db.DefaultContext) + ctx, committer, err := db.TxContext(t.Context()) assert.NoError(t, err) defer committer.Close() err = db.Insert(ctx, c) diff --git a/models/issues/label_test.go b/models/issues/label_test.go index 226036d543..50393855d9 100644 --- a/models/issues/label_test.go +++ b/models/issues/label_test.go @@ -61,15 +61,15 @@ func TestNewLabels(t *testing.T) { {RepoID: 4, Name: "labelName4", Color: "ABCDEF"}, {RepoID: 5, Name: "labelName5", Color: "DEF"}, } - assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: ""})) - assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "#45G"})) - assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "#12345G"})) - assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "45G"})) - assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "12345G"})) + assert.Error(t, issues_model.NewLabel(t.Context(), &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: ""})) + assert.Error(t, issues_model.NewLabel(t.Context(), &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "#45G"})) + assert.Error(t, issues_model.NewLabel(t.Context(), &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "#12345G"})) + assert.Error(t, issues_model.NewLabel(t.Context(), &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "45G"})) + assert.Error(t, issues_model.NewLabel(t.Context(), &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "12345G"})) for _, label := range labels { unittest.AssertNotExistsBean(t, label) } - assert.NoError(t, issues_model.NewLabels(db.DefaultContext, labels...)) + assert.NoError(t, issues_model.NewLabels(t.Context(), labels...)) for _, label := range labels { unittest.AssertExistsAndLoadBean(t, label, unittest.Cond("id = ?", label.ID)) } @@ -78,31 +78,31 @@ func TestNewLabels(t *testing.T) { func TestGetLabelByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - label, err := issues_model.GetLabelByID(db.DefaultContext, 1) + label, err := issues_model.GetLabelByID(t.Context(), 1) assert.NoError(t, err) assert.EqualValues(t, 1, label.ID) - _, err = issues_model.GetLabelByID(db.DefaultContext, unittest.NonexistentID) + _, err = issues_model.GetLabelByID(t.Context(), unittest.NonexistentID) assert.True(t, issues_model.IsErrLabelNotExist(err)) } func TestGetLabelInRepoByName(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - label, err := issues_model.GetLabelInRepoByName(db.DefaultContext, 1, "label1") + label, err := issues_model.GetLabelInRepoByName(t.Context(), 1, "label1") assert.NoError(t, err) assert.EqualValues(t, 1, label.ID) assert.Equal(t, "label1", label.Name) - _, err = issues_model.GetLabelInRepoByName(db.DefaultContext, 1, "") + _, err = issues_model.GetLabelInRepoByName(t.Context(), 1, "") assert.True(t, issues_model.IsErrRepoLabelNotExist(err)) - _, err = issues_model.GetLabelInRepoByName(db.DefaultContext, unittest.NonexistentID, "nonexistent") + _, err = issues_model.GetLabelInRepoByName(t.Context(), unittest.NonexistentID, "nonexistent") assert.True(t, issues_model.IsErrRepoLabelNotExist(err)) } func TestGetLabelInRepoByNames(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - labelIDs, err := issues_model.GetLabelIDsInRepoByNames(db.DefaultContext, 1, []string{"label1", "label2"}) + labelIDs, err := issues_model.GetLabelIDsInRepoByNames(t.Context(), 1, []string{"label1", "label2"}) assert.NoError(t, err) assert.Len(t, labelIDs, 2) @@ -114,7 +114,7 @@ func TestGetLabelInRepoByNames(t *testing.T) { func TestGetLabelInRepoByNamesDiscardsNonExistentLabels(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // label3 doesn't exists.. See labels.yml - labelIDs, err := issues_model.GetLabelIDsInRepoByNames(db.DefaultContext, 1, []string{"label1", "label2", "label3"}) + labelIDs, err := issues_model.GetLabelIDsInRepoByNames(t.Context(), 1, []string{"label1", "label2", "label3"}) assert.NoError(t, err) assert.Len(t, labelIDs, 2) @@ -126,20 +126,20 @@ func TestGetLabelInRepoByNamesDiscardsNonExistentLabels(t *testing.T) { func TestGetLabelInRepoByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - label, err := issues_model.GetLabelInRepoByID(db.DefaultContext, 1, 1) + label, err := issues_model.GetLabelInRepoByID(t.Context(), 1, 1) assert.NoError(t, err) assert.EqualValues(t, 1, label.ID) - _, err = issues_model.GetLabelInRepoByID(db.DefaultContext, 1, -1) + _, err = issues_model.GetLabelInRepoByID(t.Context(), 1, -1) assert.True(t, issues_model.IsErrRepoLabelNotExist(err)) - _, err = issues_model.GetLabelInRepoByID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) + _, err = issues_model.GetLabelInRepoByID(t.Context(), unittest.NonexistentID, unittest.NonexistentID) assert.True(t, issues_model.IsErrRepoLabelNotExist(err)) } func TestGetLabelsInRepoByIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - labels, err := issues_model.GetLabelsInRepoByIDs(db.DefaultContext, 1, []int64{1, 2, unittest.NonexistentID}) + labels, err := issues_model.GetLabelsInRepoByIDs(t.Context(), 1, []int64{1, 2, unittest.NonexistentID}) assert.NoError(t, err) if assert.Len(t, labels, 2) { assert.EqualValues(t, 1, labels[0].ID) @@ -150,7 +150,7 @@ func TestGetLabelsInRepoByIDs(t *testing.T) { func TestGetLabelsByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(repoID int64, sortType string, expectedIssueIDs []int64) { - labels, err := issues_model.GetLabelsByRepoID(db.DefaultContext, repoID, sortType, db.ListOptions{}) + labels, err := issues_model.GetLabelsByRepoID(t.Context(), repoID, sortType, db.ListOptions{}) assert.NoError(t, err) assert.Len(t, labels, len(expectedIssueIDs)) for i, label := range labels { @@ -167,46 +167,46 @@ func TestGetLabelsByRepoID(t *testing.T) { func TestGetLabelInOrgByName(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - label, err := issues_model.GetLabelInOrgByName(db.DefaultContext, 3, "orglabel3") + label, err := issues_model.GetLabelInOrgByName(t.Context(), 3, "orglabel3") assert.NoError(t, err) assert.EqualValues(t, 3, label.ID) assert.Equal(t, "orglabel3", label.Name) - _, err = issues_model.GetLabelInOrgByName(db.DefaultContext, 3, "") + _, err = issues_model.GetLabelInOrgByName(t.Context(), 3, "") assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) - _, err = issues_model.GetLabelInOrgByName(db.DefaultContext, 0, "orglabel3") + _, err = issues_model.GetLabelInOrgByName(t.Context(), 0, "orglabel3") assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) - _, err = issues_model.GetLabelInOrgByName(db.DefaultContext, -1, "orglabel3") + _, err = issues_model.GetLabelInOrgByName(t.Context(), -1, "orglabel3") assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) - _, err = issues_model.GetLabelInOrgByName(db.DefaultContext, unittest.NonexistentID, "nonexistent") + _, err = issues_model.GetLabelInOrgByName(t.Context(), unittest.NonexistentID, "nonexistent") assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) } func TestGetLabelInOrgByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - label, err := issues_model.GetLabelInOrgByID(db.DefaultContext, 3, 3) + label, err := issues_model.GetLabelInOrgByID(t.Context(), 3, 3) assert.NoError(t, err) assert.EqualValues(t, 3, label.ID) - _, err = issues_model.GetLabelInOrgByID(db.DefaultContext, 3, -1) + _, err = issues_model.GetLabelInOrgByID(t.Context(), 3, -1) assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) - _, err = issues_model.GetLabelInOrgByID(db.DefaultContext, 0, 3) + _, err = issues_model.GetLabelInOrgByID(t.Context(), 0, 3) assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) - _, err = issues_model.GetLabelInOrgByID(db.DefaultContext, -1, 3) + _, err = issues_model.GetLabelInOrgByID(t.Context(), -1, 3) assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) - _, err = issues_model.GetLabelInOrgByID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) + _, err = issues_model.GetLabelInOrgByID(t.Context(), unittest.NonexistentID, unittest.NonexistentID) assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) } func TestGetLabelsInOrgByIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - labels, err := issues_model.GetLabelsInOrgByIDs(db.DefaultContext, 3, []int64{3, 4, unittest.NonexistentID}) + labels, err := issues_model.GetLabelsInOrgByIDs(t.Context(), 3, []int64{3, 4, unittest.NonexistentID}) assert.NoError(t, err) if assert.Len(t, labels, 2) { assert.EqualValues(t, 3, labels[0].ID) @@ -217,7 +217,7 @@ func TestGetLabelsInOrgByIDs(t *testing.T) { func TestGetLabelsByOrgID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(orgID int64, sortType string, expectedIssueIDs []int64) { - labels, err := issues_model.GetLabelsByOrgID(db.DefaultContext, orgID, sortType, db.ListOptions{}) + labels, err := issues_model.GetLabelsByOrgID(t.Context(), orgID, sortType, db.ListOptions{}) assert.NoError(t, err) assert.Len(t, labels, len(expectedIssueIDs)) for i, label := range labels { @@ -229,10 +229,10 @@ func TestGetLabelsByOrgID(t *testing.T) { testSuccess(3, "reversealphabetically", []int64{4, 3}) testSuccess(3, "default", []int64{3, 4}) - _, err := issues_model.GetLabelsByOrgID(db.DefaultContext, 0, "leastissues", db.ListOptions{}) + _, err := issues_model.GetLabelsByOrgID(t.Context(), 0, "leastissues", db.ListOptions{}) assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) - _, err = issues_model.GetLabelsByOrgID(db.DefaultContext, -1, "leastissues", db.ListOptions{}) + _, err = issues_model.GetLabelsByOrgID(t.Context(), -1, "leastissues", db.ListOptions{}) assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) } @@ -240,13 +240,13 @@ func TestGetLabelsByOrgID(t *testing.T) { func TestGetLabelsByIssueID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - labels, err := issues_model.GetLabelsByIssueID(db.DefaultContext, 1) + labels, err := issues_model.GetLabelsByIssueID(t.Context(), 1) assert.NoError(t, err) if assert.Len(t, labels, 1) { assert.EqualValues(t, 1, labels[0].ID) } - labels, err = issues_model.GetLabelsByIssueID(db.DefaultContext, unittest.NonexistentID) + labels, err = issues_model.GetLabelsByIssueID(t.Context(), unittest.NonexistentID) assert.NoError(t, err) assert.Empty(t, labels) } @@ -265,7 +265,7 @@ func TestUpdateLabel(t *testing.T) { } label.Color = update.Color label.Name = update.Name - assert.NoError(t, issues_model.UpdateLabel(db.DefaultContext, update)) + assert.NoError(t, issues_model.UpdateLabel(t.Context(), update)) newLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}) assert.Equal(t, label.ID, newLabel.ID) assert.Equal(t, label.Color, newLabel.Color) @@ -278,21 +278,21 @@ func TestUpdateLabel(t *testing.T) { func TestDeleteLabel(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}) - assert.NoError(t, issues_model.DeleteLabel(db.DefaultContext, label.RepoID, label.ID)) + assert.NoError(t, issues_model.DeleteLabel(t.Context(), label.RepoID, label.ID)) unittest.AssertNotExistsBean(t, &issues_model.Label{ID: label.ID, RepoID: label.RepoID}) - assert.NoError(t, issues_model.DeleteLabel(db.DefaultContext, label.RepoID, label.ID)) + assert.NoError(t, issues_model.DeleteLabel(t.Context(), label.RepoID, label.ID)) unittest.AssertNotExistsBean(t, &issues_model.Label{ID: label.ID}) - assert.NoError(t, issues_model.DeleteLabel(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)) + assert.NoError(t, issues_model.DeleteLabel(t.Context(), unittest.NonexistentID, unittest.NonexistentID)) unittest.CheckConsistencyFor(t, &issues_model.Label{}, &repo_model.Repository{}) } func TestHasIssueLabel(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.True(t, issues_model.HasIssueLabel(db.DefaultContext, 1, 1)) - assert.False(t, issues_model.HasIssueLabel(db.DefaultContext, 1, 2)) - assert.False(t, issues_model.HasIssueLabel(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)) + assert.True(t, issues_model.HasIssueLabel(t.Context(), 1, 1)) + assert.False(t, issues_model.HasIssueLabel(t.Context(), 1, 2)) + assert.False(t, issues_model.HasIssueLabel(t.Context(), unittest.NonexistentID, unittest.NonexistentID)) } func TestNewIssueLabel(t *testing.T) { @@ -303,7 +303,7 @@ func TestNewIssueLabel(t *testing.T) { // add new IssueLabel prevNumIssues := label.NumIssues - assert.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, label, doer)) + assert.NoError(t, issues_model.NewIssueLabel(t.Context(), issue, label, doer)) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label.ID}) unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ Type: issues_model.CommentTypeLabel, @@ -316,7 +316,7 @@ func TestNewIssueLabel(t *testing.T) { assert.Equal(t, prevNumIssues+1, label.NumIssues) // re-add existing IssueLabel - assert.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, label, doer)) + assert.NoError(t, issues_model.NewIssueLabel(t.Context(), issue, label, doer)) unittest.CheckConsistencyFor(t, &issues_model.Issue{}, &issues_model.Label{}) } @@ -330,19 +330,19 @@ func TestNewIssueExclusiveLabel(t *testing.T) { exclusiveLabelB := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 8}) // coexisting regular and exclusive label - assert.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, otherLabel, doer)) - assert.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, exclusiveLabelA, doer)) + assert.NoError(t, issues_model.NewIssueLabel(t.Context(), issue, otherLabel, doer)) + assert.NoError(t, issues_model.NewIssueLabel(t.Context(), issue, exclusiveLabelA, doer)) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: otherLabel.ID}) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: exclusiveLabelA.ID}) // exclusive label replaces existing one - assert.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, exclusiveLabelB, doer)) + assert.NoError(t, issues_model.NewIssueLabel(t.Context(), issue, exclusiveLabelB, doer)) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: otherLabel.ID}) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: exclusiveLabelB.ID}) unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: exclusiveLabelA.ID}) // exclusive label replaces existing one again - assert.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, exclusiveLabelA, doer)) + assert.NoError(t, issues_model.NewIssueLabel(t.Context(), issue, exclusiveLabelA, doer)) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: otherLabel.ID}) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: exclusiveLabelA.ID}) unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: exclusiveLabelB.ID}) @@ -355,7 +355,7 @@ func TestNewIssueLabels(t *testing.T) { issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 5}) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - assert.NoError(t, issues_model.NewIssueLabels(db.DefaultContext, issue, []*issues_model.Label{label1, label2}, doer)) + assert.NoError(t, issues_model.NewIssueLabels(t.Context(), issue, []*issues_model.Label{label1, label2}, doer)) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label1.ID}) unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ Type: issues_model.CommentTypeLabel, @@ -373,7 +373,7 @@ func TestNewIssueLabels(t *testing.T) { assert.Equal(t, 1, label2.NumClosedIssues) // corner case: test empty slice - assert.NoError(t, issues_model.NewIssueLabels(db.DefaultContext, issue, []*issues_model.Label{}, doer)) + assert.NoError(t, issues_model.NewIssueLabels(t.Context(), issue, []*issues_model.Label{}, doer)) unittest.CheckConsistencyFor(t, &issues_model.Issue{}, &issues_model.Label{}) } @@ -394,7 +394,7 @@ func TestDeleteIssueLabel(t *testing.T) { } } - ctx, committer, err := db.TxContext(db.DefaultContext) + ctx, committer, err := db.TxContext(t.Context()) defer committer.Close() assert.NoError(t, err) assert.NoError(t, issues_model.DeleteIssueLabel(ctx, issue, label, doer)) diff --git a/models/issues/milestone_test.go b/models/issues/milestone_test.go index f73355c27d..107ad305d4 100644 --- a/models/issues/milestone_test.go +++ b/models/issues/milestone_test.go @@ -27,12 +27,12 @@ func TestMilestone_State(t *testing.T) { func TestGetMilestoneByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - milestone, err := issues_model.GetMilestoneByRepoID(db.DefaultContext, 1, 1) + milestone, err := issues_model.GetMilestoneByRepoID(t.Context(), 1, 1) assert.NoError(t, err) assert.EqualValues(t, 1, milestone.ID) assert.EqualValues(t, 1, milestone.RepoID) - _, err = issues_model.GetMilestoneByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) + _, err = issues_model.GetMilestoneByRepoID(t.Context(), unittest.NonexistentID, unittest.NonexistentID) assert.True(t, issues_model.IsErrMilestoneNotExist(err)) } @@ -45,7 +45,7 @@ func TestGetMilestonesByRepoID(t *testing.T) { isClosed = optional.Some(state == api.StateClosed) } repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) - milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + milestones, err := db.Find[issues_model.Milestone](t.Context(), issues_model.FindMilestoneOptions{ RepoID: repo.ID, IsClosed: isClosed, }) @@ -82,7 +82,7 @@ func TestGetMilestonesByRepoID(t *testing.T) { test(3, api.StateClosed) test(3, api.StateAll) - milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + milestones, err := db.Find[issues_model.Milestone](t.Context(), issues_model.FindMilestoneOptions{ RepoID: unittest.NonexistentID, IsClosed: optional.Some(false), }) @@ -95,7 +95,7 @@ func TestGetMilestones(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) test := func(sortType string, sortCond func(*issues_model.Milestone) int) { for _, page := range []int{0, 1} { - milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + milestones, err := db.Find[issues_model.Milestone](t.Context(), issues_model.FindMilestoneOptions{ ListOptions: db.ListOptions{ Page: page, PageSize: setting.UI.IssuePagingNum, @@ -112,7 +112,7 @@ func TestGetMilestones(t *testing.T) { } assert.True(t, sort.IntsAreSorted(values)) - milestones, err = db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + milestones, err = db.Find[issues_model.Milestone](t.Context(), issues_model.FindMilestoneOptions{ ListOptions: db.ListOptions{ Page: page, PageSize: setting.UI.IssuePagingNum, @@ -155,7 +155,7 @@ func TestCountRepoMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) - count, err := db.Count[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + count, err := db.Count[issues_model.Milestone](t.Context(), issues_model.FindMilestoneOptions{ RepoID: repoID, }) assert.NoError(t, err) @@ -165,7 +165,7 @@ func TestCountRepoMilestones(t *testing.T) { test(2) test(3) - count, err := db.Count[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + count, err := db.Count[issues_model.Milestone](t.Context(), issues_model.FindMilestoneOptions{ RepoID: unittest.NonexistentID, }) assert.NoError(t, err) @@ -176,7 +176,7 @@ func TestCountRepoClosedMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) - count, err := db.Count[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + count, err := db.Count[issues_model.Milestone](t.Context(), issues_model.FindMilestoneOptions{ RepoID: repoID, IsClosed: optional.Some(true), }) @@ -187,7 +187,7 @@ func TestCountRepoClosedMilestones(t *testing.T) { test(2) test(3) - count, err := db.Count[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + count, err := db.Count[issues_model.Milestone](t.Context(), issues_model.FindMilestoneOptions{ RepoID: unittest.NonexistentID, IsClosed: optional.Some(true), }) @@ -204,7 +204,7 @@ func TestCountMilestonesByRepoIDs(t *testing.T) { repo1OpenCount, repo1ClosedCount := milestonesCount(1) repo2OpenCount, repo2ClosedCount := milestonesCount(2) - openCounts, err := issues_model.CountMilestonesMap(db.DefaultContext, issues_model.FindMilestoneOptions{ + openCounts, err := issues_model.CountMilestonesMap(t.Context(), issues_model.FindMilestoneOptions{ RepoIDs: []int64{1, 2}, IsClosed: optional.Some(false), }) @@ -212,7 +212,7 @@ func TestCountMilestonesByRepoIDs(t *testing.T) { assert.EqualValues(t, repo1OpenCount, openCounts[1]) assert.EqualValues(t, repo2OpenCount, openCounts[2]) - closedCounts, err := issues_model.CountMilestonesMap(db.DefaultContext, + closedCounts, err := issues_model.CountMilestonesMap(t.Context(), issues_model.FindMilestoneOptions{ RepoIDs: []int64{1, 2}, IsClosed: optional.Some(true), @@ -228,7 +228,7 @@ func TestGetMilestonesByRepoIDs(t *testing.T) { repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) test := func(sortType string, sortCond func(*issues_model.Milestone) int) { for _, page := range []int{0, 1} { - openMilestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + openMilestones, err := db.Find[issues_model.Milestone](t.Context(), issues_model.FindMilestoneOptions{ ListOptions: db.ListOptions{ Page: page, PageSize: setting.UI.IssuePagingNum, @@ -245,7 +245,7 @@ func TestGetMilestonesByRepoIDs(t *testing.T) { } assert.True(t, sort.IntsAreSorted(values)) - closedMilestones, err := db.Find[issues_model.Milestone](db.DefaultContext, + closedMilestones, err := db.Find[issues_model.Milestone](t.Context(), issues_model.FindMilestoneOptions{ ListOptions: db.ListOptions{ Page: page, @@ -292,7 +292,7 @@ func TestNewMilestone(t *testing.T) { Content: "milestoneContent", } - assert.NoError(t, issues_model.NewMilestone(db.DefaultContext, milestone)) + assert.NoError(t, issues_model.NewMilestone(t.Context(), milestone)) unittest.AssertExistsAndLoadBean(t, milestone) unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{}) } @@ -301,22 +301,22 @@ func TestChangeMilestoneStatus(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}) - assert.NoError(t, issues_model.ChangeMilestoneStatus(db.DefaultContext, milestone, true)) + assert.NoError(t, issues_model.ChangeMilestoneStatus(t.Context(), milestone, true)) unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}, "is_closed=1") unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{}) - assert.NoError(t, issues_model.ChangeMilestoneStatus(db.DefaultContext, milestone, false)) + assert.NoError(t, issues_model.ChangeMilestoneStatus(t.Context(), milestone, false)) unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}, "is_closed=0") unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{}) } func TestDeleteMilestoneByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.NoError(t, issues_model.DeleteMilestoneByRepoID(db.DefaultContext, 1, 1)) + assert.NoError(t, issues_model.DeleteMilestoneByRepoID(t.Context(), 1, 1)) unittest.AssertNotExistsBean(t, &issues_model.Milestone{ID: 1}) unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: 1}) - assert.NoError(t, issues_model.DeleteMilestoneByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)) + assert.NoError(t, issues_model.DeleteMilestoneByRepoID(t.Context(), unittest.NonexistentID, unittest.NonexistentID)) } func TestUpdateMilestone(t *testing.T) { @@ -325,7 +325,7 @@ func TestUpdateMilestone(t *testing.T) { milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}) milestone.Name = " newMilestoneName " milestone.Content = "newMilestoneContent" - assert.NoError(t, issues_model.UpdateMilestone(db.DefaultContext, milestone, milestone.IsClosed)) + assert.NoError(t, issues_model.UpdateMilestone(t.Context(), milestone, milestone.IsClosed)) milestone = unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}) assert.Equal(t, "newMilestoneName", milestone.Name) unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) @@ -338,16 +338,16 @@ func TestUpdateMilestoneCounters(t *testing.T) { issue.IsClosed = true issue.ClosedUnix = timeutil.TimeStampNow() - _, err := db.GetEngine(db.DefaultContext).ID(issue.ID).Cols("is_closed", "closed_unix").Update(issue) + _, err := db.GetEngine(t.Context()).ID(issue.ID).Cols("is_closed", "closed_unix").Update(issue) assert.NoError(t, err) - assert.NoError(t, issues_model.UpdateMilestoneCounters(db.DefaultContext, issue.MilestoneID)) + assert.NoError(t, issues_model.UpdateMilestoneCounters(t.Context(), issue.MilestoneID)) unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) issue.IsClosed = false issue.ClosedUnix = 0 - _, err = db.GetEngine(db.DefaultContext).ID(issue.ID).Cols("is_closed", "closed_unix").Update(issue) + _, err = db.GetEngine(t.Context()).ID(issue.ID).Cols("is_closed", "closed_unix").Update(issue) assert.NoError(t, err) - assert.NoError(t, issues_model.UpdateMilestoneCounters(db.DefaultContext, issue.MilestoneID)) + assert.NoError(t, issues_model.UpdateMilestoneCounters(t.Context(), issue.MilestoneID)) unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) } @@ -360,7 +360,7 @@ func TestMigrate_InsertMilestones(t *testing.T) { RepoID: repo.ID, Name: name, } - err := issues_model.InsertMilestones(db.DefaultContext, ms) + err := issues_model.InsertMilestones(t.Context(), ms) assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, ms) repoModified := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo.ID}) diff --git a/models/issues/pull.go b/models/issues/pull.go index 00d7bfe1ca..7a37b627e1 100644 --- a/models/issues/pull.go +++ b/models/issues/pull.go @@ -29,6 +29,8 @@ import ( var ErrMustCollaborator = util.NewPermissionDeniedErrorf("user must be a collaborator") +const reviewedBy = "Reviewed-by: " + // ErrPullRequestNotExist represents a "PullRequestNotExist" kind of error. type ErrPullRequestNotExist struct { ID int64 @@ -348,7 +350,11 @@ type ReviewCount struct { func (pr *PullRequest) GetApprovalCounts(ctx context.Context) ([]*ReviewCount, error) { rCounts := make([]*ReviewCount, 0, 6) sess := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID) - return rCounts, sess.Select("issue_id, type, count(id) as `count`").Where("official = ? AND dismissed = ?", true, false).GroupBy("issue_id, type").Table("review").Find(&rCounts) + return rCounts, sess.Select("issue_id, type, count(id) as `count`"). + Where(builder.Eq{"official": true, "dismissed": false}). + GroupBy("issue_id, type"). + Table("review"). + Find(&rCounts) } // GetApprovers returns the approvers of the pull request @@ -392,7 +398,7 @@ func (pr *PullRequest) getReviewedByLines(ctx context.Context, writer io.Writer) } else if review.Reviewer == nil { continue } - if _, err := writer.Write([]byte("Reviewed-by: ")); err != nil { + if _, err := writer.Write([]byte(reviewedBy)); err != nil { return err } if _, err := writer.Write([]byte(review.Reviewer.NewGitSig().String())); err != nil { diff --git a/models/issues/pull_list_test.go b/models/issues/pull_list_test.go index eb2de006d6..437830701c 100644 --- a/models/issues/pull_list_test.go +++ b/models/issues/pull_list_test.go @@ -6,7 +6,6 @@ package issues_test import ( "testing" - "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" @@ -20,13 +19,13 @@ func TestPullRequestList_LoadAttributes(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}), unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}), } - assert.NoError(t, prs.LoadAttributes(db.DefaultContext)) + assert.NoError(t, prs.LoadAttributes(t.Context())) for _, pr := range prs { assert.NotNil(t, pr.Issue) assert.Equal(t, pr.IssueID, pr.Issue.ID) } - assert.NoError(t, issues_model.PullRequestList([]*issues_model.PullRequest{}).LoadAttributes(db.DefaultContext)) + assert.NoError(t, issues_model.PullRequestList([]*issues_model.PullRequest{}).LoadAttributes(t.Context())) } func TestPullRequestList_LoadReviewCommentsCounts(t *testing.T) { @@ -36,7 +35,7 @@ func TestPullRequestList_LoadReviewCommentsCounts(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}), unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}), } - reviewComments, err := prs.LoadReviewCommentsCounts(db.DefaultContext) + reviewComments, err := prs.LoadReviewCommentsCounts(t.Context()) assert.NoError(t, err) assert.Len(t, reviewComments, 2) for _, pr := range prs { @@ -51,7 +50,7 @@ func TestPullRequestList_LoadReviews(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}), unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}), } - reviewList, err := prs.LoadReviews(db.DefaultContext) + reviewList, err := prs.LoadReviews(t.Context()) assert.NoError(t, err) // 1, 7, 8, 9, 10, 22 assert.Len(t, reviewList, 6) diff --git a/models/issues/pull_test.go b/models/issues/pull_test.go index 39efaa5792..7089af253b 100644 --- a/models/issues/pull_test.go +++ b/models/issues/pull_test.go @@ -20,7 +20,7 @@ import ( func TestPullRequest_LoadAttributes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) - assert.NoError(t, pr.LoadAttributes(db.DefaultContext)) + assert.NoError(t, pr.LoadAttributes(t.Context())) assert.NotNil(t, pr.Merger) assert.Equal(t, pr.MergerID, pr.Merger.ID) } @@ -28,10 +28,10 @@ func TestPullRequest_LoadAttributes(t *testing.T) { func TestPullRequest_LoadIssue(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) - assert.NoError(t, pr.LoadIssue(db.DefaultContext)) + assert.NoError(t, pr.LoadIssue(t.Context())) assert.NotNil(t, pr.Issue) assert.Equal(t, int64(2), pr.Issue.ID) - assert.NoError(t, pr.LoadIssue(db.DefaultContext)) + assert.NoError(t, pr.LoadIssue(t.Context())) assert.NotNil(t, pr.Issue) assert.Equal(t, int64(2), pr.Issue.ID) } @@ -39,10 +39,10 @@ func TestPullRequest_LoadIssue(t *testing.T) { func TestPullRequest_LoadBaseRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) - assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext)) + assert.NoError(t, pr.LoadBaseRepo(t.Context())) assert.NotNil(t, pr.BaseRepo) assert.Equal(t, pr.BaseRepoID, pr.BaseRepo.ID) - assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext)) + assert.NoError(t, pr.LoadBaseRepo(t.Context())) assert.NotNil(t, pr.BaseRepo) assert.Equal(t, pr.BaseRepoID, pr.BaseRepo.ID) } @@ -50,7 +50,7 @@ func TestPullRequest_LoadBaseRepo(t *testing.T) { func TestPullRequest_LoadHeadRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) - assert.NoError(t, pr.LoadHeadRepo(db.DefaultContext)) + assert.NoError(t, pr.LoadHeadRepo(t.Context())) assert.NotNil(t, pr.HeadRepo) assert.Equal(t, pr.HeadRepoID, pr.HeadRepo.ID) } @@ -61,7 +61,7 @@ func TestPullRequest_LoadHeadRepo(t *testing.T) { func TestPullRequestsNewest(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs, count, err := issues_model.PullRequests(db.DefaultContext, 1, &issues_model.PullRequestsOptions{ + prs, count, err := issues_model.PullRequests(t.Context(), 1, &issues_model.PullRequestsOptions{ ListOptions: db.ListOptions{ Page: 1, }, @@ -91,16 +91,16 @@ func TestPullRequests_Closed_RecentSortType(t *testing.T) { } assert.NoError(t, unittest.PrepareTestDatabase()) - _, err := db.Exec(db.DefaultContext, "UPDATE issue SET closed_unix = 1707270001, updated_unix = 1707270001, is_closed = true WHERE id = 2") + _, err := db.Exec(t.Context(), "UPDATE issue SET closed_unix = 1707270001, updated_unix = 1707270001, is_closed = true WHERE id = 2") require.NoError(t, err) - _, err = db.Exec(db.DefaultContext, "UPDATE issue SET closed_unix = 1707271000, updated_unix = 1707279999, is_closed = true WHERE id = 3") + _, err = db.Exec(t.Context(), "UPDATE issue SET closed_unix = 1707271000, updated_unix = 1707279999, is_closed = true WHERE id = 3") require.NoError(t, err) - _, err = db.Exec(db.DefaultContext, "UPDATE issue SET closed_unix = 1707279999, updated_unix = 1707275555, is_closed = true WHERE id = 11") + _, err = db.Exec(t.Context(), "UPDATE issue SET closed_unix = 1707279999, updated_unix = 1707275555, is_closed = true WHERE id = 11") require.NoError(t, err) for _, test := range tests { t.Run(test.sortType, func(t *testing.T) { - prs, _, err := issues_model.PullRequests(db.DefaultContext, 1, &issues_model.PullRequestsOptions{ + prs, _, err := issues_model.PullRequests(t.Context(), 1, &issues_model.PullRequestsOptions{ ListOptions: db.ListOptions{ Page: 1, }, @@ -122,33 +122,33 @@ func TestLoadRequestedReviewers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) - assert.NoError(t, pull.LoadIssue(db.DefaultContext)) + assert.NoError(t, pull.LoadIssue(t.Context())) issue := pull.Issue - assert.NoError(t, issue.LoadRepo(db.DefaultContext)) + assert.NoError(t, issue.LoadRepo(t.Context())) assert.Empty(t, pull.RequestedReviewers) - user1, err := user_model.GetUserByID(db.DefaultContext, 1) + user1, err := user_model.GetUserByID(t.Context(), 1) assert.NoError(t, err) - comment, err := issues_model.AddReviewRequest(db.DefaultContext, issue, user1, &user_model.User{}) + comment, err := issues_model.AddReviewRequest(t.Context(), issue, user1, &user_model.User{}) assert.NoError(t, err) assert.NotNil(t, comment) - assert.NoError(t, pull.LoadRequestedReviewers(db.DefaultContext)) + assert.NoError(t, pull.LoadRequestedReviewers(t.Context())) assert.Len(t, pull.RequestedReviewers, 6) - comment, err = issues_model.RemoveReviewRequest(db.DefaultContext, issue, user1, &user_model.User{}) + comment, err = issues_model.RemoveReviewRequest(t.Context(), issue, user1, &user_model.User{}) assert.NoError(t, err) assert.NotNil(t, comment) pull.RequestedReviewers = nil - assert.NoError(t, pull.LoadRequestedReviewers(db.DefaultContext)) + assert.NoError(t, pull.LoadRequestedReviewers(t.Context())) assert.Empty(t, pull.RequestedReviewers) } func TestPullRequestsOldest(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs, count, err := issues_model.PullRequests(db.DefaultContext, 1, &issues_model.PullRequestsOptions{ + prs, count, err := issues_model.PullRequests(t.Context(), 1, &issues_model.PullRequestsOptions{ ListOptions: db.ListOptions{ Page: 1, }, @@ -166,11 +166,11 @@ func TestPullRequestsOldest(t *testing.T) { func TestGetUnmergedPullRequest(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr, err := issues_model.GetUnmergedPullRequest(db.DefaultContext, 1, 1, "branch2", "master", issues_model.PullRequestFlowGithub) + pr, err := issues_model.GetUnmergedPullRequest(t.Context(), 1, 1, "branch2", "master", issues_model.PullRequestFlowGithub) assert.NoError(t, err) assert.Equal(t, int64(2), pr.ID) - _, err = issues_model.GetUnmergedPullRequest(db.DefaultContext, 1, 9223372036854775807, "branch1", "master", issues_model.PullRequestFlowGithub) + _, err = issues_model.GetUnmergedPullRequest(t.Context(), 1, 9223372036854775807, "branch1", "master", issues_model.PullRequestFlowGithub) assert.Error(t, err) assert.True(t, issues_model.IsErrPullRequestNotExist(err)) } @@ -178,18 +178,18 @@ func TestGetUnmergedPullRequest(t *testing.T) { func TestHasUnmergedPullRequestsByHeadInfo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(db.DefaultContext, 1, "branch2") + exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(t.Context(), 1, "branch2") assert.NoError(t, err) assert.True(t, exist) - exist, err = issues_model.HasUnmergedPullRequestsByHeadInfo(db.DefaultContext, 1, "not_exist_branch") + exist, err = issues_model.HasUnmergedPullRequestsByHeadInfo(t.Context(), 1, "not_exist_branch") assert.NoError(t, err) assert.False(t, exist) } func TestGetUnmergedPullRequestsByHeadInfo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(db.DefaultContext, 1, "branch2") + prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(t.Context(), 1, "branch2") assert.NoError(t, err) assert.Len(t, prs, 1) for _, pr := range prs { @@ -200,7 +200,7 @@ func TestGetUnmergedPullRequestsByHeadInfo(t *testing.T) { func TestGetUnmergedPullRequestsByBaseInfo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs, err := issues_model.GetUnmergedPullRequestsByBaseInfo(db.DefaultContext, 1, "master") + prs, err := issues_model.GetUnmergedPullRequestsByBaseInfo(t.Context(), 1, "master") assert.NoError(t, err) assert.Len(t, prs, 1) pr := prs[0] @@ -211,39 +211,39 @@ func TestGetUnmergedPullRequestsByBaseInfo(t *testing.T) { func TestGetPullRequestByIndex(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr, err := issues_model.GetPullRequestByIndex(db.DefaultContext, 1, 2) + pr, err := issues_model.GetPullRequestByIndex(t.Context(), 1, 2) assert.NoError(t, err) assert.Equal(t, int64(1), pr.BaseRepoID) assert.Equal(t, int64(2), pr.Index) - _, err = issues_model.GetPullRequestByIndex(db.DefaultContext, 9223372036854775807, 9223372036854775807) + _, err = issues_model.GetPullRequestByIndex(t.Context(), 9223372036854775807, 9223372036854775807) assert.Error(t, err) assert.True(t, issues_model.IsErrPullRequestNotExist(err)) - _, err = issues_model.GetPullRequestByIndex(db.DefaultContext, 1, 0) + _, err = issues_model.GetPullRequestByIndex(t.Context(), 1, 0) assert.Error(t, err) assert.True(t, issues_model.IsErrPullRequestNotExist(err)) } func TestGetPullRequestByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr, err := issues_model.GetPullRequestByID(db.DefaultContext, 1) + pr, err := issues_model.GetPullRequestByID(t.Context(), 1) assert.NoError(t, err) assert.Equal(t, int64(1), pr.ID) assert.Equal(t, int64(2), pr.IssueID) - _, err = issues_model.GetPullRequestByID(db.DefaultContext, 9223372036854775807) + _, err = issues_model.GetPullRequestByID(t.Context(), 9223372036854775807) assert.Error(t, err) assert.True(t, issues_model.IsErrPullRequestNotExist(err)) } func TestGetPullRequestByIssueID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr, err := issues_model.GetPullRequestByIssueID(db.DefaultContext, 2) + pr, err := issues_model.GetPullRequestByIssueID(t.Context(), 2) assert.NoError(t, err) assert.Equal(t, int64(2), pr.IssueID) - _, err = issues_model.GetPullRequestByIssueID(db.DefaultContext, 9223372036854775807) + _, err = issues_model.GetPullRequestByIssueID(t.Context(), 9223372036854775807) assert.Error(t, err) assert.True(t, issues_model.IsErrPullRequestNotExist(err)) } @@ -255,7 +255,7 @@ func TestPullRequest_UpdateCols(t *testing.T) { BaseBranch: "baseBranch", HeadBranch: "headBranch", } - assert.NoError(t, pr.UpdateCols(db.DefaultContext, "head_branch")) + assert.NoError(t, pr.UpdateCols(t.Context(), "head_branch")) pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) assert.Equal(t, "master", pr.BaseBranch) @@ -269,50 +269,50 @@ func TestPullRequest_IsWorkInProgress(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) - pr.LoadIssue(db.DefaultContext) + pr.LoadIssue(t.Context()) - assert.False(t, pr.IsWorkInProgress(db.DefaultContext)) + assert.False(t, pr.IsWorkInProgress(t.Context())) pr.Issue.Title = "WIP: " + pr.Issue.Title - assert.True(t, pr.IsWorkInProgress(db.DefaultContext)) + assert.True(t, pr.IsWorkInProgress(t.Context())) pr.Issue.Title = "[wip]: " + pr.Issue.Title - assert.True(t, pr.IsWorkInProgress(db.DefaultContext)) + assert.True(t, pr.IsWorkInProgress(t.Context())) } func TestPullRequest_GetWorkInProgressPrefixWorkInProgress(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) - pr.LoadIssue(db.DefaultContext) + pr.LoadIssue(t.Context()) - assert.Empty(t, pr.GetWorkInProgressPrefix(db.DefaultContext)) + assert.Empty(t, pr.GetWorkInProgressPrefix(t.Context())) original := pr.Issue.Title pr.Issue.Title = "WIP: " + original - assert.Equal(t, "WIP:", pr.GetWorkInProgressPrefix(db.DefaultContext)) + assert.Equal(t, "WIP:", pr.GetWorkInProgressPrefix(t.Context())) pr.Issue.Title = "[wip] " + original - assert.Equal(t, "[wip]", pr.GetWorkInProgressPrefix(db.DefaultContext)) + assert.Equal(t, "[wip]", pr.GetWorkInProgressPrefix(t.Context())) } func TestDeleteOrphanedObjects(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - countBefore, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{}) + countBefore, err := db.GetEngine(t.Context()).Count(&issues_model.PullRequest{}) assert.NoError(t, err) - _, err = db.GetEngine(db.DefaultContext).Insert(&issues_model.PullRequest{IssueID: 1000}, &issues_model.PullRequest{IssueID: 1001}, &issues_model.PullRequest{IssueID: 1003}) + _, err = db.GetEngine(t.Context()).Insert(&issues_model.PullRequest{IssueID: 1000}, &issues_model.PullRequest{IssueID: 1001}, &issues_model.PullRequest{IssueID: 1003}) assert.NoError(t, err) - orphaned, err := db.CountOrphanedObjects(db.DefaultContext, "pull_request", "issue", "pull_request.issue_id=issue.id") + orphaned, err := db.CountOrphanedObjects(t.Context(), "pull_request", "issue", "pull_request.issue_id=issue.id") assert.NoError(t, err) assert.EqualValues(t, 3, orphaned) - err = db.DeleteOrphanedObjects(db.DefaultContext, "pull_request", "issue", "pull_request.issue_id=issue.id") + err = db.DeleteOrphanedObjects(t.Context(), "pull_request", "issue", "pull_request.issue_id=issue.id") assert.NoError(t, err) - countAfter, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{}) + countAfter, err := db.GetEngine(t.Context()).Count(&issues_model.PullRequest{}) assert.NoError(t, err) assert.Equal(t, countBefore, countAfter) } @@ -345,20 +345,20 @@ func TestGetApprovers(t *testing.T) { // Official reviews are already deduplicated. Allow unofficial reviews // to assert that there are no duplicated approvers. setting.Repository.PullRequest.DefaultMergeMessageOfficialApproversOnly = false - approvers := pr.GetApprovers(db.DefaultContext) + approvers := pr.GetApprovers(t.Context()) expected := "Reviewed-by: User Five \nReviewed-by: Org Six \n" assert.Equal(t, expected, approvers) } func TestGetPullRequestByMergedCommit(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr, err := issues_model.GetPullRequestByMergedCommit(db.DefaultContext, 1, "1a8823cd1a9549fde083f992f6b9b87a7ab74fb3") + pr, err := issues_model.GetPullRequestByMergedCommit(t.Context(), 1, "1a8823cd1a9549fde083f992f6b9b87a7ab74fb3") assert.NoError(t, err) assert.EqualValues(t, 1, pr.ID) - _, err = issues_model.GetPullRequestByMergedCommit(db.DefaultContext, 0, "1a8823cd1a9549fde083f992f6b9b87a7ab74fb3") + _, err = issues_model.GetPullRequestByMergedCommit(t.Context(), 0, "1a8823cd1a9549fde083f992f6b9b87a7ab74fb3") assert.ErrorAs(t, err, &issues_model.ErrPullRequestNotExist{}) - _, err = issues_model.GetPullRequestByMergedCommit(db.DefaultContext, 1, "") + _, err = issues_model.GetPullRequestByMergedCommit(t.Context(), 1, "") assert.ErrorAs(t, err, &issues_model.ErrPullRequestNotExist{}) } @@ -382,7 +382,7 @@ func TestMigrate_InsertPullRequests(t *testing.T) { Issue: i, } - err := issues_model.InsertPullRequests(db.DefaultContext, p) + err := issues_model.InsertPullRequests(t.Context(), p) assert.NoError(t, err) _ = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{IssueID: i.ID}) diff --git a/models/issues/review_test.go b/models/issues/review_test.go index 2588b8ba41..7b8537cc7d 100644 --- a/models/issues/review_test.go +++ b/models/issues/review_test.go @@ -6,7 +6,6 @@ package issues_test import ( "testing" - "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/models/unittest" @@ -17,12 +16,12 @@ import ( func TestGetReviewByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - review, err := issues_model.GetReviewByID(db.DefaultContext, 1) + review, err := issues_model.GetReviewByID(t.Context(), 1) assert.NoError(t, err) assert.Equal(t, "Demo Review", review.Content) assert.Equal(t, issues_model.ReviewTypeApprove, review.Type) - _, err = issues_model.GetReviewByID(db.DefaultContext, 23892) + _, err = issues_model.GetReviewByID(t.Context(), 23892) assert.Error(t, err) assert.True(t, issues_model.IsErrReviewNotExist(err), "IsErrReviewNotExist") } @@ -30,23 +29,23 @@ func TestGetReviewByID(t *testing.T) { func TestReview_LoadAttributes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 1}) - assert.NoError(t, review.LoadAttributes(db.DefaultContext)) + assert.NoError(t, review.LoadAttributes(t.Context())) assert.NotNil(t, review.Issue) assert.NotNil(t, review.Reviewer) invalidReview1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 2}) - assert.Error(t, invalidReview1.LoadAttributes(db.DefaultContext)) + assert.Error(t, invalidReview1.LoadAttributes(t.Context())) invalidReview2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 3}) - assert.Error(t, invalidReview2.LoadAttributes(db.DefaultContext)) + assert.Error(t, invalidReview2.LoadAttributes(t.Context())) } func TestReview_LoadCodeComments(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 4}) - assert.NoError(t, review.LoadAttributes(db.DefaultContext)) - assert.NoError(t, review.LoadCodeComments(db.DefaultContext)) + assert.NoError(t, review.LoadAttributes(t.Context())) + assert.NoError(t, review.LoadCodeComments(t.Context())) assert.Len(t, review.CodeComments, 1) assert.Equal(t, int64(4), review.CodeComments["README.md"][int64(4)][0].Line) } @@ -62,7 +61,7 @@ func TestReviewType_Icon(t *testing.T) { func TestFindReviews(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - reviews, err := issues_model.FindReviews(db.DefaultContext, issues_model.FindReviewOptions{ + reviews, err := issues_model.FindReviews(t.Context(), issues_model.FindReviewOptions{ Types: []issues_model.ReviewType{issues_model.ReviewTypeApprove}, IssueID: 2, ReviewerID: 1, @@ -74,7 +73,7 @@ func TestFindReviews(t *testing.T) { func TestFindLatestReviews(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - reviews, err := issues_model.FindLatestReviews(db.DefaultContext, issues_model.FindReviewOptions{ + reviews, err := issues_model.FindLatestReviews(t.Context(), issues_model.FindReviewOptions{ Types: []issues_model.ReviewType{issues_model.ReviewTypeApprove}, IssueID: 11, }) @@ -89,14 +88,14 @@ func TestGetCurrentReview(t *testing.T) { issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - review, err := issues_model.GetCurrentReview(db.DefaultContext, user, issue) + review, err := issues_model.GetCurrentReview(t.Context(), user, issue) assert.NoError(t, err) assert.NotNil(t, review) assert.Equal(t, issues_model.ReviewTypePending, review.Type) assert.Equal(t, "Pending Review", review.Content) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 7}) - review2, err := issues_model.GetCurrentReview(db.DefaultContext, user2, issue) + review2, err := issues_model.GetCurrentReview(t.Context(), user2, issue) assert.Error(t, err) assert.True(t, issues_model.IsErrReviewNotExist(err)) assert.Nil(t, review2) @@ -108,7 +107,7 @@ func TestCreateReview(t *testing.T) { issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - review, err := issues_model.CreateReview(db.DefaultContext, issues_model.CreateReviewOptions{ + review, err := issues_model.CreateReview(t.Context(), issues_model.CreateReviewOptions{ Content: "New Review", Type: issues_model.ReviewTypePending, Issue: issue, @@ -162,11 +161,11 @@ func TestGetReviewersByIssueID(t *testing.T) { }, ) - allReviews, migratedReviews, err := issues_model.GetReviewsByIssueID(db.DefaultContext, issue.ID) + allReviews, migratedReviews, err := issues_model.GetReviewsByIssueID(t.Context(), issue.ID) assert.NoError(t, err) assert.Empty(t, migratedReviews) for _, review := range allReviews { - assert.NoError(t, review.LoadReviewer(db.DefaultContext)) + assert.NoError(t, review.LoadReviewer(t.Context())) } if assert.Len(t, allReviews, 5) { for i, review := range allReviews { @@ -187,46 +186,46 @@ func TestDismissReview(t *testing.T) { assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, issues_model.DismissReview(db.DefaultContext, rejectReviewExample, true)) + assert.NoError(t, issues_model.DismissReview(t.Context(), rejectReviewExample, true)) rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}) requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) - assert.NoError(t, issues_model.DismissReview(db.DefaultContext, requestReviewExample, true)) + assert.NoError(t, issues_model.DismissReview(t.Context(), requestReviewExample, true)) rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}) requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, issues_model.DismissReview(db.DefaultContext, requestReviewExample, true)) + assert.NoError(t, issues_model.DismissReview(t.Context(), requestReviewExample, true)) rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}) requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, issues_model.DismissReview(db.DefaultContext, requestReviewExample, false)) + assert.NoError(t, issues_model.DismissReview(t.Context(), requestReviewExample, false)) rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}) requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, issues_model.DismissReview(db.DefaultContext, requestReviewExample, false)) + assert.NoError(t, issues_model.DismissReview(t.Context(), requestReviewExample, false)) rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}) requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, issues_model.DismissReview(db.DefaultContext, rejectReviewExample, false)) + assert.NoError(t, issues_model.DismissReview(t.Context(), rejectReviewExample, false)) assert.False(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, issues_model.DismissReview(db.DefaultContext, approveReviewExample, true)) + assert.NoError(t, issues_model.DismissReview(t.Context(), approveReviewExample, true)) assert.False(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.True(t, approveReviewExample.Dismissed) @@ -238,7 +237,7 @@ func TestDeleteReview(t *testing.T) { issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - review1, err := issues_model.CreateReview(db.DefaultContext, issues_model.CreateReviewOptions{ + review1, err := issues_model.CreateReview(t.Context(), issues_model.CreateReviewOptions{ Content: "Official rejection", Type: issues_model.ReviewTypeReject, Official: false, @@ -247,7 +246,7 @@ func TestDeleteReview(t *testing.T) { }) assert.NoError(t, err) - review2, err := issues_model.CreateReview(db.DefaultContext, issues_model.CreateReviewOptions{ + review2, err := issues_model.CreateReview(t.Context(), issues_model.CreateReviewOptions{ Content: "Official approval", Type: issues_model.ReviewTypeApprove, Official: true, @@ -256,13 +255,13 @@ func TestDeleteReview(t *testing.T) { }) assert.NoError(t, err) - assert.NoError(t, issues_model.DeleteReview(db.DefaultContext, review2)) + assert.NoError(t, issues_model.DeleteReview(t.Context(), review2)) - _, err = issues_model.GetReviewByID(db.DefaultContext, review2.ID) + _, err = issues_model.GetReviewByID(t.Context(), review2.ID) assert.Error(t, err) assert.True(t, issues_model.IsErrReviewNotExist(err), "IsErrReviewNotExist") - review1, err = issues_model.GetReviewByID(db.DefaultContext, review1.ID) + review1, err = issues_model.GetReviewByID(t.Context(), review1.ID) assert.NoError(t, err) assert.True(t, review1.Official) } @@ -273,7 +272,7 @@ func TestDeleteDismissedReview(t *testing.T) { issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) - review, err := issues_model.CreateReview(db.DefaultContext, issues_model.CreateReviewOptions{ + review, err := issues_model.CreateReview(t.Context(), issues_model.CreateReviewOptions{ Content: "reject", Type: issues_model.ReviewTypeReject, Official: false, @@ -281,8 +280,8 @@ func TestDeleteDismissedReview(t *testing.T) { Reviewer: user, }) assert.NoError(t, err) - assert.NoError(t, issues_model.DismissReview(db.DefaultContext, review, true)) - comment, err := issues_model.CreateComment(db.DefaultContext, &issues_model.CreateCommentOptions{ + assert.NoError(t, issues_model.DismissReview(t.Context(), review, true)) + comment, err := issues_model.CreateComment(t.Context(), &issues_model.CreateCommentOptions{ Type: issues_model.CommentTypeDismissReview, Doer: user, Repo: repo, @@ -292,7 +291,7 @@ func TestDeleteDismissedReview(t *testing.T) { }) assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: comment.ID}) - assert.NoError(t, issues_model.DeleteReview(db.DefaultContext, review)) + assert.NoError(t, issues_model.DeleteReview(t.Context(), review)) unittest.AssertNotExistsBean(t, &issues_model.Comment{ID: comment.ID}) } @@ -300,11 +299,11 @@ func TestAddReviewRequest(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) - assert.NoError(t, pull.LoadIssue(db.DefaultContext)) + assert.NoError(t, pull.LoadIssue(t.Context())) issue := pull.Issue - assert.NoError(t, issue.LoadRepo(db.DefaultContext)) + assert.NoError(t, issue.LoadRepo(t.Context())) reviewer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - _, err := issues_model.CreateReview(db.DefaultContext, issues_model.CreateReviewOptions{ + _, err := issues_model.CreateReview(t.Context(), issues_model.CreateReviewOptions{ Issue: issue, Reviewer: reviewer, Type: issues_model.ReviewTypeReject, @@ -312,16 +311,16 @@ func TestAddReviewRequest(t *testing.T) { assert.NoError(t, err) pull.HasMerged = false - assert.NoError(t, pull.UpdateCols(db.DefaultContext, "has_merged")) + assert.NoError(t, pull.UpdateCols(t.Context(), "has_merged")) issue.IsClosed = true - _, err = issues_model.AddReviewRequest(db.DefaultContext, issue, reviewer, &user_model.User{}) + _, err = issues_model.AddReviewRequest(t.Context(), issue, reviewer, &user_model.User{}) assert.Error(t, err) assert.True(t, issues_model.IsErrReviewRequestOnClosedPR(err)) pull.HasMerged = true - assert.NoError(t, pull.UpdateCols(db.DefaultContext, "has_merged")) + assert.NoError(t, pull.UpdateCols(t.Context(), "has_merged")) issue.IsClosed = false - _, err = issues_model.AddReviewRequest(db.DefaultContext, issue, reviewer, &user_model.User{}) + _, err = issues_model.AddReviewRequest(t.Context(), issue, reviewer, &user_model.User{}) assert.Error(t, err) assert.True(t, issues_model.IsErrReviewRequestOnClosedPR(err)) } diff --git a/models/issues/stopwatch_test.go b/models/issues/stopwatch_test.go index 6333c10234..684ec6cd31 100644 --- a/models/issues/stopwatch_test.go +++ b/models/issues/stopwatch_test.go @@ -6,7 +6,6 @@ package issues_test import ( "testing" - "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -20,32 +19,32 @@ func TestCancelStopwatch(t *testing.T) { user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) issue1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) - ok, err := issues_model.CancelStopwatch(db.DefaultContext, user1, issue1) + ok, err := issues_model.CancelStopwatch(t.Context(), user1, issue1) assert.NoError(t, err) assert.True(t, ok) unittest.AssertNotExistsBean(t, &issues_model.Stopwatch{UserID: user1.ID, IssueID: issue1.ID}) unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeCancelTracking, PosterID: user1.ID, IssueID: issue1.ID}) - ok, err = issues_model.CancelStopwatch(db.DefaultContext, user1, issue1) + ok, err = issues_model.CancelStopwatch(t.Context(), user1, issue1) assert.NoError(t, err) assert.False(t, ok) } func TestStopwatchExists(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.True(t, issues_model.StopwatchExists(db.DefaultContext, 1, 1)) - assert.False(t, issues_model.StopwatchExists(db.DefaultContext, 1, 2)) + assert.True(t, issues_model.StopwatchExists(t.Context(), 1, 1)) + assert.False(t, issues_model.StopwatchExists(t.Context(), 1, 2)) } func TestHasUserStopwatch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - exists, sw, _, err := issues_model.HasUserStopwatch(db.DefaultContext, 1) + exists, sw, _, err := issues_model.HasUserStopwatch(t.Context(), 1) assert.NoError(t, err) assert.True(t, exists) assert.Equal(t, int64(1), sw.ID) - exists, _, _, err = issues_model.HasUserStopwatch(db.DefaultContext, 3) + exists, _, _, err = issues_model.HasUserStopwatch(t.Context(), 3) assert.NoError(t, err) assert.False(t, exists) } @@ -58,16 +57,16 @@ func TestCreateOrStopIssueStopwatch(t *testing.T) { issue3 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}) // create a new stopwatch - ok, err := issues_model.CreateIssueStopwatch(db.DefaultContext, user4, issue1) + ok, err := issues_model.CreateIssueStopwatch(t.Context(), user4, issue1) assert.NoError(t, err) assert.True(t, ok) unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: user4.ID, IssueID: issue1.ID}) // should not create a second stopwatch for the same issue - ok, err = issues_model.CreateIssueStopwatch(db.DefaultContext, user4, issue1) + ok, err = issues_model.CreateIssueStopwatch(t.Context(), user4, issue1) assert.NoError(t, err) assert.False(t, ok) // on a different issue, it will finish the existing stopwatch and create a new one - ok, err = issues_model.CreateIssueStopwatch(db.DefaultContext, user4, issue3) + ok, err = issues_model.CreateIssueStopwatch(t.Context(), user4, issue3) assert.NoError(t, err) assert.True(t, ok) unittest.AssertNotExistsBean(t, &issues_model.Stopwatch{UserID: user4.ID, IssueID: issue1.ID}) @@ -76,12 +75,12 @@ func TestCreateOrStopIssueStopwatch(t *testing.T) { // user2 already has a stopwatch in test fixture user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) - ok, err = issues_model.FinishIssueStopwatch(db.DefaultContext, user2, issue2) + ok, err = issues_model.FinishIssueStopwatch(t.Context(), user2, issue2) assert.NoError(t, err) assert.True(t, ok) unittest.AssertNotExistsBean(t, &issues_model.Stopwatch{UserID: user2.ID, IssueID: issue2.ID}) unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{UserID: user2.ID, IssueID: issue2.ID}) - ok, err = issues_model.FinishIssueStopwatch(db.DefaultContext, user2, issue2) + ok, err = issues_model.FinishIssueStopwatch(t.Context(), user2, issue2) assert.NoError(t, err) assert.False(t, ok) } diff --git a/models/issues/tracked_time_test.go b/models/issues/tracked_time_test.go index 44054a1b83..ef7c72958f 100644 --- a/models/issues/tracked_time_test.go +++ b/models/issues/tracked_time_test.go @@ -7,7 +7,6 @@ import ( "testing" "time" - "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -19,14 +18,14 @@ import ( func TestAddTime(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org3, err := user_model.GetUserByID(db.DefaultContext, 3) + org3, err := user_model.GetUserByID(t.Context(), 3) assert.NoError(t, err) - issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1) + issue1, err := issues_model.GetIssueByID(t.Context(), 1) assert.NoError(t, err) // 3661 = 1h 1min 1s - trackedTime, err := issues_model.AddTime(db.DefaultContext, org3, issue1, 3661, time.Now()) + trackedTime, err := issues_model.AddTime(t.Context(), org3, issue1, 3661, time.Now()) assert.NoError(t, err) assert.Equal(t, int64(3), trackedTime.UserID) assert.Equal(t, int64(1), trackedTime.IssueID) @@ -43,39 +42,39 @@ func TestGetTrackedTimes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // by Issue - times, err := issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: 1}) + times, err := issues_model.GetTrackedTimes(t.Context(), &issues_model.FindTrackedTimesOptions{IssueID: 1}) assert.NoError(t, err) assert.Len(t, times, 1) assert.Equal(t, int64(400), times[0].Time) - times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: -1}) + times, err = issues_model.GetTrackedTimes(t.Context(), &issues_model.FindTrackedTimesOptions{IssueID: -1}) assert.NoError(t, err) assert.Empty(t, times) // by User - times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{UserID: 1}) + times, err = issues_model.GetTrackedTimes(t.Context(), &issues_model.FindTrackedTimesOptions{UserID: 1}) assert.NoError(t, err) assert.Len(t, times, 3) assert.Equal(t, int64(400), times[0].Time) - times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{UserID: 3}) + times, err = issues_model.GetTrackedTimes(t.Context(), &issues_model.FindTrackedTimesOptions{UserID: 3}) assert.NoError(t, err) assert.Empty(t, times) // by Repo - times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{RepositoryID: 2}) + times, err = issues_model.GetTrackedTimes(t.Context(), &issues_model.FindTrackedTimesOptions{RepositoryID: 2}) assert.NoError(t, err) assert.Len(t, times, 3) assert.Equal(t, int64(1), times[0].Time) - issue, err := issues_model.GetIssueByID(db.DefaultContext, times[0].IssueID) + issue, err := issues_model.GetIssueByID(t.Context(), times[0].IssueID) assert.NoError(t, err) assert.Equal(t, int64(2), issue.RepoID) - times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{RepositoryID: 1}) + times, err = issues_model.GetTrackedTimes(t.Context(), &issues_model.FindTrackedTimesOptions{RepositoryID: 1}) assert.NoError(t, err) assert.Len(t, times, 5) - times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{RepositoryID: 10}) + times, err = issues_model.GetTrackedTimes(t.Context(), &issues_model.FindTrackedTimesOptions{RepositoryID: 10}) assert.NoError(t, err) assert.Empty(t, times) } @@ -83,7 +82,7 @@ func TestGetTrackedTimes(t *testing.T) { func TestTotalTimesForEachUser(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - total, err := issues_model.TotalTimesForEachUser(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: 1}) + total, err := issues_model.TotalTimesForEachUser(t.Context(), &issues_model.FindTrackedTimesOptions{IssueID: 1}) assert.NoError(t, err) assert.Len(t, total, 1) for user, time := range total { @@ -91,7 +90,7 @@ func TestTotalTimesForEachUser(t *testing.T) { assert.EqualValues(t, 400, time) } - total, err = issues_model.TotalTimesForEachUser(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: 2}) + total, err = issues_model.TotalTimesForEachUser(t.Context(), &issues_model.FindTrackedTimesOptions{IssueID: 2}) assert.NoError(t, err) assert.Len(t, total, 2) for user, time := range total { @@ -104,7 +103,7 @@ func TestTotalTimesForEachUser(t *testing.T) { } } - total, err = issues_model.TotalTimesForEachUser(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: 5}) + total, err = issues_model.TotalTimesForEachUser(t.Context(), &issues_model.FindTrackedTimesOptions{IssueID: 5}) assert.NoError(t, err) assert.Len(t, total, 1) for user, time := range total { @@ -112,7 +111,7 @@ func TestTotalTimesForEachUser(t *testing.T) { assert.EqualValues(t, 1, time) } - total, err = issues_model.TotalTimesForEachUser(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: 4}) + total, err = issues_model.TotalTimesForEachUser(t.Context(), &issues_model.FindTrackedTimesOptions{IssueID: 4}) assert.NoError(t, err) assert.Len(t, total, 2) } @@ -120,15 +119,15 @@ func TestTotalTimesForEachUser(t *testing.T) { func TestGetIssueTotalTrackedTime(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - ttt, err := issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, optional.Some(false)) + ttt, err := issues_model.GetIssueTotalTrackedTime(t.Context(), &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, optional.Some(false)) assert.NoError(t, err) assert.EqualValues(t, 3682, ttt) - ttt, err = issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, optional.Some(true)) + ttt, err = issues_model.GetIssueTotalTrackedTime(t.Context(), &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, optional.Some(true)) assert.NoError(t, err) assert.EqualValues(t, 0, ttt) - ttt, err = issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, optional.None[bool]()) + ttt, err = issues_model.GetIssueTotalTrackedTime(t.Context(), &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, optional.None[bool]()) assert.NoError(t, err) assert.EqualValues(t, 3682, ttt) } diff --git a/models/migrations/base/tests.go b/models/migrations/base/tests.go index 33fd1df707..3b52a5e7c7 100644 --- a/models/migrations/base/tests.go +++ b/models/migrations/base/tests.go @@ -4,7 +4,6 @@ package base import ( - "context" "fmt" "os" "path/filepath" @@ -124,7 +123,7 @@ func MainTest(m *testing.M) { setting.AppDataPath = tmpDataPath unittest.InitSettingsForTesting() - if err = git.InitFull(context.Background()); err != nil { + if err = git.InitFull(); err != nil { testlogger.Fatalf("Unable to InitFull: %v\n", err) } setting.LoadDBSetting() diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 43cfa6e4d8..8946c80bf0 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -42,17 +42,24 @@ const minDBVersion = 70 // Gitea 1.5.3 type migration struct { idNumber int64 // DB version is "the last migration's idNumber" + 1 description string - migrate func(*xorm.Engine) error + migrate func(context.Context, *xorm.Engine) error } // newMigration creates a new migration -func newMigration(idNumber int64, desc string, fn func(*xorm.Engine) error) *migration { - return &migration{idNumber, desc, fn} +func newMigration[T func(*xorm.Engine) error | func(context.Context, *xorm.Engine) error](idNumber int64, desc string, fn T) *migration { + m := &migration{idNumber: idNumber, description: desc} + var ok bool + if m.migrate, ok = any(fn).(func(context.Context, *xorm.Engine) error); !ok { + m.migrate = func(ctx context.Context, x *xorm.Engine) error { + return any(fn).(func(*xorm.Engine) error)(x) + } + } + return m } // Migrate executes the migration -func (m *migration) Migrate(x *xorm.Engine) error { - return m.migrate(x) +func (m *migration) Migrate(ctx context.Context, x *xorm.Engine) error { + return m.migrate(ctx, x) } // Version describes the version table. Should have only one row with id==1 @@ -386,6 +393,7 @@ func prepareMigrationTasks() []*migration { // Gitea 1.24.0 ends at migration ID number 320 (database version 321) newMigration(321, "Use LONGTEXT for some columns and fix review_state.updated_files column", v1_25.UseLongTextInSomeColumnsAndFixBugs), + newMigration(322, "Extend comment tree_path length limit", v1_25.ExtendCommentTreePathLength), } return preparedMigrations } @@ -456,7 +464,7 @@ func migrationIDNumberToDBVersion(idNumber int64) int64 { } // Migrate database to current version -func Migrate(x *xorm.Engine) error { +func Migrate(ctx context.Context, x *xorm.Engine) error { migrations := prepareMigrationTasks() maxDBVer := calcDBVersion(migrations) @@ -500,10 +508,8 @@ Please try upgrading to a lower version first (suggested v1.6.4), then upgrade t } // Some migration tasks depend on the git command - if git.DefaultContext == nil { - if err = git.InitSimple(context.Background()); err != nil { - return err - } + if err = git.InitSimple(); err != nil { + return err } // Migrate @@ -511,7 +517,7 @@ Please try upgrading to a lower version first (suggested v1.6.4), then upgrade t log.Info("Migration[%d]: %s", m.idNumber, m.description) // Reset the mapper between each migration - migrations are not supposed to depend on each other x.SetMapper(names.GonicMapper{}) - if err = m.Migrate(x); err != nil { + if err = m.Migrate(ctx, x); err != nil { return fmt.Errorf("migration[%d]: %s failed: %w", m.idNumber, m.description, err) } currentVersion.Version = migrationIDNumberToDBVersion(m.idNumber) diff --git a/models/migrations/v1_12/v128.go b/models/migrations/v1_12/v128.go index e7dbff3766..d2e8b86a3d 100644 --- a/models/migrations/v1_12/v128.go +++ b/models/migrations/v1_12/v128.go @@ -4,6 +4,7 @@ package v1_12 import ( + "context" "fmt" "math" "path/filepath" @@ -17,7 +18,7 @@ import ( "xorm.io/xorm" ) -func FixMergeBase(x *xorm.Engine) error { +func FixMergeBase(ctx context.Context, x *xorm.Engine) error { type Repository struct { ID int64 `xorm:"pk autoincr"` OwnerID int64 `xorm:"UNIQUE(s) index"` @@ -82,17 +83,17 @@ func FixMergeBase(x *xorm.Engine) error { if !pr.HasMerged { var err error - pr.MergeBase, _, err = git.NewCommand("merge-base").AddDashesAndList(pr.BaseBranch, gitRefName).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) + pr.MergeBase, _, err = git.NewCommand("merge-base").AddDashesAndList(pr.BaseBranch, gitRefName).RunStdString(ctx, &git.RunOpts{Dir: repoPath}) if err != nil { var err2 error - pr.MergeBase, _, err2 = git.NewCommand("rev-parse").AddDynamicArguments(git.BranchPrefix+pr.BaseBranch).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) + pr.MergeBase, _, err2 = git.NewCommand("rev-parse").AddDynamicArguments(git.BranchPrefix+pr.BaseBranch).RunStdString(ctx, &git.RunOpts{Dir: repoPath}) if err2 != nil { log.Error("Unable to get merge base for PR ID %d, Index %d in %s/%s. Error: %v & %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err, err2) continue } } } else { - parentsString, _, err := git.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) + parentsString, _, err := git.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(ctx, &git.RunOpts{Dir: repoPath}) if err != nil { log.Error("Unable to get parents for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err) continue @@ -106,7 +107,7 @@ func FixMergeBase(x *xorm.Engine) error { refs = append(refs, gitRefName) cmd := git.NewCommand("merge-base").AddDashesAndList(refs...) - pr.MergeBase, _, err = cmd.RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) + pr.MergeBase, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath}) if err != nil { log.Error("Unable to get merge base for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err) continue diff --git a/models/migrations/v1_12/v134.go b/models/migrations/v1_12/v134.go index 09d743964d..189d80cc52 100644 --- a/models/migrations/v1_12/v134.go +++ b/models/migrations/v1_12/v134.go @@ -4,6 +4,7 @@ package v1_12 import ( + "context" "fmt" "math" "path/filepath" @@ -17,7 +18,7 @@ import ( "xorm.io/xorm" ) -func RefixMergeBase(x *xorm.Engine) error { +func RefixMergeBase(ctx context.Context, x *xorm.Engine) error { type Repository struct { ID int64 `xorm:"pk autoincr"` OwnerID int64 `xorm:"UNIQUE(s) index"` @@ -79,7 +80,7 @@ func RefixMergeBase(x *xorm.Engine) error { gitRefName := fmt.Sprintf("refs/pull/%d/head", pr.Index) - parentsString, _, err := git.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) + parentsString, _, err := git.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(ctx, &git.RunOpts{Dir: repoPath}) if err != nil { log.Error("Unable to get parents for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err) continue @@ -94,7 +95,7 @@ func RefixMergeBase(x *xorm.Engine) error { refs = append(refs, gitRefName) cmd := git.NewCommand("merge-base").AddDashesAndList(refs...) - pr.MergeBase, _, err = cmd.RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) + pr.MergeBase, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath}) if err != nil { log.Error("Unable to get merge base for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err) continue diff --git a/models/migrations/v1_14/v156.go b/models/migrations/v1_14/v156.go index 2fa5819610..593d3f9c70 100644 --- a/models/migrations/v1_14/v156.go +++ b/models/migrations/v1_14/v156.go @@ -4,6 +4,7 @@ package v1_14 import ( + "context" "fmt" "path/filepath" "strings" @@ -24,7 +25,7 @@ func userPath(userName string) string { return filepath.Join(setting.RepoRootPath, strings.ToLower(userName)) } -func FixPublisherIDforTagReleases(x *xorm.Engine) error { +func FixPublisherIDforTagReleases(ctx context.Context, x *xorm.Engine) error { type Release struct { ID int64 RepoID int64 @@ -108,7 +109,7 @@ func FixPublisherIDforTagReleases(x *xorm.Engine) error { return err } } - gitRepo, err = git.OpenRepository(git.DefaultContext, repoPath(repo.OwnerName, repo.Name)) + gitRepo, err = git.OpenRepository(ctx, repoPath(repo.OwnerName, repo.Name)) if err != nil { log.Error("Error whilst opening git repo for [%d]%s/%s. Error: %v", repo.ID, repo.OwnerName, repo.Name, err) return err diff --git a/models/migrations/v1_22/v293_test.go b/models/migrations/v1_22/v293_test.go index 2c8f7683a8..c7b643c7e0 100644 --- a/models/migrations/v1_22/v293_test.go +++ b/models/migrations/v1_22/v293_test.go @@ -6,7 +6,6 @@ package v1_22 import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/models/project" @@ -32,12 +31,12 @@ func Test_CheckProjectColumnsConsistency(t *testing.T) { assert.True(t, defaultColumn.Default) // check if multiple defaults, previous were removed and last will be kept - expectDefaultColumn, err := project.GetColumn(db.DefaultContext, 2) + expectDefaultColumn, err := project.GetColumn(t.Context(), 2) assert.NoError(t, err) assert.Equal(t, int64(2), expectDefaultColumn.ProjectID) assert.False(t, expectDefaultColumn.Default) - expectNonDefaultColumn, err := project.GetColumn(db.DefaultContext, 3) + expectNonDefaultColumn, err := project.GetColumn(t.Context(), 3) assert.NoError(t, err) assert.Equal(t, int64(2), expectNonDefaultColumn.ProjectID) assert.True(t, expectNonDefaultColumn.Default) diff --git a/models/migrations/v1_25/v322.go b/models/migrations/v1_25/v322.go new file mode 100644 index 0000000000..32dae9945a --- /dev/null +++ b/models/migrations/v1_25/v322.go @@ -0,0 +1,28 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_25 + +import ( + "code.gitea.io/gitea/models/migrations/base" + + "xorm.io/xorm" + "xorm.io/xorm/schemas" +) + +func ExtendCommentTreePathLength(x *xorm.Engine) error { + dbType := x.Dialect().URI().DBType + if dbType == schemas.SQLITE { // For SQLITE, varchar or char will always be represented as TEXT + return nil + } + + return base.ModifyColumn(x, "comment", &schemas.Column{ + Name: "tree_path", + SQLType: schemas.SQLType{ + Name: "VARCHAR", + }, + Length: 4000, + Nullable: true, // To keep compatible as nullable + DefaultIsEmpty: true, + }) +} diff --git a/models/migrations/v1_9/v82.go b/models/migrations/v1_9/v82.go index c685d3b86b..f0307bf07a 100644 --- a/models/migrations/v1_9/v82.go +++ b/models/migrations/v1_9/v82.go @@ -4,6 +4,7 @@ package v1_9 import ( + "context" "fmt" "path/filepath" "strings" @@ -14,7 +15,7 @@ import ( "xorm.io/xorm" ) -func FixReleaseSha1OnReleaseTable(x *xorm.Engine) error { +func FixReleaseSha1OnReleaseTable(ctx context.Context, x *xorm.Engine) error { type Release struct { ID int64 RepoID int64 @@ -98,7 +99,7 @@ func FixReleaseSha1OnReleaseTable(x *xorm.Engine) error { userCache[repo.OwnerID] = user } - gitRepo, err = git.OpenRepository(git.DefaultContext, RepoPath(user.Name, repo.Name)) + gitRepo, err = git.OpenRepository(ctx, RepoPath(user.Name, repo.Name)) if err != nil { return err } diff --git a/models/organization/org.go b/models/organization/org.go index 5eba004d69..9ece044d6c 100644 --- a/models/organization/org.go +++ b/models/organization/org.go @@ -159,8 +159,8 @@ func (org *Organization) AvatarLink(ctx context.Context) string { } // HTMLURL returns the organization's full link. -func (org *Organization) HTMLURL() string { - return org.AsUser().HTMLURL() +func (org *Organization) HTMLURL(ctx context.Context) string { + return org.AsUser().HTMLURL(ctx) } // OrganisationLink returns the organization sub page link. diff --git a/models/organization/org_list.go b/models/organization/org_list.go index 81457191fe..f37961b5f6 100644 --- a/models/organization/org_list.go +++ b/models/organization/org_list.go @@ -105,11 +105,6 @@ type MinimalOrg = Organization // GetUserOrgsList returns all organizations the given user has access to func GetUserOrgsList(ctx context.Context, user *user_model.User) ([]*MinimalOrg, error) { - schema, err := db.TableInfo(new(user_model.User)) - if err != nil { - return nil, err - } - outputCols := []string{ "id", "name", @@ -122,7 +117,7 @@ func GetUserOrgsList(ctx context.Context, user *user_model.User) ([]*MinimalOrg, selectColumns := &strings.Builder{} for i, col := range outputCols { - fmt.Fprintf(selectColumns, "`%s`.%s", schema.Name, col) + _, _ = fmt.Fprintf(selectColumns, "`user`.%s", col) if i < len(outputCols)-1 { selectColumns.WriteString(", ") } diff --git a/models/organization/org_list_test.go b/models/organization/org_list_test.go index a2a25c6f91..b2a1044422 100644 --- a/models/organization/org_list_test.go +++ b/models/organization/org_list_test.go @@ -25,15 +25,15 @@ func TestOrgList(t *testing.T) { } func testCountOrganizations(t *testing.T) { - expected, err := db.GetEngine(db.DefaultContext).Where("type=?", user_model.UserTypeOrganization).Count(&organization.Organization{}) + expected, err := db.GetEngine(t.Context()).Where("type=?", user_model.UserTypeOrganization).Count(&organization.Organization{}) assert.NoError(t, err) - cnt, err := db.Count[organization.Organization](db.DefaultContext, organization.FindOrgOptions{IncludeVisibility: structs.VisibleTypePrivate}) + cnt, err := db.Count[organization.Organization](t.Context(), organization.FindOrgOptions{IncludeVisibility: structs.VisibleTypePrivate}) assert.NoError(t, err) assert.Equal(t, expected, cnt) } func testFindOrgs(t *testing.T) { - orgs, err := db.Find[organization.Organization](db.DefaultContext, organization.FindOrgOptions{ + orgs, err := db.Find[organization.Organization](t.Context(), organization.FindOrgOptions{ UserID: 4, IncludeVisibility: structs.VisibleTypePrivate, }) @@ -42,13 +42,13 @@ func testFindOrgs(t *testing.T) { assert.EqualValues(t, 3, orgs[0].ID) } - orgs, err = db.Find[organization.Organization](db.DefaultContext, organization.FindOrgOptions{ + orgs, err = db.Find[organization.Organization](t.Context(), organization.FindOrgOptions{ UserID: 4, }) assert.NoError(t, err) assert.Empty(t, orgs) - total, err := db.Count[organization.Organization](db.DefaultContext, organization.FindOrgOptions{ + total, err := db.Count[organization.Organization](t.Context(), organization.FindOrgOptions{ UserID: 4, IncludeVisibility: structs.VisibleTypePrivate, }) @@ -57,7 +57,7 @@ func testFindOrgs(t *testing.T) { } func testGetUserOrgsList(t *testing.T) { - orgs, err := organization.GetUserOrgsList(db.DefaultContext, &user_model.User{ID: 4}) + orgs, err := organization.GetUserOrgsList(t.Context(), &user_model.User{ID: 4}) assert.NoError(t, err) if assert.Len(t, orgs, 1) { assert.EqualValues(t, 3, orgs[0].ID) @@ -67,10 +67,10 @@ func testGetUserOrgsList(t *testing.T) { } func testLoadOrgListTeams(t *testing.T) { - orgs, err := organization.GetUserOrgsList(db.DefaultContext, &user_model.User{ID: 4}) + orgs, err := organization.GetUserOrgsList(t.Context(), &user_model.User{ID: 4}) assert.NoError(t, err) assert.Len(t, orgs, 1) - teamsMap, err := organization.OrgList(orgs).LoadTeams(db.DefaultContext) + teamsMap, err := organization.OrgList(orgs).LoadTeams(t.Context()) assert.NoError(t, err) assert.Len(t, teamsMap, 1) assert.Len(t, teamsMap[3], 5) diff --git a/models/organization/org_test.go b/models/organization/org_test.go index 234325a8cd..e7c4d2f9f7 100644 --- a/models/organization/org_test.go +++ b/models/organization/org_test.go @@ -34,7 +34,7 @@ func TestUser_IsOwnedBy(t *testing.T) { {2, 3, false}, } { org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: testCase.OrgID}) - isOwner, err := org.IsOwnedBy(db.DefaultContext, testCase.UserID) + isOwner, err := org.IsOwnedBy(t.Context(), testCase.UserID) assert.NoError(t, err) assert.Equal(t, testCase.ExpectedOwner, isOwner) } @@ -55,7 +55,7 @@ func TestUser_IsOrgMember(t *testing.T) { {2, 3, false}, } { org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: testCase.OrgID}) - isMember, err := org.IsOrgMember(db.DefaultContext, testCase.UserID) + isMember, err := org.IsOrgMember(t.Context(), testCase.UserID) assert.NoError(t, err) assert.Equal(t, testCase.ExpectedMember, isMember) } @@ -64,35 +64,35 @@ func TestUser_IsOrgMember(t *testing.T) { func TestUser_GetTeam(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) - team, err := org.GetTeam(db.DefaultContext, "team1") + team, err := org.GetTeam(t.Context(), "team1") assert.NoError(t, err) assert.Equal(t, org.ID, team.OrgID) assert.Equal(t, "team1", team.LowerName) - _, err = org.GetTeam(db.DefaultContext, "does not exist") + _, err = org.GetTeam(t.Context(), "does not exist") assert.True(t, organization.IsErrTeamNotExist(err)) nonOrg := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 2}) - _, err = nonOrg.GetTeam(db.DefaultContext, "team") + _, err = nonOrg.GetTeam(t.Context(), "team") assert.True(t, organization.IsErrTeamNotExist(err)) } func TestUser_GetOwnerTeam(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) - team, err := org.GetOwnerTeam(db.DefaultContext) + team, err := org.GetOwnerTeam(t.Context()) assert.NoError(t, err) assert.Equal(t, org.ID, team.OrgID) nonOrg := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 2}) - _, err = nonOrg.GetOwnerTeam(db.DefaultContext) + _, err = nonOrg.GetOwnerTeam(t.Context()) assert.True(t, organization.IsErrTeamNotExist(err)) } func TestUser_GetTeams(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) - teams, err := org.LoadTeams(db.DefaultContext) + teams, err := org.LoadTeams(t.Context()) assert.NoError(t, err) if assert.Len(t, teams, 5) { assert.Equal(t, int64(1), teams[0].ID) @@ -106,7 +106,7 @@ func TestUser_GetTeams(t *testing.T) { func TestUser_GetMembers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) - members, _, err := org.GetMembers(db.DefaultContext, &user_model.User{IsAdmin: true}) + members, _, err := org.GetMembers(t.Context(), &user_model.User{IsAdmin: true}) assert.NoError(t, err) if assert.Len(t, members, 3) { assert.Equal(t, int64(2), members[0].ID) @@ -118,22 +118,22 @@ func TestUser_GetMembers(t *testing.T) { func TestGetOrgByName(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org, err := organization.GetOrgByName(db.DefaultContext, "org3") + org, err := organization.GetOrgByName(t.Context(), "org3") assert.NoError(t, err) assert.EqualValues(t, 3, org.ID) assert.Equal(t, "org3", org.Name) - _, err = organization.GetOrgByName(db.DefaultContext, "user2") // user2 is an individual + _, err = organization.GetOrgByName(t.Context(), "user2") // user2 is an individual assert.True(t, organization.IsErrOrgNotExist(err)) - _, err = organization.GetOrgByName(db.DefaultContext, "") // corner case + _, err = organization.GetOrgByName(t.Context(), "") // corner case assert.True(t, organization.IsErrOrgNotExist(err)) } func TestIsOrganizationOwner(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(orgID, userID int64, expected bool) { - isOwner, err := organization.IsOrganizationOwner(db.DefaultContext, orgID, userID) + isOwner, err := organization.IsOrganizationOwner(t.Context(), orgID, userID) assert.NoError(t, err) assert.Equal(t, expected, isOwner) } @@ -147,7 +147,7 @@ func TestIsOrganizationOwner(t *testing.T) { func TestIsOrganizationMember(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(orgID, userID int64, expected bool) { - isMember, err := organization.IsOrganizationMember(db.DefaultContext, orgID, userID) + isMember, err := organization.IsOrganizationMember(t.Context(), orgID, userID) assert.NoError(t, err) assert.Equal(t, expected, isMember) } @@ -162,7 +162,7 @@ func TestIsOrganizationMember(t *testing.T) { func TestIsPublicMembership(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(orgID, userID int64, expected bool) { - isMember, err := organization.IsPublicMembership(db.DefaultContext, orgID, userID) + isMember, err := organization.IsPublicMembership(t.Context(), orgID, userID) assert.NoError(t, err) assert.Equal(t, expected, isMember) } @@ -226,11 +226,11 @@ func TestRestrictedUserOrgMembers(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - count, err := organization.CountOrgMembers(db.DefaultContext, tc.opts) + count, err := organization.CountOrgMembers(t.Context(), tc.opts) assert.NoError(t, err) assert.EqualValues(t, len(tc.expectedUIDs), count) - members, err := organization.GetOrgUsersByOrgID(db.DefaultContext, tc.opts) + members, err := organization.GetOrgUsersByOrgID(t.Context(), tc.opts) assert.NoError(t, err) memberUIDs := make([]int64, 0, len(members)) for _, member := range members { @@ -250,7 +250,7 @@ func TestGetOrgUsersByOrgID(t *testing.T) { OrgID: 3, } assert.False(t, opts.PublicOnly()) - orgUsers, err := organization.GetOrgUsersByOrgID(db.DefaultContext, opts) + orgUsers, err := organization.GetOrgUsersByOrgID(t.Context(), opts) assert.NoError(t, err) sort.Slice(orgUsers, func(i, j int) bool { return orgUsers[i].ID < orgUsers[j].ID @@ -274,11 +274,11 @@ func TestGetOrgUsersByOrgID(t *testing.T) { opts = &organization.FindOrgMembersOpts{OrgID: 3} assert.True(t, opts.PublicOnly()) - orgUsers, err = organization.GetOrgUsersByOrgID(db.DefaultContext, opts) + orgUsers, err = organization.GetOrgUsersByOrgID(t.Context(), opts) assert.NoError(t, err) assert.Len(t, orgUsers, 2) - orgUsers, err = organization.GetOrgUsersByOrgID(db.DefaultContext, &organization.FindOrgMembersOpts{ + orgUsers, err = organization.GetOrgUsersByOrgID(t.Context(), &organization.FindOrgMembersOpts{ ListOptions: db.ListOptions{}, OrgID: unittest.NonexistentID, }) @@ -290,7 +290,7 @@ func TestChangeOrgUserStatus(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(orgID, userID int64, public bool) { - assert.NoError(t, organization.ChangeOrgUserStatus(db.DefaultContext, orgID, userID, public)) + assert.NoError(t, organization.ChangeOrgUserStatus(t.Context(), orgID, userID, public)) orgUser := unittest.AssertExistsAndLoadBean(t, &organization.OrgUser{OrgID: orgID, UID: userID}) assert.Equal(t, public, orgUser.IsPublic) } @@ -298,14 +298,14 @@ func TestChangeOrgUserStatus(t *testing.T) { testSuccess(3, 2, false) testSuccess(3, 2, false) testSuccess(3, 4, true) - assert.NoError(t, organization.ChangeOrgUserStatus(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID, true)) + assert.NoError(t, organization.ChangeOrgUserStatus(t.Context(), unittest.NonexistentID, unittest.NonexistentID, true)) } func TestUser_GetUserTeamIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) testSuccess := func(userID int64, expected []int64) { - teamIDs, err := org.GetUserTeamIDs(db.DefaultContext, userID) + teamIDs, err := org.GetUserTeamIDs(t.Context(), userID) assert.NoError(t, err) assert.Equal(t, expected, teamIDs) } @@ -318,9 +318,9 @@ func TestAccessibleReposEnv_CountRepos(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) testSuccess := func(userID, expectedCount int64) { - env, err := repo_model.AccessibleReposEnv(db.DefaultContext, org, userID) + env, err := repo_model.AccessibleReposEnv(t.Context(), org, userID) assert.NoError(t, err) - count, err := env.CountRepos(db.DefaultContext) + count, err := env.CountRepos(t.Context()) assert.NoError(t, err) assert.Equal(t, expectedCount, count) } @@ -332,9 +332,9 @@ func TestAccessibleReposEnv_RepoIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) testSuccess := func(userID int64, expectedRepoIDs []int64) { - env, err := repo_model.AccessibleReposEnv(db.DefaultContext, org, userID) + env, err := repo_model.AccessibleReposEnv(t.Context(), org, userID) assert.NoError(t, err) - repoIDs, err := env.RepoIDs(db.DefaultContext) + repoIDs, err := env.RepoIDs(t.Context()) assert.NoError(t, err) assert.Equal(t, expectedRepoIDs, repoIDs) } @@ -346,9 +346,9 @@ func TestAccessibleReposEnv_MirrorRepos(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) testSuccess := func(userID int64, expectedRepoIDs []int64) { - env, err := repo_model.AccessibleReposEnv(db.DefaultContext, org, userID) + env, err := repo_model.AccessibleReposEnv(t.Context(), org, userID) assert.NoError(t, err) - repos, err := env.MirrorRepos(db.DefaultContext) + repos, err := env.MirrorRepos(t.Context()) assert.NoError(t, err) expectedRepos := make(repo_model.RepositoryList, len(expectedRepoIDs)) for i, repoID := range expectedRepoIDs { @@ -373,12 +373,12 @@ func TestHasOrgVisibleTypePublic(t *testing.T) { } unittest.AssertNotExistsBean(t, &user_model.User{Name: org.Name, Type: user_model.UserTypeOrganization}) - assert.NoError(t, organization.CreateOrganization(db.DefaultContext, org, owner)) + assert.NoError(t, organization.CreateOrganization(t.Context(), org, owner)) org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization}) - test1 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), owner) - test2 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), org3) - test3 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), nil) + test1 := organization.HasOrgOrUserVisible(t.Context(), org.AsUser(), owner) + test2 := organization.HasOrgOrUserVisible(t.Context(), org.AsUser(), org3) + test3 := organization.HasOrgOrUserVisible(t.Context(), org.AsUser(), nil) assert.True(t, test1) // owner of org assert.True(t, test2) // user not a part of org assert.True(t, test3) // logged out user @@ -396,12 +396,12 @@ func TestHasOrgVisibleTypeLimited(t *testing.T) { } unittest.AssertNotExistsBean(t, &user_model.User{Name: org.Name, Type: user_model.UserTypeOrganization}) - assert.NoError(t, organization.CreateOrganization(db.DefaultContext, org, owner)) + assert.NoError(t, organization.CreateOrganization(t.Context(), org, owner)) org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization}) - test1 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), owner) - test2 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), org3) - test3 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), nil) + test1 := organization.HasOrgOrUserVisible(t.Context(), org.AsUser(), owner) + test2 := organization.HasOrgOrUserVisible(t.Context(), org.AsUser(), org3) + test3 := organization.HasOrgOrUserVisible(t.Context(), org.AsUser(), nil) assert.True(t, test1) // owner of org assert.True(t, test2) // user not a part of org assert.False(t, test3) // logged out user @@ -419,12 +419,12 @@ func TestHasOrgVisibleTypePrivate(t *testing.T) { } unittest.AssertNotExistsBean(t, &user_model.User{Name: org.Name, Type: user_model.UserTypeOrganization}) - assert.NoError(t, organization.CreateOrganization(db.DefaultContext, org, owner)) + assert.NoError(t, organization.CreateOrganization(t.Context(), org, owner)) org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization}) - test1 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), owner) - test2 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), org3) - test3 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), nil) + test1 := organization.HasOrgOrUserVisible(t.Context(), org.AsUser(), owner) + test2 := organization.HasOrgOrUserVisible(t.Context(), org.AsUser(), org3) + test3 := organization.HasOrgOrUserVisible(t.Context(), org.AsUser(), nil) assert.True(t, test1) // owner of org assert.False(t, test2) // user not a part of org assert.False(t, test3) // logged out user @@ -433,7 +433,7 @@ func TestHasOrgVisibleTypePrivate(t *testing.T) { func TestGetUsersWhoCanCreateOrgRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - users, err := organization.GetUsersWhoCanCreateOrgRepo(db.DefaultContext, 3) + users, err := organization.GetUsersWhoCanCreateOrgRepo(t.Context(), 3) assert.NoError(t, err) assert.Len(t, users, 2) var ids []int64 @@ -442,7 +442,7 @@ func TestGetUsersWhoCanCreateOrgRepo(t *testing.T) { } assert.ElementsMatch(t, ids, []int64{2, 28}) - users, err = organization.GetUsersWhoCanCreateOrgRepo(db.DefaultContext, 7) + users, err = organization.GetUsersWhoCanCreateOrgRepo(t.Context(), 7) assert.NoError(t, err) assert.Len(t, users, 1) assert.NotNil(t, users[5]) @@ -455,15 +455,15 @@ func TestUser_RemoveOrgRepo(t *testing.T) { // remove a repo that does belong to org unittest.AssertExistsAndLoadBean(t, &organization.TeamRepo{RepoID: repo.ID, OrgID: org.ID}) - assert.NoError(t, organization.RemoveOrgRepo(db.DefaultContext, org.ID, repo.ID)) + assert.NoError(t, organization.RemoveOrgRepo(t.Context(), org.ID, repo.ID)) unittest.AssertNotExistsBean(t, &organization.TeamRepo{RepoID: repo.ID, OrgID: org.ID}) unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo.ID}) // repo should still exist // remove a repo that does not belong to org - assert.NoError(t, organization.RemoveOrgRepo(db.DefaultContext, org.ID, repo.ID)) + assert.NoError(t, organization.RemoveOrgRepo(t.Context(), org.ID, repo.ID)) unittest.AssertNotExistsBean(t, &organization.TeamRepo{RepoID: repo.ID, OrgID: org.ID}) - assert.NoError(t, organization.RemoveOrgRepo(db.DefaultContext, org.ID, unittest.NonexistentID)) + assert.NoError(t, organization.RemoveOrgRepo(t.Context(), org.ID, unittest.NonexistentID)) unittest.CheckConsistencyFor(t, &user_model.User{ID: org.ID}, @@ -482,7 +482,7 @@ func TestCreateOrganization(t *testing.T) { } unittest.AssertNotExistsBean(t, &user_model.User{Name: newOrgName, Type: user_model.UserTypeOrganization}) - assert.NoError(t, organization.CreateOrganization(db.DefaultContext, org, owner)) + assert.NoError(t, organization.CreateOrganization(t.Context(), org, owner)) org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{Name: newOrgName, Type: user_model.UserTypeOrganization}) ownerTeam := unittest.AssertExistsAndLoadBean(t, @@ -502,7 +502,7 @@ func TestCreateOrganization2(t *testing.T) { } unittest.AssertNotExistsBean(t, &organization.Organization{Name: newOrgName, Type: user_model.UserTypeOrganization}) - err := organization.CreateOrganization(db.DefaultContext, org, owner) + err := organization.CreateOrganization(t.Context(), org, owner) assert.Error(t, err) assert.True(t, organization.IsErrUserNotAllowedCreateOrg(err)) unittest.AssertNotExistsBean(t, &organization.Organization{Name: newOrgName, Type: user_model.UserTypeOrganization}) @@ -516,7 +516,7 @@ func TestCreateOrganization3(t *testing.T) { owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) org := &organization.Organization{Name: "org3"} // should already exist unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: org.Name}) // sanity check - err := organization.CreateOrganization(db.DefaultContext, org, owner) + err := organization.CreateOrganization(t.Context(), org, owner) assert.Error(t, err) assert.True(t, user_model.IsErrUserAlreadyExist(err)) unittest.CheckConsistencyFor(t, &user_model.User{}, &organization.Team{}) @@ -527,7 +527,7 @@ func TestCreateOrganization4(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - err := organization.CreateOrganization(db.DefaultContext, &organization.Organization{Name: "assets"}, owner) + err := organization.CreateOrganization(t.Context(), &organization.Organization{Name: "assets"}, owner) assert.Error(t, err) assert.True(t, db.IsErrNameReserved(err)) unittest.CheckConsistencyFor(t, &organization.Organization{}, &organization.Team{}) diff --git a/models/organization/org_user_test.go b/models/organization/org_user_test.go index 689544430d..d21df4b474 100644 --- a/models/organization/org_user_test.go +++ b/models/organization/org_user_test.go @@ -7,7 +7,6 @@ import ( "fmt" "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -37,9 +36,9 @@ func TestUserIsPublicMember(t *testing.T) { } func testUserIsPublicMember(t *testing.T, uid, orgID int64, expected bool) { - user, err := user_model.GetUserByID(db.DefaultContext, uid) + user, err := user_model.GetUserByID(t.Context(), uid) assert.NoError(t, err) - is, err := organization.IsPublicMembership(db.DefaultContext, orgID, user.ID) + is, err := organization.IsPublicMembership(t.Context(), orgID, user.ID) assert.NoError(t, err) assert.Equal(t, expected, is) } @@ -65,9 +64,9 @@ func TestIsUserOrgOwner(t *testing.T) { } func testIsUserOrgOwner(t *testing.T, uid, orgID int64, expected bool) { - user, err := user_model.GetUserByID(db.DefaultContext, uid) + user, err := user_model.GetUserByID(t.Context(), uid) assert.NoError(t, err) - is, err := organization.IsOrganizationOwner(db.DefaultContext, orgID, user.ID) + is, err := organization.IsOrganizationOwner(t.Context(), orgID, user.ID) assert.NoError(t, err) assert.Equal(t, expected, is) } @@ -92,9 +91,9 @@ func TestUserListIsPublicMember(t *testing.T) { } func testUserListIsPublicMember(t *testing.T, orgID int64, expected map[int64]bool) { - org, err := organization.GetOrgByID(db.DefaultContext, orgID) + org, err := organization.GetOrgByID(t.Context(), orgID) assert.NoError(t, err) - _, membersIsPublic, err := org.GetMembers(db.DefaultContext, &user_model.User{IsAdmin: true}) + _, membersIsPublic, err := org.GetMembers(t.Context(), &user_model.User{IsAdmin: true}) assert.NoError(t, err) assert.Equal(t, expected, membersIsPublic) } @@ -119,11 +118,11 @@ func TestUserListIsUserOrgOwner(t *testing.T) { } func testUserListIsUserOrgOwner(t *testing.T, orgID int64, expected map[int64]bool) { - org, err := organization.GetOrgByID(db.DefaultContext, orgID) + org, err := organization.GetOrgByID(t.Context(), orgID) assert.NoError(t, err) - members, _, err := org.GetMembers(db.DefaultContext, &user_model.User{IsAdmin: true}) + members, _, err := org.GetMembers(t.Context(), &user_model.User{IsAdmin: true}) assert.NoError(t, err) - assert.Equal(t, expected, organization.IsUserOrgOwner(db.DefaultContext, members, orgID)) + assert.Equal(t, expected, organization.IsUserOrgOwner(t.Context(), members, orgID)) } func TestAddOrgUser(t *testing.T) { @@ -134,7 +133,7 @@ func TestAddOrgUser(t *testing.T) { if unittest.GetBean(t, &organization.OrgUser{OrgID: orgID, UID: userID}) == nil { expectedNumMembers++ } - assert.NoError(t, organization.AddOrgUser(db.DefaultContext, orgID, userID)) + assert.NoError(t, organization.AddOrgUser(t.Context(), orgID, userID)) ou := &organization.OrgUser{OrgID: orgID, UID: userID} unittest.AssertExistsAndLoadBean(t, ou) assert.Equal(t, isPublic, ou.IsPublic) diff --git a/models/organization/org_worktime.go b/models/organization/org_worktime.go index 7b57182a8a..3ef3e512ad 100644 --- a/models/organization/org_worktime.go +++ b/models/organization/org_worktime.go @@ -4,6 +4,7 @@ package organization import ( + "context" "sort" "code.gitea.io/gitea/models/db" @@ -16,8 +17,8 @@ type WorktimeSumByRepos struct { SumTime int64 } -func GetWorktimeByRepos(org *Organization, unitFrom, unixTo int64) (results []WorktimeSumByRepos, err error) { - err = db.GetEngine(db.DefaultContext). +func GetWorktimeByRepos(ctx context.Context, org *Organization, unitFrom, unixTo int64) (results []WorktimeSumByRepos, err error) { + err = db.GetEngine(ctx). Select("repository.name AS repo_name, SUM(tracked_time.time) AS sum_time"). Table("tracked_time"). Join("INNER", "issue", "tracked_time.issue_id = issue.id"). @@ -41,8 +42,8 @@ type WorktimeSumByMilestones struct { HideRepoName bool } -func GetWorktimeByMilestones(org *Organization, unitFrom, unixTo int64) (results []WorktimeSumByMilestones, err error) { - err = db.GetEngine(db.DefaultContext). +func GetWorktimeByMilestones(ctx context.Context, org *Organization, unitFrom, unixTo int64) (results []WorktimeSumByMilestones, err error) { + err = db.GetEngine(ctx). Select("repository.name AS repo_name, milestone.name AS milestone_name, milestone.id AS milestone_id, milestone.deadline_unix as milestone_deadline, SUM(tracked_time.time) AS sum_time"). Table("tracked_time"). Join("INNER", "issue", "tracked_time.issue_id = issue.id"). @@ -85,8 +86,8 @@ type WorktimeSumByMembers struct { SumTime int64 } -func GetWorktimeByMembers(org *Organization, unitFrom, unixTo int64) (results []WorktimeSumByMembers, err error) { - err = db.GetEngine(db.DefaultContext). +func GetWorktimeByMembers(ctx context.Context, org *Organization, unitFrom, unixTo int64) (results []WorktimeSumByMembers, err error) { + err = db.GetEngine(ctx). Select("`user`.name AS user_name, SUM(tracked_time.time) AS sum_time"). Table("tracked_time"). Join("INNER", "issue", "tracked_time.issue_id = issue.id"). diff --git a/models/organization/team_invite_test.go b/models/organization/team_invite_test.go index 45db8494e8..e9fabed1db 100644 --- a/models/organization/team_invite_test.go +++ b/models/organization/team_invite_test.go @@ -6,7 +6,6 @@ package organization_test import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -23,26 +22,26 @@ func TestTeamInvite(t *testing.T) { user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // user 2 already added to team 2, should result in error - _, err := organization.CreateTeamInvite(db.DefaultContext, user2, team, user2.Email) + _, err := organization.CreateTeamInvite(t.Context(), user2, team, user2.Email) assert.Error(t, err) }) t.Run("CreateAndRemove", func(t *testing.T) { user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - invite, err := organization.CreateTeamInvite(db.DefaultContext, user1, team, "org3@example.com") + invite, err := organization.CreateTeamInvite(t.Context(), user1, team, "org3@example.com") assert.NotNil(t, invite) assert.NoError(t, err) // Shouldn't allow duplicate invite - _, err = organization.CreateTeamInvite(db.DefaultContext, user1, team, "org3@example.com") + _, err = organization.CreateTeamInvite(t.Context(), user1, team, "org3@example.com") assert.Error(t, err) // should remove invite - assert.NoError(t, organization.RemoveInviteByID(db.DefaultContext, invite.ID, invite.TeamID)) + assert.NoError(t, organization.RemoveInviteByID(t.Context(), invite.ID, invite.TeamID)) // invite should not exist - _, err = organization.GetInviteByToken(db.DefaultContext, invite.Token) + _, err = organization.GetInviteByToken(t.Context(), invite.Token) assert.Error(t, err) }) } diff --git a/models/organization/team_list_test.go b/models/organization/team_list_test.go index 5526446e22..df73f95898 100644 --- a/models/organization/team_list_test.go +++ b/models/organization/team_list_test.go @@ -6,7 +6,6 @@ package organization_test import ( "testing" - "code.gitea.io/gitea/models/db" org_model "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/unittest" @@ -17,7 +16,7 @@ func Test_GetTeamsByIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // 1 owner team, 2 normal team - teams, err := org_model.GetTeamsByIDs(db.DefaultContext, []int64{1, 2}) + teams, err := org_model.GetTeamsByIDs(t.Context(), []int64{1, 2}) assert.NoError(t, err) assert.Len(t, teams, 2) assert.Equal(t, "Owners", teams[1].Name) diff --git a/models/organization/team_repo_test.go b/models/organization/team_repo_test.go index 73a06a93c2..af959f4658 100644 --- a/models/organization/team_repo_test.go +++ b/models/organization/team_repo_test.go @@ -6,7 +6,6 @@ package organization_test import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/repo" @@ -22,7 +21,7 @@ func TestGetTeamsWithAccessToRepoUnit(t *testing.T) { org41 := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 41}) repo61 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 61}) - teams, err := organization.GetTeamsWithAccessToAnyRepoUnit(db.DefaultContext, org41.ID, repo61.ID, perm.AccessModeRead, unit.TypePullRequests) + teams, err := organization.GetTeamsWithAccessToAnyRepoUnit(t.Context(), org41.ID, repo61.ID, perm.AccessModeRead, unit.TypePullRequests) assert.NoError(t, err) if assert.Len(t, teams, 2) { assert.EqualValues(t, 21, teams[0].ID) diff --git a/models/organization/team_test.go b/models/organization/team_test.go index b0bf842584..fea5e8990a 100644 --- a/models/organization/team_test.go +++ b/models/organization/team_test.go @@ -28,14 +28,14 @@ func TestTeam_IsMember(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}) - assert.True(t, team.IsMember(db.DefaultContext, 2)) - assert.False(t, team.IsMember(db.DefaultContext, 4)) - assert.False(t, team.IsMember(db.DefaultContext, unittest.NonexistentID)) + assert.True(t, team.IsMember(t.Context(), 2)) + assert.False(t, team.IsMember(t.Context(), 4)) + assert.False(t, team.IsMember(t.Context(), unittest.NonexistentID)) team = unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}) - assert.True(t, team.IsMember(db.DefaultContext, 2)) - assert.True(t, team.IsMember(db.DefaultContext, 4)) - assert.False(t, team.IsMember(db.DefaultContext, unittest.NonexistentID)) + assert.True(t, team.IsMember(t.Context(), 2)) + assert.True(t, team.IsMember(t.Context(), 4)) + assert.False(t, team.IsMember(t.Context(), unittest.NonexistentID)) } func TestTeam_GetRepositories(t *testing.T) { @@ -43,7 +43,7 @@ func TestTeam_GetRepositories(t *testing.T) { test := func(teamID int64) { team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) - repos, err := repo_model.GetTeamRepositories(db.DefaultContext, &repo_model.SearchTeamRepoOptions{ + repos, err := repo_model.GetTeamRepositories(t.Context(), &repo_model.SearchTeamRepoOptions{ TeamID: team.ID, }) assert.NoError(t, err) @@ -61,7 +61,7 @@ func TestTeam_GetMembers(t *testing.T) { test := func(teamID int64) { team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) - assert.NoError(t, team.LoadMembers(db.DefaultContext)) + assert.NoError(t, team.LoadMembers(t.Context())) assert.Len(t, team.Members, team.NumMembers) for _, member := range team.Members { unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: member.ID, TeamID: teamID}) @@ -75,7 +75,7 @@ func TestGetTeam(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(orgID int64, name string) { - team, err := organization.GetTeam(db.DefaultContext, orgID, name) + team, err := organization.GetTeam(t.Context(), orgID, name) assert.NoError(t, err) assert.Equal(t, orgID, team.OrgID) assert.Equal(t, name, team.Name) @@ -83,9 +83,9 @@ func TestGetTeam(t *testing.T) { testSuccess(3, "Owners") testSuccess(3, "team1") - _, err := organization.GetTeam(db.DefaultContext, 3, "nonexistent") + _, err := organization.GetTeam(t.Context(), 3, "nonexistent") assert.Error(t, err) - _, err = organization.GetTeam(db.DefaultContext, unittest.NonexistentID, "Owners") + _, err = organization.GetTeam(t.Context(), unittest.NonexistentID, "Owners") assert.Error(t, err) } @@ -93,7 +93,7 @@ func TestGetTeamByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(teamID int64) { - team, err := organization.GetTeamByID(db.DefaultContext, teamID) + team, err := organization.GetTeamByID(t.Context(), teamID) assert.NoError(t, err) assert.Equal(t, teamID, team.ID) } @@ -102,14 +102,14 @@ func TestGetTeamByID(t *testing.T) { testSuccess(3) testSuccess(4) - _, err := organization.GetTeamByID(db.DefaultContext, unittest.NonexistentID) + _, err := organization.GetTeamByID(t.Context(), unittest.NonexistentID) assert.Error(t, err) } func TestIsTeamMember(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(orgID, teamID, userID int64, expected bool) { - isMember, err := organization.IsTeamMember(db.DefaultContext, orgID, teamID, userID) + isMember, err := organization.IsTeamMember(t.Context(), orgID, teamID, userID) assert.NoError(t, err) assert.Equal(t, expected, isMember) } @@ -130,7 +130,7 @@ func TestGetTeamMembers(t *testing.T) { test := func(teamID int64) { team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) - members, err := organization.GetTeamMembers(db.DefaultContext, &organization.SearchMembersOptions{ + members, err := organization.GetTeamMembers(t.Context(), &organization.SearchMembersOptions{ TeamID: teamID, }) assert.NoError(t, err) @@ -146,7 +146,7 @@ func TestGetTeamMembers(t *testing.T) { func TestGetUserTeams(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(userID int64) { - teams, _, err := organization.SearchTeam(db.DefaultContext, &organization.SearchTeamOptions{UserID: userID}) + teams, _, err := organization.SearchTeam(t.Context(), &organization.SearchTeamOptions{UserID: userID}) assert.NoError(t, err) for _, team := range teams { unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{TeamID: team.ID, UID: userID}) @@ -160,7 +160,7 @@ func TestGetUserTeams(t *testing.T) { func TestGetUserOrgTeams(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(orgID, userID int64) { - teams, err := organization.GetUserOrgTeams(db.DefaultContext, orgID, userID) + teams, err := organization.GetUserOrgTeams(t.Context(), orgID, userID) assert.NoError(t, err) for _, team := range teams { assert.Equal(t, orgID, team.OrgID) @@ -177,7 +177,7 @@ func TestHasTeamRepo(t *testing.T) { test := func(teamID, repoID int64, expected bool) { team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) - assert.Equal(t, expected, organization.HasTeamRepo(db.DefaultContext, team.OrgID, teamID, repoID)) + assert.Equal(t, expected, organization.HasTeamRepo(t.Context(), team.OrgID, teamID, repoID)) } test(1, 1, false) test(1, 3, true) @@ -192,7 +192,7 @@ func TestUsersInTeamsCount(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(teamIDs, userIDs []int64, expected int64) { - count, err := organization.UsersInTeamsCount(db.DefaultContext, teamIDs, userIDs) + count, err := organization.UsersInTeamsCount(t.Context(), teamIDs, userIDs) assert.NoError(t, err) assert.Equal(t, expected, count) } diff --git a/models/packages/descriptor.go b/models/packages/descriptor.go index 2d43dc3046..ea0e0d5e73 100644 --- a/models/packages/descriptor.go +++ b/models/packages/descriptor.go @@ -83,13 +83,13 @@ func (pd *PackageDescriptor) VersionWebLink() string { } // PackageHTMLURL returns the absolute package HTML URL -func (pd *PackageDescriptor) PackageHTMLURL() string { - return fmt.Sprintf("%s/-/packages/%s/%s", pd.Owner.HTMLURL(), string(pd.Package.Type), url.PathEscape(pd.Package.LowerName)) +func (pd *PackageDescriptor) PackageHTMLURL(ctx context.Context) string { + return fmt.Sprintf("%s/-/packages/%s/%s", pd.Owner.HTMLURL(ctx), string(pd.Package.Type), url.PathEscape(pd.Package.LowerName)) } // VersionHTMLURL returns the absolute package version HTML URL -func (pd *PackageDescriptor) VersionHTMLURL() string { - return fmt.Sprintf("%s/%s", pd.PackageHTMLURL(), url.PathEscape(pd.Version.LowerVersion)) +func (pd *PackageDescriptor) VersionHTMLURL(ctx context.Context) string { + return fmt.Sprintf("%s/%s", pd.PackageHTMLURL(ctx), url.PathEscape(pd.Version.LowerVersion)) } // CalculateBlobSize returns the total blobs size in bytes diff --git a/models/packages/package_test.go b/models/packages/package_test.go index 7f03151e77..9c71f2980d 100644 --- a/models/packages/package_test.go +++ b/models/packages/package_test.go @@ -6,7 +6,6 @@ package packages_test import ( "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" @@ -27,7 +26,7 @@ func TestHasOwnerPackages(t *testing.T) { owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - p, err := packages_model.TryInsertPackage(db.DefaultContext, &packages_model.Package{ + p, err := packages_model.TryInsertPackage(t.Context(), &packages_model.Package{ OwnerID: owner.ID, LowerName: "package", }) @@ -35,11 +34,11 @@ func TestHasOwnerPackages(t *testing.T) { 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) + has, err := packages_model.HasOwnerPackages(t.Context(), owner.ID) assert.False(t, has) assert.NoError(t, err) - pv, err := packages_model.GetOrInsertVersion(db.DefaultContext, &packages_model.PackageVersion{ + pv, err := packages_model.GetOrInsertVersion(t.Context(), &packages_model.PackageVersion{ PackageID: p.ID, LowerVersion: "internal", IsInternal: true, @@ -48,11 +47,11 @@ func TestHasOwnerPackages(t *testing.T) { assert.NoError(t, err) // A package with an internal package version gets automatically cleaned up and should return false - has, err = packages_model.HasOwnerPackages(db.DefaultContext, owner.ID) + has, err = packages_model.HasOwnerPackages(t.Context(), owner.ID) assert.False(t, has) assert.NoError(t, err) - pv, err = packages_model.GetOrInsertVersion(db.DefaultContext, &packages_model.PackageVersion{ + pv, err = packages_model.GetOrInsertVersion(t.Context(), &packages_model.PackageVersion{ PackageID: p.ID, LowerVersion: "normal", IsInternal: false, @@ -61,7 +60,7 @@ func TestHasOwnerPackages(t *testing.T) { assert.NoError(t, err) // A package with a normal package version should return true - has, err = packages_model.HasOwnerPackages(db.DefaultContext, owner.ID) + has, err = packages_model.HasOwnerPackages(t.Context(), 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 51d625707c..f01993ab4e 100644 --- a/models/perm/access/access_test.go +++ b/models/perm/access/access_test.go @@ -35,34 +35,34 @@ func TestAccessLevel(t *testing.T) { // org. owned private repo repo24 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24}) - level, err := access_model.AccessLevel(db.DefaultContext, user2, repo1) + level, err := access_model.AccessLevel(t.Context(), user2, repo1) assert.NoError(t, err) assert.Equal(t, perm_model.AccessModeOwner, level) - level, err = access_model.AccessLevel(db.DefaultContext, user2, repo3) + level, err = access_model.AccessLevel(t.Context(), user2, repo3) assert.NoError(t, err) assert.Equal(t, perm_model.AccessModeOwner, level) - level, err = access_model.AccessLevel(db.DefaultContext, user5, repo1) + level, err = access_model.AccessLevel(t.Context(), user5, repo1) assert.NoError(t, err) assert.Equal(t, perm_model.AccessModeRead, level) - level, err = access_model.AccessLevel(db.DefaultContext, user5, repo3) + level, err = access_model.AccessLevel(t.Context(), user5, repo3) assert.NoError(t, err) assert.Equal(t, perm_model.AccessModeNone, level) // restricted user has no access to a public repo - level, err = access_model.AccessLevel(db.DefaultContext, user29, repo1) + level, err = access_model.AccessLevel(t.Context(), user29, repo1) assert.NoError(t, err) assert.Equal(t, perm_model.AccessModeNone, level) // ... unless he's a collaborator - level, err = access_model.AccessLevel(db.DefaultContext, user29, repo4) + level, err = access_model.AccessLevel(t.Context(), user29, repo4) assert.NoError(t, err) assert.Equal(t, perm_model.AccessModeWrite, level) // ... or a team member - level, err = access_model.AccessLevel(db.DefaultContext, user29, repo24) + level, err = access_model.AccessLevel(t.Context(), user29, repo24) assert.NoError(t, err) assert.Equal(t, perm_model.AccessModeRead, level) } @@ -79,17 +79,17 @@ func TestHasAccess(t *testing.T) { repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) assert.True(t, repo2.IsPrivate) - has, err := access_model.HasAnyUnitAccess(db.DefaultContext, user1.ID, repo1) + has, err := access_model.HasAnyUnitAccess(t.Context(), user1.ID, repo1) assert.NoError(t, err) assert.True(t, has) - _, err = access_model.HasAnyUnitAccess(db.DefaultContext, user1.ID, repo2) + _, err = access_model.HasAnyUnitAccess(t.Context(), user1.ID, repo2) assert.NoError(t, err) - _, err = access_model.HasAnyUnitAccess(db.DefaultContext, user2.ID, repo1) + _, err = access_model.HasAnyUnitAccess(t.Context(), user2.ID, repo1) assert.NoError(t, err) - _, err = access_model.HasAnyUnitAccess(db.DefaultContext, user2.ID, repo2) + _, err = access_model.HasAnyUnitAccess(t.Context(), user2.ID, repo2) assert.NoError(t, err) } @@ -97,14 +97,14 @@ func TestRepository_RecalculateAccesses(t *testing.T) { // test with organization repo assert.NoError(t, unittest.PrepareTestDatabase()) repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) - assert.NoError(t, repo1.LoadOwner(db.DefaultContext)) + assert.NoError(t, repo1.LoadOwner(t.Context())) - _, err := db.GetEngine(db.DefaultContext).Delete(&repo_model.Collaboration{UserID: 2, RepoID: 3}) + _, err := db.GetEngine(t.Context()).Delete(&repo_model.Collaboration{UserID: 2, RepoID: 3}) assert.NoError(t, err) - assert.NoError(t, access_model.RecalculateAccesses(db.DefaultContext, repo1)) + assert.NoError(t, access_model.RecalculateAccesses(t.Context(), repo1)) access := &access_model.Access{UserID: 2, RepoID: 3} - has, err := db.GetEngine(db.DefaultContext).Get(access) + has, err := db.GetEngine(t.Context()).Get(access) assert.NoError(t, err) assert.True(t, has) assert.Equal(t, perm_model.AccessModeOwner, access.Mode) @@ -114,13 +114,13 @@ func TestRepository_RecalculateAccesses2(t *testing.T) { // test with non-organization repo assert.NoError(t, unittest.PrepareTestDatabase()) repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) - assert.NoError(t, repo1.LoadOwner(db.DefaultContext)) + assert.NoError(t, repo1.LoadOwner(t.Context())) - _, err := db.GetEngine(db.DefaultContext).Delete(&repo_model.Collaboration{UserID: 4, RepoID: 4}) + _, err := db.GetEngine(t.Context()).Delete(&repo_model.Collaboration{UserID: 4, RepoID: 4}) assert.NoError(t, err) - assert.NoError(t, access_model.RecalculateAccesses(db.DefaultContext, repo1)) + assert.NoError(t, access_model.RecalculateAccesses(t.Context(), repo1)) - has, err := db.GetEngine(db.DefaultContext).Get(&access_model.Access{UserID: 4, RepoID: 4}) + has, err := db.GetEngine(t.Context()).Get(&access_model.Access{UserID: 4, RepoID: 4}) assert.NoError(t, err) assert.False(t, has) } diff --git a/models/project/column_test.go b/models/project/column_test.go index 6a615090a5..948e012c62 100644 --- a/models/project/column_test.go +++ b/models/project/column_test.go @@ -7,7 +7,6 @@ import ( "fmt" "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert" @@ -16,29 +15,29 @@ import ( func TestGetDefaultColumn(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - projectWithoutDefault, err := GetProjectByID(db.DefaultContext, 5) + projectWithoutDefault, err := GetProjectByID(t.Context(), 5) assert.NoError(t, err) // check if default column was added - column, err := projectWithoutDefault.MustDefaultColumn(db.DefaultContext) + column, err := projectWithoutDefault.MustDefaultColumn(t.Context()) assert.NoError(t, err) assert.Equal(t, int64(5), column.ProjectID) assert.Equal(t, "Done", column.Title) - projectWithMultipleDefaults, err := GetProjectByID(db.DefaultContext, 6) + projectWithMultipleDefaults, err := GetProjectByID(t.Context(), 6) assert.NoError(t, err) // check if multiple defaults were removed - column, err = projectWithMultipleDefaults.MustDefaultColumn(db.DefaultContext) + column, err = projectWithMultipleDefaults.MustDefaultColumn(t.Context()) assert.NoError(t, err) assert.Equal(t, int64(6), column.ProjectID) assert.Equal(t, int64(9), column.ID) // there are 2 default columns in the test data, use the latest one // set 8 as default column - assert.NoError(t, SetDefaultColumn(db.DefaultContext, column.ProjectID, 8)) + assert.NoError(t, SetDefaultColumn(t.Context(), column.ProjectID, 8)) // then 9 will become a non-default column - column, err = GetColumn(db.DefaultContext, 9) + column, err = GetColumn(t.Context(), 9) assert.NoError(t, err) assert.Equal(t, int64(6), column.ProjectID) assert.False(t, column.Default) @@ -49,25 +48,25 @@ func Test_moveIssuesToAnotherColumn(t *testing.T) { column1 := unittest.AssertExistsAndLoadBean(t, &Column{ID: 1, ProjectID: 1}) - issues, err := column1.GetIssues(db.DefaultContext) + issues, err := column1.GetIssues(t.Context()) assert.NoError(t, err) assert.Len(t, issues, 1) assert.EqualValues(t, 1, issues[0].ID) column2 := unittest.AssertExistsAndLoadBean(t, &Column{ID: 2, ProjectID: 1}) - issues, err = column2.GetIssues(db.DefaultContext) + issues, err = column2.GetIssues(t.Context()) assert.NoError(t, err) assert.Len(t, issues, 1) assert.EqualValues(t, 3, issues[0].ID) - err = column1.moveIssuesToAnotherColumn(db.DefaultContext, column2) + err = column1.moveIssuesToAnotherColumn(t.Context(), column2) assert.NoError(t, err) - issues, err = column1.GetIssues(db.DefaultContext) + issues, err = column1.GetIssues(t.Context()) assert.NoError(t, err) assert.Empty(t, issues) - issues, err = column2.GetIssues(db.DefaultContext) + issues, err = column2.GetIssues(t.Context()) assert.NoError(t, err) assert.Len(t, issues, 2) assert.EqualValues(t, 3, issues[0].ID) @@ -80,21 +79,21 @@ func Test_MoveColumnsOnProject(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) project1 := unittest.AssertExistsAndLoadBean(t, &Project{ID: 1}) - columns, err := project1.GetColumns(db.DefaultContext) + columns, err := project1.GetColumns(t.Context()) assert.NoError(t, err) assert.Len(t, columns, 3) assert.EqualValues(t, 0, columns[0].Sorting) // even if there is no default sorting, the code should also work assert.EqualValues(t, 0, columns[1].Sorting) assert.EqualValues(t, 0, columns[2].Sorting) - err = MoveColumnsOnProject(db.DefaultContext, project1, map[int64]int64{ + err = MoveColumnsOnProject(t.Context(), project1, map[int64]int64{ 0: columns[1].ID, 1: columns[2].ID, 2: columns[0].ID, }) assert.NoError(t, err) - columnsAfter, err := project1.GetColumns(db.DefaultContext) + columnsAfter, err := project1.GetColumns(t.Context()) assert.NoError(t, err) assert.Len(t, columnsAfter, 3) assert.Equal(t, columns[1].ID, columnsAfter[0].ID) @@ -106,18 +105,18 @@ func Test_NewColumn(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) project1 := unittest.AssertExistsAndLoadBean(t, &Project{ID: 1}) - columns, err := project1.GetColumns(db.DefaultContext) + columns, err := project1.GetColumns(t.Context()) assert.NoError(t, err) assert.Len(t, columns, 3) for i := range maxProjectColumns - 3 { - err := NewColumn(db.DefaultContext, &Column{ + err := NewColumn(t.Context(), &Column{ Title: fmt.Sprintf("column-%d", i+4), ProjectID: project1.ID, }) assert.NoError(t, err) } - err = NewColumn(db.DefaultContext, &Column{ + err = NewColumn(t.Context(), &Column{ Title: "column-21", ProjectID: project1.ID, }) diff --git a/models/project/project_test.go b/models/project/project_test.go index c2e924e8ae..4b24615979 100644 --- a/models/project/project_test.go +++ b/models/project/project_test.go @@ -34,13 +34,13 @@ func TestIsProjectTypeValid(t *testing.T) { func TestGetProjects(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - projects, err := db.Find[Project](db.DefaultContext, SearchOptions{RepoID: 1}) + projects, err := db.Find[Project](t.Context(), SearchOptions{RepoID: 1}) assert.NoError(t, err) // 1 value for this repo exists in the fixtures assert.Len(t, projects, 1) - projects, err = db.Find[Project](db.DefaultContext, SearchOptions{RepoID: 3}) + projects, err = db.Find[Project](t.Context(), SearchOptions{RepoID: 3}) assert.NoError(t, err) // 1 value for this repo exists in the fixtures @@ -60,24 +60,24 @@ func TestProject(t *testing.T) { CreatorID: 2, } - assert.NoError(t, NewProject(db.DefaultContext, project)) + assert.NoError(t, NewProject(t.Context(), project)) - _, err := GetProjectByID(db.DefaultContext, project.ID) + _, err := GetProjectByID(t.Context(), project.ID) assert.NoError(t, err) // Update project project.Title = "Updated title" - assert.NoError(t, UpdateProject(db.DefaultContext, project)) + assert.NoError(t, UpdateProject(t.Context(), project)) - projectFromDB, err := GetProjectByID(db.DefaultContext, project.ID) + projectFromDB, err := GetProjectByID(t.Context(), project.ID) assert.NoError(t, err) assert.Equal(t, project.Title, projectFromDB.Title) - assert.NoError(t, ChangeProjectStatus(db.DefaultContext, project, true)) + assert.NoError(t, ChangeProjectStatus(t.Context(), project, true)) // Retrieve from DB afresh to check if it is truly closed - projectFromDB, err = GetProjectByID(db.DefaultContext, project.ID) + projectFromDB, err = GetProjectByID(t.Context(), project.ID) assert.NoError(t, err) assert.True(t, projectFromDB.IsClosed) @@ -109,7 +109,7 @@ func TestProjectsSort(t *testing.T) { } for _, tt := range tests { - projects, count, err := db.FindAndCount[Project](db.DefaultContext, SearchOptions{ + projects, count, err := db.FindAndCount[Project](t.Context(), SearchOptions{ OrderBy: GetSearchOrderByBySortType(tt.sortType), }) assert.NoError(t, err) diff --git a/models/repo/attachment_test.go b/models/repo/attachment_test.go index c059ffd39a..d41008344d 100644 --- a/models/repo/attachment_test.go +++ b/models/repo/attachment_test.go @@ -6,7 +6,6 @@ package repo_test import ( "testing" - "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -16,15 +15,15 @@ import ( func TestIncreaseDownloadCount(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - attachment, err := repo_model.GetAttachmentByUUID(db.DefaultContext, "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11") + attachment, err := repo_model.GetAttachmentByUUID(t.Context(), "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11") assert.NoError(t, err) assert.Equal(t, int64(0), attachment.DownloadCount) // increase download count - err = attachment.IncreaseDownloadCount(db.DefaultContext) + err = attachment.IncreaseDownloadCount(t.Context()) assert.NoError(t, err) - attachment, err = repo_model.GetAttachmentByUUID(db.DefaultContext, "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11") + attachment, err = repo_model.GetAttachmentByUUID(t.Context(), "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11") assert.NoError(t, err) assert.Equal(t, int64(1), attachment.DownloadCount) } @@ -33,11 +32,11 @@ func TestGetByCommentOrIssueID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // count of attachments from issue ID - attachments, err := repo_model.GetAttachmentsByIssueID(db.DefaultContext, 1) + attachments, err := repo_model.GetAttachmentsByIssueID(t.Context(), 1) assert.NoError(t, err) assert.Len(t, attachments, 1) - attachments, err = repo_model.GetAttachmentsByCommentID(db.DefaultContext, 1) + attachments, err = repo_model.GetAttachmentsByCommentID(t.Context(), 1) assert.NoError(t, err) assert.Len(t, attachments, 2) } @@ -45,18 +44,18 @@ func TestGetByCommentOrIssueID(t *testing.T) { func TestDeleteAttachments(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - count, err := repo_model.DeleteAttachmentsByIssue(db.DefaultContext, 4, false) + count, err := repo_model.DeleteAttachmentsByIssue(t.Context(), 4, false) assert.NoError(t, err) assert.Equal(t, 2, count) - count, err = repo_model.DeleteAttachmentsByComment(db.DefaultContext, 2, false) + count, err = repo_model.DeleteAttachmentsByComment(t.Context(), 2, false) assert.NoError(t, err) assert.Equal(t, 2, count) - err = repo_model.DeleteAttachment(db.DefaultContext, &repo_model.Attachment{ID: 8}, false) + err = repo_model.DeleteAttachment(t.Context(), &repo_model.Attachment{ID: 8}, false) assert.NoError(t, err) - attachment, err := repo_model.GetAttachmentByUUID(db.DefaultContext, "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a18") + attachment, err := repo_model.GetAttachmentByUUID(t.Context(), "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a18") assert.Error(t, err) assert.True(t, repo_model.IsErrAttachmentNotExist(err)) assert.Nil(t, attachment) @@ -65,7 +64,7 @@ func TestDeleteAttachments(t *testing.T) { func TestGetAttachmentByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - attach, err := repo_model.GetAttachmentByID(db.DefaultContext, 1) + attach, err := repo_model.GetAttachmentByID(t.Context(), 1) assert.NoError(t, err) assert.Equal(t, "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", attach.UUID) } @@ -81,12 +80,12 @@ func TestAttachment_DownloadURL(t *testing.T) { func TestUpdateAttachment(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - attach, err := repo_model.GetAttachmentByID(db.DefaultContext, 1) + attach, err := repo_model.GetAttachmentByID(t.Context(), 1) assert.NoError(t, err) assert.Equal(t, "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", attach.UUID) attach.Name = "new_name" - assert.NoError(t, repo_model.UpdateAttachment(db.DefaultContext, attach)) + assert.NoError(t, repo_model.UpdateAttachment(t.Context(), attach)) unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{Name: "new_name"}) } @@ -94,7 +93,7 @@ func TestUpdateAttachment(t *testing.T) { func TestGetAttachmentsByUUIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - attachList, err := repo_model.GetAttachmentsByUUIDs(db.DefaultContext, []string{"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a17", "not-existing-uuid"}) + attachList, err := repo_model.GetAttachmentsByUUIDs(t.Context(), []string{"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a17", "not-existing-uuid"}) assert.NoError(t, err) assert.Len(t, attachList, 2) assert.Equal(t, "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", attachList[0].UUID) diff --git a/models/repo/avatar_test.go b/models/repo/avatar_test.go index fc1f8baeca..f683a13e84 100644 --- a/models/repo/avatar_test.go +++ b/models/repo/avatar_test.go @@ -6,7 +6,6 @@ package repo import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/test" @@ -18,11 +17,11 @@ func TestRepoAvatarLink(t *testing.T) { defer test.MockVariableValue(&setting.AppSubURL, "")() repo := &Repository{ID: 1, Avatar: "avatar.png"} - link := repo.AvatarLink(db.DefaultContext) + link := repo.AvatarLink(t.Context()) assert.Equal(t, "https://localhost/repo-avatars/avatar.png", link) setting.AppURL = "https://localhost/sub-path/" setting.AppSubURL = "/sub-path" - link = repo.AvatarLink(db.DefaultContext) + link = repo.AvatarLink(t.Context()) assert.Equal(t, "https://localhost/sub-path/repo-avatars/avatar.png", link) } diff --git a/models/repo/collaboration_test.go b/models/repo/collaboration_test.go index 7b07dbffdf..7e06bffb72 100644 --- a/models/repo/collaboration_test.go +++ b/models/repo/collaboration_test.go @@ -19,9 +19,9 @@ func TestRepository_GetCollaborators(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) - collaborators, _, err := repo_model.GetCollaborators(db.DefaultContext, &repo_model.FindCollaborationOptions{RepoID: repo.ID}) + collaborators, _, err := repo_model.GetCollaborators(t.Context(), &repo_model.FindCollaborationOptions{RepoID: repo.ID}) assert.NoError(t, err) - expectedLen, err := db.GetEngine(db.DefaultContext).Count(&repo_model.Collaboration{RepoID: repoID}) + expectedLen, err := db.GetEngine(t.Context()).Count(&repo_model.Collaboration{RepoID: repoID}) assert.NoError(t, err) assert.Len(t, collaborators, int(expectedLen)) for _, collaborator := range collaborators { @@ -37,14 +37,14 @@ func TestRepository_GetCollaborators(t *testing.T) { // Test db.ListOptions repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 22}) - collaborators1, _, err := repo_model.GetCollaborators(db.DefaultContext, &repo_model.FindCollaborationOptions{ + collaborators1, _, err := repo_model.GetCollaborators(t.Context(), &repo_model.FindCollaborationOptions{ ListOptions: db.ListOptions{PageSize: 1, Page: 1}, RepoID: repo.ID, }) assert.NoError(t, err) assert.Len(t, collaborators1, 1) - collaborators2, _, err := repo_model.GetCollaborators(db.DefaultContext, &repo_model.FindCollaborationOptions{ + collaborators2, _, err := repo_model.GetCollaborators(t.Context(), &repo_model.FindCollaborationOptions{ ListOptions: db.ListOptions{PageSize: 1, Page: 2}, RepoID: repo.ID, }) @@ -59,7 +59,7 @@ func TestRepository_IsCollaborator(t *testing.T) { test := func(repoID, userID int64, expected bool) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) - actual, err := repo_model.IsCollaborator(db.DefaultContext, repo.ID, userID) + actual, err := repo_model.IsCollaborator(t.Context(), repo.ID, userID) assert.NoError(t, err) assert.Equal(t, expected, actual) } @@ -73,7 +73,7 @@ func TestRepository_ChangeCollaborationAccessMode(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) - assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, 4, perm.AccessModeAdmin)) + assert.NoError(t, repo_model.ChangeCollaborationAccessMode(t.Context(), repo, 4, perm.AccessModeAdmin)) collaboration := unittest.AssertExistsAndLoadBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: 4}) assert.Equal(t, perm.AccessModeAdmin, collaboration.Mode) @@ -81,12 +81,12 @@ func TestRepository_ChangeCollaborationAccessMode(t *testing.T) { access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: repo.ID}) assert.Equal(t, perm.AccessModeAdmin, access.Mode) - assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, 4, perm.AccessModeAdmin)) + assert.NoError(t, repo_model.ChangeCollaborationAccessMode(t.Context(), repo, 4, perm.AccessModeAdmin)) - assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, unittest.NonexistentID, perm.AccessModeAdmin)) + assert.NoError(t, repo_model.ChangeCollaborationAccessMode(t.Context(), repo, unittest.NonexistentID, perm.AccessModeAdmin)) - // Disvard invalid input. - assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, 4, perm.AccessMode(unittest.NonexistentID))) + // Discard invalid input. + assert.NoError(t, repo_model.ChangeCollaborationAccessMode(t.Context(), repo, 4, perm.AccessMode(-1))) unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repo.ID}) } @@ -97,31 +97,31 @@ func TestRepository_IsOwnerMemberCollaborator(t *testing.T) { repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // Organisation owner. - actual, err := repo_model.IsOwnerMemberCollaborator(db.DefaultContext, repo1, 2) + actual, err := repo_model.IsOwnerMemberCollaborator(t.Context(), repo1, 2) assert.NoError(t, err) assert.True(t, actual) // Team member. - actual, err = repo_model.IsOwnerMemberCollaborator(db.DefaultContext, repo1, 4) + actual, err = repo_model.IsOwnerMemberCollaborator(t.Context(), repo1, 4) assert.NoError(t, err) assert.True(t, actual) // Normal user. - actual, err = repo_model.IsOwnerMemberCollaborator(db.DefaultContext, repo1, 1) + actual, err = repo_model.IsOwnerMemberCollaborator(t.Context(), repo1, 1) assert.NoError(t, err) assert.False(t, actual) repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) // Collaborator. - actual, err = repo_model.IsOwnerMemberCollaborator(db.DefaultContext, repo2, 4) + actual, err = repo_model.IsOwnerMemberCollaborator(t.Context(), repo2, 4) assert.NoError(t, err) assert.True(t, actual) repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15}) // Repository owner. - actual, err = repo_model.IsOwnerMemberCollaborator(db.DefaultContext, repo3, 2) + actual, err = repo_model.IsOwnerMemberCollaborator(t.Context(), repo3, 2) assert.NoError(t, err) assert.True(t, actual) } @@ -132,14 +132,14 @@ func TestRepo_GetCollaboration(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) // Existing collaboration. - collab, err := repo_model.GetCollaboration(db.DefaultContext, repo.ID, 4) + collab, err := repo_model.GetCollaboration(t.Context(), repo.ID, 4) assert.NoError(t, err) assert.NotNil(t, collab) assert.EqualValues(t, 4, collab.UserID) assert.EqualValues(t, 4, collab.RepoID) // Non-existing collaboration. - collab, err = repo_model.GetCollaboration(db.DefaultContext, repo.ID, 1) + collab, err = repo_model.GetCollaboration(t.Context(), repo.ID, 1) assert.NoError(t, err) assert.Nil(t, collab) } diff --git a/models/repo/fork_test.go b/models/repo/fork_test.go index e8dca204cc..e33b6f2f0a 100644 --- a/models/repo/fork_test.go +++ b/models/repo/fork_test.go @@ -6,7 +6,6 @@ package repo_test import ( "testing" - "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -17,17 +16,17 @@ func TestGetUserFork(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // User13 has repo 11 forked from repo10 - repo, err := repo_model.GetRepositoryByID(db.DefaultContext, 10) + repo, err := repo_model.GetRepositoryByID(t.Context(), 10) assert.NoError(t, err) assert.NotNil(t, repo) - repo, err = repo_model.GetUserFork(db.DefaultContext, repo.ID, 13) + repo, err = repo_model.GetUserFork(t.Context(), repo.ID, 13) assert.NoError(t, err) assert.NotNil(t, repo) - repo, err = repo_model.GetRepositoryByID(db.DefaultContext, 9) + repo, err = repo_model.GetRepositoryByID(t.Context(), 9) assert.NoError(t, err) assert.NotNil(t, repo) - repo, err = repo_model.GetUserFork(db.DefaultContext, repo.ID, 13) + repo, err = repo_model.GetUserFork(t.Context(), repo.ID, 13) assert.NoError(t, err) assert.Nil(t, repo) } diff --git a/models/repo/pushmirror_test.go b/models/repo/pushmirror_test.go index 9fb7471147..777cc5982f 100644 --- a/models/repo/pushmirror_test.go +++ b/models/repo/pushmirror_test.go @@ -20,26 +20,26 @@ func TestPushMirrorsIterate(t *testing.T) { now := timeutil.TimeStampNow() - db.Insert(db.DefaultContext, &repo_model.PushMirror{ + db.Insert(t.Context(), &repo_model.PushMirror{ RemoteName: "test-1", LastUpdateUnix: now, Interval: 1, }) long, _ := time.ParseDuration("24h") - db.Insert(db.DefaultContext, &repo_model.PushMirror{ + db.Insert(t.Context(), &repo_model.PushMirror{ RemoteName: "test-2", LastUpdateUnix: now, Interval: long, }) - db.Insert(db.DefaultContext, &repo_model.PushMirror{ + db.Insert(t.Context(), &repo_model.PushMirror{ RemoteName: "test-3", LastUpdateUnix: now, Interval: 0, }) - repo_model.PushMirrorsIterate(db.DefaultContext, 1, func(idx int, bean any) error { + repo_model.PushMirrorsIterate(t.Context(), 1, func(idx int, bean any) error { m, ok := bean.(*repo_model.PushMirror) assert.True(t, ok) assert.Equal(t, "test-1", m.RemoteName) diff --git a/models/repo/redirect_test.go b/models/repo/redirect_test.go index 24cf7e89fb..aa5e5b7c6b 100644 --- a/models/repo/redirect_test.go +++ b/models/repo/redirect_test.go @@ -6,7 +6,6 @@ package repo_test import ( "testing" - "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -16,11 +15,11 @@ import ( func TestLookupRedirect(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repoID, err := repo_model.LookupRedirect(db.DefaultContext, 2, "oldrepo1") + repoID, err := repo_model.LookupRedirect(t.Context(), 2, "oldrepo1") assert.NoError(t, err) assert.EqualValues(t, 1, repoID) - _, err = repo_model.LookupRedirect(db.DefaultContext, unittest.NonexistentID, "doesnotexist") + _, err = repo_model.LookupRedirect(t.Context(), unittest.NonexistentID, "doesnotexist") assert.True(t, repo_model.IsErrRedirectNotExist(err)) } @@ -29,7 +28,7 @@ func TestNewRedirect(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - assert.NoError(t, repo_model.NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "newreponame")) + assert.NoError(t, repo_model.NewRedirect(t.Context(), repo.OwnerID, repo.ID, repo.Name, "newreponame")) unittest.AssertExistsAndLoadBean(t, &repo_model.Redirect{ OwnerID: repo.OwnerID, @@ -48,7 +47,7 @@ func TestNewRedirect2(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - assert.NoError(t, repo_model.NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "oldrepo1")) + assert.NoError(t, repo_model.NewRedirect(t.Context(), repo.OwnerID, repo.ID, repo.Name, "oldrepo1")) unittest.AssertExistsAndLoadBean(t, &repo_model.Redirect{ OwnerID: repo.OwnerID, @@ -67,7 +66,7 @@ func TestNewRedirect3(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) - assert.NoError(t, repo_model.NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "newreponame")) + assert.NoError(t, repo_model.NewRedirect(t.Context(), repo.OwnerID, repo.ID, repo.Name, "newreponame")) unittest.AssertExistsAndLoadBean(t, &repo_model.Redirect{ OwnerID: repo.OwnerID, diff --git a/models/repo/release.go b/models/repo/release.go index 0db57503ce..67aa390e6d 100644 --- a/models/repo/release.go +++ b/models/repo/release.go @@ -282,11 +282,8 @@ func (opts FindReleasesOptions) ToOrders() string { // GetTagNamesByRepoID returns a list of release tag names of repository. func GetTagNamesByRepoID(ctx context.Context, repoID int64) ([]string, error) { - listOptions := db.ListOptions{ - ListAll: true, - } opts := FindReleasesOptions{ - ListOptions: listOptions, + ListOptions: db.ListOptionsAll, IncludeDrafts: true, IncludeTags: true, HasSha1: optional.Some(true), diff --git a/models/repo/release_test.go b/models/repo/release_test.go index 41ea083229..01f0fb3cff 100644 --- a/models/repo/release_test.go +++ b/models/repo/release_test.go @@ -6,7 +6,6 @@ package repo import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert" @@ -22,14 +21,14 @@ func TestMigrate_InsertReleases(t *testing.T) { Attachments: []*Attachment{a}, } - err := InsertReleases(db.DefaultContext, r) + err := InsertReleases(t.Context(), r) assert.NoError(t, err) } func Test_FindTagsByCommitIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - sha1Rels, err := FindTagsByCommitIDs(db.DefaultContext, 1, "65f1bf27bc3bf70f64657658635e66094edbcb4d") + sha1Rels, err := FindTagsByCommitIDs(t.Context(), 1, "65f1bf27bc3bf70f64657658635e66094edbcb4d") assert.NoError(t, err) assert.Len(t, sha1Rels, 1) rels := sha1Rels["65f1bf27bc3bf70f64657658635e66094edbcb4d"] diff --git a/models/repo/repo.go b/models/repo/repo.go index 2403b3b40b..8237a429e5 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -229,6 +229,10 @@ func RelativePath(ownerName, repoName string) string { return strings.ToLower(ownerName) + "/" + strings.ToLower(repoName) + ".git" } +func RelativeWikiPath(ownerName, repoName string) string { + return strings.ToLower(ownerName) + "/" + strings.ToLower(repoName) + ".wiki.git" +} + // RelativePath should be an unix style path like username/reponame.git func (repo *Repository) RelativePath() string { return RelativePath(repo.OwnerName, repo.Name) @@ -241,8 +245,10 @@ func (sr StorageRepo) RelativePath() string { return string(sr) } +// WikiStorageRepo returns the storage repo for the wiki +// The wiki repository should have the same object format as the code repository func (repo *Repository) WikiStorageRepo() StorageRepo { - return StorageRepo(strings.ToLower(repo.OwnerName) + "/" + strings.ToLower(repo.Name) + ".wiki.git") + return StorageRepo(RelativeWikiPath(repo.OwnerName, repo.Name)) } // SanitizedOriginalURL returns a sanitized OriginalURL @@ -363,10 +369,8 @@ func (repo *Repository) FullName() string { // HTMLURL returns the repository HTML URL func (repo *Repository) HTMLURL(ctxs ...context.Context) string { - ctx := context.TODO() - if len(ctxs) > 0 { - ctx = ctxs[0] - } + // FIXME: this HTMLURL is still used in mail templates, so the "ctx" is not provided. + ctx := util.OptionalArg(ctxs, context.TODO()) return httplib.MakeAbsoluteURL(ctx, repo.Link()) } diff --git a/models/repo/repo_list_test.go b/models/repo/repo_list_test.go index 7eb76416c2..6cc0d3155c 100644 --- a/models/repo/repo_list_test.go +++ b/models/repo/repo_list_test.go @@ -184,7 +184,7 @@ func TestSearchRepository(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // test search public repository on explore page - repos, count, err := repo_model.SearchRepositoryByName(db.DefaultContext, repo_model.SearchRepoOptions{ + repos, count, err := repo_model.SearchRepositoryByName(t.Context(), repo_model.SearchRepoOptions{ ListOptions: db.ListOptions{ Page: 1, PageSize: 10, @@ -199,7 +199,7 @@ func TestSearchRepository(t *testing.T) { } assert.Equal(t, int64(1), count) - repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, repo_model.SearchRepoOptions{ + repos, count, err = repo_model.SearchRepositoryByName(t.Context(), repo_model.SearchRepoOptions{ ListOptions: db.ListOptions{ Page: 1, PageSize: 10, @@ -213,7 +213,7 @@ func TestSearchRepository(t *testing.T) { assert.Len(t, repos, 2) // test search private repository on explore page - repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, repo_model.SearchRepoOptions{ + repos, count, err = repo_model.SearchRepositoryByName(t.Context(), repo_model.SearchRepoOptions{ ListOptions: db.ListOptions{ Page: 1, PageSize: 10, @@ -229,7 +229,7 @@ func TestSearchRepository(t *testing.T) { } assert.Equal(t, int64(1), count) - repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, repo_model.SearchRepoOptions{ + repos, count, err = repo_model.SearchRepositoryByName(t.Context(), repo_model.SearchRepoOptions{ ListOptions: db.ListOptions{ Page: 1, PageSize: 10, @@ -244,14 +244,14 @@ func TestSearchRepository(t *testing.T) { assert.Len(t, repos, 3) // Test non existing owner - repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, repo_model.SearchRepoOptions{OwnerID: unittest.NonexistentID}) + repos, count, err = repo_model.SearchRepositoryByName(t.Context(), repo_model.SearchRepoOptions{OwnerID: unittest.NonexistentID}) assert.NoError(t, err) assert.Empty(t, repos) assert.Equal(t, int64(0), count) // Test search within description - repos, count, err = repo_model.SearchRepository(db.DefaultContext, repo_model.SearchRepoOptions{ + repos, count, err = repo_model.SearchRepository(t.Context(), repo_model.SearchRepoOptions{ ListOptions: db.ListOptions{ Page: 1, PageSize: 10, @@ -268,7 +268,7 @@ func TestSearchRepository(t *testing.T) { assert.Equal(t, int64(1), count) // Test NOT search within description - repos, count, err = repo_model.SearchRepository(db.DefaultContext, repo_model.SearchRepoOptions{ + repos, count, err = repo_model.SearchRepository(t.Context(), repo_model.SearchRepoOptions{ ListOptions: db.ListOptions{ Page: 1, PageSize: 10, @@ -286,7 +286,7 @@ func TestSearchRepository(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - repos, count, err := repo_model.SearchRepositoryByName(db.DefaultContext, testCase.opts) + repos, count, err := repo_model.SearchRepositoryByName(t.Context(), testCase.opts) assert.NoError(t, err) assert.Equal(t, int64(testCase.count), count) @@ -361,7 +361,7 @@ func TestCountRepository(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - count, err := repo_model.CountRepository(db.DefaultContext, testCase.opts) + count, err := repo_model.CountRepository(t.Context(), testCase.opts) assert.NoError(t, err) assert.Equal(t, int64(testCase.count), count) @@ -396,7 +396,7 @@ func TestSearchRepositoryByTopicName(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - _, count, err := repo_model.SearchRepositoryByName(db.DefaultContext, testCase.opts) + _, count, err := repo_model.SearchRepositoryByName(t.Context(), testCase.opts) assert.NoError(t, err) assert.Equal(t, int64(testCase.count), count) }) diff --git a/models/repo/repo_test.go b/models/repo/repo_test.go index 66abe864fc..ce17789a3b 100644 --- a/models/repo/repo_test.go +++ b/models/repo/repo_test.go @@ -6,7 +6,6 @@ package repo import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -28,7 +27,7 @@ var ( func TestGetRepositoryCount(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - ctx := db.DefaultContext + ctx := t.Context() count, err1 := CountRepositories(ctx, countRepospts) privateCount, err2 := CountRepositories(ctx, countReposptsPrivate) publicCount, err3 := CountRepositories(ctx, countReposptsPublic) @@ -42,7 +41,7 @@ func TestGetRepositoryCount(t *testing.T) { func TestGetPublicRepositoryCount(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - count, err := CountRepositories(db.DefaultContext, countReposptsPublic) + count, err := CountRepositories(t.Context(), countReposptsPublic) assert.NoError(t, err) assert.Equal(t, int64(1), count) } @@ -50,7 +49,7 @@ func TestGetPublicRepositoryCount(t *testing.T) { func TestGetPrivateRepositoryCount(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - count, err := CountRepositories(db.DefaultContext, countReposptsPrivate) + count, err := CountRepositories(t.Context(), countReposptsPrivate) assert.NoError(t, err) assert.Equal(t, int64(2), count) } @@ -68,11 +67,11 @@ func TestWatchRepo(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 3}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - assert.NoError(t, WatchRepo(db.DefaultContext, user, repo, true)) + assert.NoError(t, WatchRepo(t.Context(), user, repo, true)) unittest.AssertExistsAndLoadBean(t, &Watch{RepoID: repo.ID, UserID: user.ID}) unittest.CheckConsistencyFor(t, &Repository{ID: repo.ID}) - assert.NoError(t, WatchRepo(db.DefaultContext, user, repo, false)) + assert.NoError(t, WatchRepo(t.Context(), user, repo, false)) unittest.AssertNotExistsBean(t, &Watch{RepoID: repo.ID, UserID: user.ID}) unittest.CheckConsistencyFor(t, &Repository{ID: repo.ID}) } @@ -86,7 +85,7 @@ func TestMetas(t *testing.T) { repo.Units = nil - metas := repo.ComposeCommentMetas(db.DefaultContext) + metas := repo.ComposeCommentMetas(t.Context()) assert.Equal(t, "testRepo", metas["repo"]) assert.Equal(t, "testOwner", metas["user"]) @@ -100,7 +99,7 @@ func TestMetas(t *testing.T) { testSuccess := func(expectedStyle string) { repo.Units = []*RepoUnit{&externalTracker} repo.commonRenderingMetas = nil - metas := repo.ComposeCommentMetas(db.DefaultContext) + metas := repo.ComposeCommentMetas(t.Context()) assert.Equal(t, expectedStyle, metas["style"]) assert.Equal(t, "testRepo", metas["repo"]) assert.Equal(t, "testOwner", metas["user"]) @@ -118,10 +117,10 @@ func TestMetas(t *testing.T) { externalTracker.ExternalTrackerConfig().ExternalTrackerStyle = markup.IssueNameStyleRegexp testSuccess(markup.IssueNameStyleRegexp) - repo, err := GetRepositoryByID(db.DefaultContext, 3) + repo, err := GetRepositoryByID(t.Context(), 3) assert.NoError(t, err) - metas = repo.ComposeCommentMetas(db.DefaultContext) + metas = repo.ComposeCommentMetas(t.Context()) assert.Contains(t, metas, "org") assert.Contains(t, metas, "teams") assert.Equal(t, "org3", metas["org"]) @@ -132,13 +131,13 @@ func TestGetRepositoryByURL(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) t.Run("InvalidPath", func(t *testing.T) { - repo, err := GetRepositoryByURL(db.DefaultContext, "something") + repo, err := GetRepositoryByURL(t.Context(), "something") assert.Nil(t, repo) assert.Error(t, err) }) testRepo2 := func(t *testing.T, url string) { - repo, err := GetRepositoryByURL(db.DefaultContext, url) + repo, err := GetRepositoryByURL(t.Context(), url) require.NoError(t, err) assert.EqualValues(t, 2, repo.ID) assert.EqualValues(t, 2, repo.OwnerID) @@ -162,7 +161,7 @@ func TestGetRepositoryByURL(t *testing.T) { testRepo2(t, "sshuser@try.gitea.io:user2/repo2.git") testRelax := func(t *testing.T, url string) { - repo, err := GetRepositoryByURLRelax(db.DefaultContext, url) + repo, err := GetRepositoryByURLRelax(t.Context(), url) require.NoError(t, err) assert.Equal(t, int64(2), repo.ID) assert.Equal(t, int64(2), repo.OwnerID) diff --git a/models/repo/star_test.go b/models/repo/star_test.go index b540f54310..4fd256cd08 100644 --- a/models/repo/star_test.go +++ b/models/repo/star_test.go @@ -21,25 +21,25 @@ func TestStarRepo(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) unittest.AssertNotExistsBean(t, &repo_model.Star{UID: user.ID, RepoID: repo.ID}) - assert.NoError(t, repo_model.StarRepo(db.DefaultContext, user, repo, true)) + assert.NoError(t, repo_model.StarRepo(t.Context(), user, repo, true)) unittest.AssertExistsAndLoadBean(t, &repo_model.Star{UID: user.ID, RepoID: repo.ID}) - assert.NoError(t, repo_model.StarRepo(db.DefaultContext, user, repo, true)) + assert.NoError(t, repo_model.StarRepo(t.Context(), user, repo, true)) unittest.AssertExistsAndLoadBean(t, &repo_model.Star{UID: user.ID, RepoID: repo.ID}) - assert.NoError(t, repo_model.StarRepo(db.DefaultContext, user, repo, false)) + assert.NoError(t, repo_model.StarRepo(t.Context(), user, repo, false)) unittest.AssertNotExistsBean(t, &repo_model.Star{UID: user.ID, RepoID: repo.ID}) } func TestIsStaring(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.True(t, repo_model.IsStaring(db.DefaultContext, 2, 4)) - assert.False(t, repo_model.IsStaring(db.DefaultContext, 3, 4)) + assert.True(t, repo_model.IsStaring(t.Context(), 2, 4)) + assert.False(t, repo_model.IsStaring(t.Context(), 3, 4)) } func TestRepository_GetStargazers(t *testing.T) { // repo with stargazers assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) - gazers, err := repo_model.GetStargazers(db.DefaultContext, repo, db.ListOptions{Page: 0}) + gazers, err := repo_model.GetStargazers(t.Context(), repo, db.ListOptions{Page: 0}) assert.NoError(t, err) if assert.Len(t, gazers, 1) { assert.Equal(t, int64(2), gazers[0].ID) @@ -50,7 +50,7 @@ func TestRepository_GetStargazers2(t *testing.T) { // repo with stargazers assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) - gazers, err := repo_model.GetStargazers(db.DefaultContext, repo, db.ListOptions{Page: 0}) + gazers, err := repo_model.GetStargazers(t.Context(), repo, db.ListOptions{Page: 0}) assert.NoError(t, err) assert.Empty(t, gazers) } @@ -62,14 +62,14 @@ func TestClearRepoStars(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) unittest.AssertNotExistsBean(t, &repo_model.Star{UID: user.ID, RepoID: repo.ID}) - assert.NoError(t, repo_model.StarRepo(db.DefaultContext, user, repo, true)) + assert.NoError(t, repo_model.StarRepo(t.Context(), user, repo, true)) unittest.AssertExistsAndLoadBean(t, &repo_model.Star{UID: user.ID, RepoID: repo.ID}) - assert.NoError(t, repo_model.StarRepo(db.DefaultContext, user, repo, false)) + assert.NoError(t, repo_model.StarRepo(t.Context(), user, repo, false)) unittest.AssertNotExistsBean(t, &repo_model.Star{UID: user.ID, RepoID: repo.ID}) - assert.NoError(t, repo_model.ClearRepoStars(db.DefaultContext, repo.ID)) + assert.NoError(t, repo_model.ClearRepoStars(t.Context(), repo.ID)) unittest.AssertNotExistsBean(t, &repo_model.Star{UID: user.ID, RepoID: repo.ID}) - gazers, err := repo_model.GetStargazers(db.DefaultContext, repo, db.ListOptions{Page: 0}) + gazers, err := repo_model.GetStargazers(t.Context(), repo, db.ListOptions{Page: 0}) assert.NoError(t, err) assert.Empty(t, gazers) } diff --git a/models/repo/topic_test.go b/models/repo/topic_test.go index b6a7aed7b1..903b9ad3fa 100644 --- a/models/repo/topic_test.go +++ b/models/repo/topic_test.go @@ -19,47 +19,47 @@ func TestAddTopic(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - topics, err := db.Find[repo_model.Topic](db.DefaultContext, &repo_model.FindTopicOptions{}) + topics, err := db.Find[repo_model.Topic](t.Context(), &repo_model.FindTopicOptions{}) assert.NoError(t, err) assert.Len(t, topics, totalNrOfTopics) - topics, total, err := db.FindAndCount[repo_model.Topic](db.DefaultContext, &repo_model.FindTopicOptions{ + topics, total, err := db.FindAndCount[repo_model.Topic](t.Context(), &repo_model.FindTopicOptions{ ListOptions: db.ListOptions{Page: 1, PageSize: 2}, }) assert.NoError(t, err) assert.Len(t, topics, 2) assert.EqualValues(t, 6, total) - topics, err = db.Find[repo_model.Topic](db.DefaultContext, &repo_model.FindTopicOptions{ + topics, err = db.Find[repo_model.Topic](t.Context(), &repo_model.FindTopicOptions{ RepoID: 1, }) assert.NoError(t, err) assert.Len(t, topics, repo1NrOfTopics) - assert.NoError(t, repo_model.SaveTopics(db.DefaultContext, 2, "golang")) + assert.NoError(t, repo_model.SaveTopics(t.Context(), 2, "golang")) repo2NrOfTopics := 1 - topics, err = db.Find[repo_model.Topic](db.DefaultContext, &repo_model.FindTopicOptions{}) + topics, err = db.Find[repo_model.Topic](t.Context(), &repo_model.FindTopicOptions{}) assert.NoError(t, err) assert.Len(t, topics, totalNrOfTopics) - topics, err = db.Find[repo_model.Topic](db.DefaultContext, &repo_model.FindTopicOptions{ + topics, err = db.Find[repo_model.Topic](t.Context(), &repo_model.FindTopicOptions{ RepoID: 2, }) assert.NoError(t, err) assert.Len(t, topics, repo2NrOfTopics) - assert.NoError(t, repo_model.SaveTopics(db.DefaultContext, 2, "golang", "gitea")) + assert.NoError(t, repo_model.SaveTopics(t.Context(), 2, "golang", "gitea")) repo2NrOfTopics = 2 totalNrOfTopics++ - topic, err := repo_model.GetTopicByName(db.DefaultContext, "gitea") + topic, err := repo_model.GetTopicByName(t.Context(), "gitea") assert.NoError(t, err) assert.Equal(t, 1, topic.RepoCount) - topics, err = db.Find[repo_model.Topic](db.DefaultContext, &repo_model.FindTopicOptions{}) + topics, err = db.Find[repo_model.Topic](t.Context(), &repo_model.FindTopicOptions{}) assert.NoError(t, err) assert.Len(t, topics, totalNrOfTopics) - topics, err = db.Find[repo_model.Topic](db.DefaultContext, &repo_model.FindTopicOptions{ + topics, err = db.Find[repo_model.Topic](t.Context(), &repo_model.FindTopicOptions{ RepoID: 2, }) assert.NoError(t, err) diff --git a/models/repo/user_repo_test.go b/models/repo/user_repo_test.go index 50c970344c..a53cf39dc4 100644 --- a/models/repo/user_repo_test.go +++ b/models/repo/user_repo_test.go @@ -6,7 +6,6 @@ package repo_test import ( "testing" - "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" @@ -19,21 +18,21 @@ func TestRepoAssignees(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) - users, err := repo_model.GetRepoAssignees(db.DefaultContext, repo2) + users, err := repo_model.GetRepoAssignees(t.Context(), repo2) assert.NoError(t, err) assert.Len(t, users, 1) assert.Equal(t, int64(2), users[0].ID) repo21 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 21}) - users, err = repo_model.GetRepoAssignees(db.DefaultContext, repo21) + users, err = repo_model.GetRepoAssignees(t.Context(), repo21) assert.NoError(t, err) if assert.Len(t, users, 4) { assert.ElementsMatch(t, []int64{10, 15, 16, 18}, []int64{users[0].ID, users[1].ID, users[2].ID, users[3].ID}) } // do not return deactivated users - assert.NoError(t, user_model.UpdateUserCols(db.DefaultContext, &user_model.User{ID: 15, IsActive: false}, "is_active")) - users, err = repo_model.GetRepoAssignees(db.DefaultContext, repo21) + assert.NoError(t, user_model.UpdateUserCols(t.Context(), &user_model.User{ID: 15, IsActive: false}, "is_active")) + users, err = repo_model.GetRepoAssignees(t.Context(), repo21) assert.NoError(t, err) if assert.Len(t, users, 3) { assert.NotContains(t, []int64{users[0].ID, users[1].ID, users[2].ID}, 15) @@ -45,12 +44,12 @@ func TestGetIssuePostersWithSearch(t *testing.T) { repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) - users, err := repo_model.GetIssuePostersWithSearch(db.DefaultContext, repo2, false, "USER", false /* full name */) + users, err := repo_model.GetIssuePostersWithSearch(t.Context(), repo2, false, "USER", false /* full name */) require.NoError(t, err) require.Len(t, users, 1) assert.Equal(t, "user2", users[0].Name) - users, err = repo_model.GetIssuePostersWithSearch(db.DefaultContext, repo2, false, "TW%O", true /* full name */) + users, err = repo_model.GetIssuePostersWithSearch(t.Context(), repo2, false, "TW%O", true /* full name */) require.NoError(t, err) require.Len(t, users, 1) assert.Equal(t, "user2", users[0].Name) diff --git a/models/repo/watch_test.go b/models/repo/watch_test.go index 7ed72386c9..19e363f6b0 100644 --- a/models/repo/watch_test.go +++ b/models/repo/watch_test.go @@ -18,20 +18,20 @@ import ( func TestIsWatching(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.True(t, repo_model.IsWatching(db.DefaultContext, 1, 1)) - assert.True(t, repo_model.IsWatching(db.DefaultContext, 4, 1)) - assert.True(t, repo_model.IsWatching(db.DefaultContext, 11, 1)) + assert.True(t, repo_model.IsWatching(t.Context(), 1, 1)) + assert.True(t, repo_model.IsWatching(t.Context(), 4, 1)) + assert.True(t, repo_model.IsWatching(t.Context(), 11, 1)) - assert.False(t, repo_model.IsWatching(db.DefaultContext, 1, 5)) - assert.False(t, repo_model.IsWatching(db.DefaultContext, 8, 1)) - assert.False(t, repo_model.IsWatching(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)) + assert.False(t, repo_model.IsWatching(t.Context(), 1, 5)) + assert.False(t, repo_model.IsWatching(t.Context(), 8, 1)) + assert.False(t, repo_model.IsWatching(t.Context(), unittest.NonexistentID, unittest.NonexistentID)) } func TestGetWatchers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - watches, err := repo_model.GetWatchers(db.DefaultContext, repo.ID) + watches, err := repo_model.GetWatchers(t.Context(), repo.ID) assert.NoError(t, err) // One watchers are inactive, thus minus 1 assert.Len(t, watches, repo.NumWatches-1) @@ -39,7 +39,7 @@ func TestGetWatchers(t *testing.T) { assert.Equal(t, repo.ID, watch.RepoID) } - watches, err = repo_model.GetWatchers(db.DefaultContext, unittest.NonexistentID) + watches, err = repo_model.GetWatchers(t.Context(), unittest.NonexistentID) assert.NoError(t, err) assert.Empty(t, watches) } @@ -48,7 +48,7 @@ func TestRepository_GetWatchers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - watchers, err := repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1}) + watchers, err := repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1}) assert.NoError(t, err) assert.Len(t, watchers, repo.NumWatches) for _, watcher := range watchers { @@ -56,7 +56,7 @@ func TestRepository_GetWatchers(t *testing.T) { } repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 9}) - watchers, err = repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1}) + watchers, err = repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1}) assert.NoError(t, err) assert.Empty(t, watchers) } @@ -67,7 +67,7 @@ func TestWatchIfAuto(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) user12 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 12}) - watchers, err := repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1}) + watchers, err := repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1}) assert.NoError(t, err) assert.Len(t, watchers, repo.NumWatches) @@ -76,46 +76,46 @@ func TestWatchIfAuto(t *testing.T) { prevCount := repo.NumWatches // Must not add watch - assert.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 8, 1, true)) - watchers, err = repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1}) + assert.NoError(t, repo_model.WatchIfAuto(t.Context(), 8, 1, true)) + watchers, err = repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1}) assert.NoError(t, err) assert.Len(t, watchers, prevCount) // Should not add watch - assert.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 10, 1, true)) - watchers, err = repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1}) + assert.NoError(t, repo_model.WatchIfAuto(t.Context(), 10, 1, true)) + watchers, err = repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1}) assert.NoError(t, err) assert.Len(t, watchers, prevCount) setting.Service.AutoWatchOnChanges = true // Must not add watch - assert.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 8, 1, true)) - watchers, err = repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1}) + assert.NoError(t, repo_model.WatchIfAuto(t.Context(), 8, 1, true)) + watchers, err = repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1}) assert.NoError(t, err) assert.Len(t, watchers, prevCount) // Should not add watch - assert.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 12, 1, false)) - watchers, err = repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1}) + assert.NoError(t, repo_model.WatchIfAuto(t.Context(), 12, 1, false)) + watchers, err = repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1}) assert.NoError(t, err) assert.Len(t, watchers, prevCount) // Should add watch - assert.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 12, 1, true)) - watchers, err = repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1}) + assert.NoError(t, repo_model.WatchIfAuto(t.Context(), 12, 1, true)) + watchers, err = repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1}) assert.NoError(t, err) assert.Len(t, watchers, prevCount+1) // Should remove watch, inhibit from adding auto - assert.NoError(t, repo_model.WatchRepo(db.DefaultContext, user12, repo, false)) - watchers, err = repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1}) + assert.NoError(t, repo_model.WatchRepo(t.Context(), user12, repo, false)) + watchers, err = repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1}) assert.NoError(t, err) assert.Len(t, watchers, prevCount) // Must not add watch - assert.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 12, 1, true)) - watchers, err = repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1}) + assert.NoError(t, repo_model.WatchIfAuto(t.Context(), 12, 1, true)) + watchers, err = repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1}) assert.NoError(t, err) assert.Len(t, watchers, prevCount) } diff --git a/models/repo/wiki.go b/models/repo/wiki.go index 832e15ae0d..9f41445bf8 100644 --- a/models/repo/wiki.go +++ b/models/repo/wiki.go @@ -11,7 +11,6 @@ import ( "strings" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" ) @@ -86,12 +85,3 @@ func WikiPath(userName, repoName string) string { func (repo *Repository) WikiPath() string { return WikiPath(repo.OwnerName, repo.Name) } - -// HasWiki returns true if repository has wiki. -func (repo *Repository) HasWiki() bool { - isDir, err := util.IsDir(repo.WikiPath()) - if err != nil { - log.Error("Unable to check if %s is a directory: %v", repo.WikiPath(), err) - } - return isDir -} diff --git a/models/repo/wiki_test.go b/models/repo/wiki_test.go index 103420a392..41e53d93d9 100644 --- a/models/repo/wiki_test.go +++ b/models/repo/wiki_test.go @@ -35,11 +35,3 @@ func TestRepository_WikiPath(t *testing.T) { expected := filepath.Join(setting.RepoRootPath, "user2/repo1.wiki.git") assert.Equal(t, expected, repo.WikiPath()) } - -func TestRepository_HasWiki(t *testing.T) { - unittest.PrepareTestEnv(t) - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - assert.True(t, repo1.HasWiki()) - repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) - assert.False(t, repo2.HasWiki()) -} diff --git a/models/repo_test.go b/models/repo_test.go index b6c53fd197..5273b9d838 100644 --- a/models/repo_test.go +++ b/models/repo_test.go @@ -6,7 +6,6 @@ package models import ( "testing" - "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" @@ -15,13 +14,13 @@ import ( func TestCheckRepoStats(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.NoError(t, CheckRepoStats(db.DefaultContext)) + assert.NoError(t, CheckRepoStats(t.Context())) } func TestDoctorUserStarNum(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.NoError(t, DoctorUserStarNum(db.DefaultContext)) + assert.NoError(t, DoctorUserStarNum(t.Context())) } func Test_repoStatsCorrectIssueNumComments(t *testing.T) { @@ -31,7 +30,7 @@ func Test_repoStatsCorrectIssueNumComments(t *testing.T) { assert.NotNil(t, issue2) assert.Equal(t, 0, issue2.NumComments) // the fixture data is wrong, but we don't fix it here - assert.NoError(t, repoStatsCorrectIssueNumComments(db.DefaultContext, 2)) + assert.NoError(t, repoStatsCorrectIssueNumComments(t.Context(), 2)) // reload the issue issue2 = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) assert.Equal(t, 1, issue2.NumComments) diff --git a/models/system/notice.go b/models/system/notice.go index 91bf4be0f6..f39188f8fb 100644 --- a/models/system/notice.go +++ b/models/system/notice.go @@ -9,6 +9,7 @@ import ( "time" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/timeutil" @@ -56,8 +57,7 @@ func CreateNotice(ctx context.Context, tp NoticeType, desc string, args ...any) // CreateRepositoryNotice creates new system notice with type NoticeRepository. func CreateRepositoryNotice(desc string, args ...any) error { - // Note we use the db.DefaultContext here rather than passing in a context as the context may be cancelled - return CreateNotice(db.DefaultContext, NoticeRepository, desc, args...) + return CreateNotice(graceful.GetManager().ShutdownContext(), NoticeRepository, desc, args...) } // RemoveAllWithNotice removes all directories in given path and @@ -66,8 +66,7 @@ func RemoveAllWithNotice(ctx context.Context, title, path string) { if err := util.RemoveAll(path); err != nil { desc := fmt.Sprintf("%s [%s]: %v", title, path, err) log.Warn(title+" [%s]: %v", path, err) - // Note we use the db.DefaultContext here rather than passing in a context as the context may be cancelled - if err = CreateNotice(db.DefaultContext, NoticeRepository, desc); err != nil { + if err = CreateNotice(graceful.GetManager().ShutdownContext(), NoticeRepository, desc); err != nil { log.Error("CreateRepositoryNotice: %v", err) } } @@ -80,8 +79,7 @@ func RemoveStorageWithNotice(ctx context.Context, bucket storage.ObjectStorage, desc := fmt.Sprintf("%s [%s]: %v", title, path, err) log.Warn(title+" [%s]: %v", path, err) - // Note we use the db.DefaultContext here rather than passing in a context as the context may be cancelled - if err = CreateNotice(db.DefaultContext, NoticeRepository, desc); err != nil { + if err = CreateNotice(graceful.GetManager().ShutdownContext(), NoticeRepository, desc); err != nil { log.Error("CreateRepositoryNotice: %v", err) } } diff --git a/models/system/notice_test.go b/models/system/notice_test.go index 9fc9e6cce1..802bcf41b1 100644 --- a/models/system/notice_test.go +++ b/models/system/notice_test.go @@ -29,7 +29,7 @@ func TestCreateNotice(t *testing.T) { Description: "test description", } unittest.AssertNotExistsBean(t, noticeBean) - assert.NoError(t, system.CreateNotice(db.DefaultContext, noticeBean.Type, noticeBean.Description)) + assert.NoError(t, system.CreateNotice(t.Context(), noticeBean.Type, noticeBean.Description)) unittest.AssertExistsAndLoadBean(t, noticeBean) } @@ -47,20 +47,20 @@ func TestCreateRepositoryNotice(t *testing.T) { func TestCountNotices(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.Equal(t, int64(3), system.CountNotices(db.DefaultContext)) + assert.Equal(t, int64(3), system.CountNotices(t.Context())) } func TestNotices(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - notices, err := system.Notices(db.DefaultContext, 1, 2) + notices, err := system.Notices(t.Context(), 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 = system.Notices(db.DefaultContext, 2, 2) + notices, err = system.Notices(t.Context(), 2, 2) assert.NoError(t, err) if assert.Len(t, notices, 1) { assert.Equal(t, int64(1), notices[0].ID) @@ -74,7 +74,7 @@ func TestDeleteNotices(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 1}) unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 2}) unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 3}) - assert.NoError(t, system.DeleteNotices(db.DefaultContext, 1, 2)) + assert.NoError(t, system.DeleteNotices(t.Context(), 1, 2)) unittest.AssertNotExistsBean(t, &system.Notice{ID: 1}) unittest.AssertNotExistsBean(t, &system.Notice{ID: 2}) unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 3}) @@ -87,7 +87,7 @@ func TestDeleteNotices2(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 1}) unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 2}) unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 3}) - assert.NoError(t, system.DeleteNotices(db.DefaultContext, 3, 2)) + assert.NoError(t, system.DeleteNotices(t.Context(), 3, 2)) unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 1}) unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 2}) unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 3}) @@ -99,7 +99,7 @@ func TestDeleteNoticesByIDs(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 1}) unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 2}) unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 3}) - err := db.DeleteByIDs[system.Notice](db.DefaultContext, 1, 3) + err := db.DeleteByIDs[system.Notice](t.Context(), 1, 3) assert.NoError(t, err) unittest.AssertNotExistsBean(t, &system.Notice{ID: 1}) unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 2}) diff --git a/models/system/setting_test.go b/models/system/setting_test.go index 7e7e0c8fca..780a323fe1 100644 --- a/models/system/setting_test.go +++ b/models/system/setting_test.go @@ -17,34 +17,34 @@ func TestSettings(t *testing.T) { keyName := "test.key" assert.NoError(t, unittest.PrepareTestDatabase()) - assert.NoError(t, db.TruncateBeans(db.DefaultContext, &system.Setting{})) + assert.NoError(t, db.TruncateBeans(t.Context(), &system.Setting{})) - rev, settings, err := system.GetAllSettings(db.DefaultContext) + rev, settings, err := system.GetAllSettings(t.Context()) assert.NoError(t, err) assert.Equal(t, 1, rev) assert.Len(t, settings, 1) // there is only one "revision" key - err = system.SetSettings(db.DefaultContext, map[string]string{keyName: "true"}) + err = system.SetSettings(t.Context(), map[string]string{keyName: "true"}) assert.NoError(t, err) - rev, settings, err = system.GetAllSettings(db.DefaultContext) + rev, settings, err = system.GetAllSettings(t.Context()) assert.NoError(t, err) assert.Equal(t, 2, rev) assert.Len(t, settings, 2) assert.Equal(t, "true", settings[keyName]) - err = system.SetSettings(db.DefaultContext, map[string]string{keyName: "false"}) + err = system.SetSettings(t.Context(), map[string]string{keyName: "false"}) assert.NoError(t, err) - rev, settings, err = system.GetAllSettings(db.DefaultContext) + rev, settings, err = system.GetAllSettings(t.Context()) assert.NoError(t, err) assert.Equal(t, 3, rev) assert.Len(t, settings, 2) assert.Equal(t, "false", settings[keyName]) // setting the same value should not trigger DuplicateKey error, and the "version" should be increased - err = system.SetSettings(db.DefaultContext, map[string]string{keyName: "false"}) + err = system.SetSettings(t.Context(), map[string]string{keyName: "false"}) assert.NoError(t, err) - rev, settings, err = system.GetAllSettings(db.DefaultContext) + rev, settings, err = system.GetAllSettings(t.Context()) assert.NoError(t, err) assert.Len(t, settings, 2) assert.Equal(t, 4, rev) diff --git a/models/unittest/consistency.go b/models/unittest/consistency.go index 364afb5c52..8447bd93ba 100644 --- a/models/unittest/consistency.go +++ b/models/unittest/consistency.go @@ -4,6 +4,7 @@ package unittest import ( + "context" "reflect" "strconv" "strings" @@ -22,10 +23,10 @@ const ( modelsCommentTypeComment = 0 ) -var consistencyCheckMap = make(map[string]func(t assert.TestingT, bean any)) +var consistencyCheckMap = make(map[string]func(t TestingT, bean any)) // CheckConsistencyFor test that all matching database entries are consistent -func CheckConsistencyFor(t require.TestingT, beansToCheck ...any) { +func CheckConsistencyFor(t TestingT, beansToCheck ...any) { for _, bean := range beansToCheck { sliceType := reflect.SliceOf(reflect.TypeOf(bean)) sliceValue := reflect.MakeSlice(sliceType, 0, 10) @@ -33,7 +34,7 @@ func CheckConsistencyFor(t require.TestingT, beansToCheck ...any) { ptrToSliceValue := reflect.New(sliceType) ptrToSliceValue.Elem().Set(sliceValue) - assert.NoError(t, db.GetEngine(db.DefaultContext).Table(bean).Find(ptrToSliceValue.Interface())) + assert.NoError(t, db.GetEngine(context.TODO()).Table(bean).Find(ptrToSliceValue.Interface())) sliceValue = ptrToSliceValue.Elem() for i := 0; i < sliceValue.Len(); i++ { @@ -43,8 +44,8 @@ func CheckConsistencyFor(t require.TestingT, beansToCheck ...any) { } } -func checkForConsistency(t require.TestingT, bean any) { - tb, err := db.TableInfo(bean) +func checkForConsistency(t TestingT, bean any) { + tb, err := GetXORMEngine().TableInfo(bean) assert.NoError(t, err) f := consistencyCheckMap[tb.Name] require.NotNil(t, f, "unknown bean type: %#v", bean) @@ -61,7 +62,7 @@ func init() { return i } - checkForUserConsistency := func(t assert.TestingT, bean any) { + checkForUserConsistency := func(t TestingT, bean any) { user := reflectionWrap(bean) AssertCountByCond(t, "repository", builder.Eq{"owner_id": user.int("ID")}, user.int("NumRepos")) AssertCountByCond(t, "star", builder.Eq{"uid": user.int("ID")}, user.int("NumStars")) @@ -75,7 +76,7 @@ func init() { } } - checkForRepoConsistency := func(t assert.TestingT, bean any) { + checkForRepoConsistency := func(t TestingT, bean any) { repo := reflectionWrap(bean) assert.Equal(t, repo.str("LowerName"), strings.ToLower(repo.str("Name")), "repo: %+v", repo) AssertCountByCond(t, "star", builder.Eq{"repo_id": repo.int("ID")}, repo.int("NumStars")) @@ -111,7 +112,7 @@ func init() { "Unexpected number of closed milestones for repo id: %d", repo.int("ID")) } - checkForIssueConsistency := func(t assert.TestingT, bean any) { + checkForIssueConsistency := func(t TestingT, bean any) { issue := reflectionWrap(bean) typeComment := modelsCommentTypeComment actual := GetCountByCond(t, "comment", builder.Eq{"`type`": typeComment, "issue_id": issue.int("ID")}) @@ -122,14 +123,14 @@ func init() { } } - checkForPullRequestConsistency := func(t assert.TestingT, bean any) { + checkForPullRequestConsistency := func(t TestingT, bean any) { pr := reflectionWrap(bean) issueRow := AssertExistsAndLoadMap(t, "issue", builder.Eq{"id": pr.int("IssueID")}) assert.True(t, parseBool(issueRow["is_pull"])) assert.Equal(t, parseInt(issueRow["index"]), pr.int("Index"), "Unexpected index for pull request id: %d", pr.int("ID")) } - checkForMilestoneConsistency := func(t assert.TestingT, bean any) { + checkForMilestoneConsistency := func(t TestingT, bean any) { milestone := reflectionWrap(bean) AssertCountByCond(t, "issue", builder.Eq{"milestone_id": milestone.int("ID")}, milestone.int("NumIssues")) @@ -143,9 +144,9 @@ func init() { assert.Equal(t, completeness, milestone.int("Completeness")) } - checkForLabelConsistency := func(t assert.TestingT, bean any) { + checkForLabelConsistency := func(t TestingT, bean any) { label := reflectionWrap(bean) - issueLabels, err := db.GetEngine(db.DefaultContext).Table("issue_label"). + issueLabels, err := db.GetEngine(context.TODO()).Table("issue_label"). Where(builder.Eq{"label_id": label.int("ID")}). Query() assert.NoError(t, err) @@ -164,13 +165,13 @@ func init() { assert.EqualValues(t, expected, label.int("NumClosedIssues"), "Unexpected number of closed issues for label id: %d", label.int("ID")) } - checkForTeamConsistency := func(t assert.TestingT, bean any) { + checkForTeamConsistency := func(t TestingT, bean any) { team := reflectionWrap(bean) AssertCountByCond(t, "team_user", builder.Eq{"team_id": team.int("ID")}, team.int("NumMembers")) AssertCountByCond(t, "team_repo", builder.Eq{"team_id": team.int("ID")}, team.int("NumRepos")) } - checkForActionConsistency := func(t assert.TestingT, bean any) { + checkForActionConsistency := func(t TestingT, bean any) { action := reflectionWrap(bean) if action.int("RepoID") != 1700 { // dangling intentional repoRow := AssertExistsAndLoadMap(t, "repository", builder.Eq{"id": action.int("RepoID")}) diff --git a/models/unittest/fixtures.go b/models/unittest/fixtures.go index fb2d2d0085..a9a01a3227 100644 --- a/models/unittest/fixtures.go +++ b/models/unittest/fixtures.go @@ -23,7 +23,7 @@ var fixturesLoader FixturesLoader // GetXORMEngine gets the XORM engine func GetXORMEngine() (x *xorm.Engine) { - return db.GetEngine(db.DefaultContext).(*xorm.Engine) + return db.GetXORMEngineForTesting() } func loadFixtureResetSeqPgsql(e *xorm.Engine) error { diff --git a/models/unittest/fixtures_loader.go b/models/unittest/fixtures_loader.go index 0560da8349..d92b0cdb14 100644 --- a/models/unittest/fixtures_loader.go +++ b/models/unittest/fixtures_loader.go @@ -218,7 +218,7 @@ func NewFixturesLoader(x *xorm.Engine, opts FixturesOptions) (FixturesLoader, er xormBeans, _ := db.NamesToBean() f.xormTableNames = map[string]bool{} for _, bean := range xormBeans { - f.xormTableNames[db.TableName(bean)] = true + f.xormTableNames[x.TableName(bean)] = true } return f, nil diff --git a/models/unittest/testdb.go b/models/unittest/testdb.go index cb60cf5f85..4611a079ec 100644 --- a/models/unittest/testdb.go +++ b/models/unittest/testdb.go @@ -141,7 +141,7 @@ func MainTest(m *testing.M, testOptsArg ...*TestOptions) { fatalTestError("util.SyncDirs: %v\n", err) } - if err = git.InitFull(context.Background()); err != nil { + if err = git.InitFull(); err != nil { fatalTestError("git.Init: %v\n", err) } diff --git a/models/unittest/unit_tests.go b/models/unittest/unit_tests.go index 4a4cec40ae..c49b26fea4 100644 --- a/models/unittest/unit_tests.go +++ b/models/unittest/unit_tests.go @@ -4,6 +4,7 @@ package unittest import ( + "context" "fmt" "math" "os" @@ -14,7 +15,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "xorm.io/builder" - "xorm.io/xorm" ) // Code in this file is mainly used by unittest.CheckConsistencyFor, which is not in the unit test for various reasons. @@ -23,6 +23,12 @@ import ( // NonexistentID an ID that will never exist const NonexistentID = int64(math.MaxInt64) +type TestingT interface { + require.TestingT + assert.TestingT + Context() context.Context +} + type testCond struct { query any args []any @@ -55,13 +61,13 @@ func whereOrderConditions(e db.Engine, conditions []any) db.Engine { return e.OrderBy(orderBy) } -func getBeanIfExists(bean any, conditions ...any) (bool, error) { - e := db.GetEngine(db.DefaultContext) +func getBeanIfExists(t TestingT, bean any, conditions ...any) (bool, error) { + e := db.GetEngine(t.Context()) return whereOrderConditions(e, conditions).Get(bean) } -func GetBean[T any](t require.TestingT, bean T, conditions ...any) (ret T) { - exists, err := getBeanIfExists(bean, conditions...) +func GetBean[T any](t TestingT, bean T, conditions ...any) (ret T) { + exists, err := getBeanIfExists(t, bean, conditions...) require.NoError(t, err) if exists { return bean @@ -70,8 +76,8 @@ func GetBean[T any](t require.TestingT, bean T, conditions ...any) (ret T) { } // AssertExistsAndLoadBean assert that a bean exists and load it from the test database -func AssertExistsAndLoadBean[T any](t require.TestingT, bean T, conditions ...any) T { - exists, err := getBeanIfExists(bean, conditions...) +func AssertExistsAndLoadBean[T any](t TestingT, bean T, conditions ...any) T { + exists, err := getBeanIfExists(t, bean, conditions...) require.NoError(t, err) require.True(t, exists, "Expected to find %+v (of type %T, with conditions %+v), but did not", @@ -80,8 +86,8 @@ func AssertExistsAndLoadBean[T any](t require.TestingT, bean T, conditions ...an } // AssertExistsAndLoadMap assert that a row exists and load it from the test database -func AssertExistsAndLoadMap(t assert.TestingT, table string, conditions ...any) map[string]string { - e := db.GetEngine(db.DefaultContext).Table(table) +func AssertExistsAndLoadMap(t TestingT, table string, conditions ...any) map[string]string { + e := db.GetEngine(t.Context()).Table(table) res, err := whereOrderConditions(e, conditions).Query() assert.NoError(t, err) assert.Len(t, res, 1, @@ -100,8 +106,8 @@ func AssertExistsAndLoadMap(t assert.TestingT, table string, conditions ...any) } // GetCount get the count of a bean -func GetCount(t assert.TestingT, bean any, conditions ...any) int { - e := db.GetEngine(db.DefaultContext) +func GetCount(t TestingT, bean any, conditions ...any) int { + e := db.GetEngine(t.Context()) for _, condition := range conditions { switch cond := condition.(type) { case *testCond: @@ -116,14 +122,14 @@ func GetCount(t assert.TestingT, bean any, conditions ...any) int { } // AssertNotExistsBean assert that a bean does not exist in the test database -func AssertNotExistsBean(t assert.TestingT, bean any, conditions ...any) { - exists, err := getBeanIfExists(bean, conditions...) +func AssertNotExistsBean(t TestingT, bean any, conditions ...any) { + exists, err := getBeanIfExists(t, bean, conditions...) assert.NoError(t, err) assert.False(t, exists) } // AssertCount assert the count of a bean -func AssertCount(t assert.TestingT, bean, expected any) bool { +func AssertCount(t TestingT, bean, expected any) bool { return assert.EqualValues(t, expected, GetCount(t, bean)) } @@ -134,26 +140,26 @@ func AssertInt64InRange(t assert.TestingT, low, high, value int64) { } // GetCountByCond get the count of database entries matching bean -func GetCountByCond(t assert.TestingT, tableName string, cond builder.Cond) int64 { - e := db.GetEngine(db.DefaultContext) +func GetCountByCond(t TestingT, tableName string, cond builder.Cond) int64 { + e := db.GetEngine(t.Context()) count, err := e.Table(tableName).Where(cond).Count() assert.NoError(t, err) return count } // AssertCountByCond test the count of database entries matching bean -func AssertCountByCond(t assert.TestingT, tableName string, cond builder.Cond, expected int) bool { +func AssertCountByCond(t TestingT, tableName string, cond builder.Cond, expected int) bool { return assert.EqualValues(t, expected, GetCountByCond(t, tableName, cond), "Failed consistency test, the counted bean (of table %s) was %+v", tableName, cond) } // DumpQueryResult dumps the result of a query for debugging purpose func DumpQueryResult(t require.TestingT, sqlOrBean any, sqlArgs ...any) { - x := db.GetEngine(db.DefaultContext).(*xorm.Engine) + x := GetXORMEngine() goDB := x.DB().DB sql, ok := sqlOrBean.(string) if !ok { - sql = "SELECT * FROM " + db.TableName(sqlOrBean) + sql = "SELECT * FROM " + x.TableName(sqlOrBean) } else if !strings.Contains(sql, " ") { sql = "SELECT * FROM " + sql } diff --git a/models/user/avatar_test.go b/models/user/avatar_test.go index 941068957c..9ebf00de49 100644 --- a/models/user/avatar_test.go +++ b/models/user/avatar_test.go @@ -8,7 +8,6 @@ import ( "strings" "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" @@ -23,12 +22,12 @@ func TestUserAvatarLink(t *testing.T) { defer test.MockVariableValue(&setting.AppSubURL, "")() u := &User{ID: 1, Avatar: "avatar.png"} - link := u.AvatarLink(db.DefaultContext) + link := u.AvatarLink(t.Context()) assert.Equal(t, "https://localhost/avatars/avatar.png", link) setting.AppURL = "https://localhost/sub-path/" setting.AppSubURL = "/sub-path" - link = u.AvatarLink(db.DefaultContext) + link = u.AvatarLink(t.Context()) assert.Equal(t, "https://localhost/sub-path/avatars/avatar.png", link) } @@ -43,7 +42,7 @@ func TestUserAvatarGenerate(t *testing.T) { // there was no avatar, generate a new one assert.Empty(t, u.Avatar) - err = GenerateRandomAvatar(db.DefaultContext, u) + err = GenerateRandomAvatar(t.Context(), u) require.NoError(t, err) assert.NotEmpty(t, u.Avatar) @@ -56,7 +55,7 @@ func TestUserAvatarGenerate(t *testing.T) { require.NoError(t, err) // try to generate again - err = GenerateRandomAvatar(db.DefaultContext, u) + err = GenerateRandomAvatar(t.Context(), u) require.NoError(t, err) assert.Equal(t, oldAvatarPath, u.CustomAvatarRelativePath()) f, err := storage.Avatars.Open(u.CustomAvatarRelativePath()) diff --git a/models/user/email_address.go b/models/user/email_address.go index cb423945f8..67aa1bdd82 100644 --- a/models/user/email_address.go +++ b/models/user/email_address.go @@ -442,58 +442,53 @@ func SearchEmails(ctx context.Context, opts *SearchEmailOptions) ([]*SearchEmail // ActivateUserEmail will change the activated state of an email address, // either primary or secondary (all in the email_address table) func ActivateUserEmail(ctx context.Context, userID int64, email string, activate bool) (err error) { - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return err - } - defer committer.Close() - - // Activate/deactivate a user's secondary email address - // First check if there's another user active with the same address - addr, exist, err := db.Get[EmailAddress](ctx, builder.Eq{"uid": userID, "lower_email": strings.ToLower(email)}) - if err != nil { - return err - } else if !exist { - return fmt.Errorf("no such email: %d (%s)", userID, email) - } - - if addr.IsActivated == activate { - // Already in the desired state; no action - return nil - } - if activate { - if used, err := IsEmailActive(ctx, email, addr.ID); err != nil { - return fmt.Errorf("unable to check isEmailActive() for %s: %w", email, err) - } else if used { - return ErrEmailAlreadyUsed{Email: email} - } - } - if err = updateActivation(ctx, addr, activate); err != nil { - return fmt.Errorf("unable to updateActivation() for %d:%s: %w", addr.ID, addr.Email, err) - } - - // Activate/deactivate a user's primary email address and account - if addr.IsPrimary { - user, exist, err := db.Get[User](ctx, builder.Eq{"id": userID}) + return db.WithTx(ctx, func(ctx context.Context) error { + // Activate/deactivate a user's secondary email address + // First check if there's another user active with the same address + addr, exist, err := db.Get[EmailAddress](ctx, builder.Eq{"uid": userID, "lower_email": strings.ToLower(email)}) if err != nil { return err - } else if !exist || !strings.EqualFold(user.Email, email) { - return fmt.Errorf("no user with ID: %d and Email: %s", userID, email) + } else if !exist { + return fmt.Errorf("no such email: %d (%s)", userID, email) } - // The user's activation state should be synchronized with the primary email - if user.IsActive != activate { - user.IsActive = activate - if user.Rands, err = GetUserSalt(); err != nil { - return fmt.Errorf("unable to generate salt: %w", err) - } - if err = UpdateUserCols(ctx, user, "is_active", "rands"); err != nil { - return fmt.Errorf("unable to updateUserCols() for user ID: %d: %w", userID, err) + if addr.IsActivated == activate { + // Already in the desired state; no action + return nil + } + if activate { + if used, err := IsEmailActive(ctx, email, addr.ID); err != nil { + return fmt.Errorf("unable to check isEmailActive() for %s: %w", email, err) + } else if used { + return ErrEmailAlreadyUsed{Email: email} } } - } + if err = updateActivation(ctx, addr, activate); err != nil { + return fmt.Errorf("unable to updateActivation() for %d:%s: %w", addr.ID, addr.Email, err) + } - return committer.Commit() + // Activate/deactivate a user's primary email address and account + if addr.IsPrimary { + user, exist, err := db.Get[User](ctx, builder.Eq{"id": userID}) + if err != nil { + return err + } else if !exist || !strings.EqualFold(user.Email, email) { + return fmt.Errorf("no user with ID: %d and Email: %s", userID, email) + } + + // The user's activation state should be synchronized with the primary email + if user.IsActive != activate { + user.IsActive = activate + if user.Rands, err = GetUserSalt(); err != nil { + return fmt.Errorf("unable to generate salt: %w", err) + } + if err = UpdateUserCols(ctx, user, "is_active", "rands"); err != nil { + return fmt.Errorf("unable to updateUserCols() for user ID: %d: %w", userID, err) + } + } + } + return nil + }) } // validateEmailBasic checks whether the email complies with the rules diff --git a/models/user/email_address_test.go b/models/user/email_address_test.go index c0666246b0..6ef18fb0f6 100644 --- a/models/user/email_address_test.go +++ b/models/user/email_address_test.go @@ -18,14 +18,14 @@ import ( func TestGetEmailAddresses(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - emails, _ := user_model.GetEmailAddresses(db.DefaultContext, int64(1)) + emails, _ := user_model.GetEmailAddresses(t.Context(), int64(1)) if assert.Len(t, emails, 3) { assert.True(t, emails[0].IsPrimary) assert.True(t, emails[2].IsActivated) assert.False(t, emails[2].IsPrimary) } - emails, _ = user_model.GetEmailAddresses(db.DefaultContext, int64(2)) + emails, _ = user_model.GetEmailAddresses(t.Context(), int64(2)) if assert.Len(t, emails, 2) { assert.True(t, emails[0].IsPrimary) assert.True(t, emails[0].IsActivated) @@ -35,36 +35,36 @@ func TestGetEmailAddresses(t *testing.T) { func TestIsEmailUsed(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - isExist, _ := user_model.IsEmailUsed(db.DefaultContext, "") + isExist, _ := user_model.IsEmailUsed(t.Context(), "") assert.True(t, isExist) - isExist, _ = user_model.IsEmailUsed(db.DefaultContext, "user11@example.com") + isExist, _ = user_model.IsEmailUsed(t.Context(), "user11@example.com") assert.True(t, isExist) - isExist, _ = user_model.IsEmailUsed(db.DefaultContext, "user1234567890@example.com") + isExist, _ = user_model.IsEmailUsed(t.Context(), "user1234567890@example.com") assert.False(t, isExist) } func TestMakeEmailPrimary(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - err := user_model.MakeActiveEmailPrimary(db.DefaultContext, 9999999) + err := user_model.MakeActiveEmailPrimary(t.Context(), 9999999) assert.Error(t, err) assert.ErrorIs(t, err, user_model.ErrEmailAddressNotExist{}) email := unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "user11@example.com"}) - err = user_model.MakeActiveEmailPrimary(db.DefaultContext, email.ID) + err = user_model.MakeActiveEmailPrimary(t.Context(), email.ID) assert.Error(t, err) assert.ErrorIs(t, err, user_model.ErrEmailAddressNotExist{}) // inactive email is considered as not exist for "MakeActiveEmailPrimary" email = unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "user9999999@example.com"}) - err = user_model.MakeActiveEmailPrimary(db.DefaultContext, email.ID) + err = user_model.MakeActiveEmailPrimary(t.Context(), email.ID) assert.Error(t, err) assert.True(t, user_model.IsErrUserNotExist(err)) email = unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "user101@example.com"}) - err = user_model.MakeActiveEmailPrimary(db.DefaultContext, email.ID) + err = user_model.MakeActiveEmailPrimary(t.Context(), email.ID) assert.NoError(t, err) - user, _ := user_model.GetUserByID(db.DefaultContext, int64(10)) + user, _ := user_model.GetUserByID(t.Context(), int64(10)) assert.Equal(t, "user101@example.com", user.Email) } @@ -76,9 +76,9 @@ func TestActivate(t *testing.T) { UID: int64(1), Email: "user11@example.com", } - assert.NoError(t, user_model.ActivateEmail(db.DefaultContext, email)) + assert.NoError(t, user_model.ActivateEmail(t.Context(), email)) - emails, _ := user_model.GetEmailAddresses(db.DefaultContext, int64(1)) + emails, _ := user_model.GetEmailAddresses(t.Context(), int64(1)) assert.Len(t, emails, 3) assert.True(t, emails[0].IsActivated) assert.True(t, emails[0].IsPrimary) @@ -96,7 +96,7 @@ func TestListEmails(t *testing.T) { PageSize: 10000, }, } - emails, count, err := user_model.SearchEmails(db.DefaultContext, opts) + emails, count, err := user_model.SearchEmails(t.Context(), opts) assert.NoError(t, err) assert.Greater(t, count, int64(5)) @@ -110,13 +110,13 @@ func TestListEmails(t *testing.T) { // Must find no records opts = &user_model.SearchEmailOptions{Keyword: "NOTFOUND"} - emails, count, err = user_model.SearchEmails(db.DefaultContext, opts) + emails, count, err = user_model.SearchEmails(t.Context(), opts) assert.NoError(t, err) assert.Equal(t, int64(0), count) // Must find users 'user2', 'user28', etc. opts = &user_model.SearchEmailOptions{Keyword: "user2"} - emails, count, err = user_model.SearchEmails(db.DefaultContext, opts) + emails, count, err = user_model.SearchEmails(t.Context(), opts) assert.NoError(t, err) assert.NotEqual(t, int64(0), count) assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 2 })) @@ -124,14 +124,14 @@ func TestListEmails(t *testing.T) { // Must find only primary addresses (i.e. from the `user` table) opts = &user_model.SearchEmailOptions{IsPrimary: optional.Some(true)} - emails, _, err = user_model.SearchEmails(db.DefaultContext, opts) + emails, _, err = user_model.SearchEmails(t.Context(), opts) assert.NoError(t, err) assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsPrimary })) assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsPrimary })) // Must find only inactive addresses (i.e. not validated) opts = &user_model.SearchEmailOptions{IsActivated: optional.Some(false)} - emails, _, err = user_model.SearchEmails(db.DefaultContext, opts) + emails, _, err = user_model.SearchEmails(t.Context(), opts) assert.NoError(t, err) assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsActivated })) assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsActivated })) @@ -143,7 +143,7 @@ func TestListEmails(t *testing.T) { Page: 1, }, } - emails, count, err = user_model.SearchEmails(db.DefaultContext, opts) + emails, count, err = user_model.SearchEmails(t.Context(), opts) assert.NoError(t, err) assert.Len(t, emails, 5) assert.Greater(t, count, int64(len(emails))) diff --git a/models/user/follow_test.go b/models/user/follow_test.go index c327d935ae..1d5f144164 100644 --- a/models/user/follow_test.go +++ b/models/user/follow_test.go @@ -6,7 +6,6 @@ package user_test import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -15,9 +14,9 @@ import ( func TestIsFollowing(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.True(t, user_model.IsFollowing(db.DefaultContext, 4, 2)) - assert.False(t, user_model.IsFollowing(db.DefaultContext, 2, 4)) - assert.False(t, user_model.IsFollowing(db.DefaultContext, 5, unittest.NonexistentID)) - assert.False(t, user_model.IsFollowing(db.DefaultContext, unittest.NonexistentID, 5)) - assert.False(t, user_model.IsFollowing(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)) + assert.True(t, user_model.IsFollowing(t.Context(), 4, 2)) + assert.False(t, user_model.IsFollowing(t.Context(), 2, 4)) + assert.False(t, user_model.IsFollowing(t.Context(), 5, unittest.NonexistentID)) + assert.False(t, user_model.IsFollowing(t.Context(), unittest.NonexistentID, 5)) + assert.False(t, user_model.IsFollowing(t.Context(), unittest.NonexistentID, unittest.NonexistentID)) } diff --git a/models/user/openid_test.go b/models/user/openid_test.go index 708af9e653..fa260e7a9e 100644 --- a/models/user/openid_test.go +++ b/models/user/openid_test.go @@ -6,7 +6,6 @@ package user_test import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -17,7 +16,7 @@ import ( func TestGetUserOpenIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - oids, err := user_model.GetUserOpenIDs(db.DefaultContext, int64(1)) + oids, err := user_model.GetUserOpenIDs(t.Context(), int64(1)) if assert.NoError(t, err) && assert.Len(t, oids, 2) { assert.Equal(t, "https://user1.domain1.tld/", oids[0].URI) assert.False(t, oids[0].Show) @@ -25,7 +24,7 @@ func TestGetUserOpenIDs(t *testing.T) { assert.True(t, oids[1].Show) } - oids, err = user_model.GetUserOpenIDs(db.DefaultContext, int64(2)) + oids, err = user_model.GetUserOpenIDs(t.Context(), int64(2)) if assert.NoError(t, err) && assert.Len(t, oids, 1) { assert.Equal(t, "https://domain1.tld/user2/", oids[0].URI) assert.True(t, oids[0].Show) @@ -34,23 +33,23 @@ func TestGetUserOpenIDs(t *testing.T) { func TestToggleUserOpenIDVisibility(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - oids, err := user_model.GetUserOpenIDs(db.DefaultContext, int64(2)) + oids, err := user_model.GetUserOpenIDs(t.Context(), int64(2)) require.NoError(t, err) require.Len(t, oids, 1) assert.True(t, oids[0].Show) - err = user_model.ToggleUserOpenIDVisibility(db.DefaultContext, oids[0].ID) + err = user_model.ToggleUserOpenIDVisibility(t.Context(), oids[0].ID) require.NoError(t, err) - oids, err = user_model.GetUserOpenIDs(db.DefaultContext, int64(2)) + oids, err = user_model.GetUserOpenIDs(t.Context(), int64(2)) require.NoError(t, err) require.Len(t, oids, 1) assert.False(t, oids[0].Show) - err = user_model.ToggleUserOpenIDVisibility(db.DefaultContext, oids[0].ID) + err = user_model.ToggleUserOpenIDVisibility(t.Context(), oids[0].ID) require.NoError(t, err) - oids, err = user_model.GetUserOpenIDs(db.DefaultContext, int64(2)) + oids, err = user_model.GetUserOpenIDs(t.Context(), int64(2)) require.NoError(t, err) if assert.Len(t, oids, 1) { assert.True(t, oids[0].Show) diff --git a/models/user/redirect_test.go b/models/user/redirect_test.go index 484c5a663f..015eac0668 100644 --- a/models/user/redirect_test.go +++ b/models/user/redirect_test.go @@ -6,7 +6,6 @@ package user_test import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -16,10 +15,10 @@ import ( func TestLookupUserRedirect(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - userID, err := user_model.LookupUserRedirect(db.DefaultContext, "olduser1") + userID, err := user_model.LookupUserRedirect(t.Context(), "olduser1") assert.NoError(t, err) assert.EqualValues(t, 1, userID) - _, err = user_model.LookupUserRedirect(db.DefaultContext, "doesnotexist") + _, err = user_model.LookupUserRedirect(t.Context(), "doesnotexist") assert.True(t, user_model.IsErrUserRedirectNotExist(err)) } diff --git a/models/user/setting_test.go b/models/user/setting_test.go index 3c199013f3..7332e442b4 100644 --- a/models/user/setting_test.go +++ b/models/user/setting_test.go @@ -6,7 +6,6 @@ package user_test import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -20,41 +19,41 @@ func TestSettings(t *testing.T) { newSetting := &user_model.Setting{UserID: 99, SettingKey: keyName, SettingValue: "Gitea User Setting Test"} // create setting - err := user_model.SetUserSetting(db.DefaultContext, newSetting.UserID, newSetting.SettingKey, newSetting.SettingValue) + err := user_model.SetUserSetting(t.Context(), newSetting.UserID, newSetting.SettingKey, newSetting.SettingValue) assert.NoError(t, err) // test about saving unchanged values - err = user_model.SetUserSetting(db.DefaultContext, newSetting.UserID, newSetting.SettingKey, newSetting.SettingValue) + err = user_model.SetUserSetting(t.Context(), newSetting.UserID, newSetting.SettingKey, newSetting.SettingValue) assert.NoError(t, err) // get specific setting - settings, err := user_model.GetSettings(db.DefaultContext, 99, []string{keyName}) + settings, err := user_model.GetSettings(t.Context(), 99, []string{keyName}) assert.NoError(t, err) assert.Len(t, settings, 1) assert.Equal(t, newSetting.SettingValue, settings[keyName].SettingValue) - settingValue, err := user_model.GetUserSetting(db.DefaultContext, 99, keyName) + settingValue, err := user_model.GetUserSetting(t.Context(), 99, keyName) assert.NoError(t, err) assert.Equal(t, newSetting.SettingValue, settingValue) - settingValue, err = user_model.GetUserSetting(db.DefaultContext, 99, "no_such") + settingValue, err = user_model.GetUserSetting(t.Context(), 99, "no_such") assert.NoError(t, err) assert.Empty(t, settingValue) // updated setting updatedSetting := &user_model.Setting{UserID: 99, SettingKey: keyName, SettingValue: "Updated"} - err = user_model.SetUserSetting(db.DefaultContext, updatedSetting.UserID, updatedSetting.SettingKey, updatedSetting.SettingValue) + err = user_model.SetUserSetting(t.Context(), updatedSetting.UserID, updatedSetting.SettingKey, updatedSetting.SettingValue) assert.NoError(t, err) // get all settings - settings, err = user_model.GetUserAllSettings(db.DefaultContext, 99) + settings, err = user_model.GetUserAllSettings(t.Context(), 99) assert.NoError(t, err) assert.Len(t, settings, 1) assert.Equal(t, updatedSetting.SettingValue, settings[updatedSetting.SettingKey].SettingValue) // delete setting - err = user_model.DeleteUserSetting(db.DefaultContext, 99, keyName) + err = user_model.DeleteUserSetting(t.Context(), 99, keyName) assert.NoError(t, err) - settings, err = user_model.GetUserAllSettings(db.DefaultContext, 99) + settings, err = user_model.GetUserAllSettings(t.Context(), 99) assert.NoError(t, err) assert.Empty(t, settings) } diff --git a/models/user/user.go b/models/user/user.go index c362cbc6d2..6143992a25 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -27,6 +27,7 @@ import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/httplib" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" @@ -303,8 +304,8 @@ func (u *User) HomeLink() string { } // HTMLURL returns the user or organization's full link. -func (u *User) HTMLURL() string { - return setting.AppURL + url.PathEscape(u.Name) +func (u *User) HTMLURL(ctx context.Context) string { + return httplib.MakeAbsoluteURL(ctx, u.HomeLink()) } // OrganisationLink returns the organization sub page link. @@ -715,90 +716,82 @@ func createUser(ctx context.Context, u *User, meta *Meta, createdByAdmin bool, o } } - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return err - } - defer committer.Close() - - isExist, err := IsUserExist(ctx, 0, u.Name) - if err != nil { - return err - } else if isExist { - return ErrUserAlreadyExist{u.Name} - } - - isExist, err = IsEmailUsed(ctx, u.Email) - if err != nil { - return err - } else if isExist { - return ErrEmailAlreadyUsed{ - Email: u.Email, + return db.WithTx(ctx, func(ctx context.Context) error { + isExist, err := IsUserExist(ctx, 0, u.Name) + if err != nil { + return err + } else if isExist { + return ErrUserAlreadyExist{u.Name} } - } - // prepare for database + isExist, err = IsEmailUsed(ctx, u.Email) + if err != nil { + return err + } else if isExist { + return ErrEmailAlreadyUsed{ + Email: u.Email, + } + } - u.LowerName = strings.ToLower(u.Name) - u.AvatarEmail = u.Email - if u.Rands, err = GetUserSalt(); err != nil { - return err - } - if u.Passwd != "" { - if err = u.SetPassword(u.Passwd); err != nil { + // prepare for database + + u.LowerName = strings.ToLower(u.Name) + u.AvatarEmail = u.Email + if u.Rands, err = GetUserSalt(); err != nil { return err } - } else { - u.Salt = "" - u.PasswdHashAlgo = "" - } + if u.Passwd != "" { + if err = u.SetPassword(u.Passwd); err != nil { + return err + } + } else { + u.Salt = "" + u.PasswdHashAlgo = "" + } - // save changes to database + // save changes to database - if err = DeleteUserRedirect(ctx, u.Name); err != nil { - return err - } - - if u.CreatedUnix == 0 { - // Caller expects auto-time for creation & update timestamps. - err = db.Insert(ctx, u) - } else { - // Caller sets the timestamps themselves. They are responsible for ensuring - // both `CreatedUnix` and `UpdatedUnix` are set appropriately. - _, err = db.GetEngine(ctx).NoAutoTime().Insert(u) - } - if err != nil { - return err - } - - if setting.RecordUserSignupMetadata { - // insert initial IP and UserAgent - if err = SetUserSetting(ctx, u.ID, SignupIP, meta.InitialIP); err != nil { + if err = DeleteUserRedirect(ctx, u.Name); err != nil { return err } - // trim user agent string to a reasonable length, if necessary - userAgent := strings.TrimSpace(meta.InitialUserAgent) - if len(userAgent) > 255 { - userAgent = userAgent[:255] + if u.CreatedUnix == 0 { + // Caller expects auto-time for creation & update timestamps. + err = db.Insert(ctx, u) + } else { + // Caller sets the timestamps themselves. They are responsible for ensuring + // both `CreatedUnix` and `UpdatedUnix` are set appropriately. + _, err = db.GetEngine(ctx).NoAutoTime().Insert(u) } - if err = SetUserSetting(ctx, u.ID, SignupUserAgent, userAgent); err != nil { + if err != nil { return err } - } - // insert email address - if err := db.Insert(ctx, &EmailAddress{ - UID: u.ID, - Email: u.Email, - LowerEmail: strings.ToLower(u.Email), - IsActivated: u.IsActive, - IsPrimary: true, - }); err != nil { - return err - } + if setting.RecordUserSignupMetadata { + // insert initial IP and UserAgent + if err = SetUserSetting(ctx, u.ID, SignupIP, meta.InitialIP); err != nil { + return err + } - return committer.Commit() + // trim user agent string to a reasonable length, if necessary + userAgent := strings.TrimSpace(meta.InitialUserAgent) + if len(userAgent) > 255 { + userAgent = userAgent[:255] + } + if err = SetUserSetting(ctx, u.ID, SignupUserAgent, userAgent); err != nil { + return err + } + } + + // insert email address + return db.Insert(ctx, &EmailAddress{ + UID: u.ID, + Email: u.Email, + LowerEmail: strings.ToLower(u.Email), + IsActivated: u.IsActive, + IsPrimary: true, + }) + }) } // ErrDeleteLastAdminUser represents a "DeleteLastAdminUser" kind of error. @@ -955,6 +948,16 @@ func UpdateUserCols(ctx context.Context, u *User, cols ...string) error { return err } +// UpdateUserColsNoAutoTime update user according special columns +func UpdateUserColsNoAutoTime(ctx context.Context, u *User, cols ...string) error { + if err := ValidateUser(u, cols...); err != nil { + return err + } + + _, err := db.GetEngine(ctx).ID(u.ID).Cols(cols...).NoAutoTime().Update(u) + return err +} + // GetInactiveUsers gets all inactive users func GetInactiveUsers(ctx context.Context, olderThan time.Duration) ([]*User, error) { cond := builder.And( diff --git a/models/user/user_system_test.go b/models/user/user_system_test.go index 97768b509b..5aa3fa463c 100644 --- a/models/user/user_system_test.go +++ b/models/user/user_system_test.go @@ -6,27 +6,25 @@ package user import ( "testing" - "code.gitea.io/gitea/models/db" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestSystemUser(t *testing.T) { - u, err := GetPossibleUserByID(db.DefaultContext, -1) + u, err := GetPossibleUserByID(t.Context(), -1) require.NoError(t, err) assert.Equal(t, "Ghost", u.Name) assert.Equal(t, "ghost", u.LowerName) assert.True(t, u.IsGhost()) assert.True(t, IsGhostUserName("gHost")) - u, err = GetPossibleUserByID(db.DefaultContext, -2) + u, err = GetPossibleUserByID(t.Context(), -2) require.NoError(t, err) assert.Equal(t, "gitea-actions", u.Name) assert.Equal(t, "gitea-actions", u.LowerName) assert.True(t, u.IsGiteaActions()) assert.True(t, IsGiteaActionsUserName("Gitea-actionS")) - _, err = GetPossibleUserByID(db.DefaultContext, -3) + _, err = GetPossibleUserByID(t.Context(), -3) require.Error(t, err) } diff --git a/models/user/user_test.go b/models/user/user_test.go index 7944fc4b73..4201ec4816 100644 --- a/models/user/user_test.go +++ b/models/user/user_test.go @@ -44,7 +44,7 @@ func TestIsUsableUsername(t *testing.T) { func TestOAuth2Application_LoadUser(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) app := unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{ID: 1}) - user, err := user_model.GetUserByID(db.DefaultContext, app.UID) + user, err := user_model.GetUserByID(t.Context(), app.UID) assert.NoError(t, err) assert.NotNil(t, user) } @@ -53,14 +53,14 @@ func TestUserEmails(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) t.Run("GetUserEmailsByNames", func(t *testing.T) { // ignore none active user email - assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "user9"})) - assert.ElementsMatch(t, []string{"user8@example.com", "user5@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "user5"})) - assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "org7"})) + assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(t.Context(), []string{"user8", "user9"})) + assert.ElementsMatch(t, []string{"user8@example.com", "user5@example.com"}, user_model.GetUserEmailsByNames(t.Context(), []string{"user8", "user5"})) + assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(t.Context(), []string{"user8", "org7"})) }) t.Run("GetUsersByEmails", func(t *testing.T) { defer test.MockVariableValue(&setting.Service.NoReplyAddress, "NoReply.gitea.internal")() testGetUserByEmail := func(t *testing.T, email string, uid int64) { - m, err := user_model.GetUsersByEmails(db.DefaultContext, []string{email}) + m, err := user_model.GetUsersByEmails(t.Context(), []string{email}) require.NoError(t, err) user := m.GetByEmail(email) if uid == 0 { @@ -114,7 +114,7 @@ func TestCanCreateOrganization(t *testing.T) { func TestSearchUsers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(opts user_model.SearchUserOptions, expectedUserOrOrgIDs []int64) { - users, _, err := user_model.SearchUsers(db.DefaultContext, opts) + users, _, err := user_model.SearchUsers(t.Context(), opts) assert.NoError(t, err) cassText := fmt.Sprintf("ids: %v, opts: %v", expectedUserOrOrgIDs, opts) if assert.Len(t, users, len(expectedUserOrOrgIDs), "case: %s", cassText) { @@ -243,7 +243,7 @@ func BenchmarkHashPassword(b *testing.B) { func TestNewGitSig(t *testing.T) { users := make([]*user_model.User, 0, 20) - err := db.GetEngine(db.DefaultContext).Find(&users) + err := db.GetEngine(t.Context()).Find(&users) assert.NoError(t, err) for _, user := range users { @@ -257,7 +257,7 @@ func TestNewGitSig(t *testing.T) { func TestDisplayName(t *testing.T) { users := make([]*user_model.User, 0, 20) - err := db.GetEngine(db.DefaultContext).Find(&users) + err := db.GetEngine(t.Context()).Find(&users) assert.NoError(t, err) for _, user := range users { @@ -280,7 +280,7 @@ func TestCreateUserInvalidEmail(t *testing.T) { MustChangePassword: false, } - err := user_model.CreateUser(db.DefaultContext, user, &user_model.Meta{}) + err := user_model.CreateUser(t.Context(), user, &user_model.Meta{}) assert.Error(t, err) assert.True(t, user_model.IsErrEmailCharIsNotSupported(err)) } @@ -294,7 +294,7 @@ func TestCreateUserEmailAlreadyUsed(t *testing.T) { user.Name = "testuser" user.LowerName = strings.ToLower(user.Name) user.ID = 0 - err := user_model.CreateUser(db.DefaultContext, user, &user_model.Meta{}) + err := user_model.CreateUser(t.Context(), user, &user_model.Meta{}) assert.Error(t, err) assert.True(t, user_model.IsErrEmailAlreadyUsed(err)) } @@ -311,7 +311,7 @@ func TestCreateUserCustomTimestamps(t *testing.T) { user.ID = 0 user.Email = "unique@example.com" user.CreatedUnix = creationTimestamp - err := user_model.CreateUser(db.DefaultContext, user, &user_model.Meta{}) + err := user_model.CreateUser(t.Context(), user, &user_model.Meta{}) assert.NoError(t, err) fetched, err := user_model.GetUserByID(t.Context(), user.ID) @@ -336,7 +336,7 @@ func TestCreateUserWithoutCustomTimestamps(t *testing.T) { user.Email = "unique@example.com" user.CreatedUnix = 0 user.UpdatedUnix = 0 - err := user_model.CreateUser(db.DefaultContext, user, &user_model.Meta{}) + err := user_model.CreateUser(t.Context(), user, &user_model.Meta{}) assert.NoError(t, err) timestampEnd := time.Now().Unix() @@ -355,12 +355,12 @@ func TestGetUserIDsByNames(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // ignore non existing - IDs, err := user_model.GetUserIDsByNames(db.DefaultContext, []string{"user1", "user2", "none_existing_user"}, true) + IDs, err := user_model.GetUserIDsByNames(t.Context(), []string{"user1", "user2", "none_existing_user"}, true) assert.NoError(t, err) assert.Equal(t, []int64{1, 2}, IDs) // ignore non existing - IDs, err = user_model.GetUserIDsByNames(db.DefaultContext, []string{"user1", "do_not_exist"}, false) + IDs, err = user_model.GetUserIDsByNames(t.Context(), []string{"user1", "do_not_exist"}, false) assert.Error(t, err) assert.Equal(t, []int64(nil), IDs) } @@ -368,14 +368,14 @@ func TestGetUserIDsByNames(t *testing.T) { func TestGetMaileableUsersByIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - results, err := user_model.GetMailableUsersByIDs(db.DefaultContext, []int64{1, 4}, false) + results, err := user_model.GetMailableUsersByIDs(t.Context(), []int64{1, 4}, false) assert.NoError(t, err) assert.Len(t, results, 1) if len(results) > 1 { assert.Equal(t, 1, results[0].ID) } - results, err = user_model.GetMailableUsersByIDs(db.DefaultContext, []int64{1, 4}, true) + results, err = user_model.GetMailableUsersByIDs(t.Context(), []int64{1, 4}, true) assert.NoError(t, err) assert.Len(t, results, 2) if len(results) > 2 { @@ -389,7 +389,7 @@ func TestNewUserRedirect(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "newusername")) + assert.NoError(t, user_model.NewUserRedirect(t.Context(), user.ID, user.Name, "newusername")) unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{ LowerName: user.LowerName, @@ -406,7 +406,7 @@ func TestNewUserRedirect2(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "olduser1")) + assert.NoError(t, user_model.NewUserRedirect(t.Context(), user.ID, user.Name, "olduser1")) unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{ LowerName: user.LowerName, @@ -423,7 +423,7 @@ func TestNewUserRedirect3(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "newusername")) + assert.NoError(t, user_model.NewUserRedirect(t.Context(), user.ID, user.Name, "newusername")) unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{ LowerName: user.LowerName, @@ -434,17 +434,17 @@ func TestNewUserRedirect3(t *testing.T) { func TestGetUserByOpenID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - _, err := user_model.GetUserByOpenID(db.DefaultContext, "https://unknown") + _, err := user_model.GetUserByOpenID(t.Context(), "https://unknown") if assert.Error(t, err) { assert.True(t, user_model.IsErrUserNotExist(err)) } - user, err := user_model.GetUserByOpenID(db.DefaultContext, "https://user1.domain1.tld") + user, err := user_model.GetUserByOpenID(t.Context(), "https://user1.domain1.tld") if assert.NoError(t, err) { assert.Equal(t, int64(1), user.ID) } - user, err = user_model.GetUserByOpenID(db.DefaultContext, "https://domain1.tld/user2/") + user, err = user_model.GetUserByOpenID(t.Context(), "https://domain1.tld/user2/") if assert.NoError(t, err) { assert.Equal(t, int64(2), user.ID) } @@ -454,7 +454,7 @@ func TestFollowUser(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(follower, followed *user_model.User) { - assert.NoError(t, user_model.FollowUser(db.DefaultContext, follower, followed)) + assert.NoError(t, user_model.FollowUser(t.Context(), follower, followed)) unittest.AssertExistsAndLoadBean(t, &user_model.Follow{UserID: follower.ID, FollowID: followed.ID}) } @@ -465,7 +465,7 @@ func TestFollowUser(t *testing.T) { testSuccess(user4, user2) testSuccess(user5, user2) - assert.NoError(t, user_model.FollowUser(db.DefaultContext, user2, user2)) + assert.NoError(t, user_model.FollowUser(t.Context(), user2, user2)) unittest.CheckConsistencyFor(t, &user_model.User{}) } @@ -474,7 +474,7 @@ func TestUnfollowUser(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(followerID, followedID int64) { - assert.NoError(t, user_model.UnfollowUser(db.DefaultContext, followerID, followedID)) + assert.NoError(t, user_model.UnfollowUser(t.Context(), followerID, followedID)) unittest.AssertNotExistsBean(t, &user_model.Follow{UserID: followerID, FollowID: followedID}) } testSuccess(4, 2) @@ -501,7 +501,7 @@ func TestIsUserVisibleToViewer(t *testing.T) { } return u.Name } - assert.Equal(t, expected, user_model.IsUserVisibleToViewer(db.DefaultContext, u, viewer), "user %v should be visible to viewer %v: %v", name(u), name(viewer), expected) + assert.Equal(t, expected, user_model.IsUserVisibleToViewer(t.Context(), u, viewer), "user %v should be visible to viewer %v: %v", name(u), name(viewer), expected) } // admin viewer @@ -636,11 +636,11 @@ func TestGetInactiveUsers(t *testing.T) { // all inactive users // user1's createdunix is 1730468968 - users, err := user_model.GetInactiveUsers(db.DefaultContext, 0) + users, err := user_model.GetInactiveUsers(t.Context(), 0) assert.NoError(t, err) assert.Len(t, users, 1) interval := time.Now().Unix() - 1730468968 + 3600*24 - users, err = user_model.GetInactiveUsers(db.DefaultContext, time.Duration(interval*int64(time.Second))) + users, err = user_model.GetInactiveUsers(t.Context(), time.Duration(interval*int64(time.Second))) assert.NoError(t, err) assert.Empty(t, users) } diff --git a/models/webhook/webhook_system_test.go b/models/webhook/webhook_system_test.go index 96157ed9c9..8aac693995 100644 --- a/models/webhook/webhook_system_test.go +++ b/models/webhook/webhook_system_test.go @@ -6,7 +6,6 @@ package webhook import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/optional" @@ -16,20 +15,20 @@ import ( func TestGetSystemOrDefaultWebhooks(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - hooks, err := GetSystemOrDefaultWebhooks(db.DefaultContext, optional.None[bool]()) + hooks, err := GetSystemOrDefaultWebhooks(t.Context(), optional.None[bool]()) assert.NoError(t, err) if assert.Len(t, hooks, 2) { assert.Equal(t, int64(5), hooks[0].ID) assert.Equal(t, int64(6), hooks[1].ID) } - hooks, err = GetSystemOrDefaultWebhooks(db.DefaultContext, optional.Some(true)) + hooks, err = GetSystemOrDefaultWebhooks(t.Context(), optional.Some(true)) assert.NoError(t, err) if assert.Len(t, hooks, 1) { assert.Equal(t, int64(5), hooks[0].ID) } - hooks, err = GetSystemOrDefaultWebhooks(db.DefaultContext, optional.Some(false)) + hooks, err = GetSystemOrDefaultWebhooks(t.Context(), optional.Some(false)) assert.NoError(t, err) if assert.Len(t, hooks, 1) { assert.Equal(t, int64(6), hooks[0].ID) diff --git a/models/webhook/webhook_test.go b/models/webhook/webhook_test.go index edad8fc996..71f50017c5 100644 --- a/models/webhook/webhook_test.go +++ b/models/webhook/webhook_test.go @@ -31,7 +31,7 @@ func TestIsValidHookContentType(t *testing.T) { func TestWebhook_History(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) webhook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 1}) - tasks, err := webhook.History(db.DefaultContext, 0) + tasks, err := webhook.History(t.Context(), 0) assert.NoError(t, err) if assert.Len(t, tasks, 3) { assert.Equal(t, int64(3), tasks[0].ID) @@ -40,7 +40,7 @@ func TestWebhook_History(t *testing.T) { } webhook = unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2}) - tasks, err = webhook.History(db.DefaultContext, 0) + tasks, err = webhook.History(t.Context(), 0) assert.NoError(t, err) assert.Empty(t, tasks) } @@ -95,35 +95,35 @@ func TestCreateWebhook(t *testing.T) { Events: `{"push_only":false,"send_everything":false,"choose_events":false,"events":{"create":false,"push":true,"pull_request":true}}`, } unittest.AssertNotExistsBean(t, hook) - assert.NoError(t, CreateWebhook(db.DefaultContext, hook)) + assert.NoError(t, CreateWebhook(t.Context(), hook)) unittest.AssertExistsAndLoadBean(t, hook) } func TestGetWebhookByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - hook, err := GetWebhookByRepoID(db.DefaultContext, 1, 1) + hook, err := GetWebhookByRepoID(t.Context(), 1, 1) assert.NoError(t, err) assert.Equal(t, int64(1), hook.ID) - _, err = GetWebhookByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) + _, err = GetWebhookByRepoID(t.Context(), unittest.NonexistentID, unittest.NonexistentID) assert.Error(t, err) assert.True(t, IsErrWebhookNotExist(err)) } func TestGetWebhookByOwnerID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - hook, err := GetWebhookByOwnerID(db.DefaultContext, 3, 3) + hook, err := GetWebhookByOwnerID(t.Context(), 3, 3) assert.NoError(t, err) assert.Equal(t, int64(3), hook.ID) - _, err = GetWebhookByOwnerID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) + _, err = GetWebhookByOwnerID(t.Context(), unittest.NonexistentID, unittest.NonexistentID) assert.Error(t, err) assert.True(t, IsErrWebhookNotExist(err)) } func TestGetActiveWebhooksByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - hooks, err := db.Find[Webhook](db.DefaultContext, ListWebhookOptions{RepoID: 1, IsActive: optional.Some(true)}) + hooks, err := db.Find[Webhook](t.Context(), ListWebhookOptions{RepoID: 1, IsActive: optional.Some(true)}) assert.NoError(t, err) if assert.Len(t, hooks, 1) { assert.Equal(t, int64(1), hooks[0].ID) @@ -133,7 +133,7 @@ func TestGetActiveWebhooksByRepoID(t *testing.T) { func TestGetWebhooksByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - hooks, err := db.Find[Webhook](db.DefaultContext, ListWebhookOptions{RepoID: 1}) + hooks, err := db.Find[Webhook](t.Context(), ListWebhookOptions{RepoID: 1}) assert.NoError(t, err) if assert.Len(t, hooks, 2) { assert.Equal(t, int64(1), hooks[0].ID) @@ -143,7 +143,7 @@ func TestGetWebhooksByRepoID(t *testing.T) { func TestGetActiveWebhooksByOwnerID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - hooks, err := db.Find[Webhook](db.DefaultContext, ListWebhookOptions{OwnerID: 3, IsActive: optional.Some(true)}) + hooks, err := db.Find[Webhook](t.Context(), ListWebhookOptions{OwnerID: 3, IsActive: optional.Some(true)}) assert.NoError(t, err) if assert.Len(t, hooks, 1) { assert.Equal(t, int64(3), hooks[0].ID) @@ -153,7 +153,7 @@ func TestGetActiveWebhooksByOwnerID(t *testing.T) { func TestGetWebhooksByOwnerID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - hooks, err := db.Find[Webhook](db.DefaultContext, ListWebhookOptions{OwnerID: 3}) + hooks, err := db.Find[Webhook](t.Context(), ListWebhookOptions{OwnerID: 3}) assert.NoError(t, err) if assert.Len(t, hooks, 1) { assert.Equal(t, int64(3), hooks[0].ID) @@ -167,17 +167,17 @@ func TestUpdateWebhook(t *testing.T) { hook.IsActive = true hook.ContentType = ContentTypeForm unittest.AssertNotExistsBean(t, hook) - assert.NoError(t, UpdateWebhook(db.DefaultContext, hook)) + assert.NoError(t, UpdateWebhook(t.Context(), hook)) unittest.AssertExistsAndLoadBean(t, hook) } func TestDeleteWebhookByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2, RepoID: 1}) - assert.NoError(t, DeleteWebhookByRepoID(db.DefaultContext, 1, 2)) + assert.NoError(t, DeleteWebhookByRepoID(t.Context(), 1, 2)) unittest.AssertNotExistsBean(t, &Webhook{ID: 2, RepoID: 1}) - err := DeleteWebhookByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) + err := DeleteWebhookByRepoID(t.Context(), unittest.NonexistentID, unittest.NonexistentID) assert.Error(t, err) assert.True(t, IsErrWebhookNotExist(err)) } @@ -185,17 +185,17 @@ func TestDeleteWebhookByRepoID(t *testing.T) { func TestDeleteWebhookByOwnerID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 3, OwnerID: 3}) - assert.NoError(t, DeleteWebhookByOwnerID(db.DefaultContext, 3, 3)) + assert.NoError(t, DeleteWebhookByOwnerID(t.Context(), 3, 3)) unittest.AssertNotExistsBean(t, &Webhook{ID: 3, OwnerID: 3}) - err := DeleteWebhookByOwnerID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) + err := DeleteWebhookByOwnerID(t.Context(), unittest.NonexistentID, unittest.NonexistentID) assert.Error(t, err) assert.True(t, IsErrWebhookNotExist(err)) } func TestHookTasks(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - hookTasks, err := HookTasks(db.DefaultContext, 1, 1) + hookTasks, err := HookTasks(t.Context(), 1, 1) assert.NoError(t, err) if assert.Len(t, hookTasks, 3) { assert.Equal(t, int64(3), hookTasks[0].ID) @@ -203,7 +203,7 @@ func TestHookTasks(t *testing.T) { assert.Equal(t, int64(1), hookTasks[2].ID) } - hookTasks, err = HookTasks(db.DefaultContext, unittest.NonexistentID, 1) + hookTasks, err = HookTasks(t.Context(), unittest.NonexistentID, 1) assert.NoError(t, err) assert.Empty(t, hookTasks) } @@ -215,7 +215,7 @@ func TestCreateHookTask(t *testing.T) { PayloadVersion: 2, } unittest.AssertNotExistsBean(t, hookTask) - _, err := CreateHookTask(db.DefaultContext, hookTask) + _, err := CreateHookTask(t.Context(), hookTask) assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, hookTask) } @@ -227,7 +227,7 @@ func TestUpdateHookTask(t *testing.T) { hook.PayloadContent = "new payload content" hook.IsDelivered = true unittest.AssertNotExistsBean(t, hook) - assert.NoError(t, UpdateHookTask(db.DefaultContext, hook)) + assert.NoError(t, UpdateHookTask(t.Context(), hook)) unittest.AssertExistsAndLoadBean(t, hook) } @@ -240,7 +240,7 @@ func TestCleanupHookTaskTable_PerWebhook_DeletesDelivered(t *testing.T) { PayloadVersion: 2, } unittest.AssertNotExistsBean(t, hookTask) - _, err := CreateHookTask(db.DefaultContext, hookTask) + _, err := CreateHookTask(t.Context(), hookTask) assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, hookTask) @@ -256,7 +256,7 @@ func TestCleanupHookTaskTable_PerWebhook_LeavesUndelivered(t *testing.T) { PayloadVersion: 2, } unittest.AssertNotExistsBean(t, hookTask) - _, err := CreateHookTask(db.DefaultContext, hookTask) + _, err := CreateHookTask(t.Context(), hookTask) assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, hookTask) @@ -273,7 +273,7 @@ func TestCleanupHookTaskTable_PerWebhook_LeavesMostRecentTask(t *testing.T) { PayloadVersion: 2, } unittest.AssertNotExistsBean(t, hookTask) - _, err := CreateHookTask(db.DefaultContext, hookTask) + _, err := CreateHookTask(t.Context(), hookTask) assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, hookTask) @@ -290,7 +290,7 @@ func TestCleanupHookTaskTable_OlderThan_DeletesDelivered(t *testing.T) { PayloadVersion: 2, } unittest.AssertNotExistsBean(t, hookTask) - _, err := CreateHookTask(db.DefaultContext, hookTask) + _, err := CreateHookTask(t.Context(), hookTask) assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, hookTask) @@ -306,7 +306,7 @@ func TestCleanupHookTaskTable_OlderThan_LeavesUndelivered(t *testing.T) { PayloadVersion: 2, } unittest.AssertNotExistsBean(t, hookTask) - _, err := CreateHookTask(db.DefaultContext, hookTask) + _, err := CreateHookTask(t.Context(), hookTask) assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, hookTask) @@ -323,7 +323,7 @@ func TestCleanupHookTaskTable_OlderThan_LeavesTaskEarlierThanAgeToDelete(t *test PayloadVersion: 2, } unittest.AssertNotExistsBean(t, hookTask) - _, err := CreateHookTask(db.DefaultContext, hookTask) + _, err := CreateHookTask(t.Context(), hookTask) assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, hookTask) diff --git a/modules/activitypub/client_test.go b/modules/activitypub/client_test.go index d0c4845445..361270a800 100644 --- a/modules/activitypub/client_test.go +++ b/modules/activitypub/client_test.go @@ -10,7 +10,6 @@ import ( "net/http/httptest" "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" @@ -22,7 +21,7 @@ func TestActivityPubSignedPost(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) pubID := "https://example.com/pubID" - c, err := NewClient(db.DefaultContext, user, pubID) + c, err := NewClient(t.Context(), user, pubID) assert.NoError(t, err) expected := "BODY" diff --git a/modules/activitypub/user_settings_test.go b/modules/activitypub/user_settings_test.go index 55862357f1..105d4aedea 100644 --- a/modules/activitypub/user_settings_test.go +++ b/modules/activitypub/user_settings_test.go @@ -6,7 +6,6 @@ package activitypub import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -18,12 +17,12 @@ import ( func TestUserSettings(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - pub, priv, err := GetKeyPair(db.DefaultContext, user1) + pub, priv, err := GetKeyPair(t.Context(), user1) assert.NoError(t, err) - pub1, err := GetPublicKey(db.DefaultContext, user1) + pub1, err := GetPublicKey(t.Context(), user1) assert.NoError(t, err) assert.Equal(t, pub, pub1) - priv1, err := GetPrivateKey(db.DefaultContext, user1) + priv1, err := GetPrivateKey(t.Context(), user1) assert.NoError(t, err) assert.Equal(t, priv, priv1) } diff --git a/modules/csv/csv.go b/modules/csv/csv.go index f1ca3b0923..ad61b81d69 100644 --- a/modules/csv/csv.go +++ b/modules/csv/csv.go @@ -30,6 +30,8 @@ func CreateReader(input io.Reader, delimiter rune) *stdcsv.Reader { // thus would change `\t\t` to just `\t` or ` ` (two spaces) to just ` ` (single space) rd.TrimLeadingSpace = true } + // Don't force validation of every row to have the same number of entries as the first row. + rd.FieldsPerRecord = -1 return rd } diff --git a/modules/csv/csv_test.go b/modules/csv/csv_test.go index be9fc5f823..5ea9718466 100644 --- a/modules/csv/csv_test.go +++ b/modules/csv/csv_test.go @@ -94,6 +94,24 @@ j, ,\x20 }, expectedDelimiter: ',', }, + // case 3 - every delimiter used, default to comma and handle differing number of fields per record + { + csv: `col1,col2 +a;b +c@e +f g +h|i +jkl`, + expectedRows: [][]string{ + {"col1", "col2"}, + {"a;b"}, + {"c@e"}, + {"f g"}, + {"h|i"}, + {"jkl"}, + }, + expectedDelimiter: ',', + }, } for n, c := range cases { @@ -119,21 +137,6 @@ func TestDetermineDelimiterShortBufferError(t *testing.T) { assert.Nil(t, rd, "CSV reader should be mnil") } -func TestDetermineDelimiterReadAllError(t *testing.T) { - rd, err := CreateReaderAndDetermineDelimiter(nil, strings.NewReader(`col1,col2 - a;b - c@e - f g - h|i - jkl`)) - assert.NoError(t, err, "CreateReaderAndDetermineDelimiter() shouldn't throw error") - assert.NotNil(t, rd, "CSV reader should not be mnil") - rows, err := rd.ReadAll() - assert.Error(t, err, "RaadAll() should throw error") - assert.ErrorIs(t, err, csv.ErrFieldCount) - assert.Empty(t, rows, "rows should be empty") -} - func TestDetermineDelimiter(t *testing.T) { cases := []struct { csv string diff --git a/modules/dump/dumper.go b/modules/dump/dumper.go index 47730851fb..02829d6a1e 100644 --- a/modules/dump/dumper.go +++ b/modules/dump/dumper.go @@ -4,8 +4,11 @@ package dump import ( + "context" + "errors" "fmt" "io" + "io/fs" "os" "path" "path/filepath" @@ -16,7 +19,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" - "github.com/mholt/archiver/v3" + "github.com/mholt/archives" ) var SupportedOutputTypes = []string{"zip", "tar", "tar.sz", "tar.gz", "tar.xz", "tar.bz2", "tar.br", "tar.lz4", "tar.zst"} @@ -60,37 +63,122 @@ func IsSubdir(upper, lower string) (bool, error) { } type Dumper struct { - Writer archiver.Writer Verbose bool + jobs chan archives.ArchiveAsyncJob + errArchiveAsync chan error + errArchiveJob chan error + globalExcludeAbsPaths []string } -func (dumper *Dumper) AddReader(r io.ReadCloser, info os.FileInfo, customName string) error { - if dumper.Verbose { - log.Info("Adding file %s", customName) +func NewDumper(ctx context.Context, format string, output io.Writer) (*Dumper, error) { + d := &Dumper{ + jobs: make(chan archives.ArchiveAsyncJob, 1), + errArchiveAsync: make(chan error, 1), + errArchiveJob: make(chan error, 1), } - return dumper.Writer.Write(archiver.File{ - FileInfo: archiver.FileInfo{ - FileInfo: info, - CustomName: customName, - }, - ReadCloser: r, + // TODO: in the future, we could completely drop the "mholt/archives" dependency. + // Then we only need to support "zip" and ".tar.gz" natively, and let users provide custom command line tools + // like "zstd" or "xz" with compression-level arguments. + var comp archives.ArchiverAsync + switch format { + case "zip": + comp = archives.Zip{} + case "tar": + comp = archives.Tar{} + case "tar.sz": + comp = archives.CompressedArchive{Compression: archives.Sz{}, Archival: archives.Tar{}} + case "tar.gz": + comp = archives.CompressedArchive{Compression: archives.Gz{}, Archival: archives.Tar{}} + case "tar.xz": + comp = archives.CompressedArchive{Compression: archives.Xz{}, Archival: archives.Tar{}} + case "tar.bz2": + comp = archives.CompressedArchive{Compression: archives.Bz2{}, Archival: archives.Tar{}} + case "tar.br": + comp = archives.CompressedArchive{Compression: archives.Brotli{}, Archival: archives.Tar{}} + case "tar.lz4": + comp = archives.CompressedArchive{Compression: archives.Lz4{}, Archival: archives.Tar{}} + case "tar.zst": + comp = archives.CompressedArchive{Compression: archives.Zstd{}, Archival: archives.Tar{}} + default: + return nil, fmt.Errorf("unsupported format: %s", format) + } + go func() { + d.errArchiveAsync <- comp.ArchiveAsync(ctx, output, d.jobs) + close(d.errArchiveAsync) + }() + return d, nil +} + +func (dumper *Dumper) runArchiveJob(job archives.ArchiveAsyncJob) error { + dumper.jobs <- job + select { + case err := <-dumper.errArchiveAsync: + if err == nil { + return errors.New("archiver has been closed") + } + return err + case err := <-dumper.errArchiveJob: + return err + } +} + +// AddFileByPath adds a file by its filesystem path +func (dumper *Dumper) AddFileByPath(filePath, absPath string) error { + if dumper.Verbose { + log.Info("Adding local file %s", filePath) + } + + fileInfo, err := os.Stat(absPath) + if err != nil { + return err + } + + archiveFileInfo := archives.FileInfo{ + FileInfo: fileInfo, + NameInArchive: filePath, + Open: func() (fs.File, error) { return os.Open(absPath) }, + } + + return dumper.runArchiveJob(archives.ArchiveAsyncJob{ + File: archiveFileInfo, + Result: dumper.errArchiveJob, }) } -func (dumper *Dumper) AddFile(filePath, absPath string) error { - file, err := os.Open(absPath) - if err != nil { - return err +type readerFile struct { + r io.Reader + info os.FileInfo +} + +var _ fs.File = (*readerFile)(nil) + +func (f *readerFile) Stat() (fs.FileInfo, error) { return f.info, nil } +func (f *readerFile) Read(bytes []byte) (int, error) { return f.r.Read(bytes) } +func (f *readerFile) Close() error { return nil } + +// AddFileByReader adds a file's contents from a Reader +func (dumper *Dumper) AddFileByReader(r io.Reader, info os.FileInfo, customName string) error { + if dumper.Verbose { + log.Info("Adding storage file %s", customName) } - defer file.Close() - fileInfo, err := file.Stat() - if err != nil { - return err + + fileInfo := archives.FileInfo{ + FileInfo: info, + NameInArchive: customName, + Open: func() (fs.File, error) { return &readerFile{r, info}, nil }, } - return dumper.AddReader(file, fileInfo, filePath) + return dumper.runArchiveJob(archives.ArchiveAsyncJob{ + File: fileInfo, + Result: dumper.errArchiveJob, + }) +} + +func (dumper *Dumper) Close() error { + close(dumper.jobs) + return <-dumper.errArchiveAsync } func (dumper *Dumper) normalizeFilePath(absPath string) string { @@ -143,7 +231,7 @@ func (dumper *Dumper) addFileOrDir(insidePath, absPath string, excludes []string currentInsidePath := path.Join(insidePath, file.Name()) if file.IsDir() { - if err := dumper.AddFile(currentInsidePath, currentAbsPath); err != nil { + if err := dumper.AddFileByPath(currentInsidePath, currentAbsPath); err != nil { return err } if err = dumper.addFileOrDir(currentInsidePath, currentAbsPath, excludes); err != nil { @@ -164,7 +252,7 @@ func (dumper *Dumper) addFileOrDir(insidePath, absPath string, excludes []string shouldAdd = targetStat.Mode().IsRegular() } if shouldAdd { - if err = dumper.AddFile(currentInsidePath, currentAbsPath); err != nil { + if err = dumper.AddFileByPath(currentInsidePath, currentAbsPath); err != nil { return err } } diff --git a/modules/dump/dumper_test.go b/modules/dump/dumper_test.go index 8f06c1851d..f6b79c072a 100644 --- a/modules/dump/dumper_test.go +++ b/modules/dump/dumper_test.go @@ -4,6 +4,8 @@ package dump import ( + "archive/tar" + "bytes" "fmt" "io" "os" @@ -14,8 +16,8 @@ import ( "code.gitea.io/gitea/modules/timeutil" - "github.com/mholt/archiver/v3" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestPrepareFileNameAndType(t *testing.T) { @@ -67,28 +69,26 @@ func TestIsSubDir(t *testing.T) { assert.False(t, isSub) } -type testWriter struct { - added []string -} +func TestDumperIntegration(t *testing.T) { + var buf bytes.Buffer + dumper, err := NewDumper(t.Context(), "zip", &buf) + require.NoError(t, err) -func (t *testWriter) Create(out io.Writer) error { - return nil -} + tmpDir := t.TempDir() + _ = os.WriteFile(filepath.Join(tmpDir, "test.txt"), nil, 0o644) + f, _ := os.Open(filepath.Join(tmpDir, "test.txt")) -func (t *testWriter) Write(f archiver.File) error { - t.added = append(t.added, f.Name()) - return nil -} + fi, _ := f.Stat() + err = dumper.AddFileByReader(f, fi, "test.txt") + require.NoError(t, err) -func (t *testWriter) Close() error { - return nil + err = dumper.Close() + require.NoError(t, err) + + assert.Positive(t, buf.Len()) } func TestDumper(t *testing.T) { - sortStrings := func(s []string) []string { - sort.Strings(s) - return s - } tmpDir := t.TempDir() _ = os.MkdirAll(filepath.Join(tmpDir, "include/exclude1"), 0o755) _ = os.MkdirAll(filepath.Join(tmpDir, "include/exclude2"), 0o755) @@ -98,16 +98,54 @@ func TestDumper(t *testing.T) { _ = os.WriteFile(filepath.Join(tmpDir, "include/exclude1/a-1"), nil, 0o644) _ = os.WriteFile(filepath.Join(tmpDir, "include/exclude2/a-2"), nil, 0o644) - tw := &testWriter{} - d := &Dumper{Writer: tw} - d.GlobalExcludeAbsPath(filepath.Join(tmpDir, "include/exclude1")) - err := d.AddRecursiveExclude("include", filepath.Join(tmpDir, "include"), []string{filepath.Join(tmpDir, "include/exclude2")}) - assert.NoError(t, err) - assert.Equal(t, sortStrings([]string{"include/a", "include/sub", "include/sub/b"}), sortStrings(tw.added)) + sortStrings := func(s []string) []string { + sort.Strings(s) + return s + } - tw = &testWriter{} - d = &Dumper{Writer: tw} - err = d.AddRecursiveExclude("include", filepath.Join(tmpDir, "include"), nil) - assert.NoError(t, err) - assert.Equal(t, sortStrings([]string{"include/exclude2", "include/exclude2/a-2", "include/a", "include/sub", "include/sub/b", "include/exclude1", "include/exclude1/a-1"}), sortStrings(tw.added)) + t.Run("IncludesWithExcludes", func(t *testing.T) { + var buf bytes.Buffer + dumper, err := NewDumper(t.Context(), "tar", &buf) + require.NoError(t, err) + dumper.GlobalExcludeAbsPath(filepath.Join(tmpDir, "include/exclude1")) + err = dumper.AddRecursiveExclude("include", filepath.Join(tmpDir, "include"), []string{filepath.Join(tmpDir, "include/exclude2")}) + require.NoError(t, err) + err = dumper.Close() + require.NoError(t, err) + + files := extractTarFileNames(t, &buf) + expected := []string{"include/a", "include/sub", "include/sub/b"} + assert.Equal(t, sortStrings(expected), sortStrings(files)) + }) + + t.Run("IncludesAll", func(t *testing.T) { + var buf bytes.Buffer + dumper, err := NewDumper(t.Context(), "tar", &buf) + require.NoError(t, err) + err = dumper.AddRecursiveExclude("include", filepath.Join(tmpDir, "include"), nil) + require.NoError(t, err) + err = dumper.Close() + require.NoError(t, err) + + files := extractTarFileNames(t, &buf) + expected := []string{ + "include/exclude2", "include/exclude2/a-2", + "include/a", "include/sub", "include/sub/b", + "include/exclude1", "include/exclude1/a-1", + } + assert.Equal(t, sortStrings(expected), sortStrings(files)) + }) +} + +func extractTarFileNames(t *testing.T, buf *bytes.Buffer) (fileNames []string) { + tr := tar.NewReader(buf) + for { + hdr, err := tr.Next() + if err == io.EOF { + break + } + require.NoError(t, err, "Error reading tar archive") + fileNames = append(fileNames, hdr.Name) + } + return fileNames } diff --git a/modules/git/attribute/main_test.go b/modules/git/attribute/main_test.go index df8241bfb0..1f1d80ec0a 100644 --- a/modules/git/attribute/main_test.go +++ b/modules/git/attribute/main_test.go @@ -4,7 +4,6 @@ package attribute import ( - "context" "fmt" "os" "testing" @@ -22,7 +21,7 @@ func testRun(m *testing.M) error { defer util.RemoveAll(gitHomePath) setting.Git.HomePath = gitHomePath - if err = git.InitFull(context.Background()); err != nil { + if err = git.InitFull(); err != nil { return fmt.Errorf("failed to call Init: %w", err) } diff --git a/modules/git/blame.go b/modules/git/blame.go index 659dec34a1..db10df129e 100644 --- a/modules/git/blame.go +++ b/modules/git/blame.go @@ -141,7 +141,7 @@ func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath } }() - cmd := NewCommandNoGlobals("blame", "--porcelain") + cmd := NewCommand("blame", "--porcelain") if DefaultFeatures().CheckVersionAtLeast("2.23") && !bypassBlameIgnore { ignoreRevsFileName, ignoreRevsFileCleanup, err = tryCreateBlameIgnoreRevsFile(commit) diff --git a/modules/git/blob_test.go b/modules/git/blob_test.go index f21e8d146d..4c86aa70ba 100644 --- a/modules/git/blob_test.go +++ b/modules/git/blob_test.go @@ -16,7 +16,7 @@ import ( func TestBlob_Data(t *testing.T) { output := "file2\n" bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - repo, err := openRepositoryWithDefaultContext(bareRepo1Path) + repo, err := OpenRepository(t.Context(), bareRepo1Path) require.NoError(t, err) defer repo.Close() @@ -36,7 +36,7 @@ func TestBlob_Data(t *testing.T) { func Benchmark_Blob_Data(b *testing.B) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - repo, err := openRepositoryWithDefaultContext(bareRepo1Path) + repo, err := OpenRepository(b.Context(), bareRepo1Path) if err != nil { b.Fatal(err) } diff --git a/modules/git/command.go b/modules/git/command.go index 90ee7d8daf..8753fa4ebd 100644 --- a/modules/git/command.go +++ b/modules/git/command.go @@ -29,25 +29,19 @@ import ( // In most cases, it shouldn't be used. Use AddXxx function instead type TrustedCmdArgs []internal.CmdArg -var ( - // globalCommandArgs global command args for external package setting - globalCommandArgs TrustedCmdArgs - - // defaultCommandExecutionTimeout default command execution timeout duration - defaultCommandExecutionTimeout = 360 * time.Second -) +// defaultCommandExecutionTimeout default command execution timeout duration +var defaultCommandExecutionTimeout = 360 * time.Second // DefaultLocale is the default LC_ALL to run git commands in. const DefaultLocale = "C" // Command represents a command with its subcommands or arguments. type Command struct { - prog string - args []string - globalArgsLength int - brokenArgs []string - cmd *exec.Cmd // for debug purpose only - configArgs []string + prog string + args []string + brokenArgs []string + cmd *exec.Cmd // for debug purpose only + configArgs []string } func logArgSanitize(arg string) string { @@ -72,10 +66,7 @@ func (c *Command) LogString() string { } a := make([]string, 0, len(c.args)+1) a = append(a, debugQuote(c.prog)) - if c.globalArgsLength > 0 { - a = append(a, "...global...") - } - for i := c.globalArgsLength; i < len(c.args); i++ { + for i := 0; i < len(c.args); i++ { a = append(a, debugQuote(logArgSanitize(c.args[i]))) } return strings.Join(a, " ") @@ -91,24 +82,6 @@ func (c *Command) ProcessState() string { // NewCommand creates and returns a new Git Command based on given command and arguments. // Each argument should be safe to be trusted. User-provided arguments should be passed to AddDynamicArguments instead. func NewCommand(args ...internal.CmdArg) *Command { - // Make an explicit copy of globalCommandArgs, otherwise append might overwrite it - cargs := make([]string, 0, len(globalCommandArgs)+len(args)) - for _, arg := range globalCommandArgs { - cargs = append(cargs, string(arg)) - } - for _, arg := range args { - cargs = append(cargs, string(arg)) - } - return &Command{ - prog: GitExecutable, - args: cargs, - globalArgsLength: len(globalCommandArgs), - } -} - -// NewCommandNoGlobals creates and returns a new Git Command based on given command and arguments only with the specified args and don't use global command args -// Each argument should be safe to be trusted. User-provided arguments should be passed to AddDynamicArguments instead. -func NewCommandNoGlobals(args ...internal.CmdArg) *Command { cargs := make([]string, 0, len(args)) for _, arg := range args { cargs = append(cargs, string(arg)) @@ -478,19 +451,3 @@ func (c *Command) runStdBytes(ctx context.Context, opts *RunOpts) (stdout, stder // even if there is no err, there could still be some stderr output return stdoutBuf.Bytes(), stderr, nil } - -// AllowLFSFiltersArgs return globalCommandArgs with lfs filter, it should only be used for tests -func AllowLFSFiltersArgs() TrustedCmdArgs { - // Now here we should explicitly allow lfs filters to run - filteredLFSGlobalArgs := make(TrustedCmdArgs, len(globalCommandArgs)) - j := 0 - for _, arg := range globalCommandArgs { - if strings.Contains(string(arg), "lfs") { - j-- - } else { - filteredLFSGlobalArgs[j] = arg - j++ - } - } - return filteredLFSGlobalArgs[:j] -} diff --git a/modules/git/command_test.go b/modules/git/command_test.go index eb112707e7..85976e289e 100644 --- a/modules/git/command_test.go +++ b/modules/git/command_test.go @@ -53,9 +53,9 @@ func TestGitArgument(t *testing.T) { } func TestCommandString(t *testing.T) { - cmd := NewCommandNoGlobals("a", "-m msg", "it's a test", `say "hello"`) + cmd := NewCommand("a", "-m msg", "it's a test", `say "hello"`) assert.Equal(t, cmd.prog+` a "-m msg" "it's a test" "say \"hello\""`, cmd.LogString()) - cmd = NewCommandNoGlobals("url: https://a:b@c/", "/root/dir-a/dir-b") + cmd = NewCommand("url: https://a:b@c/", "/root/dir-a/dir-b") assert.Equal(t, cmd.prog+` "url: https://sanitized-credential@c/" .../dir-a/dir-b`, cmd.LogString()) } diff --git a/modules/git/commit.go b/modules/git/commit.go index aae40c575b..0dc894d3ab 100644 --- a/modules/git/commit.go +++ b/modules/git/commit.go @@ -86,18 +86,13 @@ func (c *Commit) GetCommitByPath(relpath string) (*Commit, error) { } // AddChanges marks local changes to be ready for commit. -func AddChanges(repoPath string, all bool, files ...string) error { - return AddChangesWithArgs(repoPath, globalCommandArgs, all, files...) -} - -// AddChangesWithArgs marks local changes to be ready for commit. -func AddChangesWithArgs(repoPath string, globalArgs TrustedCmdArgs, all bool, files ...string) error { - cmd := NewCommandNoGlobals(globalArgs...).AddArguments("add") +func AddChanges(ctx context.Context, repoPath string, all bool, files ...string) error { + cmd := NewCommand().AddArguments("add") if all { cmd.AddArguments("--all") } cmd.AddDashesAndList(files...) - _, _, err := cmd.RunStdString(DefaultContext, &RunOpts{Dir: repoPath}) + _, _, err := cmd.RunStdString(ctx, &RunOpts{Dir: repoPath}) return err } @@ -110,16 +105,8 @@ type CommitChangesOptions struct { // CommitChanges commits local changes with given committer, author and message. // If author is nil, it will be the same as committer. -func CommitChanges(repoPath string, opts CommitChangesOptions) error { - cargs := make(TrustedCmdArgs, len(globalCommandArgs)) - copy(cargs, globalCommandArgs) - return CommitChangesWithArgs(repoPath, cargs, opts) -} - -// CommitChangesWithArgs commits local changes with given committer, author and message. -// If author is nil, it will be the same as committer. -func CommitChangesWithArgs(repoPath string, args TrustedCmdArgs, opts CommitChangesOptions) error { - cmd := NewCommandNoGlobals(args...) +func CommitChanges(ctx context.Context, repoPath string, opts CommitChangesOptions) error { + cmd := NewCommand() if opts.Committer != nil { cmd.AddOptionValues("-c", "user.name="+opts.Committer.Name) cmd.AddOptionValues("-c", "user.email="+opts.Committer.Email) @@ -134,7 +121,7 @@ func CommitChangesWithArgs(repoPath string, args TrustedCmdArgs, opts CommitChan } cmd.AddOptionFormat("--message=%s", opts.Message) - _, _, err := cmd.RunStdString(DefaultContext, &RunOpts{Dir: repoPath}) + _, _, err := cmd.RunStdString(ctx, &RunOpts{Dir: repoPath}) // No stderr but exit status 1 means nothing to commit. if err != nil && err.Error() == "exit status 1" { return nil diff --git a/modules/git/commit_info_test.go b/modules/git/commit_info_test.go index 078b6815d2..51e1551d2d 100644 --- a/modules/git/commit_info_test.go +++ b/modules/git/commit_info_test.go @@ -18,7 +18,7 @@ const ( func cloneRepo(tb testing.TB, url string) (string, error) { repoDir := tb.TempDir() - if err := Clone(DefaultContext, url, repoDir, CloneRepoOptions{ + if err := Clone(tb.Context(), url, repoDir, CloneRepoOptions{ Mirror: false, Bare: false, Quiet: true, @@ -104,7 +104,7 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) { func TestEntries_GetCommitsInfo(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path) assert.NoError(t, err) defer bareRepo1.Close() @@ -114,7 +114,7 @@ func TestEntries_GetCommitsInfo(t *testing.T) { if err != nil { assert.NoError(t, err) } - clonedRepo1, err := openRepositoryWithDefaultContext(clonedPath) + clonedRepo1, err := OpenRepository(t.Context(), clonedPath) if err != nil { assert.NoError(t, err) } @@ -163,7 +163,7 @@ func BenchmarkEntries_GetCommitsInfo(b *testing.B) { b.Fatal(err) } - if repo, err = openRepositoryWithDefaultContext(repoPath); err != nil { + if repo, err = OpenRepository(b.Context(), repoPath); err != nil { b.Fatal(err) } defer repo.Close() diff --git a/modules/git/commit_sha256_test.go b/modules/git/commit_sha256_test.go index 97ccecdacc..772f5eedb2 100644 --- a/modules/git/commit_sha256_test.go +++ b/modules/git/commit_sha256_test.go @@ -17,7 +17,7 @@ import ( func TestCommitsCountSha256(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256") - commitsCount, err := CommitsCount(DefaultContext, + commitsCount, err := CommitsCount(t.Context(), CommitsCountOptions{ RepoPath: bareRepo1Path, Revision: []string{"f004f41359117d319dedd0eaab8c5259ee2263da839dcba33637997458627fdc"}, @@ -30,7 +30,7 @@ func TestCommitsCountSha256(t *testing.T) { func TestCommitsCountWithoutBaseSha256(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256") - commitsCount, err := CommitsCount(DefaultContext, + commitsCount, err := CommitsCount(t.Context(), CommitsCountOptions{ RepoPath: bareRepo1Path, Not: "main", @@ -44,7 +44,7 @@ func TestCommitsCountWithoutBaseSha256(t *testing.T) { func TestGetFullCommitIDSha256(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256") - id, err := GetFullCommitID(DefaultContext, bareRepo1Path, "f004f4") + id, err := GetFullCommitID(t.Context(), bareRepo1Path, "f004f4") assert.NoError(t, err) assert.Equal(t, "f004f41359117d319dedd0eaab8c5259ee2263da839dcba33637997458627fdc", id) } @@ -52,7 +52,7 @@ func TestGetFullCommitIDSha256(t *testing.T) { func TestGetFullCommitIDErrorSha256(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256") - id, err := GetFullCommitID(DefaultContext, bareRepo1Path, "unknown") + id, err := GetFullCommitID(t.Context(), bareRepo1Path, "unknown") assert.Empty(t, id) if assert.Error(t, err) { assert.EqualError(t, err, "object does not exist [id: unknown, rel_path: ]") @@ -87,7 +87,7 @@ signed commit` 0x94, 0x33, 0xb2, 0xa6, 0x2b, 0x96, 0x4c, 0x17, 0xa4, 0x48, 0x5a, 0xe1, 0x80, 0xf4, 0x5f, 0x59, 0x5d, 0x3e, 0x69, 0xd3, 0x1b, 0x78, 0x60, 0x87, 0x77, 0x5e, 0x28, 0xc6, 0xb6, 0x39, 0x9d, 0xf0, } - gitRepo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare_sha256")) + gitRepo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo1_bare_sha256")) assert.NoError(t, err) assert.NotNil(t, gitRepo) defer gitRepo.Close() @@ -130,7 +130,7 @@ signed commit`, commitFromReader.Signature.Payload) func TestHasPreviousCommitSha256(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256") - repo, err := openRepositoryWithDefaultContext(bareRepo1Path) + repo, err := OpenRepository(t.Context(), bareRepo1Path) assert.NoError(t, err) defer repo.Close() @@ -161,7 +161,7 @@ func TestHasPreviousCommitSha256(t *testing.T) { func TestGetCommitFileStatusMergesSha256(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo6_merge_sha256") - commitFileStatus, err := GetCommitFileStatus(DefaultContext, bareRepo1Path, "d2e5609f630dd8db500f5298d05d16def282412e3e66ed68cc7d0833b29129a1") + commitFileStatus, err := GetCommitFileStatus(t.Context(), bareRepo1Path, "d2e5609f630dd8db500f5298d05d16def282412e3e66ed68cc7d0833b29129a1") assert.NoError(t, err) expected := CommitFileStatus{ @@ -186,7 +186,7 @@ func TestGetCommitFileStatusMergesSha256(t *testing.T) { []string{}, } - commitFileStatus, err = GetCommitFileStatus(DefaultContext, bareRepo1Path, "da1ded40dc8e5b7c564171f4bf2fc8370487decfb1cb6a99ef28f3ed73d09172") + commitFileStatus, err = GetCommitFileStatus(t.Context(), bareRepo1Path, "da1ded40dc8e5b7c564171f4bf2fc8370487decfb1cb6a99ef28f3ed73d09172") assert.NoError(t, err) assert.Equal(t, expected.Added, commitFileStatus.Added) diff --git a/modules/git/commit_test.go b/modules/git/commit_test.go index 81fb91dfc6..688b4e294f 100644 --- a/modules/git/commit_test.go +++ b/modules/git/commit_test.go @@ -16,7 +16,7 @@ import ( func TestCommitsCount(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - commitsCount, err := CommitsCount(DefaultContext, + commitsCount, err := CommitsCount(t.Context(), CommitsCountOptions{ RepoPath: bareRepo1Path, Revision: []string{"8006ff9adbf0cb94da7dad9e537e53817f9fa5c0"}, @@ -29,7 +29,7 @@ func TestCommitsCount(t *testing.T) { func TestCommitsCountWithoutBase(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - commitsCount, err := CommitsCount(DefaultContext, + commitsCount, err := CommitsCount(t.Context(), CommitsCountOptions{ RepoPath: bareRepo1Path, Not: "master", @@ -43,7 +43,7 @@ func TestCommitsCountWithoutBase(t *testing.T) { func TestGetFullCommitID(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - id, err := GetFullCommitID(DefaultContext, bareRepo1Path, "8006ff9a") + id, err := GetFullCommitID(t.Context(), bareRepo1Path, "8006ff9a") assert.NoError(t, err) assert.Equal(t, "8006ff9adbf0cb94da7dad9e537e53817f9fa5c0", id) } @@ -51,7 +51,7 @@ func TestGetFullCommitID(t *testing.T) { func TestGetFullCommitIDError(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - id, err := GetFullCommitID(DefaultContext, bareRepo1Path, "unknown") + id, err := GetFullCommitID(t.Context(), bareRepo1Path, "unknown") assert.Empty(t, id) if assert.Error(t, err) { assert.EqualError(t, err, "object does not exist [id: unknown, rel_path: ]") @@ -83,7 +83,7 @@ gpgsig -----BEGIN PGP SIGNATURE----- empty commit` sha := &Sha1Hash{0xfe, 0xaf, 0x4b, 0xa6, 0xbc, 0x63, 0x5f, 0xec, 0x44, 0x2f, 0x46, 0xdd, 0xd4, 0x51, 0x24, 0x16, 0xec, 0x43, 0xc2, 0xc2} - gitRepo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare")) + gitRepo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo1_bare")) assert.NoError(t, err) assert.NotNil(t, gitRepo) defer gitRepo.Close() @@ -147,7 +147,7 @@ gpgsig -----BEGIN PGP SIGNATURE----- ISO-8859-1` commitString = strings.ReplaceAll(commitString, "", " ") sha := &Sha1Hash{0xfe, 0xaf, 0x4b, 0xa6, 0xbc, 0x63, 0x5f, 0xec, 0x44, 0x2f, 0x46, 0xdd, 0xd4, 0x51, 0x24, 0x16, 0xec, 0x43, 0xc2, 0xc2} - gitRepo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare")) + gitRepo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo1_bare")) assert.NoError(t, err) assert.NotNil(t, gitRepo) defer gitRepo.Close() @@ -189,7 +189,7 @@ ISO-8859-1`, commitFromReader.Signature.Payload) func TestHasPreviousCommit(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - repo, err := openRepositoryWithDefaultContext(bareRepo1Path) + repo, err := OpenRepository(t.Context(), bareRepo1Path) assert.NoError(t, err) defer repo.Close() @@ -320,7 +320,7 @@ func TestParseCommitFileStatus(t *testing.T) { func TestGetCommitFileStatusMerges(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo6_merge") - commitFileStatus, err := GetCommitFileStatus(DefaultContext, bareRepo1Path, "022f4ce6214973e018f02bf363bf8a2e3691f699") + commitFileStatus, err := GetCommitFileStatus(t.Context(), bareRepo1Path, "022f4ce6214973e018f02bf363bf8a2e3691f699") assert.NoError(t, err) expected := CommitFileStatus{ diff --git a/modules/git/config.go b/modules/git/config.go index 234be7b955..3a717908b9 100644 --- a/modules/git/config.go +++ b/modules/git/config.go @@ -4,6 +4,7 @@ package git import ( + "context" "fmt" "os" "regexp" @@ -14,7 +15,7 @@ import ( ) // syncGitConfig only modifies gitconfig, won't change global variables (otherwise there will be data-race problem) -func syncGitConfig() (err error) { +func syncGitConfig(ctx context.Context) (err error) { if err = os.MkdirAll(HomeDir(), os.ModePerm); err != nil { return fmt.Errorf("unable to prepare git home directory %s, err: %w", HomeDir(), err) } @@ -22,7 +23,7 @@ func syncGitConfig() (err error) { // first, write user's git config options to git config file // user config options could be overwritten by builtin values later, because if a value is builtin, it must have some special purposes for k, v := range setting.GitConfig.Options { - if err = configSet(strings.ToLower(k), v); err != nil { + if err = configSet(ctx, strings.ToLower(k), v); err != nil { return err } } @@ -34,41 +35,41 @@ func syncGitConfig() (err error) { "user.name": "Gitea", "user.email": "gitea@fake.local", } { - if err := configSetNonExist(configKey, defaultValue); err != nil { + if err := configSetNonExist(ctx, configKey, defaultValue); err != nil { return err } } // Set git some configurations - these must be set to these values for gitea to work correctly - if err := configSet("core.quotePath", "false"); err != nil { + if err := configSet(ctx, "core.quotePath", "false"); err != nil { return err } if DefaultFeatures().CheckVersionAtLeast("2.10") { - if err := configSet("receive.advertisePushOptions", "true"); err != nil { + if err := configSet(ctx, "receive.advertisePushOptions", "true"); err != nil { return err } } if DefaultFeatures().CheckVersionAtLeast("2.18") { - if err := configSet("core.commitGraph", "true"); err != nil { + if err := configSet(ctx, "core.commitGraph", "true"); err != nil { return err } - if err := configSet("gc.writeCommitGraph", "true"); err != nil { + if err := configSet(ctx, "gc.writeCommitGraph", "true"); err != nil { return err } - if err := configSet("fetch.writeCommitGraph", "true"); err != nil { + if err := configSet(ctx, "fetch.writeCommitGraph", "true"); err != nil { return err } } if DefaultFeatures().SupportProcReceive { // set support for AGit flow - if err := configAddNonExist("receive.procReceiveRefs", "refs/for"); err != nil { + if err := configAddNonExist(ctx, "receive.procReceiveRefs", "refs/for"); err != nil { return err } } else { - if err := configUnsetAll("receive.procReceiveRefs", "refs/for"); err != nil { + if err := configUnsetAll(ctx, "receive.procReceiveRefs", "refs/for"); err != nil { return err } } @@ -81,18 +82,18 @@ func syncGitConfig() (err error) { // As Gitea now always use its internal git config file, and access to the git repositories is managed through Gitea, // it is now safe to set "safe.directory=*" for internal usage only. // Although this setting is only supported by some new git versions, it is also tolerated by earlier versions - if err := configAddNonExist("safe.directory", "*"); err != nil { + if err := configAddNonExist(ctx, "safe.directory", "*"); err != nil { return err } if runtime.GOOS == "windows" { - if err := configSet("core.longpaths", "true"); err != nil { + if err := configSet(ctx, "core.longpaths", "true"); err != nil { return err } if setting.Git.DisableCoreProtectNTFS { - err = configSet("core.protectNTFS", "false") + err = configSet(ctx, "core.protectNTFS", "false") } else { - err = configUnsetAll("core.protectNTFS", "false") + err = configUnsetAll(ctx, "core.protectNTFS", "false") } if err != nil { return err @@ -101,22 +102,22 @@ func syncGitConfig() (err error) { // By default partial clones are disabled, enable them from git v2.22 if !setting.Git.DisablePartialClone && DefaultFeatures().CheckVersionAtLeast("2.22") { - if err = configSet("uploadpack.allowfilter", "true"); err != nil { + if err = configSet(ctx, "uploadpack.allowfilter", "true"); err != nil { return err } - err = configSet("uploadpack.allowAnySHA1InWant", "true") + err = configSet(ctx, "uploadpack.allowAnySHA1InWant", "true") } else { - if err = configUnsetAll("uploadpack.allowfilter", "true"); err != nil { + if err = configUnsetAll(ctx, "uploadpack.allowfilter", "true"); err != nil { return err } - err = configUnsetAll("uploadpack.allowAnySHA1InWant", "true") + err = configUnsetAll(ctx, "uploadpack.allowAnySHA1InWant", "true") } return err } -func configSet(key, value string) error { - stdout, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(DefaultContext, nil) +func configSet(ctx context.Context, key, value string) error { + stdout, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx, nil) if err != nil && !IsErrorExitCode(err, 1) { return fmt.Errorf("failed to get git config %s, err: %w", key, err) } @@ -126,7 +127,7 @@ func configSet(key, value string) error { return nil } - _, _, err = NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(DefaultContext, nil) + _, _, err = NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(ctx, nil) if err != nil { return fmt.Errorf("failed to set git global config %s, err: %w", key, err) } @@ -134,15 +135,15 @@ func configSet(key, value string) error { return nil } -func configSetNonExist(key, value string) error { - _, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(DefaultContext, nil) +func configSetNonExist(ctx context.Context, key, value string) error { + _, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx, nil) if err == nil { // already exist return nil } if IsErrorExitCode(err, 1) { // not exist, set new config - _, _, err = NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(DefaultContext, nil) + _, _, err = NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(ctx, nil) if err != nil { return fmt.Errorf("failed to set git global config %s, err: %w", key, err) } @@ -152,15 +153,15 @@ func configSetNonExist(key, value string) error { return fmt.Errorf("failed to get git config %s, err: %w", key, err) } -func configAddNonExist(key, value string) error { - _, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(DefaultContext, nil) +func configAddNonExist(ctx context.Context, key, value string) error { + _, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(ctx, nil) if err == nil { // already exist return nil } if IsErrorExitCode(err, 1) { // not exist, add new config - _, _, err = NewCommand("config", "--global", "--add").AddDynamicArguments(key, value).RunStdString(DefaultContext, nil) + _, _, err = NewCommand("config", "--global", "--add").AddDynamicArguments(key, value).RunStdString(ctx, nil) if err != nil { return fmt.Errorf("failed to add git global config %s, err: %w", key, err) } @@ -169,11 +170,11 @@ func configAddNonExist(key, value string) error { return fmt.Errorf("failed to get git config %s, err: %w", key, err) } -func configUnsetAll(key, value string) error { - _, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(DefaultContext, nil) +func configUnsetAll(ctx context.Context, key, value string) error { + _, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx, nil) if err == nil { // exist, need to remove - _, _, err = NewCommand("config", "--global", "--unset-all").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(DefaultContext, nil) + _, _, err = NewCommand("config", "--global", "--unset-all").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(ctx, nil) if err != nil { return fmt.Errorf("failed to unset git global config %s, err: %w", key, err) } diff --git a/modules/git/config_test.go b/modules/git/config_test.go index 59f70c99e2..911e0e0184 100644 --- a/modules/git/config_test.go +++ b/modules/git/config_test.go @@ -21,35 +21,36 @@ func gitConfigContains(sub string) bool { } func TestGitConfig(t *testing.T) { + ctx := t.Context() assert.False(t, gitConfigContains("key-a")) - assert.NoError(t, configSetNonExist("test.key-a", "val-a")) + assert.NoError(t, configSetNonExist(ctx, "test.key-a", "val-a")) assert.True(t, gitConfigContains("key-a = val-a")) - assert.NoError(t, configSetNonExist("test.key-a", "val-a-changed")) + assert.NoError(t, configSetNonExist(ctx, "test.key-a", "val-a-changed")) assert.False(t, gitConfigContains("key-a = val-a-changed")) - assert.NoError(t, configSet("test.key-a", "val-a-changed")) + assert.NoError(t, configSet(ctx, "test.key-a", "val-a-changed")) assert.True(t, gitConfigContains("key-a = val-a-changed")) - assert.NoError(t, configAddNonExist("test.key-b", "val-b")) + assert.NoError(t, configAddNonExist(ctx, "test.key-b", "val-b")) assert.True(t, gitConfigContains("key-b = val-b")) - assert.NoError(t, configAddNonExist("test.key-b", "val-2b")) + assert.NoError(t, configAddNonExist(ctx, "test.key-b", "val-2b")) assert.True(t, gitConfigContains("key-b = val-b")) assert.True(t, gitConfigContains("key-b = val-2b")) - assert.NoError(t, configUnsetAll("test.key-b", "val-b")) + assert.NoError(t, configUnsetAll(ctx, "test.key-b", "val-b")) assert.False(t, gitConfigContains("key-b = val-b")) assert.True(t, gitConfigContains("key-b = val-2b")) - assert.NoError(t, configUnsetAll("test.key-b", "val-2b")) + assert.NoError(t, configUnsetAll(ctx, "test.key-b", "val-2b")) assert.False(t, gitConfigContains("key-b = val-2b")) - assert.NoError(t, configSet("test.key-x", "*")) + assert.NoError(t, configSet(ctx, "test.key-x", "*")) assert.True(t, gitConfigContains("key-x = *")) - assert.NoError(t, configSetNonExist("test.key-x", "*")) - assert.NoError(t, configUnsetAll("test.key-x", "*")) + assert.NoError(t, configSetNonExist(ctx, "test.key-x", "*")) + assert.NoError(t, configUnsetAll(ctx, "test.key-x", "*")) assert.False(t, gitConfigContains("key-x = *")) } @@ -60,7 +61,7 @@ func TestSyncConfig(t *testing.T) { }() setting.GitConfig.Options["sync-test.cfg-key-a"] = "CfgValA" - assert.NoError(t, syncGitConfig()) + assert.NoError(t, syncGitConfig(t.Context())) assert.True(t, gitConfigContains("[sync-test]")) assert.True(t, gitConfigContains("cfg-key-a = CfgValA")) } diff --git a/modules/git/foreachref/parser.go b/modules/git/foreachref/parser.go index de69eaa2c8..ebdc7344d0 100644 --- a/modules/git/foreachref/parser.go +++ b/modules/git/foreachref/parser.go @@ -30,6 +30,10 @@ type Parser struct { func NewParser(r io.Reader, format Format) *Parser { scanner := bufio.NewScanner(r) + // default MaxScanTokenSize = 64 kiB may be too small for some references, + // so allow the buffer to grow up to 4x if needed + scanner.Buffer(nil, 4*bufio.MaxScanTokenSize) + // in addition to the reference delimiter we specified in the --format, // `git for-each-ref` will always add a newline after every reference. refDelim := make([]byte, 0, len(format.refDelim)+1) @@ -70,6 +74,9 @@ func NewParser(r io.Reader, format Format) *Parser { // { "objecttype": "tag", "refname:short": "v1.16.4", "object": "f460b7543ed500e49c133c2cd85c8c55ee9dbe27" } func (p *Parser) Next() map[string]string { if !p.scanner.Scan() { + if err := p.scanner.Err(); err != nil { + p.err = err + } return nil } fields, err := p.parseRef(p.scanner.Text()) diff --git a/modules/git/fsck.go b/modules/git/fsck.go deleted file mode 100644 index a52684c84f..0000000000 --- a/modules/git/fsck.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2024 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package git - -import ( - "context" - "time" -) - -// Fsck verifies the connectivity and validity of the objects in the database -func Fsck(ctx context.Context, repoPath string, timeout time.Duration, args TrustedCmdArgs) error { - return NewCommand("fsck").AddArguments(args...).Run(ctx, &RunOpts{Timeout: timeout, Dir: repoPath}) -} diff --git a/modules/git/git.go b/modules/git/git.go index a2ffd6d289..0a2e87a2ea 100644 --- a/modules/git/git.go +++ b/modules/git/git.go @@ -34,8 +34,7 @@ type Features struct { } var ( - GitExecutable = "git" // the command name of git, will be updated to an absolute path during initialization - DefaultContext context.Context // the default context to run git commands in, must be initialized by git.InitXxx + GitExecutable = "git" // the command name of git, will be updated to an absolute path during initialization defaultFeatures *Features ) @@ -53,7 +52,7 @@ func DefaultFeatures() *Features { if !setting.IsProd || setting.IsInTesting { log.Warn("git.DefaultFeatures is called before git.InitXxx, initializing with default values") } - if err := InitSimple(context.Background()); err != nil { + if err := InitSimple(); err != nil { log.Fatal("git.InitSimple failed: %v", err) } } @@ -61,7 +60,7 @@ func DefaultFeatures() *Features { } func loadGitVersionFeatures() (*Features, error) { - stdout, _, runErr := NewCommand("version").RunStdString(DefaultContext, nil) + stdout, _, runErr := NewCommand("version").RunStdString(context.Background(), nil) if runErr != nil { return nil, runErr } @@ -158,18 +157,15 @@ func HomeDir() string { // InitSimple initializes git module with a very simple step, no config changes, no global command arguments. // This method doesn't change anything to filesystem. At the moment, it is only used by some Gitea sub-commands. -func InitSimple(ctx context.Context) error { +func InitSimple() error { if setting.Git.HomePath == "" { return errors.New("unable to init Git's HomeDir, incorrect initialization of the setting and git modules") } - if DefaultContext != nil && (!setting.IsProd || setting.IsInTesting) { + if defaultFeatures != nil && (!setting.IsProd || setting.IsInTesting) { log.Warn("git module has been initialized already, duplicate init may work but it's better to fix it") } - DefaultContext = ctx - globalCommandArgs = nil - if setting.Git.Timeout.Default > 0 { defaultCommandExecutionTimeout = time.Duration(setting.Git.Timeout.Default) * time.Second } @@ -196,27 +192,16 @@ func InitSimple(ctx context.Context) error { // InitFull initializes git module with version check and change global variables, sync gitconfig. // It should only be called once at the beginning of the program initialization (TestMain/GlobalInitInstalled) as this code makes unsynchronized changes to variables. -func InitFull(ctx context.Context) (err error) { - if err = InitSimple(ctx); err != nil { +func InitFull() (err error) { + if err = InitSimple(); err != nil { return err } - // Since git wire protocol has been released from git v2.18 - if setting.Git.EnableAutoGitWireProtocol && DefaultFeatures().CheckVersionAtLeast("2.18") { - globalCommandArgs = append(globalCommandArgs, "-c", "protocol.version=2") - } - - // Explicitly disable credential helper, otherwise Git credentials might leak - if DefaultFeatures().CheckVersionAtLeast("2.9") { - globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=") - } - if setting.LFS.StartServer { if !DefaultFeatures().CheckVersionAtLeast("2.1.2") { return errors.New("LFS server support requires Git >= 2.1.2") } - globalCommandArgs = append(globalCommandArgs, "-c", "filter.lfs.required=", "-c", "filter.lfs.smudge=", "-c", "filter.lfs.clean=") } - return syncGitConfig() + return syncGitConfig(context.Background()) } diff --git a/modules/git/git_test.go b/modules/git/git_test.go index 58ba01cabc..7a8ca74b01 100644 --- a/modules/git/git_test.go +++ b/modules/git/git_test.go @@ -4,7 +4,6 @@ package git import ( - "context" "fmt" "os" "testing" @@ -25,7 +24,7 @@ func testRun(m *testing.M) error { setting.Git.HomePath = gitHomePath - if err = InitFull(context.Background()); err != nil { + if err = InitFull(); err != nil { return fmt.Errorf("failed to call Init: %w", err) } diff --git a/modules/git/grep_test.go b/modules/git/grep_test.go index 0dce464b7c..b87ac4bea7 100644 --- a/modules/git/grep_test.go +++ b/modules/git/grep_test.go @@ -11,7 +11,7 @@ import ( ) func TestGrepSearch(t *testing.T) { - repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "language_stats_repo")) + repo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "language_stats_repo")) assert.NoError(t, err) defer repo.Close() diff --git a/modules/git/languagestats/main_test.go b/modules/git/languagestats/main_test.go index 707d268c81..b8f9ded005 100644 --- a/modules/git/languagestats/main_test.go +++ b/modules/git/languagestats/main_test.go @@ -4,7 +4,6 @@ package languagestats import ( - "context" "fmt" "os" "testing" @@ -22,7 +21,7 @@ func testRun(m *testing.M) error { defer util.RemoveAll(gitHomePath) setting.Git.HomePath = gitHomePath - if err = git.InitFull(context.Background()); err != nil { + if err = git.InitFull(); err != nil { return fmt.Errorf("failed to call Init: %w", err) } diff --git a/modules/git/notes_test.go b/modules/git/notes_test.go index ca05a9e525..7db2dbc0b9 100644 --- a/modules/git/notes_test.go +++ b/modules/git/notes_test.go @@ -12,7 +12,7 @@ import ( func TestGetNotes(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path) assert.NoError(t, err) defer bareRepo1.Close() @@ -25,7 +25,7 @@ func TestGetNotes(t *testing.T) { func TestGetNestedNotes(t *testing.T) { repoPath := filepath.Join(testReposDir, "repo3_notes") - repo, err := openRepositoryWithDefaultContext(repoPath) + repo, err := OpenRepository(t.Context(), repoPath) assert.NoError(t, err) defer repo.Close() @@ -40,7 +40,7 @@ func TestGetNestedNotes(t *testing.T) { func TestGetNonExistentNotes(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path) assert.NoError(t, err) defer bareRepo1.Close() diff --git a/modules/git/remote.go b/modules/git/remote.go index 530a813f82..e59880ee15 100644 --- a/modules/git/remote.go +++ b/modules/git/remote.go @@ -10,7 +10,6 @@ import ( "net/url" "strings" - giturl "code.gitea.io/gitea/modules/git/url" "code.gitea.io/gitea/modules/util" ) @@ -34,15 +33,6 @@ func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (string, return result, nil } -// GetRemoteURL returns the url of a specific remote of the repository. -func GetRemoteURL(ctx context.Context, repoPath, remoteName string) (*giturl.GitURL, error) { - addr, err := GetRemoteAddress(ctx, repoPath, remoteName) - if err != nil { - return nil, err - } - return giturl.ParseGitURL(addr) -} - // ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error. type ErrInvalidCloneAddr struct { Host string diff --git a/modules/git/repo.go b/modules/git/repo.go index 66a85309f2..d0bf4312bd 100644 --- a/modules/git/repo.go +++ b/modules/git/repo.go @@ -38,6 +38,17 @@ func (repo *Repository) GetAllCommitsCount() (int64, error) { return AllCommitsCount(repo.Ctx, repo.Path, false) } +func (repo *Repository) ShowPrettyFormatLogToList(ctx context.Context, revisionRange string) ([]*Commit, error) { + // avoid: ambiguous argument 'refs/a...refs/b': unknown revision or path not in the working tree. Use '--': 'git [...] -- [...]' + logs, _, err := NewCommand("log").AddArguments(prettyLogFormat). + AddDynamicArguments(revisionRange).AddArguments("--"). + RunStdBytes(ctx, &RunOpts{Dir: repo.Path}) + if err != nil { + return nil, err + } + return repo.parsePrettyFormatLogToList(logs) +} + func (repo *Repository) parsePrettyFormatLogToList(logs []byte) ([]*Commit, error) { var commits []*Commit if len(logs) == 0 { @@ -122,17 +133,12 @@ type CloneRepoOptions struct { // Clone clones original repository to target path. func Clone(ctx context.Context, from, to string, opts CloneRepoOptions) error { - return CloneWithArgs(ctx, globalCommandArgs, from, to, opts) -} - -// CloneWithArgs original repository to target path. -func CloneWithArgs(ctx context.Context, args TrustedCmdArgs, from, to string, opts CloneRepoOptions) (err error) { toDir := path.Dir(to) - if err = os.MkdirAll(toDir, os.ModePerm); err != nil { + if err := os.MkdirAll(toDir, os.ModePerm); err != nil { return err } - cmd := NewCommandNoGlobals(args...).AddArguments("clone") + cmd := NewCommand().AddArguments("clone") if opts.SkipTLSVerify { cmd.AddArguments("-c", "http.sslVerify=false") } diff --git a/modules/git/repo_base_gogit.go b/modules/git/repo_base_gogit.go index 293aca159c..e0d0b45372 100644 --- a/modules/git/repo_base_gogit.go +++ b/modules/git/repo_base_gogit.go @@ -39,11 +39,6 @@ type Repository struct { objectFormat ObjectFormat } -// openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext. -func openRepositoryWithDefaultContext(repoPath string) (*Repository, error) { - return OpenRepository(DefaultContext, repoPath) -} - // OpenRepository opens the repository at the given path within the context.Context func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) { repoPath, err := filepath.Abs(repoPath) diff --git a/modules/git/repo_base_nogogit.go b/modules/git/repo_base_nogogit.go index 6f9bfd4b43..4091e70846 100644 --- a/modules/git/repo_base_nogogit.go +++ b/modules/git/repo_base_nogogit.go @@ -37,11 +37,6 @@ type Repository struct { objectFormat ObjectFormat } -// openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext. -func openRepositoryWithDefaultContext(repoPath string) (*Repository, error) { - return OpenRepository(DefaultContext, repoPath) -} - // OpenRepository opens the repository at the given path with the provided context. func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) { repoPath, err := filepath.Abs(repoPath) diff --git a/modules/git/repo_blob_test.go b/modules/git/repo_blob_test.go index 8a5f5fcd5b..f07b31d236 100644 --- a/modules/git/repo_blob_test.go +++ b/modules/git/repo_blob_test.go @@ -14,7 +14,7 @@ import ( func TestRepository_GetBlob_Found(t *testing.T) { repoPath := filepath.Join(testReposDir, "repo1_bare") - r, err := openRepositoryWithDefaultContext(repoPath) + r, err := OpenRepository(t.Context(), repoPath) assert.NoError(t, err) defer r.Close() @@ -42,7 +42,7 @@ func TestRepository_GetBlob_Found(t *testing.T) { func TestRepository_GetBlob_NotExist(t *testing.T) { repoPath := filepath.Join(testReposDir, "repo1_bare") - r, err := openRepositoryWithDefaultContext(repoPath) + r, err := OpenRepository(t.Context(), repoPath) assert.NoError(t, err) defer r.Close() @@ -56,7 +56,7 @@ func TestRepository_GetBlob_NotExist(t *testing.T) { func TestRepository_GetBlob_NoId(t *testing.T) { repoPath := filepath.Join(testReposDir, "repo1_bare") - r, err := openRepositoryWithDefaultContext(repoPath) + r, err := OpenRepository(t.Context(), repoPath) assert.NoError(t, err) defer r.Close() diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go index e7ecf53f51..eac2031003 100644 --- a/modules/git/repo_branch.go +++ b/modules/git/repo_branch.go @@ -79,12 +79,6 @@ func (repo *Repository) AddRemote(name, url string, fetch bool) error { return err } -// RemoveRemote removes a remote from repository. -func (repo *Repository) RemoveRemote(name string) error { - _, _, err := NewCommand("remote", "rm").AddDynamicArguments(name).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) - return err -} - // RenameBranch rename a branch func (repo *Repository) RenameBranch(from, to string) error { _, _, err := NewCommand("branch", "-m").AddDynamicArguments(from, to).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) diff --git a/modules/git/repo_branch_test.go b/modules/git/repo_branch_test.go index 8e8ea16fcd..5d586954db 100644 --- a/modules/git/repo_branch_test.go +++ b/modules/git/repo_branch_test.go @@ -13,7 +13,7 @@ import ( func TestRepository_GetBranches(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path) assert.NoError(t, err) defer bareRepo1.Close() @@ -41,7 +41,7 @@ func TestRepository_GetBranches(t *testing.T) { func BenchmarkRepository_GetBranches(b *testing.B) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + bareRepo1, err := OpenRepository(b.Context(), bareRepo1Path) if err != nil { b.Fatal(err) } @@ -57,7 +57,7 @@ func BenchmarkRepository_GetBranches(b *testing.B) { func TestGetRefsBySha(t *testing.T) { bareRepo5Path := filepath.Join(testReposDir, "repo5_pulls") - bareRepo5, err := OpenRepository(DefaultContext, bareRepo5Path) + bareRepo5, err := OpenRepository(t.Context(), bareRepo5Path) if err != nil { t.Fatal(err) } @@ -84,7 +84,7 @@ func TestGetRefsBySha(t *testing.T) { func BenchmarkGetRefsBySha(b *testing.B) { bareRepo5Path := filepath.Join(testReposDir, "repo5_pulls") - bareRepo5, err := OpenRepository(DefaultContext, bareRepo5Path) + bareRepo5, err := OpenRepository(b.Context(), bareRepo5Path) if err != nil { b.Fatal(err) } @@ -97,7 +97,7 @@ func BenchmarkGetRefsBySha(b *testing.B) { } func TestRepository_IsObjectExist(t *testing.T) { - repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare")) + repo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo1_bare")) require.NoError(t, err) defer repo.Close() @@ -149,7 +149,7 @@ func TestRepository_IsObjectExist(t *testing.T) { } func TestRepository_IsReferenceExist(t *testing.T) { - repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare")) + repo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo1_bare")) require.NoError(t, err) defer repo.Close() diff --git a/modules/git/repo_commit_test.go b/modules/git/repo_commit_test.go index e9f469accd..3f7883ab14 100644 --- a/modules/git/repo_commit_test.go +++ b/modules/git/repo_commit_test.go @@ -17,7 +17,7 @@ import ( func TestRepository_GetCommitBranches(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path) assert.NoError(t, err) defer bareRepo1.Close() @@ -44,7 +44,7 @@ func TestRepository_GetCommitBranches(t *testing.T) { func TestGetTagCommitWithSignature(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path) assert.NoError(t, err) defer bareRepo1.Close() @@ -59,7 +59,7 @@ func TestGetTagCommitWithSignature(t *testing.T) { func TestGetCommitWithBadCommitID(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path) assert.NoError(t, err) defer bareRepo1.Close() @@ -71,7 +71,7 @@ func TestGetCommitWithBadCommitID(t *testing.T) { func TestIsCommitInBranch(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path) assert.NoError(t, err) defer bareRepo1.Close() @@ -86,7 +86,7 @@ func TestIsCommitInBranch(t *testing.T) { func TestRepository_CommitsBetweenIDs(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo4_commitsbetween") - bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path) assert.NoError(t, err) defer bareRepo1.Close() @@ -108,7 +108,7 @@ func TestRepository_CommitsBetweenIDs(t *testing.T) { func TestGetRefCommitID(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path) assert.NoError(t, err) defer bareRepo1.Close() @@ -135,7 +135,7 @@ func TestCommitsByFileAndRange(t *testing.T) { defer test.MockVariableValue(&setting.Git.CommitsRangeSize, 2)() bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path) require.NoError(t, err) defer bareRepo1.Close() diff --git a/modules/git/repo_compare.go b/modules/git/repo_compare.go index ff44506e13..56251a87a0 100644 --- a/modules/git/repo_compare.go +++ b/modules/git/repo_compare.go @@ -16,20 +16,8 @@ import ( "regexp" "strconv" "strings" - "time" - - logger "code.gitea.io/gitea/modules/log" ) -// CompareInfo represents needed information for comparing references. -type CompareInfo struct { - MergeBase string - BaseCommitID string - HeadCommitID string - Commits []*Commit - NumFiles int -} - // GetMergeBase checks and returns merge base of two branches and the reference used as base. func (repo *Repository) GetMergeBase(tmpRemote, base, head string) (string, string, error) { if tmpRemote == "" { @@ -49,83 +37,6 @@ func (repo *Repository) GetMergeBase(tmpRemote, base, head string) (string, stri return strings.TrimSpace(stdout), base, err } -// GetCompareInfo generates and returns compare information between base and head branches of repositories. -func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string, directComparison, fileOnly bool) (_ *CompareInfo, err error) { - var ( - remoteBranch string - tmpRemote string - ) - - // We don't need a temporary remote for same repository. - if repo.Path != basePath { - // Add a temporary remote - tmpRemote = strconv.FormatInt(time.Now().UnixNano(), 10) - if err = repo.AddRemote(tmpRemote, basePath, false); err != nil { - return nil, fmt.Errorf("AddRemote: %w", err) - } - defer func() { - if err := repo.RemoveRemote(tmpRemote); err != nil { - logger.Error("GetPullRequestInfo: RemoveRemote: %v", err) - } - }() - } - - compareInfo := new(CompareInfo) - - compareInfo.HeadCommitID, err = GetFullCommitID(repo.Ctx, repo.Path, headBranch) - if err != nil { - compareInfo.HeadCommitID = headBranch - } - - compareInfo.MergeBase, remoteBranch, err = repo.GetMergeBase(tmpRemote, baseBranch, headBranch) - if err == nil { - compareInfo.BaseCommitID, err = GetFullCommitID(repo.Ctx, repo.Path, remoteBranch) - if err != nil { - compareInfo.BaseCommitID = remoteBranch - } - separator := "..." - baseCommitID := compareInfo.MergeBase - if directComparison { - separator = ".." - baseCommitID = compareInfo.BaseCommitID - } - - // We have a common base - therefore we know that ... should work - if !fileOnly { - // avoid: ambiguous argument 'refs/a...refs/b': unknown revision or path not in the working tree. Use '--': 'git [...] -- [...]' - var logs []byte - logs, _, err = NewCommand("log").AddArguments(prettyLogFormat). - AddDynamicArguments(baseCommitID+separator+headBranch).AddArguments("--"). - RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path}) - if err != nil { - return nil, err - } - compareInfo.Commits, err = repo.parsePrettyFormatLogToList(logs) - if err != nil { - return nil, fmt.Errorf("parsePrettyFormatLogToList: %w", err) - } - } else { - compareInfo.Commits = []*Commit{} - } - } else { - compareInfo.Commits = []*Commit{} - compareInfo.MergeBase, err = GetFullCommitID(repo.Ctx, repo.Path, remoteBranch) - if err != nil { - compareInfo.MergeBase = remoteBranch - } - compareInfo.BaseCommitID = compareInfo.MergeBase - } - - // Count number of changed files. - // This probably should be removed as we need to use shortstat elsewhere - // Now there is git diff --shortstat but this appears to be slower than simply iterating with --nameonly - compareInfo.NumFiles, err = repo.GetDiffNumChangedFiles(remoteBranch, headBranch, directComparison) - if err != nil { - return nil, err - } - return compareInfo, nil -} - type lineCountWriter struct { numLines int } diff --git a/modules/git/repo_compare_test.go b/modules/git/repo_compare_test.go index 25ee4c5198..35636fae1a 100644 --- a/modules/git/repo_compare_test.go +++ b/modules/git/repo_compare_test.go @@ -20,7 +20,7 @@ func TestGetFormatPatch(t *testing.T) { return } - repo, err := openRepositoryWithDefaultContext(clonedPath) + repo, err := OpenRepository(t.Context(), clonedPath) if err != nil { assert.NoError(t, err) return @@ -48,7 +48,7 @@ func TestGetFormatPatch(t *testing.T) { func TestReadPatch(t *testing.T) { // Ensure we can read the patch files bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - repo, err := openRepositoryWithDefaultContext(bareRepo1Path) + repo, err := OpenRepository(t.Context(), bareRepo1Path) if err != nil { assert.NoError(t, err) return @@ -86,7 +86,7 @@ func TestReadWritePullHead(t *testing.T) { return } - repo, err := openRepositoryWithDefaultContext(clonedPath) + repo, err := OpenRepository(t.Context(), clonedPath) if err != nil { assert.NoError(t, err) return @@ -122,7 +122,7 @@ func TestReadWritePullHead(t *testing.T) { func TestGetCommitFilesChanged(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - repo, err := openRepositoryWithDefaultContext(bareRepo1Path) + repo, err := OpenRepository(t.Context(), bareRepo1Path) assert.NoError(t, err) defer repo.Close() diff --git a/modules/git/repo_ref_test.go b/modules/git/repo_ref_test.go index c08ea12760..29c255098f 100644 --- a/modules/git/repo_ref_test.go +++ b/modules/git/repo_ref_test.go @@ -12,7 +12,7 @@ import ( func TestRepository_GetRefs(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path) assert.NoError(t, err) defer bareRepo1.Close() @@ -37,7 +37,7 @@ func TestRepository_GetRefs(t *testing.T) { func TestRepository_GetRefsFiltered(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path) assert.NoError(t, err) defer bareRepo1.Close() diff --git a/modules/git/repo_stats_test.go b/modules/git/repo_stats_test.go index 85d8807a6e..538283111b 100644 --- a/modules/git/repo_stats_test.go +++ b/modules/git/repo_stats_test.go @@ -13,7 +13,7 @@ import ( func TestRepository_GetCodeActivityStats(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path) assert.NoError(t, err) defer bareRepo1.Close() diff --git a/modules/git/repo_tag_gogit.go b/modules/git/repo_tag_gogit.go index 3e1b4e89ad..878ab55bf2 100644 --- a/modules/git/repo_tag_gogit.go +++ b/modules/git/repo_tag_gogit.go @@ -7,8 +7,6 @@ package git import ( - "strings" - "code.gitea.io/gitea/modules/log" "github.com/go-git/go-git/v5/plumbing" @@ -20,40 +18,6 @@ func (repo *Repository) IsTagExist(name string) bool { return err == nil } -// GetTags returns all tags of the repository. -// returning at most limit tags, or all if limit is 0. -func (repo *Repository) GetTags(skip, limit int) ([]string, error) { - var tagNames []string - - tags, err := repo.gogitRepo.Tags() - if err != nil { - return nil, err - } - - _ = tags.ForEach(func(tag *plumbing.Reference) error { - tagNames = append(tagNames, strings.TrimPrefix(tag.Name().String(), TagPrefix)) - return nil - }) - - // Reverse order - for i := 0; i < len(tagNames)/2; i++ { - j := len(tagNames) - i - 1 - tagNames[i], tagNames[j] = tagNames[j], tagNames[i] - } - - // since we have to reverse order we can paginate only afterwards - if len(tagNames) < skip { - tagNames = []string{} - } else { - tagNames = tagNames[skip:] - } - if limit != 0 && len(tagNames) > limit { - tagNames = tagNames[:limit] - } - - return tagNames, nil -} - // GetTagType gets the type of the tag, either commit (simple) or tag (annotated) func (repo *Repository) GetTagType(id ObjectID) (string, error) { // Get tag type diff --git a/modules/git/repo_tag_nogogit.go b/modules/git/repo_tag_nogogit.go index 3d2b4f52bd..5f79b68a9a 100644 --- a/modules/git/repo_tag_nogogit.go +++ b/modules/git/repo_tag_nogogit.go @@ -22,13 +22,6 @@ func (repo *Repository) IsTagExist(name string) bool { return repo.IsReferenceExist(TagPrefix + name) } -// GetTags returns all tags of the repository. -// returning at most limit tags, or all if limit is 0. -func (repo *Repository) GetTags(skip, limit int) (tags []string, err error) { - tags, _, err = callShowRef(repo.Ctx, repo.Path, TagPrefix, TrustedCmdArgs{TagPrefix, "--sort=-taggerdate"}, skip, limit) - return tags, err -} - // GetTagType gets the type of the tag, either commit (simple) or tag (annotated) func (repo *Repository) GetTagType(id ObjectID) (string, error) { wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx) diff --git a/modules/git/repo_tag_test.go b/modules/git/repo_tag_test.go index f1f5ff6664..e6f8e75a0e 100644 --- a/modules/git/repo_tag_test.go +++ b/modules/git/repo_tag_test.go @@ -11,9 +11,9 @@ import ( "github.com/stretchr/testify/require" ) -func TestRepository_GetTags(t *testing.T) { +func TestRepository_GetTagInfos(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + bareRepo1, err := OpenRepository(t.Context(), bareRepo1Path) if err != nil { assert.NoError(t, err) return @@ -44,7 +44,7 @@ func TestRepository_GetTag(t *testing.T) { return } - bareRepo1, err := openRepositoryWithDefaultContext(clonedPath) + bareRepo1, err := OpenRepository(t.Context(), clonedPath) if err != nil { assert.NoError(t, err) return @@ -136,7 +136,7 @@ func TestRepository_GetAnnotatedTag(t *testing.T) { return } - bareRepo1, err := openRepositoryWithDefaultContext(clonedPath) + bareRepo1, err := OpenRepository(t.Context(), clonedPath) if err != nil { assert.NoError(t, err) return diff --git a/modules/git/repo_test.go b/modules/git/repo_test.go index 4638bdac1f..813844d1ea 100644 --- a/modules/git/repo_test.go +++ b/modules/git/repo_test.go @@ -12,7 +12,7 @@ import ( func TestGetLatestCommitTime(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") - lct, err := GetLatestCommitTime(DefaultContext, bareRepo1Path) + lct, err := GetLatestCommitTime(t.Context(), bareRepo1Path) assert.NoError(t, err) // Time is Sun Nov 13 16:40:14 2022 +0100 // which is the time of commit @@ -22,7 +22,7 @@ func TestGetLatestCommitTime(t *testing.T) { func TestRepoIsEmpty(t *testing.T) { emptyRepo2Path := filepath.Join(testReposDir, "repo2_empty") - repo, err := openRepositoryWithDefaultContext(emptyRepo2Path) + repo, err := OpenRepository(t.Context(), emptyRepo2Path) assert.NoError(t, err) defer repo.Close() isEmpty, err := repo.IsEmpty() diff --git a/modules/git/submodule_test.go b/modules/git/submodule_test.go index 7893b95e3a..55ac0971a5 100644 --- a/modules/git/submodule_test.go +++ b/modules/git/submodule_test.go @@ -14,7 +14,7 @@ import ( func TestGetTemplateSubmoduleCommits(t *testing.T) { testRepoPath := filepath.Join(testReposDir, "repo4_submodules") - submodules, err := GetTemplateSubmoduleCommits(DefaultContext, testRepoPath) + submodules, err := GetTemplateSubmoduleCommits(t.Context(), testRepoPath) require.NoError(t, err) assert.Len(t, submodules, 2) @@ -39,7 +39,7 @@ func TestAddTemplateSubmoduleIndexes(t *testing.T) { require.NoError(t, err) _, _, err = NewCommand("-c", "user.name=a", "-c", "user.email=b", "commit", "-m=test").RunStdString(ctx, &RunOpts{Dir: tmpDir}) require.NoError(t, err) - submodules, err := GetTemplateSubmoduleCommits(DefaultContext, tmpDir) + submodules, err := GetTemplateSubmoduleCommits(t.Context(), tmpDir) require.NoError(t, err) assert.Len(t, submodules, 1) assert.Equal(t, "new-dir", submodules[0].Path) diff --git a/modules/git/tree_entry_common_test.go b/modules/git/tree_entry_common_test.go index 8b63bbb993..8e20ee56ff 100644 --- a/modules/git/tree_entry_common_test.go +++ b/modules/git/tree_entry_common_test.go @@ -13,7 +13,7 @@ import ( ) func TestFollowLink(t *testing.T) { - r, err := openRepositoryWithDefaultContext("tests/repos/repo1_bare") + r, err := OpenRepository(t.Context(), "tests/repos/repo1_bare") require.NoError(t, err) defer r.Close() diff --git a/modules/git/tree_test.go b/modules/git/tree_test.go index cae11c4b1b..67f95fe748 100644 --- a/modules/git/tree_test.go +++ b/modules/git/tree_test.go @@ -11,7 +11,7 @@ import ( ) func TestSubTree_Issue29101(t *testing.T) { - repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare")) + repo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo1_bare")) assert.NoError(t, err) defer repo.Close() @@ -27,7 +27,7 @@ func TestSubTree_Issue29101(t *testing.T) { } func Test_GetTreePathLatestCommit(t *testing.T) { - repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo6_blame")) + repo, err := OpenRepository(t.Context(), filepath.Join(testReposDir, "repo6_blame")) assert.NoError(t, err) defer repo.Close() diff --git a/modules/gitrepo/config.go b/modules/gitrepo/config.go new file mode 100644 index 0000000000..84ef1eadf6 --- /dev/null +++ b/modules/gitrepo/config.go @@ -0,0 +1,48 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package gitrepo + +import ( + "context" + "strings" + + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/globallock" +) + +func GitConfigGet(ctx context.Context, repo Repository, key string) (string, error) { + result, _, err := git.NewCommand("config", "--get"). + AddDynamicArguments(key). + RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)}) + if err != nil { + return "", err + } + return strings.TrimSpace(result), nil +} + +func getRepoConfigLockKey(repoStoragePath string) string { + return "repo-config:" + repoStoragePath +} + +// GitConfigAdd add a git configuration key to a specific value for the given repository. +func GitConfigAdd(ctx context.Context, repo Repository, key, value string) error { + return globallock.LockAndDo(ctx, getRepoConfigLockKey(repo.RelativePath()), func(ctx context.Context) error { + _, _, err := git.NewCommand("config", "--add"). + AddDynamicArguments(key, value). + RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)}) + return err + }) +} + +// GitConfigSet updates a git configuration key to a specific value for the given repository. +// If the key does not exist, it will be created. +// If the key exists, it will be updated to the new value. +func GitConfigSet(ctx context.Context, repo Repository, key, value string) error { + return globallock.LockAndDo(ctx, getRepoConfigLockKey(repo.RelativePath()), func(ctx context.Context) error { + _, _, err := git.NewCommand("config"). + AddDynamicArguments(key, value). + RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)}) + return err + }) +} diff --git a/modules/gitrepo/fsck.go b/modules/gitrepo/fsck.go new file mode 100644 index 0000000000..bcec6aa03f --- /dev/null +++ b/modules/gitrepo/fsck.go @@ -0,0 +1,16 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package gitrepo + +import ( + "context" + "time" + + "code.gitea.io/gitea/modules/git" +) + +// Fsck verifies the connectivity and validity of the objects in the database +func Fsck(ctx context.Context, repo Repository, timeout time.Duration, args git.TrustedCmdArgs) error { + return git.NewCommand("fsck").AddArguments(args...).Run(ctx, &git.RunOpts{Timeout: timeout, Dir: repoPath(repo)}) +} diff --git a/modules/gitrepo/gitrepo.go b/modules/gitrepo/gitrepo.go index 5da65e2452..fad8f70c4c 100644 --- a/modules/gitrepo/gitrepo.go +++ b/modules/gitrepo/gitrepo.go @@ -69,7 +69,8 @@ func IsRepositoryExist(ctx context.Context, repo Repository) (bool, error) { return util.IsExist(repoPath(repo)) } -// DeleteRepository deletes the repository directory from the disk +// DeleteRepository deletes the repository directory from the disk, it will return +// nil if the repository does not exist. func DeleteRepository(ctx context.Context, repo Repository) error { return util.RemoveAll(repoPath(repo)) } @@ -81,3 +82,7 @@ func RenameRepository(ctx context.Context, repo, newRepo Repository) error { } return nil } + +func InitRepository(ctx context.Context, repo Repository, objectFormatName string) error { + return git.InitRepository(ctx, repoPath(repo), true, objectFormatName) +} diff --git a/modules/gitrepo/remote.go b/modules/gitrepo/remote.go new file mode 100644 index 0000000000..ba32c2a1d8 --- /dev/null +++ b/modules/gitrepo/remote.go @@ -0,0 +1,85 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package gitrepo + +import ( + "context" + "errors" + "io" + "time" + + "code.gitea.io/gitea/modules/git" + giturl "code.gitea.io/gitea/modules/git/url" + "code.gitea.io/gitea/modules/globallock" + "code.gitea.io/gitea/modules/util" +) + +type RemoteOption string + +const ( + RemoteOptionMirrorPush RemoteOption = "--mirror=push" + RemoteOptionMirrorFetch RemoteOption = "--mirror=fetch" +) + +func GitRemoteAdd(ctx context.Context, repo Repository, remoteName, remoteURL string, options ...RemoteOption) error { + return globallock.LockAndDo(ctx, getRepoConfigLockKey(repo.RelativePath()), func(ctx context.Context) error { + cmd := git.NewCommand("remote", "add") + if len(options) > 0 { + switch options[0] { + case RemoteOptionMirrorPush: + cmd.AddArguments("--mirror=push") + case RemoteOptionMirrorFetch: + cmd.AddArguments("--mirror=fetch") + default: + return errors.New("unknown remote option: " + string(options[0])) + } + } + _, _, err := cmd. + AddDynamicArguments(remoteName, remoteURL). + RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)}) + return err + }) +} + +func GitRemoteRemove(ctx context.Context, repo Repository, remoteName string) error { + return globallock.LockAndDo(ctx, getRepoConfigLockKey(repo.RelativePath()), func(ctx context.Context) error { + cmd := git.NewCommand("remote", "rm").AddDynamicArguments(remoteName) + _, _, err := cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)}) + return err + }) +} + +// GitRemoteGetURL returns the url of a specific remote of the repository. +func GitRemoteGetURL(ctx context.Context, repo Repository, remoteName string) (*giturl.GitURL, error) { + addr, err := git.GetRemoteAddress(ctx, repoPath(repo), remoteName) + if err != nil { + return nil, err + } + if addr == "" { + return nil, util.NewNotExistErrorf("remote '%s' does not exist", remoteName) + } + return giturl.ParseGitURL(addr) +} + +// GitRemotePrune prunes the remote branches that no longer exist in the remote repository. +func GitRemotePrune(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error { + return git.NewCommand("remote", "prune").AddDynamicArguments(remoteName). + Run(ctx, &git.RunOpts{ + Timeout: timeout, + Dir: repoPath(repo), + Stdout: stdout, + Stderr: stderr, + }) +} + +// GitRemoteUpdatePrune updates the remote branches and prunes the ones that no longer exist in the remote repository. +func GitRemoteUpdatePrune(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error { + return git.NewCommand("remote", "update", "--prune").AddDynamicArguments(remoteName). + Run(ctx, &git.RunOpts{ + Timeout: timeout, + Dir: repoPath(repo), + Stdout: stdout, + Stderr: stderr, + }) +} diff --git a/modules/globallock/locker_test.go b/modules/globallock/locker_test.go index c9e73c25d2..14cb0ec388 100644 --- a/modules/globallock/locker_test.go +++ b/modules/globallock/locker_test.go @@ -105,15 +105,13 @@ func testLocker(t *testing.T, locker Locker) { require.NoError(t, err) wg := &sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { started := time.Now() release, err := locker.Lock(t.Context(), "test") // should be blocked for seconds defer release() assert.Greater(t, time.Since(started), time.Second) assert.NoError(t, err) - }() + }) time.Sleep(2 * time.Second) release() diff --git a/modules/graceful/manager.go b/modules/graceful/manager.go index 433e8c4c27..ee1872b999 100644 --- a/modules/graceful/manager.go +++ b/modules/graceful/manager.go @@ -47,12 +47,19 @@ var ( // GetManager returns the Manager func GetManager() *Manager { - InitManager(context.Background()) + initManager(context.Background()) return manager } // InitManager creates the graceful manager in the provided context func InitManager(ctx context.Context) { + if manager != nil { + log.Error("graceful.InitManager called more than once") + } + initManager(ctx) // FIXME: this design is not right, it conflicts with the "Background" context used in GetManager +} + +func initManager(ctx context.Context) { initOnce.Do(func() { manager = newGracefulManager(ctx) diff --git a/modules/gtprof/trace_builtin.go b/modules/gtprof/trace_builtin.go index 2590ed3a13..7b4e3b8b4f 100644 --- a/modules/gtprof/trace_builtin.go +++ b/modules/gtprof/trace_builtin.go @@ -40,7 +40,7 @@ func (t *traceBuiltinSpan) toString(out *strings.Builder, indent int) { if t.ts.endTime.IsZero() { out.WriteString(" duration: (not ended)") } else { - fmt.Fprintf(out, " duration=%.4fs", t.ts.endTime.Sub(t.ts.startTime).Seconds()) + fmt.Fprintf(out, " start=%s duration=%.4fs", t.ts.startTime.Format("2006-01-02 15:04:05"), t.ts.endTime.Sub(t.ts.startTime).Seconds()) } for _, a := range t.ts.attributes { out.WriteString(" ") diff --git a/modules/httplib/url.go b/modules/httplib/url.go index f51506ac3b..2a1376b8d4 100644 --- a/modules/httplib/url.go +++ b/modules/httplib/url.go @@ -19,7 +19,7 @@ type RequestContextKeyStruct struct{} var RequestContextKey = RequestContextKeyStruct{} func urlIsRelative(s string, u *url.URL) bool { - // Unfortunately browsers consider a redirect Location with preceding "//", "\\", "/\" and "\/" as meaning redirect to "http(s)://REST_OF_PATH" + // Unfortunately, browsers consider a redirect Location with preceding "//", "\\", "/\" and "\/" as meaning redirect to "http(s)://REST_OF_PATH" // Therefore we should ignore these redirect locations to prevent open redirects if len(s) > 1 && (s[0] == '/' || s[0] == '\\') && (s[1] == '/' || s[1] == '\\') { return false diff --git a/modules/indexer/issues/meilisearch/meilisearch.go b/modules/indexer/issues/meilisearch/meilisearch.go index 759a98473f..b7fae6ee9a 100644 --- a/modules/indexer/issues/meilisearch/meilisearch.go +++ b/modules/indexer/issues/meilisearch/meilisearch.go @@ -14,6 +14,7 @@ import ( indexer_internal "code.gitea.io/gitea/modules/indexer/internal" inner_meilisearch "code.gitea.io/gitea/modules/indexer/internal/meilisearch" "code.gitea.io/gitea/modules/indexer/issues/internal" + "code.gitea.io/gitea/modules/json" "github.com/meilisearch/meilisearch-go" ) @@ -106,7 +107,8 @@ func (b *Indexer) Index(_ context.Context, issues ...*internal.IndexerData) erro return nil } for _, issue := range issues { - _, err := b.inner.Client.Index(b.inner.VersionedIndexName()).AddDocuments(issue) + // use default primary key which should be "id" + _, err := b.inner.Client.Index(b.inner.VersionedIndexName()).AddDocuments(issue, nil) if err != nil { return err } @@ -299,18 +301,13 @@ func doubleQuoteKeyword(k string) string { func convertHits(searchRes *meilisearch.SearchResponse) ([]internal.Match, error) { hits := make([]internal.Match, 0, len(searchRes.Hits)) for _, hit := range searchRes.Hits { - hit, ok := hit.(map[string]any) - if !ok { - return nil, ErrMalformedResponse - } - - issueID, ok := hit["id"].(float64) - if !ok { + var issueID int64 + if err := json.Unmarshal(hit["id"], &issueID); err != nil { return nil, ErrMalformedResponse } hits = append(hits, internal.Match{ - ID: int64(issueID), + ID: issueID, }) } return hits, nil diff --git a/modules/indexer/issues/meilisearch/meilisearch_test.go b/modules/indexer/issues/meilisearch/meilisearch_test.go index 2fea4004cb..a32cbdd6de 100644 --- a/modules/indexer/issues/meilisearch/meilisearch_test.go +++ b/modules/indexer/issues/meilisearch/meilisearch_test.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/modules/indexer/issues/internal" "code.gitea.io/gitea/modules/indexer/issues/internal/tests" + "code.gitea.io/gitea/modules/json" "github.com/meilisearch/meilisearch-go" "github.com/stretchr/testify/assert" @@ -45,30 +46,42 @@ func TestMeilisearchIndexer(t *testing.T) { } func TestConvertHits(t *testing.T) { + convert := func(d any) []byte { + b, _ := json.Marshal(d) + return b + } + _, err := convertHits(&meilisearch.SearchResponse{ - Hits: []any{"aa", "bb", "cc", "dd"}, + Hits: []meilisearch.Hit{ + { + "aa": convert(1), + "bb": convert(2), + "cc": convert(3), + "dd": convert(4), + }, + }, }) assert.ErrorIs(t, err, ErrMalformedResponse) validResponse := &meilisearch.SearchResponse{ - Hits: []any{ - map[string]any{ - "id": float64(11), - "title": "a title", - "content": "issue body with no match", - "comments": []any{"hey whats up?", "I'm currently bowling", "nice"}, + Hits: []meilisearch.Hit{ + { + "id": convert(float64(11)), + "title": convert("a title"), + "content": convert("issue body with no match"), + "comments": convert([]any{"hey whats up?", "I'm currently bowling", "nice"}), }, - map[string]any{ - "id": float64(22), - "title": "Bowling as title", - "content": "", - "comments": []any{}, + { + "id": convert(float64(22)), + "title": convert("Bowling as title"), + "content": convert(""), + "comments": convert([]any{}), }, - map[string]any{ - "id": float64(33), - "title": "Bowl-ing as fuzzy match", - "content": "", - "comments": []any{}, + { + "id": convert(float64(33)), + "title": convert("Bowl-ing as fuzzy match"), + "content": convert(""), + "comments": convert([]any{}), }, }, } diff --git a/modules/indexer/issues/util.go b/modules/indexer/issues/util.go index 19d835a1d8..7647be58e8 100644 --- a/modules/indexer/issues/util.go +++ b/modules/indexer/issues/util.go @@ -97,10 +97,14 @@ func getIssueIndexerData(ctx context.Context, issueID int64) (*internal.IndexerD return nil, false, err } + if err := issue.Repo.LoadOwner(ctx); err != nil { + return nil, false, fmt.Errorf("issue.Repo.LoadOwner: %w", err) + } + return &internal.IndexerData{ ID: issue.ID, RepoID: issue.RepoID, - IsPublic: !issue.Repo.IsPrivate, + IsPublic: !issue.Repo.IsPrivate && issue.Repo.Owner.Visibility.IsPublic(), Title: issue.Title, Content: issue.Content, Comments: comments, diff --git a/modules/indexer/stats/indexer.go b/modules/indexer/stats/indexer.go index 7ec89e2afb..aaf120c6d0 100644 --- a/modules/indexer/stats/indexer.go +++ b/modules/indexer/stats/indexer.go @@ -30,7 +30,7 @@ func Init() error { return err } - go populateRepoIndexer(db.DefaultContext) + go populateRepoIndexer(graceful.GetManager().ShutdownContext()) return nil } diff --git a/modules/indexer/stats/indexer_test.go b/modules/indexer/stats/indexer_test.go index d32a8bf151..088f63234a 100644 --- a/modules/indexer/stats/indexer_test.go +++ b/modules/indexer/stats/indexer_test.go @@ -7,7 +7,6 @@ import ( "testing" "time" - "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/queue" @@ -33,7 +32,7 @@ func TestRepoStatsIndex(t *testing.T) { err := Init() assert.NoError(t, err) - repo, err := repo_model.GetRepositoryByID(db.DefaultContext, 1) + repo, err := repo_model.GetRepositoryByID(t.Context(), 1) assert.NoError(t, err) err = UpdateRepoIndexer(repo) @@ -41,10 +40,10 @@ func TestRepoStatsIndex(t *testing.T) { assert.NoError(t, queue.GetManager().FlushAll(t.Context(), 5*time.Second)) - status, err := repo_model.GetIndexerStatus(db.DefaultContext, repo, repo_model.RepoIndexerTypeStats) + status, err := repo_model.GetIndexerStatus(t.Context(), repo, repo_model.RepoIndexerTypeStats) assert.NoError(t, err) assert.Equal(t, "65f1bf27bc3bf70f64657658635e66094edbcb4d", status.CommitSha) - langs, err := repo_model.GetTopLanguageStats(db.DefaultContext, repo, 5) + langs, err := repo_model.GetTopLanguageStats(t.Context(), repo, 5) assert.NoError(t, err) assert.Empty(t, langs) } diff --git a/modules/log/event_writer_conn_test.go b/modules/log/event_writer_conn_test.go index 2aff37812d..e7011da79c 100644 --- a/modules/log/event_writer_conn_test.go +++ b/modules/log/event_writer_conn_test.go @@ -62,11 +62,9 @@ func TestConnLogger(t *testing.T) { } expected := fmt.Sprintf("%s%s %s:%d:%s [%c] %s\n", prefix, dateString, event.Filename, event.Line, event.Caller, strings.ToUpper(event.Level.String())[0], event.MsgSimpleText) var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { listenReadAndClose(t, l, expected) - }() + }) logger.SendLogEvent(&event) wg.Wait() diff --git a/modules/markup/orgmode/orgmode_test.go b/modules/markup/orgmode/orgmode_test.go index df4bb38ad1..ebda2271f2 100644 --- a/modules/markup/orgmode/orgmode_test.go +++ b/modules/markup/orgmode/orgmode_test.go @@ -97,16 +97,10 @@ func TestRender_Source(t *testing.T) { assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) } - test(`#+begin_src go -// HelloWorld prints "Hello World" -func HelloWorld() { - fmt.Println("Hello World") -} + test(`#+begin_src c +int a; #+end_src -`, `
-
// HelloWorld prints "Hello World"
-func HelloWorld() {
-	fmt.Println("Hello World")
-}
+`, `
+
int a;
`) } diff --git a/modules/metrics/collector.go b/modules/metrics/collector.go index 4d2ec287a9..d02e5c1128 100755 --- a/modules/metrics/collector.go +++ b/modules/metrics/collector.go @@ -7,7 +7,7 @@ import ( "runtime" activities_model "code.gitea.io/gitea/models/activities" - "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/setting" "github.com/prometheus/client_golang/prometheus" @@ -233,7 +233,7 @@ func (c Collector) Describe(ch chan<- *prometheus.Desc) { // Collect returns the metrics with values func (c Collector) Collect(ch chan<- prometheus.Metric) { - stats := activities_model.GetStatistic(db.DefaultContext) + stats := activities_model.GetStatistic(graceful.GetManager().ShutdownContext()) ch <- prometheus.MustNewConstMetric( c.Accesses, diff --git a/modules/packages/swift/metadata.go b/modules/packages/swift/metadata.go index 85beb57607..78925c6e6d 100644 --- a/modules/packages/swift/metadata.go +++ b/modules/packages/swift/metadata.go @@ -82,6 +82,7 @@ type ProgrammingLanguage struct { // https://schema.org/Person type Person struct { Type string `json:"@type,omitempty"` + Name string `json:"name,omitempty"` // inherited from https://schema.org/Thing GivenName string `json:"givenName,omitempty"` MiddleName string `json:"middleName,omitempty"` FamilyName string `json:"familyName,omitempty"` @@ -184,11 +185,17 @@ func ParsePackage(sr io.ReaderAt, size int64, mr io.Reader) (*Package, error) { p.Metadata.Description = ssc.Description p.Metadata.Keywords = ssc.Keywords p.Metadata.License = ssc.License - p.Metadata.Author = Person{ + author := Person{ + Name: ssc.Author.Name, GivenName: ssc.Author.GivenName, MiddleName: ssc.Author.MiddleName, FamilyName: ssc.Author.FamilyName, } + // If Name is not provided, generate it from individual name components + if author.Name == "" { + author.Name = author.String() + } + p.Metadata.Author = author p.Metadata.RepositoryURL = ssc.CodeRepository if !validation.IsValidURL(p.Metadata.RepositoryURL) { diff --git a/modules/packages/swift/metadata_test.go b/modules/packages/swift/metadata_test.go index 3913c2355b..461773cbfc 100644 --- a/modules/packages/swift/metadata_test.go +++ b/modules/packages/swift/metadata_test.go @@ -97,10 +97,49 @@ func TestParsePackage(t *testing.T) { assert.Equal(t, packageDescription, p.Metadata.Description) assert.ElementsMatch(t, []string{"swift", "package"}, p.Metadata.Keywords) assert.Equal(t, packageLicense, p.Metadata.License) + assert.Equal(t, packageAuthor, p.Metadata.Author.Name) assert.Equal(t, packageAuthor, p.Metadata.Author.GivenName) assert.Equal(t, packageRepositoryURL, p.Metadata.RepositoryURL) assert.ElementsMatch(t, []string{packageRepositoryURL}, p.RepositoryURLs) }) + + t.Run("WithExplicitNameField", func(t *testing.T) { + data := createArchive(map[string][]byte{ + "Package.swift": []byte("// swift-tools-version:5.7\n//\n// Package.swift"), + }) + + authorName := "John Doe" + p, err := ParsePackage( + data, + data.Size(), + strings.NewReader(`{"name":"`+packageName+`","version":"`+packageVersion+`","description":"`+packageDescription+`","author":{"name":"`+authorName+`","givenName":"John","familyName":"Doe"}}`), + ) + assert.NotNil(t, p) + assert.NoError(t, err) + + assert.Equal(t, authorName, p.Metadata.Author.Name) + assert.Equal(t, "John", p.Metadata.Author.GivenName) + assert.Equal(t, "Doe", p.Metadata.Author.FamilyName) + }) + + t.Run("NameFieldGeneration", func(t *testing.T) { + data := createArchive(map[string][]byte{ + "Package.swift": []byte("// swift-tools-version:5.7\n//\n// Package.swift"), + }) + + // Test with only individual name components - Name should be auto-generated + p, err := ParsePackage( + data, + data.Size(), + strings.NewReader(`{"author":{"givenName":"John","middleName":"Q","familyName":"Doe"}}`), + ) + assert.NotNil(t, p) + assert.NoError(t, err) + assert.Equal(t, "John Q Doe", p.Metadata.Author.Name) + assert.Equal(t, "John", p.Metadata.Author.GivenName) + assert.Equal(t, "Q", p.Metadata.Author.MiddleName) + assert.Equal(t, "Doe", p.Metadata.Author.FamilyName) + }) } func TestTrimmedVersionString(t *testing.T) { @@ -142,3 +181,43 @@ func TestTrimmedVersionString(t *testing.T) { assert.Equal(t, c.Expected, TrimmedVersionString(c.Version)) } } + +func TestPersonNameString(t *testing.T) { + cases := []struct { + Name string + Person Person + Expected string + }{ + { + Name: "GivenNameOnly", + Person: Person{GivenName: "John"}, + Expected: "John", + }, + { + Name: "GivenAndFamily", + Person: Person{GivenName: "John", FamilyName: "Doe"}, + Expected: "John Doe", + }, + { + Name: "FullName", + Person: Person{GivenName: "John", MiddleName: "Q", FamilyName: "Doe"}, + Expected: "John Q Doe", + }, + { + Name: "MiddleAndFamily", + Person: Person{MiddleName: "Q", FamilyName: "Doe"}, + Expected: "Q Doe", + }, + { + Name: "Empty", + Person: Person{}, + Expected: "", + }, + } + + for _, c := range cases { + t.Run(c.Name, func(t *testing.T) { + assert.Equal(t, c.Expected, c.Person.String()) + }) + } +} diff --git a/modules/queue/workergroup.go b/modules/queue/workergroup.go index 82b0790d5a..c7e33497c6 100644 --- a/modules/queue/workergroup.go +++ b/modules/queue/workergroup.go @@ -153,11 +153,7 @@ func resetIdleTicker(t *time.Ticker, dur time.Duration) { // doStartNewWorker starts a new worker for the queue, the worker reads from worker's channel and handles the items. func (q *WorkerPoolQueue[T]) doStartNewWorker(wp *workerGroup[T]) { - wp.wg.Add(1) - - go func() { - defer wp.wg.Done() - + wp.wg.Go(func() { log.Debug("Queue %q starts new worker", q.GetName()) defer log.Debug("Queue %q stops idle worker", q.GetName()) @@ -192,7 +188,7 @@ func (q *WorkerPoolQueue[T]) doStartNewWorker(wp *workerGroup[T]) { q.workerNumMu.Unlock() } } - }() + }) } // doFlush flushes the queue: it tries to read all items from the queue and handles them. diff --git a/modules/repository/branch_test.go b/modules/repository/branch_test.go index ead28aa141..262a35fbf7 100644 --- a/modules/repository/branch_test.go +++ b/modules/repository/branch_test.go @@ -16,16 +16,16 @@ import ( func TestSyncRepoBranches(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - _, err := db.GetEngine(db.DefaultContext).ID(1).Update(&repo_model.Repository{ObjectFormatName: "bad-fmt"}) - assert.NoError(t, db.TruncateBeans(db.DefaultContext, &git_model.Branch{})) + _, err := db.GetEngine(t.Context()).ID(1).Update(&repo_model.Repository{ObjectFormatName: "bad-fmt"}) + assert.NoError(t, db.TruncateBeans(t.Context(), &git_model.Branch{})) assert.NoError(t, err) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) assert.Equal(t, "bad-fmt", repo.ObjectFormatName) - _, err = SyncRepoBranches(db.DefaultContext, 1, 0) + _, err = SyncRepoBranches(t.Context(), 1, 0) assert.NoError(t, err) repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) assert.Equal(t, "sha1", repo.ObjectFormatName) - branch, err := git_model.GetBranch(db.DefaultContext, 1, "master") + branch, err := git_model.GetBranch(t.Context(), 1, "master") assert.NoError(t, err) assert.Equal(t, "master", branch.Name) } diff --git a/modules/repository/commits_test.go b/modules/repository/commits_test.go index 030cd7714d..04c0711828 100644 --- a/modules/repository/commits_test.go +++ b/modules/repository/commits_test.go @@ -8,7 +8,6 @@ import ( "testing" "time" - "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/git" @@ -50,7 +49,7 @@ func TestPushCommits_ToAPIPayloadCommits(t *testing.T) { pushCommits.HeadCommit = &PushCommit{Sha1: "69554a6"} repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) - payloadCommits, headCommit, err := pushCommits.ToAPIPayloadCommits(git.DefaultContext, repo) + payloadCommits, headCommit, err := pushCommits.ToAPIPayloadCommits(t.Context(), repo) assert.NoError(t, err) assert.Len(t, payloadCommits, 3) assert.NotNil(t, headCommit) @@ -125,11 +124,11 @@ func TestPushCommits_AvatarLink(t *testing.T) { assert.Equal(t, "/avatars/ab53a2911ddf9b4817ac01ddcd3d975f?size="+strconv.Itoa(28*setting.Avatar.RenderedSizeFactor), - pushCommits.AvatarLink(db.DefaultContext, "user2@example.com")) + pushCommits.AvatarLink(t.Context(), "user2@example.com")) assert.Equal(t, "/assets/img/avatar_default.png", - pushCommits.AvatarLink(db.DefaultContext, "nonexistent@example.com")) + pushCommits.AvatarLink(t.Context(), "nonexistent@example.com")) } func TestCommitToPushCommit(t *testing.T) { diff --git a/modules/repository/create_test.go b/modules/repository/create_test.go index b85a10adad..68b0f4dea1 100644 --- a/modules/repository/create_test.go +++ b/modules/repository/create_test.go @@ -6,7 +6,6 @@ package repository import ( "testing" - "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -15,7 +14,7 @@ import ( func TestGetDirectorySize(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - repo, err := repo_model.GetRepositoryByID(db.DefaultContext, 1) + repo, err := repo_model.GetRepositoryByID(t.Context(), 1) assert.NoError(t, err) size, err := getDirectorySize(repo.RepoPath()) assert.NoError(t, err) diff --git a/modules/session/db.go b/modules/session/db.go index 9909f2dc1e..7b5be1bc70 100644 --- a/modules/session/db.go +++ b/modules/session/db.go @@ -4,11 +4,11 @@ package session import ( + "context" "log" "sync" "code.gitea.io/gitea/models/auth" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/timeutil" "gitea.com/go-chi/session" @@ -21,6 +21,10 @@ type DBStore struct { data map[any]any } +func dbContext() context.Context { + return context.Background() +} + // NewDBStore creates and returns a DB session store. func NewDBStore(sid string, kv map[any]any) *DBStore { return &DBStore{ @@ -72,7 +76,7 @@ func (s *DBStore) Release() error { return err } - return auth.UpdateSession(db.DefaultContext, s.sid, data) + return auth.UpdateSession(dbContext(), s.sid, data) } // Flush deletes all session data. @@ -98,7 +102,7 @@ func (p *DBProvider) Init(maxLifetime int64, connStr string) error { // Read returns raw session store by session ID. func (p *DBProvider) Read(sid string) (session.RawStore, error) { - s, err := auth.ReadSession(db.DefaultContext, sid) + s, err := auth.ReadSession(dbContext(), sid) if err != nil { return nil, err } @@ -118,7 +122,7 @@ func (p *DBProvider) Read(sid string) (session.RawStore, error) { // Exist returns true if session with given ID exists. func (p *DBProvider) Exist(sid string) bool { - has, err := auth.ExistSession(db.DefaultContext, sid) + has, err := auth.ExistSession(dbContext(), sid) if err != nil { panic("session/DB: error checking existence: " + err.Error()) } @@ -127,12 +131,12 @@ func (p *DBProvider) Exist(sid string) bool { // Destroy deletes a session by session ID. func (p *DBProvider) Destroy(sid string) error { - return auth.DestroySession(db.DefaultContext, sid) + return auth.DestroySession(dbContext(), sid) } // Regenerate regenerates a session store from old session ID to new one. func (p *DBProvider) Regenerate(oldsid, sid string) (_ session.RawStore, err error) { - s, err := auth.RegenerateSession(db.DefaultContext, oldsid, sid) + s, err := auth.RegenerateSession(dbContext(), oldsid, sid) if err != nil { return nil, err } @@ -152,7 +156,7 @@ func (p *DBProvider) Regenerate(oldsid, sid string) (_ session.RawStore, err err // Count counts and returns number of sessions. func (p *DBProvider) Count() int { - total, err := auth.CountSessions(db.DefaultContext) + total, err := auth.CountSessions(dbContext()) if err != nil { panic("session/DB: error counting records: " + err.Error()) } @@ -161,7 +165,7 @@ func (p *DBProvider) Count() int { // GC calls GC to clean expired sessions. func (p *DBProvider) GC() { - if err := auth.CleanupSessions(db.DefaultContext, p.maxLifetime); err != nil { + if err := auth.CleanupSessions(dbContext(), p.maxLifetime); err != nil { log.Printf("session/DB: error garbage collecting: %v", err) } } diff --git a/modules/setting/actions.go b/modules/setting/actions.go index 8bace1f750..34346b62cf 100644 --- a/modules/setting/actions.go +++ b/modules/setting/actions.go @@ -24,7 +24,7 @@ var ( ZombieTaskTimeout time.Duration `ini:"ZOMBIE_TASK_TIMEOUT"` EndlessTaskTimeout time.Duration `ini:"ENDLESS_TASK_TIMEOUT"` AbandonedJobTimeout time.Duration `ini:"ABANDONED_JOB_TIMEOUT"` - SkipWorkflowStrings []string `ìni:"SKIP_WORKFLOW_STRINGS"` + SkipWorkflowStrings []string `ini:"SKIP_WORKFLOW_STRINGS"` }{ Enabled: true, DefaultActionsURL: defaultActionsURLGitHub, diff --git a/modules/setting/config.go b/modules/setting/config.go index 03558574c2..4c5d2df7d8 100644 --- a/modules/setting/config.go +++ b/modules/setting/config.go @@ -49,6 +49,7 @@ func DefaultOpenWithEditorApps() OpenWithEditorAppsType { type RepositoryStruct struct { OpenWithEditorApps *config.Value[OpenWithEditorAppsType] + GitGuideRemoteName *config.Value[string] } type ConfigStruct struct { @@ -70,6 +71,7 @@ func initDefaultConfig() { }, Repository: &RepositoryStruct{ OpenWithEditorApps: config.ValueJSON[OpenWithEditorAppsType]("repository.open-with.editor-apps"), + GitGuideRemoteName: config.ValueJSON[string]("repository.git-guide-remote-name").WithDefault("origin"), }, } } diff --git a/modules/setting/config/value.go b/modules/setting/config/value.go index f0ec120544..301c60f5e8 100644 --- a/modules/setting/config/value.go +++ b/modules/setting/config/value.go @@ -46,7 +46,7 @@ func (value *Value[T]) Value(ctx context.Context) (v T) { rev := dg.GetRevision(ctx) - // if the revision in database doesn't change, use the last value + // if the revision in the database doesn't change, use the last value value.mu.RLock() if rev == value.revision { v = value.value @@ -84,6 +84,10 @@ func (value *Value[T]) WithDefault(def T) *Value[T] { return value } +func (value *Value[T]) DefaultValue() T { + return value.def +} + func (value *Value[T]) WithFileConfig(cfgSecKey CfgSecKey) *Value[T] { value.cfgSecKey = cfgSecKey return value diff --git a/modules/setting/cron_test.go b/modules/setting/cron_test.go index 39a228068a..53996b5de9 100644 --- a/modules/setting/cron_test.go +++ b/modules/setting/cron_test.go @@ -41,3 +41,56 @@ EXTEND = true assert.Equal(t, "white rabbit", extended.Second) assert.True(t, extended.Extend) } + +// Test_getCronSettings2 tests that getCronSettings can not handle two levels of embedding +func Test_getCronSettings2(t *testing.T) { + type BaseStruct struct { + Enabled bool + RunAtStart bool + Schedule string + } + + type Extended struct { + BaseStruct + Extend bool + } + type Extended2 struct { + Extended + Third string + } + + iniStr := ` +[cron.test] +ENABLED = TRUE +RUN_AT_START = TRUE +SCHEDULE = @every 1h +EXTEND = true +THIRD = white rabbit +` + cfg, err := NewConfigProviderFromData(iniStr) + assert.NoError(t, err) + + extended := &Extended2{ + Extended: Extended{ + BaseStruct: BaseStruct{ + Enabled: false, + RunAtStart: false, + Schedule: "@every 72h", + }, + Extend: false, + }, + Third: "black rabbit", + } + + _, err = getCronSettings(cfg, "test", extended) + assert.NoError(t, err) + + // This confirms the first level of embedding works + assert.Equal(t, "white rabbit", extended.Third) + assert.True(t, extended.Extend) + + // This confirms 2 levels of embedding doesn't work + assert.False(t, extended.Enabled) + assert.False(t, extended.RunAtStart) + assert.Equal(t, "@every 72h", extended.Schedule) +} diff --git a/modules/structs/activity.go b/modules/structs/activity.go index ea27fbfd77..9085495593 100644 --- a/modules/structs/activity.go +++ b/modules/structs/activity.go @@ -6,20 +6,32 @@ package structs import "time" type Activity struct { - ID int64 `json:"id"` + // The unique identifier of the activity + ID int64 `json:"id"` + // The ID of the user who receives/sees this activity UserID int64 `json:"user_id"` // Receiver user // the type of action // // enum: create_repo,rename_repo,star_repo,watch_repo,commit_repo,create_issue,create_pull_request,transfer_repo,push_tag,comment_issue,merge_pull_request,close_issue,reopen_issue,close_pull_request,reopen_pull_request,delete_tag,delete_branch,mirror_sync_push,mirror_sync_create,mirror_sync_delete,approve_pull_request,reject_pull_request,comment_pull,publish_release,pull_review_dismissed,pull_request_ready_for_review,auto_merge_pull_request - OpType string `json:"op_type"` - ActUserID int64 `json:"act_user_id"` - ActUser *User `json:"act_user"` - RepoID int64 `json:"repo_id"` - Repo *Repository `json:"repo"` - CommentID int64 `json:"comment_id"` - Comment *Comment `json:"comment"` - RefName string `json:"ref_name"` - IsPrivate bool `json:"is_private"` - Content string `json:"content"` - Created time.Time `json:"created"` + OpType string `json:"op_type"` + // The ID of the user who performed the action + ActUserID int64 `json:"act_user_id"` + // The user who performed the action + ActUser *User `json:"act_user"` + // The ID of the repository associated with the activity + RepoID int64 `json:"repo_id"` + // The repository associated with the activity + Repo *Repository `json:"repo"` + // The ID of the comment associated with the activity (if applicable) + CommentID int64 `json:"comment_id"` + // The comment associated with the activity (if applicable) + Comment *Comment `json:"comment"` + // The name of the git reference (branch/tag) associated with the activity + RefName string `json:"ref_name"` + // Whether this activity is from a private repository + IsPrivate bool `json:"is_private"` + // Additional content or details about the activity + Content string `json:"content"` + // The date and time when the activity occurred + Created time.Time `json:"created"` } diff --git a/modules/structs/activitypub.go b/modules/structs/activitypub.go index 117eb0bed2..39a6c1ac2a 100644 --- a/modules/structs/activitypub.go +++ b/modules/structs/activitypub.go @@ -5,5 +5,6 @@ package structs // ActivityPub type type ActivityPub struct { + // Context defines the JSON-LD context for ActivityPub Context string `json:"@context"` } diff --git a/modules/structs/admin_user.go b/modules/structs/admin_user.go index c68b59a897..d158a5fd31 100644 --- a/modules/structs/admin_user.go +++ b/modules/structs/admin_user.go @@ -8,6 +8,7 @@ import "time" // CreateUserOption create user options type CreateUserOption struct { + // The authentication source ID to associate with the user SourceID int64 `json:"source_id"` // identifier of the user, provided by the external authenticator (if configured) // default: empty @@ -15,15 +16,21 @@ type CreateUserOption struct { // username of the user // required: true Username string `json:"username" binding:"Required;Username;MaxSize(40)"` + // The full display name of the user FullName string `json:"full_name" binding:"MaxSize(100)"` // required: true // swagger:strfmt email - Email string `json:"email" binding:"Required;Email;MaxSize(254)"` - Password string `json:"password" binding:"MaxSize(255)"` - MustChangePassword *bool `json:"must_change_password"` - SendNotify bool `json:"send_notify"` - Restricted *bool `json:"restricted"` - Visibility string `json:"visibility" binding:"In(,public,limited,private)"` + Email string `json:"email" binding:"Required;Email;MaxSize(254)"` + // The plain text password for the user + Password string `json:"password" binding:"MaxSize(255)"` + // Whether the user must change password on first login + MustChangePassword *bool `json:"must_change_password"` + // Whether to send welcome notification email to the user + SendNotify bool `json:"send_notify"` + // Whether the user has restricted access privileges + Restricted *bool `json:"restricted"` + // User visibility level: public, limited, or private + Visibility string `json:"visibility" binding:"In(,public,limited,private)"` // For explicitly setting the user creation timestamp. Useful when users are // migrated from other systems. When omitted, the user's creation timestamp @@ -34,26 +41,43 @@ type CreateUserOption struct { // EditUserOption edit user options type EditUserOption struct { // required: true + // The authentication source ID to associate with the user SourceID int64 `json:"source_id"` // identifier of the user, provided by the external authenticator (if configured) // default: empty // required: true LoginName string `json:"login_name" binding:"Required"` // swagger:strfmt email - Email *string `json:"email" binding:"MaxSize(254)"` - FullName *string `json:"full_name" binding:"MaxSize(100)"` - Password string `json:"password" binding:"MaxSize(255)"` - MustChangePassword *bool `json:"must_change_password"` - Website *string `json:"website" binding:"OmitEmpty;ValidUrl;MaxSize(255)"` - Location *string `json:"location" binding:"MaxSize(50)"` - Description *string `json:"description" binding:"MaxSize(255)"` - Active *bool `json:"active"` - Admin *bool `json:"admin"` - AllowGitHook *bool `json:"allow_git_hook"` - AllowImportLocal *bool `json:"allow_import_local"` - MaxRepoCreation *int `json:"max_repo_creation"` - ProhibitLogin *bool `json:"prohibit_login"` - AllowCreateOrganization *bool `json:"allow_create_organization"` - Restricted *bool `json:"restricted"` - Visibility string `json:"visibility" binding:"In(,public,limited,private)"` + // The email address of the user + Email *string `json:"email" binding:"MaxSize(254)"` + // The full display name of the user + FullName *string `json:"full_name" binding:"MaxSize(100)"` + // The plain text password for the user + Password string `json:"password" binding:"MaxSize(255)"` + // Whether the user must change password on next login + MustChangePassword *bool `json:"must_change_password"` + // The user's personal website URL + Website *string `json:"website" binding:"OmitEmpty;ValidUrl;MaxSize(255)"` + // The user's location or address + Location *string `json:"location" binding:"MaxSize(50)"` + // The user's personal description or bio + Description *string `json:"description" binding:"MaxSize(255)"` + // Whether the user account is active + Active *bool `json:"active"` + // Whether the user has administrator privileges + Admin *bool `json:"admin"` + // Whether the user can use Git hooks + AllowGitHook *bool `json:"allow_git_hook"` + // Whether the user can import local repositories + AllowImportLocal *bool `json:"allow_import_local"` + // Maximum number of repositories the user can create + MaxRepoCreation *int `json:"max_repo_creation"` + // Whether the user is prohibited from logging in + ProhibitLogin *bool `json:"prohibit_login"` + // Whether the user can create organizations + AllowCreateOrganization *bool `json:"allow_create_organization"` + // Whether the user has restricted access privileges + Restricted *bool `json:"restricted"` + // User visibility level: public, limited, or private + Visibility string `json:"visibility" binding:"In(,public,limited,private)"` } diff --git a/modules/structs/attachment.go b/modules/structs/attachment.go index 38beca5e99..e9499d2ee7 100644 --- a/modules/structs/attachment.go +++ b/modules/structs/attachment.go @@ -10,18 +10,26 @@ import ( // Attachment a generic attachment // swagger:model type Attachment struct { - ID int64 `json:"id"` - Name string `json:"name"` - Size int64 `json:"size"` - DownloadCount int64 `json:"download_count"` + // ID is the unique identifier for the attachment + ID int64 `json:"id"` + // Name is the filename of the attachment + Name string `json:"name"` + // Size is the file size in bytes + Size int64 `json:"size"` + // DownloadCount is the number of times the attachment has been downloaded + DownloadCount int64 `json:"download_count"` // swagger:strfmt date-time - Created time.Time `json:"created_at"` - UUID string `json:"uuid"` - DownloadURL string `json:"browser_download_url"` + // Created is the time when the attachment was uploaded + Created time.Time `json:"created_at"` + // UUID is the unique identifier for the attachment file + UUID string `json:"uuid"` + // DownloadURL is the URL to download the attachment + DownloadURL string `json:"browser_download_url"` } // EditAttachmentOptions options for editing attachments // swagger:model type EditAttachmentOptions struct { + // Name is the new filename for the attachment Name string `json:"name"` } diff --git a/modules/structs/cron.go b/modules/structs/cron.go index 39c6a06a42..49fc463808 100644 --- a/modules/structs/cron.go +++ b/modules/structs/cron.go @@ -7,9 +7,14 @@ import "time" // Cron represents a Cron task type Cron struct { - Name string `json:"name"` - Schedule string `json:"schedule"` - Next time.Time `json:"next"` - Prev time.Time `json:"prev"` - ExecTimes int64 `json:"exec_times"` + // The name of the cron task + Name string `json:"name"` + // The cron schedule expression (e.g., "0 0 * * *") + Schedule string `json:"schedule"` + // The next scheduled execution time + Next time.Time `json:"next"` + // The previous execution time + Prev time.Time `json:"prev"` + // The total number of times this cron task has been executed + ExecTimes int64 `json:"exec_times"` } diff --git a/modules/structs/git_blob.go b/modules/structs/git_blob.go index 643b69ed37..3c12eb8fb3 100644 --- a/modules/structs/git_blob.go +++ b/modules/structs/git_blob.go @@ -5,12 +5,19 @@ package structs // GitBlobResponse represents a git blob type GitBlobResponse struct { - Content *string `json:"content"` + // The content of the git blob (may be base64 encoded) + Content *string `json:"content"` + // The encoding used for the content (e.g., "base64") Encoding *string `json:"encoding"` - URL string `json:"url"` - SHA string `json:"sha"` - Size int64 `json:"size"` + // The URL to access this git blob + URL string `json:"url"` + // The SHA hash of the git blob + SHA string `json:"sha"` + // The size of the git blob in bytes + Size int64 `json:"size"` - LfsOid *string `json:"lfs_oid,omitempty"` - LfsSize *int64 `json:"lfs_size,omitempty"` + // The LFS object ID if this blob is stored in LFS + LfsOid *string `json:"lfs_oid,omitempty"` + // The size of the LFS object if this blob is stored in LFS + LfsSize *int64 `json:"lfs_size,omitempty"` } diff --git a/modules/structs/git_hook.go b/modules/structs/git_hook.go index 20230250ec..c11e2acbdc 100644 --- a/modules/structs/git_hook.go +++ b/modules/structs/git_hook.go @@ -5,9 +5,12 @@ package structs // GitHook represents a Git repository hook type GitHook struct { - Name string `json:"name"` - IsActive bool `json:"is_active"` - Content string `json:"content,omitempty"` + // Name is the name of the Git hook + Name string `json:"name"` + // IsActive indicates if the hook is active + IsActive bool `json:"is_active"` + // Content contains the script content of the hook + Content string `json:"content,omitempty"` } // GitHookList represents a list of Git hooks @@ -15,5 +18,6 @@ type GitHookList []*GitHook // EditGitHookOption options when modifying one Git hook type EditGitHookOption struct { + // Content is the new script content for the hook Content string `json:"content"` } diff --git a/modules/structs/hook.go b/modules/structs/hook.go index ac779a5740..776e44ccec 100644 --- a/modules/structs/hook.go +++ b/modules/structs/hook.go @@ -17,17 +17,27 @@ var ErrInvalidReceiveHook = errors.New("Invalid JSON payload received over webho // Hook a hook is a web hook when one repository changed type Hook struct { - ID int64 `json:"id"` - Type string `json:"type"` - BranchFilter string `json:"branch_filter"` - URL string `json:"-"` - Config map[string]string `json:"config"` - Events []string `json:"events"` - AuthorizationHeader string `json:"authorization_header"` - Active bool `json:"active"` + // The unique identifier of the webhook + ID int64 `json:"id"` + // The type of the webhook (e.g., gitea, slack, discord) + Type string `json:"type"` + // Branch filter pattern to determine which branches trigger the webhook + BranchFilter string `json:"branch_filter"` + // The URL of the webhook endpoint (hidden in JSON) + URL string `json:"-"` + // Configuration settings for the webhook + Config map[string]string `json:"config"` + // List of events that trigger this webhook + Events []string `json:"events"` + // Authorization header to include in webhook requests + AuthorizationHeader string `json:"authorization_header"` + // Whether the webhook is active and will be triggered + Active bool `json:"active"` // swagger:strfmt date-time + // The date and time when the webhook was last updated Updated time.Time `json:"updated_at"` // swagger:strfmt date-time + // The date and time when the webhook was created Created time.Time `json:"created_at"` } @@ -42,23 +52,34 @@ type CreateHookOptionConfig map[string]string type CreateHookOption struct { // required: true // enum: dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu,wechatwork,packagist + // The type of the webhook to create Type string `json:"type" binding:"Required"` // required: true - Config CreateHookOptionConfig `json:"config" binding:"Required"` - Events []string `json:"events"` - BranchFilter string `json:"branch_filter" binding:"GlobPattern"` - AuthorizationHeader string `json:"authorization_header"` + // Configuration settings for the webhook + Config CreateHookOptionConfig `json:"config" binding:"Required"` + // List of events that will trigger this webhook + Events []string `json:"events"` + // Branch filter pattern to determine which branches trigger the webhook + BranchFilter string `json:"branch_filter" binding:"GlobPattern"` + // Authorization header to include in webhook requests + AuthorizationHeader string `json:"authorization_header"` // default: false + // Whether the webhook should be active upon creation Active bool `json:"active"` } // EditHookOption options when modify one hook type EditHookOption struct { - Config map[string]string `json:"config"` - Events []string `json:"events"` - BranchFilter string `json:"branch_filter" binding:"GlobPattern"` - AuthorizationHeader string `json:"authorization_header"` - Active *bool `json:"active"` + // Configuration settings for the webhook + Config map[string]string `json:"config"` + // List of events that trigger this webhook + Events []string `json:"events"` + // Branch filter pattern to determine which branches trigger the webhook + BranchFilter string `json:"branch_filter" binding:"GlobPattern"` + // Authorization header to include in webhook requests + AuthorizationHeader string `json:"authorization_header"` + // Whether the webhook is active and will be triggered + Active *bool `json:"active"` } // Payloader payload is some part of one hook @@ -82,26 +103,40 @@ type PayloadUser struct { // PayloadCommit represents a commit type PayloadCommit struct { // sha1 hash of the commit - ID string `json:"id"` - Message string `json:"message"` - URL string `json:"url"` - Author *PayloadUser `json:"author"` - Committer *PayloadUser `json:"committer"` + ID string `json:"id"` + // The commit message + Message string `json:"message"` + // The URL to view this commit + URL string `json:"url"` + // The author of the commit + Author *PayloadUser `json:"author"` + // The committer of the commit + Committer *PayloadUser `json:"committer"` + // GPG verification information for the commit Verification *PayloadCommitVerification `json:"verification"` // swagger:strfmt date-time + // The timestamp when the commit was made Timestamp time.Time `json:"timestamp"` - Added []string `json:"added"` - Removed []string `json:"removed"` - Modified []string `json:"modified"` + // List of files added in this commit + Added []string `json:"added"` + // List of files removed in this commit + Removed []string `json:"removed"` + // List of files modified in this commit + Modified []string `json:"modified"` } // PayloadCommitVerification represents the GPG verification of a commit type PayloadCommitVerification struct { - Verified bool `json:"verified"` - Reason string `json:"reason"` - Signature string `json:"signature"` - Signer *PayloadUser `json:"signer"` - Payload string `json:"payload"` + // Whether the commit signature is verified + Verified bool `json:"verified"` + // The reason for the verification status + Reason string `json:"reason"` + // The GPG signature of the commit + Signature string `json:"signature"` + // The user who signed the commit + Signer *PayloadUser `json:"signer"` + // The signed payload content + Payload string `json:"payload"` } var ( @@ -119,11 +154,16 @@ var ( // CreatePayload represents a payload information of create event. type CreatePayload struct { - Sha string `json:"sha"` - Ref string `json:"ref"` - RefType string `json:"ref_type"` - Repo *Repository `json:"repository"` - Sender *User `json:"sender"` + // The SHA hash of the created reference + Sha string `json:"sha"` + // The full name of the created reference + Ref string `json:"ref"` + // The type of reference created (branch or tag) + RefType string `json:"ref_type"` + // The repository where the reference was created + Repo *Repository `json:"repository"` + // The user who created the reference + Sender *User `json:"sender"` } // JSONPayload return payload information @@ -161,11 +201,16 @@ const ( // DeletePayload represents delete payload type DeletePayload struct { - Ref string `json:"ref"` - RefType string `json:"ref_type"` - PusherType PusherType `json:"pusher_type"` - Repo *Repository `json:"repository"` - Sender *User `json:"sender"` + // The name of the deleted reference + Ref string `json:"ref"` + // The type of reference deleted (branch or tag) + RefType string `json:"ref_type"` + // The type of entity that performed the deletion + PusherType PusherType `json:"pusher_type"` + // The repository where the reference was deleted + Repo *Repository `json:"repository"` + // The user who deleted the reference + Sender *User `json:"sender"` } // JSONPayload implements Payload @@ -175,9 +220,12 @@ func (p *DeletePayload) JSONPayload() ([]byte, error) { // ForkPayload represents fork payload type ForkPayload struct { + // The forked repository (the new fork) Forkee *Repository `json:"forkee"` - Repo *Repository `json:"repository"` - Sender *User `json:"sender"` + // The original repository that was forked + Repo *Repository `json:"repository"` + // The user who created the fork + Sender *User `json:"sender"` } // JSONPayload implements Payload @@ -197,14 +245,22 @@ const ( // IssueCommentPayload represents a payload information of issue comment event. type IssueCommentPayload struct { - Action HookIssueCommentAction `json:"action"` - Issue *Issue `json:"issue"` - PullRequest *PullRequest `json:"pull_request,omitempty"` - Comment *Comment `json:"comment"` - Changes *ChangesPayload `json:"changes,omitempty"` - Repository *Repository `json:"repository"` - Sender *User `json:"sender"` - IsPull bool `json:"is_pull"` + // The action performed on the comment (created, edited, deleted) + Action HookIssueCommentAction `json:"action"` + // The issue that the comment belongs to + Issue *Issue `json:"issue"` + // The pull request if the comment is on a pull request + PullRequest *PullRequest `json:"pull_request,omitempty"` + // The comment that was acted upon + Comment *Comment `json:"comment"` + // Changes made to the comment (for edit actions) + Changes *ChangesPayload `json:"changes,omitempty"` + // The repository containing the issue/pull request + Repository *Repository `json:"repository"` + // The user who performed the action + Sender *User `json:"sender"` + // Whether this comment is on a pull request + IsPull bool `json:"is_pull"` } // JSONPayload implements Payload @@ -224,10 +280,14 @@ const ( // ReleasePayload represents a payload information of release event. type ReleasePayload struct { - Action HookReleaseAction `json:"action"` - Release *Release `json:"release"` - Repository *Repository `json:"repository"` - Sender *User `json:"sender"` + // The action performed on the release (published, updated, deleted) + Action HookReleaseAction `json:"action"` + // The release that was acted upon + Release *Release `json:"release"` + // The repository containing the release + Repository *Repository `json:"repository"` + // The user who performed the action + Sender *User `json:"sender"` } // JSONPayload implements Payload @@ -237,16 +297,26 @@ func (p *ReleasePayload) JSONPayload() ([]byte, error) { // PushPayload represents a payload information of push event. type PushPayload struct { - Ref string `json:"ref"` - Before string `json:"before"` - After string `json:"after"` - CompareURL string `json:"compare_url"` - Commits []*PayloadCommit `json:"commits"` - TotalCommits int `json:"total_commits"` - HeadCommit *PayloadCommit `json:"head_commit"` - Repo *Repository `json:"repository"` - Pusher *User `json:"pusher"` - Sender *User `json:"sender"` + // The full name of the pushed reference + Ref string `json:"ref"` + // The SHA of the most recent commit before the push + Before string `json:"before"` + // The SHA of the most recent commit after the push + After string `json:"after"` + // URL to compare the changes in this push + CompareURL string `json:"compare_url"` + // List of commits included in the push + Commits []*PayloadCommit `json:"commits"` + // Total number of commits in the push + TotalCommits int `json:"total_commits"` + // The most recent commit in the push + HeadCommit *PayloadCommit `json:"head_commit"` + // The repository that was pushed to + Repo *Repository `json:"repository"` + // The user who performed the push + Pusher *User `json:"pusher"` + // The user who triggered the webhook + Sender *User `json:"sender"` } // JSONPayload FIXME @@ -313,13 +383,20 @@ const ( // IssuePayload represents the payload information that is sent along with an issue event. type IssuePayload struct { - Action HookIssueAction `json:"action"` - Index int64 `json:"number"` - Changes *ChangesPayload `json:"changes,omitempty"` - Issue *Issue `json:"issue"` - Repository *Repository `json:"repository"` - Sender *User `json:"sender"` - CommitID string `json:"commit_id"` + // The action performed on the issue + Action HookIssueAction `json:"action"` + // The index number of the issue + Index int64 `json:"number"` + // Changes made to the issue (for edit actions) + Changes *ChangesPayload `json:"changes,omitempty"` + // The issue that was acted upon + Issue *Issue `json:"issue"` + // The repository containing the issue + Repository *Repository `json:"repository"` + // The user who performed the action + Sender *User `json:"sender"` + // The commit ID related to the issue action + CommitID string `json:"commit_id"` } // JSONPayload encodes the IssuePayload to JSON, with an indentation of two spaces. @@ -329,27 +406,40 @@ func (p *IssuePayload) JSONPayload() ([]byte, error) { // ChangesFromPayload FIXME type ChangesFromPayload struct { + // The previous value before the change From string `json:"from"` } // ChangesPayload represents the payload information of issue change type ChangesPayload struct { + // Changes made to the title Title *ChangesFromPayload `json:"title,omitempty"` - Body *ChangesFromPayload `json:"body,omitempty"` - Ref *ChangesFromPayload `json:"ref,omitempty"` + // Changes made to the body/description + Body *ChangesFromPayload `json:"body,omitempty"` + // Changes made to the reference + Ref *ChangesFromPayload `json:"ref,omitempty"` } // PullRequestPayload represents a payload information of pull request event. type PullRequestPayload struct { - Action HookIssueAction `json:"action"` - Index int64 `json:"number"` - Changes *ChangesPayload `json:"changes,omitempty"` - PullRequest *PullRequest `json:"pull_request"` - RequestedReviewer *User `json:"requested_reviewer"` - Repository *Repository `json:"repository"` - Sender *User `json:"sender"` - CommitID string `json:"commit_id"` - Review *ReviewPayload `json:"review"` + // The action performed on the pull request + Action HookIssueAction `json:"action"` + // The index number of the pull request + Index int64 `json:"number"` + // Changes made to the pull request (for edit actions) + Changes *ChangesPayload `json:"changes,omitempty"` + // The pull request that was acted upon + PullRequest *PullRequest `json:"pull_request"` + // The reviewer that was requested (for review request actions) + RequestedReviewer *User `json:"requested_reviewer"` + // The repository containing the pull request + Repository *Repository `json:"repository"` + // The user who performed the action + Sender *User `json:"sender"` + // The commit ID related to the pull request action + CommitID string `json:"commit_id"` + // The review information (for review actions) + Review *ReviewPayload `json:"review"` } // JSONPayload FIXME @@ -359,7 +449,9 @@ func (p *PullRequestPayload) JSONPayload() ([]byte, error) { // ReviewPayload FIXME type ReviewPayload struct { - Type string `json:"type"` + // The type of review (approved, rejected, comment) + Type string `json:"type"` + // The content/body of the review Content string `json:"content"` } @@ -377,11 +469,16 @@ const ( // 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"` + // The action performed on the wiki page + Action HookWikiAction `json:"action"` + // The repository containing the wiki + Repository *Repository `json:"repository"` + // The user who performed the action + Sender *User `json:"sender"` + // The name of the wiki page + Page string `json:"page"` + // The comment/commit message for the wiki change + Comment string `json:"comment"` } // JSONPayload JSON representation of the payload @@ -401,10 +498,14 @@ const ( // RepositoryPayload payload for repository webhooks type RepositoryPayload struct { - Action HookRepoAction `json:"action"` - Repository *Repository `json:"repository"` - Organization *User `json:"organization"` - Sender *User `json:"sender"` + // The action performed on the repository + Action HookRepoAction `json:"action"` + // The repository that was acted upon + Repository *Repository `json:"repository"` + // The organization that owns the repository (if applicable) + Organization *User `json:"organization"` + // The user who performed the action + Sender *User `json:"sender"` } // JSONPayload JSON representation of the payload @@ -424,11 +525,16 @@ const ( // PackagePayload represents a package payload type PackagePayload struct { - Action HookPackageAction `json:"action"` - Repository *Repository `json:"repository"` - Package *Package `json:"package"` - Organization *Organization `json:"organization"` - Sender *User `json:"sender"` + // The action performed on the package + Action HookPackageAction `json:"action"` + // The repository associated with the package + Repository *Repository `json:"repository"` + // The package that was acted upon + Package *Package `json:"package"` + // The organization that owns the package (if applicable) + Organization *Organization `json:"organization"` + // The user who performed the action + Sender *User `json:"sender"` } // JSONPayload implements Payload @@ -438,11 +544,16 @@ func (p *PackagePayload) JSONPayload() ([]byte, error) { // WorkflowDispatchPayload represents a workflow dispatch payload type WorkflowDispatchPayload struct { - Workflow string `json:"workflow"` - Ref string `json:"ref"` - Inputs map[string]any `json:"inputs"` - Repository *Repository `json:"repository"` - Sender *User `json:"sender"` + // The name or path of the workflow file + Workflow string `json:"workflow"` + // The git reference (branch, tag, or commit SHA) to run the workflow on + Ref string `json:"ref"` + // Input parameters for the workflow dispatch event + Inputs map[string]any `json:"inputs"` + // The repository containing the workflow + Repository *Repository `json:"repository"` + // The user who triggered the workflow dispatch + Sender *User `json:"sender"` } // JSONPayload implements Payload @@ -453,18 +564,29 @@ func (p *WorkflowDispatchPayload) JSONPayload() ([]byte, error) { // CommitStatusPayload represents a payload information of commit status event. type CommitStatusPayload struct { // TODO: add Branches per https://docs.github.com/en/webhooks/webhook-events-and-payloads#status - Commit *PayloadCommit `json:"commit"` - Context string `json:"context"` + // The commit that the status is associated with + Commit *PayloadCommit `json:"commit"` + // The context/identifier for this status check + Context string `json:"context"` // swagger:strfmt date-time - CreatedAt time.Time `json:"created_at"` - Description string `json:"description"` - ID int64 `json:"id"` - Repo *Repository `json:"repository"` - Sender *User `json:"sender"` - SHA string `json:"sha"` - State string `json:"state"` - TargetURL string `json:"target_url"` + // The date and time when the status was created + CreatedAt time.Time `json:"created_at"` + // A short description of the status + Description string `json:"description"` + // The unique identifier of the status + ID int64 `json:"id"` + // The repository containing the commit + Repo *Repository `json:"repository"` + // The user who created the status + Sender *User `json:"sender"` + // The SHA hash of the commit + SHA string `json:"sha"` + // The state of the status (pending, success, error, failure) + State string `json:"state"` + // The target URL to associate with this status + TargetURL string `json:"target_url"` // swagger:strfmt date-time + // The date and time when the status was last updated UpdatedAt *time.Time `json:"updated_at"` } @@ -475,13 +597,20 @@ func (p *CommitStatusPayload) JSONPayload() ([]byte, error) { // WorkflowRunPayload represents a payload information of workflow run event. type WorkflowRunPayload struct { - Action string `json:"action"` - Workflow *ActionWorkflow `json:"workflow"` - WorkflowRun *ActionWorkflowRun `json:"workflow_run"` - PullRequest *PullRequest `json:"pull_request,omitempty"` - Organization *Organization `json:"organization,omitempty"` - Repo *Repository `json:"repository"` - Sender *User `json:"sender"` + // The action performed on the workflow run + Action string `json:"action"` + // The workflow definition + Workflow *ActionWorkflow `json:"workflow"` + // The workflow run that was acted upon + WorkflowRun *ActionWorkflowRun `json:"workflow_run"` + // The pull request associated with the workflow run (if applicable) + PullRequest *PullRequest `json:"pull_request,omitempty"` + // The organization that owns the repository (if applicable) + Organization *Organization `json:"organization,omitempty"` + // The repository containing the workflow + Repo *Repository `json:"repository"` + // The user who triggered the workflow run + Sender *User `json:"sender"` } // JSONPayload implements Payload @@ -491,12 +620,18 @@ func (p *WorkflowRunPayload) JSONPayload() ([]byte, error) { // WorkflowJobPayload represents a payload information of workflow job event. type WorkflowJobPayload struct { - Action string `json:"action"` - WorkflowJob *ActionWorkflowJob `json:"workflow_job"` - PullRequest *PullRequest `json:"pull_request,omitempty"` - Organization *Organization `json:"organization,omitempty"` - Repo *Repository `json:"repository"` - Sender *User `json:"sender"` + // The action performed on the workflow job + Action string `json:"action"` + // The workflow job that was acted upon + WorkflowJob *ActionWorkflowJob `json:"workflow_job"` + // The pull request associated with the workflow job (if applicable) + PullRequest *PullRequest `json:"pull_request,omitempty"` + // The organization that owns the repository (if applicable) + Organization *Organization `json:"organization,omitempty"` + // The repository containing the workflow + Repo *Repository `json:"repository"` + // The user who triggered the workflow job + Sender *User `json:"sender"` } // JSONPayload implements Payload diff --git a/modules/structs/issue_comment.go b/modules/structs/issue_comment.go index 9e8f5c4bf3..5223602e1a 100644 --- a/modules/structs/issue_comment.go +++ b/modules/structs/issue_comment.go @@ -9,15 +9,24 @@ import ( // Comment represents a comment on a commit or issue type Comment struct { - ID int64 `json:"id"` - HTMLURL string `json:"html_url"` - PRURL string `json:"pull_request_url"` - IssueURL string `json:"issue_url"` - Poster *User `json:"user"` - OriginalAuthor string `json:"original_author"` - OriginalAuthorID int64 `json:"original_author_id"` - Body string `json:"body"` - Attachments []*Attachment `json:"assets"` + // ID is the unique identifier for the comment + ID int64 `json:"id"` + // HTMLURL is the web URL for viewing the comment + HTMLURL string `json:"html_url"` + // PRURL is the API URL for the pull request (if applicable) + PRURL string `json:"pull_request_url"` + // IssueURL is the API URL for the issue + IssueURL string `json:"issue_url"` + // Poster is the user who posted the comment + Poster *User `json:"user"` + // OriginalAuthor is the original author name (for imported comments) + OriginalAuthor string `json:"original_author"` + // OriginalAuthorID is the original author ID (for imported comments) + OriginalAuthorID int64 `json:"original_author_id"` + // Body contains the comment text content + Body string `json:"body"` + // Attachments contains files attached to the comment + Attachments []*Attachment `json:"assets"` // swagger:strfmt date-time Created time.Time `json:"created_at"` // swagger:strfmt date-time @@ -27,25 +36,34 @@ type Comment struct { // CreateIssueCommentOption options for creating a comment on an issue type CreateIssueCommentOption struct { // required:true + // Body is the comment text content Body string `json:"body" binding:"Required"` } // EditIssueCommentOption options for editing a comment type EditIssueCommentOption struct { // required: true + // Body is the updated comment text content Body string `json:"body" binding:"Required"` } // TimelineComment represents a timeline comment (comment of any type) on a commit or issue type TimelineComment struct { - ID int64 `json:"id"` + // ID is the unique identifier for the timeline comment + ID int64 `json:"id"` + // Type indicates the type of timeline event Type string `json:"type"` - HTMLURL string `json:"html_url"` - PRURL string `json:"pull_request_url"` + // HTMLURL is the web URL for viewing the comment + HTMLURL string `json:"html_url"` + // PRURL is the API URL for the pull request (if applicable) + PRURL string `json:"pull_request_url"` + // IssueURL is the API URL for the issue IssueURL string `json:"issue_url"` - Poster *User `json:"user"` - Body string `json:"body"` + // Poster is the user who created the timeline event + Poster *User `json:"user"` + // Body contains the timeline event content + Body string `json:"body"` // swagger:strfmt date-time Created time.Time `json:"created_at"` // swagger:strfmt date-time diff --git a/modules/structs/issue_label.go b/modules/structs/issue_label.go index 942cc0b3a1..16bd0b3c94 100644 --- a/modules/structs/issue_label.go +++ b/modules/structs/issue_label.go @@ -7,27 +7,33 @@ package structs // Label a label to an issue or a pr // swagger:model type Label struct { - ID int64 `json:"id"` + // ID is the unique identifier for the label + ID int64 `json:"id"` + // Name is the display name of the label Name string `json:"name"` // example: false Exclusive bool `json:"exclusive"` // example: false IsArchived bool `json:"is_archived"` // example: 00aabb - Color string `json:"color"` + Color string `json:"color"` + // Description provides additional context about the label's purpose Description string `json:"description"` - URL string `json:"url"` + // URL is the API endpoint for accessing this label + URL string `json:"url"` } // CreateLabelOption options for creating a label type CreateLabelOption struct { // required:true + // Name is the display name for the new label Name string `json:"name" binding:"Required"` // example: false Exclusive bool `json:"exclusive"` // required:true // example: #00aabb - Color string `json:"color" binding:"Required"` + Color string `json:"color" binding:"Required"` + // Description provides additional context about the label's purpose Description string `json:"description"` // example: false IsArchived bool `json:"is_archived"` @@ -35,11 +41,13 @@ type CreateLabelOption struct { // EditLabelOption options for editing a label type EditLabelOption struct { + // Name is the new display name for the label Name *string `json:"name"` // example: false Exclusive *bool `json:"exclusive"` // example: #00aabb - Color *string `json:"color"` + Color *string `json:"color"` + // Description provides additional context about the label's purpose Description *string `json:"description"` // example: false IsArchived *bool `json:"is_archived"` @@ -54,10 +62,12 @@ type IssueLabelsOption struct { // LabelTemplate info of a Label template type LabelTemplate struct { + // Name is the display name of the label template Name string `json:"name"` // example: false Exclusive bool `json:"exclusive"` // example: 00aabb - Color string `json:"color"` + Color string `json:"color"` + // Description provides additional context about the label template's purpose Description string `json:"description"` } diff --git a/modules/structs/issue_milestone.go b/modules/structs/issue_milestone.go index a840cf1820..226c613d47 100644 --- a/modules/structs/issue_milestone.go +++ b/modules/structs/issue_milestone.go @@ -9,12 +9,18 @@ import ( // Milestone milestone is a collection of issues on one repository type Milestone struct { - ID int64 `json:"id"` - Title string `json:"title"` - Description string `json:"description"` - State StateType `json:"state"` - OpenIssues int `json:"open_issues"` - ClosedIssues int `json:"closed_issues"` + // ID is the unique identifier for the milestone + ID int64 `json:"id"` + // Title is the title of the milestone + Title string `json:"title"` + // Description provides details about the milestone + Description string `json:"description"` + // State indicates if the milestone is open or closed + State StateType `json:"state"` + // OpenIssues is the number of open issues in this milestone + OpenIssues int `json:"open_issues"` + // ClosedIssues is the number of closed issues in this milestone + ClosedIssues int `json:"closed_issues"` // swagger:strfmt date-time Created time.Time `json:"created_at"` // swagger:strfmt date-time @@ -27,18 +33,26 @@ type Milestone struct { // CreateMilestoneOption options for creating a milestone type CreateMilestoneOption struct { - Title string `json:"title"` + // Title is the title of the new milestone + Title string `json:"title"` + // Description provides details about the milestone Description string `json:"description"` // swagger:strfmt date-time + // Deadline is the due date for the milestone Deadline *time.Time `json:"due_on"` // enum: open,closed + // State indicates the initial state of the milestone State string `json:"state"` } // EditMilestoneOption options for editing a milestone type EditMilestoneOption struct { - Title string `json:"title"` - Description *string `json:"description"` - State *string `json:"state"` - Deadline *time.Time `json:"due_on"` + // Title is the updated title of the milestone + Title string `json:"title"` + // Description provides updated details about the milestone + Description *string `json:"description"` + // State indicates the updated state of the milestone + State *string `json:"state"` + // Deadline is the updated due date for the milestone + Deadline *time.Time `json:"due_on"` } diff --git a/modules/structs/issue_reaction.go b/modules/structs/issue_reaction.go index 8d907a47e5..d611b5bc67 100644 --- a/modules/structs/issue_reaction.go +++ b/modules/structs/issue_reaction.go @@ -9,13 +9,17 @@ import ( // EditReactionOption contain the reaction type type EditReactionOption struct { + // The reaction content (e.g., emoji or reaction type) Reaction string `json:"content"` } // Reaction contain one reaction type Reaction struct { - User *User `json:"user"` + // The user who created the reaction + User *User `json:"user"` + // The reaction content (e.g., emoji or reaction type) Reaction string `json:"content"` // swagger:strfmt date-time + // The date and time when the reaction was created Created time.Time `json:"created_at"` } diff --git a/modules/structs/issue_stopwatch.go b/modules/structs/issue_stopwatch.go index ceade1ddd2..77c41593ef 100644 --- a/modules/structs/issue_stopwatch.go +++ b/modules/structs/issue_stopwatch.go @@ -10,13 +10,20 @@ import ( // StopWatch represent a running stopwatch type StopWatch struct { // swagger:strfmt date-time - Created time.Time `json:"created"` - Seconds int64 `json:"seconds"` - Duration string `json:"duration"` - IssueIndex int64 `json:"issue_index"` - IssueTitle string `json:"issue_title"` - RepoOwnerName string `json:"repo_owner_name"` - RepoName string `json:"repo_name"` + // Created is the time when the stopwatch was started + Created time.Time `json:"created"` + // Seconds is the total elapsed time in seconds + Seconds int64 `json:"seconds"` + // Duration is a human-readable duration string + Duration string `json:"duration"` + // IssueIndex is the index number of the associated issue + IssueIndex int64 `json:"issue_index"` + // IssueTitle is the title of the associated issue + IssueTitle string `json:"issue_title"` + // RepoOwnerName is the name of the repository owner + RepoOwnerName string `json:"repo_owner_name"` + // RepoName is the name of the repository + RepoName string `json:"repo_name"` } // StopWatches represent a list of stopwatches diff --git a/modules/structs/issue_tracked_time.go b/modules/structs/issue_tracked_time.go index befcfb323d..b59f0598f8 100644 --- a/modules/structs/issue_tracked_time.go +++ b/modules/structs/issue_tracked_time.go @@ -20,6 +20,7 @@ type AddTimeOption struct { // TrackedTime worked time for an issue / pr type TrackedTime struct { + // ID is the unique identifier for the tracked time entry ID int64 `json:"id"` // swagger:strfmt date-time Created time.Time `json:"created"` @@ -30,8 +31,9 @@ type TrackedTime struct { // username of the user UserName string `json:"user_name"` // deprecated (only for backwards compatibility) - IssueID int64 `json:"issue_id"` - Issue *Issue `json:"issue"` + IssueID int64 `json:"issue_id"` + // Issue contains the associated issue information + Issue *Issue `json:"issue"` } // TrackedTimeList represents a list of tracked times diff --git a/modules/structs/lfs_lock.go b/modules/structs/lfs_lock.go index 6b4c0bc111..2f226e91ab 100644 --- a/modules/structs/lfs_lock.go +++ b/modules/structs/lfs_lock.go @@ -10,55 +10,72 @@ import ( // LFSLock represent a lock // for use with the locks API. type LFSLock struct { - ID string `json:"id"` - Path string `json:"path"` - LockedAt time.Time `json:"locked_at"` - Owner *LFSLockOwner `json:"owner"` + // The unique identifier of the lock + ID string `json:"id"` + // The file path that is locked + Path string `json:"path"` + // The timestamp when the lock was created + LockedAt time.Time `json:"locked_at"` + // The owner of the lock + Owner *LFSLockOwner `json:"owner"` } // LFSLockOwner represent a lock owner // for use with the locks API. type LFSLockOwner struct { + // The name of the lock owner Name string `json:"name"` } // LFSLockRequest contains the path of the lock to create // https://github.com/git-lfs/git-lfs/blob/master/docs/api/locking.md#create-lock type LFSLockRequest struct { + // The file path to lock Path string `json:"path"` } // LFSLockResponse represent a lock created // https://github.com/git-lfs/git-lfs/blob/master/docs/api/locking.md#create-lock type LFSLockResponse struct { + // The created lock Lock *LFSLock `json:"lock"` } // LFSLockList represent a list of lock requested // https://github.com/git-lfs/git-lfs/blob/master/docs/api/locking.md#list-locks type LFSLockList struct { + // The list of locks Locks []*LFSLock `json:"locks"` - Next string `json:"next_cursor,omitempty"` + // The cursor for pagination to the next set of results + Next string `json:"next_cursor,omitempty"` } // LFSLockListVerify represent a list of lock verification requested // https://github.com/git-lfs/git-lfs/blob/master/docs/api/locking.md#list-locks-for-verification type LFSLockListVerify struct { - Ours []*LFSLock `json:"ours"` + // Locks owned by the requesting user + Ours []*LFSLock `json:"ours"` + // Locks owned by other users Theirs []*LFSLock `json:"theirs"` - Next string `json:"next_cursor,omitempty"` + // The cursor for pagination to the next set of results + Next string `json:"next_cursor,omitempty"` } // LFSLockError contains information on the error that occurs type LFSLockError struct { - Message string `json:"message"` - Lock *LFSLock `json:"lock,omitempty"` - Documentation string `json:"documentation_url,omitempty"` - RequestID string `json:"request_id,omitempty"` + // The error message + Message string `json:"message"` + // The lock related to the error, if any + Lock *LFSLock `json:"lock,omitempty"` + // URL to documentation about the error + Documentation string `json:"documentation_url,omitempty"` + // The request ID for debugging purposes + RequestID string `json:"request_id,omitempty"` } // LFSLockDeleteRequest contains params of a delete request // https://github.com/git-lfs/git-lfs/blob/master/docs/api/locking.md#delete-lock type LFSLockDeleteRequest struct { + // Whether to force delete the lock even if not owned by the requester Force bool `json:"force"` } diff --git a/modules/structs/mirror.go b/modules/structs/mirror.go index 8259583cde..50b0a5d2cc 100644 --- a/modules/structs/mirror.go +++ b/modules/structs/mirror.go @@ -7,24 +7,35 @@ import "time" // CreatePushMirrorOption represents need information to create a push mirror of a repository. type CreatePushMirrorOption struct { - RemoteAddress string `json:"remote_address"` + // The remote repository URL to push to + RemoteAddress string `json:"remote_address"` + // The username for authentication with the remote repository RemoteUsername string `json:"remote_username"` + // The password for authentication with the remote repository RemotePassword string `json:"remote_password"` - Interval string `json:"interval"` - SyncOnCommit bool `json:"sync_on_commit"` + // The sync interval for automatic updates + Interval string `json:"interval"` + // Whether to sync on every commit + SyncOnCommit bool `json:"sync_on_commit"` } // PushMirror represents information of a push mirror // swagger:model type PushMirror struct { - RepoName string `json:"repo_name"` - RemoteName string `json:"remote_name"` + // The name of the source repository + RepoName string `json:"repo_name"` + // The name of the remote in the git configuration + RemoteName string `json:"remote_name"` + // The remote repository URL being mirrored to RemoteAddress string `json:"remote_address"` // swagger:strfmt date-time CreatedUnix time.Time `json:"created"` // swagger:strfmt date-time LastUpdateUnix *time.Time `json:"last_update"` - LastError string `json:"last_error"` - Interval string `json:"interval"` - SyncOnCommit bool `json:"sync_on_commit"` + // The last error message encountered during sync + LastError string `json:"last_error"` + // The sync interval for automatic updates + Interval string `json:"interval"` + // Whether to sync on every commit + SyncOnCommit bool `json:"sync_on_commit"` } diff --git a/modules/structs/miscellaneous.go b/modules/structs/miscellaneous.go index cfdb6db96c..293ba99579 100644 --- a/modules/structs/miscellaneous.go +++ b/modules/structs/miscellaneous.go @@ -5,13 +5,17 @@ package structs // SearchResults results of a successful search type SearchResults struct { - OK bool `json:"ok"` + // OK indicates if the search was successful + OK bool `json:"ok"` + // Data contains the repository search results Data []*Repository `json:"data"` } // SearchError error of a failed search type SearchError struct { - OK bool `json:"ok"` + // OK indicates the search status (always false for errors) + OK bool `json:"ok"` + // Error contains the error message Error string `json:"error"` } @@ -73,33 +77,46 @@ type MarkdownRender string // ServerVersion wraps the version of the server type ServerVersion struct { + // Version is the server version string Version string `json:"version"` } // GitignoreTemplateInfo name and text of a gitignore template type GitignoreTemplateInfo struct { - Name string `json:"name"` + // Name is the name of the gitignore template + Name string `json:"name"` + // Source contains the content of the gitignore template Source string `json:"source"` } // LicensesListEntry is used for the API type LicensesTemplateListEntry struct { - Key string `json:"key"` + // Key is the unique identifier for the license template + Key string `json:"key"` + // Name is the display name of the license Name string `json:"name"` - URL string `json:"url"` + // URL is the reference URL for the license + URL string `json:"url"` } // LicensesInfo contains information about a License type LicenseTemplateInfo struct { - Key string `json:"key"` - Name string `json:"name"` - URL string `json:"url"` + // Key is the unique identifier for the license template + Key string `json:"key"` + // Name is the display name of the license + Name string `json:"name"` + // URL is the reference URL for the license + URL string `json:"url"` + // Implementation contains license implementation details Implementation string `json:"implementation"` - Body string `json:"body"` + // Body contains the full text of the license + Body string `json:"body"` } // APIError is an api error with a message type APIError struct { + // Message contains the error description Message string `json:"message"` - URL string `json:"url"` + // URL contains the documentation URL for this error + URL string `json:"url"` } diff --git a/modules/structs/nodeinfo.go b/modules/structs/nodeinfo.go index 802c8d3e57..7af056ff49 100644 --- a/modules/structs/nodeinfo.go +++ b/modules/structs/nodeinfo.go @@ -5,39 +5,58 @@ package structs // NodeInfo contains standardized way of exposing metadata about a server running one of the distributed social networks type NodeInfo struct { - Version string `json:"version"` - Software NodeInfoSoftware `json:"software"` - Protocols []string `json:"protocols"` - Services NodeInfoServices `json:"services"` - OpenRegistrations bool `json:"openRegistrations"` - Usage NodeInfoUsage `json:"usage"` - Metadata struct{} `json:"metadata"` + // Version specifies the schema version + Version string `json:"version"` + // Software contains information about the server software + Software NodeInfoSoftware `json:"software"` + // Protocols lists the protocols supported by this server + Protocols []string `json:"protocols"` + // Services contains third party services this server can connect to + Services NodeInfoServices `json:"services"` + // OpenRegistrations indicates if new user registrations are accepted + OpenRegistrations bool `json:"openRegistrations"` + // Usage contains server usage statistics + Usage NodeInfoUsage `json:"usage"` + // Metadata contains free form key value pairs for software specific values + Metadata struct{} `json:"metadata"` } // NodeInfoSoftware contains Metadata about server software in use type NodeInfoSoftware struct { - Name string `json:"name"` - Version string `json:"version"` + // Name is the canonical name of this server software + Name string `json:"name"` + // Version is the version of this server software + Version string `json:"version"` + // Repository is the URL to the source code repository Repository string `json:"repository"` - Homepage string `json:"homepage"` + // Homepage is the URL to the homepage of this server software + Homepage string `json:"homepage"` } // NodeInfoServices contains the third party sites this server can connect to via their application API type NodeInfoServices struct { - Inbound []string `json:"inbound"` + // Inbound lists services that can deliver content to this server + Inbound []string `json:"inbound"` + // Outbound lists services this server can deliver content to Outbound []string `json:"outbound"` } // NodeInfoUsage contains usage statistics for this server type NodeInfoUsage struct { - Users NodeInfoUsageUsers `json:"users"` - LocalPosts int `json:"localPosts,omitempty"` - LocalComments int `json:"localComments,omitempty"` + // Users contains user statistics + Users NodeInfoUsageUsers `json:"users"` + // LocalPosts is the total amount of posts made by users local to this server + LocalPosts int `json:"localPosts,omitempty"` + // LocalComments is the total amount of comments made by users local to this server + LocalComments int `json:"localComments,omitempty"` } // NodeInfoUsageUsers contains statistics about the users of this server type NodeInfoUsageUsers struct { - Total int `json:"total,omitempty"` + // Total is the total amount of users on this server + Total int `json:"total,omitempty"` + // ActiveHalfyear is the amount of users that signed in at least once in the last 180 days ActiveHalfyear int `json:"activeHalfyear,omitempty"` - ActiveMonth int `json:"activeMonth,omitempty"` + // ActiveMonth is the amount of users that signed in at least once in the last 30 days + ActiveMonth int `json:"activeMonth,omitempty"` } diff --git a/modules/structs/notifications.go b/modules/structs/notifications.go index 7fbf4cb46d..cee5da6624 100644 --- a/modules/structs/notifications.go +++ b/modules/structs/notifications.go @@ -9,28 +9,43 @@ import ( // NotificationThread expose Notification on API type NotificationThread struct { - ID int64 `json:"id"` - Repository *Repository `json:"repository"` - Subject *NotificationSubject `json:"subject"` - Unread bool `json:"unread"` - Pinned bool `json:"pinned"` - UpdatedAt time.Time `json:"updated_at"` - URL string `json:"url"` + // ID is the unique identifier for the notification thread + ID int64 `json:"id"` + // Repository is the repository associated with the notification + Repository *Repository `json:"repository"` + // Subject contains details about the notification subject + Subject *NotificationSubject `json:"subject"` + // Unread indicates if the notification has been read + Unread bool `json:"unread"` + // Pinned indicates if the notification is pinned + Pinned bool `json:"pinned"` + // UpdatedAt is the time when the notification was last updated + UpdatedAt time.Time `json:"updated_at"` + // URL is the API URL for this notification thread + URL string `json:"url"` } // NotificationSubject contains the notification subject (Issue/Pull/Commit) type NotificationSubject struct { - Title string `json:"title"` - URL string `json:"url"` - LatestCommentURL string `json:"latest_comment_url"` - HTMLURL string `json:"html_url"` - LatestCommentHTMLURL string `json:"latest_comment_html_url"` - Type NotifySubjectType `json:"type" binding:"In(Issue,Pull,Commit,Repository)"` - State StateType `json:"state"` + // Title is the title of the notification subject + Title string `json:"title"` + // URL is the API URL for the notification subject + URL string `json:"url"` + // LatestCommentURL is the API URL for the latest comment + LatestCommentURL string `json:"latest_comment_url"` + // HTMLURL is the web URL for the notification subject + HTMLURL string `json:"html_url"` + // LatestCommentHTMLURL is the web URL for the latest comment + LatestCommentHTMLURL string `json:"latest_comment_html_url"` + // Type indicates the type of the notification subject + Type NotifySubjectType `json:"type" binding:"In(Issue,Pull,Commit,Repository)"` + // State indicates the current state of the notification subject + State StateType `json:"state"` } // NotificationCount number of unread notifications type NotificationCount struct { + // New is the number of unread notifications New int64 `json:"new"` } diff --git a/modules/structs/org.go b/modules/structs/org.go index 33b45c6344..c3d70ebf00 100644 --- a/modules/structs/org.go +++ b/modules/structs/org.go @@ -5,16 +5,26 @@ package structs // Organization represents an organization type Organization struct { - ID int64 `json:"id"` - Name string `json:"name"` - FullName string `json:"full_name"` - Email string `json:"email"` - AvatarURL string `json:"avatar_url"` - Description string `json:"description"` - Website string `json:"website"` - Location string `json:"location"` - Visibility string `json:"visibility"` - RepoAdminChangeTeamAccess bool `json:"repo_admin_change_team_access"` + // The unique identifier of the organization + ID int64 `json:"id"` + // The name of the organization + Name string `json:"name"` + // The full display name of the organization + FullName string `json:"full_name"` + // The email address of the organization + Email string `json:"email"` + // The URL of the organization's avatar + AvatarURL string `json:"avatar_url"` + // The description of the organization + Description string `json:"description"` + // The website URL of the organization + Website string `json:"website"` + // The location of the organization + Location string `json:"location"` + // The visibility level of the organization (public, limited, private) + Visibility string `json:"visibility"` + // Whether repository administrators can change team access + RepoAdminChangeTeamAccess bool `json:"repo_admin_change_team_access"` // username of the organization // deprecated UserName string `json:"username"` @@ -22,10 +32,15 @@ type Organization struct { // OrganizationPermissions list different users permissions on an organization type OrganizationPermissions struct { - IsOwner bool `json:"is_owner"` - IsAdmin bool `json:"is_admin"` - CanWrite bool `json:"can_write"` - CanRead bool `json:"can_read"` + // Whether the user is an owner of the organization + IsOwner bool `json:"is_owner"` + // Whether the user is an admin of the organization + IsAdmin bool `json:"is_admin"` + // Whether the user can write to the organization + CanWrite bool `json:"can_write"` + // Whether the user can read the organization + CanRead bool `json:"can_read"` + // Whether the user can create repositories in the organization CanCreateRepository bool `json:"can_create_repository"` } @@ -33,31 +48,43 @@ type OrganizationPermissions struct { type CreateOrgOption struct { // username of the organization // required: true - UserName string `json:"username" binding:"Required;Username;MaxSize(40)"` - FullName string `json:"full_name" binding:"MaxSize(100)"` - Email string `json:"email" binding:"MaxSize(255)"` + UserName string `json:"username" binding:"Required;Username;MaxSize(40)"` + // The full display name of the organization + FullName string `json:"full_name" binding:"MaxSize(100)"` + // The email address of the organization + Email string `json:"email" binding:"MaxSize(255)"` + // The description of the organization Description string `json:"description" binding:"MaxSize(255)"` - Website string `json:"website" binding:"ValidUrl;MaxSize(255)"` - Location string `json:"location" binding:"MaxSize(50)"` + // The website URL of the organization + Website string `json:"website" binding:"ValidUrl;MaxSize(255)"` + // The location of the organization + Location string `json:"location" binding:"MaxSize(50)"` // possible values are `public` (default), `limited` or `private` // enum: public,limited,private - Visibility string `json:"visibility" binding:"In(,public,limited,private)"` - RepoAdminChangeTeamAccess bool `json:"repo_admin_change_team_access"` + Visibility string `json:"visibility" binding:"In(,public,limited,private)"` + // Whether repository administrators can change team access + RepoAdminChangeTeamAccess bool `json:"repo_admin_change_team_access"` } // TODO: make EditOrgOption fields optional after https://gitea.com/go-chi/binding/pulls/5 got merged // EditOrgOption options for editing an organization type EditOrgOption struct { - FullName string `json:"full_name" binding:"MaxSize(100)"` - Email string `json:"email" binding:"MaxSize(255)"` + // The full display name of the organization + FullName string `json:"full_name" binding:"MaxSize(100)"` + // The email address of the organization + Email string `json:"email" binding:"MaxSize(255)"` + // The description of the organization Description string `json:"description" binding:"MaxSize(255)"` - Website string `json:"website" binding:"ValidUrl;MaxSize(255)"` - Location string `json:"location" binding:"MaxSize(50)"` + // The website URL of the organization + Website string `json:"website" binding:"ValidUrl;MaxSize(255)"` + // The location of the organization + Location string `json:"location" binding:"MaxSize(50)"` // possible values are `public`, `limited` or `private` // enum: public,limited,private - Visibility string `json:"visibility" binding:"In(,public,limited,private)"` - RepoAdminChangeTeamAccess *bool `json:"repo_admin_change_team_access"` + Visibility string `json:"visibility" binding:"In(,public,limited,private)"` + // Whether repository administrators can change team access + RepoAdminChangeTeamAccess *bool `json:"repo_admin_change_team_access"` } // RenameOrgOption options when renaming an organization diff --git a/modules/structs/org_member.go b/modules/structs/org_member.go index 2df5099de9..86c7c0f4fe 100644 --- a/modules/structs/org_member.go +++ b/modules/structs/org_member.go @@ -5,5 +5,6 @@ package structs // AddOrgMembershipOption add user to organization options type AddOrgMembershipOption struct { + // Role is the role to assign to the organization member Role string `json:"role" binding:"Required"` } diff --git a/modules/structs/org_team.go b/modules/structs/org_team.go index f8899b236b..d34de5b6d2 100644 --- a/modules/structs/org_team.go +++ b/modules/structs/org_team.go @@ -6,49 +6,61 @@ package structs // Team represents a team in an organization type Team struct { - ID int64 `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Organization *Organization `json:"organization"` - IncludesAllRepositories bool `json:"includes_all_repositories"` + // The unique identifier of the team + ID int64 `json:"id"` + // The name of the team + Name string `json:"name"` + // The description of the team + Description string `json:"description"` + // The organization that the team belongs to + Organization *Organization `json:"organization"` + // Whether the team has access to all repositories in the organization + IncludesAllRepositories bool `json:"includes_all_repositories"` // enum: none,read,write,admin,owner Permission string `json:"permission"` // example: ["repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.pulls","repo.releases","repo.projects","repo.ext_wiki"] // Deprecated: This variable should be replaced by UnitsMap and will be dropped in later versions. Units []string `json:"units"` // example: {"repo.code":"read","repo.issues":"write","repo.ext_issues":"none","repo.wiki":"admin","repo.pulls":"owner","repo.releases":"none","repo.projects":"none","repo.ext_wiki":"none"} - UnitsMap map[string]string `json:"units_map"` - CanCreateOrgRepo bool `json:"can_create_org_repo"` + UnitsMap map[string]string `json:"units_map"` + // Whether the team can create repositories in the organization + CanCreateOrgRepo bool `json:"can_create_org_repo"` } // CreateTeamOption options for creating a team type CreateTeamOption struct { // required: true - Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(255)"` - Description string `json:"description" binding:"MaxSize(255)"` - IncludesAllRepositories bool `json:"includes_all_repositories"` + Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(255)"` + // The description of the team + Description string `json:"description" binding:"MaxSize(255)"` + // Whether the team has access to all repositories in the organization + IncludesAllRepositories bool `json:"includes_all_repositories"` // enum: read,write,admin Permission string `json:"permission"` // example: ["repo.actions","repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.ext_wiki","repo.pulls","repo.releases","repo.projects","repo.ext_wiki"] // Deprecated: This variable should be replaced by UnitsMap and will be dropped in later versions. Units []string `json:"units"` // example: {"repo.actions","repo.packages","repo.code":"read","repo.issues":"write","repo.ext_issues":"none","repo.wiki":"admin","repo.pulls":"owner","repo.releases":"none","repo.projects":"none","repo.ext_wiki":"none"} - UnitsMap map[string]string `json:"units_map"` - CanCreateOrgRepo bool `json:"can_create_org_repo"` + UnitsMap map[string]string `json:"units_map"` + // Whether the team can create repositories in the organization + CanCreateOrgRepo bool `json:"can_create_org_repo"` } // EditTeamOption options for editing a team type EditTeamOption struct { // required: true - Name string `json:"name" binding:"AlphaDashDot;MaxSize(255)"` - Description *string `json:"description" binding:"MaxSize(255)"` - IncludesAllRepositories *bool `json:"includes_all_repositories"` + Name string `json:"name" binding:"AlphaDashDot;MaxSize(255)"` + // The description of the team + Description *string `json:"description" binding:"MaxSize(255)"` + // Whether the team has access to all repositories in the organization + IncludesAllRepositories *bool `json:"includes_all_repositories"` // enum: read,write,admin Permission string `json:"permission"` // example: ["repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.pulls","repo.releases","repo.projects","repo.ext_wiki"] // Deprecated: This variable should be replaced by UnitsMap and will be dropped in later versions. Units []string `json:"units"` // example: {"repo.code":"read","repo.issues":"write","repo.ext_issues":"none","repo.wiki":"admin","repo.pulls":"owner","repo.releases":"none","repo.projects":"none","repo.ext_wiki":"none"} - UnitsMap map[string]string `json:"units_map"` - CanCreateOrgRepo *bool `json:"can_create_org_repo"` + UnitsMap map[string]string `json:"units_map"` + // Whether the team can create repositories in the organization + CanCreateOrgRepo *bool `json:"can_create_org_repo"` } diff --git a/modules/structs/package.go b/modules/structs/package.go index 1973f925a5..e656e26cd0 100644 --- a/modules/structs/package.go +++ b/modules/structs/package.go @@ -9,25 +9,41 @@ import ( // Package represents a package type Package struct { - ID int64 `json:"id"` - Owner *User `json:"owner"` + // The unique identifier of the package + ID int64 `json:"id"` + // The owner of the package + Owner *User `json:"owner"` + // The repository that contains this package Repository *Repository `json:"repository"` - Creator *User `json:"creator"` - Type string `json:"type"` - Name string `json:"name"` - Version string `json:"version"` - HTMLURL string `json:"html_url"` + // The user who created this package + Creator *User `json:"creator"` + // The type of the package (e.g., npm, maven, docker) + Type string `json:"type"` + // The name of the package + Name string `json:"name"` + // The version of the package + Version string `json:"version"` + // The HTML URL to view the package + HTMLURL string `json:"html_url"` // swagger:strfmt date-time + // The date and time when the package was created CreatedAt time.Time `json:"created_at"` } // PackageFile represents a package file type PackageFile struct { - ID int64 `json:"id"` - Size int64 `json:"size"` - Name string `json:"name"` - HashMD5 string `json:"md5"` - HashSHA1 string `json:"sha1"` + // The unique identifier of the package file + ID int64 `json:"id"` + // The size of the package file in bytes + Size int64 `json:"size"` + // The name of the package file + Name string `json:"name"` + // The MD5 hash of the package file + HashMD5 string `json:"md5"` + // The SHA1 hash of the package file + HashSHA1 string `json:"sha1"` + // The SHA256 hash of the package file HashSHA256 string `json:"sha256"` + // The SHA512 hash of the package file HashSHA512 string `json:"sha512"` } diff --git a/modules/structs/pull.go b/modules/structs/pull.go index f53d6adafc..7cc58217a0 100644 --- a/modules/structs/pull.go +++ b/modules/structs/pull.go @@ -9,45 +9,75 @@ import ( // PullRequest represents a pull request type PullRequest struct { - ID int64 `json:"id"` - URL string `json:"url"` - Index int64 `json:"number"` - Poster *User `json:"user"` - Title string `json:"title"` - Body string `json:"body"` - Labels []*Label `json:"labels"` - Milestone *Milestone `json:"milestone"` - Assignee *User `json:"assignee"` - Assignees []*User `json:"assignees"` - RequestedReviewers []*User `json:"requested_reviewers"` - RequestedReviewersTeams []*Team `json:"requested_reviewers_teams"` - State StateType `json:"state"` - Draft bool `json:"draft"` - IsLocked bool `json:"is_locked"` - Comments int `json:"comments"` + // The unique identifier of the pull request + ID int64 `json:"id"` + // The API URL of the pull request + URL string `json:"url"` + // The pull request number + Index int64 `json:"number"` + // The user who created the pull request + Poster *User `json:"user"` + // The title of the pull request + Title string `json:"title"` + // The description body of the pull request + Body string `json:"body"` + // The labels attached to the pull request + Labels []*Label `json:"labels"` + // The milestone associated with the pull request + Milestone *Milestone `json:"milestone"` + // The primary assignee of the pull request + Assignee *User `json:"assignee"` + // The list of users assigned to the pull request + Assignees []*User `json:"assignees"` + // The users requested to review the pull request + RequestedReviewers []*User `json:"requested_reviewers"` + // The teams requested to review the pull request + RequestedReviewersTeams []*Team `json:"requested_reviewers_teams"` + // The current state of the pull request + State StateType `json:"state"` + // Whether the pull request is a draft + Draft bool `json:"draft"` + // Whether the pull request conversation is locked + IsLocked bool `json:"is_locked"` + // The number of comments on the pull request + Comments int `json:"comments"` // number of review comments made on the diff of a PR review (not including comments on commits or issues in a PR) ReviewComments int `json:"review_comments,omitempty"` - Additions *int `json:"additions,omitempty"` - Deletions *int `json:"deletions,omitempty"` + // The number of lines added in the pull request + Additions *int `json:"additions,omitempty"` + // The number of lines deleted in the pull request + Deletions *int `json:"deletions,omitempty"` + // The number of files changed in the pull request ChangedFiles *int `json:"changed_files,omitempty"` - HTMLURL string `json:"html_url"` - DiffURL string `json:"diff_url"` + // The HTML URL to view the pull request + HTMLURL string `json:"html_url"` + // The URL to download the diff patch + DiffURL string `json:"diff_url"` + // The URL to download the patch file PatchURL string `json:"patch_url"` + // Whether the pull request can be merged Mergeable bool `json:"mergeable"` + // Whether the pull request has been merged HasMerged bool `json:"merged"` // swagger:strfmt date-time - Merged *time.Time `json:"merged_at"` - MergedCommitID *string `json:"merge_commit_sha"` - MergedBy *User `json:"merged_by"` - AllowMaintainerEdit bool `json:"allow_maintainer_edit"` + Merged *time.Time `json:"merged_at"` + // The SHA of the merge commit + MergedCommitID *string `json:"merge_commit_sha"` + // The user who merged the pull request + MergedBy *User `json:"merged_by"` + // Whether maintainers can edit the pull request + AllowMaintainerEdit bool `json:"allow_maintainer_edit"` - Base *PRBranchInfo `json:"base"` - Head *PRBranchInfo `json:"head"` - MergeBase string `json:"merge_base"` + // Information about the base branch + Base *PRBranchInfo `json:"base"` + // Information about the head branch + Head *PRBranchInfo `json:"head"` + // The merge base commit SHA + MergeBase string `json:"merge_base"` // swagger:strfmt date-time Deadline *time.Time `json:"due_date"` @@ -59,65 +89,103 @@ type PullRequest struct { // swagger:strfmt date-time Closed *time.Time `json:"closed_at"` + // The pin order for the pull request PinOrder int `json:"pin_order"` } // PRBranchInfo information about a branch type PRBranchInfo struct { - Name string `json:"label"` - Ref string `json:"ref"` - Sha string `json:"sha"` - RepoID int64 `json:"repo_id"` + // The display name of the branch + Name string `json:"label"` + // The git reference of the branch + Ref string `json:"ref"` + // The commit SHA of the branch head + Sha string `json:"sha"` + // The unique identifier of the repository + RepoID int64 `json:"repo_id"` + // The repository information Repository *Repository `json:"repo"` } // ListPullRequestsOptions options for listing pull requests type ListPullRequestsOptions struct { - Page int `json:"page"` + // The page number for pagination + Page int `json:"page"` + // The state filter for pull requests State string `json:"state"` } // CreatePullRequestOption options when creating a pull request type CreatePullRequestOption struct { - Head string `json:"head" binding:"Required"` - Base string `json:"base" binding:"Required"` - Title string `json:"title" binding:"Required"` - Body string `json:"body"` - Assignee string `json:"assignee"` + // The head branch for the pull request, it could be a branch name on the base repository or + // a form like `:` which refers to the user's fork repository's branch. + Head string `json:"head" binding:"Required"` + // The base branch for the pull request + Base string `json:"base" binding:"Required"` + // The title of the pull request + Title string `json:"title" binding:"Required"` + // The description body of the pull request + Body string `json:"body"` + // The primary assignee username + Assignee string `json:"assignee"` + // The list of assignee usernames Assignees []string `json:"assignees"` - Milestone int64 `json:"milestone"` - Labels []int64 `json:"labels"` + // The milestone ID to assign to the pull request + Milestone int64 `json:"milestone"` + // The list of label IDs to assign to the pull request + Labels []int64 `json:"labels"` // swagger:strfmt date-time - Deadline *time.Time `json:"due_date"` - Reviewers []string `json:"reviewers"` - TeamReviewers []string `json:"team_reviewers"` + Deadline *time.Time `json:"due_date"` + // The list of reviewer usernames + Reviewers []string `json:"reviewers"` + // The list of team reviewer names + TeamReviewers []string `json:"team_reviewers"` } // EditPullRequestOption options when modify pull request type EditPullRequestOption struct { - Title string `json:"title"` - Body *string `json:"body"` - Base string `json:"base"` - Assignee string `json:"assignee"` + // The new title for the pull request + Title string `json:"title"` + // The new description body for the pull request + Body *string `json:"body"` + // The new base branch for the pull request + Base string `json:"base"` + // The new primary assignee username + Assignee string `json:"assignee"` + // The new list of assignee usernames Assignees []string `json:"assignees"` - Milestone int64 `json:"milestone"` - Labels []int64 `json:"labels"` - State *string `json:"state"` + // The new milestone ID for the pull request + Milestone int64 `json:"milestone"` + // The new list of label IDs for the pull request + Labels []int64 `json:"labels"` + // The new state for the pull request + State *string `json:"state"` // swagger:strfmt date-time - Deadline *time.Time `json:"due_date"` - RemoveDeadline *bool `json:"unset_due_date"` - AllowMaintainerEdit *bool `json:"allow_maintainer_edit"` + Deadline *time.Time `json:"due_date"` + // Whether to remove the current deadline + RemoveDeadline *bool `json:"unset_due_date"` + // Whether to allow maintainer edits + AllowMaintainerEdit *bool `json:"allow_maintainer_edit"` } // ChangedFile store information about files affected by the pull request type ChangedFile struct { - Filename string `json:"filename"` + // The name of the changed file + Filename string `json:"filename"` + // The previous filename if the file was renamed PreviousFilename string `json:"previous_filename,omitempty"` - Status string `json:"status"` - Additions int `json:"additions"` - Deletions int `json:"deletions"` - Changes int `json:"changes"` - HTMLURL string `json:"html_url,omitempty"` - ContentsURL string `json:"contents_url,omitempty"` - RawURL string `json:"raw_url,omitempty"` + // The status of the file change (added, modified, deleted, etc.) + Status string `json:"status"` + // The number of lines added to the file + Additions int `json:"additions"` + // The number of lines deleted from the file + Deletions int `json:"deletions"` + // The total number of changes to the file + Changes int `json:"changes"` + // The HTML URL to view the file changes + HTMLURL string `json:"html_url,omitempty"` + // The API URL to get the file contents + ContentsURL string `json:"contents_url,omitempty"` + // The raw URL to download the file + RawURL string `json:"raw_url,omitempty"` } diff --git a/modules/structs/pull_review.go b/modules/structs/pull_review.go index 810be8f521..e93e4e9720 100644 --- a/modules/structs/pull_review.go +++ b/modules/structs/pull_review.go @@ -42,7 +42,9 @@ type PullReview struct { // swagger:strfmt date-time Updated time.Time `json:"updated_at"` - HTMLURL string `json:"html_url"` + // HTMLURL is the web URL for viewing the review + HTMLURL string `json:"html_url"` + // HTMLPullURL is the web URL for the pull request HTMLPullURL string `json:"pull_request_url"` } diff --git a/modules/structs/release.go b/modules/structs/release.go index fac86ca7a2..6a3e87ccbc 100644 --- a/modules/structs/release.go +++ b/modules/structs/release.go @@ -9,44 +9,70 @@ import ( // Release represents a repository release type Release struct { - ID int64 `json:"id"` - TagName string `json:"tag_name"` - Target string `json:"target_commitish"` - Title string `json:"name"` - Note string `json:"body"` - URL string `json:"url"` - HTMLURL string `json:"html_url"` - TarURL string `json:"tarball_url"` - ZipURL string `json:"zipball_url"` - UploadURL string `json:"upload_url"` - IsDraft bool `json:"draft"` - IsPrerelease bool `json:"prerelease"` + // The unique identifier of the release + ID int64 `json:"id"` + // The name of the git tag associated with the release + TagName string `json:"tag_name"` + // The target commitish for the release + Target string `json:"target_commitish"` + // The display title of the release + Title string `json:"name"` + // The release notes or description + Note string `json:"body"` + // The API URL of the release + URL string `json:"url"` + // The HTML URL to view the release + HTMLURL string `json:"html_url"` + // The URL to download the tarball archive + TarURL string `json:"tarball_url"` + // The URL to download the zip archive + ZipURL string `json:"zipball_url"` + // The URL template for uploading release assets + UploadURL string `json:"upload_url"` + // Whether the release is a draft + IsDraft bool `json:"draft"` + // Whether the release is a prerelease + IsPrerelease bool `json:"prerelease"` // swagger:strfmt date-time CreatedAt time.Time `json:"created_at"` // swagger:strfmt date-time - PublishedAt time.Time `json:"published_at"` - Publisher *User `json:"author"` + PublishedAt time.Time `json:"published_at"` + // The user who published the release + Publisher *User `json:"author"` + // The files attached to the release Attachments []*Attachment `json:"assets"` } // CreateReleaseOption options when creating a release type CreateReleaseOption struct { // required: true - TagName string `json:"tag_name" binding:"Required"` - TagMessage string `json:"tag_message"` - Target string `json:"target_commitish"` - Title string `json:"name"` - Note string `json:"body"` - IsDraft bool `json:"draft"` - IsPrerelease bool `json:"prerelease"` + TagName string `json:"tag_name" binding:"Required"` + // The message for the git tag + TagMessage string `json:"tag_message"` + // The target commitish for the release + Target string `json:"target_commitish"` + // The display title of the release + Title string `json:"name"` + // The release notes or description + Note string `json:"body"` + // Whether to create the release as a draft + IsDraft bool `json:"draft"` + // Whether to mark the release as a prerelease + IsPrerelease bool `json:"prerelease"` } // EditReleaseOption options when editing a release type EditReleaseOption struct { - TagName string `json:"tag_name"` - Target string `json:"target_commitish"` - Title string `json:"name"` - Note string `json:"body"` - IsDraft *bool `json:"draft"` - IsPrerelease *bool `json:"prerelease"` + // The new name of the git tag + TagName string `json:"tag_name"` + // The new target commitish for the release + Target string `json:"target_commitish"` + // The new display title of the release + Title string `json:"name"` + // The new release notes or description + Note string `json:"body"` + // Whether to change the draft status + IsDraft *bool `json:"draft"` + // Whether to change the prerelease status + IsPrerelease *bool `json:"prerelease"` } diff --git a/modules/structs/repo.go b/modules/structs/repo.go index f2e11b1542..e82a6dc25e 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -84,6 +84,7 @@ type Repository struct { Updated time.Time `json:"updated_at"` ArchivedAt time.Time `json:"archived_at"` Permissions *Permission `json:"permissions,omitempty"` + HasCode bool `json:"has_code"` HasIssues bool `json:"has_issues"` InternalTracker *InternalTracker `json:"internal_tracker,omitempty"` ExternalTracker *ExternalTracker `json:"external_tracker,omitempty"` @@ -170,6 +171,8 @@ type EditRepoOption struct { Private *bool `json:"private,omitempty"` // either `true` to make this repository a template or `false` to make it a normal repository Template *bool `json:"template,omitempty"` + // either `true` to enable code for this repository or `false` to disable it. + HasCode *bool `json:"has_code,omitempty"` // either `true` to enable issues for this repository or `false` to disable them. HasIssues *bool `json:"has_issues,omitempty"` // set this structure to configure internal issue tracker @@ -279,9 +282,9 @@ type CreateBranchRepoOption struct { OldRefName string `json:"old_ref_name" binding:"GitRefName;MaxSize(100)"` } -// UpdateBranchRepoOption options when updating a branch in a repository +// RenameBranchRepoOption options when renaming a branch in a repository // swagger:model -type UpdateBranchRepoOption struct { +type RenameBranchRepoOption struct { // New branch name // // required: true diff --git a/modules/structs/repo_actions.go b/modules/structs/repo_actions.go index ac1c288270..b491d6ccce 100644 --- a/modules/structs/repo_actions.go +++ b/modules/structs/repo_actions.go @@ -9,16 +9,26 @@ import ( // ActionTask represents a ActionTask type ActionTask struct { - ID int64 `json:"id"` - Name string `json:"name"` - HeadBranch string `json:"head_branch"` - HeadSHA string `json:"head_sha"` - RunNumber int64 `json:"run_number"` - Event string `json:"event"` + // ID is the unique identifier for the action task + ID int64 `json:"id"` + // Name is the name of the workflow + Name string `json:"name"` + // HeadBranch is the branch that triggered the workflow + HeadBranch string `json:"head_branch"` + // HeadSHA is the commit SHA that triggered the workflow + HeadSHA string `json:"head_sha"` + // RunNumber is the sequential number of the workflow run + RunNumber int64 `json:"run_number"` + // Event is the type of event that triggered the workflow + Event string `json:"event"` + // DisplayTitle is the display title for the workflow run DisplayTitle string `json:"display_title"` - Status string `json:"status"` - WorkflowID string `json:"workflow_id"` - URL string `json:"url"` + // Status indicates the current status of the workflow run + Status string `json:"status"` + // WorkflowID is the identifier of the workflow + WorkflowID string `json:"workflow_id"` + // URL is the API URL for this workflow run + URL string `json:"url"` // swagger:strfmt date-time CreatedAt time.Time `json:"created_at"` // swagger:strfmt date-time @@ -29,8 +39,10 @@ type ActionTask struct { // ActionTaskResponse returns a ActionTask type ActionTaskResponse struct { - Entries []*ActionTask `json:"workflow_runs"` - TotalCount int64 `json:"total_count"` + // Entries contains the list of workflow runs + Entries []*ActionTask `json:"workflow_runs"` + // TotalCount is the total number of workflow runs + TotalCount int64 `json:"total_count"` } // CreateActionWorkflowDispatch represents the payload for triggering a workflow dispatch event @@ -45,17 +57,24 @@ type CreateActionWorkflowDispatch struct { // ActionWorkflow represents a ActionWorkflow type ActionWorkflow struct { - ID string `json:"id"` - Name string `json:"name"` - Path string `json:"path"` + // ID is the unique identifier for the workflow + ID string `json:"id"` + // Name is the name of the workflow + Name string `json:"name"` + // Path is the file path of the workflow + Path string `json:"path"` + // State indicates if the workflow is active or disabled State string `json:"state"` // swagger:strfmt date-time CreatedAt time.Time `json:"created_at"` // swagger:strfmt date-time UpdatedAt time.Time `json:"updated_at"` - URL string `json:"url"` - HTMLURL string `json:"html_url"` - BadgeURL string `json:"badge_url"` + // URL is the API URL for this workflow + URL string `json:"url"` + // HTMLURL is the web URL for viewing the workflow + HTMLURL string `json:"html_url"` + // BadgeURL is the URL for the workflow badge + BadgeURL string `json:"badge_url"` // swagger:strfmt date-time DeletedAt time.Time `json:"deleted_at"` } diff --git a/modules/structs/repo_branch.go b/modules/structs/repo_branch.go index 5416f43b0d..75f7878aa6 100644 --- a/modules/structs/repo_branch.go +++ b/modules/structs/repo_branch.go @@ -9,22 +9,33 @@ import ( // Branch represents a repository branch type Branch struct { - Name string `json:"name"` - Commit *PayloadCommit `json:"commit"` - Protected bool `json:"protected"` - RequiredApprovals int64 `json:"required_approvals"` - EnableStatusCheck bool `json:"enable_status_check"` - StatusCheckContexts []string `json:"status_check_contexts"` - UserCanPush bool `json:"user_can_push"` - UserCanMerge bool `json:"user_can_merge"` - EffectiveBranchProtectionName string `json:"effective_branch_protection_name"` + // Name is the branch name + Name string `json:"name"` + // Commit contains the latest commit information for this branch + Commit *PayloadCommit `json:"commit"` + // Protected indicates if the branch is protected + Protected bool `json:"protected"` + // RequiredApprovals is the number of required approvals for pull requests + RequiredApprovals int64 `json:"required_approvals"` + // EnableStatusCheck indicates if status checks are enabled + EnableStatusCheck bool `json:"enable_status_check"` + // StatusCheckContexts contains the list of required status check contexts + StatusCheckContexts []string `json:"status_check_contexts"` + // UserCanPush indicates if the current user can push to this branch + UserCanPush bool `json:"user_can_push"` + // UserCanMerge indicates if the current user can merge to this branch + UserCanMerge bool `json:"user_can_merge"` + // EffectiveBranchProtectionName is the name of the effective branch protection rule + EffectiveBranchProtectionName string `json:"effective_branch_protection_name"` } // BranchProtection represents a branch protection for a repository type BranchProtection struct { // Deprecated: true - BranchName string `json:"branch_name"` - RuleName string `json:"rule_name"` + BranchName string `json:"branch_name"` + // RuleName is the name of the branch protection rule + RuleName string `json:"rule_name"` + // Priority is the priority of this branch protection rule Priority int64 `json:"priority"` EnablePush bool `json:"enable_push"` EnablePushWhitelist bool `json:"enable_push_whitelist"` diff --git a/modules/structs/repo_collaborator.go b/modules/structs/repo_collaborator.go index 7d39b5a798..9ede7f075a 100644 --- a/modules/structs/repo_collaborator.go +++ b/modules/structs/repo_collaborator.go @@ -6,12 +6,16 @@ package structs // AddCollaboratorOption options when adding a user as a collaborator of a repository type AddCollaboratorOption struct { // enum: read,write,admin + // Permission level to grant the collaborator Permission *string `json:"permission"` } // RepoCollaboratorPermission to get repository permission for a collaborator type RepoCollaboratorPermission struct { + // Permission level of the collaborator Permission string `json:"permission"` - RoleName string `json:"role_name"` - User *User `json:"user"` + // RoleName is the name of the permission role + RoleName string `json:"role_name"` + // User information of the collaborator + User *User `json:"user"` } diff --git a/modules/structs/repo_commit.go b/modules/structs/repo_commit.go index fec7d97608..14d8a86bcf 100644 --- a/modules/structs/repo_commit.go +++ b/modules/structs/repo_commit.go @@ -10,64 +10,90 @@ import ( // Identity for a person's identity like an author or committer type Identity struct { + // Name is the person's name Name string `json:"name" binding:"MaxSize(100)"` // swagger:strfmt email + // Email is the person's email address Email string `json:"email" binding:"MaxSize(254)"` } // CommitMeta contains meta information of a commit in terms of API. type CommitMeta struct { + // URL is the API URL for the commit URL string `json:"url"` + // SHA is the commit SHA hash SHA string `json:"sha"` // swagger:strfmt date-time + // Created is the time when the commit was created Created time.Time `json:"created"` } // CommitUser contains information of a user in the context of a commit. type CommitUser struct { Identity + // Date is the commit date in string format Date string `json:"date"` } // RepoCommit contains information of a commit in the context of a repository. type RepoCommit struct { - URL string `json:"url"` - Author *CommitUser `json:"author"` - Committer *CommitUser `json:"committer"` - Message string `json:"message"` - Tree *CommitMeta `json:"tree"` + // URL is the API URL for the commit + URL string `json:"url"` + // Author contains the commit author information + Author *CommitUser `json:"author"` + // Committer contains the commit committer information + Committer *CommitUser `json:"committer"` + // Message is the commit message + Message string `json:"message"` + // Tree contains the tree information for the commit + Tree *CommitMeta `json:"tree"` + // Verification contains commit signature verification information Verification *PayloadCommitVerification `json:"verification"` } // CommitStats is statistics for a RepoCommit type CommitStats struct { - Total int `json:"total"` + // Total is the total number of lines changed + Total int `json:"total"` + // Additions is the number of lines added Additions int `json:"additions"` + // Deletions is the number of lines deleted Deletions int `json:"deletions"` } // Commit contains information generated from a Git commit. type Commit struct { *CommitMeta - HTMLURL string `json:"html_url"` - RepoCommit *RepoCommit `json:"commit"` - Author *User `json:"author"` - Committer *User `json:"committer"` - Parents []*CommitMeta `json:"parents"` - Files []*CommitAffectedFiles `json:"files"` - Stats *CommitStats `json:"stats"` + // HTMLURL is the web URL for viewing the commit + HTMLURL string `json:"html_url"` + // RepoCommit contains the commit information + RepoCommit *RepoCommit `json:"commit"` + // Author is the GitHub/Gitea user who authored the commit + Author *User `json:"author"` + // Committer is the GitHub/Gitea user who committed the commit + Committer *User `json:"committer"` + // Parents contains the parent commit information + Parents []*CommitMeta `json:"parents"` + // Files contains information about files affected by the commit + Files []*CommitAffectedFiles `json:"files"` + // Stats contains statistics about the commit changes + Stats *CommitStats `json:"stats"` } // CommitDateOptions store dates for GIT_AUTHOR_DATE and GIT_COMMITTER_DATE type CommitDateOptions struct { // swagger:strfmt date-time + // Author is the author date for the commit Author time.Time `json:"author"` // swagger:strfmt date-time + // Committer is the committer date for the commit Committer time.Time `json:"committer"` } // CommitAffectedFiles store information about files affected by the commit type CommitAffectedFiles struct { + // Filename is the path of the affected file Filename string `json:"filename"` - Status string `json:"status"` + // Status indicates how the file was affected (added, modified, deleted) + Status string `json:"status"` } diff --git a/modules/structs/repo_file.go b/modules/structs/repo_file.go index 5a86db868b..99efe19e4f 100644 --- a/modules/structs/repo_file.go +++ b/modules/structs/repo_file.go @@ -104,83 +104,117 @@ type ApplyDiffPatchFileOptions struct { // FileLinksResponse contains the links for a repo's file type FileLinksResponse struct { - Self *string `json:"self"` - GitURL *string `json:"git"` + // Self is the API URL for this file + Self *string `json:"self"` + // GitURL is the Git API URL for this file + GitURL *string `json:"git"` + // HTMLURL is the web URL for this file HTMLURL *string `json:"html"` } type ContentsExtResponse struct { - FileContents *ContentsResponse `json:"file_contents,omitempty"` - DirContents []*ContentsResponse `json:"dir_contents,omitempty"` + // FileContents contains file information when the path represents a file + FileContents *ContentsResponse `json:"file_contents,omitempty"` + // DirContents contains directory listing when the path represents a directory + DirContents []*ContentsResponse `json:"dir_contents,omitempty"` } // ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content type ContentsResponse struct { + // Name is the file or directory name Name string `json:"name"` + // Path is the full path to the file or directory Path string `json:"path"` - SHA string `json:"sha"` + // SHA is the Git blob or tree SHA + SHA string `json:"sha"` + // LastCommitSHA is the SHA of the last commit that affected this file LastCommitSHA *string `json:"last_commit_sha,omitempty"` // swagger:strfmt date-time LastCommitterDate *time.Time `json:"last_committer_date,omitempty"` // swagger:strfmt date-time - LastAuthorDate *time.Time `json:"last_author_date,omitempty"` - LastCommitMessage *string `json:"last_commit_message,omitempty"` + LastAuthorDate *time.Time `json:"last_author_date,omitempty"` + // LastCommitMessage is the message of the last commit that affected this file + LastCommitMessage *string `json:"last_commit_message,omitempty"` // `type` will be `file`, `dir`, `symlink`, or `submodule` Type string `json:"type"` - Size int64 `json:"size"` + // Size is the file size in bytes + Size int64 `json:"size"` // `encoding` is populated when `type` is `file`, otherwise null Encoding *string `json:"encoding"` // `content` is populated when `type` is `file`, otherwise null Content *string `json:"content"` // `target` is populated when `type` is `symlink`, otherwise null - Target *string `json:"target"` - URL *string `json:"url"` - HTMLURL *string `json:"html_url"` - GitURL *string `json:"git_url"` + Target *string `json:"target"` + // URL is the API URL for this file or directory + URL *string `json:"url"` + // HTMLURL is the web URL for this file or directory + HTMLURL *string `json:"html_url"` + // GitURL is the Git API URL for this blob or tree + GitURL *string `json:"git_url"` + // DownloadURL is the direct download URL for this file DownloadURL *string `json:"download_url"` // `submodule_git_url` is populated when `type` is `submodule`, otherwise null - SubmoduleGitURL *string `json:"submodule_git_url"` - Links *FileLinksResponse `json:"_links"` + SubmoduleGitURL *string `json:"submodule_git_url"` + // Links contains related URLs for this file or directory + Links *FileLinksResponse `json:"_links"` - LfsOid *string `json:"lfs_oid,omitempty"` - LfsSize *int64 `json:"lfs_size,omitempty"` + // LfsOid is the Git LFS object ID if this file is stored in LFS + LfsOid *string `json:"lfs_oid,omitempty"` + // LfsSize is the file size if this file is stored in LFS + LfsSize *int64 `json:"lfs_size,omitempty"` } // FileCommitResponse contains information generated from a Git commit for a repo's file. type FileCommitResponse struct { CommitMeta - HTMLURL string `json:"html_url"` - Author *CommitUser `json:"author"` - Committer *CommitUser `json:"committer"` - Parents []*CommitMeta `json:"parents"` - Message string `json:"message"` - Tree *CommitMeta `json:"tree"` + // HTMLURL is the web URL for viewing this commit + HTMLURL string `json:"html_url"` + // Author is the commit author information + Author *CommitUser `json:"author"` + // Committer is the commit committer information + Committer *CommitUser `json:"committer"` + // Parents contains parent commit metadata + Parents []*CommitMeta `json:"parents"` + // Message is the commit message + Message string `json:"message"` + // Tree contains the tree metadata for this commit + Tree *CommitMeta `json:"tree"` } // FileResponse contains information about a repo's file type FileResponse struct { - Content *ContentsResponse `json:"content"` - Commit *FileCommitResponse `json:"commit"` + // Content contains the file content and metadata + Content *ContentsResponse `json:"content"` + // Commit contains the commit information for this file operation + Commit *FileCommitResponse `json:"commit"` + // Verification contains the commit signature verification information Verification *PayloadCommitVerification `json:"verification"` } // FilesResponse contains information about multiple files from a repo type FilesResponse struct { - Files []*ContentsResponse `json:"files"` - Commit *FileCommitResponse `json:"commit"` + // Files contains the list of file contents and metadata + Files []*ContentsResponse `json:"files"` + // Commit contains the commit information for this file operation + Commit *FileCommitResponse `json:"commit"` + // Verification contains the commit signature verification information Verification *PayloadCommitVerification `json:"verification"` } // FileDeleteResponse contains information about a repo's file that was deleted type FileDeleteResponse struct { - Content any `json:"content"` // to be set to nil - Commit *FileCommitResponse `json:"commit"` + // Content is always null for delete operations + Content any `json:"content"` // to be set to nil + // Commit contains the commit information for this delete operation + Commit *FileCommitResponse `json:"commit"` + // Verification contains the commit signature verification information Verification *PayloadCommitVerification `json:"verification"` } // GetFilesOptions options for retrieving metadate and content of multiple files type GetFilesOptions struct { + // Files is the list of file paths to retrieve Files []string `json:"files" binding:"Required"` } diff --git a/modules/structs/repo_key.go b/modules/structs/repo_key.go index 27b9d05a75..a13cde71fb 100644 --- a/modules/structs/repo_key.go +++ b/modules/structs/repo_key.go @@ -9,15 +9,24 @@ import ( // DeployKey a deploy key type DeployKey struct { - ID int64 `json:"id"` - KeyID int64 `json:"key_id"` - Key string `json:"key"` - URL string `json:"url"` - Title string `json:"title"` + // ID is the unique identifier for the deploy key + ID int64 `json:"id"` + // KeyID is the associated public key ID + KeyID int64 `json:"key_id"` + // Key contains the actual SSH key content + Key string `json:"key"` + // URL is the API URL for this deploy key + URL string `json:"url"` + // Title is the human-readable name for the key + Title string `json:"title"` + // Fingerprint is the key's fingerprint Fingerprint string `json:"fingerprint"` // swagger:strfmt date-time - Created time.Time `json:"created_at"` - ReadOnly bool `json:"read_only"` + // Created is the time when the deploy key was added + Created time.Time `json:"created_at"` + // ReadOnly indicates if the key has read-only access + ReadOnly bool `json:"read_only"` + // Repository is the repository this deploy key belongs to Repository *Repository `json:"repository,omitempty"` } diff --git a/modules/structs/repo_note.go b/modules/structs/repo_note.go index 4eaf5a255d..fcd3f7abd6 100644 --- a/modules/structs/repo_note.go +++ b/modules/structs/repo_note.go @@ -5,6 +5,8 @@ package structs // Note contains information related to a git note type Note struct { - Message string `json:"message"` - Commit *Commit `json:"commit"` + // The content message of the git note + Message string `json:"message"` + // The commit that this note is attached to + Commit *Commit `json:"commit"` } diff --git a/modules/structs/repo_refs.go b/modules/structs/repo_refs.go index 6ffbc74a51..9ea7f4305e 100644 --- a/modules/structs/repo_refs.go +++ b/modules/structs/repo_refs.go @@ -5,14 +5,20 @@ package structs // Reference represents a Git reference. type Reference struct { - Ref string `json:"ref"` - URL string `json:"url"` + // The name of the Git reference (e.g., refs/heads/main) + Ref string `json:"ref"` + // The URL to access this Git reference + URL string `json:"url"` + // The Git object that this reference points to Object *GitObject `json:"object"` } // GitObject represents a Git object. type GitObject struct { + // The type of the Git object (e.g., commit, tag, tree, blob) Type string `json:"type"` - SHA string `json:"sha"` - URL string `json:"url"` + // The SHA hash of the Git object + SHA string `json:"sha"` + // The URL to access this Git object + URL string `json:"url"` } diff --git a/modules/structs/repo_tag.go b/modules/structs/repo_tag.go index bb8bfd10cb..429c715ad9 100644 --- a/modules/structs/repo_tag.go +++ b/modules/structs/repo_tag.go @@ -7,62 +7,93 @@ import "time" // Tag represents a repository tag type Tag struct { - Name string `json:"name"` - Message string `json:"message"` - ID string `json:"id"` - Commit *CommitMeta `json:"commit"` - ZipballURL string `json:"zipball_url,omitempty"` - TarballURL string `json:"tarball_url,omitempty"` + // The name of the tag + Name string `json:"name"` + // The message associated with the tag + Message string `json:"message"` + // The ID (SHA) of the tag + ID string `json:"id"` + // The commit information associated with this tag + Commit *CommitMeta `json:"commit"` + // The URL to download the zipball archive + ZipballURL string `json:"zipball_url,omitempty"` + // The URL to download the tarball archive + TarballURL string `json:"tarball_url,omitempty"` } // AnnotatedTag represents an annotated tag type AnnotatedTag struct { - Tag string `json:"tag"` - SHA string `json:"sha"` - URL string `json:"url"` - Message string `json:"message"` - Tagger *CommitUser `json:"tagger"` - Object *AnnotatedTagObject `json:"object"` + // The name of the annotated tag + Tag string `json:"tag"` + // The SHA hash of the annotated tag + SHA string `json:"sha"` + // The URL to access the annotated tag + URL string `json:"url"` + // The message associated with the annotated tag + Message string `json:"message"` + // The user who created the annotated tag + Tagger *CommitUser `json:"tagger"` + // The object that the annotated tag points to + Object *AnnotatedTagObject `json:"object"` + // The verification information for the annotated tag Verification *PayloadCommitVerification `json:"verification"` } // AnnotatedTagObject contains meta information of the tag object type AnnotatedTagObject struct { + // The type of the tagged object (e.g., commit, tree) Type string `json:"type"` - URL string `json:"url"` - SHA string `json:"sha"` + // The URL to access the tagged object + URL string `json:"url"` + // The SHA hash of the tagged object + SHA string `json:"sha"` } // CreateTagOption options when creating a tag type CreateTagOption struct { // required: true + // The name of the tag to create TagName string `json:"tag_name" binding:"Required"` + // The message to associate with the tag Message string `json:"message"` - Target string `json:"target"` + // The target commit SHA or branch name for the tag + Target string `json:"target"` } // TagProtection represents a tag protection type TagProtection struct { - ID int64 `json:"id"` - NamePattern string `json:"name_pattern"` + // The unique identifier of the tag protection + ID int64 `json:"id"` + // The pattern to match tag names for protection + NamePattern string `json:"name_pattern"` + // List of usernames allowed to create/delete protected tags WhitelistUsernames []string `json:"whitelist_usernames"` - WhitelistTeams []string `json:"whitelist_teams"` + // List of team names allowed to create/delete protected tags + WhitelistTeams []string `json:"whitelist_teams"` // swagger:strfmt date-time + // The date and time when the tag protection was created Created time.Time `json:"created_at"` // swagger:strfmt date-time + // The date and time when the tag protection was last updated Updated time.Time `json:"updated_at"` } // CreateTagProtectionOption options for creating a tag protection type CreateTagProtectionOption struct { - NamePattern string `json:"name_pattern"` + // The pattern to match tag names for protection + NamePattern string `json:"name_pattern"` + // List of usernames allowed to create/delete protected tags WhitelistUsernames []string `json:"whitelist_usernames"` - WhitelistTeams []string `json:"whitelist_teams"` + // List of team names allowed to create/delete protected tags + WhitelistTeams []string `json:"whitelist_teams"` } // EditTagProtectionOption options for editing a tag protection type EditTagProtectionOption struct { - NamePattern *string `json:"name_pattern"` + // The pattern to match tag names for protection + NamePattern *string `json:"name_pattern"` + // List of usernames allowed to create/delete protected tags WhitelistUsernames []string `json:"whitelist_usernames"` - WhitelistTeams []string `json:"whitelist_teams"` + // List of team names allowed to create/delete protected tags + WhitelistTeams []string `json:"whitelist_teams"` } diff --git a/modules/structs/repo_topic.go b/modules/structs/repo_topic.go index fea193e86b..6a79297943 100644 --- a/modules/structs/repo_topic.go +++ b/modules/structs/repo_topic.go @@ -9,15 +9,21 @@ import ( // TopicResponse for returning topics type TopicResponse struct { - ID int64 `json:"id"` - Name string `json:"topic_name"` - RepoCount int `json:"repo_count"` - Created time.Time `json:"created"` - Updated time.Time `json:"updated"` + // The unique identifier of the topic + ID int64 `json:"id"` + // The name of the topic + Name string `json:"topic_name"` + // The number of repositories using this topic + RepoCount int `json:"repo_count"` + // The date and time when the topic was created + Created time.Time `json:"created"` + // The date and time when the topic was last updated + Updated time.Time `json:"updated"` } // TopicName a list of repo topic names type TopicName struct { + // List of topic names TopicNames []string `json:"topics"` } diff --git a/modules/structs/repo_tree.go b/modules/structs/repo_tree.go index 86b221e1fe..9d91f303b7 100644 --- a/modules/structs/repo_tree.go +++ b/modules/structs/repo_tree.go @@ -5,20 +5,32 @@ package structs // GitEntry represents a git tree type GitEntry struct { + // Path is the file or directory path Path string `json:"path"` + // Mode is the file mode (permissions) Mode string `json:"mode"` + // Type indicates if this is a file, directory, or symlink Type string `json:"type"` - Size int64 `json:"size"` - SHA string `json:"sha"` - URL string `json:"url"` + // Size is the file size in bytes + Size int64 `json:"size"` + // SHA is the Git object SHA + SHA string `json:"sha"` + // URL is the API URL for this tree entry + URL string `json:"url"` } // GitTreeResponse returns a git tree type GitTreeResponse struct { - SHA string `json:"sha"` - URL string `json:"url"` - Entries []GitEntry `json:"tree"` - Truncated bool `json:"truncated"` - Page int `json:"page"` - TotalCount int `json:"total_count"` + // SHA is the tree object SHA + SHA string `json:"sha"` + // URL is the API URL for this tree + URL string `json:"url"` + // Entries contains the tree entries (files and directories) + Entries []GitEntry `json:"tree"` + // Truncated indicates if the response was truncated due to size + Truncated bool `json:"truncated"` + // Page is the current page number for pagination + Page int `json:"page"` + // TotalCount is the total number of entries in the tree + TotalCount int `json:"total_count"` } diff --git a/modules/structs/repo_watch.go b/modules/structs/repo_watch.go index 0d0b7c4ae0..439af28892 100644 --- a/modules/structs/repo_watch.go +++ b/modules/structs/repo_watch.go @@ -9,10 +9,16 @@ import ( // WatchInfo represents an API watch status of one repository type WatchInfo struct { - Subscribed bool `json:"subscribed"` - Ignored bool `json:"ignored"` - Reason any `json:"reason"` - CreatedAt time.Time `json:"created_at"` - URL string `json:"url"` - RepositoryURL string `json:"repository_url"` + // Whether the repository is being watched for notifications + Subscribed bool `json:"subscribed"` + // Whether notifications for the repository are ignored + Ignored bool `json:"ignored"` + // The reason for the current watch status + Reason any `json:"reason"` + // The timestamp when the watch status was created + CreatedAt time.Time `json:"created_at"` + // The URL for managing the watch status + URL string `json:"url"` + // The URL of the repository being watched + RepositoryURL string `json:"repository_url"` } diff --git a/modules/structs/repo_wiki.go b/modules/structs/repo_wiki.go index 3df5a0be99..1944c1a3f7 100644 --- a/modules/structs/repo_wiki.go +++ b/modules/structs/repo_wiki.go @@ -5,10 +5,14 @@ package structs // WikiCommit page commit/revision type WikiCommit struct { - ID string `json:"sha"` - Author *CommitUser `json:"author"` + // The commit SHA hash + ID string `json:"sha"` + // The author of the commit + Author *CommitUser `json:"author"` + // The committer of the commit Committer *CommitUser `json:"commiter"` - Message string `json:"message"` + // The commit message + Message string `json:"message"` } // WikiPage a wiki page @@ -16,16 +20,23 @@ type WikiPage struct { *WikiPageMetaData // Page content, base64 encoded ContentBase64 string `json:"content_base64"` - CommitCount int64 `json:"commit_count"` - Sidebar string `json:"sidebar"` - Footer string `json:"footer"` + // The number of commits that modified this page + CommitCount int64 `json:"commit_count"` + // The sidebar content for the wiki page + Sidebar string `json:"sidebar"` + // The footer content for the wiki page + Footer string `json:"footer"` } // WikiPageMetaData wiki page meta information type WikiPageMetaData struct { - Title string `json:"title"` - HTMLURL string `json:"html_url"` - SubURL string `json:"sub_url"` + // The title of the wiki page + Title string `json:"title"` + // The HTML URL to view the wiki page + HTMLURL string `json:"html_url"` + // The sub URL path for the wiki page + SubURL string `json:"sub_url"` + // The last commit that modified this wiki page LastCommit *WikiCommit `json:"last_commit"` } @@ -41,6 +52,8 @@ type CreateWikiPageOptions struct { // WikiCommitList commit/revision list type WikiCommitList struct { + // The list of wiki commits WikiCommits []*WikiCommit `json:"commits"` - Count int64 `json:"count"` + // The total count of commits + Count int64 `json:"count"` } diff --git a/modules/structs/settings.go b/modules/structs/settings.go index 59176210e6..403afda9ff 100644 --- a/modules/structs/settings.go +++ b/modules/structs/settings.go @@ -5,34 +5,52 @@ package structs // GeneralRepoSettings contains global repository settings exposed by API type GeneralRepoSettings struct { - MirrorsDisabled bool `json:"mirrors_disabled"` - HTTPGitDisabled bool `json:"http_git_disabled"` - MigrationsDisabled bool `json:"migrations_disabled"` - StarsDisabled bool `json:"stars_disabled"` + // MirrorsDisabled indicates if repository mirroring is disabled + MirrorsDisabled bool `json:"mirrors_disabled"` + // HTTPGitDisabled indicates if HTTP Git operations are disabled + HTTPGitDisabled bool `json:"http_git_disabled"` + // MigrationsDisabled indicates if repository migrations are disabled + MigrationsDisabled bool `json:"migrations_disabled"` + // StarsDisabled indicates if repository starring is disabled + StarsDisabled bool `json:"stars_disabled"` + // TimeTrackingDisabled indicates if time tracking is disabled TimeTrackingDisabled bool `json:"time_tracking_disabled"` - LFSDisabled bool `json:"lfs_disabled"` + // LFSDisabled indicates if Git LFS support is disabled + LFSDisabled bool `json:"lfs_disabled"` } // GeneralUISettings contains global ui settings exposed by API type GeneralUISettings struct { - DefaultTheme string `json:"default_theme"` + // DefaultTheme is the default UI theme + DefaultTheme string `json:"default_theme"` + // AllowedReactions contains the list of allowed emoji reactions AllowedReactions []string `json:"allowed_reactions"` - CustomEmojis []string `json:"custom_emojis"` + // CustomEmojis contains the list of custom emojis + CustomEmojis []string `json:"custom_emojis"` } // GeneralAPISettings contains global api settings exposed by it type GeneralAPISettings struct { - MaxResponseItems int `json:"max_response_items"` - DefaultPagingNum int `json:"default_paging_num"` - DefaultGitTreesPerPage int `json:"default_git_trees_per_page"` - DefaultMaxBlobSize int64 `json:"default_max_blob_size"` + // MaxResponseItems is the maximum number of items returned in API responses + MaxResponseItems int `json:"max_response_items"` + // DefaultPagingNum is the default number of items per page + DefaultPagingNum int `json:"default_paging_num"` + // DefaultGitTreesPerPage is the default number of Git tree items per page + DefaultGitTreesPerPage int `json:"default_git_trees_per_page"` + // DefaultMaxBlobSize is the default maximum blob size for API responses + DefaultMaxBlobSize int64 `json:"default_max_blob_size"` + // DefaultMaxResponseSize is the default maximum response size DefaultMaxResponseSize int64 `json:"default_max_response_size"` } // GeneralAttachmentSettings contains global Attachment settings exposed by API type GeneralAttachmentSettings struct { - Enabled bool `json:"enabled"` + // Enabled indicates if file attachments are enabled + Enabled bool `json:"enabled"` + // AllowedTypes contains the allowed file types for attachments AllowedTypes string `json:"allowed_types"` - MaxSize int64 `json:"max_size"` - MaxFiles int `json:"max_files"` + // MaxSize is the maximum size for individual attachments + MaxSize int64 `json:"max_size"` + // MaxFiles is the maximum number of files per attachment + MaxFiles int `json:"max_files"` } diff --git a/modules/structs/status.go b/modules/structs/status.go index a9779541ff..923a245c46 100644 --- a/modules/structs/status.go +++ b/modules/structs/status.go @@ -11,13 +11,20 @@ import ( // CommitStatus holds a single status of a single Commit type CommitStatus struct { - ID int64 `json:"id"` - State commitstatus.CommitStatusState `json:"status"` - TargetURL string `json:"target_url"` - Description string `json:"description"` - URL string `json:"url"` - Context string `json:"context"` - Creator *User `json:"creator"` + // ID is the unique identifier for the commit status + ID int64 `json:"id"` + // State represents the status state (pending, success, error, failure) + State commitstatus.CommitStatusState `json:"status"` + // TargetURL is the URL to link to for more details + TargetURL string `json:"target_url"` + // Description provides a brief description of the status + Description string `json:"description"` + // URL is the API URL for this status + URL string `json:"url"` + // Context is the unique context identifier for the status + Context string `json:"context"` + // Creator is the user who created the status + Creator *User `json:"creator"` // swagger:strfmt date-time Created time.Time `json:"created_at"` // swagger:strfmt date-time @@ -26,19 +33,30 @@ type CommitStatus struct { // CombinedStatus holds the combined state of several statuses for a single commit type CombinedStatus struct { - State commitstatus.CommitStatusState `json:"state"` - SHA string `json:"sha"` - TotalCount int `json:"total_count"` - Statuses []*CommitStatus `json:"statuses"` - Repository *Repository `json:"repository"` - CommitURL string `json:"commit_url"` - URL string `json:"url"` + // State is the overall combined status state + State commitstatus.CommitStatusState `json:"state"` + // SHA is the commit SHA this status applies to + SHA string `json:"sha"` + // TotalCount is the total number of statuses + TotalCount int `json:"total_count"` + // Statuses contains all individual commit statuses + Statuses []*CommitStatus `json:"statuses"` + // Repository is the repository this status belongs to + Repository *Repository `json:"repository"` + // CommitURL is the API URL for the commit + CommitURL string `json:"commit_url"` + // URL is the API URL for this combined status + URL string `json:"url"` } // CreateStatusOption holds the information needed to create a new CommitStatus for a Commit type CreateStatusOption struct { - State commitstatus.CommitStatusState `json:"state"` - TargetURL string `json:"target_url"` - Description string `json:"description"` - Context string `json:"context"` + // State represents the status state to set (pending, success, error, failure) + State commitstatus.CommitStatusState `json:"state"` + // TargetURL is the URL to link to for more details + TargetURL string `json:"target_url"` + // Description provides a brief description of the status + Description string `json:"description"` + // Context is the unique context identifier for the status + Context string `json:"context"` } diff --git a/modules/structs/user_app.go b/modules/structs/user_app.go index 15811ceb66..76add1c635 100644 --- a/modules/structs/user_app.go +++ b/modules/structs/user_app.go @@ -11,13 +11,20 @@ import ( // AccessToken represents an API access token. // swagger:response AccessToken type AccessToken struct { - ID int64 `json:"id"` - Name string `json:"name"` - Token string `json:"sha1"` - TokenLastEight string `json:"token_last_eight"` - Scopes []string `json:"scopes"` - Created time.Time `json:"created_at"` - Updated time.Time `json:"last_used_at"` + // The unique identifier of the access token + ID int64 `json:"id"` + // The name of the access token + Name string `json:"name"` + // The SHA1 hash of the access token + Token string `json:"sha1"` + // The last eight characters of the token + TokenLastEight string `json:"token_last_eight"` + // The scopes granted to this access token + Scopes []string `json:"scopes"` + // The timestamp when the token was created + Created time.Time `json:"created_at"` + // The timestamp when the token was last used + Updated time.Time `json:"last_used_at"` } // AccessTokenList represents a list of API access token. @@ -35,23 +42,35 @@ type CreateAccessTokenOption struct { // CreateOAuth2ApplicationOptions holds options to create an oauth2 application type CreateOAuth2ApplicationOptions struct { - Name string `json:"name" binding:"Required"` - ConfidentialClient bool `json:"confidential_client"` - SkipSecondaryAuthorization bool `json:"skip_secondary_authorization"` - RedirectURIs []string `json:"redirect_uris" binding:"Required"` + // The name of the OAuth2 application + Name string `json:"name" binding:"Required"` + // Whether the client is confidential + ConfidentialClient bool `json:"confidential_client"` + // Whether to skip secondary authorization + SkipSecondaryAuthorization bool `json:"skip_secondary_authorization"` + // The list of allowed redirect URIs + RedirectURIs []string `json:"redirect_uris" binding:"Required"` } // OAuth2Application represents an OAuth2 application. // swagger:response OAuth2Application type OAuth2Application struct { - ID int64 `json:"id"` - Name string `json:"name"` - ClientID string `json:"client_id"` - ClientSecret string `json:"client_secret"` - ConfidentialClient bool `json:"confidential_client"` - SkipSecondaryAuthorization bool `json:"skip_secondary_authorization"` - RedirectURIs []string `json:"redirect_uris"` - Created time.Time `json:"created"` + // The unique identifier of the OAuth2 application + ID int64 `json:"id"` + // The name of the OAuth2 application + Name string `json:"name"` + // The client ID of the OAuth2 application + ClientID string `json:"client_id"` + // The client secret of the OAuth2 application + ClientSecret string `json:"client_secret"` + // Whether the client is confidential + ConfidentialClient bool `json:"confidential_client"` + // Whether to skip secondary authorization + SkipSecondaryAuthorization bool `json:"skip_secondary_authorization"` + // The list of allowed redirect URIs + RedirectURIs []string `json:"redirect_uris"` + // The timestamp when the application was created + Created time.Time `json:"created"` } // OAuth2ApplicationList represents a list of OAuth2 applications. diff --git a/modules/structs/user_email.go b/modules/structs/user_email.go index 01895a0058..57e4af1993 100644 --- a/modules/structs/user_email.go +++ b/modules/structs/user_email.go @@ -7,10 +7,14 @@ package structs // Email an email address belonging to a user type Email struct { // swagger:strfmt email - Email string `json:"email"` - Verified bool `json:"verified"` - Primary bool `json:"primary"` - UserID int64 `json:"user_id"` + // The email address + Email string `json:"email"` + // Whether the email address has been verified + Verified bool `json:"verified"` + // Whether this is the primary email address + Primary bool `json:"primary"` + // The unique identifier of the user who owns this email + UserID int64 `json:"user_id"` // username of the user UserName string `json:"username"` } diff --git a/modules/structs/user_gpgkey.go b/modules/structs/user_gpgkey.go index deae70de33..183a26c3b4 100644 --- a/modules/structs/user_gpgkey.go +++ b/modules/structs/user_gpgkey.go @@ -9,28 +9,43 @@ import ( // GPGKey a user GPG key to sign commit and tag in repository type GPGKey struct { - ID int64 `json:"id"` - PrimaryKeyID string `json:"primary_key_id"` - KeyID string `json:"key_id"` - PublicKey string `json:"public_key"` - Emails []*GPGKeyEmail `json:"emails"` - SubsKey []*GPGKey `json:"subkeys"` - CanSign bool `json:"can_sign"` - CanEncryptComms bool `json:"can_encrypt_comms"` - CanEncryptStorage bool `json:"can_encrypt_storage"` - CanCertify bool `json:"can_certify"` - Verified bool `json:"verified"` + // The unique identifier of the GPG key + ID int64 `json:"id"` + // The primary key ID of the GPG key + PrimaryKeyID string `json:"primary_key_id"` + // The key ID of the GPG key + KeyID string `json:"key_id"` + // The public key content in armored format + PublicKey string `json:"public_key"` + // List of email addresses associated with this GPG key + Emails []*GPGKeyEmail `json:"emails"` + // List of subkeys of this GPG key + SubsKey []*GPGKey `json:"subkeys"` + // Whether the key can be used for signing + CanSign bool `json:"can_sign"` + // Whether the key can be used for encrypting communications + CanEncryptComms bool `json:"can_encrypt_comms"` + // Whether the key can be used for encrypting storage + CanEncryptStorage bool `json:"can_encrypt_storage"` + // Whether the key can be used for certification + CanCertify bool `json:"can_certify"` + // Whether the GPG key has been verified + Verified bool `json:"verified"` // swagger:strfmt date-time + // The date and time when the GPG key was created Created time.Time `json:"created_at"` // swagger:strfmt date-time + // The date and time when the GPG key expires Expires time.Time `json:"expires_at"` } // GPGKeyEmail an email attached to a GPGKey // swagger:model GPGKeyEmail type GPGKeyEmail struct { - Email string `json:"email"` - Verified bool `json:"verified"` + // The email address associated with the GPG key + Email string `json:"email"` + // Whether the email address has been verified + Verified bool `json:"verified"` } // CreateGPGKeyOption options create user GPG key @@ -40,7 +55,8 @@ type CreateGPGKeyOption struct { // required: true // unique: true ArmoredKey string `json:"armored_public_key" binding:"Required"` - Signature string `json:"armored_signature,omitempty"` + // An optional armored signature for the GPG key + Signature string `json:"armored_signature,omitempty"` } // VerifyGPGKeyOption options verifies user GPG key @@ -48,6 +64,8 @@ type VerifyGPGKeyOption struct { // An Signature for a GPG key token // // required: true - KeyID string `json:"key_id" binding:"Required"` + // The key ID of the GPG key to verify + KeyID string `json:"key_id" binding:"Required"` + // The armored signature to verify the GPG key Signature string `json:"armored_signature" binding:"Required"` } diff --git a/modules/structs/user_key.go b/modules/structs/user_key.go index 16225a852a..f61ce5df10 100644 --- a/modules/structs/user_key.go +++ b/modules/structs/user_key.go @@ -9,15 +9,25 @@ import ( // PublicKey publickey is a user key to push code to repository type PublicKey struct { - ID int64 `json:"id"` - Key string `json:"key"` - URL string `json:"url,omitempty"` - Title string `json:"title,omitempty"` + // ID is the unique identifier for the public key + ID int64 `json:"id"` + // Key contains the actual SSH public key content + Key string `json:"key"` + // URL is the API URL for this key + URL string `json:"url,omitempty"` + // Title is the human-readable name for the key + Title string `json:"title,omitempty"` + // Fingerprint is the key's fingerprint Fingerprint string `json:"fingerprint,omitempty"` // swagger:strfmt date-time - Created time.Time `json:"created_at"` - Updated time.Time `json:"last_used_at"` - Owner *User `json:"user,omitempty"` - ReadOnly bool `json:"read_only,omitempty"` - KeyType string `json:"key_type,omitempty"` + // Created is the time when the key was added + Created time.Time `json:"created_at"` + // Updated is the time when the key was last used + Updated time.Time `json:"last_used_at"` + // Owner is the user who owns this key + Owner *User `json:"user,omitempty"` + // ReadOnly indicates if the key has read-only access + ReadOnly bool `json:"read_only,omitempty"` + // KeyType indicates the type of the SSH key + KeyType string `json:"key_type,omitempty"` } diff --git a/modules/system/appstate_test.go b/modules/system/appstate_test.go index b5c057cf88..509210127d 100644 --- a/modules/system/appstate_test.go +++ b/modules/system/appstate_test.go @@ -6,7 +6,6 @@ package system import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert" @@ -37,25 +36,25 @@ func TestAppStateDB(t *testing.T) { as := &DBStore{} item1 := new(testItem1) - assert.NoError(t, as.Get(db.DefaultContext, item1)) + assert.NoError(t, as.Get(t.Context(), item1)) assert.Empty(t, item1.Val1) assert.Equal(t, 0, item1.Val2) item1 = new(testItem1) item1.Val1 = "a" item1.Val2 = 2 - assert.NoError(t, as.Set(db.DefaultContext, item1)) + assert.NoError(t, as.Set(t.Context(), item1)) item2 := new(testItem2) item2.K = "V" - assert.NoError(t, as.Set(db.DefaultContext, item2)) + assert.NoError(t, as.Set(t.Context(), item2)) item1 = new(testItem1) - assert.NoError(t, as.Get(db.DefaultContext, item1)) + assert.NoError(t, as.Get(t.Context(), item1)) assert.Equal(t, "a", item1.Val1) assert.Equal(t, 2, item1.Val2) item2 = new(testItem2) - assert.NoError(t, as.Get(db.DefaultContext, item2)) + assert.NoError(t, as.Get(t.Context(), item2)) assert.Equal(t, "V", item2.K) } diff --git a/modules/templates/util_format_test.go b/modules/templates/util_format_test.go index 13a57c24e2..89e42532f9 100644 --- a/modules/templates/util_format_test.go +++ b/modules/templates/util_format_test.go @@ -13,6 +13,6 @@ func TestCountFmt(t *testing.T) { assert.Equal(t, "125", countFmt(125)) assert.Equal(t, "1.3k", countFmt(int64(1317))) assert.Equal(t, "21.3M", countFmt(21317675)) - assert.Equal(t, "45.7G", countFmt(45721317675)) + assert.Equal(t, "45.7G", countFmt(int64(45721317675))) assert.Empty(t, countFmt("test")) } diff --git a/modules/templates/util_misc.go b/modules/templates/util_misc.go index cc5bf67b42..4cf339ef42 100644 --- a/modules/templates/util_misc.go +++ b/modules/templates/util_misc.go @@ -14,8 +14,7 @@ import ( activities_model "code.gitea.io/gitea/models/activities" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/git" - giturl "code.gitea.io/gitea/modules/git/url" + "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/repository" @@ -145,18 +144,12 @@ type remoteAddress struct { func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteName string) remoteAddress { ret := remoteAddress{} - remoteURL, err := git.GetRemoteAddress(ctx, m.RepoPath(), remoteName) + u, err := gitrepo.GitRemoteGetURL(ctx, m, remoteName) if err != nil { log.Error("GetRemoteURL %v", err) return ret } - u, err := giturl.ParseGitURL(remoteURL) - if err != nil { - log.Error("giturl.Parse %v", err) - return ret - } - if u.Scheme != "ssh" && u.Scheme != "file" { if u.User != nil { ret.Username = u.User.Username() diff --git a/modules/web/handler.go b/modules/web/handler.go index 42a649714d..843b17e8d1 100644 --- a/modules/web/handler.go +++ b/modules/web/handler.go @@ -16,7 +16,7 @@ import ( var responseStatusProviders = map[reflect.Type]func(req *http.Request) types.ResponseStatusProvider{} func RegisterResponseStatusProvider[T any](fn func(req *http.Request) types.ResponseStatusProvider) { - responseStatusProviders[reflect.TypeOf((*T)(nil)).Elem()] = fn + responseStatusProviders[reflect.TypeFor[T]()] = fn } // responseWriter is a wrapper of http.ResponseWriter, to check whether the response has been written @@ -48,8 +48,8 @@ func (r *responseWriter) WriteHeader(statusCode int) { } var ( - httpReqType = reflect.TypeOf((*http.Request)(nil)) - respWriterType = reflect.TypeOf((*http.ResponseWriter)(nil)).Elem() + httpReqType = reflect.TypeFor[*http.Request]() + respWriterType = reflect.TypeFor[http.ResponseWriter]() ) // preCheckHandler checks whether the handler is valid, developers could get first-time feedback, all mistakes could be found at startup diff --git a/options/fileicon/material-icon-rules.json b/options/fileicon/material-icon-rules.json index caa068ff44..622564fe2b 100644 --- a/options/fileicon/material-icon-rules.json +++ b/options/fileicon/material-icon-rules.json @@ -72,6 +72,14 @@ ".distribution": "folder-dist", "_distribution": "folder-dist", "__distribution__": "folder-dist", + "built": "folder-dist", + ".built": "folder-dist", + "_built": "folder-dist", + "__built__": "folder-dist", + "compiled": "folder-dist", + ".compiled": "folder-dist", + "_compiled": "folder-dist", + "__compiled__": "folder-dist", "css": "folder-css", ".css": "folder-css", "_css": "folder-css", @@ -120,6 +128,30 @@ ".console": "folder-console", "_console": "folder-console", "__console__": "folder-console", + "xbox": "folder-console", + ".xbox": "folder-console", + "_xbox": "folder-console", + "__xbox__": "folder-console", + "ps4": "folder-console", + ".ps4": "folder-console", + "_ps4": "folder-console", + "__ps4__": "folder-console", + "ps5": "folder-console", + ".ps5": "folder-console", + "_ps5": "folder-console", + "__ps5__": "folder-console", + "switch": "folder-console", + ".switch": "folder-console", + "_switch": "folder-console", + "__switch__": "folder-console", + "game": "folder-console", + ".game": "folder-console", + "_game": "folder-console", + "__game__": "folder-console", + "games": "folder-console", + ".games": "folder-console", + "_games": "folder-console", + "__games__": "folder-console", "images": "folder-images", ".images": "folder-images", "_images": "folder-images", @@ -216,6 +248,14 @@ ".photographs": "folder-images", "_photographs": "folder-images", "__photographs__": "folder-images", + "texture": "folder-images", + ".texture": "folder-images", + "_texture": "folder-images", + "__texture__": "folder-images", + "textures": "folder-images", + ".textures": "folder-images", + "_textures": "folder-images", + "__textures__": "folder-images", "script": "folder-scripts", ".script": "folder-scripts", "_script": "folder-scripts", @@ -252,6 +292,14 @@ ".javascripts": "folder-javascript", "_javascripts": "folder-javascript", "__javascripts__": "folder-javascript", + "cjs": "folder-javascript", + ".cjs": "folder-javascript", + "_cjs": "folder-javascript", + "__cjs__": "folder-javascript", + "mjs": "folder-javascript", + ".mjs": "folder-javascript", + "_mjs": "folder-javascript", + "__mjs__": "folder-javascript", "json": "folder-json", ".json": "folder-json", "_json": "folder-json", @@ -260,6 +308,14 @@ ".jsons": "folder-json", "_jsons": "folder-json", "__jsons__": "folder-json", + "jsonc": "folder-json", + ".jsonc": "folder-json", + "_jsonc": "folder-json", + "__jsonc__": "folder-json", + "jsonl": "folder-json", + ".jsonl": "folder-json", + "_jsonl": "folder-json", + "__jsonl__": "folder-json", "font": "folder-font", ".font": "folder-font", "_font": "folder-font", @@ -268,6 +324,14 @@ ".fonts": "folder-font", "_fonts": "folder-font", "__fonts__": "folder-font", + "typeface": "folder-font", + ".typeface": "folder-font", + "_typeface": "folder-font", + "__typeface__": "folder-font", + "typefaces": "folder-font", + ".typefaces": "folder-font", + "_typefaces": "folder-font", + "__typefaces__": "folder-font", "bower_components": "folder-bower", ".bower_components": "folder-bower", "_bower_components": "folder-bower", @@ -296,6 +360,10 @@ ".specs": "folder-test", "_specs": "folder-test", "__specs__": "folder-test", + "testfiles": "folder-test", + ".testfiles": "folder-test", + "_testfiles": "folder-test", + "__testfiles__": "folder-test", "directive": "folder-directive", ".directive": "folder-directive", "_directive": "folder-directive", @@ -548,6 +616,14 @@ ".preferences": "folder-config", "_preferences": "folder-config", "__preferences__": "folder-config", + "props": "folder-config", + ".props": "folder-config", + "_props": "folder-config", + "__props__": "folder-config", + "properties": "folder-config", + ".properties": "folder-config", + "_properties": "folder-config", + "__properties__": "folder-config", "i18n": "folder-i18n", ".i18n": "folder-i18n", "_i18n": "folder-i18n", @@ -708,6 +784,14 @@ ".colors": "folder-theme", "_colors": "folder-theme", "__colors__": "folder-theme", + "colour": "folder-theme", + ".colour": "folder-theme", + "_colour": "folder-theme", + "__colour__": "folder-theme", + "colours": "folder-theme", + ".colours": "folder-theme", + "_colours": "folder-theme", + "__colours__": "folder-theme", "design": "folder-theme", ".design": "folder-theme", "_design": "folder-theme", @@ -1108,6 +1192,14 @@ ".types": "folder-typescript", "_types": "folder-typescript", "__types__": "folder-typescript", + "cts": "folder-typescript", + ".cts": "folder-typescript", + "_cts": "folder-typescript", + "__cts__": "folder-typescript", + "mts": "folder-typescript", + ".mts": "folder-typescript", + "_mts": "folder-typescript", + "__mts__": "folder-typescript", "graphql": "folder-graphql", ".graphql": "folder-graphql", "_graphql": "folder-graphql", @@ -1244,6 +1336,10 @@ ".gulpfile.babel.js": "folder-gulp", "_gulpfile.babel.js": "folder-gulp", "__gulpfile.babel.js__": "folder-gulp", + "gulpfiles": "folder-gulp", + ".gulpfiles": "folder-gulp", + "_gulpfiles": "folder-gulp", + "__gulpfiles__": "folder-gulp", "python": "folder-python", ".python": "folder-python", "_python": "folder-python", @@ -1996,6 +2092,10 @@ ".meta": "folder-meta", "_meta": "folder-meta", "__meta__": "folder-meta", + "metadata": "folder-meta", + ".metadata": "folder-meta", + "_metadata": "folder-meta", + "__metadata__": "folder-meta", "changesets": "folder-changesets", ".changesets": "folder-changesets", "_changesets": "folder-changesets", @@ -2116,6 +2216,38 @@ ".unix": "folder-linux", "_unix": "folder-linux", "__unix__": "folder-linux", + "wsl": "folder-linux", + ".wsl": "folder-linux", + "_wsl": "folder-linux", + "__wsl__": "folder-linux", + "ubuntu": "folder-linux", + ".ubuntu": "folder-linux", + "_ubuntu": "folder-linux", + "__ubuntu__": "folder-linux", + "deb": "folder-linux", + ".deb": "folder-linux", + "_deb": "folder-linux", + "__deb__": "folder-linux", + "debian": "folder-linux", + ".debian": "folder-linux", + "_debian": "folder-linux", + "__debian__": "folder-linux", + "deepin": "folder-linux", + ".deepin": "folder-linux", + "_deepin": "folder-linux", + "__deepin__": "folder-linux", + "centos": "folder-linux", + ".centos": "folder-linux", + "_centos": "folder-linux", + "__centos__": "folder-linux", + "popos": "folder-linux", + ".popos": "folder-linux", + "_popos": "folder-linux", + "__popos__": "folder-linux", + "mint": "folder-linux", + ".mint": "folder-linux", + "_mint": "folder-linux", + "__mint__": "folder-linux", "windows": "folder-windows", ".windows": "folder-windows", "_windows": "folder-windows", @@ -2128,6 +2260,38 @@ ".win32": "folder-windows", "_win32": "folder-windows", "__win32__": "folder-windows", + "windows11": "folder-windows", + ".windows11": "folder-windows", + "_windows11": "folder-windows", + "__windows11__": "folder-windows", + "windows10": "folder-windows", + ".windows10": "folder-windows", + "_windows10": "folder-windows", + "__windows10__": "folder-windows", + "windowsxp": "folder-windows", + ".windowsxp": "folder-windows", + "_windowsxp": "folder-windows", + "__windowsxp__": "folder-windows", + "windowsnt": "folder-windows", + ".windowsnt": "folder-windows", + "_windowsnt": "folder-windows", + "__windowsnt__": "folder-windows", + "win11": "folder-windows", + ".win11": "folder-windows", + "_win11": "folder-windows", + "__win11__": "folder-windows", + "win10": "folder-windows", + ".win10": "folder-windows", + "_win10": "folder-windows", + "__win10__": "folder-windows", + "winxp": "folder-windows", + ".winxp": "folder-windows", + "_winxp": "folder-windows", + "__winxp__": "folder-windows", + "winnt": "folder-windows", + ".winnt": "folder-windows", + "_winnt": "folder-windows", + "__winnt__": "folder-windows", "macos": "folder-macos", ".macos": "folder-macos", "_macos": "folder-macos", @@ -2460,6 +2624,14 @@ ".pipelines": "folder-pipe", "_pipelines": "folder-pipe", "__pipelines__": "folder-pipe", + "interceptor": "folder-interceptor", + ".interceptor": "folder-interceptor", + "_interceptor": "folder-interceptor", + "__interceptor__": "folder-interceptor", + "interceptors": "folder-interceptor", + ".interceptors": "folder-interceptor", + "_interceptors": "folder-interceptor", + "__interceptors__": "folder-interceptor", "svg": "folder-svg", ".svg": "folder-svg", "_svg": "folder-svg", @@ -2720,6 +2892,14 @@ ".projects": "folder-project", "_projects": "folder-project", "__projects__": "folder-project", + "prompt": "folder-prompts", + ".prompt": "folder-prompts", + "_prompt": "folder-prompts", + "__prompt__": "folder-prompts", + "prompts": "folder-prompts", + ".prompts": "folder-prompts", + "_prompts": "folder-prompts", + "__prompts__": "folder-prompts", "interface": "folder-interface", ".interface": "folder-interface", "_interface": "folder-interface", @@ -3159,6 +3339,50 @@ ".blender-models": "folder-blender", "_blender-models": "folder-blender", "__blender-models__": "folder-blender", + "atoms": "folder-atom", + ".atoms": "folder-atom", + "_atoms": "folder-atom", + "__atoms__": "folder-atom", + "atom": "folder-atom", + ".atom": "folder-atom", + "_atom": "folder-atom", + "__atom__": "folder-atom", + "molecules": "folder-molecule", + ".molecules": "folder-molecule", + "_molecules": "folder-molecule", + "__molecules__": "folder-molecule", + "molecule": "folder-molecule", + ".molecule": "folder-molecule", + "_molecule": "folder-molecule", + "__molecule__": "folder-molecule", + "organisms": "folder-organism", + ".organisms": "folder-organism", + "_organisms": "folder-organism", + "__organisms__": "folder-organism", + "organism": "folder-organism", + ".organism": "folder-organism", + "_organism": "folder-organism", + "__organism__": "folder-organism", + ".claude": "folder-claude", + "..claude": "folder-claude", + "_.claude": "folder-claude", + "__.claude__": "folder-claude", + ".cursor": "folder-cursor", + "..cursor": "folder-cursor", + "_.cursor": "folder-cursor", + "__.cursor__": "folder-cursor", + "metro": "folder-metro", + ".metro": "folder-metro", + "_metro": "folder-metro", + "__metro__": "folder-metro", + "filter": "folder-filter", + ".filter": "folder-filter", + "_filter": "folder-filter", + "__filter__": "folder-filter", + "filters": "folder-filter", + ".filters": "folder-filter", + "_filters": "folder-filter", + "__filters__": "folder-filter", "meta-inf": "folder-config", ".meta-inf": "folder-config", "_meta-inf": "folder-config", @@ -3261,6 +3485,14 @@ ".distribution": "folder-dist-open", "_distribution": "folder-dist-open", "__distribution__": "folder-dist-open", + "built": "folder-dist-open", + ".built": "folder-dist-open", + "_built": "folder-dist-open", + "__built__": "folder-dist-open", + "compiled": "folder-dist-open", + ".compiled": "folder-dist-open", + "_compiled": "folder-dist-open", + "__compiled__": "folder-dist-open", "css": "folder-css-open", ".css": "folder-css-open", "_css": "folder-css-open", @@ -3309,6 +3541,30 @@ ".console": "folder-console-open", "_console": "folder-console-open", "__console__": "folder-console-open", + "xbox": "folder-console-open", + ".xbox": "folder-console-open", + "_xbox": "folder-console-open", + "__xbox__": "folder-console-open", + "ps4": "folder-console-open", + ".ps4": "folder-console-open", + "_ps4": "folder-console-open", + "__ps4__": "folder-console-open", + "ps5": "folder-console-open", + ".ps5": "folder-console-open", + "_ps5": "folder-console-open", + "__ps5__": "folder-console-open", + "switch": "folder-console-open", + ".switch": "folder-console-open", + "_switch": "folder-console-open", + "__switch__": "folder-console-open", + "game": "folder-console-open", + ".game": "folder-console-open", + "_game": "folder-console-open", + "__game__": "folder-console-open", + "games": "folder-console-open", + ".games": "folder-console-open", + "_games": "folder-console-open", + "__games__": "folder-console-open", "images": "folder-images-open", ".images": "folder-images-open", "_images": "folder-images-open", @@ -3405,6 +3661,14 @@ ".photographs": "folder-images-open", "_photographs": "folder-images-open", "__photographs__": "folder-images-open", + "texture": "folder-images-open", + ".texture": "folder-images-open", + "_texture": "folder-images-open", + "__texture__": "folder-images-open", + "textures": "folder-images-open", + ".textures": "folder-images-open", + "_textures": "folder-images-open", + "__textures__": "folder-images-open", "script": "folder-scripts-open", ".script": "folder-scripts-open", "_script": "folder-scripts-open", @@ -3441,6 +3705,14 @@ ".javascripts": "folder-javascript-open", "_javascripts": "folder-javascript-open", "__javascripts__": "folder-javascript-open", + "cjs": "folder-javascript-open", + ".cjs": "folder-javascript-open", + "_cjs": "folder-javascript-open", + "__cjs__": "folder-javascript-open", + "mjs": "folder-javascript-open", + ".mjs": "folder-javascript-open", + "_mjs": "folder-javascript-open", + "__mjs__": "folder-javascript-open", "json": "folder-json-open", ".json": "folder-json-open", "_json": "folder-json-open", @@ -3449,6 +3721,14 @@ ".jsons": "folder-json-open", "_jsons": "folder-json-open", "__jsons__": "folder-json-open", + "jsonc": "folder-json-open", + ".jsonc": "folder-json-open", + "_jsonc": "folder-json-open", + "__jsonc__": "folder-json-open", + "jsonl": "folder-json-open", + ".jsonl": "folder-json-open", + "_jsonl": "folder-json-open", + "__jsonl__": "folder-json-open", "font": "folder-font-open", ".font": "folder-font-open", "_font": "folder-font-open", @@ -3457,6 +3737,14 @@ ".fonts": "folder-font-open", "_fonts": "folder-font-open", "__fonts__": "folder-font-open", + "typeface": "folder-font-open", + ".typeface": "folder-font-open", + "_typeface": "folder-font-open", + "__typeface__": "folder-font-open", + "typefaces": "folder-font-open", + ".typefaces": "folder-font-open", + "_typefaces": "folder-font-open", + "__typefaces__": "folder-font-open", "bower_components": "folder-bower-open", ".bower_components": "folder-bower-open", "_bower_components": "folder-bower-open", @@ -3485,6 +3773,10 @@ ".specs": "folder-test-open", "_specs": "folder-test-open", "__specs__": "folder-test-open", + "testfiles": "folder-test-open", + ".testfiles": "folder-test-open", + "_testfiles": "folder-test-open", + "__testfiles__": "folder-test-open", "directive": "folder-directive-open", ".directive": "folder-directive-open", "_directive": "folder-directive-open", @@ -3737,6 +4029,14 @@ ".preferences": "folder-config-open", "_preferences": "folder-config-open", "__preferences__": "folder-config-open", + "props": "folder-config-open", + ".props": "folder-config-open", + "_props": "folder-config-open", + "__props__": "folder-config-open", + "properties": "folder-config-open", + ".properties": "folder-config-open", + "_properties": "folder-config-open", + "__properties__": "folder-config-open", "i18n": "folder-i18n-open", ".i18n": "folder-i18n-open", "_i18n": "folder-i18n-open", @@ -3897,6 +4197,14 @@ ".colors": "folder-theme-open", "_colors": "folder-theme-open", "__colors__": "folder-theme-open", + "colour": "folder-theme-open", + ".colour": "folder-theme-open", + "_colour": "folder-theme-open", + "__colour__": "folder-theme-open", + "colours": "folder-theme-open", + ".colours": "folder-theme-open", + "_colours": "folder-theme-open", + "__colours__": "folder-theme-open", "design": "folder-theme-open", ".design": "folder-theme-open", "_design": "folder-theme-open", @@ -4297,6 +4605,14 @@ ".types": "folder-typescript-open", "_types": "folder-typescript-open", "__types__": "folder-typescript-open", + "cts": "folder-typescript-open", + ".cts": "folder-typescript-open", + "_cts": "folder-typescript-open", + "__cts__": "folder-typescript-open", + "mts": "folder-typescript-open", + ".mts": "folder-typescript-open", + "_mts": "folder-typescript-open", + "__mts__": "folder-typescript-open", "graphql": "folder-graphql-open", ".graphql": "folder-graphql-open", "_graphql": "folder-graphql-open", @@ -4433,6 +4749,10 @@ ".gulpfile.babel.js": "folder-gulp-open", "_gulpfile.babel.js": "folder-gulp-open", "__gulpfile.babel.js__": "folder-gulp-open", + "gulpfiles": "folder-gulp-open", + ".gulpfiles": "folder-gulp-open", + "_gulpfiles": "folder-gulp-open", + "__gulpfiles__": "folder-gulp-open", "python": "folder-python-open", ".python": "folder-python-open", "_python": "folder-python-open", @@ -5185,6 +5505,10 @@ ".meta": "folder-meta-open", "_meta": "folder-meta-open", "__meta__": "folder-meta-open", + "metadata": "folder-meta-open", + ".metadata": "folder-meta-open", + "_metadata": "folder-meta-open", + "__metadata__": "folder-meta-open", "changesets": "folder-changesets-open", ".changesets": "folder-changesets-open", "_changesets": "folder-changesets-open", @@ -5305,6 +5629,38 @@ ".unix": "folder-linux-open", "_unix": "folder-linux-open", "__unix__": "folder-linux-open", + "wsl": "folder-linux-open", + ".wsl": "folder-linux-open", + "_wsl": "folder-linux-open", + "__wsl__": "folder-linux-open", + "ubuntu": "folder-linux-open", + ".ubuntu": "folder-linux-open", + "_ubuntu": "folder-linux-open", + "__ubuntu__": "folder-linux-open", + "deb": "folder-linux-open", + ".deb": "folder-linux-open", + "_deb": "folder-linux-open", + "__deb__": "folder-linux-open", + "debian": "folder-linux-open", + ".debian": "folder-linux-open", + "_debian": "folder-linux-open", + "__debian__": "folder-linux-open", + "deepin": "folder-linux-open", + ".deepin": "folder-linux-open", + "_deepin": "folder-linux-open", + "__deepin__": "folder-linux-open", + "centos": "folder-linux-open", + ".centos": "folder-linux-open", + "_centos": "folder-linux-open", + "__centos__": "folder-linux-open", + "popos": "folder-linux-open", + ".popos": "folder-linux-open", + "_popos": "folder-linux-open", + "__popos__": "folder-linux-open", + "mint": "folder-linux-open", + ".mint": "folder-linux-open", + "_mint": "folder-linux-open", + "__mint__": "folder-linux-open", "windows": "folder-windows-open", ".windows": "folder-windows-open", "_windows": "folder-windows-open", @@ -5317,6 +5673,38 @@ ".win32": "folder-windows-open", "_win32": "folder-windows-open", "__win32__": "folder-windows-open", + "windows11": "folder-windows-open", + ".windows11": "folder-windows-open", + "_windows11": "folder-windows-open", + "__windows11__": "folder-windows-open", + "windows10": "folder-windows-open", + ".windows10": "folder-windows-open", + "_windows10": "folder-windows-open", + "__windows10__": "folder-windows-open", + "windowsxp": "folder-windows-open", + ".windowsxp": "folder-windows-open", + "_windowsxp": "folder-windows-open", + "__windowsxp__": "folder-windows-open", + "windowsnt": "folder-windows-open", + ".windowsnt": "folder-windows-open", + "_windowsnt": "folder-windows-open", + "__windowsnt__": "folder-windows-open", + "win11": "folder-windows-open", + ".win11": "folder-windows-open", + "_win11": "folder-windows-open", + "__win11__": "folder-windows-open", + "win10": "folder-windows-open", + ".win10": "folder-windows-open", + "_win10": "folder-windows-open", + "__win10__": "folder-windows-open", + "winxp": "folder-windows-open", + ".winxp": "folder-windows-open", + "_winxp": "folder-windows-open", + "__winxp__": "folder-windows-open", + "winnt": "folder-windows-open", + ".winnt": "folder-windows-open", + "_winnt": "folder-windows-open", + "__winnt__": "folder-windows-open", "macos": "folder-macos-open", ".macos": "folder-macos-open", "_macos": "folder-macos-open", @@ -5649,6 +6037,14 @@ ".pipelines": "folder-pipe-open", "_pipelines": "folder-pipe-open", "__pipelines__": "folder-pipe-open", + "interceptor": "folder-interceptor-open", + ".interceptor": "folder-interceptor-open", + "_interceptor": "folder-interceptor-open", + "__interceptor__": "folder-interceptor-open", + "interceptors": "folder-interceptor-open", + ".interceptors": "folder-interceptor-open", + "_interceptors": "folder-interceptor-open", + "__interceptors__": "folder-interceptor-open", "svg": "folder-svg-open", ".svg": "folder-svg-open", "_svg": "folder-svg-open", @@ -5909,6 +6305,14 @@ ".projects": "folder-project-open", "_projects": "folder-project-open", "__projects__": "folder-project-open", + "prompt": "folder-prompts-open", + ".prompt": "folder-prompts-open", + "_prompt": "folder-prompts-open", + "__prompt__": "folder-prompts-open", + "prompts": "folder-prompts-open", + ".prompts": "folder-prompts-open", + "_prompts": "folder-prompts-open", + "__prompts__": "folder-prompts-open", "interface": "folder-interface-open", ".interface": "folder-interface-open", "_interface": "folder-interface-open", @@ -6347,7 +6751,51 @@ "blender-models": "folder-blender-open", ".blender-models": "folder-blender-open", "_blender-models": "folder-blender-open", - "__blender-models__": "folder-blender-open" + "__blender-models__": "folder-blender-open", + "atoms": "folder-atom-open", + ".atoms": "folder-atom-open", + "_atoms": "folder-atom-open", + "__atoms__": "folder-atom-open", + "atom": "folder-atom-open", + ".atom": "folder-atom-open", + "_atom": "folder-atom-open", + "__atom__": "folder-atom-open", + "molecules": "folder-molecule-open", + ".molecules": "folder-molecule-open", + "_molecules": "folder-molecule-open", + "__molecules__": "folder-molecule-open", + "molecule": "folder-molecule-open", + ".molecule": "folder-molecule-open", + "_molecule": "folder-molecule-open", + "__molecule__": "folder-molecule-open", + "organisms": "folder-organism-open", + ".organisms": "folder-organism-open", + "_organisms": "folder-organism-open", + "__organisms__": "folder-organism-open", + "organism": "folder-organism-open", + ".organism": "folder-organism-open", + "_organism": "folder-organism-open", + "__organism__": "folder-organism-open", + ".claude": "folder-claude-open", + "..claude": "folder-claude-open", + "_.claude": "folder-claude-open", + "__.claude__": "folder-claude-open", + ".cursor": "folder-cursor-open", + "..cursor": "folder-cursor-open", + "_.cursor": "folder-cursor-open", + "__.cursor__": "folder-cursor-open", + "metro": "folder-metro-open", + ".metro": "folder-metro-open", + "_metro": "folder-metro-open", + "__metro__": "folder-metro-open", + "filter": "folder-filter-open", + ".filter": "folder-filter-open", + "_filter": "folder-filter-open", + "__filter__": "folder-filter-open", + "filters": "folder-filter-open", + ".filters": "folder-filter-open", + "_filters": "folder-filter-open", + "__filters__": "folder-filter-open" }, "rootFolderNames": {}, "rootFolderNamesExpanded": {}, @@ -6379,9 +6827,12 @@ "j2": "jinja", "jinja-html": "jinja", "proto": "proto", + "prompt.md": "prompt", + "prompts.md": "prompt", "sublime-project": "sublime", "sublime-workspace": "sublime", "slx": "simulink", + "qmd": "quarto", "tw": "twine", "twee": "twine", "yml.dist": "yaml", @@ -6564,6 +7015,7 @@ "vcxitems.filters": "visualstudio", "vcxproj": "visualstudio", "vcxproj.filters": "visualstudio", + "vcl": "varnish", "pdb": "database", "sql": "database", "pks": "database", @@ -6582,6 +7034,26 @@ "dblite3": "database", "debugsymbols": "database", "odb": "database", + "accde": "database", + "adp": "database", + "bak": "database", + "bdb": "database", + "dbf": "database", + "fdb": "database", + "feather": "database", + "gdb": "database", + "ibd": "database", + "mdf": "database", + "mde": "database", + "myd": "database", + "myi": "database", + "ndf": "database", + "orc": "database", + "parquet": "database", + "sdf": "database", + "ldf": "database", + "frm": "database", + "kdbx": "database", "kql": "kusto", "cs": "csharp", "csx": "csharp", @@ -6692,6 +7164,7 @@ "ps1xml": "powershell", "psc1": "powershell", "pssc": "powershell", + "excalidraw": "excalidraw", "excalidraw.json": "excalidraw", "excalidraw.svg": "excalidraw", "excalidraw.png": "excalidraw", @@ -6752,13 +7225,13 @@ "containerfile": "docker", "compose.yaml": "docker", "compose.yml": "docker", + "sty": "sty", + "ctx": "context", + "dtx": "dtx", + "ins": "doctex-installer", "bbx": "bbx", "cbx": "cbx", "lbx": "lbx", - "tex": "tex", - "sty": "sty", - "ltx": "ltx", - "dtx": "dtx", "pptx": "powerpoint", "ppt": "powerpoint", "pptm": "powerpoint", @@ -6926,6 +7399,7 @@ "mli": "ocaml", "cmx": "ocaml", "odin": "odin", + "onnx": "onnx", "js.map": "javascript-map", "mjs.map": "javascript-map", "cjs.map": "javascript-map", @@ -7028,6 +7502,7 @@ "tfvars": "terraform", "tfstate": "terraform", "tfbackend": "terraform", + "tofu": "opentofu", "blade.php": "laravel", "inky.php": "laravel", "applescript": "applescript", @@ -7321,12 +7796,24 @@ "geom": "shader", "frag": "shader", "comp": "shader", + "rgen": "shader", + "rint": "shader", + "rahit": "shader", + "rchit": "shader", + "rmiss": "shader", + "rcall": "shader", "vert.glsl": "shader", "tesc.glsl": "shader", "tese.glsl": "shader", "geom.glsl": "shader", "frag.glsl": "shader", "comp.glsl": "shader", + "rgen.glsl": "shader", + "rint.glsl": "shader", + "rahit.glsl": "shader", + "rchit.glsl": "shader", + "rmiss.glsl": "shader", + "rcall.glsl": "shader", "vertex.glsl": "shader", "geometry.glsl": "shader", "fragment.glsl": "shader", @@ -7350,6 +7837,8 @@ "comp.hlsl": "shader", "tess.hlsl": "shader", "wgsl": "shader", + "spv": "shader", + "slang": "shader", "sy": "siyuan", "ndst.yml": "ndst", "ndst.yaml": "ndst", @@ -7412,6 +7901,7 @@ "hurl": "hurl", "cds": "cds", "slint": "slint", + "verse": "verse", "sw": "sway", "zeabur": "zeabur", "bench.ts": "bench-ts", @@ -7450,6 +7940,12 @@ "blend": "blender", "blend1": "blender", "blend2": "blender", + "css.ts": "vanilla-extract", + "css.js": "vanilla-extract", + "css.cjs": "vanilla-extract", + "css.mjs": "vanilla-extract", + "css.tsx": "vanilla-extract", + "css.jsx": "vanilla-extract", "yaml-tmlanguage": "yaml", "tmlanguage": "xml", "cljx": "clojure", @@ -7517,7 +8013,8 @@ "babelrc": "jsonc", "jmd": "juliamarkdown", "cls": "tex", - "ctx": "latex", + "tex": "latex", + "ltx": "latex", "mak": "makefile", "mkd": "markdown", "mdwn": "markdown", @@ -7657,17 +8154,25 @@ ".jsbeautifyrc": "json", ".esformatter": "json", "cdp.pid": "json", - ".lintstagedrc": "json", ".whitesource": "json", "playwright.config.js": "playwright", + "playwright.config.cjs": "playwright", "playwright.config.mjs": "playwright", "playwright.config.ts": "playwright", + "playwright.config.cts": "playwright", + "playwright.config.mts": "playwright", "playwright.config.base.js": "playwright", + "playwright.config.base.cjs": "playwright", "playwright.config.base.mjs": "playwright", "playwright.config.base.ts": "playwright", + "playwright.config.base.cts": "playwright", + "playwright.config.base.mts": "playwright", "playwright-ct.config.js": "playwright", + "playwright-ct.config.cjs": "playwright", "playwright-ct.config.mjs": "playwright", "playwright-ct.config.ts": "playwright", + "playwright-ct.config.cts": "playwright", + "playwright-ct.config.mts": "playwright", ".htaccess": "xml", ".release-it.json": "rocket", ".release-it.ts": "rocket", @@ -7713,6 +8218,7 @@ "astro.config.ts": "astro-config", "astro.config.cts": "astro-config", "astro.config.mts": "astro-config", + ".vsconfig": "visualstudio", "go.mod": "go-mod", "go.sum": "go-mod", "go.work": "go-mod", @@ -7741,12 +8247,14 @@ "pre-commit": "console", "pre-push": "console", "post-merge": "console", + "excalidraw": "excalidraw", "excalidraw.json": "excalidraw", "excalidraw.svg": "excalidraw", "excalidraw.png": "excalidraw", "gradle.properties": "gradle", "gradlew": "gradle", "gradle-wrapper.properties": "gradle", + "gradlew.bat": "gradle", "copying": "certificate", "copying.md": "certificate", "copying.rst": "certificate", @@ -7790,6 +8298,8 @@ ".rubocop-todo.yml": "rubocop", ".rubocop_todo.yml": "rubocop", ".rspec": "rspec", + ".swift-format": "swift", + ".swift-version": "swift", "dockerfile": "docker", "dockerfile.prod": "docker", "dockerfile.production": "docker", @@ -7927,6 +8437,7 @@ "graphql.config.mts": "graphql", "graphql.config.cts": "graphql", ".graphqlconfig": "graphql", + "XamlStyler.json": "xaml", ".git": "git", ".gitignore": "git", ".gitmessage": "git", @@ -8302,6 +8813,7 @@ "gulpfile.cts": "gulp", "gulpfile.mts": "gulp", "gulpfile.babel.js": "gulp", + "gulpfile.cjs": "gulp", "package.json": "nodejs", "package-lock.json": "nodejs", ".nvmrc": "nodejs", @@ -8542,6 +9054,7 @@ ".eslintrc.base.json": "eslint", ".eslintignore": "eslint", ".eslintcache": "eslint", + "eslint-options.js": "eslint", "code_of_conduct.md": "conduct", "code_of_conduct.txt": "conduct", "code_of_conduct": "conduct", @@ -8563,6 +9076,7 @@ ".mocharc.json": "mocha", ".mocharc.jsonc": "mocha", "jenkinsfile": "jenkins", + "firebase.config.js": "firebase", "firebase.json": "firebase", ".firebaserc": "firebase", "firestore.rules": "firebase", @@ -9059,6 +9573,7 @@ "sentry.edge.config.mts": "sentry", "sentry.edge.config.cts": "sentry", ".sentryclirc": "sentry", + ".env.sentry-build-plugin": "sentry", "contentlayer.config.js": "contentlayer", "contentlayer.config.mjs": "contentlayer", "contentlayer.config.cjs": "contentlayer", @@ -9302,6 +9817,7 @@ "unocss.config.ts": "unocss", "unocss.config.mts": "unocss", ".mincloudrc": "ifanr-cloud", + ".qa-mincloudrc": "ifanr-cloud", "concourse.yml": "concourse", ".syncpackrc": "syncpack", ".syncpackrc.json": "syncpack", @@ -9368,8 +9884,14 @@ "esbuild.config.mts": "esbuild", "esbuild.config.cts": "esbuild", "drizzle.config.ts": "drizzle", + "drizzle.config.dev.ts": "drizzle", + "drizzle.config.prod.ts": "drizzle", "drizzle.config.js": "drizzle", + "drizzle.config.dev.js": "drizzle", + "drizzle.config.prod.js": "drizzle", "drizzle.config.json": "drizzle", + "drizzle.config.dev.json": "drizzle", + "drizzle.config.prod.json": "drizzle", ".puppeteerrc": "puppeteer", ".puppeteerrc.json": "puppeteer", ".puppeteerrc.jsonc": "puppeteer", @@ -9422,7 +9944,8 @@ ".k8s.yml": "kubernetes", ".k8s.yaml": "kubernetes", "phpstan.neon": "phpstan", - "phpneon.neon.dist": "phpstan", + "phpstan.neon.dist": "phpstan", + "phpstan.dist.neon": "phpstan", "screwdriver.yaml": "screwdriver", "screwdriver.yml": "screwdriver", "snapcraft.yaml": "snapcraft", @@ -9494,9 +10017,19 @@ "zeabur.yaml": "zeabur", "zeabur.yml": "zeabur", "zeabur.toml": "zeabur", - ".github/copilot-instructions.md": "copilot", + "copilot-instructions.md": "copilot", ".pre-commit-config.yaml": "pre-commit", ".pre-commit-hooks.yaml": "pre-commit", + ".lintstagedrc": "lintstaged", + ".lintstagedrc.json": "lintstaged", + ".lintstagedrc.yaml": "lintstaged", + ".lintstagedrc.yml": "lintstaged", + ".lintstagedrc.mjs": "lintstaged", + ".lintstagedrc.cjs": "lintstaged", + "lint-staged.config.mjs": "lintstaged", + "lint-staged.config.cjs": "lintstaged", + "lint-staged.config.js": "lintstaged", + ".lintstagedrc.js": "lintstaged", "histoire.config.js": "histoire", "histoire.config.mjs": "histoire", "histoire.config.cjs": "histoire", @@ -9547,6 +10080,23 @@ ".hadolint.yml": "hadolint", "hadolint.yaml": "hadolint", "hadolint.yml": "hadolint", + "tsdoc.json": "tsdoc", + ".oxlintrc.json": "oxlint", + "CLAUDE.md": "claude", + "CLAUDE.local.md": "claude", + ".cursorignore": "cursor", + ".cursorindexingignore": "cursor", + ".cursorrules": "cursor", + ".cursor": "cursor", + ".cursor.json": "cursor", + ".cursorrc": "cursor", + "metro.config.js": "metro", + "metro.config.json": "metro", + "src/bashly.yaml": "bashly", + "src/bashly.yml": "bashly", + "bashly-settings.yaml": "bashly-settings", + "bashly-settings.yml": "bashly-settings", + "xamlstyler.json": "xaml", ".rhistory": "r", "cmakepresets.json": "cmake", "cname": "http", @@ -9557,6 +10107,8 @@ "pklproject.deps.json": "pkl", ".github/funding.yml": "github-sponsors", "snakefile": "snakemake", + "claude.md": "claude", + "claude.local.md": "claude", "language-configuration.json": "jsonc", "icon-theme.json": "jsonc", "color-theme.json": "jsonc", @@ -9625,6 +10177,7 @@ "haml": "haml", "yang": "yang", "terraform": "terraform", + "opentofu": "opentofu", "applescript": "applescript", "cake": "cake", "cucumber": "cucumber", @@ -9754,7 +10307,9 @@ "hosts": "hosts", "beancount": "beancount", "ahk2": "ahk2", - "gnuplot": "gnuplot" + "gnuplot": "gnuplot", + "helm": "helm", + "nginx": "nginx" }, "light": { "fileExtensions": { @@ -9764,6 +10319,7 @@ "j2": "jinja_light", "jinja-html": "jinja_light", "toml": "toml_light", + "tofu": "opentofu_light", "huff": "huff_light", "cr": "crystal_light", "ecr": "crystal_light", @@ -9786,6 +10342,7 @@ "openapi.yml": "openapi_light", "openapi.yaml": "openapi_light", "tldr": "tldraw_light", + "verse": "verse_light", "zeabur": "zeabur_light" }, "fileNames": { @@ -9947,8 +10504,16 @@ "zeabur.yaml": "zeabur_light", "zeabur.yml": "zeabur_light", "zeabur.toml": "zeabur_light", - ".github/copilot-instructions.md": "copilot_light", - "hosts": "hosts_light" + "copilot-instructions.md": "copilot_light", + "hosts": "hosts_light", + ".cursorignore": "cursor_light", + ".cursorindexingignore": "cursor_light", + ".cursorrules": "cursor_light", + ".cursor": "cursor_light", + ".cursor.json": "cursor_light", + ".cursorrc": "cursor_light", + "bashly-settings.yaml": "bashly-settings_light", + "bashly-settings.yml": "bashly-settings_light" }, "languageIds": { "toml": "toml_light", @@ -9971,7 +10536,11 @@ "idea": "folder-intellij_light", ".idea": "folder-intellij_light", "_idea": "folder-intellij_light", - "__idea__": "folder-intellij_light" + "__idea__": "folder-intellij_light", + ".cursor": "folder-cursor_light", + "..cursor": "folder-cursor_light", + "_.cursor": "folder-cursor_light", + "__.cursor__": "folder-cursor_light" }, "folderNamesExpanded": { "jinja": "folder-jinja-open_light", @@ -9989,7 +10558,11 @@ "idea": "folder-intellij-open_light", ".idea": "folder-intellij-open_light", "_idea": "folder-intellij-open_light", - "__idea__": "folder-intellij-open_light" + "__idea__": "folder-intellij-open_light", + ".cursor": "folder-cursor-open_light", + "..cursor": "folder-cursor-open_light", + "_.cursor": "folder-cursor-open_light", + "__.cursor__": "folder-cursor-open_light" }, "rootFolderNames": {}, "rootFolderNamesExpanded": {} diff --git a/options/fileicon/material-icon-svgs.json b/options/fileicon/material-icon-svgs.json index 326e0a1b91..9aa78359da 100644 --- a/options/fileicon/material-icon-svgs.json +++ b/options/fileicon/material-icon-svgs.json @@ -49,6 +49,10 @@ "azure": "", "babel": "", "ballerina": "", + "bashly-hook": "", + "bashly-settings.clone": "", + "bashly-settings_light.clone": "", + "bashly": "", "bazel": "", "bbx": "", "beancount": "", @@ -95,6 +99,7 @@ "circleci_light": "", "citation": "", "clangd": "", + "claude": "", "cline": "", "clojure": "", "cloudfoundry": "", @@ -115,7 +120,7 @@ "commitlint": "", "concourse": "", "conduct": "", - "console": "", + "console": "", "container.clone": "", "contentlayer": "", "context": "", @@ -133,6 +138,8 @@ "css": "", "cucumber": "", "cuda": "", + "cursor": "", + "cursor_light": "", "cypress": "", "d": "", "dart": "", @@ -202,6 +209,8 @@ "folder-archive": "", "folder-astro-open": "", "folder-astro": "", + "folder-atom-open": "", + "folder-atom": "", "folder-attachment-open": "", "folder-attachment": "", "folder-audio-open": "", @@ -242,6 +251,8 @@ "folder-circleci": "", "folder-class-open": "", "folder-class": "", + "folder-claude-open": "", + "folder-claude": "", "folder-client-open": "", "folder-client": "", "folder-cline-open": "", @@ -282,6 +293,10 @@ "folder-coverage": "", "folder-css-open": "", "folder-css": "", + "folder-cursor-open": "", + "folder-cursor-open_light": "", + "folder-cursor": "", + "folder-cursor_light": "", "folder-custom-open": "", "folder-custom": "", "folder-cypress-open": "", @@ -334,6 +349,8 @@ "folder-fastlane": "", "folder-favicon-open": "", "folder-favicon": "", + "folder-filter-open": "", + "folder-filter": "", "folder-firebase-open": "", "folder-firebase": "", "folder-firestore-open": "", @@ -396,6 +413,8 @@ "folder-intellij-open_light": "", "folder-intellij": "", "folder-intellij_light": "", + "folder-interceptor-open": "", + "folder-interceptor": "", "folder-interface-open": "", "folder-interface": "", "folder-ios-open": "", @@ -456,6 +475,8 @@ "folder-messages": "", "folder-meta-open": "", "folder-meta": "", + "folder-metro-open": "", + "folder-metro": "", "folder-middleware-open": "", "folder-middleware": "", "folder-mjml-open": "", @@ -466,6 +487,8 @@ "folder-mock": "", "folder-mojo-open": "", "folder-mojo": "", + "folder-molecule-open": "", + "folder-molecule": "", "folder-moon-open": "", "folder-moon": "", "folder-netlify-open": "", @@ -493,6 +516,8 @@ "folder-obsidian-open": "", "folder-obsidian": "", "folder-open": "", + "folder-organism-open": "", + "folder-organism": "", "folder-other-open": "", "folder-other": "", "folder-packages-open": "", @@ -521,6 +546,8 @@ "folder-private": "", "folder-project-open": "", "folder-project": "", + "folder-prompts-open": "", + "folder-prompts": "", "folder-proto-open": "", "folder-proto": "", "folder-public-open": "", @@ -791,6 +818,7 @@ "lib": "", "lighthouse": "", "lilypond": "", + "lintstaged": "", "liquid": "", "lisp": "", "livescript": "", @@ -798,7 +826,6 @@ "log": "", "lolcode": "", "lottie": "", - "ltx.clone": "", "lua": "", "luau": "", "lyric": "", @@ -817,6 +844,7 @@ "merlin": "", "mermaid": "", "meson": "", + "metro": "", "minecraft-fabric": "", "minecraft": "", "mint": "", @@ -868,11 +896,15 @@ "objective-cpp": "", "ocaml": "", "odin": "", + "onnx": "", "opa": "", "opam": "", "openapi": "", "openapi_light": "", + "opentofu": "", + "opentofu_light": "", "otne": "", + "oxlint": "", "packship": "", "palette": "", "panda": "", @@ -910,6 +942,7 @@ "prisma": "", "processing": "", "prolog": "", + "prompt": "", "proto": "", "protractor": "", "pug": "", @@ -920,6 +953,7 @@ "python": "", "pytorch": "", "qsharp": "", + "quarto": "", "quasar": "", "quokka": "", "qwik": "", @@ -1056,6 +1090,7 @@ "tree": "", "trigger": "", "tsconfig": "", + "tsdoc": "", "tsil": "", "tune": "", "turborepo": "", @@ -1074,6 +1109,8 @@ "uv": "", "vagrant": "", "vala": "", + "vanilla-extract": "", + "varnish": "", "vedic": "", "velite": "", "velocity": "", @@ -1082,6 +1119,8 @@ "verdaccio": "", "verified": "", "verilog": "", + "verse": "", + "verse_light": "", "vfl": "", "video": "", "vim": "", diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 1eea0616a9..cc92f2e626 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -496,6 +496,7 @@ repo.transfer.to_you=vám repo.collaborator.added.subject=%s vás přidal do %s repo.collaborator.added.text=Byl jste přidán jako spolupracovník repozitáře: + team_invite.subject=%[1]s vás pozval/a, abyste se připojili k organizaci %[2]s team_invite.text_1=%[1]s vás pozval/a do týmu %[2]s v organizaci %[3]s. team_invite.text_2=Pro připojení k týmu klikněte na následující odkaz: @@ -3424,7 +3425,6 @@ swift.install=Přidejte balíček do svého Package.swift souboru: swift.install2=a spustit následující příkaz: vagrant.install=Pro přidání Vagrant box spusťte následující příkaz: settings.link=Propojit tento balíček s repozitářem -settings.link.description=Pokud propojíte balíček s repozitářem, je tento balíček uveden v seznamu balíčků repozitáře. settings.link.select=Vybrat repozitář settings.link.button=Aktualizovat odkaz na repozitář settings.link.success=Odkaz na repozitář byl úspěšně aktualizován. diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 6d86a0c8fd..dae7275f82 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -509,6 +509,7 @@ repo.transfer.to_you=dir repo.collaborator.added.subject=%s hat dich zu %s hinzugefügt repo.collaborator.added.text=Du wurdest als Mitarbeiter für folgendes Repository hinzugefügt: + team_invite.subject=%[1]s hat dich eingeladen, der Organisation %[2]s beizutreten team_invite.text_1=%[1]s hat dich eingeladen, dem Team %[2]s in der Organisation %[3]s beizutreten. team_invite.text_2=Bitte klicke auf den folgenden Link, um dem Team beizutreten: @@ -3474,7 +3475,6 @@ swift.install=Füge das Paket deiner Package.swift Datei hinzu: swift.install2=und führe den folgenden Befehl aus: vagrant.install=Um eine Vagrant-Box hinzuzufügen, führe den folgenden Befehl aus: settings.link=Dieses Paket einem Repository zuweisen -settings.link.description=Wenn du ein Paket mit einem Repository verknüpfst, wird es in der Paketliste des Repositories angezeigt. settings.link.select=Repository auswählen settings.link.button=Repository-Link aktualisieren settings.link.success=Repository-Link wurde erfolgreich aktualisiert. diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index 4b34b15738..42b23dea05 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -451,6 +451,7 @@ repo.transfer.to_you=εσάς repo.collaborator.added.subject=%s σας πρόσθεσε στο %s repo.collaborator.added.text=Έχετε προστεθεί ως συνεργάτης του αποθετηρίου: + team_invite.subject=%[1]s σας προσκάλεσε να συμμετέχετε στον οργανισμό %[2]s team_invite.text_1=%[1]s σας προσκάλεσε να συμμετέχετε στην ομάδα %[2]s στον οργανισμός %[3]s. team_invite.text_2=Παρακαλώ κάντε κλικ στον παρακάτω σύνδεσμο για να συμμετάσχετε στην ομάδα: @@ -3132,7 +3133,6 @@ swift.install=Προσθέστε το πακέτο στο αρχείο Pac swift.install2=και εκτελέστε την ακόλουθη εντολή: vagrant.install=Για προσθήκη ενός κυτίου Vagrant, εκτελέστε την ακόλουθη εντολή: settings.link=Σύνδεση αυτού του πακέτου με ένα αποθετήριο -settings.link.description=Εάν συνδέσετε ένα πακέτο με ένα αποθετήριο, το πακέτο περιλαμβάνεται στη λίστα πακέτων του αποθετηρίου. settings.link.select=Επιλογή Αποθετηρίου settings.link.button=Ενημέρωση Συνδέσμου Αποθετηρίου settings.link.success=Ο σύνδεσμος αποθετηρίου ενημερώθηκε επιτυχώς. diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index ac7c1af8a0..c2a33d4c6d 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -120,6 +120,7 @@ error404 = The page you are trying to reach either does not existPackage.swift file: swift.install2 = and run the following command: vagrant.install = To add a Vagrant box, run the following command: 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.description = If you link a package with a repository, the package will appear in the repository's package list. Only repositories under the same owner can be linked. Leaving the field empty will remove the link. settings.link.select = Select Repository settings.link.button = Update Repository Link settings.link.success = Repository link was successfully updated. settings.link.error = Failed to update repository link. +settings.link.repo_not_found = Repository %s not found. +settings.unlink.error = Failed to remove repository link. +settings.unlink.success = Repository link was successfully removed. settings.delete = Delete package settings.delete.description = Deleting a package is permanent and cannot be undone. settings.delete.notice = You are about to delete %s (%s). This operation is irreversible, are you sure? diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index 0f24e6227f..ffacb46b19 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -448,6 +448,7 @@ repo.transfer.to_you=usted repo.collaborator.added.subject=%s le añadió en %s repo.collaborator.added.text=Has sido añadido como colaborador del repositorio: + team_invite.subject=%[1]s le ha invitado a unirse a la organización de %[2]s team_invite.text_1=%[1]s le ha invitado a unirse al equipo %[2]s en la organización %[3]s. team_invite.text_2=Por favor, haz clic en el siguiente enlace para unirte al equipo: @@ -3112,7 +3113,6 @@ swift.install=Añade el paquete en tu archivo Package.swift: swift.install2=y ejecuta el siguiente comando: vagrant.install=Para añadir un paquete Vagrant, ejecuta el siguiente comando: 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 settings.link.button=Actualizar enlace de repositorio settings.link.success=El enlace del repositorio se ha actualizado correctamente. diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index 023a3ed2ea..abeef31988 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -363,6 +363,7 @@ repo.collaborator.added.subject=%s شما را به پروژه %s اضافه ک repo.collaborator.added.text=شما به عنوان مشارکت‌کننده در این مخزن اضافه شدید: + [modal] yes=بله no=خیر diff --git a/options/locale/locale_fi-FI.ini b/options/locale/locale_fi-FI.ini index cd4c06c013..9d7fc033c4 100644 --- a/options/locale/locale_fi-FI.ini +++ b/options/locale/locale_fi-FI.ini @@ -348,6 +348,7 @@ repo.transfer.to_you=sinä + [modal] yes=Kyllä no=Ei diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index c9e074b659..5814de64ca 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -120,6 +120,7 @@ error404=La page que vous essayez d'atteindre n'existe pas ou < error503=Le serveur n’a pas pu répondre à votre demande. Veuillez réessayer plus tard. go_back=Retour invalid_data=Données invalides : %v +nothing_has_been_changed=Rien n’a été changé. never=Jamais unknown=Inconnu @@ -550,6 +551,14 @@ repo.transfer.body=Pour l’accepter ou le rejeter, visitez %s ou ignorez-le. repo.collaborator.added.subject=%s vous a ajouté à %s repo.collaborator.added.text=Vous avez été ajouté en tant que collaborateur du dépôt : +repo.actions.run.failed=L’exécution a échoué +repo.actions.run.succeeded=L’exécution a réussi +repo.actions.run.cancelled=L’exécution a été annulée +repo.actions.jobs.all_succeeded=Tous les tâches ont réussi. +repo.actions.jobs.all_failed=Toutes les tâches ont échoué. +repo.actions.jobs.some_not_successful=Certaines tâches n’ont pas réussi. +repo.actions.jobs.all_cancelled=Toutes les tâches ont bien été annulés. + team_invite.subject=%[1]s vous a invité à rejoindre l’organisation %[2]s team_invite.text_1=%[1]s vous a invité à rejoindre l’équipe %[2]s dans l’organisation %[3]s. team_invite.text_2=Veuillez cliquer sur le lien suivant pour rejoindre l'équipe : @@ -2843,6 +2852,11 @@ settings.location=Localisation settings.permission=Autorisations settings.repoadminchangeteam=L'administrateur de dépôt peut ajouter et supprimer l'accès aux équipes settings.visibility=Visibilité +settings.change_visibility=Modifier la visibilité +settings.change_visibility_notices_1=Si l’organisation est convertie en privé, les étoiles du dépôt seront supprimées et ne pourront pas être restaurées. +settings.change_visibility_notices_2=Les non-membres ne pourront plus accéder aux dépôts de l’organisation si la visibilité devient privée. +settings.change_visibility_success=La visibilité de l’organisation %s a été modifiée. +settings.visibility_desc=Changez qui peut voir l’organisation et ses dépôts. settings.visibility.public=Public settings.visibility.limited=Limité (Visible uniquement aux utilisateurs authentifiés) settings.visibility.limited_shortname=Limité @@ -3419,6 +3433,7 @@ config.picture_service=Service d'Imagerie config.disable_gravatar=Désactiver Gravatar config.enable_federated_avatar=Activer les avatars unifiés config.open_with_editor_app_help=Les éditeurs disponibles via « Ouvrir avec ». Si laissé vide, la valeur par défaut sera utilisée. Développez pour voir la valeur par défaut. +config.git_guide_remote_name=Nom du dépôt distant pour les commandes git dans le guide config.git_config=Configuration de Git config.git_disable_diff_highlight=Désactiver la surbrillance syntaxique de Diff @@ -3714,7 +3729,6 @@ swift.install=Ajoutez le paquet dans votre fichier Package.swift: swift.install2=et exécutez la commande suivante : vagrant.install=Pour ajouter une machine Vagrant, exécutez la commande suivante : settings.link=Lier ce paquet à un dépôt -settings.link.description=Si vous liez un paquet à dépôt, le paquet sera inclus dans sa liste des paquets. settings.link.select=Sélectionner un dépôt settings.link.button=Actualiser le lien du dépôt settings.link.success=Le lien du dépôt a été mis à jour avec succès. diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini index cb0c2373ed..cbad425cc1 100644 --- a/options/locale/locale_ga-IE.ini +++ b/options/locale/locale_ga-IE.ini @@ -120,6 +120,7 @@ error404=Níl an leathanach atá tú ag iarraidh a bhaint amach annchomhad Package.swift: swift.install2=agus reáchtáil an t-ordú seo a leanas: vagrant.install=Chun bosca Vagrant a chur leis, reáchtáil an t-ordú seo a leanas: settings.link=Nasc an pacáiste seo le stóras -settings.link.description=Má nascann tú pacáiste le stóras, liostaítear an pacáiste i liosta pacáistí an stórais. settings.link.select=Roghnaigh Stóras settings.link.button=Nuashonraigh Nasc Stórais settings.link.success=D'éirigh le nasc an stórais a nuashonrú. diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini index e86030e127..0fc86f0775 100644 --- a/options/locale/locale_hu-HU.ini +++ b/options/locale/locale_hu-HU.ini @@ -294,6 +294,7 @@ register_success=Sikeres regisztráció + [modal] yes=Igen no=Nem diff --git a/options/locale/locale_id-ID.ini b/options/locale/locale_id-ID.ini index e6d383cff0..a5640655d2 100644 --- a/options/locale/locale_id-ID.ini +++ b/options/locale/locale_id-ID.ini @@ -302,6 +302,7 @@ register_success=Pendaftaran berhasil + [modal] yes=Ya no=Tidak diff --git a/options/locale/locale_is-IS.ini b/options/locale/locale_is-IS.ini index 1e4669e32b..177cf61068 100644 --- a/options/locale/locale_is-IS.ini +++ b/options/locale/locale_is-IS.ini @@ -326,6 +326,7 @@ repo.collaborator.added.subject=%s bætti þér við í %s repo.collaborator.added.text=Þér hefur verið bætt við sem aðila hugbúnaðarsafns: + [modal] yes=Já no=Nei diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index f6616418ad..31aebff2d6 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -386,6 +386,7 @@ repo.collaborator.added.subject=%s ti ha aggiunto a %s repo.collaborator.added.text=Sei stato aggiunto come collaboratore del repository: + [modal] yes=Sì no=No @@ -2666,7 +2667,6 @@ rubygems.dependencies.development=Dipendenze Di Sviluppo rubygems.required.ruby=Richiede la versione di Ruby rubygems.required.rubygems=Richiede la versione RubyGem settings.link=Collega questo pacchetto a un repository -settings.link.description=Se si collega un pacchetto a un repository, il pacchetto è elencato nell'elenco dei pacchetti del repository. settings.link.select=Seleziona Repository settings.link.button=Aggiorna Collegamento Repository settings.link.success=Il link del repository è stato aggiornato correttamente. diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 312e0dd4f1..3b3083d8c6 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -120,6 +120,7 @@ error404=アクセスしようとしたページは存在しないPackage.swift ファイルにパッケ swift.install2=そして次のコマンドを実行します: vagrant.install=Vagrant ボックスを追加するには、次のコマンドを実行します。 settings.link=このパッケージをリポジトリにリンク -settings.link.description=パッケージをリポジトリにリンクすると、リポジトリのパッケージリストに表示されるようになります。 settings.link.select=リポジトリを選択 settings.link.button=リポジトリのリンクを更新 settings.link.success=リポジトリのリンクが正常に更新されました。 diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini index e010d17331..39df68f126 100644 --- a/options/locale/locale_ko-KR.ini +++ b/options/locale/locale_ko-KR.ini @@ -278,6 +278,7 @@ register_success=등록 완료 + [modal] yes=예 no=아니오 diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index 3328a6f759..9c8f47534b 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -454,6 +454,7 @@ repo.transfer.to_you=Jums repo.collaborator.added.subject=%s pievienoja Jūs repozitorijam %s repo.collaborator.added.text=Jūs tikāt pievienots kā līdzstrādnieks repozitorijam: + team_invite.subject=%[1]s uzaicināja Jūs pievienoties organizācijai %[2]s team_invite.text_1=%[1]s uzaicināja Jūs pievienoties komandai %[2]s organizācijā %[3]s. team_invite.text_2=Uzspiediet uz šīs saites, lai pievienoties komandai: @@ -3133,7 +3134,6 @@ swift.install=Pievienojiet pakotni savā Package.swift failā: swift.install2=un izpildiet sekojošu komandu: vagrant.install=Lai pievienotu Vagrant kasti, izpildiet sekojošu komandu: settings.link=Piesaistīt pakotni šim repozitorijam -settings.link.description=Sasaistot pakotni ar repozitoriju, tā tiks attēlota repozitorija pakotņu sarakstā. settings.link.select=Norādiet repozitoriju settings.link.button=Atjaunot repozitorija saiti settings.link.success=Repozitorija saite tika veiksmīgi atjaunota. diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini index c04d843ae5..326a203c8f 100644 --- a/options/locale/locale_nl-NL.ini +++ b/options/locale/locale_nl-NL.ini @@ -385,6 +385,7 @@ repo.collaborator.added.subject=%s heeft jou toegevoegd aan %s repo.collaborator.added.text=U bent toegevoegd als een medewerker van de repository: + [modal] yes=Ja no=Nee diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index a6f1143236..872f1104ab 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -372,6 +372,7 @@ repo.collaborator.added.subject=%s dodał Cię do %s repo.collaborator.added.text=Zostałeś dodany jako współtwórca repozytorium: + [modal] yes=Tak no=Nie diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index cc571816ac..614f53b2c8 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -8,7 +8,7 @@ sign_in_with_provider=Entrar com %s sign_in_or=ou sign_out=Sair sign_up=Cadastrar -link_account=Vincular conta +link_account=Vincular Conta register=Cadastrar version=Versão powered_by=Desenvolvido por %s @@ -16,7 +16,8 @@ page=Página template=Template language=Idioma notifications=Notificações -active_stopwatch=Cronômetro ativo +active_stopwatch=Cronômetro Ativo +tracked_time_summary=Resumo do tempo monitorado com base nos filtros da lista de problemas create_new=Criar… user_profile_and_more=Perfil e Configurações... signed_in_as=Acessado como @@ -24,24 +25,26 @@ enable_javascript=Este site requer JavaScript. toc=Índice licenses=Licenças return_to_gitea=Volte para Gitea +more_items=Mais itens username=Nome de usuário -email=Endereço de e-mail +email=Endereço de E-mail password=Senha access_token=Token de Acesso -re_type=Confirmar senha +re_type=Confirmar Senha captcha=CAPTCHA -twofa=Autenticação de dois fatores -twofa_scratch=Código de backup da autenticação de dois fatores +twofa=Autenticação de Dois Fatores +twofa_scratch=Código de Backup da Autenticação de Dois Fatores passcode=Senha webauthn_insert_key=Insira sua chave de segurança webauthn_sign_in=Pressione o botão na sua chave de segurança. Se a sua chave de segurança não tiver um botão, insira-a novamente. webauthn_press_button=Por favor, pressione o botão na sua chave de segurança… -webauthn_use_twofa=Use um código de duas etapas do seu telefone +webauthn_use_twofa=Use um código de dois fatores do seu telefone webauthn_error=Não foi possível ler sua chave de segurança. webauthn_unsupported_browser=Seu navegador não oferece suporte ao WebAuthn. webauthn_error_unknown=Ocorreu um erro desconhecido. Por favor, tente novamente. +webauthn_error_insecure=`WebAuthn suporta apenas conexões seguras. Para testar via HTTP, você pode usar a origem "localhost" ou "127.0.0.1"` webauthn_error_unable_to_process=O servidor não pôde processar sua solicitação. webauthn_error_duplicated=A chave de segurança não é permitida para esta solicitação. Por favor, certifique-se que a chave já não está registrada. webauthn_error_empty=Você deve definir um nome para esta chave. @@ -52,16 +55,16 @@ repository=Repositório organization=Organização mirror=Espelhamento issue_milestone=Marco -new_repo=Novo repositório -new_migrate=Nova migração -new_mirror=Novo espelhamento +new_repo=Novo Repositório +new_migrate=Nova Migração +new_mirror=Novo Espelhamento new_fork=Novo Fork de Repositório -new_org=Nova organização +new_org=Nova Organização new_project=Novo Projeto new_project_column=Nova Coluna -manage_org=Gerenciar organizações -admin_panel=Administração geral -account_settings=Configurações da conta +manage_org=Gerenciar Organizações +admin_panel=Administração Geral +account_settings=Configurações da Conta settings=Configurações your_profile=Perfil your_starred=Favorito @@ -74,7 +77,7 @@ collaborative=Colaborativo forks=Forks activities=Atividades -pull_requests=Pull requests +pull_requests=Pull Requests issues=Issues milestones=Marcos @@ -85,12 +88,13 @@ rerun=Reexecutar rerun_all=Reexecutar todas as tarefas save=Salvar add=Adicionar -add_all=Adicionar todos +add_all=Adicionar Todos remove=Remover -remove_all=Excluir todos +remove_all=Excluir Todos remove_label_str=`Remover item "%s"` edit=Editar view=Visualizar +test=Teste enabled=Habilitado disabled=Desabilitado @@ -101,6 +105,7 @@ copy_url=Copiar URL copy_hash=Copiar hash copy_content=Copiar conteúdo copy_branch=Copiar nome do branch +copy_path=Copiar caminho copy_success=Copiado! copy_error=A cópia falhou copy_type_unsupported=Este tipo de arquivo não pode ser copiado @@ -108,10 +113,14 @@ copy_type_unsupported=Este tipo de arquivo não pode ser copiado write=Escrever preview=Pré-visualização loading=Carregando… +files=Arquivos error=Erro error404=A página que você está tentando acessar não existe ou você não está autorizado a visualizá-la. +error503=O servidor foi incapaz de concluir sua solicitação. Por favor, tente novamente mais tarde. go_back=Voltar +invalid_data=Dados inválidos: %v +nothing_has_been_changed=Nada foi alterado. never=Nunca unknown=Desconhecido @@ -122,6 +131,8 @@ pin=Fixar unpin=Desfixar artifacts=Artefatos +expired=Expirado +confirm_delete_artifact=Tem certeza que deseja excluir o artefato '%s'? archived=Arquivado @@ -139,18 +150,53 @@ confirm_delete_selected=Confirma a exclusão de todos os itens selecionados? name=Nome value=Valor +readme=Readme filter=Filtro +filter.clear=Limpar Filtro filter.is_archived=Arquivado +filter.not_archived=Não Arquivados +filter.is_fork=Fork +filter.not_fork=Não Fork +filter.is_mirror=Espelhado +filter.not_mirror=Não Espelhado filter.is_template=Template +filter.not_template=Não Modelo filter.public=Pública filter.private=Privado +no_results_found=Nenhum resultado encontrado. +internal_error_skipped=Ocorreu um erro interno, mas foi ignorado: %s [search] +search=Pesquisar… +type_tooltip=Tipo de pesquisa +fuzzy=Fuzzy +fuzzy_tooltip=Incluir resultados que sejam próximos ao termo de busca +words=Palavras +words_tooltip=Incluir somente resultados que correspondam às palavras do termo de busca +regexp=Regexp +regexp_tooltip=Incluir somente resultados que correspondam ao termo de pesquisa regexp +exact=Exato +exact_tooltip=Incluir somente resultados que correspondam exatamente ao termo de busca +repo_kind=Pesquisar repositório... +user_kind=Pesquisar usuário… +org_kind=Pesquisar orgs… +team_kind=Pesquisar equipes… +code_kind=Pesquisar código… +code_search_unavailable=A pesquisa por código está indisponível no momento. Entre em contato com o administrador. +package_kind=Pesquisar pacotes… +project_kind=Pesquisar projetos… +branch_kind=Pesquisar branches… +tag_kind=Pesquisar tags… +commit_kind=Pesquisar commits… +runner_kind=Pesquisar runners… +no_results=Nenhum resultado foi encontrado. +issue_kind=Pesquisar issues… +pull_kind=Pesquisar pull requests… [aria] -navbar=Barra de navegação +navbar=Barra de Navegação footer=Rodapé footer.software=Sobre o Software footer.links=Links @@ -171,7 +217,10 @@ buttons.link.tooltip=Adicionar um link buttons.list.unordered.tooltip=Adicionar uma lista com marcadores buttons.list.ordered.tooltip=Adicionar uma lista numerada buttons.list.task.tooltip=Adicionar uma lista de tarefas +buttons.table.add.tooltip=Adicionar uma tabela buttons.table.add.insert=Adicionar +buttons.table.rows=Linhas +buttons.table.cols=Colunas buttons.mention.tooltip=Mencionar um usuário ou equipe buttons.ref.tooltip=Referenciar um issue ou um pull request buttons.switch_to_legacy.tooltip=Em vez disso, usar o editor legado @@ -179,31 +228,37 @@ buttons.enable_monospace_font=Habilitar fonte mono espaçada buttons.disable_monospace_font=Desabilitar fonte mono espaçada [filter] +string.asc=A–Z +string.desc=Z–A [error] occurred=Ocorreu um erro +report_message=Se você acredita que esse é um falha do Gitea, pesquise por issues no GitHub ou abra uma nova issue, se necessário. not_found=Não foi possível encontrar o destino. network_error=Erro de rede [startpage] -app_desc=Um serviço de hospedagem Git amigável +app_desc=Um serviço amigável de Git selfhosted install=Fácil de instalar +install_desc=Simplesmente execute o binário para sua plataforma, suba com Docker, or use um pacote. platform=Multi-plataforma +platform_desc=Gitea roda em qualquer lugar para qual Go consegue compilar: Windows, macOS, Linux, ARM, etc. Escolha qual você gosta mais! lightweight=Leve e rápido -lightweight_desc=Gitea utiliza poucos recursos e consegue mesmo rodar no barato Raspberry Pi. Economize energia elétrica da sua máquina! -license=Código aberto +lightweight_desc=Gitea tem requisitos minimos e pode rodar até em um Raspberry Pi. Economize energia da sua máquina! +license=Código Aberto +license_desc=Receba %[2]s! Junte-se a nós contribuindo para tornar este projeto ainda melhor. Não seja tímido, seja um colaborador! [install] install=Instalação -title=Configuração inicial +title=Configuração Inicial docker_helper=Se você está rodando o Gitea dentro do Docker, por favor leia a documentação cuidadosamente antes de alterar qualquer coisa nesta página. require_db_desc=Gitea requer MySQL, PostgreSQL, MSSQL, SQLite3 ou TiDB (protocolo MySQL). -db_title=Configurações de banco de dados -db_type=Tipo de banco de dados +db_title=Configurações de Banco de Dados +db_type=Tipo de Banco de Dados host=Servidor user=Nome de usuário password=Senha -db_name=Nome do banco de dados +db_name=Nome do Banco de Dados db_schema=Esquema db_schema_helper=Deixe em branco para banco de dados padrão ("public"). ssl_mode=SSL @@ -211,64 +266,72 @@ path=Caminho sqlite_helper=Caminho do arquivo do banco de dados SQLite3.
Informe um caminho absoluto se você executar o Gitea como um serviço. reinstall_error=Você está tentando instalar em um banco de dados existente do Gitea reinstall_confirm_message=Reinstalar com um banco de dados Gitea existente pode causar vários problemas. Na maioria dos casos, você deve usar seu "app.ini" existente para executar o Gitea. Se você sabe o que está fazendo, confirme o seguinte: +reinstall_confirm_check_1=Os dados criptografados pelo SECRET_KEY no app.ini poderão ser perdidos: os usuários podem não conseguir fazer login com 2FA/OTP e espelhos podem não funcionar corretamente. Ao marcar esta caixa você confirma que o atual arquivo app.ini contém o SECRET_KEY correto. +reinstall_confirm_check_2=Os repositórios e configurações podem precisar ser re-sincronizados. Marcando esta caixa você confirma que irá sincronizar novamente os hooks para os repositórios e o arquivo authorized_keys manualmente. Você confirma que irá garantir que as configurações de repositório e espelhamento estão corretas. reinstall_confirm_check_3=Você confirma que este Gitea está realmente executando com a localização correta do app.ini e que você tem certeza de que precisa reinstalar. Você confirma que tomou conhecimento dos riscos acima descritos. err_empty_db_path=O caminho do banco de dados SQLite3 não pode ser em branco. no_admin_and_disable_registration=Você não pode desabilitar o auto-cadastro do usuário sem criar uma conta de administrador. err_empty_admin_password=A senha do administrador não pode ser em branco. +err_empty_admin_email=O e-mail do administrador não pode estar em branco. +err_admin_name_is_reserved=Nome de usuário do administrador é inválido, nome de usuário está reservado. +err_admin_name_pattern_not_allowed=Nome de usuário administrador é inválido. O nome de usuário corresponde a um padrão reservado. +err_admin_name_is_invalid=Nome de usuário do administrador inválido -general_title=Configurações gerais -app_name=Nome do servidor +general_title=Configurações Gerais +app_name=Nome do Site app_name_helper=Você pode inserir o nome da empresa aqui. -repo_path=Caminho raíz do repositório +repo_path=Caminho Raíz do Repositório repo_path_helper=Todos os repositórios remotos do Git serão salvos neste diretório. lfs_path=Caminho raiz do Git LFS lfs_path_helper=Os arquivos armazenados com o Git LFS serão armazenados neste diretório. Deixe em branco para desabilitar. -run_user=Executar como nome de usuário +run_user=Executar como Usuário run_user_helper=O nome de usuário do sistema operacional com o qual o Gitea é executado. Observe que este usuário deve ter acesso ao caminho da raiz do repositório. -domain=Domínio do servidor +domain=Domínio do Servidor domain_helper=Domínio ou endereço de host para o servidor. ssh_port=Porta do servidor SSH ssh_port_helper=Número da porta que seu servidor SSH está usando. Deixe em branco para desabilitar. http_port=Porta HTTP de uso do Gitea +http_port_helper=Número da porta que o servidor web do Gitea irá usar. app_url=URL base do Gitea app_url_helper=Endereço base para URLs clone HTTP(S) e notificações por e-mail. -log_root_path=Caminho do log +log_root_path=Caminho do Log log_root_path_helper=Arquivos de log serão gravados neste diretório. -optional_title=Configurações opcionais -email_title=Configurações de e-mail +optional_title=Configurações Opcionais +email_title=Configurações de E-mail smtp_addr=Host SMTP smtp_port=Porta SMTP -smtp_from=Enviar e-mail como +smtp_from=Enviar E-mail Como +smtp_from_invalid=O endereço "Enviar e-mail como" é inválido smtp_from_helper=Endereço de e-mail que o Gitea irá usar. Digite um endereço de e-mail simples ou use o formato "Nome" . mailer_user=Nome de usuário do SMTP mailer_password=Senha do SMTP -register_confirm=Exigir confirmação de e-mail para se cadastrar -mail_notify=Habilitar notificações de e-mail -server_service_title=Configurações de servidor e serviços de terceiros -offline_mode=Habilitar autenticação local +register_confirm=Exigir Confirmação de E-mail para se Cadastrar +mail_notify=Habilitar Notificações de E-mail +server_service_title=Configurações de Servidor e Serviços de Terceiros +offline_mode=Habilitar Autenticação Local offline_mode_popup=Desabilitar redes de entrega de conteúdo de terceiros e entregar todos os recursos localmente. -disable_gravatar=Desabilitar o gravatar +disable_gravatar=Desabilitar o Gravatar disable_gravatar_popup=Desabilitar o gravatar e avatar de fontes de terceiros. Um avatar padrão será usado a menos que um usuário localmente carrega um avatar. -federated_avatar_lookup=Habilitar avatares federativos +federated_avatar_lookup=Habilitar Avatares Federativos federated_avatar_lookup_popup=Habilitar a busca federativa de avatares a usar o serviço federativo de código aberto baseado no libravatar. -disable_registration=Desabilitar auto-cadastro +disable_registration=Desabilitar Auto-Cadastro disable_registration_popup=Desabilitar auto-cadastro de usuário. Somente os administradores serão capazes de criar novas contas de usuário. -allow_only_external_registration_popup=Permitir cadastro somente por meio de serviços externos +allow_only_external_registration_popup=Permitir Cadastro Somente por Meio de Serviços Externos openid_signin=Habilitar acesso via OpenID openid_signin_popup=Habilitar o acesso de usuários via OpenID. openid_signup=Habilitar o auto-cadastro via OpenID openid_signup_popup=Habilitar o auto-cadastro com base no OpenID. enable_captcha=Habilitar CAPTCHA ao registrar enable_captcha_popup=Obrigar validação por CAPTCHA para auto-cadastro de usuários. -require_sign_in_view=Exigir acesso do usuário para a visualização de páginas +require_sign_in_view=Exigir Acesso para a Visualização de Páginas require_sign_in_view_popup=Limitar o acesso de página aos usuários autenticados. Os visitantes só verão as páginas de autenticação e cadastro. admin_setting_desc=Criar uma conta de administrador é opcional. O primeiro usuário cadastrado automaticamente se tornará um administrador. -admin_title=Configurações da conta de administrador -admin_name=Nome do usuário administrador +admin_title=Configurações da Conta de Administrador +admin_name=Nome do Usuário Administrador admin_password=Senha -confirm_password=Confirmar senha -admin_email=Endereço de e-mail +confirm_password=Confirmar Senha +admin_email=Endereço de E-mail install_btn_confirm=Instalar Gitea test_git_failed=Falha ao testar o comando 'git': %v sqlite3_not_available=Esta versão do Gitea não suporta SQLite3. Por favor faça o download da versão binária oficial em %s (não utilize a versão 'gobuild'). @@ -282,32 +345,35 @@ secret_key_failed=Falha ao gerar a chave secreta: %v save_config_failed=Falha ao salvar a configuração: %v invalid_admin_setting=Configuração da conta de administrador está inválida: %v invalid_log_root_path=Pasta raíz do log está inválida: %v -default_keep_email_private=Ocultar endereços de e-mail por padrão +default_keep_email_private=Ocultar Endereços de E-mail por Padrão default_keep_email_private_popup=Ocultar endereços de e-mail de novas contas de usuário por padrão. -default_allow_create_organization=Permitir a criação de organizações por padrão +default_allow_create_organization=Permitir a Criação de Organizações por Padrão default_allow_create_organization_popup=Permitir que novas contas de usuários criem organizações por padrão. default_enable_timetracking=Habilitar o Cronômetro por Padrão default_enable_timetracking_popup=Habilitar o cronômetro para novos repositórios por padrão. -no_reply_address=Domínio de e-mail oculto +no_reply_address=Domínio de E-mail Oculto no_reply_address_helper=Nome de domínio para usuários com um endereço de e-mail oculto. Por exemplo, o nome de usuário 'joe' será registrado no Git como 'joe@noreply.example.org' se o domínio de e-mail oculto estiver definido como 'noreply.example.org'. password_algorithm=Algoritmo Hash de Senha invalid_password_algorithm=Algoritmo de hash de senha inválido +password_algorithm_helper=Escolha o algoritmo de hash para as senhas. Diferentes algoritmos têm requerimentos e forças diversos. O algoritmo argon2 é bastante seguro, mas usa muita memória e pode ser inapropriado para sistemas com menos recursos. enable_update_checker=Habilitar Verificador de Atualizações enable_update_checker_helper=Procura por novas versões periodicamente conectando-se ao gitea.io. -env_config_keys=Configuração do ambiente +env_config_keys=Configuração do Ambiente env_config_keys_prompt=As seguintes variáveis de ambiente também serão aplicadas ao seu arquivo de configuração: +config_write_file_prompt=Estas opções de configuração serão escritas em: %s [home] -uname_holder=Usuário ou e-mail +nav_menu=Menu de Navegação +uname_holder=Usuário ou E-mail password_holder=Senha -switch_dashboard_context=Trocar contexto do painel de controle +switch_dashboard_context=Trocar Contexto do Painel de Controle my_repos=Repositórios show_more_repos=Mostrar mais repositórios… -collaborative_repos=Repositórios colaborativos -my_orgs=Minhas organizações -my_mirrors=Meus espelhos +collaborative_repos=Repositórios Colaborativos +my_orgs=Minhas Organizações +my_mirrors=Meus Espelhos view_home=Ver %s -filter=Outros filtros +filter=Outros Filtros filter_by_team_repositories=Filtrar por repositórios da equipe feed_of=`Feed de "%s"` @@ -323,6 +389,11 @@ show_only_public=Mostrando somente públicos issues.in_your_repos=Em seus repositórios +guide_title=Nenhuma Atividade +explore_repos=Explorar repositórios +explore_users=Explorar usuários +empty_org=Ainda não existem organizações. +empty_repo=Ainda não existem repositórios. [explore] repos=Repositórios @@ -335,30 +406,38 @@ relevant_repositories_tooltip=Repositórios que são forks ou que não possuem t relevant_repositories=Apenas repositórios relevantes estão sendo mostrados, mostrar resultados não filtrados. [auth] -create_new_account=Cadastrar conta +create_new_account=Cadastrar Conta +already_have_account=Já tem uma conta? +sign_in_now=Entre agora! disable_register_prompt=Cadastro está desabilitado. Entre em contato com o administrador do site. disable_register_mail=E-mail de confirmação de cadastro está desabilitado. manual_activation_only=Entre em contato com o administrador do site para concluir a ativação. remember_me=Lembrar deste Dispositivo remember_me.compromised=O token de login não é mais válido, o que pode indicar uma conta comprometida. Por favor, verifique a sua conta por atividades incomuns. -forgot_password_title=Esqueci minha senha +forgot_password_title=Esqueci a Senha forgot_password=Esqueceu sua senha? +need_account=Precisa de uma conta? +sign_up_now=Cadastre-se agora. sign_up_successful=A conta foi criada com sucesso. Bem-vindo! +confirmation_mail_sent_prompt_ex=Um novo e-mail de confirmação foi enviado para %s. Por favor, verifique sua caixa de entrada dentro dos próximos %s para concluir o processo de registro. Se o seu endereço de e-mail de registro estiver incorreto, você pode fazer login novamente e alterá-lo. must_change_password=Redefina sua senha allow_password_change=Exigir que o usuário redefina a senha (recomendado) reset_password_mail_sent_prompt=Um e-mail de confirmação foi enviado para %s. Por favor, verifique sua caixa de entrada dentro do(s) próximo(s) %s para concluir o processo de recuperação de conta. -active_your_account=Ativar sua conta +active_your_account=Ativar sua Conta account_activated=Conta foi ativada +prohibit_login=Acesso Proibido +prohibit_login_desc=Sua conta está proibida de fazer login, entre em contato com o administrador do site. resent_limit_prompt=Você já solicitou recentemente um e-mail de ativação. Por favor, aguarde 3 minutos e tente novamente. has_unconfirmed_mail=Oi %s, você possui um endereço de e-mail não confirmado (%s). Se você não recebeu um e-mail de confirmação ou precisa reenviar um novo, clique no botão abaixo. +change_unconfirmed_mail_address=Se o seu endereço de e-mail de registro estiver incorreto, você pode mudá-lo aqui e reenviar um novo e-mail de confirmação. resend_mail=Clique aqui para reenviar seu e-mail de ativação email_not_associate=O endereço de e-mail não está associado à nenhuma conta. -send_reset_mail=Enviar e-mail de recuperação de conta -reset_password=Recuperação de conta +send_reset_mail=Enviar E-mail de Recuperação de Conta +reset_password=Recuperação de Conta invalid_code=Seu código de confirmação é inválido ou expirou. invalid_code_forgot_password=Seu código de confirmação expirou ou está inválido. Clique aqui para iniciar uma nova sessão. invalid_password=Sua senha não coincide com a senha que foi usada para criar a conta. -reset_password_helper=Recuperar conta +reset_password_helper=Recuperar Conta reset_password_wrong_user=Você está conectado como %s, mas o link de recuperação de conta é destinado a %s password_too_short=A senha deve ter %d ou mais caracteres. non_local_account=Usuários não-locais não podem atualizar sua senha através da interface web do Gitea. @@ -370,12 +449,12 @@ twofa_passcode_incorrect=Seu código de acesso está incorreto. Se você perdeu twofa_scratch_token_incorrect=Seu código de backup está incorreto. login_userpass=Acessar login_openid=OpenID -oauth_signup_tab=Cadastrar nova conta +oauth_signup_tab=Cadastrar Nova Conta oauth_signup_title=Completar Nova Conta -oauth_signup_submit=Completar conta +oauth_signup_submit=Completar Conta oauth_signin_tab=Vincular à uma conta existente -oauth_signin_title=Acesse com uma conta vinculada -oauth_signin_submit=Vincular conta +oauth_signin_title=Acesse para Autorizar Conta Vinculada +oauth_signin_submit=Vincular Conta oauth.signin.error.access_denied=O pedido de autorização foi negado. oauth.signin.error.temporarily_unavailable=A autorização falhou porque o servidor de autenticação está temporariamente indisponível. Por favor, tente novamente mais tarde. openid_connect_submit=Conectar @@ -384,15 +463,21 @@ openid_connect_desc=O URI do OpenID escolhido é desconhecido. Associe-o com uma openid_register_title=Criar uma nova conta openid_register_desc=O URI do OpenID escolhido é desconhecido. Associe-o com uma nova conta aqui. openid_signin_desc=Digite o URI do seu OpenID. Por exemplo: alice.openid.example.org ou https://openid.example.org/alice. +disable_forgot_password_mail=A recuperação de conta está desativada porque nenhum e-mail está configurado. Por favor, contate o administrador do site. +disable_forgot_password_mail_admin=A recuperação de conta só está disponível quando o e-mail está configurado. email_domain_blacklisted=Você não pode se cadastrar com seu endereço de e-mail. -authorize_application=Autorizar aplicativo +authorize_application=Autorizar Aplicativo authorize_redirect_notice=Você será redirecionado para %s se você autorizar este aplicativo. authorize_application_created_by=Este aplicativo foi criado por %s. +authorize_application_description=Se você conceder o acesso, ele será capaz de acessar e escrever em todas as informações da sua conta, incluindo repositórios privados e organizações. authorize_title=Autorizar "%s" para acessar sua conta? authorization_failed=Autorização falhou +authorization_failed_desc=A autorização falhou porque detectamos uma solicitação inválida. Entre em contato com o responsável do aplicativo que você tentou autorizar. sspi_auth_failed=Falha de autenticação SSPI +password_pwned=A senha que você escolheu faz parte de uma lista de senhas roubadas expostas anteriormente em violações de dados. Tente novamente com uma senha diferente e considere alterar a senha em outros lugares. password_pwned_err=Não foi possível concluir a requisição ao HaveIBeenPwned last_admin=Você não pode remover o último administrador. Deve haver pelo menos um administrador. +back_to_sign_in=Voltar ao Login [mail] view_it_on=Veja em %s @@ -409,7 +494,10 @@ activate_email=Verifique seu endereço de e-mail activate_email.title=%s, por favor verifique o seu endereço de e-mail activate_email.text=Por favor clique no link a seguir para verificar o seu endereço de e-mail em %s: +register_notify=Bem-vindo ao %s register_notify.title=%[1]s, bem-vindo(a) a %[2]s +register_notify.text_1=Este é o seu e-mail de confirmação de registro para %s! +register_notify.text_2=Agora você pode entrar com o nome de usuário: %s. register_notify.text_3=Se esta conta foi criada para você, defina sua senha primeiro. reset_password=Recuperar sua conta @@ -441,16 +529,18 @@ release.new.text=@%[1]s lançou a versão %[2]s em %[3]s release.title=Título: %s release.note=Nota: release.downloads=Downloads: -release.download.zip=Código fonte (ZIP) -release.download.targz=Código fonte (TAR.GZ) +release.download.zip=Código-Fonte (ZIP) +release.download.targz=Código-Fonte (TAR.GZ) repo.transfer.subject_to=%s gostaria de transferir "%s" para %s repo.transfer.subject_to_you=%s gostaria de transferir "%s" para você repo.transfer.to_you=você +repo.transfer.body=Para o aceitar ou rejeitar visite %s, ou simplesmente o ignore. repo.collaborator.added.subject=%s adicionou você a %s repo.collaborator.added.text=Você foi adicionado como um colaborador do repositório: + team_invite.subject=%[1]s convidou você para participar da organização %[2]s team_invite.text_1=%[1]s convidou você para participar da equipe %[2]s na organização %[3]s. team_invite.text_2=Por favor, clique no seguinte link para se juntar à equipe: @@ -468,7 +558,7 @@ UserName=Nome de usuário RepoName=Nome do repositório Email=Endereço de e-mail Password=Senha -Retype=Confirmar senha +Retype=Confirmar Senha SSHTitle=Nome da chave SSH HttpsUrl=URL HTTPS PayloadUrl=URL de carga @@ -484,7 +574,7 @@ TreeName=Caminho do arquivo Content=Conteúdo SSPISeparatorReplacement=Separador -SSPIDefaultLanguage=Idioma padrão +SSPIDefaultLanguage=Idioma Padrão require_error=` não pode estar em branco.` alpha_dash_error=` deve conter somente alfanumérico, caracteres de traço ('-') e sublinhado ('_').` @@ -498,6 +588,7 @@ url_error= `"%s" não é um URL válido.` include_error=` deve conter "%s".` glob_pattern_error=` padrão glob é inválido: %s.` regex_pattern_error=` o regex é inválido: %s.` +username_error=` só pode conter caracteres alfanuméricos ('0-9','a-z','A-Z'), traço ('-'), sublinhado ('_') e ponto ('.'). Não pode começar ou terminar com caracteres não alfanuméricos, e caracteres não-alfanuméricos consecutivos também são proibidos.` invalid_group_team_map_error=` mapeamento é inválido: %s` unknown_error=Erro desconhecido: captcha_incorrect=O código CAPTCHA está incorreto. @@ -506,18 +597,23 @@ lang_select_error=Selecione um idioma da lista. username_been_taken=O nome de usuário já está sendo usado. username_change_not_local_user=Usuários não-locais não são autorizados a alterar nome de usuário. +change_username_disabled=Alterar nome de usuário está desabilitado. +change_full_name_disabled=Alterar nome completo está desabilitado. username_has_not_been_changed=Nome de usuário não foi alterado repo_name_been_taken=O nome de repositório já está sendo usado. repository_force_private=Forçar Privado está ativado: repositórios privados não podem ser tornados públicos. repository_files_already_exist=Arquivos já existem neste repositório. Contate o administrador. +repository_files_already_exist.adopt=Arquivos já existem neste repositório e só podem ser adotados. repository_files_already_exist.delete=Arquivos já existem neste repositório. Você deve deletá-los. repository_files_already_exist.adopt_or_delete=Arquivos já existem neste repositório. Você deve adotá-los ou deletá-los. visit_rate_limit=Limitação da taxa de visita remota. +2fa_auth_required=Visita remota requer autenticação de dois fatores. org_name_been_taken=O nome da organização já está sendo usado. team_name_been_taken=O nome da equipe já está sendo usado. team_no_units_error=Permitir acesso a pelo menos uma seção de repositório. email_been_used=Este endereço de e-mail já está sendo usado. email_invalid=O endereço de email é inválido. +email_domain_is_not_allowed=O domínio do e-mail do usuário %s conflita com EMAIL_DOMAIN_ALLOWLIST ou EMAIL_DOMAIN_BLOCKLIST. Por favor, certifique-se de que a sua operação é esperada. openid_been_used=O endereço OpenID "%s" já está sendo usado. username_password_incorrect=Nome de usuário ou senha incorretos. password_complexity=A senha não passa pelos requisitos de complexidade: @@ -529,6 +625,8 @@ enterred_invalid_repo_name=O nome do repositório que você digitou está incorr enterred_invalid_org_name=O nome da organização inserido é incorreto. enterred_invalid_owner_name=O nome do novo proprietário não é válido. enterred_invalid_password=A senha que você digitou está incorreta. +unset_password=O usuário de login não definiu a senha. +unsupported_login_type=O tipo de login não é suportado para excluir a conta. user_not_exist=O usuário não existe. team_not_exist=A equipe não existe. last_org_owner=Você não pode remover o último usuário do time 'proprietários'. Deve haver pelo menos um proprietário em uma organização. @@ -540,10 +638,17 @@ invalid_ssh_key=Não é possível verificar sua chave SSH: %s invalid_gpg_key=Não é possível verificar sua chave GPG: %s invalid_ssh_principal=Nome principal inválido: %s must_use_public_key=A chave que você forneceu é uma chave privada. Por favor, não envie sua chave privada em nenhum lugar. Use sua chave pública em vez disso. +unable_verify_ssh_key=Não é possível verificar a chave SSH, verifique se há erros. auth_failed=Autenticação falhou: %v +still_own_repo=Sua conta possui um ou mais repositórios, exclua ou transfira-os primeiro. +still_has_org=Sua conta é um membro de uma ou mais organizações, deixe-as primeiro. +still_own_packages=Sua conta possui um ou mais pacotes, exclua-os primeiro. +org_still_own_repo=Esta organização ainda possui repositórios, exclua ou transfira-os primeiro. +org_still_own_packages=Esta organização ainda possui pacotes, exclua-os primeiro. target_branch_not_exist=O branch de destino não existe. +target_ref_not_exist=Ref de destino não existe %s admin_cannot_delete_self=Você não pode excluir você mesmo quando você é um administrador. Por favor, remova seus privilégios de administrador primeiro. @@ -551,11 +656,11 @@ admin_cannot_delete_self=Você não pode excluir você mesmo quando você é um change_avatar=Altere seu avatar... joined_on=Inscreveu-se em %s repositories=Repositórios -activity=Atividade pública +activity=Atividade Pública followers=Seguidores -show_more=Mostrar mais -starred=Repositórios favoritos -watched=Repositórios observados +show_more=Mostrar Mais +starred=Repositórios Favoritos +watched=Repositórios Observados code=Código projects=Projetos overview=Visão geral @@ -567,11 +672,28 @@ disabled_public_activity=Este usuário desativou a visibilidade pública da ativ email_visibility.limited=Seu endereço de e-mail está visível para todos os usuários autenticados email_visibility.private=Seu endereço de e-mail é visível apenas para você e administradores show_on_map=Mostrar este lugar em um mapa -settings=Configurações do usuário +settings=Configurações do Usuário form.name_reserved=O nome de usuário "%s" está reservado. form.name_pattern_not_allowed=O padrão de "%s" não é permitido em um nome de usuário. +form.name_chars_not_allowed=Nome de usuário "%s" contém caracteres inválidos. +block.block=Bloquear +block.block.user=Bloquear usuário +block.block.org=Bloquear usuário para organização +block.block.failure=Falha ao bloquear usuário: %s +block.unblock=Desbloquear +block.unblock.failure=Falha ao desbloquear o usuário: %s +block.blocked=Você bloqueou este usuário. +block.title=Bloquear um usuário +block.info_2=seguindo sua conta +block.user_to_block=Usuário a bloquear +block.note=Nota +block.note.title=Nota opcional: +block.note.info=A nota não é visível para o usuário bloqueado. +block.note.edit=Editar nota +block.list=Usuários bloqueados +block.list.none=Você não bloqueou nenhum usuário. [settings] profile=Perfil @@ -581,23 +703,27 @@ password=Senha security=Segurança avatar=Avatar ssh_gpg_keys=Chaves SSH / GPG -social=Contas sociais +social=Contas Sociais applications=Aplicativos -orgs=Gerenciar organizações +orgs=Gerenciar Organizações repos=Repositórios -delete=Excluir conta -account_link=Contas vinculadas +delete=Excluir Conta +twofa=Autenticação de Dois Fatores (TOTP) +account_link=Contas Vinculadas organization=Organizações uid=UID +webauthn=Autenticação de Dois Fatores (Chaves de Segurança) -public_profile=Perfil público +public_profile=Perfil Público biography_placeholder=Conte-nos um pouco sobre você! (Você pode usar Markdown) location_placeholder=Compartilhe sua localização aproximada com outras pessoas -full_name=Nome completo +profile_desc=Controle como o seu perfil é exibido para outros usuários. Seu endereço de e-mail principal será usado para notificações, recuperação de senha e operações do Git baseadas na Web. +password_username_disabled=Você não tem permissão para mudar seu nome de usuário. Entre em contato com o administrador do site para mais detalhes. +full_name=Nome Completo website=Site location=Localização -update_theme=Atualizar o tema -update_profile=Atualizar o perfil +update_theme=Atualizar o Tema +update_profile=Atualizar o Perfil update_language=Atualizar Idioma update_language_not_found=Idioma "%s" não está disponível. update_language_success=O idioma foi atualizado. @@ -610,6 +736,7 @@ cancel=Cancelar language=Idioma ui=Tema hidden_comment_types=Tipos de comentários ocultos +hidden_comment_types_description=Tipos de comentários marcados aqui não serão mostrados nas páginas de issues. Marcar "Etiqueta", por exemplo, remove todos os comentários "{usuário} adicionou/removeu {etiqueta}". hidden_comment_types.ref_tooltip=Comentários onde este issue foi referenciado de outro issue/commit/… hidden_comment_types.issue_ref_tooltip=Comentários onde o usuário altera o branch/tag associado ao issue comment_type_group_reference=Referência @@ -618,7 +745,7 @@ comment_type_group_milestone=Marco comment_type_group_assignee=Atribuído comment_type_group_title=Título comment_type_group_branch=Branch -comment_type_group_time_tracking=Contador de tempo +comment_type_group_time_tracking=Cronômetro comment_type_group_deadline=Prazo final comment_type_group_dependency=Dependência comment_type_group_lock=Status de Bloqueio @@ -628,30 +755,30 @@ comment_type_group_project=Projeto comment_type_group_issue_ref=Referência do issue saved_successfully=Suas configurações foram salvas com sucesso. privacy=Privacidade -keep_activity_private=Ocultar atividade da página de perfil +keep_activity_private=Ocultar Atividade da Página de Perfil keep_activity_private_popup=Torna a atividade visível somente para você e os administradores -lookup_avatar_by_mail=Procurar o avatar do endereço de e-mail -federated_avatar_lookup=Busca de avatar federativo -enable_custom_avatar=Habilitar avatar customizado +lookup_avatar_by_mail=Procurar o Avatar do Endereço de E-mail +federated_avatar_lookup=Busca de Avatar Federativo +enable_custom_avatar=Usar Avatar Customizado choose_new_avatar=Escolha um novo avatar -update_avatar=Atualizar o avatar -delete_current_avatar=Excluir o avatar atual +update_avatar=Atualizar o Avatar +delete_current_avatar=Excluir o Avatar Atual uploaded_avatar_not_a_image=O arquivo enviado não é uma imagem. uploaded_avatar_is_too_big=O tamanho do arquivo enviado (%d KiB) excede o tamanho máximo permitido (%d KiB). update_avatar_success=Seu avatar foi atualizado. update_user_avatar_success=O avatar do usuário foi atualizado. -change_password=Atualizar senha -old_password=Senha atual -new_password=Nova senha -retype_new_password=Confirmar nova senha +change_password=Atualizar Senha +old_password=Senha Atual +new_password=Nova Senha +retype_new_password=Confirmar Nova Senha password_incorrect=A senha atual está incorreta. change_password_success=Sua senha foi atualizada. Acesse usando sua nova senha de agora em diante. password_change_disabled=Contas não-locais não podem alterar sua senha através da interface web do Gitea. -emails=Endereços de e-mail -manage_emails=Gerenciar endereços de e-mail +emails=Endereços de E-mail +manage_emails=Gerenciar Endereços de E-mail manage_themes=Selecione o tema padrão manage_openid=Gerencia endereços OpenID email_desc=Seu endereço de e-mail principal será usado para notificações, recuperação de senha e, desde que não esteja oculto, para operações do Git baseadas na Web. @@ -661,31 +788,33 @@ activated=Ativado requires_activation=Requer ativação primary_email=Tornar Principal activate_email=Enviar Ativação -activations_pending=Ativações pendentes +activations_pending=Ativações Pendentes +can_not_add_email_activations_pending=Há uma ativação pendente, tente novamente em alguns minutos se quiser adicionar um novo e-mail. delete_email=Remover -email_deletion=Remover endereço de e-mail +email_deletion=Remover Endereço de E-mail +email_deletion_desc=Este endereço de e-mail e informações relacionadas serão removidos de sua conta. Commits aplicados por este endereço de e-mail permanecerão inalterados. Continuar? email_deletion_success=O endereço de e-mail foi removido. theme_update_success=Seu tema foi atualizado. theme_update_error=O tema selecionado não existe. openid_deletion=Remover endereço de OpenID openid_deletion_desc=A exclusão deste endereço OpenID da sua conta impedirá que você acesse com ele. Continuar? openid_deletion_success=O endereço de OpenID foi removido. -add_new_email=Adicionar novo endereço de e-mail +add_new_email=Adicionar Novo Endereço de E-mail add_new_openid=Adicionar novo URI OpenID -add_email=Adicionar novo endereço de e-mail +add_email=Adicionar Endereço de E-mail add_openid=Adicionar URI OpenID add_email_confirmation_sent=Um e-mail de confirmação foi enviado para "%s". Verifique sua caixa de entrada nos próximos %s para confirmar seu endereço de e-mail. add_email_success=O novo endereço de e-mail foi adicionado. email_preference_set_success=Preferência de e-mail definida com sucesso. add_openid_success=O novo endereço de OpenID foi adicionado. -keep_email_private=Ocultar endereço de e-mail +keep_email_private=Ocultar Endereço de E-mail keep_email_private_popup=Isso ocultará seu endereço de e-mail do seu perfil, bem como quando você fizer um pull request ou editar um arquivo usando a interface Web. Os commits enviados não serão modificados. openid_desc=OpenID permite delegar autenticação para um provedor externo. manage_ssh_keys=Gerenciar Chaves SSH manage_ssh_principals=Gerenciar Nomes Principais do certificado SSH manage_gpg_keys=Gerenciar chaves GPG -add_key=Adicionar chave +add_key=Adicionar Chave ssh_desc=Estas chaves SSH públicas estão associados a sua conta. Chaves privadas correspondentes permitam acesso completo a seus repositórios. principal_desc=Estes nomes principais do certificado SSH estão associados à sua conta e permitem acesso total aos seus repositórios. gpg_desc=Essas chaves GPG públicas estão associadas à sua conta. Mantenha suas chaves privadas seguras, pois elas permitem que os commits sejam verificados. @@ -701,20 +830,22 @@ ssh_key_name_used=Uma chave SSH com o mesmo nome já existe em sua conta. ssh_principal_been_used=Este nome principal já foi adicionada ao servidor. gpg_key_id_used=Uma chave GPG pública com a mesma ID já existe. gpg_no_key_email_found=Esta chave GPG não corresponde a nenhum endereço de e-mail ativado associado à sua conta. Ela ainda pode ser adicionada se você assinar o token fornecido. -gpg_key_matched_identities=Identidades correspondentes: +gpg_key_matched_identities=Identidades Correspondentes: gpg_key_matched_identities_long=As identidades incorporadas nesta chave coincidem com os seguintes endereços de email ativados para este usuário. Os commits correspondentes a estes endereços de e-mail podem ser verificados com esta chave. -gpg_key_verified=Chave validada +gpg_key_verified=Chave Validada gpg_key_verified_long=A chave foi validada com um token e pode ser usada para verificar commits correspondentes a qualquer endereço de e-mail ativado para esse usuário, além de quaisquer identidades correspondentes para essa chave. gpg_key_verify=Validar +gpg_invalid_token_signature=A chave GPG fornecida, a assinatura e o token não correspondem ou então o token expirou. gpg_token_required=Você tem que fornecer uma assinatura para o token abaixo gpg_token=Token gpg_token_help=Você pode gerar uma assinatura usando: gpg_token_signature=Assinatura GPG blindada key_signature_gpg_placeholder=Começa com '-----BEGIN PGP SIGNATURE-----' verify_gpg_key_success=A chave GPG "%s" foi validada. -ssh_key_verified=Chave validada +ssh_key_verified=Chave Validada ssh_key_verified_long=A chave foi validada com um token e pode ser usada para validar commits que correspondam a qualquer dos endereços de e-mail ativados deste usuário. ssh_key_verify=Validar +ssh_invalid_token_signature=A chave, assinatura ou token SSH fornecidos não coincidem, ou então o token expirou. ssh_token_required=Você tem que fornecer uma assinatura para o token abaixo ssh_token=Token ssh_token_help=Você pode gerar uma assinatura usando: @@ -722,7 +853,7 @@ ssh_token_signature=Assinatura SSH blindada key_signature_ssh_placeholder=Começa com '-----BEGIN SSH SIGNATURE-----' verify_ssh_key_success=A chave SSH "%s" foi validada. subkeys=Subchaves -key_id=ID da chave +key_id=ID da Chave key_name=Nome da Chave key_content=Conteúdo principal_content=Conteúdo @@ -735,6 +866,7 @@ gpg_key_deletion=Remover a chave GPG ssh_principal_deletion=Remover Nome Principal do Certificado SSH ssh_key_deletion_desc=A exclusão de uma chave SSH revoga seu acesso à sua conta. Continuar? gpg_key_deletion_desc=A exclusão de uma chave GPG cancela a verificação de confirmações assinadas por ela. Continuar? +ssh_principal_deletion_desc=A remoção de um Certificado de SSH Principal revoga seu acesso à sua conta. Continuar? ssh_key_deletion_success=A chave SSH foi removida. gpg_key_deletion_success=A chave GPG foi removida. ssh_principal_deletion_success=O nome principal foi removido. @@ -750,23 +882,23 @@ token_state_desc=Este token tem sido utilizado nos últimos 7 dias principal_state_desc=Este nome principal foi utilizado nos últimos 7 dias show_openid=Mostrar no perfil hide_openid=Ocultar no perfil -ssh_disabled=SSH desabilitado +ssh_disabled=SSH Desabilitado ssh_signonly=O SSH está desativado no momento, portanto, essas chaves são usadas apenas para verificação de assinatura de confirmação. ssh_externally_managed=Esta chave SSH para este usuário é gerenciada externamente -manage_social=Gerenciar contas sociais associadas +manage_social=Gerenciar Contas Sociais Associadas social_desc=Essas contas sociais podem ser usadas para fazer login em sua conta. Certifique-se de reconhecer todas elas. unbind=Desvincular unbind_success=A conta social foi removida com sucesso. -manage_access_token=Gerenciar tokens de acesso -generate_new_token=Gerar novo token +manage_access_token=Gerenciar Tokens de Acesso +generate_new_token=Gerar Novo Token tokens_desc=Esses tokens concedem acesso à sua conta usando a API do Gitea. -token_name=Nome do token -generate_token=Gerar token +token_name=Nome do Token +generate_token=Gerar Token generate_token_success=Seu novo token foi gerado. Copie-o agora, pois ele não será mostrado novamente. generate_token_name_duplicate=%s já foi usado como um nome de aplicativo. Por favor, use outro. delete_token=Excluir -access_token_deletion=Excluir token de acesso +access_token_deletion=Excluir Token de Acesso access_token_deletion_cancel_action=Cancelar access_token_deletion_confirm_action=Excluir access_token_deletion_desc=A exclusão de um token revoga o acesso à sua conta para aplicativos que o usam. Continuar? @@ -774,9 +906,11 @@ delete_token_success=O token foi excluído. Os aplicativos que o utilizam já n repo_and_org_access=Acesso ao Repositório e Organização permissions_public_only=Apenas público permissions_access_all=Todos (público, privado e limitado) -permission_no_access=Sem acesso +permission_not_set=Não definido +permission_no_access=Sem Acesso permission_read=Ler -permission_write=Ler e escrever +permission_write=Ler e Escrever +access_token_desc=As permissões de token selecionadas limitam a autorização somente às rotas da API correspondente. Leia a documentação para obter mais informações. at_least_one_permission=Você deve selecionar pelo menos uma permissão para criar um token permissions_list=Permissões: @@ -787,10 +921,11 @@ remove_oauth2_application=Remover aplicativo OAuth2 remove_oauth2_application_desc=Remover um aplicativo OAuth2 irá revogar o acesso a todos os tokens de acesso assinados. Continuar? remove_oauth2_application_success=O aplicativo foi excluído. create_oauth2_application=Criar um novo aplicativo OAuth2 -create_oauth2_application_button=Criar aplicativo +create_oauth2_application_button=Criar Aplicativo create_oauth2_application_success=Você criou um aplicativo OAuth2 com sucesso. update_oauth2_application_success=Você atualizou o aplicativo OAuth2 com sucesso. -oauth2_application_name=Nome do aplicativo +oauth2_application_name=Nome do Aplicativo +oauth2_confidential_client=Cliente Confidencial. Selecione para aplicativos que mantêm a confidencialidade do segredo, como aplicativos web. Não selecione para aplicativos nativos, incluindo aplicativos desktop e celulares. oauth2_redirect_uris=URIs de redirecionamento. Por favor use uma nova linha para cada URI. save_application=Salvar oauth2_client_id=Client ID @@ -804,33 +939,44 @@ oauth2_application_remove_description=A remoção de um aplicativo OAuth2 impedi oauth2_application_locked=O Gitea pré-registra alguns aplicativos OAuth2 na inicialização, se habilitados na configuração. Para evitar um comportamento inesperado, eles não podem ser editados nem removidos. Consulte a documentação do OAuth2 para obter mais informações. authorized_oauth2_applications=Aplicações OAuth2 autorizadas +authorized_oauth2_applications_description=Você concedeu acesso à sua conta pessoal da Gitea para esses aplicativos de terceiros. Revogue o acesso aos aplicativos de que não precisa mais. revoke_key=Revogar -revoke_oauth2_grant=Revogar acesso +revoke_oauth2_grant=Revogar Acesso +revoke_oauth2_grant_description=Revogar o acesso para este aplicativo de terceiros impedirá este aplicativo de acessar seus dados. Tem certeza? revoke_oauth2_grant_success=Acesso revogado com sucesso. +twofa_desc=Para proteger sua conta contra roubo de senhas, você pode usar um smartphone ou outro dispositivo para receber senhas únicas baseadas em tempo único ("TOTP"). twofa_recovery_tip=Se você perder o seu dispositivo, você será capaz de usar uma chave de recuperação de uso único para recuperar o acesso à sua conta. twofa_is_enrolled=Sua conta está atualmente habilitada com autenticação de dois fatores. -twofa_not_enrolled=Sua conta não está atualmente inscrita para a autenticação em duas etapas. -twofa_disable=Desabilitar a autenticação de dois fatores +twofa_not_enrolled=Sua conta não está usando autenticação em dois fatores. +twofa_disable=Desabilitar Autenticação de Dois Fatores +twofa_scratch_token_regenerate=Regenerar Chave de Recuperação de Uso-Único +twofa_scratch_token_regenerated=Sua chave de recuperação de uso único agora é %s. Armazene-a em um lugar seguro, pois não será mostrada novamente. +twofa_enroll=Habilitar Autenticação de Dois Fatores twofa_disable_note=Você pode desabilitar a autenticação de dois fatores se necessário. twofa_disable_desc=Desabilitar a autenticação de dois fatores tornará sua conta menos segura. Tem certeza que deseja continuar? +regenerate_scratch_token_desc=Se você perdeu o seu token de backup, ou teve que usá-lo para realizar um acesso, você pode redefini-lo. twofa_disabled=A autenticação de dois fatores foi desabilitada. scan_this_image=Escaneie esta imagem com o seu aplicativo de autenticação: or_enter_secret=Ou digite esse código: %s then_enter_passcode=E insira a senha mostrada no aplicativo: passcode_invalid=Esse código de acesso é inválido. Tente novamente. +twofa_enrolled=Sua conta foi habilitada com sucesso. Armazene sua chave de recuperação de uso único (%s) em um lugar seguro, pois ela não será exibida novamente. twofa_failed_get_secret=Falha ao obter o segredo. -webauthn_register_key=Adicionar chave de segurança +webauthn_desc=Chaves de segurança são dispositivos de hardware que contém chaves criptográficas. Elas podem ser usadas para autenticação de dois fatores. A chave de segurança deve suportar o padrão WebAuthn Authenticator. +webauthn_register_key=Adicionar Chave de Segurança webauthn_nickname=Apelido -webauthn_delete_key=Remover chave de segurança +webauthn_delete_key=Remover Chave de Segurança +webauthn_delete_key_desc=Se você remover uma chave de segurança, não poderá mais entrar usando ela. Continuar? webauthn_key_loss_warning=Se você perder suas chaves de segurança, perderá o acesso à sua conta. webauthn_alternative_tip=Você pode querer configurar um método de autenticação adicional. -manage_account_links=Gerenciar contas vinculadas +manage_account_links=Gerenciar Contas Vinculadas manage_account_links_desc=Estas contas externas estão vinculadas a sua conta de Gitea. +account_links_not_available=Nenhuma conta externa está conectada à sua conta de Gitea. link_account=Vincular Conta -remove_account_link=Remover conta vinculada +remove_account_link=Remover Conta Vinculada remove_account_link_desc=A exclusão da chave SSH revogará o acesso à sua conta. Continuar? remove_account_link_success=A conta vinculada foi removida. @@ -839,17 +985,17 @@ hooks.desc=Adicione webhooks que serão acionados para todos os reposit orgs_none=Você não é membro de nenhuma organização. repos_none=Você não é proprietário de nenhum repositório. -delete_account=Excluir sua conta +delete_account=Excluir Sua Conta delete_prompt=Esta operação irá apagar permanentemente a sua conta de usuário. Isto NÃO PODERÁ ser desfeito. delete_with_all_comments=Sua conta é mais nova que %s. Para evitar comentários fantasmas, todos os comentários de Issue/PR serão excluídos com ela. -confirm_delete_account=Confirmar exclusão -delete_account_title=Excluir conta de usuário +confirm_delete_account=Confirmar Exclusão +delete_account_title=Excluir Conta de Usuário delete_account_desc=Tem certeza que deseja apagar sua conta de usuário permanentemente? -email_notifications.enable=Habilitar notificações de e-mail -email_notifications.onmention=Somente e-mail com menção -email_notifications.disable=Desabilitar notificações de e-mail -email_notifications.submit=Atualizar preferências de e-mail +email_notifications.enable=Habilitar Notificações de E-mail +email_notifications.onmention=Somente E-mail com Menção +email_notifications.disable=Desabilitar Notificações de E-mail +email_notifications.submit=Definir Preferências de E-mail email_notifications.andyourown=E Suas Próprias Notificações visibility=Visibilidade do usuário @@ -864,8 +1010,9 @@ visibility.private_tooltip=Visível apenas para membros das organizações às q new_repo_helper=Um repositório contém todos os arquivos do projeto, inclusive o histórico de revisões. Já está hospedando um em outro lugar? Migre o repositório. owner=Proprietário owner_helper=Algumas organizações podem não aparecer no menu devido a um limite de contagem dos repositórios. -repo_name=Nome do repositório -repo_size=Tamanho do repositório +repo_name=Nome do Repositório +repo_name_helper=Bons nomes de repositórios usam palavras-chave curtas, memorizáveis e únicas. Um repositório chamado ".profile" ou ".profile-private" pode ser usado para adicionar um README.md para seu perfil de usuário/organização. +repo_size=Tamanho do Repositório template=Modelo template_select=Selecione um modelo. template_helper=Tornar repositório um modelo @@ -876,38 +1023,45 @@ visibility_helper=Tornar o repositório privado visibility_helper_forced=O administrador do site força novos repositórios a serem privados. visibility_fork_helper=(Esta alteração irá afetar todos os forks.) clone_helper=Precisa de ajuda com o clone? Visite a Ajuda. -fork_repo=Fork do repositório +fork_repo=Fork do Repositório fork_from=Fork de already_forked=Você já fez o fork de %s fork_to_different_account=Faça um fork para uma conta diferente fork_visibility_helper=A visibilidade do fork de um repositório não pode ser alterada. fork_branch=Branch a ser clonado para o fork all_branches=Todos os branches +view_all_branches=Ver todos branches +view_all_tags=Ver todas as tags +fork_no_valid_owners=Não é possível fazer um fork desse repositório porque não há proprietários validos. use_template=Usar este modelo +open_with_editor=Abrir com %s download_zip=Baixar ZIP download_tar=Baixar TAR.GZ download_bundle=Baixar PACOTE -generate_repo=Gerar repositório +generate_repo=Gerar Repositório generate_from=Gerar de repo_desc=Descrição repo_desc_helper=Digite uma breve descrição (opcional) +repo_no_desc=Descrição não fornecida +repo_lang=Linguagens repo_gitignore_helper=Selecione modelos do .gitignore. repo_gitignore_helper_desc=Escolha os arquivos que não serão rastreados da lista de modelos para linguagens comuns. Artefatos típicos gerados pelos compiladores de cada linguagem estão incluídos no .gitignore por padrão. -issue_labels=Etiquetas de issue +issue_labels=Etiquetas de Issue issue_labels_helper=Selecione um conjunto de etiquetas de issue. license=Licença license_helper=Selecione um arquivo de licença. license_helper_desc=Uma licença define o que os outros podem e não podem fazer com o seu código. Não tem certeza qual é a mais adequada para o seu projeto? Veja Escolher uma licença. -readme=LEIA-ME -readme_helper=Selecione um modelo de arquivo LEIA-ME. +multiple_licenses=Múltiplas Licenças +readme=README +readme_helper=Selecione um modelo de arquivo README. readme_helper_desc=Aqui você pode escrever uma descrição completa para o seu projeto. -auto_init=Inicializar o repositório (adicionando .gitignore, licença e LEIA-ME) +auto_init=Inicializar o repositório (adicionando .gitignore, licença e README) trust_model_helper=Selecione o modelo de confiança para verificação de assinatura. As opções possíveis são: trust_model_helper_collaborator=Colaborador: Confiar em assinaturas de colaboradores trust_model_helper_committer=Committer: Confiar em assinaturas que correspondem aos committers trust_model_helper_collaborator_committer=Colaborador+Committer: Confiar em assinaturas dos colaboradores que correspondem ao committer trust_model_helper_default=Padrão: Usar o modelo de confiança padrão para esta instalação -create_repo=Criar repositório +create_repo=Criar Repositório default_branch=Branch Padrão default_branch_label=padrão default_branch_helper=O branch padrão é o branch base para pull requests e commits de código. @@ -919,11 +1073,13 @@ mirror_sync=sincronizado mirror_sync_on_commit=Sincronizar quando commits forem enviados mirror_address=Clonar de URL mirror_address_desc=Coloque todas as credenciais necessárias na seção de autorização. +mirror_address_url_invalid=O URL fornecido é inválido. Você deve escapar todos os componentes do URL corretamente. mirror_address_protocol_invalid=O URL fornecido é inválido. Somente locais http(s):// ou git:// podem ser usados para espelhamento. mirror_lfs=Armazenamento de Arquivo Grande (LFS) mirror_lfs_desc=Ativar espelhamento de dados LFS. mirror_lfs_endpoint=Destino LFS -mirror_last_synced=Última sincronização +mirror_lfs_endpoint_desc=A sincronização tentará usar o URL de clonagem para determinar o servidor LFS. Você também pode especificar um destino personalizado se os dados do repositório LFS forem armazenados em outro lugar. +mirror_last_synced=Última Sincronização mirror_password_placeholder=(inalterada) mirror_password_blank_placeholder=(não definida) mirror_password_help=Altere o nome de usuário para apagar uma senha armazenada. @@ -931,10 +1087,12 @@ watchers=Observadores stargazers=Usuários que estrelaram stars_remove_warning=Isto irá remover todos os favoritos dados a este repositório. forks=Forks +stars=Favoritos reactions_more=e %d mais unit_disabled=O administrador do site desabilitou esta seção do repositório. language_other=Outra -adopt_preexisting_label=Adotar arquivos +adopt_search=Digite o nome de usuário para pesquisar por repositórios órfãos… (deixe em branco para encontrar todos) +adopt_preexisting_label=Adotar Arquivos adopt_preexisting=Adotar arquivos pré-existentes adopt_preexisting_content=Criar repositório a partir de %s adopt_preexisting_success=Arquivos adotados e repositório criado a partir de %s @@ -946,12 +1104,15 @@ blame_prior=Ver a responsabilização anterior a esta modificação transfer.accept=Aceitar transferência +transfer.accept_desc=`Transferir para "%s"` transfer.reject=Rejeitar transferência +transfer.reject_desc=`Cancelar a transferência para "%s"` transfer.no_permission_to_accept=Você não tem permissão para aceitar essa transferência. transfer.no_permission_to_reject=Você não tem permissão para rejeitar essa transferência. desc.private=Privado desc.public=Público +desc.public_access=Acesso Público desc.template=Template desc.internal=Interno desc.archived=Arquivado @@ -968,6 +1129,8 @@ template.issue_labels=Etiquetas de issue template.one_item=Deve-se selecionar pelo menos um item de modelo template.invalid=Deve-se selecionar um repositório de modelo +archive.title=Este repositório está arquivado. Você pode visualizar arquivos e cloná-lo. Você não pode abrir issues ou pull requests ou fazer push de commits. +archive.title_date=Este repositório foi arquivado em %s. Você pode visualizar arquivos e cloná-lo. Você não pode abrir issues ou pull requests ou fazer push de commits. archive.issue.nocomment=Este repositório está arquivado. Você não pode comentar nas issues. archive.pull.nocomment=Este repositório está arquivado. Você não pode comentar nos pull requests. @@ -984,19 +1147,22 @@ migrate_options_lfs=Migrar arquivos LFS migrate_options_lfs_endpoint.label=Destino LFS migrate_options_lfs_endpoint.description=A migração tentará usar seu controle remoto Git para determinar o servidor LFS. Você também pode especificar um destino personalizado se os dados do repositório LFS forem armazenados em outro lugar. migrate_options_lfs_endpoint.description.local=Um caminho de servidor local também é suportado. -migrate_items=Itens da migração +migrate_options_lfs_endpoint.placeholder=Se for deixado em branco, o destino será derivado do URL de clone. +migrate_items=Itens da Migração migrate_items_wiki=Wiki migrate_items_milestones=Marcos migrate_items_labels=Etiquetas migrate_items_issues=Issues -migrate_items_pullrequests=Pull requests +migrate_items_pullrequests=Pull Requests migrate_items_merge_requests=Requisições de merge migrate_items_releases=Versões -migrate_repo=Migrar repositório +migrate_repo=Migrar Repositório migrate.clone_address=Migrar / Clonar de URL migrate.clone_address_desc=URL HTTP (S) ou Git 'clone' de um repositório existente +migrate.github_token_desc=Você pode colocar um ou mais tokens aqui, separados por vírgulas, para tornar a migração mais rápida, contornando os limites da API do GitHub. AVISO: abusar deste recurso pode violar a política do provedor de serviços e pode levar a que a sua(s) conta(s) seja bloqueada. migrate.clone_local_path=ou um caminho de servidor local migrate.permission_denied=Você não pode importar repositórios locais. +migrate.permission_denied_blocked=Você não pode importar dos hosts não permitidos, por favor peça ao administrador para verificar as configurações ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS. migrate.invalid_local_path=O caminho local é inválido. Ele não existe ou não é um diretório. migrate.invalid_lfs_endpoint=O destino LFS não é válido. migrate.failed=Migração falhou: %v @@ -1004,6 +1170,7 @@ migrate.migrate_items_options=Um Token de Acesso é necessário para migrar iten migrated_from=Migrado de %[2]s migrated_from_fake=Migrado de %[1]s migrate.migrate=Migrar de %s +migrate.migrating=Migrando de %s… migrate.migrating_failed=Migração a partir de %s falhou. migrate.migrating_failed.error=Falha ao migrar: %s migrate.migrating_failed_no_addr=A migração falhou. @@ -1015,15 +1182,21 @@ migrate.gogs.description=Migrar dados de notabug.org ou de outras instâncias do migrate.onedev.description=Migrar dados de code.onedev.io ou de outras instâncias do OneDev. migrate.codebase.description=Migrar dados de codebasehq.com. migrate.gitbucket.description=Migrar dados de instâncias do GitBucket. +migrate.codecommit.description=Migrar dados do AWS CodeCommit. +migrate.codecommit.aws_access_key_id=Chave ID AWS (Access Key ID) +migrate.codecommit.aws_secret_access_key=Chave Secreta AWS (Secret Access Key) +migrate.codecommit.https_git_credentials_username=Nome de Usuário para Git HTTPS +migrate.codecommit.https_git_credentials_password=Senha para Git HTTPS migrate.migrating_git=Migrando dados Git -migrate.migrating_topics=Migrando tópicos +migrate.migrating_topics=Migrando Tópicos migrate.migrating_milestones=Migrando Marcos migrate.migrating_labels=Migrando Rótulos migrate.migrating_releases=Migrando Versões migrate.migrating_issues=Migrando Issues migrate.migrating_pulls=Migrando Pull Requests -migrate.cancel_migrating_title=Cancelar migração +migrate.cancel_migrating_title=Cancelar Migração migrate.cancel_migrating_confirm=Você quer cancelar essa migração? +migration_status=Status da migração mirror_from=espelhamento de forked_from=feito fork de @@ -1037,7 +1210,8 @@ watch=Observar unstar=Retirar dos favoritos star=Juntar aos favoritos fork=Fork -download_archive=Baixar repositório +action.blocked_user=Não é possível executar a ação porque você está bloqueado pelo proprietário do repositório. +download_archive=Baixar Repositório more_operations=Mais Operações quick_guide=Guia Rápido @@ -1045,6 +1219,7 @@ clone_this_repo=Clonar este repositório cite_this_repo=Citar este repositório create_new_repo_command=Criando um novo repositório por linha de comando push_exist_repo=Realizando push para um repositório existente por linha de comando +empty_message=Este repositório está vazio. broken_message=Os dados Git subjacentes a este repositório não podem ser lidos. Entre em contato com o administrador desta instância ou exclua este repositório. code=Código @@ -1057,11 +1232,12 @@ find_tag=Pesquisar etiqueta branches=Branches tags=Tags issues=Issues -pulls=Pull requests +pulls=Pull Requests projects=Projetos packages=Pacotes actions=Ações labels=Etiquetas +org_labels_desc=Etiquetas a nível de organização que podem ser usadas com todos os repositórios sob esta organização org_labels_desc_manage=gerenciar milestone=Marco @@ -1073,13 +1249,15 @@ releases=Versões tag=Tag released_this=lançou isto tagged_this=criou essa tag +file.title=%s em %s file_raw=Original file_history=Histórico -file_view_source=Exibir código-fonte +file_view_source=Exibir Código-Fonte file_view_rendered=Ver Renderizado -file_view_raw=Ver original +file_view_raw=Ver Original file_permalink=Link permanente file_too_large=O arquivo é muito grande para ser mostrado. +file_is_empty=O arquivo está vazio. invisible_runes_header=`Este arquivo contém caracteres Unicode invisíveis` invisible_runes_description=`Este arquivo contém caracteres Unicode invisíveis que são indistinguíveis para humanos, mas que podem ser processados de forma diferente por um computador. Se você acha que isso é intencional, pode ignorar esse aviso com segurança. Use o botão Escapar para revelá-los` ambiguous_runes_header=`Este arquivo contém caracteres Unicode ambíguos` @@ -1094,9 +1272,9 @@ view_git_blame=Ver Git Blame video_not_supported_in_browser=Seu navegador não suporta a tag 'video' do HTML5. audio_not_supported_in_browser=Seu navegador não suporta a tag 'audio' do HTML5. symbolic_link=Link simbólico -executable_file=Arquivo executável +executable_file=Arquivo Executável generated=Gerado -commit_graph=Gráfico de commits +commit_graph=Gráfico de Commits commit_graph.select=Selecionar branches commit_graph.hide_pr_refs=Esconder Pull Requests commit_graph.monochrome=Monocromático @@ -1106,37 +1284,41 @@ commit.contained_in_default_branch=Esse commit faz parte do branch padrão commit.load_referencing_branches_and_tags=Carregar branches e tags que fazem referência a este commit blame=Anotar download_file=Baixar arquivo -normal_view=Visão normal +normal_view=Visão Normal line=linha lines=linhas from_comment=(comentário) editor.add_file=Adicionar Arquivo -editor.new_file=Novo arquivo -editor.upload_file=Enviar arquivo -editor.edit_file=Editar arquivo -editor.preview_changes=Visualizar alterações +editor.new_file=Novo Arquivo +editor.upload_file=Enviar Arquivo +editor.edit_file=Editar Arquivo +editor.preview_changes=Visualizar Alterações editor.cannot_edit_lfs_files=Arquivos LFS não podem ser editados na interface web. +editor.cannot_edit_too_large_file=O arquivo é muito grande para ser editado. editor.cannot_edit_non_text_files=Arquivos binários não podem ser editados na interface web. -editor.edit_this_file=Editar arquivo +editor.file_not_editable_hint=Mas você ainda pode renomear ou movê-lo. +editor.edit_this_file=Editar Arquivo editor.this_file_locked=Arquivo está bloqueado editor.must_be_on_a_branch=Você deve estar em um branch para propor alterações neste arquivo. editor.fork_before_edit=Você deve fazer um fork desse repositório para fazer ou propor alterações neste arquivo. -editor.delete_this_file=Excluir arquivo +editor.delete_this_file=Excluir Arquivo editor.must_have_write_access=Você deve ter permissão de escrita para fazer ou propor alterações neste arquivo. editor.file_delete_success=O arquivo "%s" foi excluído. editor.name_your_file=Nomeie o seu arquivo… editor.filename_help=Adicione um diretório digitando seu nome seguido por uma barra ('/'). Remova um diretório digitando o backspace no início do campo de entrada. editor.or=ou editor.cancel_lower=Cancelar -editor.commit_signed_changes=Commit de alteradores assinadas -editor.commit_changes=Aplicar commit das alterações +editor.commit_signed_changes=Criar Commit das Alterações Assinadas +editor.commit_changes=Criar Commit das Alterações +editor.add_tmpl=Adicionar '{filename}' editor.add=Adicionar %s editor.update=Atualizar %s editor.delete=Excluir %s editor.patch=Aplicar Correção editor.patching=Corrigindo: -editor.new_patch=Nova correção +editor.fail_to_apply_patch=Não foi possível aplicar correção +editor.new_patch=Nova Correção editor.commit_message_desc=Adicione uma descrição detalhada (opcional)... editor.signoff_desc=Adicione um assinado-por-committer no final do log do commit. editor.commit_directly_to_this_branch=Commit diretamente no branch %s. @@ -1151,6 +1333,7 @@ editor.filename_is_invalid=O nome do arquivo é inválido: "%s". editor.branch_does_not_exist=Branch "%s" não existe neste repositório. editor.branch_already_exists=Branch "%s" já existe neste repositório. editor.directory_is_a_file=O nome do diretório "%s" já é usado como um nome de arquivo neste repositório. +editor.file_is_a_symlink=`"%s" é um link simbólico. Links simbólicos não podem ser editados no editor da web` editor.filename_is_a_directory=O nome do arquivo "%s" já é usado como um nome de diretório neste repositório. editor.file_changed_while_editing=O conteúdo do arquivo mudou desde que você começou a editar. Clique aqui para ver o que foi editado ou clique em Aplicar commit das alterações novamemente para sobreescrever estas alterações. editor.file_already_exists=Um arquivo com nome "%s" já existe neste repositório. @@ -1159,7 +1342,7 @@ editor.commit_empty_file_text=O arquivo que você está prestes fazer commit est editor.no_changes_to_show=Nenhuma alteração a mostrar. editor.push_rejected_no_message=A alteração foi rejeitada pelo servidor sem uma mensagem. Por favor, verifique os Hooks Git. editor.push_rejected=A alteração foi rejeitada pelo servidor. Por favor, verifique os Hooks Git. -editor.push_rejected_summary=Mensagem completa de rejeição: +editor.push_rejected_summary=Mensagem Completa de Rejeição: editor.add_subdir=Adicionar um subdiretório... editor.unable_to_upload_files=Ocorreu um erro ao enviar arquivos para "%s": %v editor.upload_file_is_locked=Arquivo "%s" está bloqueado por %s. @@ -1170,13 +1353,16 @@ editor.user_no_push_to_branch=O usuário não pode fazer push no branch editor.require_signed_commit=Branch requer um commit assinado editor.cherry_pick=Cherry-pick %s para: editor.revert=Reverter %s para: +editor.failed_to_commit=Falha ao criar commit das alterações. +editor.failed_to_commit_summary=Mensagem de Erro: -commits.desc=Veja o histórico de alterações do código de fonte. +commits.desc=Veja o histórico de alterações do código-fonte. commits.commits=Commits commits.no_commits=Nenhum commit em comum. "%s" e "%s" tem históricos completamente diferentes. commits.nothing_to_compare=Estes branches são iguais. commits.search.tooltip=Você pode prefixar as palavras-chave com "author:" (autor da mudança), "committer:" (autor do commit), "after:" (depois) ou "before:" (antes). Por exemplo: "revert author:Ana before:2019-01-13".\ +commits.search_branch=Este Branch commits.search_all=Todos os branches commits.author=Autor commits.message=Mensagem @@ -1210,7 +1396,7 @@ projects.description=Descrição (opcional) projects.description_placeholder=Descrição projects.create=Criar Projeto projects.title=Título -projects.new=Novo projeto +projects.new=Novo Projeto projects.new_subheader=Coordene, acompanhe e atualize seu trabalho em um só lugar, para que os projetos permaneçam transparentes e dentro do cronograma. projects.create_success=Projeto "%s" criado. projects.deletion=Apagar Projeto @@ -1221,25 +1407,25 @@ projects.edit_subheader=Projetos organizam issues e acompanham o progresso. projects.modify=Atualizar Projeto projects.edit_success=Projeto "%s" atualizado. projects.type.none=Nenhum -projects.type.basic_kanban=Kanban básico +projects.type.basic_kanban=Kanban Básico projects.type.bug_triage=Triagem de Bugs projects.template.desc=Modelo de projeto projects.template.desc_helper=Selecione um modelo de projeto para começar projects.column.edit=Editar coluna projects.column.edit_title=Nome projects.column.new_title=Nome -projects.column.new_submit=Criar coluna +projects.column.new_submit=Criar Coluna projects.column.new=Nova Coluna -projects.column.set_default=Atribuir como padrão +projects.column.set_default=Atribuir como Padrão projects.column.set_default_desc=Definir esta coluna como padrão para pull e issues sem categoria -projects.column.delete=Excluir coluna +projects.column.delete=Excluir Coluna projects.column.color=Cor projects.open=Abrir projects.close=Fechar projects.column.assigned_to=Atribuído a projects.card_type.desc=Pré-visualizações de Cards projects.card_type.images_and_text=Imagens e Texto -projects.card_type.text_only=Somente texto +projects.card_type.text_only=Somente Texto issues.desc=Organize relatórios de bugs, tarefas e marcos. issues.filter_assignees=Filtrar Atribuição @@ -1247,40 +1433,42 @@ issues.filter_milestones=Filtrar Marco issues.filter_projects=Filtrar Projeto issues.filter_labels=Filtrar Rótulo issues.filter_reviewers=Filtrar Revisor -issues.new=Nova issue +issues.filter_no_results=Nenhum resultado +issues.filter_no_results_placeholder=Tente ajustar seus filtros de pesquisa. +issues.new=Nova Issue issues.new.title_empty=Título não pode ser em branco issues.new.labels=Etiquetas -issues.new.no_label=Sem etiqueta +issues.new.no_label=Sem Etiqueta issues.new.clear_labels=Limpar etiquetas issues.new.projects=Projetos issues.new.clear_projects=Limpar projetos issues.new.no_projects=Sem projeto issues.new.open_projects=Abrir Projetos -issues.new.closed_projects=Projetos fechados +issues.new.closed_projects=Projetos Fechados issues.new.no_items=Nenhum item issues.new.milestone=Marco -issues.new.no_milestone=Sem marco +issues.new.no_milestone=Sem Marco issues.new.clear_milestone=Limpar marco issues.new.assignees=Responsáveis issues.new.clear_assignees=Limpar responsáveis -issues.new.no_assignees=Sem responsável -issues.choose.get_started=Primeiros passos +issues.new.no_assignees=Sem Responsáveis +issues.choose.get_started=Primeiros Passos issues.choose.open_external_link=Abrir 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.choose.invalid_templates=%v modelo(s) inválido(s) encontrado(s) issues.choose.invalid_config=A configuração da issue contém erros: -issues.no_ref=Nenhum branch/tag especificado -issues.create=Criar issue -issues.new_label=Nova etiqueta +issues.no_ref=Nenhum Branch/Tag Especificado +issues.create=Criar Issue +issues.new_label=Nova Etiqueta issues.new_label_placeholder=Nome da etiqueta issues.new_label_desc_placeholder=Descrição -issues.create_label=Criar etiqueta +issues.create_label=Criar Etiqueta issues.label_templates.title=Carregue um conjunto de etiquetas pré-definidas issues.label_templates.info=Ainda não existem etiquetas. Crie uma etiqueta em 'Nova etiqueta' ou use um conjunto de etiquetas predefinida: issues.label_templates.helper=Selecione um conjunto de etiquetas -issues.label_templates.use=Use o conjunto de etiquetas +issues.label_templates.use=Usar Conjunto de Etiquetas issues.label_templates.fail_to_load_file=Falha ao carregar o modelo de etiquetas "%s": %v issues.add_label=adicionou o rótulo %s %s issues.add_labels=adicionou os rótulos %s %s @@ -1361,16 +1549,18 @@ issues.num_comments_1=%d comentário issues.num_comments=%d comentários issues.commented_at=`comentou %s` issues.delete_comment_confirm=Tem certeza que deseja excluir este comentário? -issues.context.copy_link=Copiar link -issues.context.quote_reply=Citar resposta -issues.context.reference_issue=Referência em uma nova issue +issues.context.copy_link=Copiar Link +issues.context.quote_reply=Citar Resposta +issues.context.reference_issue=Referência em uma Nova Issue issues.context.edit=Editar issues.context.delete=Excluir issues.no_content=Nenhuma descrição fornecida. -issues.close=Fechar issue +issues.close=Fechar Issue issues.comment_pull_merged_at=aplicou o merge do commit %[1]s em %[2]s %[3]s issues.comment_manually_pull_merged_at=aplicou o merge manual do commit %[1]s em %[2]s %[3]s +issues.close_comment_issue=Comentar e Fechar issues.reopen_issue=Reabrir +issues.reopen_comment_issue=Comentar e Reabrir issues.create_comment=Comentar issues.closed_at=`fechou esta issue %[2]s` issues.reopened_at=`reabriu esta issue %[2]s` @@ -1387,16 +1577,18 @@ issues.author_helper=Este usuário é o autor. issues.role.owner=Proprietário issues.role.owner_helper=Este usuário é o dono deste repositório. issues.role.member=Membro +issues.role.member_helper=Este usuário é um membro da organização proprietária deste repositório. issues.role.collaborator=Colaborador issues.role.collaborator_helper=Este usuário foi convidado para colaborar no repositório. issues.role.first_time_contributor=Primeira vez contribuindo issues.role.first_time_contributor_helper=Esta é a primeira contribuição deste usuário para o repositório. issues.role.contributor=Contribuidor +issues.role.contributor_helper=Este usuário já fez commit para o repositório. issues.re_request_review=Re-solicitar revisão issues.is_stale=Houve alterações nessa PR desde essa revisão issues.remove_request_review=Remover solicitação de revisão issues.remove_request_review_block=Não é possível remover a solicitação de revisão -issues.dismiss_review=Descartar revisão +issues.dismiss_review=Descartar Revisão issues.dismiss_review_warning=Tem certeza de que deseja descartar esta revisão? issues.sign_in_require_desc=Acesse para participar desta conversação. issues.edit=Editar @@ -1405,18 +1597,20 @@ issues.save=Salvar issues.label_title=Nome da etiqueta issues.label_description=Descrição da etiqueta issues.label_color=Cor da etiqueta +issues.label_color_invalid=Cor inválida issues.label_exclusive=Exclusivo -issues.label_archive=Arquivar etiqueta +issues.label_archive=Arquivar Etiqueta issues.label_archived_filter=Mostrar etiquetas arquivadas issues.label_archive_tooltip=Etiquetas arquivadas são excluídas, por padrão, das sugestões ao pesquisar por etiqueta. issues.label_exclusive_desc=Nomeie o rótulo escopo/item para torná-lo mutuamente exclusivo com outros rótulos do escopo/. issues.label_exclusive_warning=Quaisquer rótulos com escopo conflitantes serão removidos ao editar os rótulos de uma issue ou pull request. +issues.label_exclusive_order=Ordem issues.label_count=%d etiquetas issues.label_open_issues=%d issues abertas issues.label_edit=Editar issues.label_delete=Excluir -issues.label_modify=Editar etiqueta -issues.label_deletion=Excluir etiqueta +issues.label_modify=Editar Etiqueta +issues.label_deletion=Excluir Etiqueta issues.label_deletion_desc=A exclusão desta etiqueta irá removê-la de todas as issues. Tem certeza que deseja continuar? issues.label_deletion_success=A etiqueta foi excluída. issues.label.filter_sort.alphabetically=Alfabeticamente @@ -1453,20 +1647,27 @@ issues.delete=Apagar issues.delete.title=Apagar esta issue? issues.delete.text=Você realmente deseja excluir esta issue? (Isto irá remover permanentemente todo o conteúdo. Considere fechá-la em vez disso, se você pretende mantê-la arquivado) -issues.tracker=Contador de tempo +issues.tracker=Cronômetro +issues.timetracker_timer_start=Iniciar cronômetro +issues.timetracker_timer_stop=Parar cronômetro +issues.timetracker_timer_discard=Descartar cronômetro +issues.timetracker_timer_manually_add=Adicionar Tempo -issues.tracker_auto_close=Contador de tempo será parado automaticamente quando esta issue for fechada +issues.start_tracking_history=começou a trabalhar %s +issues.tracker_auto_close=Cronômetro será parado automaticamente quando esta issue for fechada issues.tracking_already_started=`Você já iniciou o cronômetro em outra issue!` +issues.stop_tracking=Parar Cronômetro +issues.stop_tracking_history=trabalhou por %[1]s %[2]s issues.cancel_tracking_history=`cronômetro cancelado %s` issues.del_time=Apagar este registro de tempo issues.del_time_history=`removeu tempo gasto %s` issues.add_time_hours=Horas issues.add_time_minutes=Minutos issues.add_time_sum_to_small=Nenhum tempo foi inserido. -issues.time_spent_total=Tempo total gasto -issues.time_spent_from_all_authors=`Tempo total gasto: %s` +issues.time_spent_total=Tempo Total Gasto +issues.time_spent_from_all_authors=`Tempo Total Gasto: %s` -issues.due_date=Data limite +issues.due_date=Data Limite issues.invalid_due_date_format=Formato da data limite inválido, deve ser 'dd/mm/aaaa'. issues.error_modifying_due_date=Falha ao modificar a data limite. issues.error_removing_due_date=Falha ao remover a data limite. @@ -1478,7 +1679,7 @@ issues.due_date_form=dd/mm/aaaa issues.due_date_form_add=Adicionar data limite issues.due_date_form_edit=Editar issues.due_date_form_remove=Remover -issues.due_date_not_set=Data limite não informada. +issues.due_date_not_set=Data limite não definida. issues.due_date_added=adicionou a data limite %s %s issues.due_date_modified=modificou a data limite de %[2]s para %[1]s %[3]s issues.due_date_remove=removeu a data limite %s %s @@ -1503,10 +1704,10 @@ issues.dependency.pr_close_blocks=Este pull request bloqueia o fechamento das se issues.dependency.issue_batch_close_blocked=Não é possível fechar as issues que você escolheu, porque a issue #%d ainda tem dependências abertas issues.dependency.blocks_short=Bloqueia issues.dependency.blocked_by_short=Depende de -issues.dependency.remove_header=Remover dependência +issues.dependency.remove_header=Remover Dependência issues.dependency.issue_remove_text=Isto removerá a dependência desta issue. Continuar? issues.dependency.pr_remove_text=Isto removerá a dependência deste pull request. Continuar? -issues.dependency.setting=Habilitar dependências para issues e pull requests +issues.dependency.setting=Habilitar Dependências para Issues e Pull Requests issues.dependency.add_error_same_issue=Você não pode fazer uma issue depender de si mesma. issues.dependency.add_error_dep_issue_not_exist=Issue dependente não existe. issues.dependency.add_error_dep_not_exist=Dependência não existe. @@ -1515,6 +1716,7 @@ issues.dependency.add_error_dep_not_same_repo=Ambas as issues devem estar no mes issues.review.self.approval=Você não pode aprovar o seu próprio pull request. issues.review.self.rejection=Você não pode solicitar alterações em seu próprio pull request. issues.review.approve=aprovou estas alterações %s +issues.review.comment=revisou %s issues.review.dismissed_label=Rejeitada issues.review.left_comment=deixou um comentário issues.review.content.empty=Você precisa deixar um comentário indicando as alterações solicitadas. @@ -1522,6 +1724,7 @@ issues.review.reject=alterações solicitadas %s issues.review.wait=foi solicitada para revisão %s issues.review.add_review_request=solicitou revisão de %s %s issues.review.remove_review_request=removeu a solicitação de revisão para %s %s +issues.review.remove_review_request_self=recusou revisar %s issues.review.pending=Pendente issues.review.pending.tooltip=Este comentário não está atualmente visível para outros usuários. Para enviar seus comentários pendentes, selecione "%s" -> "%s/%s/%s" no topo da página. issues.review.review=Revisão @@ -1538,6 +1741,7 @@ issues.review.resolve_conversation=Resolver conversa issues.review.un_resolve_conversation=Conversa não resolvida issues.review.resolved_by=marcou esta conversa como resolvida issues.review.commented=Comentar +issues.assignee.error=Nem todos os responsáveis foram adicionados devido a um erro inesperado. issues.reference_issue.body=Conteúdo issues.content_history.deleted=excluído issues.content_history.edited=editado @@ -1551,9 +1755,9 @@ compare.compare_base=base compare.compare_head=comparar pulls.desc=Habilitar pull requests e revisões de código. -pulls.new=Novo pull request +pulls.new=Novo Pull Request pulls.view=Ver Pull Request -pulls.compare_changes=Novo pull request +pulls.compare_changes=Novo Pull Request pulls.allow_edits_from_maintainers=Permitir edições de mantenedores pulls.allow_edits_from_maintainers_desc=Usuários com acesso de gravação para o branch base também podem fazer push para este branch pulls.allow_edits_from_maintainers_err=Falha na atualização @@ -1577,13 +1781,13 @@ pulls.filter_changes_by_commit=Filtrar por commit pulls.nothing_to_compare=Estes branches são iguais. Não há nenhuma necessidade para criar um pull request. pulls.nothing_to_compare_and_allow_empty_pr=Estes branches são iguais. Este PR ficará vazio. pulls.has_pull_request=`Um pull request entre esses branches já existe: %[2]s#%[3]d` -pulls.create=Criar pull request +pulls.create=Criar Pull Request pulls.title_desc=quer aplicar o merge de %[1]d commits de %[2]s em %[3]s pulls.merged_title_desc=aplicou merge dos %[1]d commits de %[2]s em %[3]s %[4]s pulls.change_target_branch_at=`mudou o branch de destino de %s para %s %s` pulls.tab_conversation=Conversação pulls.tab_commits=Commits -pulls.tab_files=Arquivos alterados +pulls.tab_files=Arquivos Alterados pulls.reopen_to_merge=Por favor reabra este pull request para aplicar o merge. pulls.cant_reopen_deleted_branch=Este pull request não pode ser reaberto porque o branch foi excluído. pulls.merged=Merge aplicado @@ -1633,9 +1837,9 @@ pulls.merge_commit_id=A ID de merge commit pulls.require_signed_wont_sign=O branch requer commits assinados, mas este merge não será assinado pulls.invalid_merge_option=Você não pode usar esta opção de merge neste pull request. -pulls.merge_conflict_summary=Mensagem de erro +pulls.merge_conflict_summary=Mensagem de Erro pulls.rebase_conflict_summary=Mensagem de Erro -pulls.push_rejected_summary=Mensagem completa da rejeição +pulls.push_rejected_summary=Mensagem Completa da Rejeição pulls.open_unmerged_pull_exists=`Não é possível executar uma operação de reabertura pois há um pull request pendente (#%d) com propriedades idênticas.` pulls.status_checking=Algumas verificações estão pendentes pulls.status_checks_success=Todas as verificações foram bem sucedidas @@ -1651,7 +1855,7 @@ pulls.update_branch_rebase=Atualizar branch por rebase pulls.update_branch_success=Atualização do branch foi bem-sucedida pulls.update_not_allowed=Você não tem permissão para atualizar o branch pulls.outdated_with_base_branch=Este branch está desatualizado com o branch base -pulls.close=Fechar pull request +pulls.close=Fechar Pull Request pulls.closed_at=`fechou este pull request %[2]s` pulls.reopened_at=`reabriu este pull request %[2]s` pulls.cmd_instruction_checkout_title=Checkout @@ -1675,30 +1879,33 @@ pulls.delete.title=Excluir este pull request? pulls.delete.text=Você realmente deseja excluir este pull request? (Isto irá remover permanentemente todo o conteúdo. Considere fechá-la em vez disso, se você pretende mantê-la arquivado) pulls.recently_pushed_new_branches=Você fez push no branch %[1]s %[2]s +pulls.upstream_diverging_merge=Sincronizar fork pull.deleted_branch=(excluído):%s +pull.agit_documentation=Veja a documentação sobre AGit -milestones.new=Novo marco +milestones.new=Novo Marco milestones.closed=Fechado %s milestones.update_ago=Atualizado há %s milestones.no_due_date=Sem data limite milestones.open=Reabrir milestones.close=Fechar milestones.new_subheader=Os marcos podem ajudá-lo a organizar os problemas e acompanhar seu progresso. -milestones.create=Criar marco +milestones.completeness=%d%% Concluído +milestones.create=Criar Marco milestones.title=Título milestones.desc=Descrição -milestones.due_date=Data limite (opcional) +milestones.due_date=Data Limite (opcional) milestones.clear=Limpar milestones.invalid_due_date_format=Formato da data limite deve ser 'dd/mm/aaaa'. milestones.create_success=O marco "%s" foi criado. -milestones.edit=Editar marco +milestones.edit=Editar Marco milestones.edit_subheader=Marcos organizam as issues e acompanham o progresso. milestones.cancel=Cancelar -milestones.modify=Atualizar marco +milestones.modify=Atualizar Marco milestones.edit_success=O marco "%s" foi atualizado. -milestones.deletion=Excluir marco +milestones.deletion=Excluir Marco milestones.deletion_desc=A exclusão deste marco irá removê-lo de todas as issues. Tem certeza que deseja continuar? milestones.deletion_success=O marco foi excluído. milestones.filter_sort.name=Nome @@ -1753,6 +1960,7 @@ wiki.original_git_entry_tooltip=Ver o arquivo Git original em vez de usar o link activity=Atividade activity.navbar.pulse=Pulso activity.navbar.contributors=Contribuidores +activity.navbar.recent_commits=Commits Recentes activity.period.filter_label=Período: activity.period.daily=1 dia activity.period.halfweekly=3 dias @@ -1762,12 +1970,12 @@ activity.period.quarterly=3 meses activity.period.semiyearly=6 meses activity.period.yearly=1 ano activity.overview=Visão geral -activity.active_prs_count_1=%d Pull request ativo -activity.active_prs_count_n=%d Pull requests ativos -activity.merged_prs_count_1=Pull request com merge aplicado -activity.merged_prs_count_n=Pull requests com merge aplicado -activity.opened_prs_count_1=Pull request proposto -activity.opened_prs_count_n=Pull requests propostos +activity.active_prs_count_1=%d Pull Request Ativo +activity.active_prs_count_n=%d Pull Requests Ativos +activity.merged_prs_count_1=Pull Request com Merge Aplicado +activity.merged_prs_count_n=Pull Requests com Merge Aplicado +activity.opened_prs_count_1=Pull Request Proposto +activity.opened_prs_count_n=Pull Requests Propostos activity.title.user_1=%d usuário activity.title.user_n=%d usuários activity.title.prs_1=%d Pull request @@ -1776,20 +1984,20 @@ activity.title.prs_merged_by=%s com merge aplicado por %s activity.title.prs_opened_by=%s proposto(s) por %s activity.merged_prs_label=Merge aplicado activity.opened_prs_label=Proposto -activity.active_issues_count_1=%d Issue ativa -activity.active_issues_count_n=%d Issues ativas -activity.closed_issues_count_1=Issue fechada -activity.closed_issues_count_n=Issues fechadas +activity.active_issues_count_1=%d Issue Ativa +activity.active_issues_count_n=%d Issues Ativas +activity.closed_issues_count_1=Issue Fechada +activity.closed_issues_count_n=Issues Fechadas activity.title.issues_1=+%d Issue activity.title.issues_n=+%d Issues activity.title.issues_closed_from=%s fechada por %s activity.title.issues_created_by=%s criada por %s activity.closed_issue_label=Fechado -activity.new_issues_count_1=Nova issue -activity.new_issues_count_n=Novas issues +activity.new_issues_count_1=Nova Issue +activity.new_issues_count_n=Novas Issues activity.new_issue_label=Aberta -activity.title.unresolved_conv_1=%d conversa não resolvida -activity.title.unresolved_conv_n=%d conversas não resolvidas +activity.title.unresolved_conv_1=%d Conversa Não Resolvida +activity.title.unresolved_conv_n=%d Conversas Não Resolvidas activity.unresolved_conv_desc=Estas issues foram recentemente alteradas e pull requests ainda não foram resolvidos. activity.unresolved_conv_label=Aberta activity.title.releases_1=%d Versão @@ -1824,6 +2032,7 @@ contributors.contribution_type.deletions=Exclusões settings=Configurações settings.options=Repositório +settings.public_access=Acesso Público settings.collaboration=Colaboradores settings.collaboration.admin=Administrador settings.collaboration.write=Escrita @@ -1832,7 +2041,7 @@ settings.collaboration.owner=Proprietário settings.collaboration.undefined=Indefinido settings.hooks=Webhooks settings.githooks=Hooks do Git -settings.basic_settings=Configurações básicas +settings.basic_settings=Configurações Básicas settings.mirror_settings=Opções de espelhamento settings.mirror_settings.docs=Configure o seu repositório para sincronizar automaticamente commits, tags e branches de outro repositório. settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning=No momento, isso só pode ser feito no menu "Nova migração". Para obter mais informações, consulte: @@ -1858,11 +2067,12 @@ settings.branches.add_new_rule=Adicionar Nova Regra settings.advanced_settings=Configurações avançadas settings.wiki_desc=Habilitar a wiki do repositório settings.use_internal_wiki=Usar a wiki nativa +settings.default_wiki_branch_name=Nome Padrão do Branch da Wiki settings.use_external_wiki=Usar wiki externa settings.external_wiki_url=URL externa da wiki settings.external_wiki_url_error=A URL da wiki externa não é válida. settings.external_wiki_url_desc=Visitantes são redirecionados para a URL da wiki externa ao clicar na aba da wiki. -settings.issues_desc=Habilitar issue tracker para o repositório +settings.issues_desc=Habilitar Issue Tracker para o Repositório settings.use_internal_issue_tracker=Usar o issue tracker nativo settings.use_external_issue_tracker=Usar issue tracker externo settings.external_tracker_url=URL do issue tracker externo @@ -1887,6 +2097,7 @@ settings.pulls.default_delete_branch_after_merge=Excluir o branch de pull reques settings.pulls.default_allow_edits_from_maintainers=Permitir edições de mantenedores por padrão settings.releases_desc=Habilitar versões do Repositório settings.packages_desc=Habilitar Registro de Pacotes de Repositório +settings.projects_desc=Habilitar Projetos settings.projects_mode_all=Todos os projetos settings.actions_desc=Habilitar ações do repositório settings.admin_settings=Configurações do administrador @@ -1896,7 +2107,8 @@ settings.admin_stats_indexer=Indexador de Estatísticas do Código settings.admin_indexer_commit_sha=Último SHA indexado settings.admin_indexer_unindexed=Não indexado settings.reindex_button=Adicionar à fila de reindexação -settings.reindex_requested=Reindexação requisitada +settings.reindex_requested=Reindexação Requisitada +settings.admin_enable_close_issues_via_commit_in_any_branch=Fechar issue via commit em um branch não padrão settings.danger_zone=Zona de perigo settings.new_owner_has_same_repo=O novo proprietário já tem um repositório com o mesmo nome. Por favor, escolha outro nome. settings.convert=Converter para repositório tradicional @@ -1914,6 +2126,7 @@ settings.transfer.rejected=A transferência do repositório foi rejeitada. settings.transfer.success=A transferência do repositório foi bem sucedida. settings.transfer_abort=Cancelar transferência settings.transfer_abort_invalid=Não é possível cancelar uma transferência de repositório não existente. +settings.transfer_abort_success=A transferência do repositório para %s foi cancelada com sucesso. settings.transfer_desc=Transferir este repositório para outro usuário ou para uma organização onde você tem direitos de administrador. settings.transfer_form_title=Digite o nome do repositório para confirmar: settings.transfer_notices_1=- Você perderá o acesso ao repositório se transferir para um usuário individual. @@ -1935,9 +2148,9 @@ settings.trust_model.collaboratorcommitter.long=Colaborador+Committer: Confiar n settings.wiki_delete=Excluir dados da wiki settings.wiki_delete_desc=A exclusão de dados da wiki é permanente e não pode ser desfeita. settings.wiki_delete_notices_1=- Isso excluirá e desabilitará permanentemente a wiki do repositório %s. -settings.confirm_wiki_delete=Excluir dados da wiki +settings.confirm_wiki_delete=Excluir Dados da Wiki settings.wiki_deletion_success=Os dados da wiki do repositório foi excluídos. -settings.delete=Excluir este repositório +settings.delete=Excluir Este Repositório settings.delete_desc=A exclusão de um repositório é permanente e não pode ser desfeita. settings.delete_notices_1=- Esta operação NÃO PODERÁ ser desfeita. settings.delete_notices_fork_1=- Forks deste repositório se tornarão independentes após a exclusão. @@ -1967,6 +2180,7 @@ settings.hooks_desc=Webhooks automaticamente fazem requisições de HTTP POST pa settings.webhook_deletion=Remover webhook settings.webhook_deletion_desc=A exclusão de um webhook exclui suas configurações e o histórico de entrega. Continuar? settings.webhook_deletion_success=O webhook foi removido. +settings.webhook.test_delivery=Testar Evento de Push settings.webhook.request=Solicitação settings.webhook.response=Resposta settings.webhook.headers=Cabeçalhos @@ -2005,11 +2219,13 @@ settings.event_wiki_desc=Página da wiki criada, renomeada, editada ou excluída settings.event_release=Versão settings.event_release_desc=Versão publicada, atualizada ou excluída em um repositório. settings.event_push=Push +settings.event_force_push=Forçar Push settings.event_push_desc=Git push para o repositório. settings.event_repository=Repositório settings.event_repository_desc=Repositório criado ou excluído. settings.event_header_issue=Eventos da Issue settings.event_issues=Issues +settings.event_issues_desc=Issue aberta, fechada, reaberta, editada ou excluída. settings.event_issue_assign=Issue Atribuída settings.event_issue_assign_desc=Issue atribuída ou não atribuída. settings.event_issue_label=Issue Rotulada @@ -2020,6 +2236,7 @@ settings.event_issue_comment=Comentário da issue settings.event_issue_comment_desc=Comentário da issue criado, editado ou excluído. settings.event_header_pull_request=Eventos de Pull Request settings.event_pull_request=Pull request +settings.event_pull_request_desc=Pull request aberto, fechado, reaberto, editado ou excluído. settings.event_pull_request_assign=Pull Request Atribuído settings.event_pull_request_assign_desc=Pull request atribuído ou desatribuído. settings.event_pull_request_label=Pull Request Rotulado @@ -2066,7 +2283,7 @@ settings.packagist_username=Nome de usuário no Packagist settings.packagist_api_token=Token de API settings.packagist_package_url=URL do pacote do Packagist settings.deploy_keys=Chaves de Deploy -settings.add_deploy_key=Nova chave +settings.add_deploy_key=Nova Chave de Deploy settings.deploy_key_desc=As chaves de deploy possuem somente acesso de leitura (pull) ao repositório. settings.is_writable=Habilitar acesso de escrita settings.is_writable_info=Permitir que esta chave de deploy faça push para o repositório. @@ -2078,14 +2295,22 @@ settings.key_name_used=Uma chave de deploy já existe com esse mesmo nome. settings.deploy_key_deletion=Remover chave de deploy settings.deploy_key_deletion_desc=A exclusão de uma chave de deploy irá revogar o seu acesso a este repositório. Continuar? settings.deploy_key_deletion_success=A chave de deploy foi removida. +settings.branches=Branches +settings.protected_branch=Proteção de Branch settings.protected_branch.save_rule=Salvar Regra settings.protected_branch.delete_rule=Excluir Regra +settings.protected_branch_can_push=Permitir push? +settings.protected_branch_can_push_yes=Você pode fazer push +settings.protected_branch_can_push_no=Você não pode fazer push settings.protect_this_branch=Habilitar Proteção de Branch settings.protect_this_branch_desc=Previne a exclusão e restringe o merge e push para o branch. settings.protect_disable_push=Desabilitar push settings.protect_disable_push_desc=Nenhum push será permitido neste branch. -settings.protect_enable_push=Habilitar push +settings.protect_disable_force_push=Desativar Push Forçado +settings.protect_disable_force_push_desc=Nenhum push forçado será permitido para este branch. +settings.protect_enable_push=Habilitar Push settings.protect_enable_push_desc=Qualquer pessoa com acesso de escrita terá permissão para realizar push neste branch (mas não forçar o push). +settings.protect_enable_force_push_all=Ativar Push Forçado settings.protect_enable_merge=Permitir merge settings.protect_check_status_contexts=Habilitar verificação de status settings.protect_check_status_contexts_list=Verificações de status encontradas na última semana para este repositório @@ -2098,6 +2323,8 @@ settings.protect_branch_name_pattern=Padrão de Nome de Branch Protegida settings.protect_patterns=Padrões settings.protect_protected_file_patterns=Padrões de arquivos protegidos (separados usando ponto e vírgula ';'): settings.protect_unprotected_file_patterns=Padrões de arquivos desprotegidos (separados usando ponto e vírgula ';'): +settings.add_protected_branch=Habilitar proteção +settings.delete_protected_branch=Desabilitar proteção settings.update_protect_branch_success=Proteção do branch "%s" foi atualizada. settings.remove_protected_branch_success=Proteção do branch "%s" foi desabilitada. settings.remove_protected_branch_failed=Removendo regra de proteção de branch "%s" falhou. @@ -2130,8 +2357,10 @@ settings.chat_id=ID do Chat settings.matrix.homeserver_url=URL do Homeserver settings.matrix.room_id=ID da Sala settings.matrix.message_type=Tipo de Mensagem +settings.visibility.private.button=Tornar Privado +settings.visibility.public.button=Tornar Público settings.archive.button=Arquivar repositório -settings.archive.header=Arquivar este repositório +settings.archive.header=Arquivar Este Repositório settings.archive.success=O repositório foi arquivado com sucesso. settings.archive.error=Um erro ocorreu enquanto estava sendo arquivado o repositório. Veja o log para mais detalhes. settings.archive.error_ismirror=Você não pode arquivar um repositório espelhado. @@ -2171,16 +2400,16 @@ settings.rename_branch_from=nome antigo do branch settings.rename_branch_to=novo nome do branch settings.rename_branch=Renomear branch -diff.browse_source=Ver código fonte +diff.browse_source=Ver Código-Fonte diff.parent=pai diff.commit=commit diff.git-notes=Notas -diff.data_not_available=Conteúdo de diff não disponível -diff.options_button=Opções de diferenças -diff.download_patch=Baixar arquivo de patch -diff.download_diff=Baixar arquivo de diferenças -diff.show_split_view=Visão dividida -diff.show_unified_view=Visão unificada +diff.data_not_available=Conteúdo de Diff Não Disponível +diff.options_button=Opções de Diff +diff.download_patch=Baixar Arquivo de Patch +diff.download_diff=Baixar Arquivo de Diff +diff.show_split_view=Visão Dividida +diff.show_unified_view=Visão Unificada diff.whitespace_button=Espaço em branco diff.whitespace_show_everything=Mostrar todas as alterações diff.whitespace_ignore_all_whitespace=Ignorar todas as alterações de espaço em branco @@ -2190,7 +2419,7 @@ diff.stats_desc= %d arquivos alterados com %d adições diff.stats_desc_file=%d alterações: %d adições e %d exclusões diff.bin=BIN diff.bin_not_shown=Arquivo binário não exibido. -diff.view_file=Ver arquivo +diff.view_file=Ver Arquivo diff.file_before=Antes diff.file_after=Depois diff.file_image_width=Largura @@ -2199,10 +2428,11 @@ diff.file_byte_size=Tamanho diff.file_suppressed=Diferenças do arquivo suprimidas por serem muito extensas diff.file_suppressed_line_too_long=Diff do arquivo suprimido porque uma ou mais linhas são muito longas diff.too_many_files=Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff -diff.show_more=Mostrar mais +diff.show_more=Mostrar Mais diff.load=Carregar Diff diff.generated=gerado diff.vendored=externo +diff.comment.add_line_comment=Adicionar comentário na linha diff.comment.placeholder=Deixe um comentário diff.comment.add_single_comment=Adicionar um único comentário diff.comment.add_review_comment=Adicionar comentário @@ -2229,7 +2459,7 @@ releases.desc=Acompanhe as versões e downloads do projeto. release.releases=Versões release.detail=Detalhes da versão release.tags=Tags -release.new_release=Nova versão +release.new_release=Nova Versão release.draft=Rascunho release.prerelease=Versão prévia release.stable=Estável @@ -2238,7 +2468,7 @@ release.edit=editar release.ahead.commits=%d commits release.ahead.target=para %s desde esta versão tag.ahead.target=para %s desde esta tag -release.source_code=Código fonte +release.source_code=Código-Fonte release.new_subheader=Lançamentos organizam versões do projeto. release.edit_subheader=Lançamentos organizam versões do projeto. release.tag_name=Nome da tag @@ -2252,12 +2482,12 @@ release.message=Descreva esta versão release.prerelease_desc=Marcar como pré-lançamento release.prerelease_helper=Marcar esta versão como inadequada para uso em produção. release.cancel=Cancelar -release.publish=Publicar versão -release.save_draft=Salvar rascunho -release.edit_release=Atualizar versão -release.delete_release=Excluir versão +release.publish=Publicar Versão +release.save_draft=Salvar Rascunho +release.edit_release=Atualizar Versão +release.delete_release=Excluir Versão release.delete_tag=Apagar Tag -release.deletion=Excluir versão +release.deletion=Excluir Versão release.deletion_desc=A exclusão de uma versão apenas a remove do Gitea. Isso não afetará a tag do Git, o conteúdo do seu repositório ou seu histórico. Continuar? release.deletion_success=A versão foi excluída. release.deletion_tag_desc=A tag será excluída do repositório. Conteúdo do repositório e histórico permanecerão inalterados. Continuar? @@ -2269,14 +2499,14 @@ release.tag_already_exist=Este nome de tag já existe. release.downloads=Downloads release.download_count=Downloads: %s release.add_tag_msg=Use o título e o conteúdo do lançamento como mensagem da tag. -release.add_tag=Criar apenas a tag +release.add_tag=Criar Apenas a Tag release.releases_for=Versões para %s release.tags_for=Tags para %s branch.name=Nome do Branch branch.already_exists=Um branch com o nome "%s" já existe. branch.delete_head=Excluir -branch.delete=`Excluir branch "%s"` +branch.delete=`Excluir Branch "%s"` branch.delete_html=Excluir Branch branch.deletion_success=Branch "%s" excluído. branch.deletion_failed=Falha ao excluir o branch "%s". @@ -2290,9 +2520,10 @@ branch.restore_success=Branch "%s" restaurado. branch.restore_failed=Ocorreu um erro ao restaurar o branch "%s". branch.protected_deletion_failed=Branch "%s" é protegido. Ele não pode ser excluído. branch.default_deletion_failed=Branch "%s" é o branch padrão. Ele não pode ser excluído. -branch.restore=`Restaurar branch "%s"` -branch.download=`Baixar branch "%s"` -branch.rename=`Renomear branch "%s"` +branch.default_branch_not_exist=Branch padrão "%s" não existe. +branch.restore=`Restaurar Branch "%s"` +branch.download=`Baixar Branch "%s"` +branch.rename=`Renomear Branch "%s"` branch.included_desc=Este branch faz parte do branch padrão branch.included=Incluído branch.create_new_branch=Criar branch a partir do branch: @@ -2304,6 +2535,7 @@ branch.create_branch_operation=Criar branch branch.new_branch=Criar novo branch branch.new_branch_from=`Criar novo branch a partir de "%s"` branch.renamed=Branch %s foi renomeado para %s. +branch.commits_no_divergence=O mesmo que branch %[1]s tag.create_tag=Criar tag %s tag.create_tag_operation=Criar tag @@ -2323,43 +2555,50 @@ error.csv.unexpected=Não é possível renderizar este arquivo porque ele conté error.csv.invalid_field_count=Não é possível renderizar este arquivo porque ele tem um número errado de campos na linha %d. [graphs] +component_loading=Carregando %s… component_loading_failed=Não foi possível carregar %s component_loading_info=Isto pode demorar um pouco… +component_failed_to_load=Ocorreu um erro inesperado. +contributors.what=contribuições +recent_commits.what=commits recentes [org] -org_name_holder=Nome da organização -org_full_name_holder=Nome completo da organização +org_name_holder=Nome da Organização +org_full_name_holder=Nome Completo da Organização org_name_helper=Nomes de organização devem ser curtos e memoráveis. -create_org=Criar organização +create_org=Criar Organização repo_updated=Atualizado members=Membros teams=Equipes code=Código lower_members=membros lower_repositories=repositórios -create_new_team=Nova equipe -create_team=Criar equipe +create_new_team=Nova Equipe +create_team=Criar Equipe org_desc=Descrição -team_name=Nome da equipe +team_name=Nome da Equipe team_desc=Descrição team_name_helper=Nomes de equipe devem ser curtos e memoráveis. team_desc_helper=Descreva a finalidade ou o papel da equipe. team_access_desc=Acesso ao repositório team_permission_desc=Permissão -team_unit_desc=Permitir o acesso a seções de repositório +team_unit_desc=Permitir o Acesso a Seções de Repositório team_unit_disabled=(Desabilitado) form.name_reserved=O nome de organização "%s" está reservado. +form.name_pattern_not_allowed=O padrão "%s" não é permitido em um nome de organização. form.create_org_not_allowed=Você não tem permissão para criar uma organização. settings=Configurações settings.options=Organização -settings.full_name=Nome completo +settings.full_name=Nome Completo +settings.email=E-mail de contato settings.website=Site settings.location=Localização settings.permission=Permissões settings.repoadminchangeteam=O administrador do repositório pode adicionar e remover o acesso para equipes settings.visibility=Visibilidade +settings.change_visibility=Alterar Visibilidade settings.visibility.public=Pública settings.visibility.limited=Limitado (Visível apenas para usuários autenticados) settings.visibility.limited_shortname=Limitado @@ -2369,22 +2608,24 @@ settings.visibility.private_shortname=Privado settings.update_settings=Atualizar Configurações settings.update_setting_success=Configurações da organização foram atualizadas. +settings.rename=Renomear Organização +settings.rename_new_org_name=Novo Nome da Organização settings.update_avatar_success=O avatar da organização foi atualizado. -settings.delete=Excluir organização -settings.delete_account=Excluir esta organização +settings.delete=Excluir Organização +settings.delete_account=Excluir Esta Organização settings.delete_prompt=A organização será excluída permanentemente. Isto NÃO PODERÁ ser desfeito! -settings.confirm_delete_account=Confirmar exclusão +settings.confirm_delete_account=Confirmar Exclusão settings.hooks_desc=Adicionar Webhooks que serão acionados para todos os repositórios desta organização. settings.labels_desc=Adicionar rótulos que possam ser usadas em issues para todos os repositórios desta organização. -members.membership_visibility=Visibilidade da associação: +members.membership_visibility=Visibilidade da Associação: members.public=Público members.public_helper=tornar privado members.private=Privado members.private_helper=tornar público -members.member_role=Categoria de membro: +members.member_role=Categoria de Membro: members.owner=Proprietário members.member=Membro members.remove=Remover @@ -2392,7 +2633,7 @@ members.remove.detail=Remover %[1]s de %[2]s? members.leave=Sair members.leave.detail=Sair de %s? members.invite_desc=Adicionar novo membro em %s: -members.invite_now=Convidar agora +members.invite_now=Convidar Agora teams.join=Juntar-se teams.leave=Deixar @@ -2406,25 +2647,25 @@ teams.read_access=Leitura teams.read_access_helper=Os membros podem ver e clonar os repositórios da equipe. teams.write_access=Escrita teams.write_access_helper=Os membros podem ler e realizar push para os repositórios da equipe. -teams.admin_access=Acesso de administrador +teams.admin_access=Acesso de Administrador teams.admin_access_helper=Os membros podem realizar pull e push em repositórios da equipe e adicionar colaboradores a eles. teams.no_desc=Esta equipe não tem descrição teams.settings=Configurações teams.owners_permission_desc=Proprietários tem acesso total a todos repositórios e também direitos de administrador na organização. -teams.members=Membros da equipe -teams.update_settings=Atualizar configurações -teams.delete_team=Excluir equipe -teams.add_team_member=Adicionar membro na equipe +teams.members=Membros da Equipe +teams.update_settings=Atualizar Configurações +teams.delete_team=Excluir Equipe +teams.add_team_member=Adicionar Membro na Equipe teams.invite_team_member=Convidar para %s -teams.invite_team_member.list=Convites pendentes -teams.delete_team_title=Excluir equipe +teams.invite_team_member.list=Convites Pendentes +teams.delete_team_title=Excluir Equipe teams.delete_team_desc=A exclusão de uma equipe revoga o acesso ao repositório de seus membros. Continuar? teams.delete_team_success=A equipe foi excluída. teams.read_permission_desc=Essa equipe concede acesso para Leitura: membros podem ver e clonar os repositórios da equipe. teams.write_permission_desc=Esta equipe concede acesso para escrita: Membros podem ler e fazer push para os repositórios da equipe. teams.admin_permission_desc=Esta equipe concede acesso de Administrador: Membros podem ler, fazer push e adicionar outros colaboradores para os repositórios da equipe. teams.create_repo_permission_desc=Além disso, esta equipe concede permissão de Criar repositório: membros podem criar novos repositórios na organização. -teams.repositories=Repositórios da equipe +teams.repositories=Repositórios da Equipe teams.remove_all_repos_title=Remover todos os repositórios da equipe teams.remove_all_repos_desc=Isto irá remover todos os repositórios da equipe. teams.add_all_repos_title=Adicionar todos os repositórios @@ -2432,6 +2673,7 @@ teams.add_all_repos_desc=Isto irá adicionar todos os repositórios da organiza teams.add_duplicate_users=Usuário já é um membro da equipe. teams.repos.none=Nenhum repositório pode ser acessado por essa equipe. teams.members.none=Nenhum membro nesta equipe. +teams.members.blocked_user=Não é possível adicionar o usuário porque ele está bloqueado pela organização. teams.specific_repositories=Repositórios específicos teams.specific_repositories_helper=Os membros terão acesso apenas aos repositórios explicitamente adicionados à equipe. Selecionar este não removerá automaticamente os repositórios já adicionados com Todos os repositórios. teams.all_repositories=Todos os repositórios @@ -2443,21 +2685,27 @@ teams.invite.title=Você foi convidado para fazer parte da equipe %s%s @@ -2956,6 +3235,7 @@ raw_minutes=minutos [dropzone] default_message=Arraste e solte arquivos aqui, ou clique para selecioná-los. +invalid_input_type=Você não pode enviar arquivos deste tipo. file_too_big=Tamanho de arquivo ({{filesize}} MB) excede o máximo de ({{maxFilesize}} MB). remove_file=Remover arquivo @@ -2981,6 +3261,8 @@ error.no_committer_account=Nenhuma conta vinculada ao e-mail do autor do commit error.no_gpg_keys_found=Nenhuma chave conhecida encontrada para esta assinatura no banco de dados error.not_signed_commit=Não é um commit assinado error.failed_retrieval_gpg_keys=Falha em obter qualquer chave anexada à conta do autor do commit +error.probable_bad_signature=AVISO! Embora exista uma chave com este ID no banco de dados, ela não verifica este commit! Este commit é SUSPEITO. +error.probable_bad_default_signature=AVISO! Embora a chave padrão tenha este ID, ela não verifica este commit! Este commit é SUSPEITO. [units] unit=Unidade @@ -2993,6 +3275,7 @@ desc=Gerenciar pacotes do repositório. empty=Não há pacotes ainda. empty.documentation=Para obter mais informações sobre o registro de pacotes, consulte a documentação. empty.repo=Você enviou um pacote, mas ele não está aqui? Vá para configurações do pacote e vincule-o a este repositório. +registry.documentation=Para obter mais informações sobre o registro %s, consulte a documentação. filter.type=Tipo filter.type.all=Todos filter.no_result=Seu filtro não produziu resultados. @@ -3016,45 +3299,60 @@ versions=Versões versions.view_all=Ver todas dependency.id=ID dependency.version=Versão +alpine.registry=Configure este registro adicionando o URL no arquivo /etc/apk/repositories: alpine.registry.key=Baixe a chave RSA pública do registro para a pasta /etc/apk/keys/ para verificar a assinatura do índice: alpine.registry.info=Escolha o $branch e $repository da lista abaixo. alpine.install=Para instalar o pacote, execute o seguinte comando: -alpine.repository=Informações do repositório +alpine.repository=Informações do Repositório +alpine.repository.branches=Branches alpine.repository.repositories=Repositórios alpine.repository.architectures=Arquiteturas -arch.repository=Informações do repositório +arch.repository=Informações do Repositório arch.repository.repositories=Repositórios arch.repository.architectures=Arquiteturas +cargo.registry=Configure este registro no arquivo de configuração do Cargo (por exemplo ~/.cargo/config.toml): cargo.install=Para instalar o pacote usando Cargo, execute o seguinte comando: +chef.registry=Configure este registro em seu arquivo ~/.chef/config.rb: chef.install=Para instalar o pacote, execute o seguinte comando: +composer.registry=Configure este registro em seu arquivo ~/.composer/config.json: composer.install=Para instalar o pacote usando o Composer, execute o seguinte comando: composer.dependencies=Dependências composer.dependencies.development=Dependências de Desenvolvimento conan.details.repository=Repositório +conan.registry=Configure este registro pela linha de comando: conan.install=Para instalar o pacote usando o Conan, execute o seguinte comando: +conda.registry=Configure este registro como um repositório Conda no arquivo .condarc: conda.install=Para instalar o pacote usando o Conda, execute o seguinte comando: container.details.type=Tipo de Imagem container.details.platform=Plataforma container.pull=Puxe a imagem pela linha de comando: +container.digest=Digest container.multi_arch=S.O. / Arquitetura container.layers=Camadas da Imagem container.labels=Rótulos container.labels.key=Chave container.labels.value=Valor +cran.registry=Configure este registro no arquivo Rprofile.site: cran.install=Para instalar o pacote, execute o seguinte comando: +debian.registry=Configure este registro pela linha de comando: debian.registry.info=Escolha uma $distribution e um $component da lista abaixo: debian.install=Para instalar o pacote, execute o seguinte comando: -debian.repository=Informações do repositório +debian.repository=Informações do Repositório debian.repository.distributions=Distribuições debian.repository.components=Componentes debian.repository.architectures=Arquiteturas generic.download=Baixar pacote pela linha de comando: go.install=Instale o pacote usando o comando: +helm.registry=Configure este registro pela linha de comando: helm.install=Para instalar o pacote, execute o seguinte comando: +maven.registry=Configure este registro no arquivo pom.xml do seu projeto: +maven.install=Para usar o pacote inclua o seguinte no bloco de dependencies no arquivo pom.xml: maven.install2=Executar via linha de comando: maven.download=Para baixar a dependência, execute via linha de comando: +nuget.registry=Configurar este registro pela linha de comando: nuget.install=Para instalar o pacote usando NuGet, execute o seguinte comando: nuget.dependency.framework=Estrutura Alvo +npm.registry=Configure este registro no arquivo .npmrc do seu projeto: npm.install=Para instalar o pacote usando o npm, execute o seguinte comando: npm.install2=ou adicione-o ao arquivo package.json: npm.dependencies=Dependências @@ -3065,24 +3363,27 @@ npm.details.tag=Tag pub.install=Para instalar o pacote usando Dart, execute o seguinte comando: pypi.requires=Requer Python pypi.install=Para instalar o pacote usando pip, execute o seguinte comando: +rpm.registry=Configure este registro pela linha de comando: rpm.distros.redhat=em distribuições baseadas no RedHat rpm.distros.suse=em distribuições baseadas no SUSE rpm.install=Para instalar o pacote, execute o seguinte comando: -rpm.repository=Informações do repositório +rpm.repository=Informações do Repositório rpm.repository.architectures=Arquiteturas +rpm.repository.multiple_groups=Esse pacote está disponível em vários grupos. rubygems.install=Para instalar o pacote usando gem, execute o seguinte comando: rubygems.install2=ou adicione-o ao Gemfile: rubygems.dependencies.runtime=Dependências de Execução rubygems.dependencies.development=Dependências de Desenvolvimento rubygems.required.ruby=Requer o Ruby versão rubygems.required.rubygems=Requer o RubyGem versão +swift.registry=Configure este registro pela linha de comando: swift.install=Adicione o pacote em seu arquivo Package.swift: swift.install2=e execute o seguinte comando: vagrant.install=Para adicionar uma Vagrant box, execute o seguinte comando: 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=Selecionar Repositório settings.link.button=Atualizar Link do Repositório +settings.link.success=Link do repositório foi atualizado com sucesso. settings.link.error=Falha ao atualizar o link do repositório. settings.delete=Excluir o pacote settings.delete.description=A exclusão de um pacote é permanente e não pode ser desfeita. @@ -3091,13 +3392,17 @@ settings.delete.success=O pacote foi excluído. settings.delete.error=Falha ao excluir o pacote. owner.settings.cargo.title=Índice do Registro Cargo owner.settings.cargo.initialize=Iniciar Índice +owner.settings.cargo.initialize.description=É necessário um repositório Git de índice especial para usar o registro do Cargo. O uso dessa opção (re)criará o repositório e o configurará automaticamente. owner.settings.cargo.initialize.error=Falha ao inicializar índice Cargo: %v owner.settings.cargo.initialize.success=O índice Cargo foi criado com sucesso. owner.settings.cargo.rebuild=Reconstruir Índice +owner.settings.cargo.rebuild.description=A recompilação pode ser útil se o índice não estiver sincronizado com os pacotes Cargo armazenados. owner.settings.cargo.rebuild.error=Falha ao reconstruir índice Cargo: %v +owner.settings.cargo.rebuild.success=O índice Cargo foi reconstruído com sucesso. owner.settings.cleanuprules.title=Gerenciar Regras de Limpeza owner.settings.cleanuprules.add=Adicionar Regra de Limpeza owner.settings.cleanuprules.edit=Editar Regra de Limpeza +owner.settings.cleanuprules.none=Não há regras de limpeza disponíveis. Consulte a documentação. owner.settings.cleanuprules.preview=Pré-visualizar Regra de Limpeza owner.settings.cleanuprules.preview.overview=%d pacotes agendados para serem removidos. owner.settings.cleanuprules.preview.none=A regra de limpeza não corresponde a nenhum pacote. @@ -3116,6 +3421,7 @@ owner.settings.cleanuprules.success.update=Regra de limpeza foi atualizada. owner.settings.cleanuprules.success.delete=Regra de limpeza foi excluída. owner.settings.chef.title=Registro Chef owner.settings.chef.keypair=Gerar par de chaves +owner.settings.chef.keypair.description=Um par de chaves é necessário para autenticar o registro do Chef. Se você já tiver gerado um par de chaves antes, a geração de um novo par de chaves descartará o par de chaves antigo. [secrets] secrets=Segredos @@ -3175,6 +3481,7 @@ runners.delete_runner=Deletar esse runner runners.delete_runner_success=Runner excluído com sucesso runners.delete_runner_failed=Falha ao excluir runner runners.delete_runner_header=Confirme para excluir este runner +runners.delete_runner_notice=Se uma tarefa estiver sendo executada neste runner, ela será encerrada e marcada como falha. Pode quebrar o workflow de construção. runners.none=Nenhum runner disponível runners.status.unspecified=Desconhecido runners.status.idle=Inativo @@ -3189,24 +3496,49 @@ runs.commit=Commit runs.scheduled=Agendado runs.pushed_by=push feito por runs.invalid_workflow_helper=O arquivo de configuração do workflow é inválido. Por favor, verifique seu arquivo de configuração: %s +runs.no_matching_online_runner_helper=Nenhum runner online com a etiqueta: %s runs.actor=Ator runs.status=Status runs.actors_no_select=Todos os atores runs.status_no_select=Todos os Status runs.no_results=Não houve correspondência de resultados. +runs.no_workflows=Ainda não existem workflows. +runs.no_workflows.quick_start=Não sabe como começar com as Ações do Gitea? Veja o guia de início rápido. +runs.no_workflows.documentation=Para obter mais informações sobre as Ações do Gitea, consulte a documentação. +runs.no_runs=O workflow ainda não foi executado. runs.empty_commit_message=(mensagem de commit vazia) +workflow.disable=Desabilitar Workflow +workflow.disable_success=Workflow '%s' desativado com sucesso. +workflow.enable=Habilitar Workflow +workflow.enable_success=Workflow '%s' habilitado com sucesso. +workflow.disabled=Workflow está desativado. need_approval_desc=Precisa de aprovação para executar workflows para pull request do fork. +variables=Variáveis +variables.management=Gerenciamento de Variáveis +variables.creation=Adicionar Variável +variables.none=Ainda não há variáveis. +variables.deletion=Remover variável +variables.deletion.description=A remoção de uma variável é permanente e não pode ser desfeita. Continuar? +variables.id_not_exist=A variável com o ID %d não existe. +variables.edit=Editar Variável +variables.deletion.failed=Falha ao remover a variável. +variables.deletion.success=A variável foi removida. +variables.creation.failed=Falha ao adicionar a variável. +variables.creation.success=A variável "%s" foi adicionada. +variables.update.failed=Falha ao editar a variável. +variables.update.success=A variável foi editada. [projects] -type-1.display_name=Projeto individual -type-2.display_name=Projeto do repositório -type-3.display_name=Projeto da organização +type-1.display_name=Projeto Individual +type-2.display_name=Projeto do Repositório +type-3.display_name=Projeto da Organização [git.filemode] +changed_filemode=%[1]s → %[2]s ; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … directory=Diretório normal_file=Arquivo normal diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 099d4a7816..9c028cf72f 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -120,6 +120,7 @@ error404=A página que pretende aceder não existe ou n error503=O servidor não conseguiu concluir o seu pedido. Tente novamente mais tarde. go_back=Voltar invalid_data=Dados inválidos: %v +nothing_has_been_changed=Nada foi alterado. never=Nunca unknown=Desconhecido @@ -550,6 +551,14 @@ repo.transfer.body=Para o aceitar ou rejeitar, visite %s ou ignore-o, simplesmen repo.collaborator.added.subject=%s adicionou você a %s repo.collaborator.added.text=Foi adicionado(a) como colaborador(a) do repositório: +repo.actions.run.failed=A execução falhou +repo.actions.run.succeeded=A execução foi bem sucedida +repo.actions.run.cancelled=A execução foi cancelada +repo.actions.jobs.all_succeeded=Todos os trabalhos foram bem sucedidos +repo.actions.jobs.all_failed=Todos os trabalhos falharam +repo.actions.jobs.some_not_successful=Alguns trabalhos não foram bem sucedidos +repo.actions.jobs.all_cancelled=Todos os trabalhos foram cancelados + team_invite.subject=%[1]s fez-lhe um convite para se juntar à organização %[2]s team_invite.text_1=%[1]s fez-lhe um convite para se juntar à equipa %[2]s na organização %[3]s. team_invite.text_2=Clique na ligação seguinte para se juntar à equipa: @@ -2843,6 +2852,11 @@ settings.location=Localização settings.permission=Permissões settings.repoadminchangeteam=O administrador do repositório pode adicionar e remover o acesso às equipas settings.visibility=Visibilidade +settings.change_visibility=Alterar visibilidade +settings.change_visibility_notices_1=Se a organização for convertida em privada, a contagem de favoritos do repositório será eliminada e não poderá ser restaurada. +settings.change_visibility_notices_2=Os não-membros irão perder acesso aos repositórios da organização se a visibilidade for mudada para privada. +settings.change_visibility_success=A visibilidade da organização %s foi mudada com sucesso. +settings.visibility_desc=Mudar quem pode ver a organização e os seus repositórios. settings.visibility.public=Público settings.visibility.limited=Limitada (visível apenas para utilizadores autenticados) settings.visibility.limited_shortname=Limitada @@ -3419,6 +3433,7 @@ config.picture_service=Serviço de imagem config.disable_gravatar=Desabilitar o Gravatar config.enable_federated_avatar=Habilitar avatares federados config.open_with_editor_app_help=Os editores de "Abrir com" do menu de clonagem. Se for deixado em branco, será usado o predefinido. Expanda para ver o predefinido. +config.git_guide_remote_name=Nome remoto do repositório para os comandos git no guia config.git_config=Configuração Git config.git_disable_diff_highlight=Desabilitar o realce de sintaxe no diff @@ -3714,7 +3729,6 @@ swift.install=Adicione o pacote no seu ficheiro Package.swift: swift.install2=e execute o seguinte comando: vagrant.install=Para adicionar uma máquina virtual Vagrant, execute o seguinte comando: 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 settings.link.button=Modificar vínculo ao repositório settings.link.success=A ligação ao repositório foi modificada com sucesso. diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index 30443e2a23..6da0eea91c 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -449,6 +449,7 @@ repo.transfer.to_you=вам repo.collaborator.added.subject=%s добавил(а) вас в %s repo.collaborator.added.text=Вы были добавлены в качестве соавтора репозитория: + team_invite.subject=%[1]s приглашает вас присоединиться к организации %[2]s team_invite.text_1=%[1]s приглашает вас присоединиться к команде %[2]s в организации %[3]s. team_invite.text_2=Перейдите по ссылке, чтобы присоединиться к команде: @@ -3082,7 +3083,6 @@ swift.install=Добавьте пакет в свой файл Package.swi swift.install2=и запустите следующую команду: vagrant.install=Чтобы добавить бокс Vagrant, выполните следующую команду: settings.link=Связать этот пакет с репозиторием -settings.link.description=Если связать пакет с репозиторием, он добавится в список пакетов репозитория. settings.link.select=Выберите репозиторий settings.link.button=Обновить ссылку на репозиторий settings.link.success=Связь с репозиторием успешно обновлена. diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini index 39c3835eb9..e065527bbe 100644 --- a/options/locale/locale_si-LK.ini +++ b/options/locale/locale_si-LK.ini @@ -355,6 +355,7 @@ repo.collaborator.added.subject=%s ඔබව %s ට එකතු කළා repo.collaborator.added.text=ඔබ ගබඩාවේ සහයෝගිතාකරුවෙකු ලෙස එකතු කර ඇත: + [modal] yes=ඔව් no=නැහැ diff --git a/options/locale/locale_sk-SK.ini b/options/locale/locale_sk-SK.ini index 1c6cc7a7ad..dc022da24b 100644 --- a/options/locale/locale_sk-SK.ini +++ b/options/locale/locale_sk-SK.ini @@ -436,6 +436,7 @@ repo.transfer.to_you=vy repo.collaborator.added.subject=%s vás pridal do %s repo.collaborator.added.text=Boli ste pridaný ako spolupracovník repozitára: + team_invite.subject=%[1]s vás pozval/a, aby ste sa pripojili k organizácii %[2]s team_invite.text_1=%[1]s vás pozval/a, aby ste sa pripojili k tímu %[2]s v organizácii %[3]s. team_invite.text_2=Ak sa chcete pripojiť k tímu, kliknite na nasledujúci odkaz: diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini index 7ec0090bcb..e8c13cae0d 100644 --- a/options/locale/locale_sv-SE.ini +++ b/options/locale/locale_sv-SE.ini @@ -303,6 +303,7 @@ register_success=Registreringen lyckades + [modal] yes=Ja no=Nej diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index ca7ae8a962..a3ae736f67 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -44,6 +44,7 @@ webauthn_use_twofa=Telefonunuzdan iki aşamalı doğrulama kodu kullanın webauthn_error=Güvenlik anahtarınız okunamıyor. webauthn_unsupported_browser=Tarayıcınız henüz WebAuthn desteklemiyor. webauthn_error_unknown=Bilinmeyen bir hata oluştu. Lütfen tekrar deneyin. +webauthn_error_insecure=WebAuthn sadece güvenli bağlantıyı destekler. HTTP üzerinden test etmek için "localhost" veya "127.0.0.1" adreslerini kullanabilirsiniz. webauthn_error_unable_to_process=Sunucu isteğinizi işleyemedi. webauthn_error_duplicated=Güvenlik anahtarının bu istek için izni yok. Anahtarın halihazırda kayıtlı olmadığından emin olun. webauthn_error_empty=Bu anahtar için bir isim belirlemelisiniz. @@ -116,8 +117,10 @@ files=Dosyalar error=Hata error404=Ulaşmaya çalıştığınız sayfa mevcut değil veya görüntüleme yetkiniz yok. +error503=Sunucu isteğinizi gerçekleştiremedi. Lütfen daha sonra tekrar deneyin. go_back=Geri Git invalid_data=Geçersiz veri: %v +nothing_has_been_changed=Hiçbir şey değişmedi. never=Asla unknown=Bilinmiyor @@ -129,6 +132,7 @@ unpin=Sabitlemeyi kaldır artifacts=Yapılar expired=Süresi doldu +confirm_delete_artifact=%s yapısını silmek istediğinizden emin misiniz? archived=Arşivlenmiş @@ -165,18 +169,33 @@ no_results_found=Sonuç bulunamadı. internal_error_skipped=Dahili bir hata oluştu ama atlandı: %s [search] +search=Ara... type_tooltip=Arama türü fuzzy=Bulanık +fuzzy_tooltip=Arama terimine benzeyen sonuçları da içer words=Kelimeler words_tooltip=Sadece arama terimi kelimeleriyle eşleşen sonuçları içer regexp=Regexp regexp_tooltip=Sadece regexp arama terimiyle tamamen eşleşen sonuçları içer exact=Tam exact_tooltip=Sadece arama terimiyle tamamen eşleşen sonuçları içer +repo_kind=Depoları ara... +user_kind=Kullanıcıları ara... +org_kind=Organizasyonları ara... +team_kind=Takımları ara... +code_kind=Kod ara... code_search_unavailable=Kod arama şu an mevcut değil. Lütfen site yöneticisiyle iletişime geçin. code_search_by_git_grep=Mevcut kod arama sonuçları "git grep" ile sağlanıyor. Eğer yönetici Depo Dizinleyici'yi etkinleştirirse daha iyi sonuçlar çıkabilir. +package_kind=Paketleri ara... +project_kind=Projeleri ara... +branch_kind=Dalları ara... +tag_kind=Etiketleri ara... tag_tooltip=Eşleşen etiketler için arama. Herhangi bir numara serisi bulmak için '%' kullanın. +commit_kind=İşlemeleri ara... +runner_kind=Çalıştırıcıları ara... no_results=Eşleşen sonuç bulunamadı. +issue_kind=Konuları ara... +pull_kind=Değişiklikleri ara... keyword_search_unavailable=Anahtar kelime ile arama şu an mevcut değil. Lütfen site yöneticinizle iletişime geçin. [aria] @@ -212,6 +231,8 @@ buttons.enable_monospace_font=Eşaralıklı yazıtipini etkinleştir buttons.disable_monospace_font=Eşaralıklı yazıtipini devre dışı bırak [filter] +string.asc=A - Z +string.desc=Z - A [error] occurred=Bir hata oluştu @@ -232,6 +253,7 @@ license_desc=Gidin ve belgeleri okuyun. require_db_desc=Gitea MySQL, PostgreSQL, MSSQL, SQLite3 veya TiDB (MySQL protokolü) gerektirir. @@ -252,6 +274,7 @@ reinstall_confirm_check_3=Bu Gitea'nın doğru app.ini konumuyla çalıştığı err_empty_db_path=SQLite3 veritabanı dosya yolu boş olamaz. no_admin_and_disable_registration=Bir yönetici hesabı oluşturmadan kullanıcı kaydını kapatamazsınız. err_empty_admin_password=Yönetici parolası boş olamaz. +err_empty_admin_email=Yönetici e-postası boş olamaz. general_title=Genel Ayarlar app_name=Site Başlığı @@ -510,6 +533,7 @@ repo.transfer.to_you=siz repo.collaborator.added.subject=%s sizi %s ekledi repo.collaborator.added.text=Bu depo için katkıcı olarak eklendiniz: + team_invite.subject=%[1]s sizi %[2]s organizasyonuna katılmaya davet etti team_invite.text_1=%[1]s sizi %[3]s organizasyonundaki %[2]s takımına katılmaya davet etti. team_invite.text_2=Takıma katılmak lütfen aşağıdaki bağlantıya tıklayın: @@ -3394,7 +3418,6 @@ swift.install=Paketi Package.swift dosyanıza ekleyin: swift.install2=ve şu komutu çalıştırın: vagrant.install=Vagrant paketi eklemek için aşağıdaki komutu çalıştırın: 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ç settings.link.button=Depo Bağlantısını Güncelle settings.link.success=Depo bağlantısı başarıyla güncellendi. diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index c0de41a8c3..1849d5d378 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -503,6 +503,7 @@ repo.transfer.to_you=вам repo.collaborator.added.subject=%s додав вас до %s repo.collaborator.added.text=Вас додали як співавтора до сховища: + team_invite.subject=%[1]s запрошує вас приєднатися до організації %[2]s team_invite.text_1=%[1]s запрошує вас до команди %[2]s в організації %[3]s. team_invite.text_2=Перейдіть за посиланням, щоб приєднатися до команди: @@ -3289,7 +3290,6 @@ swift.install=Додайте пакет у ваш файл Package.swift不存在您尚未被授权 查看该页面。 +error503=服务器无法完成您的请求,请稍后重试。 go_back=返回 invalid_data=无效数据: %v +nothing_has_been_changed=没有任何更改。 never=从不 unknown=未知 rss_feed=RSS 订阅源 -pin=固定 +pin=置顶 unpin=取消置顶 artifacts=产物 @@ -166,18 +169,33 @@ no_results_found=未找到结果 internal_error_skipped=发生内部错误,但已跳过: %s [search] +search=搜索… type_tooltip=搜索类型 fuzzy=模糊 +fuzzy_tooltip=包含近似匹配搜索词的结果 words=词 words_tooltip=仅包含匹配搜索词的结果 regexp=正则表达式 regexp_tooltip=仅包含匹配正则表达式搜索词的结果 exact=精确 exact_tooltip=仅包含精确匹配搜索词的结果 +repo_kind=搜索仓库… +user_kind=搜索用户… +org_kind=搜索组织… +team_kind=搜索团队… +code_kind=搜索代码… code_search_unavailable=代码搜索当前不可用。请与网站管理员联系。 code_search_by_git_grep=当前代码搜索结果由「git grep」提供。如果站点管理员启用仓库索引器,可能会有更好的结果。 -tag_tooltip=搜索匹配的标签。使用「%」来匹配任何序列的数字。 +package_kind=搜索软件包… +project_kind=搜索项目… +branch_kind=搜索分支… +tag_kind=搜索 Git 标签… +tag_tooltip=搜索匹配的 Git 标签。使用「%」来匹配任何序列的数字。 +commit_kind=搜索提交记录… +runner_kind=搜索运行器… no_results=未找到匹配结果 +issue_kind=搜索工单… +pull_kind=搜索合并请求… keyword_search_unavailable=按关键字搜索当前不可用。请联系站点管理员。 [aria] @@ -213,6 +231,8 @@ buttons.enable_monospace_font=启用等宽字体 buttons.disable_monospace_font=禁用等宽字体 [filter] +string.asc=A - Z +string.desc=Z - A [error] occurred=发生了一个错误 @@ -233,6 +253,7 @@ license_desc=所有的代码都开源在 官方文档 后再对本页面进行填写。 require_db_desc=Gitea 需要使用 MySQL、PostgreSQL、MSSQL、SQLite3 或 TiDB (MySQL协议) 等数据库 @@ -249,10 +270,16 @@ path=数据库文件路径 sqlite_helper=SQLite3 数据库的文件路径。
如果以服务的方式运行 Gitea,请输入绝对路径。 reinstall_error=您正在尝试安装到一个已经有 Gitea 数据的数据库中 reinstall_confirm_message=使用现有的 Gitea 数据库重新安装可能会导致多个问题。在大多数情况下,您应该使用您现有的「app.ini」来运行 Gitea。如果您知道自己在做什么,请确认以下内容: +reinstall_confirm_check_1=使用 app.ini 中 SECRET KEY 加密的数据可能会丢失:用户可能无法使用 2FA/OTP 登录,仓库镜像可能无法正常工作。勾选此框,表示您确认当前 app.ini 文件包含正确的 SECRET KEY。 +reinstall_confirm_check_2=代码仓库和设置可能需要重新同步。勾选此框,表示您确认将手动重新同步仓库和 SSH authorized_keys 的钩子。您确认您将确保代码仓库和镜像设置是正确的。 reinstall_confirm_check_3=您确认您绝对肯定这个 Gitea 在正确的 app.ini 位置上运行,而且您确定您必须重新安装。您确认您知晓上述风险。 err_empty_db_path=SQLite 数据库文件路径不能为空。 no_admin_and_disable_registration=您不能够在未创建管理员用户的情况下禁止注册。 err_empty_admin_password=管理员密码不能为空。 +err_empty_admin_email=管理员邮箱不能为空。 +err_admin_name_is_reserved=管理员用户名无效,用户名是保留的 +err_admin_name_pattern_not_allowed=管理员用户名无效,用户名是保留字 +err_admin_name_is_invalid=管理员用户名无效 general_title=一般设置 app_name=站点名称 @@ -268,6 +295,7 @@ domain_helper=服务器的域名或主机地址。 ssh_port=SSH 服务端口 ssh_port_helper=SSH 服务器的端口号,为空则禁用它。 http_port=HTTP 服务端口 +http_port_helper=Gitea Web 服务器将侦听的端口号。 app_url=基础URL app_url_helper=用于 HTTP (S) 克隆和邮件通知的基本地址。 log_root_path=日志路径 @@ -288,9 +316,9 @@ server_service_title=服务器和第三方服务设置 offline_mode=启用本地模式 offline_mode_popup=禁用第三方 CDN 并在本地服务所有资源。 disable_gravatar=禁用 Gravatar 头像 -disable_gravatar_popup=禁用 Gravatar 和第三方头像源。除非用户在本地上传头像, 否则将使用默认的头像。 +disable_gravatar_popup=禁用 Gravatar 和第三方头像源。除非用户在本地上传头像,否则将使用默认头像。 federated_avatar_lookup=启用 Federated 头像 -federated_avatar_lookup_popup=启用 Federated Avatars 查找以使用开源的 Libravatar 服务。 +federated_avatar_lookup_popup=启用 Federated 头像查找以使用开源的 Libravatar 服务。 disable_registration=禁止用户自助注册 disable_registration_popup=禁用用户自助注册。只有管理员才能创建新的用户帐户。 allow_only_external_registration_popup=仅允许通过外部服务注册 @@ -316,21 +344,22 @@ invalid_db_table=数据库表「%s」无效:%v invalid_repo_path=仓库根目录设置无效:%v invalid_app_data_path=应用数据路径无效: %v run_user_not_match=运行用户名不是当前的用户名:%s -> %s -internal_token_failed=生成内部令牌失败: %v -secret_key_failed=生成密钥失败: %v +internal_token_failed=生成内部令牌失败:%v +secret_key_failed=生成密钥失败:%v save_config_failed=应用配置保存失败:%v invalid_admin_setting=管理员帐户设置无效: %v invalid_log_root_path=日志路径无效: %v default_keep_email_private=默认情况下隐藏邮箱地址 default_keep_email_private_popup=默认情况下,隐藏新用户帐户的邮箱地址。 default_allow_create_organization=默认情况下允许创建组织 -default_allow_create_organization_popup=默认情况下, 允许新用户帐户创建组织。 +default_allow_create_organization_popup=默认情况下,允许新用户帐户创建组织。 default_enable_timetracking=默认情况下启用时间跟踪 default_enable_timetracking_popup=默认情况下启用新仓库的时间跟踪。 no_reply_address=隐藏邮件域 no_reply_address_helper=具有隐藏邮箱地址的用户的域名。例如,如果隐藏邮箱域名设置为「noreply.example.org」,那么用户名「joe」在 Git 中将显示为「joe@noreply.example.org」。 password_algorithm=密码哈希算法 invalid_password_algorithm=无效的密码哈希算法 +password_algorithm_helper=设置密码散列算法。算法有不同的要求和强度。 argon2 算法相当安全,但使用大量内存,因此可能不适合小型系统。 enable_update_checker=启用更新检查 enable_update_checker_helper=通过连接到 gitea.io 定期检查新版本发布。 env_config_keys=环境配置 @@ -402,6 +431,8 @@ allow_password_change=要求用户更改密码(推荐) reset_password_mail_sent_prompt=确认邮件已被发送到 %s。请您在 %s 内检查您的收件箱 ,完成密码重置流程。 active_your_account=激活您的帐户 account_activated=帐户已激活 +prohibit_login=禁止登录 +prohibit_login_desc=您的帐户被禁止登录,请与网站管理员联系。 resent_limit_prompt=您请求发送激活邮件过于频繁,请等待 3 分钟后再试! has_unconfirmed_mail=%s 您好,系统检测到您有一封发送至 %s 但未被确认的邮件。如果您未收到激活邮件,或需要重新发送,请单击下方的按钮。 change_unconfirmed_mail_address=如果您的注册邮箱地址不正确,您可以在此更改并重新发送新的确认邮件。 @@ -422,6 +453,7 @@ use_scratch_code=使用验证口令 twofa_scratch_used=您已经使用了您的验证口令。您将会转到两步验证设置页面以便移除您的注册设备或者重新生成新的验证口令。 twofa_passcode_incorrect=您的验证码不正确。如果您丢失了您的设备,请使用您的验证口令。 twofa_scratch_token_incorrect=您的验证口令不正确。 +twofa_required=您必须设置两步验证来访问仓库,或者尝试重新登录。 login_userpass=登录 login_openid=OpenID oauth_signup_tab=注册帐号 @@ -440,13 +472,17 @@ openid_connect_desc=所选的 OpenID URI 未知。在这里关联一个新帐户 openid_register_title=创建新帐户 openid_register_desc=所选的 OpenID URI 未知。在这里关联一个新帐户。 openid_signin_desc=输入您的OpenID地址。例如:alice.openid.example.org 或 https://openid.example.org/alice. +disable_forgot_password_mail=由于未设置邮箱,帐户恢复被禁用。 请联系您的站点管理员。 +disable_forgot_password_mail_admin=帐户恢复仅在设置邮箱后可用。 请设置邮箱以启用帐户恢复。 email_domain_blacklisted=您不能使用您的邮箱地址注册。 authorize_application=应用授权 authorize_redirect_notice=如果您授权此应用,您将会被重定向到 %s。 authorize_application_created_by=此应用由 %s 创建。 +authorize_application_description=如果您允许,它将能够读取和修改您的所有帐户信息,包括私人仓库和组织。 authorize_application_with_scopes=范围:%s authorize_title=授权 %s 访问您的帐户? authorization_failed=授权失败 +authorization_failed_desc=因为检测到无效请求,授权失败。请尝试联系您授权应用的管理员。 sspi_auth_failed=SSPI 认证失败 password_pwned=此密码出现在 被盗密码 列表上并且曾经被公开。 请使用另一个密码再试一次。 password_pwned_err=无法完成对 HaveIBeenPwned 的请求 @@ -472,6 +508,7 @@ activate_email.text=请在 %s 时间内,点击以下链接,以验证 register_notify=欢迎来到 %s register_notify.title=%[1]s,欢迎来到 %[2]s register_notify.text_1=这是您的 %s 注册确认邮件 ! +register_notify.text_2=您现在可以以用户名 %s 登录。 register_notify.text_3=如果此账户已为您创建,请先 设置您的密码。 reset_password=恢复您的账户 @@ -509,10 +546,12 @@ release.download.targz=源代码(TAR.GZ) repo.transfer.subject_to=%s 想要将「%s」转移给 %s repo.transfer.subject_to_you=%s 想要将「%s」转移给您 repo.transfer.to_you=您 +repo.transfer.body=访问 %s 以接受或拒绝转移,亦可忽略此邮件。 -repo.collaborator.added.subject=%s 把您添加到了 %s +repo.collaborator.added.subject=%s 把您添加到 %s repo.collaborator.added.text=您已被添加为仓库的协作者: + team_invite.subject=%[1]s 邀请您加入组织 %[2]s team_invite.text_1=%[1]s 邀请您加入组织 %[3]s 中的团队 %[2]s。 team_invite.text_2=请点击下面的链接加入团队: @@ -549,8 +588,8 @@ SSPISeparatorReplacement=分隔符 SSPIDefaultLanguage=默认语言 require_error=不能为空。 -alpha_dash_error=应该只包含字母数字、破折号 ('-') 和下划线 ('_') 字符。 -alpha_dash_dot_error=` 应该只包含字母数字, 破折号 ('-'), 下划线 ('_') 和点 ('. ') 。` +alpha_dash_error=`应该只包含字母数字、破折号('-')和下划线('_')。` +alpha_dash_dot_error=`应该只包含字母数字、破折号('-')、下划线('_')和点('.')。` git_ref_name_error=` 必须是格式良好的 git 引用名称。` size_error=长度必须为 %s。 min_size_error=长度最小为 %s 个字符。 @@ -560,6 +599,7 @@ url_error=`「%s」不是一个有效的 URL。` include_error=`必须包含子字符串「%s」。` glob_pattern_error=`匹配表达式无效:%s.` regex_pattern_error=`正则表达式无效:%s.` +username_error=`只能包含字母数字('0-9'、'a-z'、'A-Z')破折号('-')下划线('_')和点('.')。不能以非字母数字字符开头和结尾且不允许连续的非字母数字字符。` invalid_group_team_map_error=`映射无效: %s` unknown_error=未知错误: captcha_incorrect=验证码不正确。 @@ -574,14 +614,17 @@ username_has_not_been_changed=用户名未更改 repo_name_been_taken=仓库名称已使用。 repository_force_private=「强制私有」已启用:私有仓库不能被公开。 repository_files_already_exist=此仓库已存在文件。请联系系统管理员。 +repository_files_already_exist.adopt=此仓库已存在文件,只能被收录。 repository_files_already_exist.delete=此仓库已存在文件,必须先删除他们。 repository_files_already_exist.adopt_or_delete=此仓库已存在文件,要么删除他们,要么收录他们。 visit_rate_limit=远程访问达到速度限制。 +2fa_auth_required=远程访问需要两步验证。 org_name_been_taken=组织名称已使用。 team_name_been_taken=团队名称已使用。 team_no_units_error=至少选择一项仓库单元。 email_been_used=该邮箱地址已在使用中。 email_invalid=此邮箱地址无效。 +email_domain_is_not_allowed=用户 %s 与EMAIL_DOMAIN_ALLOWLIT 或 EMAIL_DOMAIN_BLOCKLIT 冲突。请确保您的操作是预期的。 openid_been_used=OpenID 地址「%s」已被使用。 username_password_incorrect=用户名或密码不正确。 password_complexity=密码未达到复杂程度要求: @@ -606,8 +649,14 @@ invalid_ssh_key=无法验证您的 SSH 密钥:%s invalid_gpg_key=无法验证您的 GPG 密钥:%s invalid_ssh_principal=无效的规则:%s must_use_public_key=您提供的密钥是私钥。不要在任何地方上传您的私钥,请改用您的公钥。 +unable_verify_ssh_key=无法验证 SSH 密钥,请仔细检查是否有错误。 auth_failed=授权验证失败:%v +still_own_repo=此帐户仍拥有至少一个仓库,您需要先删除或转移它们。 +still_has_org=此帐户隶属于一个或多个组织,请先退出这些组织。 +still_own_packages=您的账户拥有一个或多个软件包,请先删除它们。 +org_still_own_repo=该组织仍然是某些仓库的拥有者,请先删除或转移它们! +org_still_own_packages=该组织仍然是一个或多个软件包的拥有者,请先删除它们。 target_branch_not_exist=目标分支不存在。 target_ref_not_exist=目标引用 %s 不存在 @@ -638,9 +687,11 @@ settings=用户设置 form.name_reserved=用户名「%s」被保留。 form.name_pattern_not_allowed=用户名中不允许使用「%s」格式。 +form.name_chars_not_allowed=用户名「%s」包含无效字符。 block.block=屏蔽 block.block.user=屏蔽用户 +block.block.org=屏蔽用户访问组织 block.block.failure=屏蔽用户失败:%s block.unblock=取消屏蔽 block.unblock.failure=取消屏蔽用户失败:%s @@ -653,6 +704,7 @@ block.info_3=通过 @ 提及您的用户名向您发送通知 block.info_4=邀请您作为协作者到他们的仓库中 block.info_5=在仓库中点赞、派生或关注 block.info_6=打开和评论工单或合并请求 +block.info_7=在问题或合并请求中对您的评论做出反应 block.user_to_block=要屏蔽的用户 block.note=备注 block.note.title=可选备注: @@ -703,8 +755,9 @@ cancel=取消操作 language=界面语言 ui=主题 hidden_comment_types=隐藏的评论类型 -hidden_comment_types.ref_tooltip=注释此问题在何处被提及过,如另一个问题、代码提交等 -hidden_comment_types.issue_ref_tooltip=注释用户在何处更改了与此问题相关联的分支/标签 +hidden_comment_types_description=此处选中的注释类型不会显示在工单页面上。比如,勾选「标签」删除所有「{user} 添加/删除的 {label}」注释。 +hidden_comment_types.ref_tooltip=注释此工单在何处被提及过,如另一个工单、提交… +hidden_comment_types.issue_ref_tooltip=注释用户在何处更改了与此工单相关联的分支 / Git 标签 comment_type_group_reference=引用 comment_type_group_label=标签 comment_type_group_milestone=里程碑 @@ -725,13 +778,13 @@ keep_activity_private=隐藏个人资料页面中的活动 keep_activity_private_popup=使活动仅对您和管理员可见 lookup_avatar_by_mail=从邮箱地址查找头像 -federated_avatar_lookup=Federated Avatar 查找 -enable_custom_avatar=启动自定义头像 +federated_avatar_lookup=查找 Federated 头像 +enable_custom_avatar=使用自定义头像 choose_new_avatar=选择新的头像 update_avatar=更新头像 delete_current_avatar=删除当前头像 uploaded_avatar_not_a_image=上传的文件不是一张图片。 -uploaded_avatar_is_too_big=上传的文件大小(%d KiB) 超过最大限制(%d KiB)。 +uploaded_avatar_is_too_big=上传的文件大小(%d KiB)超过最大限制(%d KiB)。 update_avatar_success=您的头像已更新。 update_user_avatar_success=用户头像已更新。 cropper_prompt=您可以在保存前编辑图像。编辑的图像将被保存为 PNG 格式。 @@ -750,15 +803,18 @@ manage_themes=选择默认主题 manage_openid=管理 OpenID 地址 email_desc=您的主邮箱地址将用于通知、密码恢复以及基于网页的 Git 操作(如果它未设为隐藏)。 theme_desc=这将是您在整个网站上的默认主题。 -primary=主要 +theme_colorblindness_help=颜色障碍主题支持 +theme_colorblindness_prompt=Gitea 仅有少数主题存在基本的颜色障碍支持,这些主题只定义了少数颜色。这项工作仍在进行中,可以通过在主题的 CSS 文件中定义更多颜色来实现更多改进。 +primary=主 activated=已激活 requires_activation=需要激活 primary_email=设为主邮箱 activate_email=发送激活邮件 activations_pending=等待激活 +can_not_add_email_activations_pending=有一个待处理的激活请求,请稍等几分钟后再尝试添加新的邮箱地址。 delete_email=移除 email_deletion=移除邮箱地址 -email_deletion_desc=邮箱地址和相关信息将会被删除。使用此邮箱地址发送的Git提交将会保留,继续? +email_deletion_desc=邮箱地址和相关信息将会被删除。使用此邮箱地址发送的 Git 提交将会保留,继续? email_deletion_success=您的邮箱地址已移除。 theme_update_success=您的主题已更新。 theme_update_error=所选主题不存在。 @@ -793,7 +849,7 @@ key_content_gpg_placeholder=以 '-----BEGIN PGP PUBLIC KEY BLOCK-----' 开头 add_new_principal=添加规则 ssh_key_been_used=此 SSH 密钥已添加到服务器。 ssh_key_name_used=使用相同名称的 SSH 公钥已经存在。 -ssh_principal_been_used=此规则已经加入到了服务器。 +ssh_principal_been_used=此规则已经加入到服务器。 gpg_key_id_used=使用相同名称的 GPG 公钥已经存在。 gpg_no_key_email_found=此 GPG 密钥与您帐户关联的任何已激活邮箱地址均不匹配。如果您已对提供的令牌进行签名,仍可添加该密钥。 gpg_key_matched_identities=匹配的身份: @@ -801,6 +857,7 @@ gpg_key_matched_identities_long=此密钥中包含的身份信息与以下此用 gpg_key_verified=已验证的密钥 gpg_key_verified_long=密钥已通过令牌验证,除与此密钥匹配的任何身份外,还可用于验证与该用户任何已激活邮箱地址匹配的提交。 gpg_key_verify=验证 +gpg_invalid_token_signature=提供的 GPG 密钥、签名和令牌不匹配或过期。 gpg_token_required=您必须为下面的令牌提供签名 gpg_token=令牌 gpg_token_help=您可以使用以下方式生成签名: @@ -810,6 +867,7 @@ verify_gpg_key_success=GPG 密钥「%s」已验证。 ssh_key_verified=已验证的密钥 ssh_key_verified_long=密钥已通过令牌验证,可用于验证与该用户任何已激活邮箱地址匹配的提交。 ssh_key_verify=验证 +ssh_invalid_token_signature=提供的 SSH 密钥、签名或令牌不匹配或令牌已过期。 ssh_token_required=您必须为下面的令牌提供签名 ssh_token=令牌 ssh_token_help=您可以使用以下方式生成签名: @@ -830,6 +888,7 @@ gpg_key_deletion=删除 GPG 密钥 ssh_principal_deletion=删除 SSH 证书规则 ssh_key_deletion_desc=删除 SSH 公钥将取消对应的私钥对您的 Gitea 帐户的访问权限。继续? gpg_key_deletion_desc=删除 GPG 公钥将无法认证对应私钥签名的提交,继续? +ssh_principal_deletion_desc=删除此 SSH 证书规则将取消它对您的账户的访问权限。继续? ssh_key_deletion_success=SSH 密钥已删除。 gpg_key_deletion_success=GPG 密钥已删除。 ssh_principal_deletion_success=此规则删除成功。 @@ -888,9 +947,10 @@ remove_oauth2_application_desc=删除 OAuth2 应用将撤销所有签名的访 remove_oauth2_application_success=该应用已删除。 create_oauth2_application=创建新的 OAuth2 应用程序 create_oauth2_application_button=创建应用 -create_oauth2_application_success=您已成功创建了一个新的 OAuth2 应用。 -update_oauth2_application_success=您已成功更新了此 OAuth2 应用。 +create_oauth2_application_success=您已成功创建一个新的 OAuth2 应用。 +update_oauth2_application_success=您已成功更新此 OAuth2 应用。 oauth2_application_name=应用名称 +oauth2_confidential_client=机密客户端。对于需要保密的应用(例如 Web 应用),请选择此选项。对于包括桌面和移动应用在内的本机应用,请勿选择此选项。 oauth2_skip_secondary_authorization=首次授权后允许公共客户端跳过授权步骤。 可能会带来安全风险。 oauth2_redirect_uris=重定向 URI。每行一个 URI。 save_application=保存 @@ -905,9 +965,11 @@ oauth2_application_remove_description=移除一个OAuth2应用将会阻止它访 oauth2_application_locked=如果配置启用,Gitea 将在启动时预注册一些 OAuth2 应用程序。 为了防止意外的行为, 这些应用既不能编辑也不能删除。请参阅 OAuth2 文档以获取更多信息。 authorized_oauth2_applications=已授权的 OAuth2 应用 +authorized_oauth2_applications_description=您已授予这些第三方应用程序访问您的个人 Gitea 账户的权限。请撤销那些您不再需要的应用程序的访问权限。 revoke_key=撤销 revoke_oauth2_grant=撤回权限 -revoke_oauth2_grant_success=成功撤销了访问权限。 +revoke_oauth2_grant_description=确定撤销此三方应用程序的授权,并阻止此应用程序访问您的数据? +revoke_oauth2_grant_success=成功撤销访问权限。 twofa_desc=为保护您的账号密码安全,您可以使用智能手机或其它设备来接收时间强相关的一次性密码(TOTP)。 twofa_recovery_tip=如果您丢失了您的设备,您将能够使用一次性恢复密钥来重新获得对您账户的访问。 @@ -916,21 +978,23 @@ twofa_not_enrolled=您的账号未开启两步验证。 twofa_disable=禁用两步认证 twofa_scratch_token_regenerate=重新生成初始令牌 twofa_scratch_token_regenerated=您的初始令牌现在是 %s。将其存放在安全的地方,它将不会再次显示。 -twofa_disable_note=如果需要, 可以禁用双因素身份验证。 +twofa_enroll=启用两步验证 +twofa_disable_note=如果需要,您可以禁用两步验证。 twofa_disable_desc=关掉两步验证会使得您的账号不安全,继续执行? -regenerate_scratch_token_desc=如果您丢失了您的恢复密钥或已经使用它登录, 您可以在这里重置它。 +regenerate_scratch_token_desc=如果您丢失了您的恢复密钥或已经使用它登录,您可以在这里重置它。 twofa_disabled=两步验证已禁用。 scan_this_image=使用您的授权应用扫描这张图片: or_enter_secret=或者输入密钥:%s then_enter_passcode=并输入应用程序中显示的密码: passcode_invalid=密码不正确。再试一次。 -twofa_enrolled=您的账号已经启用了两步验证。请保存初始令牌(%s)到一个安全的地方,此令牌仅显示一次。 +twofa_enrolled=您的账号已经启用两步验证。请保存初始令牌(%s)到一个安全的地方,此令牌仅显示一次。 twofa_failed_get_secret=获取 secret 失败。 webauthn_desc=安全密钥是包含加密密钥的硬件设备。它们可以用于双因素身份验证。安全密钥必须支持 WebAuthn 身份验证器 标准。 webauthn_register_key=添加安全密钥 webauthn_nickname=昵称 webauthn_delete_key=移除安全密钥 +webauthn_delete_key_desc=如果删除了安全密钥,则不能再使用它登录。继续? webauthn_key_loss_warning=如果您丢失了您的安全密钥,您将无法访问您的帐户。 webauthn_alternative_tip=您可能想要配置额外的身份验证方法。 @@ -949,7 +1013,7 @@ repos_none=您并不拥有任何仓库。 delete_account=删除当前帐户 delete_prompt=此操作将永久删除您的用户帐户。它 无法 被撤消。 -delete_with_all_comments=您的帐户年龄小于 %s。为了避免幽灵评论,所有工单/合并请求的评论都将与它一起被删除。 +delete_with_all_comments=您的帐户年龄小于 %s。为了避免幽灵评论,所有工单 / 合并请求的评论都将与它一起被删除。 confirm_delete_account=确认删除帐户 delete_account_title=删除当前帐户 delete_account_desc=确实要永久删除此用户帐户吗? @@ -959,7 +1023,7 @@ email_notifications.onmention=仅被提及时通知 email_notifications.disable=停用邮件通知 email_notifications.submit=设置邮件通知 email_notifications.andyourown=仅与您相关的通知 -email_notifications.actions.desc=设置了 Gitea 工作流 的仓库中工作流运行的通知。 +email_notifications.actions.desc=已设置 Gitea 工作流 的仓库中工作流运行的通知。 email_notifications.actions.failure_only=仅在工作流运行失败时通知 visibility=用户可见性 @@ -997,7 +1061,8 @@ fork_visibility_helper=无法更改派生仓库的可见性。 fork_branch=要克隆为派生的分支 all_branches=所有分支 view_all_branches=查看所有分支 -view_all_tags=查看所有标签 +view_all_tags=查看所有 Git 标签 +fork_no_valid_owners=这个代码仓库无法被派生,因为没有有效的所有者。 fork.blocked_user=无法克隆仓库,因为您被仓库所有者屏蔽。 use_template=使用此模板 open_with_editor=用 %s 打开 @@ -1036,16 +1101,18 @@ default_branch_label=默认 default_branch_helper=默认分支是用于合并请求和代码提交的基础分支。 mirror_prune=修剪 mirror_prune_desc=删除过时的远程跟踪引用 -mirror_interval=镜像间隔 (有效的时间单位是 'h', 'm', 's')。0 禁用自动定期同步 (最短间隔: %s) +mirror_interval=镜像间隔(有效的时间单位是 'h'、'm'、's')。0 禁用自动定期同步(最短间隔: %s) mirror_interval_invalid=镜像间隔无效。 mirror_sync=已同步 mirror_sync_on_commit=推送提交时同步 mirror_address=从 URL 克隆 mirror_address_desc=在授权框中输入必要的凭据。 +mirror_address_url_invalid=提供的 URL 无效。请确保 URL 的所有组成部分均已正确转义。 mirror_address_protocol_invalid=提供的URL无效。只能使用http(s)://或git://地址进行镜像操作。 mirror_lfs=大文件存储 (LFS) mirror_lfs_desc=镜像 LFS 数据。 mirror_lfs_endpoint=LFS 网址 +mirror_lfs_endpoint_desc=同步将尝试使用克隆 URL 来 确定 LFS 服务器。如果仓库 LFS 数据存储在其他位置,您还可以指定自定义网址。 mirror_last_synced=上次同步 mirror_password_placeholder=(未更改) mirror_password_blank_placeholder=(未设置) @@ -1058,6 +1125,7 @@ stars=点赞数 reactions_more=再加载 %d unit_disabled=站点管理员已禁用此仓库单元。 language_other=其它 +adopt_search=输入用户名以搜索未被收录的仓库…(留空以查找全部) adopt_preexisting_label=收录仓库 adopt_preexisting=收录已存在的仓库 adopt_preexisting_content=从 %s 创建仓库 @@ -1099,6 +1167,8 @@ template.issue_labels=工单标签 template.one_item=必须至少选择一个模板项 template.invalid=必须选择一个模板仓库 +archive.title=该仓库已被归档。您可以查看文件和克隆它,但不能创建工单、合并请求或推送提交。 +archive.title_date=该仓库已于 %s 归档。您可以查看文件和克隆它,但不能创建工单、合并请求或推送提交。 archive.issue.nocomment=此仓库已存档,您不能在此工单添加评论。 archive.pull.nocomment=此仓库已存档,您不能在此合并请求添加评论。 @@ -1115,6 +1185,7 @@ migrate_options_lfs=迁移 LFS 文件 migrate_options_lfs_endpoint.label=LFS 网址 migrate_options_lfs_endpoint.description=迁移将尝试使用您的 Git remote 来 确定 LFS 服务器。如果仓库 LFS 数据存储在其他位置,您还可以指定自定义网址。 migrate_options_lfs_endpoint.description.local=支持本地服务器路径。 +migrate_options_lfs_endpoint.placeholder=如果留空,网址将从克隆 URL 中得到 migrate_items=迁移项目 migrate_items_wiki=百科 migrate_items_milestones=里程碑 @@ -1126,8 +1197,10 @@ migrate_items_releases=发布 migrate_repo=迁移仓库 migrate.clone_address=从 URL 迁移/克隆 migrate.clone_address_desc=现有仓库的 HTTP(s) 或 Git "clone" URL +migrate.github_token_desc=您可以在此处输入一个或多个令牌(以逗号分隔),以绕过 GitHub API 速率限制来加快迁移速度。警告:滥用此功能可能会违反服务提供商的政策并导致帐户被封禁。 migrate.clone_local_path=或服务器本地路径 migrate.permission_denied=您没有获得导入本地仓库的权限。 +migrate.permission_denied_blocked=您不能从不允许的主机导入,请询问管理员以检查 ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS 设置。 migrate.invalid_local_path=本地路径无效。它不存在或不是一个目录。 migrate.invalid_lfs_endpoint=LFS 网址无效。 migrate.failed=迁移失败:%v @@ -1135,6 +1208,7 @@ migrate.migrate_items_options=需要访问令牌来迁移额外的内容 migrated_from=从 %[2]s 迁移 migrated_from_fake=从 %[1]s 迁移成功 migrate.migrate=从 %s 迁移 +migrate.migrating=正在从 %s 迁移… migrate.migrating_failed=从 %s 迁移失败。 migrate.migrating_failed.error=迁移失败:%s migrate.migrating_failed_no_addr=迁移失败。 @@ -1183,23 +1257,26 @@ clone_this_repo=克隆当前仓库 cite_this_repo=引用此仓库 create_new_repo_command=从命令行创建一个新的仓库 push_exist_repo=从命令行推送已经创建的仓库 +empty_message=这个家伙很懒,什么都没有推送。 broken_message=无法读取此仓库下的 Git 数据。 联系此实例的管理员或删除此仓库。 +no_branch=该仓库没有任何分支。 code=代码 code.desc=查看源码、文件、提交和分支。 branch=分支 tree=目录树 clear_ref=`清除当前引用` -filter_branch_and_tag=过滤分支或标签 -find_tag=查找标签 +filter_branch_and_tag=过滤分支或 Git 标签 +find_tag=查找 Git 标签 branches=分支列表 -tags=标签列表 +tags=Git 标签列表 issues=工单 pulls=合并请求 projects=项目 packages=软件包 actions=工作流 labels=标签 +org_labels_desc=组织级别的标签,可以被本组织下的 所有仓库 使用 org_labels_desc_manage=管理 milestone=里程碑 @@ -1208,8 +1285,8 @@ commits=提交 commit=提交 release=发布 releases=发布 -tag=标签 -released_this=发布 +tag=Git 标签 +released_this=发布于 tagged_this=已标记 file.title=%s 位于 %s file_raw=原始文件 @@ -1247,7 +1324,8 @@ commit_graph.monochrome=黑白 commit_graph.color=彩色 commit.contained_in=这个提交包含在: commit.contained_in_default_branch=此提交是默认分支的一部分 -commit.load_referencing_branches_and_tags=加载引用该提交的分支和标签 +commit.load_referencing_branches_and_tags=加载引用该提交的分支和 Git 标签 +commit.merged_in_pr=此提交已合并在合并请求 %s 中。 blame=Blame download_file=下载文件 normal_view=普通视图 @@ -1271,7 +1349,7 @@ editor.fork_before_edit=您必须派生这个仓库才能对此文件进行修 editor.delete_this_file=删除文件 editor.must_have_write_access=您必须具有写权限才能对此文件进行修改操作。 editor.file_delete_success=文件「%s」已删除。 -editor.name_your_file=命名文件... +editor.name_your_file=命名文件… editor.filename_help=通过键入名称后跟斜线 ("/") 来添加目录。通过在输入框的开头键入「退格」来删除目录。 editor.or=或 editor.cancel_lower=取消 @@ -1285,24 +1363,28 @@ editor.patch=应用补丁 editor.patching=打补丁: editor.fail_to_apply_patch=无法应用补丁 editor.new_patch=新补丁 -editor.commit_message_desc=添加一个可选的扩展描述... +editor.commit_message_desc=添加一个可选的扩展描述… editor.signoff_desc=在提交日志消息末尾添加签署人信息。 editor.commit_directly_to_this_branch=直接提交至 %s 分支。 editor.create_new_branch=为此提交创建一个 新的分支 并发起合并请求。 editor.create_new_branch_np=为此提交创建 新分支。 editor.propose_file_change=建议文件更改 editor.new_branch_name=为这次提交的新分支命名 -editor.new_branch_name_desc=新的分支名称... +editor.new_branch_name_desc=新的分支名称… editor.cancel=取消 editor.filename_cannot_be_empty=文件名不能为空。 editor.filename_is_invalid=文件名无效:「%s」。 +editor.commit_email=提交邮箱地址 +editor.invalid_commit_email=提交的邮箱地址无效。 editor.branch_does_not_exist=此仓库中不存在名为「%s」的分支。 editor.branch_already_exists=此仓库已存在名为「%s」的分支。 editor.directory_is_a_file=目录名「%s」已作为文件名在此仓库中存在。 +editor.file_is_a_symlink=`「%s」是一个符号链接,无法在 Web 编辑器中编辑` editor.filename_is_a_directory=文件名「%s」已作为目录名在此仓库中存在。 editor.file_modifying_no_longer_exists=正在修改的文件「%s」已不存在于此仓库。 editor.file_changed_while_editing=文件内容在您进行编辑时已经发生变动。单击此处 查看变动的具体内容,或者 再次提交 覆盖已发生的变动。 editor.file_already_exists=此仓库已经存在名为「%s」的文件。 +editor.commit_id_not_matching=提交 ID 与您开始编辑时的 ID 不匹配。请提交到补丁分支然后合并。 editor.push_out_of_date=推送似乎已经过时。 editor.commit_empty_file_header=提交一个空文件 editor.commit_empty_file_text=您要提交的文件是空的,继续吗? @@ -1310,7 +1392,7 @@ editor.no_changes_to_show=没有可以显示的变更。 editor.push_rejected_no_message=此修改被服务器拒绝并且没有反馈消息。请检查 Git 钩子。 editor.push_rejected=此修改被服务器拒绝。请检查 Git 钩子。 editor.push_rejected_summary=详细拒绝信息: -editor.add_subdir=添加目录 +editor.add_subdir=添加目录… editor.unable_to_upload_files=上传文件至「%s」失败:%v editor.upload_file_is_locked=文件「%s」被 %s 锁定。 editor.upload_files_to_dir=上传文件至「%s」 @@ -1328,12 +1410,13 @@ editor.fork_create_description=您不能直接编辑此仓库。您可以派生 editor.fork_edit_description=您不能直接编辑此仓库。 更改将写入您的派生仓库 %s,以便您可以创建一个合并请求。 editor.fork_not_editable=您已经派生了此仓库,但您的派生是不可编辑的。 editor.fork_failed_to_push_branch=推送分支 %s 到仓库失败。 +editor.fork_branch_exists=分支「%s」已存在于您的派生仓库中,请选择一个新的分支名称。 commits.desc=浏览代码修改历史 commits.commits=次代码提交 commits.no_commits=没有共同的提交。「%s」和「%s」的历史完全不同。 commits.nothing_to_compare=这些分支是相同的。 -commits.search.tooltip=`您可以在关键词前加上前缀,如"author:", "committer:", "after:", 或"before:", 例如 "retrin author:Alice before:2019-01-13"` +commits.search.tooltip=您可以在关键词前加上前缀,如「author:」、「committer:」、「after:」或「before:」,例如「retrin author:Alice before:2019-01-13」。 commits.search_branch=此分支 commits.search_all=所有分支 commits.author=作者 @@ -1407,7 +1490,7 @@ issues.filter_assignees=筛选指派人 issues.filter_milestones=筛选里程碑 issues.filter_projects=筛选项目 issues.filter_labels=筛选标签 -issues.filter_reviewers=筛选审核者 +issues.filter_reviewers=筛选评审人 issues.filter_no_results=没有结果 issues.filter_no_results_placeholder=请尝试调整您的搜索过滤器。 issues.new=创建工单 @@ -1427,8 +1510,9 @@ issues.new.clear_milestone=取消选中里程碑 issues.new.assignees=指派成员 issues.new.clear_assignees=取消指派成员 issues.new.no_assignees=未指派成员 -issues.new.no_reviewers=无审核者 +issues.new.no_reviewers=无评审人 issues.new.blocked_user=无法创建工单,因为您已被仓库所有者屏蔽。 +issues.edit.already_changed=无法保存对工单的更改。其内容似乎已被其他用户更改。请刷新页面并重新编辑以避免覆盖他们的更改。 issues.edit.blocked_user=无法编辑内容,因为您已被仓库所有者或工单创建者屏蔽。 issues.choose.get_started=开始 issues.choose.open_external_link=开启 @@ -1437,7 +1521,7 @@ issues.choose.blank_about=从默认模板创建一个工单。 issues.choose.ignore_invalid_templates=已忽略无效模板 issues.choose.invalid_templates=发现了 %v 个无效模板 issues.choose.invalid_config=问题配置包含错误: -issues.no_ref=分支/Git标签未指定 +issues.no_ref=分支 / Git 标签未指定 issues.create=创建工单 issues.new_label=创建标签 issues.new_label_placeholder=标签名称 @@ -1448,29 +1532,29 @@ issues.label_templates.info=还没有任何标签。您可以使用「创建标 issues.label_templates.helper=选择标签模板 issues.label_templates.use=使用标签集 issues.label_templates.fail_to_load_file=加载标签模板文件「%s」时发生错误:%v -issues.add_label=于 %[2]s 添加了标签 %[1]s -issues.add_labels=于 %[2]s 添加了标签 %[1]s -issues.remove_label=于 %[2]s 删除了标签 %[1]s -issues.remove_labels=于 %[2]s 删除了标签 %[1]s -issues.add_remove_labels=于 %[3]s 添加了标签 %[1]s ,删除了标签 %[2]s -issues.add_milestone_at=`于 %[2]s 添加了里程碑 %[1]s` -issues.add_project_at=`于 %[2]s 将此添加到 %[1]s 项目` -issues.move_to_column_of_project=`将此对象移至 %s 的 %s 中在 %s 上` -issues.change_milestone_at=`%[3]s 修改了里程碑从 %[1]s%[2]s` -issues.change_project_at=于 %[3]s 将此从项目 %[1]s 移到 %[2]s -issues.remove_milestone_at=`%[2]s 删除了里程碑 %[1]s` -issues.remove_project_at=`于 %[2]s 将此工单从项目 %[1]s 中删除` +issues.add_label=于 %[2]s 添加标签 %[1]s +issues.add_labels=于 %[2]s 添加标签 %[1]s +issues.remove_label=于 %[2]s 移除标签 %[1]s +issues.remove_labels=于 %[2]s 移除标签 %[1]s +issues.add_remove_labels=于 %[3]s 添加标签 %[1]s 移除标签 %[2]s +issues.add_milestone_at=`于 %[2]s 添加里程碑 %[1]s` +issues.add_project_at=`于 %[2]s 将此工单添加到 %[1]s 项目` +issues.move_to_column_of_project=`将 %[3]s 上的 %[2]s 移至 %[1]s` +issues.change_milestone_at=`于 %[3]s 修改里程碑从 %[1]s%[2]s` +issues.change_project_at=于 %[3]s 将项目从 %[1]s 移至 %[2]s +issues.remove_milestone_at=`于 %[2]s 删除里程碑 %[1]s` +issues.remove_project_at=`于 %[2]s 将此工单从项目 %[1]s 中移除` issues.deleted_milestone=(已删除) issues.deleted_project=`(已删除)` issues.self_assign_at=`于 %s 指派给自己` issues.add_assignee_at=`于 %[2]s 由 %[1]s 指派` -issues.remove_assignee_at=`%s 取消了指派在 %s` -issues.remove_self_assignment=`于 %s 取消了指派` +issues.remove_assignee_at=`于 %[2]s 由 %[1]s 取消指派` +issues.remove_self_assignment=`于 %s 取消指派` issues.change_title_at=`于 %[3]s 修改标题 %[1]s%[2]s` -issues.change_ref_at=`将引用从 %s 更改为了 %s %s` -issues.remove_ref_at=`删除了引用 %s %s` -issues.add_ref_at=`添加了引用 %s %s` -issues.delete_branch_at=`于 %[2]s 删除了分支 %[1]s` +issues.change_ref_at=`于 %[3]s 修改引用 %[1]s%[2]s` +issues.remove_ref_at=`于 %[2]s 删除引用 %[1]s` +issues.add_ref_at=`于 %[2]s 添加引用 %[1]s` +issues.delete_branch_at=`于 %[2]s 删除分支 %[1]s` issues.filter_label=标签筛选 issues.filter_label_exclude=`使用 alt + 鼠标左键 / 回车 排除标签` issues.filter_label_no_select=所有标签 @@ -1496,10 +1580,11 @@ issues.filter_type.assigned_to_you=指派给您的 issues.filter_type.created_by_you=由您创建的 issues.filter_type.mentioning_you=提及您的 issues.filter_type.review_requested=已请求评审 -issues.filter_type.reviewed_by_you=您评审过的 +issues.filter_type.reviewed_by_you=您已评审的 issues.filter_sort=排序 issues.filter_sort.latest=最新创建 issues.filter_sort.oldest=最早创建 +issues.filter_sort.recentupdate=最近更新 issues.filter_sort.leastupdate=最早更新 issues.filter_sort.mostcomment=最多评论 issues.filter_sort.leastcomment=最少评论 @@ -1540,33 +1625,33 @@ issues.context.edit=编辑 issues.context.delete=刪除 issues.no_content=没有提供说明。 issues.close=关闭工单 -issues.comment_pull_merged_at=已合并提交 %[1]s 到 %[2]s %[3]s -issues.comment_manually_pull_merged_at=手动合并提交 %[1]s 到 %[2]s %[3]s +issues.comment_pull_merged_at=于 %[3]s 合并提交 %[1]s 到 %[2]s +issues.comment_manually_pull_merged_at=于 %[3]s 手动合并提交 %[1]s 到 %[2]s issues.close_comment_issue=评论并关闭 issues.reopen_issue=重新打开 issues.reopen_comment_issue=评论并重新打开 issues.create_comment=评论 issues.comment.blocked_user=无法创建或编辑评论,因为您已被仓库所有者或工单创建者屏蔽。 issues.closed_at=`于 %[2]s 关闭此工单` -issues.reopened_at=`重新打开此问题 %[2]s` -issues.commit_ref_at=`于 %[2]s 在代码提交中引用了该工单` -issues.ref_issue_from=`于 %[2]s 引用了工单 %[4]s ` -issues.ref_pull_from=`于 %[2]s 引用了合并请求 %[4]s ` -issues.ref_closing_from=`于 %[2]s 引用了合并请求 %[4]s 将关闭此工单` -issues.ref_reopening_from=`于 %[2]s 引用了合并请求 %[4]s 将重新讨论此工单 ` -issues.ref_closed_from=`关闭了这个工单 %[4]s %[2]s` -issues.ref_reopened_from=`重新打开这个工单 %[4]s %[2]s` +issues.reopened_at=`于 %[2]s 重新打开此工单` +issues.commit_ref_at=`于 %[2]s 在代码提交中引用该工单` +issues.ref_issue_from=`于 %[2]s 引用工单 %[4]s ` +issues.ref_pull_from=`于 %[2]s 引用合并请求 %[4]s ` +issues.ref_closing_from=`于 %[2]s 引用合并请求 %[4]s 将关闭此工单` +issues.ref_reopening_from=`于 %[2]s 引用合并请求 %[4]s 将重新打开此工单 ` +issues.ref_closed_from=`关闭此工单 %[4]s %[2]s` +issues.ref_reopened_from=`重新打开此工单 %[4]s %[2]s` issues.ref_from=`来自 %[1]s` issues.author=作者 issues.author_helper=此用户是作者。 issues.role.owner=所有者 -issues.role.owner_helper=该用户是该仓库的所有者。 +issues.role.owner_helper=该用户是此仓库的所有者。 issues.role.member=成员 -issues.role.member_helper=该用户是拥有该仓库的组织成员。 +issues.role.member_helper=该用户是拥有此仓库的组织的成员。 issues.role.collaborator=协作者 issues.role.collaborator_helper=该用户已被邀请在仓库上进行协作。 issues.role.first_time_contributor=首次贡献者 -issues.role.first_time_contributor_helper=这是该用户对仓库的第一次贡献。 +issues.role.first_time_contributor_helper=这是该用户对此仓库的第一次贡献。 issues.role.contributor=贡献者 issues.role.contributor_helper=该用户之前提交过该仓库。 issues.re_request_review=再次请求审核 @@ -1592,7 +1677,7 @@ issues.label_exclusive_warning=在编辑工单或合并请求的标签时,任 issues.label_exclusive_order=排序顺序 issues.label_exclusive_order_tooltip=在同一个范围内的互斥标签将按照这个数字进行排序 issues.label_count=%d 个标签 -issues.label_open_issues=%d 个已打开工单/合并请求 +issues.label_open_issues=%d 个开启中工单 / 合并请求 issues.label_edit=编辑 issues.label_delete=删除 issues.label_modify=编辑标签 @@ -1616,18 +1701,19 @@ issues.lock=锁定对话 issues.unlock=解锁对话 issues.lock_duplicate=一个工单不能锁定两次。 issues.unlock_error=无法解锁一个未锁定的工单。 -issues.lock_with_reason=因为 %s 而锁定,并将对话限制为协作者 %s +issues.lock_with_reason=于 %s 锁定为 %s,并将对话限制为协作者 issues.lock_no_reason=锁定并限制仅协作者 %s issues.unlock_comment=解锁此对话 %s issues.lock_confirm=锁定 issues.unlock_confirm=解锁​​​​ +issues.lock.notice_1=- 其他用户不能对这个工单添加新的评论。 issues.lock.notice_2=- 您和仓库其他协作者仍可评论并可见。 issues.lock.notice_3=- 您可以在未来再次解锁这个工单。 issues.unlock.notice_1=- 每个人都可以再次就这一工单发表评论。 -issues.unlock.notice_2=- 您可以在未来再次解锁这个工单。 +issues.unlock.notice_2=- 您可以在未来再次锁定这个工单。 issues.lock.reason=锁定原因 -issues.lock.title=锁定有关此问题的对话。 -issues.unlock.title=解锁有关此问题的对话。 +issues.lock.title=锁定有关此工单的对话。 +issues.unlock.title=解锁有关此工单的对话。 issues.comment_on_locked=您不能对锁定的问题发表评论。 issues.delete=删除 issues.delete.title=是否删除工单? @@ -1654,72 +1740,78 @@ issues.stop_tracking_history=工作 %[1]s 于 %[2]s 停止 issues.cancel_tracking=取消 issues.cancel_tracking_history=`取消时间跟踪 %s` issues.del_time=删除此时间跟踪日志 -issues.add_time_history=已于 %[2]s 添加计时 %[1] +issues.add_time_history=于 %[2]s 添加计时 %[1] issues.del_time_history=`已删除时间 %s` issues.add_time_manually=手动添加时间 issues.add_time_hours=小时 issues.add_time_minutes=分钟 issues.add_time_sum_to_small=没有输入时间。 issues.time_spent_total=总用时 -issues.time_spent_from_all_authors=`总花费时间:%s` +issues.time_spent_from_all_authors=`总用时:%s` -issues.due_date=到期时间 -issues.invalid_due_date_format=到期时间的格式必须是「yyyy-mm-dd」的形式。 -issues.error_modifying_due_date=修改到期时间失败。 -issues.error_removing_due_date=删除到期时间失败。 -issues.push_commit_1=于 %[2]s 推送了 %[1]d 个提交 -issues.push_commits_n=于 %[2]s 推送了 %[1]d 个提交 -issues.force_push_codes=`于 %[6]s 强制推送 %[1]s,从 %[2]s,至 %[4]s` +issues.due_date=截止日期 +issues.invalid_due_date_format=截止日期的格式必须是「yyyy-mm-dd」的形式。 +issues.error_modifying_due_date=修改截止日期失败。 +issues.error_removing_due_date=删除截止日期失败。 +issues.push_commit_1=于 %[2]s 推送 %[1]d 个提交 +issues.push_commits_n=于 %[2]s 推送 %[1]d 个提交 +issues.force_push_codes=`于 %[6]s 强制推送 %[1]s,从 %[2]s%[4]s` issues.force_push_compare=比较 issues.due_date_form=yyyy年mm月dd日 -issues.due_date_form_add=设置到期时间 +issues.due_date_form_add=设置截止日期 issues.due_date_form_edit=编辑 issues.due_date_form_remove=删除 -issues.due_date_not_set=未设置到期时间。 -issues.due_date_added=于 %[2]s 设置到期时间为 %[1]s -issues.due_date_modified=将到期日从 %[2]s 修改为 %[1]s %[3]s -issues.due_date_remove=于 %[2]s 删除了到期时间 %[1]s +issues.due_date_not_writer=您需要该仓库的写权限以更新工单的截止日期。 +issues.due_date_not_set=未设置截止日期。 +issues.due_date_added=于 %[2]s 设置截止日期为 %[1]s +issues.due_date_modified=于 %[3]s 将截止日期从 %[2]s 修改为 %[1]s +issues.due_date_remove=于 %[2]s 删除截止日期 %[1]s issues.due_date_overdue=过期 -issues.due_date_invalid=到期日期无效或超出范围。请使用 'yyyy-mm-dd' 格式。 +issues.due_date_invalid=截止日期无效或超出范围。请使用「yyyy-mm-dd」格式。 issues.dependency.title=依赖工单 -issues.dependency.issue_no_dependencies=没有设置依赖项。 -issues.dependency.pr_no_dependencies=没有设置依赖项。 +issues.dependency.issue_no_dependencies=未设置依赖工单。 +issues.dependency.pr_no_dependencies=未设置依赖工单。 issues.dependency.no_permission_1=您没有读取 %d 依赖关系的权限 issues.dependency.no_permission_n=您没有读取 %d 依赖关系的权限 issues.dependency.no_permission.can_remove=您没有读取此依赖关系的权限,但可以删除此依赖关系 -issues.dependency.add=添加依赖工单... +issues.dependency.add=添加依赖工单… issues.dependency.cancel=取消 issues.dependency.remove=删除 issues.dependency.remove_info=删除此依赖项 -issues.dependency.added_dependency=`添加了一个新的依赖项 %s` +issues.dependency.added_dependency=`添加了一个新依赖项 %s` issues.dependency.removed_dependency=`移除了一个依赖项 %s` -issues.dependency.pr_closing_blockedby=以下工单阻止了关闭此合并请求 +issues.dependency.pr_closing_blockedby=以下工单阻止关闭此合并请求 issues.dependency.issue_closing_blockedby=关闭此工单被以下工单阻止 -issues.dependency.issue_close_blocks=此工单阻止了以下工单的关闭 +issues.dependency.issue_close_blocks=此工单阻止以下工单的关闭 issues.dependency.pr_close_blocks=此合并请求阻止以下工单的关闭 +issues.dependency.issue_close_blocked=您需要关闭所有阻止此工单的工单后才能关闭它。 issues.dependency.issue_batch_close_blocked=无法批量关闭您所选择的工单,因为 #%d 工单仍然有处于打开状态的依赖工单 +issues.dependency.pr_close_blocked=您需要关闭所有阻止此合并请求的工单后才能合并它。 issues.dependency.blocks_short=阻止 issues.dependency.blocked_by_short=依赖于 issues.dependency.remove_header=删除依赖项 -issues.dependency.issue_remove_text=此操作将从工单中删除依赖。是否要继续? -issues.dependency.pr_remove_text=此操作将从合并请求中删除依赖。是否要继续? +issues.dependency.issue_remove_text=此操作将从工单中删除依赖。是否要继续? +issues.dependency.pr_remove_text=此操作将从合并请求中删除依赖。是否要继续? issues.dependency.setting=为工单和合并请求启用依赖 issues.dependency.add_error_same_issue=您不能让一个工单依赖于自身。 issues.dependency.add_error_dep_issue_not_exist=依赖项不存在。 issues.dependency.add_error_dep_not_exist=依赖项不存在。 issues.dependency.add_error_dep_exists=依赖项已存在。 +issues.dependency.add_error_cannot_create_circular=您无法在相互阻塞的工单之间建立依赖关系。 issues.dependency.add_error_dep_not_same_repo=这两个工单必须在同一仓库。 issues.review.self.approval=您不能批准您自己的合并请求。 issues.review.self.rejection=您不能请求对您自己的合并请求进行更改。 issues.review.approve=于 %s 批准此合并请求 -issues.review.comment=评审于 %s +issues.review.comment=于 %s 评审 +issues.review.dismissed=于 %[2]s 取消 %[1]s 的评审 issues.review.dismissed_label=已取消 issues.review.left_comment=留下了一条评论 issues.review.content.empty=您需要留下一个注释,表明需要的更改。 issues.review.reject=请求变更 %s -issues.review.wait=已请求 %s 审核 +issues.review.wait=已请求 %s 评审 issues.review.add_review_request=于 %[2]s 请求 %[1]s 评审 issues.review.remove_review_request=取消对 %s 的评审请求 %s +issues.review.remove_review_request_self=拒绝评审 %s issues.review.pending=待定 issues.review.pending.tooltip=此评论目前对其他用户不可见。 若要提交您的待定评论,请在页面顶部选择 %s -> %s/%s/%s。 issues.review.review=评审 @@ -1741,6 +1833,7 @@ issues.review.requested=等待审核 issues.review.rejected=请求变更 issues.review.stale=批准后已更新 issues.review.unofficial=非官方审批数 +issues.assignee.error=因为未知原因,并非所有的指派都成功。 issues.reference_issue.body=内容 issues.content_history.deleted=已删除 issues.content_history.edited=已编辑 @@ -1748,7 +1841,7 @@ issues.content_history.created=已创建 issues.content_history.delete_from_history=从历史记录中删除 issues.content_history.delete_from_history_confirm=从历史记录中删除吗? issues.content_history.options=选项 -issues.reference_link=参考:%s +issues.reference_link=引用:%s compare.compare_base=基准分支 compare.compare_head=比较 @@ -1757,6 +1850,7 @@ pulls.desc=启用合并请求和代码评审。 pulls.new=创建合并请求 pulls.new.blocked_user=无法创建合并请求,因为您已被仓库所有者屏蔽。 pulls.new.must_collaborator=您必须是仓库的协作者才能创建合并请求。 +pulls.edit.already_changed=无法保存对合并请求的更改。其内容似乎已被其他用户更改。请刷新页面并重新编辑以避免覆盖他们的更改。 pulls.view=查看合并请求 pulls.compare_changes=创建合并请求 pulls.allow_edits_from_maintainers=允许维护者编辑 @@ -1777,11 +1871,13 @@ pulls.show_all_commits=显示所有提交 pulls.show_changes_since_your_last_review=显示自您上次审核以来的更改 pulls.showing_only_single_commit=仅显示提交 %[1]s 的更改 pulls.showing_specified_commit_range=仅显示 %[1]s..%[2]s 之间的更改 +pulls.select_commit_hold_shift_for_range=选择提交。按住 Shift + 单击选择一个范围 pulls.review_only_possible_for_full_diff=只有在查看全部差异时才能进行审核 pulls.filter_changes_by_commit=按提交筛选 pulls.nothing_to_compare=分支内容相同,无需创建合并请求。 +pulls.nothing_to_compare_have_tag=所选分支 / Git 标签相同。 pulls.nothing_to_compare_and_allow_empty_pr=这些分支是相等的,此合并请求将为空。 -pulls.has_pull_request=这些分支之间的合并请求已存在: %[2]s#%[3]d +pulls.has_pull_request=这些分支之间的合并请求已存在:%[2]s#%[3]d pulls.create=创建合并请求 pulls.title_desc=请求将 %[1]d 次代码提交从 %[2]s 合并至 %[3]s pulls.merged_title_desc=于 %[4]s 将 %[1]d 次代码提交从 %[2]s合并至 %[3]s @@ -1792,11 +1888,11 @@ pulls.tab_files=文件变动 pulls.reopen_to_merge=请重新创建此合并请求。 pulls.cant_reopen_deleted_branch=无法重新打开此合并请求,因为分支已删除。 pulls.merged=已合并 -pulls.merged_success=合并请求已成功合并和关闭 +pulls.merged_success=合并请求已成功合并并关闭 pulls.closed=合并请求已关闭 pulls.manually_merged=已手动合并 pulls.merged_info_text=分支 %s 现在可以删除了。 -pulls.is_closed=合并请求已经关闭。 +pulls.is_closed=合并请求已关闭。 pulls.title_wip_desc=`标题以 %s 开头以免合并请求意外合并。` pulls.cannot_merge_work_in_progress=此合并请求被标记为正在进行的工作。 pulls.still_in_progress=仍在进行中? @@ -1804,13 +1900,14 @@ pulls.add_prefix=添加 %s 前缀 pulls.remove_prefix=删除 %s 前缀 pulls.data_broken=此合并请求因为派生仓库信息缺失而中断。 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=作为管理员,您仍可合并此合并请求 pulls.blocked_by_approvals=此合并请求还没有足够的批准。已获批准数 %d 个,需获批准数 %d 个。 -pulls.blocked_by_approvals_whitelisted=此合并请求还没有足够的批准。%[2]d 中的 %[1]d 个已由允许名单中的用户或团队批准。 +pulls.blocked_by_approvals_whitelisted=此合并请求尚未获得足够的批准。已获得 %d/%d 个来自允许列表中用户或团队的批准。 pulls.blocked_by_rejection=此合并请求有官方审核员请求的更改。 pulls.blocked_by_official_review_requests=此合并请求需要官方评审。 pulls.blocked_by_outdated_branch=此合并请求因过期而被阻止。 @@ -1827,12 +1924,16 @@ pulls.reject_count_1=%d 变更请求 pulls.reject_count_n=%d 变更请求 pulls.waiting_count_1=%d 个正在等待审核 pulls.waiting_count_n=%d 个正在等待审核 +pulls.wrong_commit_id=提交 id 必须在目标分支上 pulls.no_merge_desc=由于未启用合并选项,此合并请求无法合并。 pulls.no_merge_helper=在仓库设置中启用合并选项或者手工合并请求。 pulls.no_merge_wip=这个合并请求无法合并,因为被标记为尚未完成的工作。 +pulls.no_merge_not_ready=此合并请求尚未准备好合并,请检查审核状态和状态检查。 pulls.no_merge_access=您无权合并此合并请求。 pulls.merge_pull_request=创建合并提交 +pulls.rebase_merge_pull_request=变基后快进 +pulls.rebase_merge_commit_pull_request=变基后创建合并提交 pulls.squash_merge_pull_request=创建压缩提交 pulls.fast_forward_only_merge_pull_request=仅快进 pulls.merge_manually=手动合并 @@ -1840,13 +1941,20 @@ pulls.merge_commit_id=合并提交 ID pulls.require_signed_wont_sign=分支需要签名的提交,但这个合并将不会被签名 pulls.invalid_merge_option=您可以在此合并请求中使用合并选项。 +pulls.merge_conflict=合并失败:合并时有冲突发生。提示:采用其它合并策略。 pulls.merge_conflict_summary=错误信息 +pulls.rebase_conflict=合并失败:变基提交有冲突:%[1]s。提示:采用其它合并策略。 pulls.rebase_conflict_summary=错误信息 +pulls.unrelated_histories=合并失败:两个分支没有共同历史。提示:尝试不同的策略。 +pulls.merge_out_of_date=合并失败:在生成合并时,主分支已更新。提示:再试一次。 +pulls.head_out_of_date=合并失败:在生成合并时,head 已更新。提示:再试一次。 +pulls.has_merged=失败:合并请求已经合并。您不能再次合并或更改目标分支。 pulls.push_rejected=推送失败:推送被拒绝。审查此仓库的 Git 钩子。 pulls.push_rejected_summary=详细拒绝信息 -pulls.open_unmerged_pull_exists=`您不能执行重新打开操作, 因为已经存在相同的合并请求 (#%d)。` -pulls.status_checking=一些检测仍在等待运行 -pulls.status_checks_success=所有检测均成功 +pulls.push_rejected_no_message=推送失败:此推送被拒绝但未提供其他信息。请检查此仓库的 Git 钩子。 +pulls.open_unmerged_pull_exists=`您不能执行重新打开操作,因为已经存在相同的合并请求 (#%d)。` +pulls.status_checking=一些检查仍在等待运行 +pulls.status_checks_success=所有检查均成功 pulls.status_checks_warning=一些检查报告了警告 pulls.status_checks_failure=一些检查失败了 pulls.status_checks_error=一些检查报告了错误 @@ -1861,14 +1969,15 @@ pulls.update_not_allowed=您无权更新分支 pulls.outdated_with_base_branch=此分支相比基础分支已过期 pulls.close=关闭合并请求 pulls.closed_at=`于 %[2]s 关闭此合并请求 ` -pulls.reopened_at=`重新打开此合并请求 %[2]s` +pulls.reopened_at=`于 %[2]s 重新打开此合并请求` pulls.cmd_instruction_hint=查看命令行提示 pulls.cmd_instruction_checkout_title=检出 pulls.cmd_instruction_checkout_desc=从您的仓库中检出一个新的分支并测试变更。 pulls.cmd_instruction_merge_title=合并 pulls.cmd_instruction_merge_desc=合并变更并更新到 Gitea 上 -pulls.cmd_instruction_merge_warning=警告:此操作不能合并该合并请求,因为「自动检测手动合并」未启用 +pulls.cmd_instruction_merge_warning=警告:此操作不能合并该合并请求,因为「自动检查手动合并」未启用。 pulls.clear_merge_message=清除合并信息 +pulls.clear_merge_message_hint=清除合并消息只会删除提交消息内容,并保留生成的 Git 附加内容,如「Co-Authored-By…」。 pulls.auto_merge_button_when_succeed=(当检查成功时) pulls.auto_merge_when_succeed=在所有检查成功后自动合并 @@ -1880,12 +1989,12 @@ pulls.auto_merge_not_scheduled=此合并请求没有计划自动合并。 pulls.auto_merge_canceled_schedule=此合并请求的自动合并已取消。 pulls.auto_merge_newly_scheduled_comment=`已于 %[1]s 设置此合并请求在所有检查成功后自动合并` -pulls.auto_merge_canceled_schedule_comment=`已于 %[1]s 取消了自动合并设置 ` +pulls.auto_merge_canceled_schedule_comment=`已于 %[1]s 取消自动合并设置 ` pulls.delete.title=删除此合并请求? pulls.delete.text=您真的要删除这个合并请求吗?(这将永久删除所有内容。如果您打算将内容存档,请考虑关闭它) -pulls.recently_pushed_new_branches=您已经于%[2]s推送了分支 %[1]s +pulls.recently_pushed_new_branches=您已经于 %[2]s 推送分支 %[1]s pulls.upstream_diverging_prompt_behind_1=该分支落后于 %[2]s %[1]d 个提交 pulls.upstream_diverging_prompt_behind_n=该分支落后于 %[2]s %[1]d 个提交 pulls.upstream_diverging_prompt_base_newer=基础分支 %s 有新的更改 @@ -1910,7 +2019,7 @@ milestones.title=标题 milestones.desc=描述 milestones.due_date=截止日期(可选) milestones.clear=清除 -milestones.invalid_due_date_format=到期时间的格式必须是「yyyy-mm-dd」的形式。 +milestones.invalid_due_date_format=截止日期的格式必须是「yyyy-mm-dd」的形式。 milestones.create_success=里程碑「%s」创建成功。 milestones.edit=编辑里程碑 milestones.edit_subheader=里程碑组织工单,合并请求和跟踪进度。 @@ -1929,10 +2038,12 @@ milestones.filter_sort.most_issues=工单从多到少 milestones.filter_sort.least_issues=工单从少到多 signing.will_sign=这个提交将用密钥「%s」签名。 +signing.wont_sign.error=在检查提交是否可以被签名时出错。 signing.wont_sign.nokey=没有可用的密钥来签署这个提交。 signing.wont_sign.never=提交从未签名。 signing.wont_sign.always=提交总是签名。 signing.wont_sign.pubkey=由于您没有公钥关联到您的账户,提交将不会被签名。 +signing.wont_sign.twofa=您必须启用两步验证才能签名提交。 signing.wont_sign.parentsigned=提交将不会被签名,因为父提交没有签名。 signing.wont_sign.basesigned=合并将不会被签名,因为父提交没有签名。 signing.wont_sign.headsigned=合并将不会被签名,因为最新提交没有签名。 @@ -1945,7 +2056,7 @@ ext_wiki.desc=链接到外部百科。 wiki=百科 wiki.welcome=欢迎来到百科。 -wiki.welcome_desc=百科允许您撰写和与协作者分享文档。 +wiki.welcome_desc=百科允许您撰写并与协作者分享文档。 wiki.desc=撰写和与协作者分享文档 wiki.create_first_page=创建第一个页面 wiki.page=页面 @@ -1963,11 +2074,11 @@ wiki.wiki_page_revisions=页面历史 wiki.back_to_wiki=返回百科 wiki.delete_page_button=删除页面 wiki.delete_page_notice_1=百科页面「%s」删除后无法恢复,是否继续? -wiki.page_already_exists=相同名称的 Wiki 页面已经存在。 +wiki.page_already_exists=相同名称的百科页面已经存在。 wiki.reserved_page=百科页面名称「%s」是保留的。 wiki.pages=所有页面 wiki.last_updated=最后更新于 %s -wiki.page_name_desc=输入此百科页面的名称。特殊名称有:「Home」,「_Sidebar」和「_Footer」。 +wiki.page_name_desc=输入此百科页面的名称。特殊名称有:「Home」、「_Sidebar」和「_Footer」。 wiki.original_git_entry_tooltip=查看原始的 Git 文件而不是使用友好链接。 activity=活动 @@ -1988,13 +2099,13 @@ activity.active_prs_count_1=%d 个合并请求 activity.active_prs_count_n=%d 个合并请求 activity.merged_prs_count_1=已合并的合并请求 activity.merged_prs_count_n=已合并的合并请求 -activity.opened_prs_count_1=创建的合并请求 -activity.opened_prs_count_n=创建的合并请求 +activity.opened_prs_count_1=已创建的合并请求 +activity.opened_prs_count_n=已创建的合并请求 activity.title.user_1=%d 位用户 activity.title.user_n=%d 位用户 activity.title.prs_1=%d 个合并请求 activity.title.prs_n=%d 个合并请求 -activity.title.prs_merged_by=%[2]s 由 %[1]s 合并 +activity.title.prs_merged_by=%[2]s 合并了 %[1]s activity.title.prs_opened_by=%[2]s 创建了 %[1]s activity.merged_prs_label=已合并 activity.opened_prs_label=已创建 @@ -2004,20 +2115,21 @@ activity.closed_issues_count_1=已关闭的工单 activity.closed_issues_count_n=已关闭的工单 activity.title.issues_1=%d 张工单 activity.title.issues_n=%d 张工单 -activity.title.issues_closed_from=%s 从 %s 关闭 +activity.title.issues_closed_from=%[2]s 关闭了 %[1]s activity.title.issues_created_by=%[2]s 创建了 %[1]s activity.closed_issue_label=已关闭 -activity.new_issues_count_1=已打开的工单 +activity.new_issues_count_1=开启的工单 activity.new_issues_count_n=已打开的工单 activity.new_issue_label=打开的 activity.title.unresolved_conv_1=%d 未解决的会话 activity.title.unresolved_conv_n=%d 未解决的会话 activity.unresolved_conv_desc=这些最近更新的工单和合并请求还没有解决。 activity.unresolved_conv_label=打开 -activity.title.releases_1=%d 个发布 -activity.title.releases_n=%d 个发布 +activity.title.releases_1=%d 个版本 +activity.title.releases_n=%d 个版本 activity.title.releases_published_by=%[2]s 发布了 %[1]s activity.published_release_label=已发布 +activity.no_git_activity=在此期间没有任何提交活动。 activity.git_stats_exclude_merges=排除合并后, activity.git_stats_author_1=%d 位作者 activity.git_stats_author_n=%d 位作者 @@ -2045,11 +2157,13 @@ contributors.contribution_type.additions=新增 contributors.contribution_type.deletions=删除 settings=设置 +settings.desc=设置是您可以管理仓库设置的地方。 settings.options=仓库 settings.public_access=公开访问 settings.public_access_desc=配置公共访客访问权限以覆盖此仓库的默认值。 settings.public_access.docs.not_set=未设置:没有额外的公共访问权限。访客权限遵循仓库的可见性和成员权限。 settings.public_access.docs.anonymous_read=匿名可读:未登录的用户可以通过读取权限访问单元。 +settings.public_access.docs.everyone_read=所有人可读:所有登录用户都可以通过读取权限访问单元。读取问题/拉取请求单元的权限也意味着用户可以创建新的问题/拉取请求。 settings.public_access.docs.everyone_write=所有人可写:所有登录用户都有写入权限。只有百科支持此权限。 settings.collaboration=协作者 settings.collaboration.admin=管理员 @@ -2062,11 +2176,12 @@ settings.hooks=Web 钩子 settings.githooks=管理 Git 钩子 settings.basic_settings=基本设置 settings.mirror_settings=镜像设置 -settings.mirror_settings.docs=将您的仓库设置为自动同步另一个仓库的提交、标签和分支。 -settings.mirror_settings.docs.disabled_pull_mirror.instructions=将您的项目设置为自动将提交、标签和分支推送到另一个仓库。您的站点管理员已禁用了拉取镜像。 -settings.mirror_settings.docs.disabled_push_mirror.instructions=将您的项目设置为自动从一个仓库拉取提交、标签和分支。 +settings.mirror_settings.docs=将您的仓库设置为自动同步另一个仓库的提交、Git 标签和分支。 +settings.mirror_settings.docs.disabled_pull_mirror.instructions=将您的项目设置为自动将提交、Git 标签和分支推送到另一个仓库。您的站点管理员已禁用了拉取镜像。 +settings.mirror_settings.docs.disabled_push_mirror.instructions=将您的项目设置为自动从一个仓库拉取提交、Git 标签和分支。 settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning=现在,这只能在「迁移外部仓库」菜单中完成。欲了解更多信息,请参考: settings.mirror_settings.docs.disabled_push_mirror.info=您的站点管理员已禁用推送镜像。 +settings.mirror_settings.docs.no_new_mirrors=您的仓库将镜像同步另一个仓库的更改。请注意,您目前无法创建任何新的镜像。 settings.mirror_settings.docs.can_still_use=虽然您不能修改现有镜像或创建新镜像,但您仍然可以使用已存在的镜像。 settings.mirror_settings.docs.pull_mirror_instructions=要创建一个拉取镜像,请参阅: settings.mirror_settings.docs.more_information_if_disabled=您可以在这里找到更多关于推送和拉取镜像的信息: @@ -2116,12 +2231,12 @@ settings.tracker_issue_style.alphanumeric=英文字母数字组合形式 settings.tracker_issue_style.regexp=正则表达式 settings.tracker_issue_style.regexp_pattern=正则表达式 settings.tracker_issue_style.regexp_pattern_desc=第一个被捕获的组将取代 {index}。 -settings.tracker_url_format_desc=使用占位符 {user}, {repo}{index} 作为用户名、仓库名和工单索引。 +settings.tracker_url_format_desc=使用占位符 {user}{repo}{index} 作为用户名、仓库名和工单索引。 settings.enable_timetracker=启用时间跟踪 settings.allow_only_contributors_to_track_time=仅允许成员跟踪时间 settings.pulls_desc=启用合并请求 settings.pulls.ignore_whitespace=忽略空白冲突 -settings.pulls.enable_autodetect_manual_merge=启用自动检测手动合并 (注意:在某些特殊情况下可能发生错误判断) +settings.pulls.enable_autodetect_manual_merge=启用自动检查手动合并(注意:在某些特殊情况下可能会出现误判) settings.pulls.allow_rebase_update=允许通过变基更新合并请求分支 settings.pulls.default_delete_branch_after_merge=默认合并后删除合并请求分支 settings.pulls.default_allow_edits_from_maintainers=默认允许维护者编辑 @@ -2141,6 +2256,7 @@ settings.admin_indexer_commit_sha=上次索引的 SHA settings.admin_indexer_unindexed=未索引 settings.reindex_button=添加到重新索引队列 settings.reindex_requested=已请求重新索引 +settings.admin_enable_close_issues_via_commit_in_any_branch=通过在非默认分支中提交来关闭工单 settings.danger_zone=危险操作区 settings.new_owner_has_same_repo=新的仓库拥有者已经存在同名仓库! settings.convert=转换为普通仓库 @@ -2162,6 +2278,7 @@ settings.transfer_abort_invalid=您不能取消不存在的仓库转移。 settings.transfer_abort_success=成功取消将仓库转移给 %s。 settings.transfer_desc=您可以将仓库转移至您拥有管理员权限的帐户或组织。 settings.transfer_form_title=输入仓库名称以确认: +settings.transfer_in_progress=当前正在进行转移。 如果您想将此仓库转移给另一个用户,请取消它。 settings.transfer_notices_1=- 如果将此仓库转移给其他用户,您将失去对此仓库的访问权限。 settings.transfer_notices_2=- 如果将其转移到您(共同)拥有的组织,您可以继续访问该仓库。 settings.transfer_notices_3=- 如果仓库是私有的并且被转移给某个用户,那么此操作可以确保该用户至少具有读权限(以及必要时的更改权限)。 @@ -2176,17 +2293,22 @@ settings.trust_model.default=默认信任模型 settings.trust_model.default.desc=为此安装使用默认仓库信任模型。 settings.trust_model.collaborator=协作者 settings.trust_model.collaborator.long=协作者:信任协作者的签名 +settings.trust_model.collaborator.desc=此仓库中协作者的有效签名将被标记为「可信」(无论它们是否是提交者),签名只符合提交者时将标记为「不可信」,都不匹配时标记为「不匹配」。 settings.trust_model.committer=提交者 +settings.trust_model.committer.long=提交者: 信任与提交者相符的签名(这符合 GitHub 的行为并将强制 Gitea 签名的提交以 Gitea 为提交者)。 +settings.trust_model.committer.desc=有效签名只有和提交者相匹配才会被标记为「受信任」,否则它们将被标记为「不匹配」。这强制 Gitea 成为签名提交的提交者,而实际提交者被加上 Co-authored-by: 和 Co-committed-by: 的标记。 默认的 Gitea 密钥必须匹配数据库中的一名用户。 settings.trust_model.collaboratorcommitter=协作者+提交者 settings.trust_model.collaboratorcommitter.long=协作者+提交者:信任协作者同时是提交者的签名 +settings.trust_model.collaboratorcommitter.desc=此仓库中协作者的有效签名在他同时是提交者时将被标记为「可信」,签名只匹配了提交者时将标记为「不可信」,都不匹配时标记为「不匹配」。这会强制 Gitea 成为签名者和提交者,实际的提交者将被标记于提交消息结尾处的「Co-Authored-By:」和「Co-Committed-By:」。默认的 Gitea 签名密钥必须匹配数据库中的一个用户密钥。 settings.wiki_delete=删除百科数据 settings.wiki_delete_desc=删除仓库百科数据是永久性的,无法撤消。 settings.wiki_delete_notices_1=- 这将永久删除和禁用 %s 的百科。 settings.confirm_wiki_delete=删除百科数据 settings.wiki_deletion_success=仓库百科数据删除成功! settings.delete=删除本仓库 -settings.delete_desc=删除仓库是永久性的, 无法撤消。 +settings.delete_desc=删除仓库是永久性的,无法撤消。 settings.delete_notices_1=- 此操作 无法 被回滚。 +settings.delete_notices_2=- 此操作将永久删除仓库 %s,包括代码、 工单、评论、百科数据和协作者设置。 settings.delete_notices_fork_1=- 在此仓库删除后,它的派生仓库将变成独立仓库。 settings.deletion_success=仓库已删除。 settings.update_settings_success=仓库设置已更新。 @@ -2208,7 +2330,9 @@ settings.team_not_in_organization=团队不在与仓库相同的组织中 settings.teams=团队 settings.add_team=添加团队 settings.add_team_duplicate=团队已经拥有仓库 -settings.delete_team_tip=该团队仍有仓库, 无法删除 +settings.add_team_success=团队现在可以访问仓库。 +settings.change_team_permission_tip=团队权限设置于团队设置页面,不能根据仓库更改 +settings.delete_team_tip=该团队仍有仓库,无法删除 settings.remove_team_success=团队访问仓库的权限已删除。 settings.add_webhook=添加 Web 钩子 settings.add_webhook.invalid_channel_name=Web 钩子通道名称不能为空且不能仅包含一个 # 字符。 @@ -2246,12 +2370,12 @@ settings.discord_icon_url=图标 URL settings.event_desc=触发条件: settings.event_push_only=推送事件 settings.event_send_everything=所有事件 -settings.event_choose=自定义事件... +settings.event_choose=自定义事件… settings.event_header_repository=仓库事件 settings.event_create=创建 -settings.event_create_desc=创建分支或标签 +settings.event_create_desc=分支或 Git 标签已创建。 settings.event_delete=刪除 -settings.event_delete_desc=分支或标签已删除。 +settings.event_delete_desc=分支或 Git 标签已删除。 settings.event_fork=派生 settings.event_fork_desc=仓库已派生。 settings.event_wiki=百科 @@ -2303,7 +2427,7 @@ settings.event_workflow_job_desc=Gitea 工作流队列中、等待中、正在 settings.event_package=软件包 settings.event_package_desc=软件包在仓库中已创建或删除。 settings.branch_filter=分支过滤 -settings.branch_filter_desc=推送、创建,删除分支事件的分支白名单,使用 glob 表达式匹配指定。若为空或 *,则会报告所有分支的事件。语法文档见 %[2]s。示例:master,{master,release*}。 +settings.branch_filter_desc=推送、创建,删除分支事件的分支白名单,使用 glob 表达式匹配指定。若为空或 *,则会报告所有分支的事件。语法文档见 %[2]s。示例:master{master,release*}。 settings.authorization_header=授权标头 settings.authorization_header_desc=当存在时将被作为授权标头包含在内。例如: %s。 settings.active=激活 @@ -2406,9 +2530,9 @@ settings.protect_branch_name_pattern=受保护的分支名称表达式 settings.protect_branch_name_pattern_desc=分支保护的名称匹配表达式。语法请参阅 文档 。如:main, release/** settings.protect_patterns=表达式 settings.protect_protected_file_patterns=受保护的文件表达式(使用分号「;」分隔): -settings.protect_protected_file_patterns_desc=即使用户有权添加、编辑或删除此分支中的文件,也不允许直接更改受保护的文件。 可以使用分号「;」分隔多个表达式。 见%[2]s文档了解表达式语法。例如: .drone.yml, /docs/**/*.txt。 +settings.protect_protected_file_patterns_desc=即使用户有权添加、编辑或删除此分支中的文件,也不允许直接更改受保护的文件。可以使用分号(';')分隔多个表达式。见 %[2]s 文档了解表达式语法。例如:.drone.yml/docs/**/*.txt。 settings.protect_unprotected_file_patterns=不受保护的文件表达式(使用分号「;」分隔): -settings.protect_unprotected_file_patterns_desc=如果用户有写权限,则允许直接更改的不受保护的文件,以绕过推送限制。可以使用分号分隔多个表达式「;」。 见 %[2]s 文档了解表达式语法。例如: .drone.yml, /docs/**/*.txt。 +settings.protect_unprotected_file_patterns_desc=如果用户具有写权限则允许直接更改的不受保护文件,可绕过推送限制。可使用分号(';')分隔多个表达式。见 %[2]s 文档了解表达式语法。例如:.drone.yml/docs/**/*.txt。 settings.add_protected_branch=启用保护 settings.delete_protected_branch=禁用保护 settings.update_protect_branch_success=分支保护规则「%s」更新成功。 @@ -2423,25 +2547,26 @@ settings.block_on_official_review_requests_desc=处于评审状态时,即使 settings.block_outdated_branch=如果合并请求已经过时,阻止合并 settings.block_outdated_branch_desc=当头部分支落后基础分支时,不能合并。 settings.block_admin_merge_override=管理员须遵守分支保护规则 +settings.block_admin_merge_override_desc=管理员须遵守分支保护规则,不能规避该规则。 settings.default_branch_desc=请选择一个默认的分支用于合并请求和提交: settings.merge_style_desc=合并方式 settings.default_merge_style_desc=默认合并风格 -settings.choose_branch=选择一个分支... +settings.choose_branch=选择一个分支… settings.no_protected_branch=没有受保护的分支 settings.edit_protected_branch=编辑 settings.protected_branch_required_rule_name=必须填写规则名称 settings.protected_branch_duplicate_rule_name=规则名称已存在 settings.protected_branch_required_approvals_min=所需的审批数不能为负数。 -settings.tags=标签 -settings.tags.protection=标签保护 -settings.tags.protection.pattern=标签表达式 +settings.tags=Git 标签 +settings.tags.protection=Git 标签保护 +settings.tags.protection.pattern=Git 标签表达式 settings.tags.protection.allowed=允许列表 settings.tags.protection.allowed.users=允许的账号 settings.tags.protection.allowed.teams=允许的团队 settings.tags.protection.allowed.noone=无 -settings.tags.protection.create=保护标签 -settings.tags.protection.none=没有受保护的标签。 -settings.tags.protection.pattern.description=您可以使用单个名称或 glob 表达式匹配或正则表达式来匹配多个标签。了解详情请访问 保护标签指南。 +settings.tags.protection.create=保护 Git 标签 +settings.tags.protection.none=没有受保护的 Git 标签。 +settings.tags.protection.pattern.description=您可以使用单个名称或 glob 表达式匹配或正则表达式来匹配多个 Git 标签。了解详情请访问 保护标签指南。 settings.bot_token=Bot 令牌 settings.chat_id=聊天 ID settings.thread_id=线程 ID @@ -2449,7 +2574,10 @@ settings.matrix.homeserver_url=主服务器网址 settings.matrix.room_id=房间ID settings.matrix.message_type=消息类型 settings.visibility.private.button=设为私有 +settings.visibility.private.text=将可见性更改为私有会使仓库仅对允许的成员可见,而且可能会消除它与派生仓库、关注者和点赞之间的关系。 settings.visibility.private.bullet_title=将可见性改为私有将会: +settings.visibility.private.bullet_one=使仓库只对允许的成员可见。 +settings.visibility.private.bullet_two=可能会删除它与 派生仓库关注者点赞 之间的关系。 settings.visibility.public.button=设为公开 settings.visibility.public.text=将可见性更改为公开会使任何人都可见。 settings.visibility.public.bullet_title=将可见性改为公开将会: @@ -2459,15 +2587,16 @@ settings.visibility.error=试图更改仓库可见性时出错。 settings.visibility.fork_error=无法更改派生仓库的可见性。 settings.archive.button=归档仓库 settings.archive.header=归档此仓库 -settings.archive.text=归档仓库将使其完全只读。它将在首页隐藏。没有人(包括您)能够进行新的提交,或打开工单及合并请求。 +settings.archive.text=归档仓库将使其完全只读。它将在首页隐藏。没有人(包括您)能够进行新的提交,或创建工单及合并请求。 settings.archive.success=仓库已成功归档。 settings.archive.error=仓库在归档时出现异常。请通过日志获取详细信息。 settings.archive.error_ismirror=请不要对镜像仓库归档,谢谢! settings.archive.branchsettings_unavailable=已归档仓库无法进行分支设置。 -settings.archive.tagsettings_unavailable=已归档仓库的标签设置不可用。 +settings.archive.tagsettings_unavailable=已归档仓库的 Git 标签设置不可用。 settings.archive.mirrors_unavailable=如果仓库已归档,镜像将不可用。 settings.unarchive.button=撤销仓库归档 settings.unarchive.header=撤销此仓库归档 +settings.unarchive.text=撤销归档将恢复仓库接收提交、推送,以及新工单和合并请求的能力。 settings.unarchive.success=仓库已成功撤销归档。 settings.unarchive.error=仓库在取消归档时出现异常。请通过日志获取详细信息。 settings.update_avatar_success=仓库头像已经更新。 @@ -2485,9 +2614,11 @@ settings.lfs_invalid_locking_path=无效路径:%s settings.lfs_invalid_lock_directory=无法锁定目录:%s settings.lfs_lock_already_exists=锁已经存在:%s settings.lfs_lock=锁定 +settings.lfs_lock_path=要锁定的文件路径… settings.lfs_locks_no_locks=无锁定 settings.lfs_lock_file_no_exist=锁定的文件在默认分支中不存在 settings.lfs_force_unlock=强制解锁 +settings.lfs_pointers.found=找到 %d 个块指针 — %d 个关联, %d 个未关联(%d 个从仓库丢失) settings.lfs_pointers.sha=Blob SHA settings.lfs_pointers.oid=OID settings.lfs_pointers.inRepo=在仓库中 @@ -2560,9 +2691,9 @@ diff.submodule_deleted=子模块 %[1]s 已从 %[2]s 中删除 diff.submodule_updated=子模块 %[1]s 已更新:%[2]s releases.desc=跟踪项目版本和下载。 -release.releases=发布 +release.releases=版本发布 release.detail=发布详情 -release.tags=标签 +release.tags=Git 标签 release.new_release=发布新版 release.draft=草稿 release.prerelease=预发布 @@ -2571,16 +2702,16 @@ release.latest=最新 release.compare=比较 release.edit=编辑 release.ahead.commits=%d 次提交 -release.ahead.target=在此版本发布后已加入到 %s -tag.ahead.target=自此标签到 %s +release.ahead.target=在此版本后已推送到 %s +tag.ahead.target=自此 Git 标签到 %s release.source_code=源代码 release.new_subheader=发布组织项目的版本。 release.edit_subheader=发布组织项目的版本。 -release.tag_name=标签名称 +release.tag_name=Git 标签名称 release.target=目标分支 -release.tag_helper=选择一个存在的标签或者创建新标签。 -release.tag_helper_new=新标签。此标签将从目标创建。 -release.tag_helper_existing=现有标签。 +release.tag_helper=选择一个存在的 Git 标签或者创建新 Git 标签。 +release.tag_helper_new=新 Git 标签。此 Git 标签将从目标创建。 +release.tag_helper_existing=现有 Git 标签。 release.title=发布标题 release.title_empty=标题不能为空。 release.message=描述这个版本 @@ -2591,22 +2722,22 @@ release.publish=发布版本 release.save_draft=保存草稿 release.edit_release=保存此次发布 release.delete_release=删除发布 -release.delete_tag=删除标签 +release.delete_tag=删除 Git 标签 release.deletion=删除发布 release.deletion_desc=删除发布只会从 Gitea 中移除发布。这不会影响 Git 的标签以及您仓库的内容和历史。是否继续? release.deletion_success=该发布已删除。 -release.deletion_tag_desc=将从仓库中删除此标签。仓库内容和历史记录保持不变。继续吗? -release.deletion_tag_success=该标签已删除。 -release.tag_name_already_exist=使用此标签名称的发布已经存在。 -release.tag_name_invalid=标签名称无效。 -release.tag_name_protected=标签名已受保护。 -release.tag_already_exist=此标签名已存在。 +release.deletion_tag_desc=将从仓库中删除此 Git 标签。仓库内容和历史记录保持不变。继续吗? +release.deletion_tag_success=该 Git 标签已删除。 +release.tag_name_already_exist=使用此 Git 标签名称的发布已经存在。 +release.tag_name_invalid=Git 标签名称无效。 +release.tag_name_protected=Git 标签名已受保护。 +release.tag_already_exist=此 Git 标签名已存在。 release.downloads=下载附件 release.download_count=下载:%s -release.add_tag_msg=使用发布的标题和内容作为标签消息。 -release.add_tag=仅创建标签 +release.add_tag_msg=使用发布的标题和内容作为 Git 标签消息。 +release.add_tag=仅创建 Git 标签 release.releases_for=%s 的发布 -release.tags_for=%s 的标签 +release.tags_for=%s 的 Git 标签 branch.name=分支名称 branch.already_exists=名为「%s」的分支已存在。 @@ -2622,7 +2753,7 @@ branch.create_from=从「%s」 branch.create_success=分支「%s」已创建。 branch.branch_already_exists=此仓库已存在名为「%s」的分支。 branch.branch_name_conflict=分支名称「%s」与已存在的分支「%s」冲突。 -branch.tag_collision=分支「%s」无法创建,因为同名的标签已经存在。 +branch.tag_collision=分支「%s」无法创建,因为同名的 Git 标签已经存在。 branch.deleted_by=删除人:%s branch.restore_success=分支「%s」已还原。 branch.restore_failed=分支「%s」还原失败。 @@ -2645,14 +2776,15 @@ branch.new_branch_from=基于「%s」创建新分支 branch.renamed=分支 %s 已重命名为 %s。 branch.rename_default_or_protected_branch_error=只有管理员能重命名默认分支和受保护的分支。 branch.rename_protected_branch_failed=此分支受到 glob 语法规则的保护。 +branch.commits_divergence_from=提交分歧:落后 %[3]s %[1]d 个提交,领先 %[2]d 个提交 branch.commits_no_divergence=与分支 %[1]s 相同 -tag.create_tag=创建标签 %s -tag.create_tag_operation=创建标签 -tag.confirm_create_tag=创建标签 -tag.create_tag_from=基于「%s」创建新标签 +tag.create_tag=创建 Git 标签 %s +tag.create_tag_operation=创建 Git 标签 +tag.confirm_create_tag=创建 Git 标签 +tag.create_tag_from=基于「%s」创建新 Git 标签 -tag.create_success=标签「%s」已存在。 +tag.create_success=Git 标签「%s」已存在。 topic.manage_topics=管理主题 topic.done=保存 @@ -2669,6 +2801,7 @@ error.csv.invalid_field_count=无法渲染此文件,因为它在第 %d 行中 error.broken_git_hook=此仓库的 Git 钩子似乎已损坏。 请按照 文档 来修复它们,然后推送一些提交来刷新状态。 [graphs] +component_loading=正在加载 %s… component_loading_failed=无法加载 %s component_loading_info=这可能需要一点时间… component_failed_to_load=意外的错误发生了。 @@ -2697,7 +2830,7 @@ team_desc_helper=描述团队的目的或作用。 team_access_desc=仓库权限 team_permission_desc=权限 team_unit_desc=允许访问仓库单元 -team_unit_disabled=(已禁用) +team_unit_disabled=(已禁用) form.name_been_taken=组织名称「%s」已经被占用。 form.name_reserved=组织名称「%s」是保留的。 @@ -2707,11 +2840,17 @@ form.create_org_not_allowed=此账号禁止创建组织 settings=组织设置 settings.options=组织 settings.full_name=组织全名 +settings.email=联系邮箱 settings.website=网站 settings.location=所在地区 settings.permission=权限 settings.repoadminchangeteam=仓库管理员可以添加或移除团队的访问权限 settings.visibility=可见性 +settings.change_visibility=更改可见性 +settings.change_visibility_notices_1=如果组织被转换为私有,仓库的所有点赞将被删除且无法恢复。 +settings.change_visibility_notices_2=如果可见性更改为私有,非成员将无法访问该组织的仓库。 +settings.change_visibility_success=组织 %s 的可见性已成功更改。 +settings.visibility_desc=更改谁可以查看组织及其仓库。 settings.visibility.public=公开 settings.visibility.limited=受限 (仅对认证用户可见) settings.visibility.limited_shortname=受限 @@ -2723,7 +2862,10 @@ settings.update_setting_success=组织设置已更新。 settings.rename=修改组织名称 settings.rename_desc=更改组织名称同时会更改组织的 URL 地址并释放旧的名称。 +settings.rename_success=组织 %[1]s 已成功重命名为 %[2]s。 +settings.rename_no_change=组织名称没有变更。 settings.rename_new_org_name=新组织名称 +settings.rename_failed=由于内部错误,重命名组织失败 settings.rename_notices_1=此操作 无法 被回滚。 settings.rename_notices_2=在被人使用前,旧名称将会被重定向。 @@ -2733,9 +2875,11 @@ settings.delete_account=删除当前组织 settings.delete_prompt=删除操作会永久清除该组织的信息,并且 无法 恢复! settings.name_confirm=输入组织名称以确认: settings.delete_notices_1=此操作 无法 被回滚。 +settings.delete_notices_2=此操作将永久删除 %s 的所有仓库,包括 Git 数据、 工单、评论、百科和协作者的操作权限。 settings.delete_notices_3=此操作将永久删除 %s 的所有 软件包。 settings.delete_notices_4=此操作将永久删除 %s 的所有 项目。 settings.confirm_delete_account=确认删除组织 +settings.delete_failed=由于内部错误,删除组织失败 settings.delete_successful=组织 %s 已成功删除。 settings.hooks_desc=在此处添加的 Web 钩子将会应用到该组织下的 所有仓库。 @@ -2792,6 +2936,7 @@ teams.remove_all_repos_title=移除所有团队仓库 teams.remove_all_repos_desc=这将从团队中移除所有仓库。 teams.add_all_repos_title=添加所有仓库 teams.add_all_repos_desc=这将把组织的所有仓库添加到团队。 +teams.add_nonexistent_repo=您尝试添加的仓库不存在,请先创建它。 teams.add_duplicate_users=用户已经是团队成员。 teams.repos.none=此团队无法访问任何仓库。 teams.members.none=团队中没有成员。 @@ -2832,6 +2977,7 @@ repositories=仓库管理 hooks=Web 钩子 integrations=集成 authentication=认证源 +emails=用户邮箱 config=应用配置 config_summary=摘要 config_settings=设置 @@ -2863,19 +3009,28 @@ dashboard.cron.cancelled=计划任务:%[1]s 已取消:%[3]s dashboard.cron.error=计划任务错误: %s: %[3]s dashboard.cron.finished=计划任务:%[1]s 已完成 dashboard.delete_inactive_accounts=删除所有未激活的帐户 +dashboard.delete_inactive_accounts.started=删除所有未激活的账号任务已启动。 dashboard.delete_repo_archives=删除所有仓库的存档(ZIP、TAR、GZ等) +dashboard.delete_repo_archives.started=删除所有仓库存档任务已启动。 dashboard.delete_missing_repos=删除所有丢失 Git 文件的仓库 +dashboard.delete_missing_repos.started=删除所有丢失 Git 文件的仓库任务已启动。 dashboard.delete_generated_repository_avatars=删除生成的仓库头像 dashboard.sync_repo_branches=将缺少的分支从 Git 数据同步到数据库 -dashboard.sync_repo_tags=从 Git 数据同步标签到数据库 +dashboard.sync_repo_tags=从 Git 数据同步 Git 标签到数据库 dashboard.update_mirrors=更新镜像仓库 dashboard.repo_health_check=健康检查所有仓库 dashboard.check_repo_stats=检查所有仓库统计 dashboard.archive_cleanup=删除旧的仓库存档 +dashboard.deleted_branches_cleanup=清理已删除的分支 dashboard.update_migration_poster_id=更新迁移的发表者ID +dashboard.git_gc_repos=对仓库进行垃圾回收 +dashboard.resync_all_sshkeys=使用 Gitea 的 SSH 密钥更新「.ssh/authorized_keys」文件。 +dashboard.resync_all_sshprincipals=使用 Gitea 的 SSH 规则更新「.ssh/authorized_principals」文件。 +dashboard.resync_all_hooks=重新同步所有仓库的 pre-receive、update 和 post-receive 钩子 dashboard.reinit_missing_repos=重新初始化所有丢失的 Git 仓库存在的记录 dashboard.sync_external_users=同步外部用户数据 dashboard.cleanup_hook_task_table=清理 hook_task 表 +dashboard.cleanup_packages=清理过期的软件包 dashboard.cleanup_actions=清理过期的工作流资源 dashboard.server_uptime=服务运行时间 dashboard.current_goroutine=当前 Goroutines 数量 @@ -2907,14 +3062,16 @@ dashboard.total_gc_pause=GC 暂停时间总量 dashboard.last_gc_pause=上次 GC 暂停时间 dashboard.gc_times=GC 执行次数 dashboard.delete_old_actions=从数据库中删除所有旧工作流记录 +dashboard.delete_old_actions.started=已开始从数据库中删除所有旧工作流记录。 dashboard.update_checker=更新检查器 dashboard.delete_old_system_notices=从数据库中删除所有旧系统通知 +dashboard.gc_lfs=垃圾回收 LFS 元数据 dashboard.stop_zombie_tasks=停止僵尸工作流任务 dashboard.stop_endless_tasks=停止无限循环的工作流任务 dashboard.cancel_abandoned_jobs=取消已放弃的工作流任务 dashboard.start_schedule_tasks=启动工作流计划任务 dashboard.sync_branch.started=分支同步已开始 -dashboard.sync_tag.started=标签同步已开始 +dashboard.sync_tag.started=Git 标签同步已开始 dashboard.rebuild_issue_indexer=重建工单索引 dashboard.sync_repo_licenses=重新探测仓库许可证 @@ -2932,6 +3089,7 @@ users.2fa=两步验证 users.repos=仓库数 users.created=创建时间 users.last_login=上次登录 +users.never_login=从未登录 users.send_register_notify=发送注册通知 users.new_success=用户账户「%s」已创建。 users.edit=修改 @@ -2943,7 +3101,7 @@ users.update_profile_success=该帐户已更新。 users.edit_account=编辑帐号 users.max_repo_creation=最大仓库数 users.max_repo_creation_desc=(设置为 -1 表示使用全局默认值) -users.is_activated=该用户已激活 +users.is_activated=用户已激活 users.prohibit_login=禁用登录 users.is_admin=是管理员 users.is_restricted=受限 @@ -2958,6 +3116,7 @@ users.still_own_repo=此用户仍然拥有一个或多个仓库。必须首先 users.still_has_org=此用户是组织的成员。必须先从组织中删除用户。 users.purge=清理用户 users.purge_help=强制删除用户和用户拥有的任何仓库、组织和软件包。所有评论也将删除。 +users.still_own_packages=此用户仍然拥有一个或多个软件包,请先删除这些软件包。 users.deletion_success=用户帐户已删除。 users.reset_2fa=重置两步验证 users.list_status_filter.menu_text=过滤 @@ -2975,9 +3134,13 @@ users.list_status_filter.not_2fa_enabled=未启用 2FA users.details=用户详细信息 emails.email_manage_panel=邮件管理 -emails.primary=主要的 +emails.primary=主 emails.activated=已激活 +emails.filter_sort.email=邮箱 +emails.filter_sort.email_reverse=邮箱(倒序) emails.filter_sort.name=用户名 +emails.filter_sort.name_reverse=用户名(倒序) +emails.updated=邮箱已更新 emails.not_updated=无法更新请求的邮箱地址:%v emails.duplicate_active=此邮箱地址已被另一个用户激活使用。 emails.change_email_header=更新邮箱属性 @@ -2985,6 +3148,7 @@ emails.change_email_text=您确定要更新该邮箱地址吗? emails.delete=删除邮箱 emails.delete_desc=您确定要删除该邮箱地址? emails.deletion_success=邮箱地址已删除。 +emails.delete_primary_email_error=您不能删除主邮箱。 orgs.org_manage_panel=组织管理 orgs.name=名称 @@ -3098,30 +3262,39 @@ auths.oauth2_required_claim_name_helper=设置此名称,只有具有此名称 auths.oauth2_required_claim_value=必须填写 Claim 声明的值 auths.oauth2_required_claim_value_helper=设置此值,只有拥有对应的声明(Claim)的名称和值的用户才被允许从此源登录 auths.oauth2_group_claim_name=用于提供用户组名称的 Claim 声明名称。(可选) +auths.oauth2_full_name_claim_name=全名声明名称。(可选,如果设置,用户的全名将始终与此声明同步) auths.oauth2_ssh_public_key_claim_name=SSH 公钥声明名称 +auths.oauth2_admin_group=管理员用户组的 Claim 声明值。(可选 — 需要上面的声明名称) +auths.oauth2_restricted_group=受限用户组的 Claim 声明值。(可选 — 需要上面的声明名称) +auths.oauth2_map_group_to_team=映射声明的组到组织团队。(可选 — 要求在上面填写声明的名字) auths.oauth2_map_group_to_team_removal=如果用户不属于相应的组,从已同步团队中移除用户 auths.enable_auto_register=允许用户自动注册 auths.sspi_auto_create_users=自动创建用户 +auths.sspi_auto_create_users_helper=允许 SSPI 认证在用户第一次登录时自动创建新账号 auths.sspi_auto_activate_users=自动激活用户 auths.sspi_auto_activate_users_helper=允许 SSPI 认证自动激活新用户 auths.sspi_strip_domain_names=从用户名中删除域名部分 +auths.sspi_strip_domain_names_helper=如果选中此项,域名将从登录名中删除(例如,「DOMAIN\user」和「user@example.org」,两者都将变成只是「用户」)。 auths.sspi_separator_replacement=要使用的分隔符代替\, / 和 @ +auths.sspi_separator_replacement_helper=用于替换下级登录名称分隔符的字符(例如「DOMAIN\user」)中的 \ 和用户主名字(如「user@example.org」中的 @)。 auths.sspi_default_language=默认语言 +auths.sspi_default_language_helper=通过 SSPI 身份验证方式自动创建的用户的默认语言。如果您希望自动检测语言,请留空。 auths.tips=帮助提示 auths.tips.oauth2.general=OAuth2 认证 auths.tips.oauth2.general.tip=当注册新的 OAuth2 身份验证时,回调/重定向 URL 应该是: auths.tip.oauth2_provider=OAuth2 提供程序 auths.tip.bitbucket=在 %s 注册新的 OAuth 使用者同时添加权限「账号」-「读取」 +auths.tip.nextcloud=使用下面的菜单「设置 -> 安全 -> OAuth 2.0 客户端」在您的实例上注册一个新的 OAuth 客户端 auths.tip.dropbox=在 %s 上创建一个新的应用程序 auths.tip.facebook=在 %s 注册一个新的应用,并添加产品「Facebook 登录」 auths.tip.github=在 %s 注册一个 OAuth 应用程序 auths.tip.gitlab_new=在 %s 注册一个新的应用 auths.tip.google_plus=从谷歌 API 控制台 %s 获得 OAuth2 客户端凭据 -auths.tip.openid_connect=使用 OpenID 连接发现 URL ({server}/.well-known/openid-configuration) 来指定终点 +auths.tip.openid_connect=使用 OpenID 连接发现 URL「{server}/.well-known/openid-configuration」来指定终点 auths.tip.twitter=访问 %s,创建应用并确保启用了「允许此应用程序使用 Twitter 登录」的选项 auths.tip.discord=在 %s 上注册新应用程序 auths.tip.gitea=注册一个新的 OAuth2 应用程序。可以访问 %s 查看帮助 -auths.tip.yandex=在 %s 上创建一个新的应用。在「Yandex.Passport API」这部分中选择以下权限:「访问邮箱地址」,「访问用户头像」和「访问用户名,名字和姓氏,性别」 +auths.tip.yandex=在 %s 上创建一个新的应用。在「Yandex.Passport API」这部分中选择以下权限:「访问邮箱地址」、「访问用户头像」和「访问用户名,名字和姓氏,性别」 auths.tip.mastodon=输入您想要认证的 mastodon 实例的自定义 URL (或使用默认值) auths.edit=修改认证源 auths.activated=该认证源已经启用 @@ -3140,7 +3313,7 @@ auths.invalid_openIdConnectAutoDiscoveryURL=无效的自动发现 URL(这必 config.server_config=服务器配置 config.app_name=站点名称 -config.app_ver=Gitea版本 +config.app_ver=Gitea 版本 config.app_url=Gitea 基本 URL config.custom_conf=配置文件路径 config.custom_file_root_path=自定义文件根路径 @@ -3221,6 +3394,7 @@ 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.send_test_mail_submit=发送 config.test_mail_failed=发送测试邮件至「%s」失败:%v @@ -3229,30 +3403,31 @@ config.test_mail_sent=测试邮件已经发送至「%s」。 config.oauth_config=OAuth 配置 config.oauth_enabled=启用 -config.cache_config=Cache 配置 -config.cache_adapter=Cache 适配器 -config.cache_interval=Cache 周期 -config.cache_conn=Cache 连接字符串 +config.cache_config=缓存配置 +config.cache_adapter=缓存适配器 +config.cache_interval=缓存周期 +config.cache_conn=缓存连接字符串 config.cache_item_ttl=缓存项目 TTL config.cache_test=测试缓存 -config.cache_test_failed=缓存测试失败: %v。 +config.cache_test_failed=缓存测试失败:%v。 config.cache_test_slow=缓存测试成功,但响应缓慢:%s。 config.cache_test_succeeded=缓存测试成功,在 %s 时间内得到响应。 -config.session_config=Session 配置 -config.session_provider=Session 提供者 +config.session_config=会话配置 +config.session_provider=会话提供者 config.provider_config=提供者配置 config.cookie_name=Cookie 名称 config.gc_interval_time=GC 周期 -config.session_life_time=Session 生命周期 +config.session_life_time=会话生命周期 config.https_only=仅限 HTTPS config.cookie_life_time=Cookie 生命周期 config.picture_config=图片和头像配置 config.picture_service=图片服务 config.disable_gravatar=禁用 Gravatar 头像 -config.enable_federated_avatar=启用 Federated Avatars +config.enable_federated_avatar=启用 Federated 头像 config.open_with_editor_app_help=用于克隆菜单的编辑器。如果为空将使用默认值。展开可以查看默认值。 +config.git_guide_remote_name=指南中 git 命令使用的仓库远程名称 config.git_config=Git 配置 config.git_disable_diff_highlight=禁用差异对比语法高亮 @@ -3267,11 +3442,11 @@ config.git_pull_timeout=拉取操作超时 config.git_gc_timeout=GC 操作超时 config.log_config=日志配置 -config.logger_name_fmt=日志:%s +config.logger_name_fmt=%s 日志 config.disabled_logger=禁用 config.access_log_mode=访问日志模式 config.access_log_template=访问日志模板 -config.xorm_log_sql=日志 SQL +config.xorm_log_sql=SQL 日志 config.set_setting_failed=设置 %s 失败 @@ -3294,6 +3469,7 @@ monitor.start=开始时间 monitor.execute_time=执行时长 monitor.last_execution_result=结果 monitor.process.cancel=中止进程 +monitor.process.cancel_desc=中止一个进程可能导致数据丢失 monitor.process.children=子进程 monitor.queues=队列 @@ -3308,6 +3484,7 @@ monitor.queue.numberinqueue=队列中的数量 monitor.queue.review_add=查看 / 添加工作者 monitor.queue.settings.title=池设置 monitor.queue.settings.desc=因为工作者队列阻塞,池正在动态扩展。 +monitor.queue.settings.maxnumberworkers=最大工作者数量 monitor.queue.settings.maxnumberworkers.placeholder=当前 %[1]d monitor.queue.settings.maxnumberworkers.error=最大工作者数必须是数字 monitor.queue.settings.submit=更新设置 @@ -3333,12 +3510,16 @@ notices.delete_success=系统通知已删除。 self_check.no_problem_found=尚未发现问题。 self_check.startup_warnings=启动警告: self_check.database_collation_mismatch=期望数据库使用的校验方式:%s -self_check.location_origin_mismatch=当前 URL(%[1]s)与 Gitea 的 URL(%[2]s)不匹配 。 如果您正在使用反向代理,请确保设置正确的「Host」和「X-Forwarded-Proto」标头。 +self_check.database_collation_case_insensitive=数据库正在使用一个排序规则 %s,这是一个不区分大小写的排序规则。虽然 Gitea 可以在此环境下工作,但可能存在一些无法按预期工作的罕见情况。 +self_check.database_inconsistent_collation_columns=数据库正在使用排序规则 %s,但这些列使用了不匹配的排序规则。这可能会导致一些意外问题。 +self_check.database_fix_mysql=对于 MySQL/MariaDB 用户,您可以使用「gitea doctor convert」命令来解决校验问题。 或者您也可以通过「ALTER ... COLLATE ...」这样的 SQL 来手动解决这个问题。 +self_check.database_fix_mssql=对于 MSSQL 用户,您现在只能通过「ALTER ... COLLATE ...」SQL 手动解决这个问题。 +self_check.location_origin_mismatch=当前 URL(%[1]s)与 Gitea 的 URL(%[2]s)不匹配。如果您正在使用反向代理,请确保设置正确的「Host」和「X-Forwarded-Proto」标头。 [action] create_repo=创建了仓库 %s -rename_repo=重命名仓库 %[1]s%[3]s -commit_repo=推送到了仓库 %[4]s%[3]s 分支 +rename_repo=重命名了仓库 %[1]s%[3]s +commit_repo=推送了仓库 %[4]s%[3]s 分支 create_issue=`创建了工单 %[3]s#%[2]s` close_issue=`关闭了工单 %[3]s#%[2]s` reopen_issue=`重新打开了工单 %[3]s#%[2]s` @@ -3350,9 +3531,9 @@ comment_pull=`评论了合并请求 %[3]s#%[2]s` merge_pull_request=`合并了合并请求 %[3]s#%[2]s` auto_merge_pull_request=`自动合并了合并请求 %[3]s#%[2]s` transfer_repo=将仓库 %s 转移至 %s -push_tag=推送了标签 %[3]s 至仓库 %[4]s -delete_tag=从%[3]s 删除了标签 %[2]s -delete_branch=从 %[3]s 删除分支 %[2]s +push_tag=推送了 Git 标签 %[3]s 至仓库 %[4]s +delete_tag=从 %[3]s 删除了 Git 标签 %[2]s +delete_branch=从 %[3]s 删除了分支 %[2]s compare_branch=比较 compare_commits=比较 %d 提交 compare_commits_general=比较提交 @@ -3360,13 +3541,13 @@ mirror_sync_push=从镜像同步了提交至仓库 %[4]s 的 mirror_sync_create=从镜像同步了引用 %[3]s 至仓库 %[4]s mirror_sync_delete=从镜像同步并从 %[3]s 删除了引用 %[2]s approve_pull_request=`批准了 %[3]s#%[2]s` -reject_pull_request=`建议变更 %[3]s#%[2]s` +reject_pull_request=`建议了变更 %[3]s#%[2]s` publish_release=`在 %[3]s 发布了 %[4]s ` -review_dismissed=`取消了 %[4]s%[3]s#%[2]s 的变更请求` +review_dismissed=`取消了 %[4]s%[3]s#%[2]s 的评审` review_dismissed_reason=原因: create_branch=于 %[4]s 创建了分支 %[3]s starred_repo=点赞了 %[2]s -watched_repo=开始关注 %[2]s +watched_repo=关注了 %[2]s [tool] now=现在 @@ -3389,7 +3570,7 @@ raw_seconds=秒 raw_minutes=分钟 [dropzone] -default_message=拖动文件或者点击此处上传。 +default_message=拖曳文件或点击此处上传。 invalid_input_type=您不能上传该类型的文件 file_too_big=文件体积({{filesize}} MB)超过了最大允许体积({{maxFilesize}} MB) remove_file=移除文件 @@ -3416,6 +3597,8 @@ error.no_committer_account=没有帐户链接到提交者的邮箱 error.no_gpg_keys_found=找不到此签名对应的密钥 error.not_signed_commit=未签名的提交 error.failed_retrieval_gpg_keys=找不到任何与该提交者账号相关的密钥 +error.probable_bad_signature=警告!虽然数据库中有一个此 ID 的密钥,但它没有验证此提交!此提交是可疑的。 +error.probable_bad_default_signature=警告!虽然默认密钥拥有此 ID,但它没有验证此提交!此提交是可疑的。 [units] unit=单元 @@ -3454,6 +3637,7 @@ versions.view_all=查看全部 dependency.id=ID dependency.version=版本 search_in_external_registry=在 %s 中搜索 +alpine.registry=通过在您的 /etc/apk/repositories 文件中添加 URL 来设置此注册中心: alpine.registry.key=下载注册中心公开的 RSA 密钥到 /etc/apk/keys/ 文件夹来验证索引签名: alpine.registry.info=从下面的列表中选择 $branch 和 $repository。 alpine.install=要安装软件包,请运行以下命令: @@ -3466,13 +3650,18 @@ arch.install=使用 pacman 同步软件包: arch.repository=仓库信息 arch.repository.repositories=仓库 arch.repository.architectures=架构 +cargo.registry=在 Cargo 配置文件中设置此注册中心(例如:~/.cargo/config.toml): cargo.install=要使用 Cargo 安装软件包,请运行以下命令: +chef.registry=在您的 ~/.chef/config.rb 文件中设置此注册中心: chef.install=要安装软件包,请运行以下命令: +composer.registry=在您的 ~/.composer/config.json 文件中设置此注册中心: composer.install=要使用 Composer 安装软件包,请运行以下命令: composer.dependencies=依赖 composer.dependencies.development=开发依赖 conan.details.repository=仓库 +conan.registry=从命令行设置此注册中心: conan.install=要使用 Conan 安装软件包,请运行以下命令: +conda.registry=在您的 .condarc 文件中将此注册中心设置为 Conda 仓库: conda.install=要使用 Conda 安装软件包,请运行以下命令: container.details.type=镜像类型 container.details.platform=平台 @@ -3484,7 +3673,9 @@ container.layers=镜像层 container.labels=标签 container.labels.key=键 container.labels.value=值 +cran.registry=在您的 Rprofile.site 文件中设置此注册中心: cran.install=要安装软件包,请运行以下命令: +debian.registry=从命令行设置此注册中心: debian.registry.info=从下面的列表中选择 $distribution 和 $component。 debian.install=要安装软件包,请运行以下命令: debian.repository=仓库信息 @@ -3493,11 +3684,16 @@ debian.repository.components=组件 debian.repository.architectures=架构 generic.download=从命令行下载软件包: go.install=通过命令行安装软件包: +helm.registry=从命令行设置此注册中心: helm.install=要安装包,请运行以下命令: +maven.registry=在您项目的 pom.xml 文件中设置此注册中心: +maven.install=要使用这个软件包,在 pom.xml 文件中的 依赖项 块中包含以下内容: maven.install2=通过命令行运行: maven.download=要下载依赖项,请通过命令行运行: +nuget.registry=从命令行设置此注册中心: nuget.install=要使用 Nuget 安装软件包,请运行以下命令: nuget.dependency.framework=目标框架 +npm.registry=在您项目的 .npmrc 文件中设置此注册中心: npm.install=要使用 npm 安装软件包,请运行以下命令: npm.install2=或将其添加到 package.json 文件: npm.dependencies=依赖项 @@ -3509,6 +3705,7 @@ npm.details.tag=标签 pub.install=要使用 Dart 安装软件包,请运行以下命令: pypi.requires=需要 Python pypi.install=要使用 pip 安装软件包,请运行以下命令: +rpm.registry=从命令行设置此仓库: rpm.distros.redhat=在基于 RedHat 的发行版 rpm.distros.suse=在基于 SUSE 的发行版 rpm.install=要安装软件包,请运行以下命令: @@ -3521,11 +3718,11 @@ rubygems.dependencies.runtime=运行时依赖 rubygems.dependencies.development=开发依赖 rubygems.required.ruby=需要 Ruby 版本 rubygems.required.rubygems=需要 RubyGem 版本 -swift.install=在您的 Package.swift文件中添加该包: +swift.registry=从命令行设置此仓库: +swift.install=在您的 Package.swift 文件中添加该包: swift.install2=并运行以下命令: vagrant.install=若要添加一个 Vagrant box,请运行以下命令: settings.link=将此软件包链接到仓库 -settings.link.description=如果您将一个软件包与一个仓库链接起来,软件包将显示在仓库的软件包列表中。 settings.link.select=选择仓库 settings.link.button=更新仓库链接 settings.link.success=仓库链接已成功更新。 @@ -3538,7 +3735,7 @@ settings.delete.error=删除软件包失败。 owner.settings.cargo.title=Cargo 注册中心索引 owner.settings.cargo.initialize=初始化索引 owner.settings.cargo.initialize.description=使用 Cargo 注册中心时需要一个特殊索引的 Git 仓库。使用此选项将(重新)创建仓库并自动配置它。 -owner.settings.cargo.initialize.error=初始化 Cargo 索引失败: %v +owner.settings.cargo.initialize.error=初始化 Cargo 索引失败:%v owner.settings.cargo.initialize.success=Cargo 索引已经成功创建。 owner.settings.cargo.rebuild=重建索引 owner.settings.cargo.rebuild.description=如果索引与存储的 Cargo 包不同步,重建可能会有用。 @@ -3631,6 +3828,7 @@ runners.delete_runner=删除此运行器 runners.delete_runner_success=运行器删除成功 runners.delete_runner_failed=运行器删除失败 runners.delete_runner_header=确认要删除此运行器 +runners.delete_runner_notice=如果一个任务正在运行在此运行器上,它将被终止并标记为失败。它可能会打断正在构建的工作流。 runners.none=无可用运行器 runners.status.unspecified=未知 runners.status.idle=空闲 diff --git a/options/locale/locale_zh-HK.ini b/options/locale/locale_zh-HK.ini index 0cf0de3ec4..8a8c2a7bb6 100644 --- a/options/locale/locale_zh-HK.ini +++ b/options/locale/locale_zh-HK.ini @@ -158,6 +158,7 @@ register_success=註冊成功 + [modal] yes=確認操作 no=取消操作 diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index 10f103b82a..c1879203f7 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -494,6 +494,7 @@ repo.transfer.to_you=您 repo.collaborator.added.subject=%s 把您加入到 %s repo.collaborator.added.text=您已被新增為儲存庫的協作者: + team_invite.subject=%[1]s 邀請您加入組織 %[2]s team_invite.text_1=%[1]s 邀請您加入組織 %[3]s 中的 %[2]s 團隊 team_invite.text_2=請點擊下方連結加入團隊: @@ -3396,7 +3397,6 @@ swift.install=將此套件加入您的 Package.swift 檔: swift.install2=並執行下列命令: vagrant.install=執行下列命令以新增 Vagrant box: settings.link=連結此套件到儲存庫 -settings.link.description=如果您將套件連結到儲存庫,該套件會顯示在儲存庫的套件清單。 settings.link.select=選擇儲存庫 settings.link.button=更新儲存庫連結 settings.link.success=儲存庫連結更新成功。 diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 0cee3699a8..0000000000 --- a/package-lock.json +++ /dev/null @@ -1,14391 +0,0 @@ -{ - "name": "gitea", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "@citation-js/core": "0.7.18", - "@citation-js/plugin-bibtex": "0.7.18", - "@citation-js/plugin-csl": "0.7.18", - "@citation-js/plugin-software-formats": "0.6.1", - "@github/markdown-toolbar-element": "2.2.3", - "@github/relative-time-element": "4.4.8", - "@github/text-expander-element": "2.9.2", - "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", - "@primer/octicons": "19.15.5", - "@silverwind/vue3-calendar-heatmap": "2.0.6", - "add-asset-webpack-plugin": "3.0.0", - "ansi_up": "6.0.6", - "asciinema-player": "3.10.0", - "chart.js": "4.5.0", - "chartjs-adapter-dayjs-4": "1.0.4", - "chartjs-plugin-zoom": "2.2.0", - "clippie": "4.1.7", - "cropperjs": "1.6.2", - "css-loader": "7.1.2", - "dayjs": "1.11.13", - "dropzone": "6.0.0-beta.2", - "easymde": "2.20.0", - "esbuild-loader": "4.3.0", - "fast-glob": "3.3.3", - "htmx.org": "2.0.6", - "idiomorph": "0.7.3", - "jquery": "3.7.1", - "katex": "0.16.22", - "license-checker-webpack-plugin": "0.2.1", - "mermaid": "11.9.0", - "mini-css-extract-plugin": "2.9.2", - "minimatch": "10.0.3", - "monaco-editor": "0.52.2", - "monaco-editor-webpack-plugin": "7.1.0", - "online-3d-viewer": "0.16.0", - "pdfobject": "2.3.1", - "perfect-debounce": "1.0.0", - "postcss": "8.5.6", - "postcss-loader": "8.1.1", - "postcss-nesting": "13.0.2", - "sortablejs": "1.15.6", - "swagger-ui-dist": "5.27.0", - "tailwindcss": "3.4.17", - "throttle-debounce": "5.0.2", - "tinycolor2": "1.6.0", - "tippy.js": "6.3.7", - "toastify-js": "1.12.0", - "tributejs": "5.1.3", - "typescript": "5.8.3", - "uint8-to-base64": "0.2.1", - "vanilla-colorful": "0.7.2", - "vue": "3.5.18", - "vue-bar-graph": "2.2.0", - "vue-chartjs": "5.3.2", - "vue-loader": "17.4.2", - "webpack": "5.101.0", - "webpack-cli": "6.0.1", - "wrap-ansi": "9.0.0" - }, - "devDependencies": { - "@eslint-community/eslint-plugin-eslint-comments": "4.5.0", - "@playwright/test": "1.54.1", - "@stoplight/spectral-cli": "6.15.0", - "@stylistic/eslint-plugin-js": "3.1.0", - "@stylistic/stylelint-plugin": "4.0.0", - "@types/dropzone": "5.7.9", - "@types/jquery": "3.5.32", - "@types/katex": "0.16.7", - "@types/license-checker-webpack-plugin": "0.2.5", - "@types/pdfobject": "2.2.5", - "@types/sortablejs": "1.15.8", - "@types/swagger-ui-dist": "3.30.6", - "@types/throttle-debounce": "5.0.2", - "@types/tinycolor2": "1.4.6", - "@types/toastify-js": "1.12.4", - "@typescript-eslint/eslint-plugin": "8.38.0", - "@typescript-eslint/parser": "8.38.0", - "@vitejs/plugin-vue": "6.0.1", - "@vitest/eslint-plugin": "1.3.4", - "eslint": "8.57.0", - "eslint-import-resolver-typescript": "4.4.4", - "eslint-plugin-array-func": "4.0.0", - "eslint-plugin-github": "5.0.2", - "eslint-plugin-import-x": "4.16.1", - "eslint-plugin-no-jquery": "3.1.1", - "eslint-plugin-no-use-extend-native": "0.5.0", - "eslint-plugin-playwright": "2.2.2", - "eslint-plugin-regexp": "2.9.0", - "eslint-plugin-sonarjs": "3.0.4", - "eslint-plugin-unicorn": "56.0.1", - "eslint-plugin-vue": "10.4.0", - "eslint-plugin-vue-scoped-css": "2.11.0", - "eslint-plugin-wc": "3.0.1", - "happy-dom": "18.0.1", - "markdownlint-cli": "0.45.0", - "material-icon-theme": "5.24.0", - "nolyfill": "1.0.44", - "postcss-html": "1.8.0", - "stylelint": "16.23.0", - "stylelint-config-recommended": "17.0.0", - "stylelint-declaration-block-no-ignored-properties": "2.8.0", - "stylelint-declaration-strict-value": "1.10.11", - "stylelint-define-config": "16.22.0", - "stylelint-value-no-unknown-custom-properties": "6.0.1", - "svgo": "4.0.0", - "type-fest": "4.41.0", - "updates": "16.5.2", - "vite-string-plugin": "1.4.6", - "vitest": "3.2.4", - "vue-tsc": "3.0.4" - }, - "engines": { - "node": ">= 20.0.0" - } - }, - "node_modules/@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@antfu/install-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz", - "integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==", - "license": "MIT", - "dependencies": { - "package-manager-detector": "^1.3.0", - "tinyexec": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@antfu/utils": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.1.tgz", - "integrity": "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@asyncapi/specs": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/@asyncapi/specs/-/specs-6.8.1.tgz", - "integrity": "sha512-czHoAk3PeXTLR+X8IUaD+IpT+g+zUvkcgMDJVothBsan+oHN3jfcFcFUNdOPAAFoUCQN1hXF1dWuphWy05THlA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.11" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/code-frame/node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", - "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz", - "integrity": "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", - "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@braintree/sanitize-url": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz", - "integrity": "sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==", - "license": "MIT" - }, - "node_modules/@chevrotain/cst-dts-gen": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", - "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", - "license": "Apache-2.0", - "dependencies": { - "@chevrotain/gast": "11.0.3", - "@chevrotain/types": "11.0.3", - "lodash-es": "4.17.21" - } - }, - "node_modules/@chevrotain/gast": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", - "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", - "license": "Apache-2.0", - "dependencies": { - "@chevrotain/types": "11.0.3", - "lodash-es": "4.17.21" - } - }, - "node_modules/@chevrotain/regexp-to-ast": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", - "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==", - "license": "Apache-2.0" - }, - "node_modules/@chevrotain/types": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", - "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==", - "license": "Apache-2.0" - }, - "node_modules/@chevrotain/utils": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", - "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==", - "license": "Apache-2.0" - }, - "node_modules/@citation-js/core": { - "version": "0.7.18", - "resolved": "https://registry.npmjs.org/@citation-js/core/-/core-0.7.18.tgz", - "integrity": "sha512-EjLuZWA5156dIFGdF7OnyPyWFBW43B8Ckje6Sn/W2RFxHDu0oACvW4/6TNgWT80jhEA4bVFm7ahrZe9MJ2B2UQ==", - "license": "MIT", - "dependencies": { - "@citation-js/date": "^0.5.0", - "@citation-js/name": "^0.4.2", - "fetch-ponyfill": "^7.1.0", - "sync-fetch": "^0.4.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@citation-js/date": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@citation-js/date/-/date-0.5.1.tgz", - "integrity": "sha512-1iDKAZ4ie48PVhovsOXQ+C6o55dWJloXqtznnnKy6CltJBQLIuLLuUqa8zlIvma0ZigjVjgDUhnVaNU1MErtZw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@citation-js/name": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@citation-js/name/-/name-0.4.2.tgz", - "integrity": "sha512-brSPsjs2fOVzSnARLKu0qncn6suWjHVQtrqSUrnqyaRH95r/Ad4wPF5EsoWr+Dx8HzkCGb/ogmoAzfCsqlTwTQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/@citation-js/plugin-bibtex": { - "version": "0.7.18", - "resolved": "https://registry.npmjs.org/@citation-js/plugin-bibtex/-/plugin-bibtex-0.7.18.tgz", - "integrity": "sha512-TdsZSMpgpfcx2NMPu0KiulEoecllwT5EtRUzAJl2pDsdPD1tUqqbyj/NBi0l8fwNy1r7WwAqSFGiqGPjQWpFdg==", - "license": "MIT", - "dependencies": { - "@citation-js/date": "^0.5.0", - "@citation-js/name": "^0.4.2", - "moo": "^0.5.1" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@citation-js/core": "^0.7.0" - } - }, - "node_modules/@citation-js/plugin-cff": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@citation-js/plugin-cff/-/plugin-cff-0.6.1.tgz", - "integrity": "sha512-tLjTgsfzNOdQWGn5mNc2NAaydHnlRucSERoyAXLN7u0BQBfp7j5zwdxCmxcQD/N7hH3fpDKMG+qDzbqpJuKyNA==", - "license": "MIT", - "dependencies": { - "@citation-js/date": "^0.5.0", - "@citation-js/plugin-yaml": "^0.6.1" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@citation-js/plugin-csl": { - "version": "0.7.18", - "resolved": "https://registry.npmjs.org/@citation-js/plugin-csl/-/plugin-csl-0.7.18.tgz", - "integrity": "sha512-cJcOdEZurmtIxNj0d4cOERHpVQJB/mN3YPSDNqfI/xTFRN3bWDpFAsaqubPtMO2ZPpoDS+ZGIP1kggbwCfMmlA==", - "license": "MIT", - "dependencies": { - "@citation-js/date": "^0.5.0", - "citeproc": "^2.4.6" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "@citation-js/core": "^0.7.0" - } - }, - "node_modules/@citation-js/plugin-github": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@citation-js/plugin-github/-/plugin-github-0.6.1.tgz", - "integrity": "sha512-1ZeSgQ5AoYsa8n2acVooUeRk76oA8rLszYNBjzj5z6MPa11BZlQJ9O+Gy4tHjlImvsENLbLPx5f8/V1VHXaCfQ==", - "license": "MIT", - "dependencies": { - "@citation-js/date": "^0.5.0", - "@citation-js/name": "^0.4.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@citation-js/plugin-npm": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@citation-js/plugin-npm/-/plugin-npm-0.6.1.tgz", - "integrity": "sha512-rojJA+l/p2KBpDoY+8n0YfNyQO1Aw03fQR5BN+gXD1LNAP1V+8wqvdPsaHnzPsrhrd4ZXDR7ch/Nk0yynPkJ3Q==", - "license": "MIT", - "dependencies": { - "@citation-js/date": "^0.5.0", - "@citation-js/name": "^0.4.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@citation-js/plugin-software-formats": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@citation-js/plugin-software-formats/-/plugin-software-formats-0.6.1.tgz", - "integrity": "sha512-BDF9rqi56K0hoTgYTVANCFVRSbWKC9V06Uap7oa8SjqCTgnHJAy8t/F3NxsyYPPG+zmRsLW9VNbcIsJOl0eu/w==", - "license": "MIT", - "dependencies": { - "@citation-js/plugin-cff": "^0.6.1", - "@citation-js/plugin-github": "^0.6.1", - "@citation-js/plugin-npm": "^0.6.1", - "@citation-js/plugin-yaml": "^0.6.1", - "@citation-js/plugin-zenodo": "^0.6.1" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@citation-js/plugin-yaml": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@citation-js/plugin-yaml/-/plugin-yaml-0.6.1.tgz", - "integrity": "sha512-XEVVks1cJTqRbjy+nmthfw/puR6NwRB3fyJWi1tX13UYXlkhP/h45nsv4zjgLLGekdcMHQvhad9MAYunOftGKA==", - "license": "MIT", - "dependencies": { - "js-yaml": "^4.0.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@citation-js/plugin-zenodo": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@citation-js/plugin-zenodo/-/plugin-zenodo-0.6.1.tgz", - "integrity": "sha512-bUybENHoZqJ6gheUqgkumjI+mu+fA2bg6VoniDmZTb7Qng9iEpi+IWEAR26/vBE0gK0EWrJjczyDW3HCwrhvVw==", - "license": "MIT", - "dependencies": { - "@citation-js/date": "^0.5.0", - "@citation-js/name": "^0.4.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-tokenizer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@csstools/media-query-list-parser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", - "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/selector-resolve-nested": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.1.0.tgz", - "integrity": "sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^7.0.0" - } - }, - "node_modules/@csstools/selector-specificity": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^7.0.0" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", - "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", - "license": "MIT", - "engines": { - "node": ">=14.17.0" - } - }, - "node_modules/@dual-bundle/import-meta-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", - "integrity": "sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@emnapi/core": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.5.tgz", - "integrity": "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.0.4", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz", - "integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.4.tgz", - "integrity": "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz", - "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz", - "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz", - "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz", - "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz", - "integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz", - "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz", - "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz", - "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz", - "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz", - "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz", - "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz", - "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz", - "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz", - "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz", - "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz", - "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz", - "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz", - "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz", - "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz", - "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz", - "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz", - "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz", - "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz", - "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz", - "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz", - "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-plugin-eslint-comments": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.5.0.tgz", - "integrity": "sha512-MAhuTKlr4y/CE3WYX26raZjy+I/kS2PLKSzvfmDCGrBLTFHOYwqROZdr4XwPgXwX3K9rjzMr4pSmUWGnzsUyMg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^4.0.0", - "ignore": "^5.2.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@eslint/eslintrc/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@github/browserslist-config": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@github/browserslist-config/-/browserslist-config-1.0.0.tgz", - "integrity": "sha512-gIhjdJp/c2beaIWWIlsXdqXVRUz3r2BxBCpfz/F3JXHvSAQ1paMYjLH+maEATtENg+k5eLV7gA+9yPp762ieuw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@github/combobox-nav": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@github/combobox-nav/-/combobox-nav-2.3.1.tgz", - "integrity": "sha512-gwxPzLw8XKecy1nP63i9lOBritS3bWmxl02UX6G0TwMQZbMem1BCS1tEZgYd3mkrkiDrUMWaX+DbFCuDFo3K+A==", - "license": "MIT" - }, - "node_modules/@github/markdown-toolbar-element": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@github/markdown-toolbar-element/-/markdown-toolbar-element-2.2.3.tgz", - "integrity": "sha512-AlquKGee+IWiAMYVB0xyHFZRMnu4n3X4HTvJHu79GiVJ1ojTukCWyxMlF5NMsecoLcBKsuBhx3QPv2vkE/zQ0A==", - "license": "MIT" - }, - "node_modules/@github/relative-time-element": { - "version": "4.4.8", - "resolved": "https://registry.npmjs.org/@github/relative-time-element/-/relative-time-element-4.4.8.tgz", - "integrity": "sha512-FSLYm6F3TSQnqHE1EMQUVVgi2XjbCvsESwwXfugHFpBnhyF1uhJOtu0Psp/BB/qqazfdkk7f5fVcu7WuXl3t8Q==", - "license": "MIT" - }, - "node_modules/@github/text-expander-element": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@github/text-expander-element/-/text-expander-element-2.9.2.tgz", - "integrity": "sha512-XY8EUMqM4GAloNxXNA1Py1ny+engWwYntbgsnpstQN4piaTI9rIlfYldyd0nnPXhxjGCVqHPmP6yg17Q0/n9Vg==", - "license": "MIT", - "dependencies": { - "@github/combobox-nav": "^2.0.2", - "dom-input-range": "^2.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@iconify/types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", - "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", - "license": "MIT" - }, - "node_modules/@iconify/utils": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.3.0.tgz", - "integrity": "sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==", - "license": "MIT", - "dependencies": { - "@antfu/install-pkg": "^1.0.0", - "@antfu/utils": "^8.1.0", - "@iconify/types": "^2.0.0", - "debug": "^4.4.0", - "globals": "^15.14.0", - "kolorist": "^1.8.0", - "local-pkg": "^1.0.0", - "mlly": "^1.7.4" - } - }, - "node_modules/@iconify/utils/node_modules/globals": { - "version": "15.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", - "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", - "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.10.tgz", - "integrity": "sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", - "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.29", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", - "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@jsep-plugin/assignment": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.3.0.tgz", - "integrity": "sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.16.0" - }, - "peerDependencies": { - "jsep": "^0.4.0||^1.0.0" - } - }, - "node_modules/@jsep-plugin/regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.4.tgz", - "integrity": "sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.16.0" - }, - "peerDependencies": { - "jsep": "^0.4.0||^1.0.0" - } - }, - "node_modules/@jsep-plugin/ternary": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@jsep-plugin/ternary/-/ternary-1.1.4.tgz", - "integrity": "sha512-ck5wiqIbqdMX6WRQztBL7ASDty9YLgJ3sSAK5ZpBzXeySvFGCzIvM6UiAI4hTZ22fEcYQVV/zhUbNscggW+Ukg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.16.0" - }, - "peerDependencies": { - "jsep": "^0.4.0||^1.0.0" - } - }, - "node_modules/@keyv/serialize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.0.tgz", - "integrity": "sha512-RlDgexML7Z63Q8BSaqhXdCYNBy/JQnqYIwxofUrNLGCblOMHp+xux2Q8nLMLlPpgHQPoU0Do8Z6btCpRBEqZ8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@kurkle/color": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", - "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", - "license": "MIT" - }, - "node_modules/@mcaptcha/core-glue": { - "version": "0.1.0-alpha-5", - "resolved": "https://registry.npmjs.org/@mcaptcha/core-glue/-/core-glue-0.1.0-alpha-5.tgz", - "integrity": "sha512-16qWm5O5X0Y9LXULULaAks8Vf9FNlUUBcR5KDt49aWhFhG5++JzxNmCwQM9EJSHNU7y0U+FdyAWcGmjfKlkRLA==", - "funding": [ - { - "type": "individual", - "url": "http://mcaptcha.org/donate" - }, - { - "type": "liberapay", - "url": "https://liberapay.com/mcaptcha" - }, - { - "type": "individual", - "url": "http://batsense.net/donate" - }, - { - "type": "liberapay", - "url": "https://liberapay.com/realaravinth" - } - ], - "license": "(MIT OR Apache-2.0)" - }, - "node_modules/@mcaptcha/vanilla-glue": { - "version": "0.1.0-alpha-3", - "resolved": "https://registry.npmjs.org/@mcaptcha/vanilla-glue/-/vanilla-glue-0.1.0-alpha-3.tgz", - "integrity": "sha512-GT6TJBgmViGXcXiT5VOr+h/6iOnThSlZuCoOWncubyTZU9R3cgU5vWPkF7G6Ob6ee2CBe3yqBxxk24CFVGTVXw==", - "funding": [ - { - "type": "individual", - "url": "http://mcaptcha.org/donate" - }, - { - "type": "liberapay", - "url": "https://liberapay.com/mcaptcha" - }, - { - "type": "individual", - "url": "http://batsense.net/donate" - }, - { - "type": "liberapay", - "url": "https://liberapay.com/realaravinth" - } - ], - "license": "(MIT OR Apache-2.0)", - "dependencies": { - "@mcaptcha/core-glue": "^0.1.0-alpha-5" - } - }, - "node_modules/@mermaid-js/parser": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.6.2.tgz", - "integrity": "sha512-+PO02uGF6L6Cs0Bw8RpGhikVvMWEysfAyl27qTlroUB8jSWr1lL0Sf6zi78ZxlSnmgSY2AMMKVgghnN9jTtwkQ==", - "license": "MIT", - "dependencies": { - "langium": "3.3.1" - } - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", - "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nolyfill/shared": { - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/@nolyfill/shared/-/shared-1.0.44.tgz", - "integrity": "sha512-NI1zxDh4LYL7PYlKKCwojjuc5CEZslywrOTKBNyodjmWjRiZ4AlCMs3Gp+zDoPQPNkYCSQp/luNojHmJWWfCbw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@pkgr/core": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/pkgr" - } - }, - "node_modules/@playwright/test": { - "version": "1.54.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.54.1.tgz", - "integrity": "sha512-FS8hQ12acieG2dYSksmLOF7BNxnVf2afRJdCuM1eMSxj6QTSE6G4InGF7oApGgDb65MX7AwMVlIkpru0yZA4Xw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "playwright": "1.54.1" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@popperjs/core": { - "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" - } - }, - "node_modules/@primer/octicons": { - "version": "19.15.5", - "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-19.15.5.tgz", - "integrity": "sha512-FCXPTlXlHvAS3rRBd1C/xVBYSYzPPwS8tNcUxnvUYK6L4/d+zUy2KExLtzW+L9xKo2z8J9uY+c1VCsNRf+b4MQ==", - "license": "MIT", - "dependencies": { - "object-assign": "^4.1.1" - } - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.29", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.29.tgz", - "integrity": "sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/plugin-commonjs": { - "version": "22.0.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.2.tgz", - "integrity": "sha512-//NdP6iIwPbMTcazYsiBMbJW7gfmpHom33u1beiIoHDEM0Q9clvtQB1T0efvMqHeKsGohiHo97BCPCkBXdscwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "commondir": "^1.0.1", - "estree-walker": "^2.0.1", - "glob": "^7.1.6", - "is-reference": "^1.2.1", - "magic-string": "^0.25.7", - "resolve": "^1.17.0" - }, - "engines": { - "node": ">= 12.0.0" - }, - "peerDependencies": { - "rollup": "^2.68.0" - } - }, - "node_modules/@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" - } - }, - "node_modules/@rollup/pluginutils/node_modules/estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.2.tgz", - "integrity": "sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.2.tgz", - "integrity": "sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.2.tgz", - "integrity": "sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.2.tgz", - "integrity": "sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.2.tgz", - "integrity": "sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.2.tgz", - "integrity": "sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.2.tgz", - "integrity": "sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.2.tgz", - "integrity": "sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.2.tgz", - "integrity": "sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.2.tgz", - "integrity": "sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.2.tgz", - "integrity": "sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.2.tgz", - "integrity": "sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.2.tgz", - "integrity": "sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.2.tgz", - "integrity": "sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.2.tgz", - "integrity": "sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.2.tgz", - "integrity": "sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.2.tgz", - "integrity": "sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.2.tgz", - "integrity": "sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.2.tgz", - "integrity": "sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.2.tgz", - "integrity": "sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@scarf/scarf": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz", - "integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==", - "hasInstallScript": true, - "license": "Apache-2.0" - }, - "node_modules/@silverwind/vue3-calendar-heatmap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@silverwind/vue3-calendar-heatmap/-/vue3-calendar-heatmap-2.0.6.tgz", - "integrity": "sha512-efX+nf2GR7EfA7iNgZDeM9Jue5ksglSXvN0C/ja0M1bTmkCpAxKlGJ3vki7wfTPQgX1O0nCfAM62IKqUUEM0cQ==", - "license": "MIT", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "tippy.js": "^6.3.7", - "vue": "^3.2.29" - } - }, - "node_modules/@simonwep/pickr": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@simonwep/pickr/-/pickr-1.9.0.tgz", - "integrity": "sha512-oEYvv15PyfZzjoAzvXYt3UyNGwzsrpFxLaZKzkOSd0WYBVwLd19iJerePDONxC1iF6+DpcswPdLIM2KzCJuYFg==", - "license": "MIT", - "dependencies": { - "core-js": "3.32.2", - "nanopop": "2.3.0" - } - }, - "node_modules/@stoplight/better-ajv-errors": { - "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, - "license": "Apache-2.0", - "dependencies": { - "jsonpointer": "^5.0.0", - "leven": "^3.1.0" - }, - "engines": { - "node": "^12.20 || >= 14.13" - }, - "peerDependencies": { - "ajv": ">=8" - } - }, - "node_modules/@stoplight/json": { - "version": "3.21.7", - "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.21.7.tgz", - "integrity": "sha512-xcJXgKFqv/uCEgtGlPxy3tPA+4I+ZI4vAuMJ885+ThkTHFVkC+0Fm58lA9NlsyjnkpxFh4YiQWpH+KefHdbA0A==", - "dev": true, - "license": "Apache-2.0", - "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/json-ref-readers": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@stoplight/json-ref-readers/-/json-ref-readers-1.2.2.tgz", - "integrity": "sha512-nty0tHUq2f1IKuFYsLM4CXLZGHdMn+X/IwEUIpeSOXt0QjMUbL0Em57iJUDzz+2MkWG83smIigNZ3fauGjqgdQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "node-fetch": "^2.6.0", - "tslib": "^1.14.1" - }, - "engines": { - "node": ">=8.3.0" - } - }, - "node_modules/@stoplight/json-ref-readers/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "license": "0BSD" - }, - "node_modules/@stoplight/json-ref-resolver": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@stoplight/json-ref-resolver/-/json-ref-resolver-3.1.6.tgz", - "integrity": "sha512-YNcWv3R3n3U6iQYBsFOiWSuRGE5su1tJSiX6pAPRVk7dP0L7lqCteXGzuVRQ0gMZqUl8v1P0+fAKxF6PLo9B5A==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@stoplight/json": "^3.21.0", - "@stoplight/path": "^1.3.2", - "@stoplight/types": "^12.3.0 || ^13.0.0", - "@types/urijs": "^1.19.19", - "dependency-graph": "~0.11.0", - "fast-memoize": "^2.5.2", - "immer": "^9.0.6", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "urijs": "^1.19.11" - }, - "engines": { - "node": ">=8.3.0" - } - }, - "node_modules/@stoplight/ordered-object-literal": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@stoplight/ordered-object-literal/-/ordered-object-literal-1.0.5.tgz", - "integrity": "sha512-COTiuCU5bgMUtbIFBuyyh2/yVVzlr5Om0v5utQDgBCuQUOPgU1DwoffkTfg4UBQOvByi5foF4w4T+H9CoRe5wg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/@stoplight/path": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@stoplight/path/-/path-1.3.2.tgz", - "integrity": "sha512-lyIc6JUlUA8Ve5ELywPC8I2Sdnh1zc1zmbYgVarhXIp9YeAB0ReeqmGEOWNtlHkbP2DAA1AL65Wfn2ncjK/jtQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/@stoplight/spectral-cli": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.15.0.tgz", - "integrity": "sha512-FVeQIuqQQnnLfa8vy+oatTKUve7uU+3SaaAfdjpX/B+uB1NcfkKRJYhKT9wMEehDRaMPL5AKIRYMCFerdEbIpw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@stoplight/json": "~3.21.0", - "@stoplight/path": "1.3.2", - "@stoplight/spectral-core": "^1.19.5", - "@stoplight/spectral-formatters": "^1.4.1", - "@stoplight/spectral-parsers": "^1.0.4", - "@stoplight/spectral-ref-resolver": "^1.0.4", - "@stoplight/spectral-ruleset-bundler": "^1.6.0", - "@stoplight/spectral-ruleset-migrator": "^1.11.0", - "@stoplight/spectral-rulesets": ">=1", - "@stoplight/spectral-runtime": "^1.1.2", - "@stoplight/types": "^13.6.0", - "chalk": "4.1.2", - "fast-glob": "~3.2.12", - "hpagent": "~1.2.0", - "lodash": "~4.17.21", - "pony-cause": "^1.1.1", - "stacktracey": "^2.1.8", - "tslib": "^2.8.1", - "yargs": "~17.7.2" - }, - "bin": { - "spectral": "dist/index.js" - }, - "engines": { - "node": "^16.20 || ^18.18 || >= 20.17" - } - }, - "node_modules/@stoplight/spectral-cli/node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/@stoplight/spectral-cli/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@stoplight/spectral-core": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.20.0.tgz", - "integrity": "sha512-5hBP81nCC1zn1hJXL/uxPNRKNcB+/pEIHgCjPRpl/w/qy9yC9ver04tw1W0l/PMiv0UeB5dYgozXVQ4j5a6QQQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@stoplight/better-ajv-errors": "1.0.3", - "@stoplight/json": "~3.21.0", - "@stoplight/path": "1.3.2", - "@stoplight/spectral-parsers": "^1.0.0", - "@stoplight/spectral-ref-resolver": "^1.0.4", - "@stoplight/spectral-runtime": "^1.1.2", - "@stoplight/types": "~13.6.0", - "@types/es-aggregate-error": "^1.0.2", - "@types/json-schema": "^7.0.11", - "ajv": "^8.17.1", - "ajv-errors": "~3.0.0", - "ajv-formats": "~2.1.1", - "es-aggregate-error": "^1.0.7", - "jsonpath-plus": "^10.3.0", - "lodash": "~4.17.21", - "lodash.topath": "^4.5.2", - "minimatch": "3.1.2", - "nimma": "0.2.3", - "pony-cause": "^1.1.1", - "simple-eval": "1.0.1", - "tslib": "^2.8.1" - }, - "engines": { - "node": "^16.20 || ^18.18 || >= 20.17" - } - }, - "node_modules/@stoplight/spectral-core/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, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.4", - "utility-types": "^3.10.0" - }, - "engines": { - "node": "^12.20 || >=14.13" - } - }, - "node_modules/@stoplight/spectral-core/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@stoplight/spectral-formats": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-formats/-/spectral-formats-1.8.2.tgz", - "integrity": "sha512-c06HB+rOKfe7tuxg0IdKDEA5XnjL2vrn/m/OVIIxtINtBzphZrOgtRn7epQ5bQF5SWp84Ue7UJWaGgDwVngMFw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@stoplight/json": "^3.17.0", - "@stoplight/spectral-core": "^1.19.2", - "@types/json-schema": "^7.0.7", - "tslib": "^2.8.1" - }, - "engines": { - "node": "^16.20 || ^18.18 || >= 20.17" - } - }, - "node_modules/@stoplight/spectral-formatters": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-formatters/-/spectral-formatters-1.5.0.tgz", - "integrity": "sha512-lR7s41Z00Mf8TdXBBZQ3oi2uR8wqAtR6NO0KA8Ltk4FSpmAy0i6CKUmJG9hZQjanTnGmwpQkT/WP66p1GY3iXA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@stoplight/path": "^1.3.2", - "@stoplight/spectral-core": "^1.19.4", - "@stoplight/spectral-runtime": "^1.1.2", - "@stoplight/types": "^13.15.0", - "@types/markdown-escape": "^1.1.3", - "chalk": "4.1.2", - "cliui": "7.0.4", - "lodash": "^4.17.21", - "markdown-escape": "^2.0.0", - "node-sarif-builder": "^2.0.3", - "strip-ansi": "6.0", - "text-table": "^0.2.0", - "tslib": "^2.8.1" - }, - "engines": { - "node": "^16.20 || ^18.18 || >= 20.17" - } - }, - "node_modules/@stoplight/spectral-functions": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.10.1.tgz", - "integrity": "sha512-obu8ZfoHxELOapfGsCJixKZXZcffjg+lSoNuttpmUFuDzVLT3VmH8QkPXfOGOL5Pz80BR35ClNAToDkdnYIURg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@stoplight/better-ajv-errors": "1.0.3", - "@stoplight/json": "^3.17.1", - "@stoplight/spectral-core": "^1.19.4", - "@stoplight/spectral-formats": "^1.8.1", - "@stoplight/spectral-runtime": "^1.1.2", - "ajv": "^8.17.1", - "ajv-draft-04": "~1.0.0", - "ajv-errors": "~3.0.0", - "ajv-formats": "~2.1.1", - "lodash": "~4.17.21", - "tslib": "^2.8.1" - }, - "engines": { - "node": "^16.20 || ^18.18 || >= 20.17" - } - }, - "node_modules/@stoplight/spectral-parsers": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-parsers/-/spectral-parsers-1.0.5.tgz", - "integrity": "sha512-ANDTp2IHWGvsQDAY85/jQi9ZrF4mRrA5bciNHX+PUxPr4DwS6iv4h+FVWJMVwcEYdpyoIdyL+SRmHdJfQEPmwQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@stoplight/json": "~3.21.0", - "@stoplight/types": "^14.1.1", - "@stoplight/yaml": "~4.3.0", - "tslib": "^2.8.1" - }, - "engines": { - "node": "^16.20 || ^18.18 || >= 20.17" - } - }, - "node_modules/@stoplight/spectral-parsers/node_modules/@stoplight/types": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-14.1.1.tgz", - "integrity": "sha512-/kjtr+0t0tjKr+heVfviO9FrU/uGLc+QNX3fHJc19xsCNYqU7lVhaXxDmEID9BZTjG+/r9pK9xP/xU02XGg65g==", - "dev": true, - "license": "Apache-2.0", - "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.5", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-ref-resolver/-/spectral-ref-resolver-1.0.5.tgz", - "integrity": "sha512-gj3TieX5a9zMW29z3mBlAtDOCgN3GEc1VgZnCVlr5irmR4Qi5LuECuFItAq4pTn5Zu+sW5bqutsCH7D4PkpyAA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@stoplight/json-ref-readers": "1.2.2", - "@stoplight/json-ref-resolver": "~3.1.6", - "@stoplight/spectral-runtime": "^1.1.2", - "dependency-graph": "0.11.0", - "tslib": "^2.8.1" - }, - "engines": { - "node": "^16.20 || ^18.18 || >= 20.17" - } - }, - "node_modules/@stoplight/spectral-ruleset-bundler": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-bundler/-/spectral-ruleset-bundler-1.6.3.tgz", - "integrity": "sha512-AQFRO6OCKg8SZJUupnr3+OzI1LrMieDTEUHsYgmaRpNiDRPvzImE3bzM1KyQg99q58kTQyZ8kpr7sG8Lp94RRA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@rollup/plugin-commonjs": "~22.0.2", - "@stoplight/path": "1.3.2", - "@stoplight/spectral-core": ">=1", - "@stoplight/spectral-formats": "^1.8.1", - "@stoplight/spectral-functions": ">=1", - "@stoplight/spectral-parsers": ">=1", - "@stoplight/spectral-ref-resolver": "^1.0.4", - "@stoplight/spectral-ruleset-migrator": "^1.9.6", - "@stoplight/spectral-rulesets": ">=1", - "@stoplight/spectral-runtime": "^1.1.2", - "@stoplight/types": "^13.6.0", - "@types/node": "*", - "pony-cause": "1.1.1", - "rollup": "~2.79.2", - "tslib": "^2.8.1", - "validate-npm-package-name": "3.0.0" - }, - "engines": { - "node": "^16.20 || ^18.18 || >= 20.17" - } - }, - "node_modules/@stoplight/spectral-ruleset-migrator": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-migrator/-/spectral-ruleset-migrator-1.11.2.tgz", - "integrity": "sha512-6r5i4hrDmppspSSxdUKKNHc07NGSSIkvwKNk3M5ukCwvSslImvDEimeWAhPBryhmSJ82YAsKr8erZZpKullxWw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@stoplight/json": "~3.21.0", - "@stoplight/ordered-object-literal": "~1.0.4", - "@stoplight/path": "1.3.2", - "@stoplight/spectral-functions": "^1.9.1", - "@stoplight/spectral-runtime": "^1.1.2", - "@stoplight/types": "^13.6.0", - "@stoplight/yaml": "~4.2.3", - "@types/node": "*", - "ajv": "^8.17.1", - "ast-types": "0.14.2", - "astring": "^1.9.0", - "reserved": "0.1.2", - "tslib": "^2.8.1", - "validate-npm-package-name": "3.0.0" - }, - "engines": { - "node": "^16.20 || ^18.18 || >= 20.17" - } - }, - "node_modules/@stoplight/spectral-ruleset-migrator/node_modules/@stoplight/yaml": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/@stoplight/yaml/-/yaml-4.2.3.tgz", - "integrity": "sha512-Mx01wjRAR9C7yLMUyYFTfbUf5DimEpHMkRDQ1PKLe9dfNILbgdxyrncsOXM3vCpsQ1Hfj4bPiGl+u4u6e9Akqw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@stoplight/ordered-object-literal": "^1.0.1", - "@stoplight/types": "^13.0.0", - "@stoplight/yaml-ast-parser": "0.0.48", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=10.8" - } - }, - "node_modules/@stoplight/spectral-ruleset-migrator/node_modules/@stoplight/yaml-ast-parser": { - "version": "0.0.48", - "resolved": "https://registry.npmjs.org/@stoplight/yaml-ast-parser/-/yaml-ast-parser-0.0.48.tgz", - "integrity": "sha512-sV+51I7WYnLJnKPn2EMWgS4EUfoP4iWEbrWwbXsj0MZCB/xOK8j6+C9fntIdOM50kpx45ZLC3s6kwKivWuqvyg==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/@stoplight/spectral-rulesets": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.22.0.tgz", - "integrity": "sha512-l2EY2jiKKLsvnPfGy+pXC0LeGsbJzcQP5G/AojHgf+cwN//VYxW1Wvv4WKFx/CLmLxc42mJYF2juwWofjWYNIQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@asyncapi/specs": "^6.8.0", - "@stoplight/better-ajv-errors": "1.0.3", - "@stoplight/json": "^3.17.0", - "@stoplight/spectral-core": "^1.19.4", - "@stoplight/spectral-formats": "^1.8.1", - "@stoplight/spectral-functions": "^1.9.1", - "@stoplight/spectral-runtime": "^1.1.2", - "@stoplight/types": "^13.6.0", - "@types/json-schema": "^7.0.7", - "ajv": "^8.17.1", - "ajv-formats": "~2.1.1", - "json-schema-traverse": "^1.0.0", - "leven": "3.1.0", - "lodash": "~4.17.21", - "tslib": "^2.8.1" - }, - "engines": { - "node": "^16.20 || ^18.18 || >= 20.17" - } - }, - "node_modules/@stoplight/spectral-runtime": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-runtime/-/spectral-runtime-1.1.4.tgz", - "integrity": "sha512-YHbhX3dqW0do6DhiPSgSGQzr6yQLlWybhKwWx0cqxjMwxej3TqLv3BXMfIUYFKKUqIwH4Q2mV8rrMM8qD2N0rQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@stoplight/json": "^3.20.1", - "@stoplight/path": "^1.3.2", - "@stoplight/types": "^13.6.0", - "abort-controller": "^3.0.0", - "lodash": "^4.17.21", - "node-fetch": "^2.7.0", - "tslib": "^2.8.1" - }, - "engines": { - "node": "^16.20 || ^18.18 || >= 20.17" - } - }, - "node_modules/@stoplight/types": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.20.0.tgz", - "integrity": "sha512-2FNTv05If7ib79VPDA/r9eUet76jewXFH2y2K5vuge6SXbRHtWBhcaRmu+6QpF4/WRNoJj5XYRSwLGXDxysBGA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.4", - "utility-types": "^3.10.0" - }, - "engines": { - "node": "^12.20 || >=14.13" - } - }, - "node_modules/@stoplight/yaml": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@stoplight/yaml/-/yaml-4.3.0.tgz", - "integrity": "sha512-JZlVFE6/dYpP9tQmV0/ADfn32L9uFarHWxfcRhReKUnljz1ZiUM5zpX+PH8h5CJs6lao3TuFqnPm9IJJCEkE2w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@stoplight/ordered-object-literal": "^1.0.5", - "@stoplight/types": "^14.1.1", - "@stoplight/yaml-ast-parser": "0.0.50", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=10.8" - } - }, - "node_modules/@stoplight/yaml-ast-parser": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@stoplight/yaml-ast-parser/-/yaml-ast-parser-0.0.50.tgz", - "integrity": "sha512-Pb6M8TDO9DtSVla9yXSTAxmo9GVEouq5P40DWXdOie69bXogZTkgvopCq+yEvTMA0F6PEvdJmbtTV3ccIp11VQ==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/@stoplight/yaml/node_modules/@stoplight/types": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-14.1.1.tgz", - "integrity": "sha512-/kjtr+0t0tjKr+heVfviO9FrU/uGLc+QNX3fHJc19xsCNYqU7lVhaXxDmEID9BZTjG+/r9pK9xP/xU02XGg65g==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.4", - "utility-types": "^3.10.0" - }, - "engines": { - "node": "^12.20 || >=14.13" - } - }, - "node_modules/@stylistic/eslint-plugin-js": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-3.1.0.tgz", - "integrity": "sha512-lQktsOiCr8S6StG29C5fzXYxLOD6ID1rp4j6TRS+E/qY1xd59Fm7dy5qm9UauJIEoSTlYx6yGsCHYh5UkgXPyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/@stylistic/stylelint-plugin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-4.0.0.tgz", - "integrity": "sha512-CFwt3K4Y/7bygNCLCQ8Sy4Hzgbhxq3BsNW0FIuYxl17HD3ywptm54ocyeiLVRrk5jtz1Zwks7Xr9eiZt8SWHAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/media-query-list-parser": "^4.0.3", - "postcss": "^8.5.6", - "postcss-selector-parser": "^7.1.0", - "postcss-value-parser": "^4.2.0", - "style-search": "^0.1.0" - }, - "engines": { - "node": "^18.12 || >=20.9" - }, - "peerDependencies": { - "stylelint": "^16.22.0" - } - }, - "node_modules/@swc/helpers": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.2.14.tgz", - "integrity": "sha512-wpCQMhf5p5GhNg2MmGKXzUNwxe7zRiCsmqYsamez2beP7mKPCSiu+BjZcdN95yYSzO857kr0VfQewmGpS77nqA==", - "license": "MIT" - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", - "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/chai": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", - "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/deep-eql": "*" - } - }, - "node_modules/@types/codemirror": { - "version": "5.60.16", - "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.16.tgz", - "integrity": "sha512-V/yHdamffSS075jit+fDxaOAmdP2liok8NSNJnAZfDJErzOheuygHZEhAJrfmk5TEyM32MhkZjwo/idX791yxw==", - "license": "MIT", - "dependencies": { - "@types/tern": "*" - } - }, - "node_modules/@types/d3": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", - "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", - "license": "MIT", - "dependencies": { - "@types/d3-array": "*", - "@types/d3-axis": "*", - "@types/d3-brush": "*", - "@types/d3-chord": "*", - "@types/d3-color": "*", - "@types/d3-contour": "*", - "@types/d3-delaunay": "*", - "@types/d3-dispatch": "*", - "@types/d3-drag": "*", - "@types/d3-dsv": "*", - "@types/d3-ease": "*", - "@types/d3-fetch": "*", - "@types/d3-force": "*", - "@types/d3-format": "*", - "@types/d3-geo": "*", - "@types/d3-hierarchy": "*", - "@types/d3-interpolate": "*", - "@types/d3-path": "*", - "@types/d3-polygon": "*", - "@types/d3-quadtree": "*", - "@types/d3-random": "*", - "@types/d3-scale": "*", - "@types/d3-scale-chromatic": "*", - "@types/d3-selection": "*", - "@types/d3-shape": "*", - "@types/d3-time": "*", - "@types/d3-time-format": "*", - "@types/d3-timer": "*", - "@types/d3-transition": "*", - "@types/d3-zoom": "*" - } - }, - "node_modules/@types/d3-array": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", - "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", - "license": "MIT" - }, - "node_modules/@types/d3-axis": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", - "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", - "license": "MIT", - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-brush": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", - "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", - "license": "MIT", - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-chord": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", - "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", - "license": "MIT" - }, - "node_modules/@types/d3-color": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", - "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", - "license": "MIT" - }, - "node_modules/@types/d3-contour": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", - "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", - "license": "MIT", - "dependencies": { - "@types/d3-array": "*", - "@types/geojson": "*" - } - }, - "node_modules/@types/d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", - "license": "MIT" - }, - "node_modules/@types/d3-dispatch": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz", - "integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==", - "license": "MIT" - }, - "node_modules/@types/d3-drag": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", - "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", - "license": "MIT", - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-dsv": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", - "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", - "license": "MIT" - }, - "node_modules/@types/d3-ease": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", - "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", - "license": "MIT" - }, - "node_modules/@types/d3-fetch": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", - "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", - "license": "MIT", - "dependencies": { - "@types/d3-dsv": "*" - } - }, - "node_modules/@types/d3-force": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", - "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", - "license": "MIT" - }, - "node_modules/@types/d3-format": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", - "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", - "license": "MIT" - }, - "node_modules/@types/d3-geo": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", - "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", - "license": "MIT", - "dependencies": { - "@types/geojson": "*" - } - }, - "node_modules/@types/d3-hierarchy": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", - "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", - "license": "MIT" - }, - "node_modules/@types/d3-interpolate": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", - "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", - "license": "MIT", - "dependencies": { - "@types/d3-color": "*" - } - }, - "node_modules/@types/d3-path": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", - "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", - "license": "MIT" - }, - "node_modules/@types/d3-polygon": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", - "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", - "license": "MIT" - }, - "node_modules/@types/d3-quadtree": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", - "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", - "license": "MIT" - }, - "node_modules/@types/d3-random": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", - "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", - "license": "MIT" - }, - "node_modules/@types/d3-scale": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", - "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", - "license": "MIT", - "dependencies": { - "@types/d3-time": "*" - } - }, - "node_modules/@types/d3-scale-chromatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", - "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", - "license": "MIT" - }, - "node_modules/@types/d3-selection": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", - "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", - "license": "MIT" - }, - "node_modules/@types/d3-shape": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", - "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", - "license": "MIT", - "dependencies": { - "@types/d3-path": "*" - } - }, - "node_modules/@types/d3-time": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", - "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", - "license": "MIT" - }, - "node_modules/@types/d3-time-format": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", - "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", - "license": "MIT" - }, - "node_modules/@types/d3-timer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", - "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", - "license": "MIT" - }, - "node_modules/@types/d3-transition": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", - "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", - "license": "MIT", - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-zoom": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", - "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", - "license": "MIT", - "dependencies": { - "@types/d3-interpolate": "*", - "@types/d3-selection": "*" - } - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/dropzone": { - "version": "5.7.9", - "resolved": "https://registry.npmjs.org/@types/dropzone/-/dropzone-5.7.9.tgz", - "integrity": "sha512-c6IlUz+DeQ4gANzJKn8fdP5rO6UyDNOyWLjfPbDRUHCNsXaAVKQOpuOv6LWEyvaK7pLqmoIpvSIlvBgGsk1vGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/jquery": "*" - } - }, - "node_modules/@types/es-aggregate-error": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/es-aggregate-error/-/es-aggregate-error-1.0.6.tgz", - "integrity": "sha512-qJ7LIFp06h1QE1aVxbVd+zJP2wdaugYXYfd6JxsyRMrYHaxb6itXPogW2tz+ylUJ1n1b+JF1PHyYCfYHm0dvUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/eslint": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "license": "MIT", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "license": "MIT" - }, - "node_modules/@types/geojson": { - "version": "7946.0.16", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", - "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", - "license": "MIT" - }, - "node_modules/@types/hammerjs": { - "version": "2.0.46", - "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.46.tgz", - "integrity": "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==", - "license": "MIT" - }, - "node_modules/@types/jquery": { - "version": "3.5.32", - "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.32.tgz", - "integrity": "sha512-b9Xbf4CkMqS02YH8zACqN1xzdxc3cO735Qe5AbSUFmyOiaWAbcpqh9Wna+Uk0vgACvoQHpWDg2rGdHkYPLmCiQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/sizzle": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT" - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/katex": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", - "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/license-checker-webpack-plugin": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@types/license-checker-webpack-plugin/-/license-checker-webpack-plugin-0.2.5.tgz", - "integrity": "sha512-raj3YPZxjkDlRrJJUq6So+C9i/fqYxUtVZzlXxm6bwwXONOnTHvGCfYmbQhzsHJneiJdlR6mMH76/bvWbZZN8Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/webpack": "^4" - } - }, - "node_modules/@types/markdown-escape": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@types/markdown-escape/-/markdown-escape-1.1.3.tgz", - "integrity": "sha512-JIc1+s3y5ujKnt/+N+wq6s/QdL2qZ11fP79MijrVXsAAnzSxCbT2j/3prHRouJdZ2yFLN3vkP0HytfnoCczjOw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/marked": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.3.2.tgz", - "integrity": "sha512-a79Yc3TOk6dGdituy8hmTTJXjOkZ7zsFYV10L337ttq/rec8lRMDBpV7fL3uLx6TgbFCa5DU/h8FmIBQPSbU0w==", - "license": "MIT" - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz", - "integrity": "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==", - "license": "MIT", - "dependencies": { - "undici-types": "~7.8.0" - } - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/pdfobject": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/@types/pdfobject/-/pdfobject-2.2.5.tgz", - "integrity": "sha512-7gD5tqc/RUDq0PyoLemL0vEHxBYi+zY0WVaFAx/Y0jBsXFgot1vB9No1GhDZGwRGJMCIZbgAb74QG9MTyTNU/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/sarif": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@types/sarif/-/sarif-2.1.7.tgz", - "integrity": "sha512-kRz0VEkJqWLf1LLVN4pT1cg1Z9wAuvI6L97V3m2f5B76Tg8d413ddvLBPTEHAZJlnn4XSvu0FkZtViCQGVyrXQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/sizzle": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.9.tgz", - "integrity": "sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/sortablejs": { - "version": "1.15.8", - "resolved": "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.15.8.tgz", - "integrity": "sha512-b79830lW+RZfwaztgs1aVPgbasJ8e7AXtZYHTELNXZPsERt4ymJdjV4OccDbHQAvHrCcFpbF78jkm0R6h/pZVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/source-list-map": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.6.tgz", - "integrity": "sha512-5JcVt1u5HDmlXkwOD2nslZVllBBc7HDuOICfiZah2Z0is8M8g+ddAEawbmd3VjedfDHBzxCaXLs07QEmb7y54g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/swagger-ui-dist": { - "version": "3.30.6", - "resolved": "https://registry.npmjs.org/@types/swagger-ui-dist/-/swagger-ui-dist-3.30.6.tgz", - "integrity": "sha512-FVxN7wjLYRtJsZBscOcOcf8oR++m38vbUFjT33Mr9HBuasX9bRDrJsp7iwixcOtKSHEEa2B7o2+4wEiXqC+Ebw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/tapable": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.12.tgz", - "integrity": "sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/tern": { - "version": "0.23.9", - "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz", - "integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==", - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/throttle-debounce": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@types/throttle-debounce/-/throttle-debounce-5.0.2.tgz", - "integrity": "sha512-pDzSNulqooSKvSNcksnV72nk8p7gRqN8As71Sp28nov1IgmPKWbOEIwAWvBME5pPTtaXJAvG3O4oc76HlQ4kqQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/tinycolor2": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/@types/tinycolor2/-/tinycolor2-1.4.6.tgz", - "integrity": "sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/toastify-js": { - "version": "1.12.4", - "resolved": "https://registry.npmjs.org/@types/toastify-js/-/toastify-js-1.12.4.tgz", - "integrity": "sha512-zfZHU4tKffPCnZRe7pjv/eFKzTVHozKewFCKaCjZ4gFinKgJRz/t0bkZiMCXJxPhv/ZoeDGNOeRD09R0kQZ/nw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", - "license": "MIT", - "optional": true - }, - "node_modules/@types/uglify-js": { - "version": "3.17.5", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.17.5.tgz", - "integrity": "sha512-TU+fZFBTBcXj/GpDpDaBmgWk/gn96kMZ+uocaFUlV2f8a6WdMzzI44QBCmGcCiYR0Y6ZlNRiyUyKKt5nl/lbzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "source-map": "^0.6.1" - } - }, - "node_modules/@types/unist": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/urijs": { - "version": "1.19.25", - "resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.25.tgz", - "integrity": "sha512-XOfUup9r3Y06nFAZh3WvO0rBU4OtlfPB/vgxpjg+NRdGU6CN6djdc6OEiH+PcqHCY6eFLo9Ista73uarf4gnBg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/webpack": { - "version": "4.41.40", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.40.tgz", - "integrity": "sha512-u6kMFSBM9HcoTpUXnL6mt2HSzftqb3JgYV6oxIgL2dl6sX6aCa5k6SOkzv5DuZjBTPUE/dJltKtwwuqrkZHpfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/tapable": "^1", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "anymatch": "^3.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/@types/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-4nZOdMwSPHZ4pTEZzSp0AsTM4K7Qmu40UKW4tJDiOVs20UzYF9l+qUe4s0ftfN0pin06n+5cWWDJXH+sbhAiDw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.7.3" - } - }, - "node_modules/@types/webpack-sources/node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 12" - } - }, - "node_modules/@types/whatwg-mimetype": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/whatwg-mimetype/-/whatwg-mimetype-3.0.2.tgz", - "integrity": "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.38.0.tgz", - "integrity": "sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.38.0", - "@typescript-eslint/type-utils": "8.38.0", - "@typescript-eslint/utils": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.38.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.38.0.tgz", - "integrity": "sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.38.0", - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.38.0.tgz", - "integrity": "sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.38.0", - "@typescript-eslint/types": "^8.38.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.38.0.tgz", - "integrity": "sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz", - "integrity": "sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.38.0.tgz", - "integrity": "sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0", - "@typescript-eslint/utils": "8.38.0", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.38.0.tgz", - "integrity": "sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz", - "integrity": "sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.38.0", - "@typescript-eslint/tsconfig-utils": "8.38.0", - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.38.0.tgz", - "integrity": "sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.38.0", - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz", - "integrity": "sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.38.0", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "dev": true, - "license": "ISC" - }, - "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", - "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", - "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", - "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", - "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", - "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", - "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", - "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", - "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", - "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", - "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", - "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", - "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", - "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", - "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", - "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", - "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.11" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", - "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", - "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", - "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@vitejs/plugin-vue": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.1.tgz", - "integrity": "sha512-+MaE752hU0wfPFJEUAIxqw18+20euHHdxVtMvbFcOEpjEyfqXH/5DCoTHiVJ0J29EhTJdoTkjEv5YBKU9dnoTw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rolldown/pluginutils": "1.0.0-beta.29" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "peerDependencies": { - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0", - "vue": "^3.2.25" - } - }, - "node_modules/@vitest/eslint-plugin": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.3.4.tgz", - "integrity": "sha512-EOg8d0jn3BAiKnR55WkFxmxfWA3nmzrbIIuOXyTe6A72duryNgyU+bdBEauA97Aab3ho9kLmAwgPX63Ckj4QEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/utils": "^8.24.1" - }, - "peerDependencies": { - "eslint": ">= 8.57.0", - "typescript": ">= 5.0.0", - "vitest": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "vitest": { - "optional": true - } - } - }, - "node_modules/@vitest/expect": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", - "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.4", - "@vitest/utils": "3.2.4", - "chai": "^5.2.0", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/mocker": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", - "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/spy": "3.2.4", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.17" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" - }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } - } - }, - "node_modules/@vitest/mocker/node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@vitest/mocker/node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/@vitest/mocker/node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/@vitest/pretty-format": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", - "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", - "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/utils": "3.2.4", - "pathe": "^2.0.3", - "strip-literal": "^3.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", - "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "3.2.4", - "magic-string": "^0.30.17", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot/node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/@vitest/spy": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", - "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyspy": "^4.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", - "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "3.2.4", - "loupe": "^3.1.4", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@volar/language-core": { - "version": "2.4.20", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.20.tgz", - "integrity": "sha512-dRDF1G33xaAIDqR6+mXUIjXYdu9vzSxlMGfMEwBxQsfY/JMUEXSpLTR057oTKlUQ2nIvCmP9k94A8h8z2VrNSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@volar/source-map": "2.4.20" - } - }, - "node_modules/@volar/source-map": { - "version": "2.4.20", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.20.tgz", - "integrity": "sha512-mVjmFQH8mC+nUaVwmbxoYUy8cww+abaO8dWzqPUjilsavjxH0jCJ3Mp8HFuHsdewZs2c+SP+EO7hCd8Z92whJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@volar/typescript": { - "version": "2.4.20", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.20.tgz", - "integrity": "sha512-Oc4DczPwQyXcVbd+5RsNEqX6ia0+w3p+klwdZQ6ZKhFjWoBP9PCPQYlKYRi/tDemWphW93P/Vv13vcE9I9D2GQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@volar/language-core": "2.4.20", - "path-browserify": "^1.0.1", - "vscode-uri": "^3.0.8" - } - }, - "node_modules/@vue/compiler-core": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.18.tgz", - "integrity": "sha512-3slwjQrrV1TO8MoXgy3aynDQ7lslj5UqDxuHnrzHtpON5CBinhWjJETciPngpin/T3OuW3tXUf86tEurusnztw==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.0", - "@vue/shared": "3.5.18", - "entities": "^4.5.0", - "estree-walker": "^2.0.2", - "source-map-js": "^1.2.1" - } - }, - "node_modules/@vue/compiler-dom": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.18.tgz", - "integrity": "sha512-RMbU6NTU70++B1JyVJbNbeFkK+A+Q7y9XKE2EM4NLGm2WFR8x9MbAtWxPPLdm0wUkuZv9trpwfSlL6tjdIa1+A==", - "license": "MIT", - "dependencies": { - "@vue/compiler-core": "3.5.18", - "@vue/shared": "3.5.18" - } - }, - "node_modules/@vue/compiler-sfc": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.18.tgz", - "integrity": "sha512-5aBjvGqsWs+MoxswZPoTB9nSDb3dhd1x30xrrltKujlCxo48j8HGDNj3QPhF4VIS0VQDUrA1xUfp2hEa+FNyXA==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.0", - "@vue/compiler-core": "3.5.18", - "@vue/compiler-dom": "3.5.18", - "@vue/compiler-ssr": "3.5.18", - "@vue/shared": "3.5.18", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.17", - "postcss": "^8.5.6", - "source-map-js": "^1.2.1" - } - }, - "node_modules/@vue/compiler-sfc/node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/@vue/compiler-ssr": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.18.tgz", - "integrity": "sha512-xM16Ak7rSWHkM3m22NlmcdIM+K4BMyFARAfV9hYFl+SFuRzrZ3uGMNW05kA5pmeMa0X9X963Kgou7ufdbpOP9g==", - "license": "MIT", - "dependencies": { - "@vue/compiler-dom": "3.5.18", - "@vue/shared": "3.5.18" - } - }, - "node_modules/@vue/compiler-vue2": { - "version": "2.7.16", - "resolved": "https://registry.npmjs.org/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz", - "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==", - "dev": true, - "license": "MIT", - "dependencies": { - "de-indent": "^1.0.2", - "he": "^1.2.0" - } - }, - "node_modules/@vue/language-core": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.0.4.tgz", - "integrity": "sha512-BvueED4LfBCSNH66eeUQk37MQCb7hjdezzGgxniM0LbriW53AJIyLorgshAtStmjfsAuOCcTl/c1b+nz/ye8xQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@volar/language-core": "2.4.20", - "@vue/compiler-dom": "^3.5.0", - "@vue/compiler-vue2": "^2.7.16", - "@vue/shared": "^3.5.0", - "alien-signals": "^2.0.5", - "muggle-string": "^0.4.1", - "path-browserify": "^1.0.1", - "picomatch": "^4.0.2" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@vue/language-core/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@vue/reactivity": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.18.tgz", - "integrity": "sha512-x0vPO5Imw+3sChLM5Y+B6G1zPjwdOri9e8V21NnTnlEvkxatHEH5B5KEAJcjuzQ7BsjGrKtfzuQ5eQwXh8HXBg==", - "license": "MIT", - "dependencies": { - "@vue/shared": "3.5.18" - } - }, - "node_modules/@vue/runtime-core": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.18.tgz", - "integrity": "sha512-DUpHa1HpeOQEt6+3nheUfqVXRog2kivkXHUhoqJiKR33SO4x+a5uNOMkV487WPerQkL0vUuRvq/7JhRgLW3S+w==", - "license": "MIT", - "dependencies": { - "@vue/reactivity": "3.5.18", - "@vue/shared": "3.5.18" - } - }, - "node_modules/@vue/runtime-dom": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.18.tgz", - "integrity": "sha512-YwDj71iV05j4RnzZnZtGaXwPoUWeRsqinblgVJwR8XTXYZ9D5PbahHQgsbmzUvCWNF6x7siQ89HgnX5eWkr3mw==", - "license": "MIT", - "dependencies": { - "@vue/reactivity": "3.5.18", - "@vue/runtime-core": "3.5.18", - "@vue/shared": "3.5.18", - "csstype": "^3.1.3" - } - }, - "node_modules/@vue/server-renderer": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.18.tgz", - "integrity": "sha512-PvIHLUoWgSbDG7zLHqSqaCoZvHi6NNmfVFOqO+OnwvqMz/tqQr3FuGWS8ufluNddk7ZLBJYMrjcw1c6XzR12mA==", - "license": "MIT", - "dependencies": { - "@vue/compiler-ssr": "3.5.18", - "@vue/shared": "3.5.18" - }, - "peerDependencies": { - "vue": "3.5.18" - } - }, - "node_modules/@vue/shared": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.18.tgz", - "integrity": "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", - "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", - "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.13.2", - "@webassemblyjs/helper-api-error": "1.13.2", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", - "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", - "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/wasm-gen": "1.14.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", - "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", - "license": "MIT", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", - "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", - "license": "Apache-2.0", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", - "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", - "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/helper-wasm-section": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-opt": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1", - "@webassemblyjs/wast-printer": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", - "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", - "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", - "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-api-error": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", - "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-3.0.1.tgz", - "integrity": "sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==", - "license": "MIT", - "engines": { - "node": ">=18.12.0" - }, - "peerDependencies": { - "webpack": "^5.82.0", - "webpack-cli": "6.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-3.0.1.tgz", - "integrity": "sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==", - "license": "MIT", - "engines": { - "node": ">=18.12.0" - }, - "peerDependencies": { - "webpack": "^5.82.0", - "webpack-cli": "6.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-3.0.1.tgz", - "integrity": "sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==", - "license": "MIT", - "engines": { - "node": ">=18.12.0" - }, - "peerDependencies": { - "webpack": "^5.82.0", - "webpack-cli": "6.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "license": "BSD-3-Clause" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "license": "Apache-2.0" - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-phases": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", - "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", - "license": "MIT", - "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "acorn": "^8.14.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/add-asset-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/add-asset-webpack-plugin/-/add-asset-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-mg6nL4E+dNZPQfTc/A4xcOYsIxCN7Cuy9OScZsjI9qOYPiJeFZfsYcdoYlqcNNQEC4w8yNwArhD1Gm+G1iWrNg==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - }, - "peerDependencies": { - "webpack": ">=5" - } - }, - "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-draft-04": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", - "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "ajv": "^8.5.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-errors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz", - "integrity": "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "ajv": "^8.0.1" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/alien-signals": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-2.0.5.tgz", - "integrity": "sha512-PdJB6+06nUNAClInE3Dweq7/2xVAYM64vvvS1IHVHSJmgeOtEdrAGyp7Z2oJtYm0B342/Exd2NT0uMJaThcjLQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/ansi_up": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/ansi_up/-/ansi_up-6.0.6.tgz", - "integrity": "sha512-yIa1x3Ecf8jWP4UWEunNjqNX6gzE4vg2gGz+xqRGY+TBSucnYp6RRdPV4brmtg6bQ1ljD48mZ5iGSEj7QEpRKA==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "license": "MIT" - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-includes": { - "name": "@nolyfill/array-includes", - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/@nolyfill/array-includes/-/array-includes-1.0.44.tgz", - "integrity": "sha512-IVEqpEgFbLaU0hUoMwJYXNSdi6lq+FxHdxd8xTKDLxh8k6u5YNGz4Bo6bT46l7p0x8PbJmHViBtngqhvE528fA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nolyfill/shared": "1.0.44" - }, - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.findlastindex": { - "name": "@nolyfill/array.prototype.findlastindex", - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/@nolyfill/array.prototype.findlastindex/-/array.prototype.findlastindex-1.0.44.tgz", - "integrity": "sha512-BLeHS3SulsR3iFxxETL9q21lArV2KS7lh2wcUnhue1ppx19xah1W7MdFxepyeGbM3Umk9S90snfboXAds5HkTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nolyfill/shared": "1.0.44" - }, - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/array.prototype.flat": { - "name": "@nolyfill/array.prototype.flat", - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/@nolyfill/array.prototype.flat/-/array.prototype.flat-1.0.44.tgz", - "integrity": "sha512-HnOqOT4te0l+XU9UKhy3ry+pc+ZRNsUJFR7omMEtjXf4+dq6oXmIBk7vR35+hSTk4ldjwm/27jwV3ZIGp3l4IQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nolyfill/shared": "1.0.44" - }, - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/array.prototype.flatmap": { - "name": "@nolyfill/array.prototype.flatmap", - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/@nolyfill/array.prototype.flatmap/-/array.prototype.flatmap-1.0.44.tgz", - "integrity": "sha512-P6OsaEUrpBJ9NdNekFDQVM9LOFHPDKSJzwOWRBaC6LqREX+4lkZT2Q+to78R6aG6atuOQsxBVqPjMGCKjWdvyQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nolyfill/shared": "1.0.44" - }, - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/as-table": { - "version": "1.0.55", - "resolved": "https://registry.npmjs.org/as-table/-/as-table-1.0.55.tgz", - "integrity": "sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "printable-characters": "^1.0.42" - } - }, - "node_modules/asciinema-player": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/asciinema-player/-/asciinema-player-3.10.0.tgz", - "integrity": "sha512-shoOK6F606nDKZxDVM7JuGSCAyWLePoGRFNlV+FqiP5Sqvyn0BlE7wlbjZyd2X4P1iRhv/HKfVNtnQIxmgphRA==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.21.0", - "solid-js": "^1.3.0" - } - }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/ast-types": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", - "integrity": "sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ast-types-flow": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/astring": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", - "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", - "dev": true, - "license": "MIT", - "bin": { - "astring": "bin/astring" - } - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "license": "(MIT OR Apache-2.0)", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/axe-core": { - "version": "4.10.3", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", - "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==", - "dev": true, - "license": "MPL-2.0", - "engines": { - "node": ">=4" - } - }, - "node_modules/axobject-query": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/balanced-match": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", - "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", - "dev": true, - "license": "MIT" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true, - "license": "ISC" - }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/brace-expansion/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.25.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", - "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001726", - "electron-to-chromium": "^1.5.173", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "license": "MIT" - }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.3.tgz", - "integrity": "sha512-M6p10iJ/VT0wT7TLIGUnm958oVrU2cUK8pQAVU21Zu7h8rbk/PeRtRWrvHJBql97Bhzk3g1N6+2VKC+Rjxna9Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "hookified": "^1.10.0", - "keyv": "^5.4.0" - } - }, - "node_modules/cacheable/node_modules/keyv": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.4.0.tgz", - "integrity": "sha512-TMckyVjEoacG5IteUpUrOBsFORtheqziVyyY2dLUwg1jwTb8u48LX4TgmtogkNl9Y9unaEJ1luj10fGyjMGFOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@keyv/serialize": "^1.1.0" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001731", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz", - "integrity": "sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chai": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.1.tgz", - "integrity": "sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==", - "dev": true, - "license": "MIT", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chart.js": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.0.tgz", - "integrity": "sha512-aYeC/jDgSEx8SHWZvANYMioYMZ2KX02W6f6uVfyteuCGcadDLcYVHdfdygsTQkQ4TKn5lghoojAsPj5pu0SnvQ==", - "license": "MIT", - "dependencies": { - "@kurkle/color": "^0.3.0" - }, - "engines": { - "pnpm": ">=8" - } - }, - "node_modules/chartjs-adapter-dayjs-4": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chartjs-adapter-dayjs-4/-/chartjs-adapter-dayjs-4-1.0.4.tgz", - "integrity": "sha512-yy9BAYW4aNzPVrCWZetbILegTRb7HokhgospPoC3b5iZ5qdlqNmXts2KdSp6AqnjkPAp/YWyHDxLvIvwt5x81w==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "chart.js": ">=4.0.1", - "dayjs": "^1.9.7" - } - }, - "node_modules/chartjs-plugin-zoom": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/chartjs-plugin-zoom/-/chartjs-plugin-zoom-2.2.0.tgz", - "integrity": "sha512-in6kcdiTlP6npIVLMd4zXZ08PDUXC52gZ4FAy5oyjk1zX3gKarXMAof7B9eFiisf9WOC3bh2saHg+J5WtLXZeA==", - "license": "MIT", - "dependencies": { - "@types/hammerjs": "^2.0.45", - "hammerjs": "^2.0.8" - }, - "peerDependencies": { - "chart.js": ">=3.2.0" - } - }, - "node_modules/check-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", - "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - } - }, - "node_modules/chevrotain": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", - "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", - "license": "Apache-2.0", - "dependencies": { - "@chevrotain/cst-dts-gen": "11.0.3", - "@chevrotain/gast": "11.0.3", - "@chevrotain/regexp-to-ast": "11.0.3", - "@chevrotain/types": "11.0.3", - "@chevrotain/utils": "11.0.3", - "lodash-es": "4.17.21" - } - }, - "node_modules/chevrotain-allstar": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", - "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", - "license": "MIT", - "dependencies": { - "lodash-es": "^4.17.21" - }, - "peerDependencies": { - "chevrotain": "^11.0.0" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/chroma-js": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-3.1.2.tgz", - "integrity": "sha512-IJnETTalXbsLx1eKEgx19d5L6SRM7cH4vINw/99p/M11HCuXGRWL+6YmCm7FWFGIo6dtWuQoQi1dc5yQ7ESIHg==", - "dev": true, - "license": "(BSD-3-Clause AND Apache-2.0)" - }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "license": "MIT", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", - "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/citeproc": { - "version": "2.4.63", - "resolved": "https://registry.npmjs.org/citeproc/-/citeproc-2.4.63.tgz", - "integrity": "sha512-68F95Bp4UbgZU/DBUGQn0qV3HDZLCdI9+Bb2ByrTaNJDL5VEm9LqaiNaxljsvoaExSLEXe1/r6n2Z06SCzW3/Q==", - "license": "CPAL-1.0 OR AGPL-1.0" - }, - "node_modules/clean-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", - "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/clean-regexp/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/clippie": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/clippie/-/clippie-4.1.7.tgz", - "integrity": "sha512-l8BmUmWqOt4mpxeSflcfODJJOU+DsE5atWj82k1zsxd2X82haz2+g12PJPMOt6e1Cs4/ZnOWdRAV+nY9n2o1Rg==", - "license": "BSD-2-Clause" - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clone-deep/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/codemirror": { - "version": "5.65.19", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.19.tgz", - "integrity": "sha512-+aFkvqhaAVr1gferNMuN8vkTSrWIFvzlMV9I2KBLCWS2WpZ2+UAkZjlMZmEuT+gcXTi6RrGQCkWq1/bDtGqhIA==", - "license": "MIT" - }, - "node_modules/codemirror-spell-checker": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/codemirror-spell-checker/-/codemirror-spell-checker-1.1.2.tgz", - "integrity": "sha512-2Tl6n0v+GJRsC9K3MLCdLaMOmvWL0uukajNJseorZJsslaxZyZMgENocPU8R0DyoTAiKsyqiemSOZo7kjGV0LQ==", - "license": "MIT", - "dependencies": { - "typo-js": "*" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true, - "license": "MIT" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "license": "MIT" - }, - "node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/comment-parser": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", - "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true, - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/confbox": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", - "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", - "license": "MIT" - }, - "node_modules/core-js": { - "version": "3.32.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.32.2.tgz", - "integrity": "sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ==", - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat": { - "version": "3.44.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.44.0.tgz", - "integrity": "sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA==", - "dev": true, - "license": "MIT", - "dependencies": { - "browserslist": "^4.25.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/cose-base": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", - "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", - "license": "MIT", - "dependencies": { - "layout-base": "^1.0.0" - } - }, - "node_modules/cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/cropperjs": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-1.6.2.tgz", - "integrity": "sha512-nhymn9GdnV3CqiEHJVai54TULFAE3VshJTXSqSJKa8yXAKyBKDWdhHarnlIPrshJ0WMFTGuFvG02YjLXfPiuOA==", - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/css": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", - "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "source-map": "^0.6.1", - "source-map-resolve": "^0.6.0" - } - }, - "node_modules/css-functions-list": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", - "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12 || >=16" - } - }, - "node_modules/css-loader": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", - "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", - "license": "MIT", - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.1.0", - "postcss-modules-local-by-default": "^4.0.5", - "postcss-modules-scope": "^3.2.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.27.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/css-select": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", - "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-tree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", - "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "mdn-data": "2.12.2", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/css-what": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", - "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "css-tree": "~2.2.0" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "dev": true, - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT" - }, - "node_modules/cytoscape": { - "version": "3.33.0", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.0.tgz", - "integrity": "sha512-2d2EwwhaxLWC8ahkH1PpQwCyu6EY3xDRdcEJXrLTb4fOUtVc+YWQalHU67rFS1a6ngj1fgv9dQLtJxP/KAFZEw==", - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/cytoscape-cose-bilkent": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", - "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", - "license": "MIT", - "dependencies": { - "cose-base": "^1.0.0" - }, - "peerDependencies": { - "cytoscape": "^3.2.0" - } - }, - "node_modules/cytoscape-fcose": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", - "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", - "license": "MIT", - "dependencies": { - "cose-base": "^2.2.0" - }, - "peerDependencies": { - "cytoscape": "^3.2.0" - } - }, - "node_modules/cytoscape-fcose/node_modules/cose-base": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", - "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", - "license": "MIT", - "dependencies": { - "layout-base": "^2.0.0" - } - }, - "node_modules/cytoscape-fcose/node_modules/layout-base": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", - "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==", - "license": "MIT" - }, - "node_modules/d3": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", - "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", - "license": "ISC", - "dependencies": { - "d3-array": "3", - "d3-axis": "3", - "d3-brush": "3", - "d3-chord": "3", - "d3-color": "3", - "d3-contour": "4", - "d3-delaunay": "6", - "d3-dispatch": "3", - "d3-drag": "3", - "d3-dsv": "3", - "d3-ease": "3", - "d3-fetch": "3", - "d3-force": "3", - "d3-format": "3", - "d3-geo": "3", - "d3-hierarchy": "3", - "d3-interpolate": "3", - "d3-path": "3", - "d3-polygon": "3", - "d3-quadtree": "3", - "d3-random": "3", - "d3-scale": "4", - "d3-scale-chromatic": "3", - "d3-selection": "3", - "d3-shape": "3", - "d3-time": "3", - "d3-time-format": "4", - "d3-timer": "3", - "d3-transition": "3", - "d3-zoom": "3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-array": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", - "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", - "license": "ISC", - "dependencies": { - "internmap": "1 - 2" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-axis": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", - "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-brush": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", - "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", - "license": "ISC", - "dependencies": { - "d3-dispatch": "1 - 3", - "d3-drag": "2 - 3", - "d3-interpolate": "1 - 3", - "d3-selection": "3", - "d3-transition": "3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-chord": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", - "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", - "license": "ISC", - "dependencies": { - "d3-path": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-color": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-contour": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", - "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", - "license": "ISC", - "dependencies": { - "d3-array": "^3.2.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", - "license": "ISC", - "dependencies": { - "delaunator": "5" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-dispatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", - "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-drag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", - "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", - "license": "ISC", - "dependencies": { - "d3-dispatch": "1 - 3", - "d3-selection": "3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-dsv": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", - "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", - "license": "ISC", - "dependencies": { - "commander": "7", - "iconv-lite": "0.6", - "rw": "1" - }, - "bin": { - "csv2json": "bin/dsv2json.js", - "csv2tsv": "bin/dsv2dsv.js", - "dsv2dsv": "bin/dsv2dsv.js", - "dsv2json": "bin/dsv2json.js", - "json2csv": "bin/json2dsv.js", - "json2dsv": "bin/json2dsv.js", - "json2tsv": "bin/json2dsv.js", - "tsv2csv": "bin/dsv2dsv.js", - "tsv2json": "bin/dsv2json.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-dsv/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/d3-ease": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", - "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-fetch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", - "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", - "license": "ISC", - "dependencies": { - "d3-dsv": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-force": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", - "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", - "license": "ISC", - "dependencies": { - "d3-dispatch": "1 - 3", - "d3-quadtree": "1 - 3", - "d3-timer": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-geo": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", - "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", - "license": "ISC", - "dependencies": { - "d3-array": "2.5.0 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-hierarchy": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", - "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", - "license": "ISC", - "dependencies": { - "d3-color": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-polygon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", - "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-quadtree": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", - "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-random": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", - "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-sankey": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", - "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", - "license": "BSD-3-Clause", - "dependencies": { - "d3-array": "1 - 2", - "d3-shape": "^1.2.0" - } - }, - "node_modules/d3-sankey/node_modules/d3-array": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", - "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", - "license": "BSD-3-Clause", - "dependencies": { - "internmap": "^1.0.0" - } - }, - "node_modules/d3-sankey/node_modules/d3-path": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", - "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", - "license": "BSD-3-Clause" - }, - "node_modules/d3-sankey/node_modules/d3-shape": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", - "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", - "license": "BSD-3-Clause", - "dependencies": { - "d3-path": "1" - } - }, - "node_modules/d3-sankey/node_modules/internmap": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", - "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", - "license": "ISC" - }, - "node_modules/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", - "license": "ISC", - "dependencies": { - "d3-array": "2.10.0 - 3", - "d3-format": "1 - 3", - "d3-interpolate": "1.2.0 - 3", - "d3-time": "2.1.1 - 3", - "d3-time-format": "2 - 4" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-scale-chromatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", - "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", - "license": "ISC", - "dependencies": { - "d3-color": "1 - 3", - "d3-interpolate": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-selection": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", - "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "license": "ISC", - "dependencies": { - "d3-path": "^3.1.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", - "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", - "license": "ISC", - "dependencies": { - "d3-array": "2 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-time-format": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", - "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", - "license": "ISC", - "dependencies": { - "d3-time": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-timer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", - "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-transition": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", - "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", - "license": "ISC", - "dependencies": { - "d3-color": "1 - 3", - "d3-dispatch": "1 - 3", - "d3-ease": "1 - 3", - "d3-interpolate": "1 - 3", - "d3-timer": "1 - 3" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "d3-selection": "2 - 3" - } - }, - "node_modules/d3-zoom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", - "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", - "license": "ISC", - "dependencies": { - "d3-dispatch": "1 - 3", - "d3-drag": "2 - 3", - "d3-interpolate": "1 - 3", - "d3-selection": "2 - 3", - "d3-transition": "2 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/dagre-d3-es": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.11.tgz", - "integrity": "sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==", - "license": "MIT", - "dependencies": { - "d3": "^7.9.0", - "lodash-es": "^4.17.21" - } - }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/data-uri-to-buffer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-2.0.2.tgz", - "integrity": "sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==", - "dev": true, - "license": "MIT" - }, - "node_modules/dayjs": { - "version": "1.11.13", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", - "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", - "license": "MIT" - }, - "node_modules/de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", - "dev": true, - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-named-character-reference": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", - "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/deep-rename-keys": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/deep-rename-keys/-/deep-rename-keys-0.2.1.tgz", - "integrity": "sha512-RHd9ABw4Fvk+gYDWqwOftG849x0bYOySl/RgX0tLI9i27ZIeSO91mLZJEp7oPHOMFqHvpgu21YptmDt0FYD/0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2", - "rename-keys": "^1.1.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/deep-rename-keys/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/delaunator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", - "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", - "license": "ISC", - "dependencies": { - "robust-predicates": "^3.0.2" - } - }, - "node_modules/dependency-graph": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", - "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "dev": true, - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "license": "Apache-2.0" - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "license": "MIT" - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-input-range": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/dom-input-range/-/dom-input-range-2.0.1.tgz", - "integrity": "sha512-UMGnuQlEepIPCju5NrPe+8y52B+pRvSjIaSPW92KpukoDGSEVkI2iaCR4HxK7K6C7zmVsWE8PEjCYZaJMr3vpg==", - "license": "MIT", - "workspaces": [ - "demos" - ] - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dev": true, - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/dompurify": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz", - "integrity": "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==", - "license": "(MPL-2.0 OR Apache-2.0)", - "optionalDependencies": { - "@types/trusted-types": "^2.0.7" - } - }, - "node_modules/domutils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dropzone": { - "version": "6.0.0-beta.2", - "resolved": "https://registry.npmjs.org/dropzone/-/dropzone-6.0.0-beta.2.tgz", - "integrity": "sha512-k44yLuFFhRk53M8zP71FaaNzJYIzr99SKmpbO/oZKNslDjNXQsBTdfLs+iONd0U0L94zzlFzRnFdqbLcs7h9fQ==", - "license": "MIT", - "dependencies": { - "@swc/helpers": "^0.2.13", - "just-extend": "^5.0.0" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "license": "MIT" - }, - "node_modules/easymde": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/easymde/-/easymde-2.20.0.tgz", - "integrity": "sha512-V1Z5f92TfR42Na852OWnIZMbM7zotWQYTddNaLYZFVKj7APBbyZ3FYJ27gBw2grMW3R6Qdv9J8n5Ij7XRSIgXQ==", - "license": "MIT", - "dependencies": { - "@types/codemirror": "^5.60.10", - "@types/marked": "^4.0.7", - "codemirror": "^5.65.15", - "codemirror-spell-checker": "1.1.2", - "marked": "^4.1.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.194", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.194.tgz", - "integrity": "sha512-SdnWJwSUot04UR51I2oPD8kuP2VI37/CADR1OHsFOUzZIvfWJBO6q11k5P/uKNyTT3cdOsnyjkrZ+DDShqYqJA==", - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "license": "MIT" - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.18.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", - "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/envinfo": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz", - "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", - "license": "MIT", - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-aggregate-error": { - "name": "@nolyfill/es-aggregate-error", - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/@nolyfill/es-aggregate-error/-/es-aggregate-error-1.0.44.tgz", - "integrity": "sha512-NBXDS4gpOiK4csFDGjqAF0WVKAMsqq/2ZU+/z+q+Mmvpr6CIrwKC/X+EbMpalEOZYT8kSTaCMVDUcXTDeMYOLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nolyfill/shared": "1.0.44" - }, - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", - "license": "MIT" - }, - "node_modules/esbuild": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", - "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.8", - "@esbuild/android-arm": "0.25.8", - "@esbuild/android-arm64": "0.25.8", - "@esbuild/android-x64": "0.25.8", - "@esbuild/darwin-arm64": "0.25.8", - "@esbuild/darwin-x64": "0.25.8", - "@esbuild/freebsd-arm64": "0.25.8", - "@esbuild/freebsd-x64": "0.25.8", - "@esbuild/linux-arm": "0.25.8", - "@esbuild/linux-arm64": "0.25.8", - "@esbuild/linux-ia32": "0.25.8", - "@esbuild/linux-loong64": "0.25.8", - "@esbuild/linux-mips64el": "0.25.8", - "@esbuild/linux-ppc64": "0.25.8", - "@esbuild/linux-riscv64": "0.25.8", - "@esbuild/linux-s390x": "0.25.8", - "@esbuild/linux-x64": "0.25.8", - "@esbuild/netbsd-arm64": "0.25.8", - "@esbuild/netbsd-x64": "0.25.8", - "@esbuild/openbsd-arm64": "0.25.8", - "@esbuild/openbsd-x64": "0.25.8", - "@esbuild/openharmony-arm64": "0.25.8", - "@esbuild/sunos-x64": "0.25.8", - "@esbuild/win32-arm64": "0.25.8", - "@esbuild/win32-ia32": "0.25.8", - "@esbuild/win32-x64": "0.25.8" - } - }, - "node_modules/esbuild-loader": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.3.0.tgz", - "integrity": "sha512-D7HeJNdkDKKMarPQO/3dlJT6RwN2YJO7ENU6RPlpOz5YxSHnUNi2yvW41Bckvi1EVwctIaLzlb0ni5ag2GINYA==", - "license": "MIT", - "dependencies": { - "esbuild": "^0.25.0", - "get-tsconfig": "^4.7.0", - "loader-utils": "^2.0.4", - "webpack-sources": "^1.4.3" - }, - "funding": { - "url": "https://github.com/privatenumber/esbuild-loader?sponsor=1" - }, - "peerDependencies": { - "webpack": "^4.40.0 || ^5.0.0" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-compat-utils": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.6.5.tgz", - "integrity": "sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, - "node_modules/eslint-config-prettier": { - "version": "10.1.8", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", - "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "funding": { - "url": "https://opencollective.com/eslint-config-prettier" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-import-context": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", - "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-tsconfig": "^4.10.1", - "stable-hash-x": "^0.2.0" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-import-context" - }, - "peerDependencies": { - "unrs-resolver": "^1.0.0" - }, - "peerDependenciesMeta": { - "unrs-resolver": { - "optional": true - } - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-4.4.4.tgz", - "integrity": "sha512-1iM2zeBvrYmUNTj2vSC/90JTHDth+dfOfiNKkxApWRsTJYNrc8rOdxxIf5vazX+BiAXTeOT0UvWpGI/7qIWQOw==", - "dev": true, - "license": "ISC", - "dependencies": { - "debug": "^4.4.1", - "eslint-import-context": "^0.1.8", - "get-tsconfig": "^4.10.1", - "is-bun-module": "^2.0.0", - "stable-hash-x": "^0.2.0", - "tinyglobby": "^0.2.14", - "unrs-resolver": "^1.7.11" - }, - "engines": { - "node": "^16.17.0 || >=18.6.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-import-resolver-typescript" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*", - "eslint-plugin-import-x": "*" - }, - "peerDependenciesMeta": { - "eslint-plugin-import": { - "optional": true - }, - "eslint-plugin-import-x": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", - "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-array-func": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-array-func/-/eslint-plugin-array-func-4.0.0.tgz", - "integrity": "sha512-p3NY2idNIvgmQLF2/62ZskYt8gOuUgQ51smRc3Lh7FtSozpNc2sg+lniz9VaCagLZHEZTl8qGJKqE7xy8O/D/g==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/eslint-plugin-escompat": { - "version": "3.11.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-escompat/-/eslint-plugin-escompat-3.11.4.tgz", - "integrity": "sha512-j0ywwNnIufshOzgAu+PfIig1c7VRClKSNKzpniMT2vXQ4leL5q+e/SpMFQU0nrdL2WFFM44XmhSuwmxb3G0CJg==", - "dev": true, - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.1" - }, - "peerDependencies": { - "eslint": ">=5.14.1" - } - }, - "node_modules/eslint-plugin-eslint-comments": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz", - "integrity": "sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5", - "ignore": "^5.0.5" - }, - "engines": { - "node": ">=6.5.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" - } - }, - "node_modules/eslint-plugin-eslint-comments/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eslint-plugin-filenames": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-filenames/-/eslint-plugin-filenames-1.3.2.tgz", - "integrity": "sha512-tqxJTiEM5a0JmRCUYQmxw23vtTxrb2+a3Q2mMOPhFxvt7ZQQJmdiuMby9B/vUAuVMghyP7oET+nIf6EO6CBd/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash.camelcase": "4.3.0", - "lodash.kebabcase": "4.1.1", - "lodash.snakecase": "4.1.1", - "lodash.upperfirst": "4.3.1" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "node_modules/eslint-plugin-github": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-github/-/eslint-plugin-github-5.0.2.tgz", - "integrity": "sha512-nMdzWJQ5CimjQDY6SFeJ0KIXuNFf0dgDWEd4eP3UWfuTuP/dXcZJDg7MQRvAFt743T1zUi4+/HdOihfu8xJkLA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@github/browserslist-config": "^1.0.0", - "@typescript-eslint/eslint-plugin": "^8.0.0", - "@typescript-eslint/parser": "^8.0.0", - "aria-query": "^5.3.0", - "eslint-config-prettier": ">=8.0.0", - "eslint-plugin-escompat": "^3.3.3", - "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-filenames": "^1.3.2", - "eslint-plugin-i18n-text": "^1.0.1", - "eslint-plugin-import": "^2.25.2", - "eslint-plugin-jsx-a11y": "^6.7.1", - "eslint-plugin-no-only-tests": "^3.0.0", - "eslint-plugin-prettier": "^5.0.0", - "eslint-rule-documentation": ">=1.0.0", - "jsx-ast-utils": "^3.3.2", - "prettier": "^3.0.0", - "svg-element-attributes": "^1.3.1" - }, - "bin": { - "eslint-ignore-errors": "bin/eslint-ignore-errors.js" - }, - "peerDependencies": { - "eslint": "^8.0.1" - } - }, - "node_modules/eslint-plugin-i18n-text": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-i18n-text/-/eslint-plugin-i18n-text-1.0.1.tgz", - "integrity": "sha512-3G3UetST6rdqhqW9SfcfzNYMpQXS7wNkJvp6dsXnjzGiku6Iu5hl3B0kmk6lIcFPwYjhQIY+tXVRtK9TlGT7RA==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "eslint": ">=5.0.0" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.32.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", - "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.9", - "array.prototype.findlastindex": "^1.2.6", - "array.prototype.flat": "^1.3.3", - "array.prototype.flatmap": "^1.3.3", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.1", - "hasown": "^2.0.2", - "is-core-module": "^2.16.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "object.groupby": "^1.0.3", - "object.values": "^1.2.1", - "semver": "^6.3.1", - "string.prototype.trimend": "^1.0.9", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" - } - }, - "node_modules/eslint-plugin-import-x": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.16.1.tgz", - "integrity": "sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "^8.35.0", - "comment-parser": "^1.4.1", - "debug": "^4.4.1", - "eslint-import-context": "^0.1.9", - "is-glob": "^4.0.3", - "minimatch": "^9.0.3 || ^10.0.1", - "semver": "^7.7.2", - "stable-hash-x": "^0.2.0", - "unrs-resolver": "^1.9.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-import-x" - }, - "peerDependencies": { - "@typescript-eslint/utils": "^8.0.0", - "eslint": "^8.57.0 || ^9.0.0", - "eslint-import-resolver-node": "*" - }, - "peerDependenciesMeta": { - "@typescript-eslint/utils": { - "optional": true - }, - "eslint-import-resolver-node": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", - "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "aria-query": "^5.3.2", - "array-includes": "^3.1.8", - "array.prototype.flatmap": "^1.3.2", - "ast-types-flow": "^0.0.8", - "axe-core": "^4.10.0", - "axobject-query": "^4.1.0", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.2", - "hasown": "^2.0.2", - "jsx-ast-utils": "^3.3.5", - "language-tags": "^1.0.9", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "safe-regex-test": "^1.0.3", - "string.prototype.includes": "^2.0.1" - }, - "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" - } - }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-no-jquery": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.1.1.tgz", - "integrity": "sha512-LTLO3jH/Tjr1pmxCEqtV6qmt+OChv8La4fwgG470JRpgxyFF4NOzoC9CRy92GIWD3Yjl0qLEgPmD2FLQWcNEjg==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "eslint": ">=8.0.0" - } - }, - "node_modules/eslint-plugin-no-only-tests": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.3.0.tgz", - "integrity": "sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=5.0.0" - } - }, - "node_modules/eslint-plugin-no-use-extend-native": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-use-extend-native/-/eslint-plugin-no-use-extend-native-0.5.0.tgz", - "integrity": "sha512-dBNjs8hor8rJgeXLH4HTut5eD3RGWf9JUsadIfuL7UosVQ/dnvOKwxEcRrXrFxrMZ8llUVWT+hOimxJABsAUzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-get-set-prop": "^1.0.0", - "is-js-type": "^2.0.0", - "is-obj-prop": "^1.0.0", - "is-proto-prop": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/eslint-plugin-playwright": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-2.2.2.tgz", - "integrity": "sha512-j0jKpndIPOXRRP9uMkwb9l/nSmModOU3452nrFdgFJoEv/435J1onk8+aITzjDW8DfypxgmVaDMdmVIa6F7I0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "globals": "^13.23.0" - }, - "engines": { - "node": ">=16.6.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.3.tgz", - "integrity": "sha512-NAdMYww51ehKfDyDhv59/eIItUVzU0Io9H2E8nHNGKEeeqlnci+1gCvrHib6EmZdf6GxF+LCV5K7UC65Ezvw7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.11.7" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-regexp": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.9.0.tgz", - "integrity": "sha512-9WqJMnOq8VlE/cK+YAo9C9YHhkOtcEtEk9d12a+H7OSZFwlpI6stiHmYPGa2VE0QhTzodJyhlyprUaXDZLgHBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", - "comment-parser": "^1.4.0", - "jsdoc-type-pratt-parser": "^4.0.0", - "refa": "^0.12.1", - "regexp-ast-analysis": "^0.7.1", - "scslre": "^0.3.0" - }, - "engines": { - "node": "^18 || >=20" - }, - "peerDependencies": { - "eslint": ">=8.44.0" - } - }, - "node_modules/eslint-plugin-sonarjs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-3.0.4.tgz", - "integrity": "sha512-ftQcP811kRJNXapqpQXHErEoVOdTPfYPPYd7n3AExIPwv4qWKKHf4slFvXmodiOnfgy1Tl3waPZZLD7lcvJOtw==", - "dev": true, - "license": "LGPL-3.0-only", - "dependencies": { - "@eslint-community/regexpp": "4.12.1", - "builtin-modules": "3.3.0", - "bytes": "3.1.2", - "functional-red-black-tree": "1.0.1", - "jsx-ast-utils": "3.3.5", - "lodash.merge": "4.6.2", - "minimatch": "9.0.5", - "scslre": "0.3.0", - "semver": "7.7.2", - "typescript": ">=5" - }, - "peerDependencies": { - "eslint": "^8.0.0 || ^9.0.0" - } - }, - "node_modules/eslint-plugin-sonarjs/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint-plugin-sonarjs/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/eslint-plugin-sonarjs/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/eslint-plugin-unicorn": { - "version": "56.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-56.0.1.tgz", - "integrity": "sha512-FwVV0Uwf8XPfVnKSGpMg7NtlZh0G0gBarCaFcMUOoqPxXryxdYxTRRv4kH6B9TFCVIrjRXG+emcxIk2ayZilog==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "@eslint-community/eslint-utils": "^4.4.0", - "ci-info": "^4.0.0", - "clean-regexp": "^1.0.0", - "core-js-compat": "^3.38.1", - "esquery": "^1.6.0", - "globals": "^15.9.0", - "indent-string": "^4.0.0", - "is-builtin-module": "^3.2.1", - "jsesc": "^3.0.2", - "pluralize": "^8.0.0", - "read-pkg-up": "^7.0.1", - "regexp-tree": "^0.1.27", - "regjsparser": "^0.10.0", - "semver": "^7.6.3", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=18.18" - }, - "funding": { - "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" - }, - "peerDependencies": { - "eslint": ">=8.56.0" - } - }, - "node_modules/eslint-plugin-unicorn/node_modules/globals": { - "version": "15.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", - "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-plugin-vue": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.4.0.tgz", - "integrity": "sha512-K6tP0dW8FJVZLQxa2S7LcE1lLw3X8VvB3t887Q6CLrFVxHYBXGANbXvwNzYIu6Ughx1bSJ5BDT0YB3ybPT39lw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "natural-compare": "^1.4.0", - "nth-check": "^2.1.1", - "postcss-selector-parser": "^6.0.15", - "semver": "^7.6.3", - "xml-name-validator": "^4.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0 || ^8.0.0", - "eslint": "^8.57.0 || ^9.0.0", - "vue-eslint-parser": "^10.0.0" - }, - "peerDependenciesMeta": { - "@typescript-eslint/parser": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-vue-scoped-css": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue-scoped-css/-/eslint-plugin-vue-scoped-css-2.11.0.tgz", - "integrity": "sha512-rrJgLY8iroTIUMSyxhyhJzFcRxABbk3gFrOLkl41F9G1VBqNNpDShyf6PmDoBEWDk07/bJlnqYlvnQ3giUrRYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "eslint-compat-utils": "^0.6.5", - "lodash": "^4.17.21", - "postcss": "^8.4.31", - "postcss-safe-parser": "^6.0.0", - "postcss-scss": "^4.0.3", - "postcss-selector-parser": "^7.0.0", - "postcss-styl": "^0.12.0" - }, - "engines": { - "node": "^12.22 || ^14.17 || >=16" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, - "peerDependencies": { - "eslint": ">=5.0.0", - "vue-eslint-parser": ">=7.1.0" - } - }, - "node_modules/eslint-plugin-vue/node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-wc": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-3.0.1.tgz", - "integrity": "sha512-0p1wkSlA2Ue3FA4qW+5LZ+15sy0p1nUyVl1eyBMLq4rtN1LtE9IdI49BXNWMz8N8bM/y7Ulx8SWGAni5f8XO5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-valid-element-name": "^1.0.0", - "js-levenshtein-esm": "^2.0.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/eslint-rule-documentation": { - "version": "1.0.23", - "resolved": "https://registry.npmjs.org/eslint-rule-documentation/-/eslint-rule-documentation-1.0.23.tgz", - "integrity": "sha512-pWReu3fkohwyvztx/oQWWgld2iad25TfUdi6wvhhaDPIQjHU/pyvlKgXFw1kX31SQK2Nq9MH+vRDWB0ZLy8fYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "license": "MIT" - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/eventemitter3": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", - "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==", - "dev": true, - "license": "MIT" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/expect-type": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", - "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/exsolve": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", - "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-memoize": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz", - "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fetch-ponyfill": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-7.1.0.tgz", - "integrity": "sha512-FhbbL55dj/qdVO3YNK7ZEkshvj3eQ7EuIGV2I6ic/2YiocvyWv+7jg2s4AyS0wdRU75s3tA8ZxI/xPigb0v5Aw==", - "license": "MIT", - "dependencies": { - "node-fetch": "~2.6.1" - } - }, - "node_modules/fetch-ponyfill/node_modules/node-fetch": { - "version": "2.6.13", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz", - "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/fflate": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", - "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", - "license": "MIT" - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true, - "license": "ISC" - }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true, - "license": "MIT" - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-east-asian-width": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", - "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-set-props": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz", - "integrity": "sha512-7oKuKzAGKj0ag+eWZwcGw2fjiZ78tXnXQoBgY0aU7ZOxTu4bB7hSuQSDgtKy978EDH062P5FmD2EWiDpQS9K9Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/get-source": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/get-source/-/get-source-2.0.12.tgz", - "integrity": "sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==", - "dev": true, - "license": "Unlicense", - "dependencies": { - "data-uri-to-buffer": "^2.0.0", - "source-map": "^0.6.1" - } - }, - "node_modules/get-tsconfig": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", - "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "license": "BSD-2-Clause" - }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "license": "ISC" - }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globals/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globjoin": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", - "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", - "dev": true, - "license": "MIT" - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, - "node_modules/hachure-fill": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", - "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==", - "license": "MIT" - }, - "node_modules/hammerjs": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", - "integrity": "sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/happy-dom": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-18.0.1.tgz", - "integrity": "sha512-qn+rKOW7KWpVTtgIUi6RVmTBZJSe2k0Db0vh1f7CWrWclkkc7/Q+FrOfkZIb2eiErLyqu5AXEzE7XthO9JVxRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "^20.0.0", - "@types/whatwg-mimetype": "^3.0.2", - "whatwg-mimetype": "^3.0.0" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/happy-dom/node_modules/@types/node": { - "version": "20.19.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.9.tgz", - "integrity": "sha512-cuVNgarYWZqxRJDQHEB58GEONhOK79QVR/qYx4S7kcUObQvUwvFnYxJuuHUKm2aieN9X3yZB4LZsuYNU1Qphsw==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/happy-dom/node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/hash-sum": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", - "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==", - "license": "MIT" - }, - "node_modules/hasown": { - "name": "@nolyfill/hasown", - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/@nolyfill/hasown/-/hasown-1.0.44.tgz", - "integrity": "sha512-GA/21lkTr2PAQuT6jGnhLuBD5IFd/AEhBXJ/tf33+/bVxPxg+5ejKx9jGQGnyV/P0eSmdup5E+s8b2HL6lOrwQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "license": "MIT", - "bin": { - "he": "bin/he" - } - }, - "node_modules/hookified": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.11.0.tgz", - "integrity": "sha512-aDdIN3GyU5I6wextPplYdfmWCo+aLmjjVbntmX6HLD5RCi/xKsivYEBhnRD+d9224zFf008ZpLMPlWF0ZodYZw==", - "dev": true, - "license": "MIT" - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true, - "license": "ISC" - }, - "node_modules/hpagent": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz", - "integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/html-tags": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, - "node_modules/htmx.org": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-2.0.6.tgz", - "integrity": "sha512-7ythjYneGSk3yCHgtCnQeaoF+D+o7U2LF37WU3O0JYv3gTZSicdEFiI/Ai/NJyC5ZpYJWMpUb11OC5Lr6AfAqA==", - "license": "0BSD" - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "license": "ISC", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/idiomorph": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/idiomorph/-/idiomorph-0.7.3.tgz", - "integrity": "sha512-YI/L1QQkBRDtiaGZN+/KolIkNoZuIsCgus1ciueosiqdyWz/weeP+ghFgDQpk2vzA3BkX6/M/kY5SCM03LBDkA==", - "license": "0BSD" - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/immer": { - "version": "9.0.21", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", - "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ini": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", - "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/internmap": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", - "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "license": "MIT" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "license": "MIT", - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-bun-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", - "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.7.1" - } - }, - "node_modules/is-core-module": { - "name": "@nolyfill/is-core-module", - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", - "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", - "license": "MIT", - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-get-set-prop": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz", - "integrity": "sha512-DvAYZ1ZgGUz4lzxKMPYlt08qAUqyG9ckSg2pIjfvcQ7+pkVNUHk8yVLXOnCLe5WKXhLop8oorWFBJHpwWQpszQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-set-props": "^0.1.0", - "lowercase-keys": "^1.0.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-js-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz", - "integrity": "sha512-Aj13l47+uyTjlQNHtXBV8Cji3jb037vxwMWCgopRR8h6xocgBGW3qG8qGlIOEmbXQtkKShKuBM9e8AA1OeQ+xw==", - "dev": true, - "license": "MIT", - "dependencies": { - "js-types": "^1.0.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-obj-prop": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz", - "integrity": "sha512-5Idb61slRlJlsAzi0Wsfwbp+zZY+9LXKUAZpvT/1ySw+NxKLRWfa0Bzj+wXI3fX5O9hiddm5c3DAaRSNP/yl2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "lowercase-keys": "^1.0.0", - "obj-props": "^1.0.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, - "license": "MIT", - "engines": { - "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, - "license": "MIT" - }, - "node_modules/is-proto-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-2.0.0.tgz", - "integrity": "sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==", - "dev": true, - "license": "MIT", - "dependencies": { - "lowercase-keys": "^1.0.0", - "proto-props": "^2.0.0" - } - }, - "node_modules/is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/is-valid-element-name": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-element-name/-/is-valid-element-name-1.0.0.tgz", - "integrity": "sha512-GZITEJY2LkSjQfaIPBha7eyZv+ge0PhBR7KITeCCWvy7VBQrCUdFkvpI+HrAPQjVtVjy1LvlEkqQTHckoszruw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "is-potential-custom-element-name": "^1.0.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jackspeak": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", - "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jiti": { - "version": "1.21.7", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", - "license": "MIT", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/jquery": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", - "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", - "license": "MIT" - }, - "node_modules/js-levenshtein-esm": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/js-levenshtein-esm/-/js-levenshtein-esm-2.0.0.tgz", - "integrity": "sha512-1n4LEPOL4wRXY8rOQcuA7Iuaphe5xCMayvufCzlLAi+hRsnBRDbSS6XPuV58CBVJxj5D9ApFLyjQ7KzFToyHBw==", - "dev": true, - "license": "MIT" - }, - "node_modules/js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/js-types": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz", - "integrity": "sha512-bfwqBW9cC/Lp7xcRpug7YrXm0IVw+T9e3g4mCYnv0Pjr3zIzU9PCQElYU9oSGAWzXlbdl9X5SAMPejO9sxkeUw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdoc-type-pratt-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", - "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/jsep": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.4.0.tgz", - "integrity": "sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.16.0" - } - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==", - "dev": true, - "license": "MIT" - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonpath-plus": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.3.0.tgz", - "integrity": "sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jsep-plugin/assignment": "^1.3.0", - "@jsep-plugin/regex": "^1.0.4", - "jsep": "^1.4.0" - }, - "bin": { - "jsonpath": "bin/jsonpath-cli.js", - "jsonpath-plus": "bin/jsonpath-cli.js" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jsx-ast-utils": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", - "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "object.assign": "^4.1.4", - "object.values": "^1.1.6" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/just-extend": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-5.1.1.tgz", - "integrity": "sha512-b+z6yF1d4EOyDgylzQo5IminlUmzSeqR1hs/bzjBNjuGras4FXq/6TrzjxfN0j+TmI0ltJzTNlqXUMCniciwKQ==", - "license": "MIT" - }, - "node_modules/katex": { - "version": "0.16.22", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.22.tgz", - "integrity": "sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==", - "funding": [ - "https://opencollective.com/katex", - "https://github.com/sponsors/katex" - ], - "license": "MIT", - "dependencies": { - "commander": "^8.3.0" - }, - "bin": { - "katex": "cli.js" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/khroma": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", - "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/known-css-properties": { - "version": "0.37.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.37.0.tgz", - "integrity": "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/kolorist": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", - "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", - "license": "MIT" - }, - "node_modules/langium": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/langium/-/langium-3.3.1.tgz", - "integrity": "sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==", - "license": "MIT", - "dependencies": { - "chevrotain": "~11.0.3", - "chevrotain-allstar": "~0.3.0", - "vscode-languageserver": "~9.0.1", - "vscode-languageserver-textdocument": "~1.0.11", - "vscode-uri": "~3.0.8" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/language-subtag-registry": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", - "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/language-tags": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", - "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", - "dev": true, - "license": "MIT", - "dependencies": { - "language-subtag-registry": "^0.3.20" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/layout-base": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", - "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==", - "license": "MIT" - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/license-checker-webpack-plugin": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/license-checker-webpack-plugin/-/license-checker-webpack-plugin-0.2.1.tgz", - "integrity": "sha512-rX8B+mH6fk1vxbnIu/UztqTEonQw95xwOkoRjX3TSrRZA/pbG9CWa3wnSo89KY/ej379JQoq050fsuthy6AU+A==", - "license": "MIT", - "dependencies": { - "glob": "^7.1.6", - "lodash.template": "^4.5.0", - "minimatch": "^3.0.4", - "semver": "^6.3.0", - "spdx-expression-validate": "^2.0.0", - "spdx-satisfies": "^5.0.0", - "superstruct": "^0.10.12", - "webpack-sources": "^1.4.3", - "wrap-ansi": "^6.1.0" - }, - "peerDependencies": { - "webpack": "^4.4.0 || ^5.4.0" - } - }, - "node_modules/license-checker-webpack-plugin/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/license-checker-webpack-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/license-checker-webpack-plugin/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lilconfig": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "license": "MIT" - }, - "node_modules/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "uc.micro": "^2.0.0" - } - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "license": "MIT", - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/local-pkg": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.1.tgz", - "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==", - "license": "MIT", - "dependencies": { - "mlly": "^1.7.4", - "pkg-types": "^2.0.1", - "quansync": "^0.2.8" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "license": "MIT" - }, - "node_modules/lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", - "license": "MIT" - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.snakecase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", - "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.sortedlastindex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/lodash.sortedlastindex/-/lodash.sortedlastindex-4.1.0.tgz", - "integrity": "sha512-s8xEQdsp2Tu5zUqVdFSe9C0kR8YlnAJYLqMdkh+pIRBRxF6/apWseLdHl3/+jv2I61dhPwtI/Ff+EqvCpc+N8w==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "deprecated": "This package is deprecated. Use https://socket.dev/npm/package/eta instead.", - "license": "MIT", - "dependencies": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "node_modules/lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "license": "MIT", - "dependencies": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "node_modules/lodash.topath": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz", - "integrity": "sha512-1/W4dM+35DwvE/iEd1M9ekewOSTlpFekhw9mhAtrwjVqUr83/ilQiyAvmg4tVX7Unkcfl1KC+i9WdaT4B6aQcg==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.upperfirst": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", - "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", - "dev": true, - "license": "MIT" - }, - "node_modules/loupe": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.0.tgz", - "integrity": "sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==", - "dev": true, - "license": "MIT" - }, - "node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lru-cache": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", - "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", - "dev": true, - "license": "ISC", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "sourcemap-codec": "^1.4.8" - } - }, - "node_modules/markdown-escape": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-escape/-/markdown-escape-2.0.0.tgz", - "integrity": "sha512-Trz4v0+XWlwy68LJIyw3bLbsJiC8XAbRCKF9DbEtZjyndKOGVx6n+wNB0VfoRmY2LKboQLeniap3xrb6LGSJ8A==", - "dev": true, - "license": "MIT" - }, - "node_modules/markdown-it": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", - "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1", - "entities": "^4.4.0", - "linkify-it": "^5.0.0", - "mdurl": "^2.0.0", - "punycode.js": "^2.3.1", - "uc.micro": "^2.1.0" - }, - "bin": { - "markdown-it": "bin/markdown-it.mjs" - } - }, - "node_modules/markdownlint": { - "version": "0.38.0", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.38.0.tgz", - "integrity": "sha512-xaSxkaU7wY/0852zGApM8LdlIfGCW8ETZ0Rr62IQtAnUMlMuifsg09vWJcNYeL4f0anvr8Vo4ZQar8jGpV0btQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "micromark": "4.0.2", - "micromark-core-commonmark": "2.0.3", - "micromark-extension-directive": "4.0.0", - "micromark-extension-gfm-autolink-literal": "2.1.0", - "micromark-extension-gfm-footnote": "2.1.0", - "micromark-extension-gfm-table": "2.1.1", - "micromark-extension-math": "3.1.0", - "micromark-util-types": "2.0.2" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/DavidAnson" - } - }, - "node_modules/markdownlint-cli": { - "version": "0.45.0", - "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.45.0.tgz", - "integrity": "sha512-GiWr7GfJLVfcopL3t3pLumXCYs8sgWppjIA1F/Cc3zIMgD3tmkpyZ1xkm1Tej8mw53B93JsDjgA3KOftuYcfOw==", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "~13.1.0", - "glob": "~11.0.2", - "ignore": "~7.0.4", - "js-yaml": "~4.1.0", - "jsonc-parser": "~3.3.1", - "jsonpointer": "~5.0.1", - "markdown-it": "~14.1.0", - "markdownlint": "~0.38.0", - "minimatch": "~10.0.1", - "run-con": "~1.3.2", - "smol-toml": "~1.3.4" - }, - "bin": { - "markdownlint": "markdownlint.js" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/markdownlint-cli/node_modules/commander": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", - "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/markdownlint-cli/node_modules/glob": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", - "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.3.1", - "jackspeak": "^4.1.1", - "minimatch": "^10.0.3", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/markdownlint-cli/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/markdownlint-cli/node_modules/jsonc-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", - "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/marked": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", - "license": "MIT", - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/material-icon-theme": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/material-icon-theme/-/material-icon-theme-5.24.0.tgz", - "integrity": "sha512-fKCtRSOZwSMipgfsisDtlERXndg7hu4Ykhw8Vr+92NFVhYAi3izRHyKg6YooTw6yIB8fMF6Gq8IeNhbRxRY2SQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "chroma-js": "^3.0.0", - "events": "^3.3.0", - "fast-deep-equal": "^3.1.3", - "svgson": "^5.3.1" - }, - "engines": { - "vscode": "^1.55.0" - }, - "funding": { - "url": "https://github.com/sponsors/material-extensions" - } - }, - "node_modules/mathml-tag-names": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", - "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/mdn-data": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", - "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", - "dev": true, - "license": "MIT" - }, - "node_modules/meow": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", - "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/mermaid": { - "version": "11.9.0", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.9.0.tgz", - "integrity": "sha512-YdPXn9slEwO0omQfQIsW6vS84weVQftIyyTGAZCwM//MGhPzL1+l6vO6bkf0wnP4tHigH1alZ5Ooy3HXI2gOag==", - "license": "MIT", - "dependencies": { - "@braintree/sanitize-url": "^7.0.4", - "@iconify/utils": "^2.1.33", - "@mermaid-js/parser": "^0.6.2", - "@types/d3": "^7.4.3", - "cytoscape": "^3.29.3", - "cytoscape-cose-bilkent": "^4.1.0", - "cytoscape-fcose": "^2.2.0", - "d3": "^7.9.0", - "d3-sankey": "^0.12.3", - "dagre-d3-es": "7.0.11", - "dayjs": "^1.11.13", - "dompurify": "^3.2.5", - "katex": "^0.16.22", - "khroma": "^2.1.0", - "lodash-es": "^4.17.21", - "marked": "^16.0.0", - "roughjs": "^4.6.6", - "stylis": "^4.3.6", - "ts-dedent": "^2.2.0", - "uuid": "^11.1.0" - } - }, - "node_modules/mermaid/node_modules/marked": { - "version": "16.1.1", - "resolved": "https://registry.npmjs.org/marked/-/marked-16.1.1.tgz", - "integrity": "sha512-ij/2lXfCRT71L6u0M29tJPhP0bM5shLL3u5BePhFwPELj2blMJ6GDtD7PfJhRLhJ/c2UwrK17ySVcDzy2YHjHQ==", - "license": "MIT", - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/micromark": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-4.0.0.tgz", - "integrity": "sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "parse-entities": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", - "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", - "dev": true, - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", - "dev": true, - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", - "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", - "dev": true, - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-math": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", - "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/katex": "^0.16.0", - "devlop": "^1.0.0", - "katex": "^0.16.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", - "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/mini-css-extract-plugin": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", - "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", - "license": "MIT", - "dependencies": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", - "license": "ISC", - "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mlly": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", - "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", - "license": "MIT", - "dependencies": { - "acorn": "^8.14.0", - "pathe": "^2.0.1", - "pkg-types": "^1.3.0", - "ufo": "^1.5.4" - } - }, - "node_modules/mlly/node_modules/confbox": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", - "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", - "license": "MIT" - }, - "node_modules/mlly/node_modules/pkg-types": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", - "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", - "license": "MIT", - "dependencies": { - "confbox": "^0.1.8", - "mlly": "^1.7.4", - "pathe": "^2.0.1" - } - }, - "node_modules/monaco-editor": { - "version": "0.52.2", - "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz", - "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==", - "license": "MIT" - }, - "node_modules/monaco-editor-webpack-plugin": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-7.1.0.tgz", - "integrity": "sha512-ZjnGINHN963JQkFqjjcBtn1XBtUATDZBMgNQhDQwd78w2ukRhFXAPNgWuacaQiDZsUr4h1rWv5Mv6eriKuOSzA==", - "license": "MIT", - "dependencies": { - "loader-utils": "^2.0.2" - }, - "peerDependencies": { - "monaco-editor": ">= 0.31.0", - "webpack": "^4.5.0 || 5.x" - } - }, - "node_modules/moo": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", - "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", - "license": "BSD-3-Clause" - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/muggle-string": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", - "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/nanopop": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/nanopop/-/nanopop-2.3.0.tgz", - "integrity": "sha512-fzN+T2K7/Ah25XU02MJkPZ5q4Tj5FpjmIYq4rvoHX4yb16HzFdCO6JxFFn5Y/oBhQ8no8fUZavnyIv9/+xkBBw==", - "license": "MIT" - }, - "node_modules/napi-postinstall": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.2.tgz", - "integrity": "sha512-tWVJxJHmBWLy69PvO96TZMZDrzmw5KeiZBz3RHmiM2XZ9grBJ2WgMAFVVg25nqp3ZjTFUs2Ftw1JhscL3Teliw==", - "dev": true, - "license": "MIT", - "bin": { - "napi-postinstall": "lib/cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/napi-postinstall" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "license": "MIT" - }, - "node_modules/nimma": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/nimma/-/nimma-0.2.3.tgz", - "integrity": "sha512-1ZOI8J+1PKKGceo/5CT5GfQOG6H8I2BencSK06YarZ2wXwH37BSSUWldqJmMJYA5JfqDqffxDXynt6f11AyKcA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsep-plugin/regex": "^1.0.1", - "@jsep-plugin/ternary": "^1.0.2", - "astring": "^1.8.1", - "jsep": "^1.2.0" - }, - "engines": { - "node": "^12.20 || >=14.13" - }, - "optionalDependencies": { - "jsonpath-plus": "^6.0.1 || ^10.1.0", - "lodash.topath": "^4.5.2" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "license": "MIT" - }, - "node_modules/node-sarif-builder": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/node-sarif-builder/-/node-sarif-builder-2.0.3.tgz", - "integrity": "sha512-Pzr3rol8fvhG/oJjIq2NTVB0vmdNNlz22FENhhPojYRZ4/ee08CfK4YuKmuL54V9MLhI1kpzxfOJ/63LzmZzDg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/sarif": "^2.1.4", - "fs-extra": "^10.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/nolyfill": { - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/nolyfill/-/nolyfill-1.0.44.tgz", - "integrity": "sha512-PoggwVLiJUn0MnodpftsiC7EuknW5+6v62ntTOQ6T6l7g2r6aoaOwgk0tQW2BxGLYw9bF298LL8jDFTmEFuzlA==", - "dev": true, - "license": "MIT", - "bin": { - "nolyfill": "bin/nolyfill.js" - }, - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/obj-props": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.4.0.tgz", - "integrity": "sha512-p7p/7ltzPDiBs6DqxOrIbtRdwxxVRBj5ROukeNb9RgA+fawhrz5n2hpNz8DDmYR//tviJSj7nUnlppGmONkjiQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/object.assign": { - "name": "@nolyfill/object.assign", - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/@nolyfill/object.assign/-/object.assign-1.0.44.tgz", - "integrity": "sha512-cZoXq09YZXDgkxRMAP/TTb3kAsWm7p5OyBugWDe4fOfxf0XRI55mgDSkuyq41sV1qW1zVC5aSsKEh1hQo1KOvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nolyfill/shared": "1.0.44" - }, - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/object.fromentries": { - "name": "@nolyfill/object.fromentries", - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/@nolyfill/object.fromentries/-/object.fromentries-1.0.44.tgz", - "integrity": "sha512-/LrsCtpLmByZ6GwP/NeXULSgMyNsVr5d6FlgQy1HZatAiBc8c+WZ1VmFkK19ZLXCNNXBedXDultrp0x4Nz+QQw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nolyfill/shared": "1.0.44" - }, - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/object.groupby": { - "name": "@nolyfill/object.groupby", - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/@nolyfill/object.groupby/-/object.groupby-1.0.44.tgz", - "integrity": "sha512-jCt/8pN+10mlbeg0ZESpVVaqn5qqpv6kpjM+GDfEP7cXGDSPlIjtvfYWRZK4k4Gftkhhgqkzvcrr8z1wuNO1TQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nolyfill/shared": "1.0.44" - }, - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/object.values": { - "name": "@nolyfill/object.values", - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/@nolyfill/object.values/-/object.values-1.0.44.tgz", - "integrity": "sha512-bwIpVzFMudUC0ofnvdSDB/OyGUizcU+r32ZZ0QTMbN03gUttMtdCFDekuSYT0XGFgufTQyZ4ONBnAeb3DFCPGQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nolyfill/shared": "1.0.44" - }, - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/online-3d-viewer": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/online-3d-viewer/-/online-3d-viewer-0.16.0.tgz", - "integrity": "sha512-Mcmo41TM3K+svlMDRH8ySKSY2e8s7Sssdb5U9LV3gkFKVWGGuS304Vk5gqxopAJbE72DpsC67Ve3YNtcAuROwQ==", - "license": "MIT", - "dependencies": { - "@simonwep/pickr": "1.9.0", - "fflate": "0.8.2", - "three": "0.176.0" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "license": "BlueOak-1.0.0" - }, - "node_modules/package-manager-detector": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.3.0.tgz", - "integrity": "sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==", - "license": "MIT" - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-entities": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", - "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-data-parser": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz", - "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==", - "license": "MIT" - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "license": "MIT" - }, - "node_modules/path-scurry": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", - "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "license": "MIT" - }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16" - } - }, - "node_modules/pdfobject": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/pdfobject/-/pdfobject-2.3.1.tgz", - "integrity": "sha512-vluuGiSDmMGpOvWFGiUY4trNB8aGKLDVxIXuuGHjX0kK3bMxCANUVtLivctE7uejLBScWCnbVarKatFVvdwXaQ==", - "license": "MIT" - }, - "node_modules/perfect-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", - "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pirates": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.2.0.tgz", - "integrity": "sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ==", - "license": "MIT", - "dependencies": { - "confbox": "^0.2.2", - "exsolve": "^1.0.7", - "pathe": "^2.0.3" - } - }, - "node_modules/playwright": { - "version": "1.54.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.54.1.tgz", - "integrity": "sha512-peWpSwIBmSLi6aW2auvrUtf2DqY16YYcCMO8rTVx486jKmDTJg7UAhyrraP98GB8BoPURZP8+nxO7TSd4cPr5g==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "playwright-core": "1.54.1" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "fsevents": "2.3.2" - } - }, - "node_modules/playwright-core": { - "version": "1.54.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.54.1.tgz", - "integrity": "sha512-Nbjs2zjj0htNhzgiy5wu+3w09YetDx5pkrpI/kZotDlDUaYk0HVA5xrBVPdow4SAUIlhgKcJeJg4GRKW6xHusA==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "playwright-core": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/points-on-curve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz", - "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==", - "license": "MIT" - }, - "node_modules/points-on-path": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz", - "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", - "license": "MIT", - "dependencies": { - "path-data-parser": "0.1.0", - "points-on-curve": "0.2.0" - } - }, - "node_modules/pony-cause": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pony-cause/-/pony-cause-1.1.1.tgz", - "integrity": "sha512-PxkIc/2ZpLiEzQXu5YRDOUgBlfGYBY8156HY5ZcRAwwonMk5W/MrJP2LLkG/hF7GEQzaHo2aS7ho6ZLCOvf+6g==", - "dev": true, - "license": "0BSD", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-html": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.8.0.tgz", - "integrity": "sha512-5mMeb1TgLWoRKxZ0Xh9RZDfwUUIqRrcxO2uXO+Ezl1N5lqpCiSU5Gk6+1kZediBfBHFtPCdopr2UZ2SgUsKcgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "htmlparser2": "^8.0.0", - "js-tokens": "^9.0.0", - "postcss": "^8.5.0", - "postcss-safe-parser": "^6.0.0" - }, - "engines": { - "node": "^12 || >=14" - } - }, - "node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "license": "MIT", - "dependencies": { - "camelcase-css": "^2.0.1" - }, - "engines": { - "node": "^12 || ^14 || >= 16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.4.21" - } - }, - "node_modules/postcss-loader": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz", - "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==", - "license": "MIT", - "dependencies": { - "cosmiconfig": "^9.0.0", - "jiti": "^1.20.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", - "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", - "license": "ISC", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", - "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", - "license": "MIT", - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^7.0.0", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", - "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", - "license": "ISC", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "license": "ISC", - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-nested": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", - "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.1.1" - }, - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-nested/node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-nesting": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.2.tgz", - "integrity": "sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/selector-resolve-nested": "^3.1.0", - "@csstools/selector-specificity": "^5.0.0", - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-resolve-nested-selector": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", - "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", - "dev": true, - "license": "MIT" - }, - "node_modules/postcss-safe-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", - "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.3.3" - } - }, - "node_modules/postcss-scss": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz", - "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss-scss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.4.29" - } - }, - "node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-styl": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/postcss-styl/-/postcss-styl-0.12.3.tgz", - "integrity": "sha512-8I7Cd8sxiEITIp32xBK4K/Aj1ukX6vuWnx8oY/oAH35NfQI4OZaY5nd68Yx8HeN5S49uhQ6DL0rNk0ZBu/TaLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.1", - "fast-diff": "^1.2.0", - "lodash.sortedlastindex": "^4.1.0", - "postcss": "^7.0.27 || ^8.0.0", - "stylus": "^0.57.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || ^11.10.1 || >=12.13.0" - }, - "funding": { - "url": "https://opencollective.com/stylus" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "license": "MIT" - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", - "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/printable-characters": { - "version": "1.0.42", - "resolved": "https://registry.npmjs.org/printable-characters/-/printable-characters-1.0.42.tgz", - "integrity": "sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==", - "dev": true, - "license": "Unlicense" - }, - "node_modules/proto-props": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/proto-props/-/proto-props-2.0.0.tgz", - "integrity": "sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/punycode.js": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", - "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/quansync": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.10.tgz", - "integrity": "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/antfu" - }, - { - "type": "individual", - "url": "https://github.com/sponsors/sxzz" - } - ], - "license": "MIT" - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "license": "MIT", - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "license": "MIT", - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/refa": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/refa/-/refa-0.12.1.tgz", - "integrity": "sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.8.0" - }, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/regexp-ast-analysis": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.7.1.tgz", - "integrity": "sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.8.0", - "refa": "^0.12.1" - }, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/regexp-tree": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", - "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", - "dev": true, - "license": "MIT", - "bin": { - "regexp-tree": "bin/regexp-tree" - } - }, - "node_modules/regjsparser": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz", - "integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/rename-keys": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/rename-keys/-/rename-keys-1.2.0.tgz", - "integrity": "sha512-U7XpAktpbSgHTRSNRrjKSrjYkZKuhUukfoBlXWXUExCAqhzh1TU3BDRAfJmarcl5voKS+pbKU9MvyLWKZ4UEEg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "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==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/reserved": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/reserved/-/reserved-0.1.2.tgz", - "integrity": "sha512-/qO54MWj5L8WCBP9/UNe2iefJc+L9yETbH32xO/ft/EYPOTCR5k+azvDUgdCOKwZH8hXwPd0b8XBL78Nn2U69g==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/robust-predicates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", - "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", - "license": "Unlicense" - }, - "node_modules/rollup": { - "version": "2.79.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", - "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", - "dev": true, - "license": "MIT", - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=10.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/roughjs": { - "version": "4.6.6", - "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz", - "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", - "license": "MIT", - "dependencies": { - "hachure-fill": "^0.5.2", - "path-data-parser": "^0.1.0", - "points-on-curve": "^0.2.0", - "points-on-path": "^0.2.1" - } - }, - "node_modules/run-con": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz", - "integrity": "sha512-CcfE+mYiTcKEzg0IqS08+efdnH0oJ3zV0wSUFBNrMHMuxCtXvBCLzCJHatwuXDcu/RlhjTziTo/a1ruQik6/Yg==", - "dev": true, - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~4.1.0", - "minimist": "^1.2.8", - "strip-json-comments": "~3.1.1" - }, - "bin": { - "run-con": "cli.js" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rw": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", - "license": "BSD-3-Clause" - }, - "node_modules/safe-buffer": { - "name": "@nolyfill/safe-buffer", - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/@nolyfill/safe-buffer/-/safe-buffer-1.0.44.tgz", - "integrity": "sha512-SqlKXtlhNTDMeZKey9jnnuPhi8YTl1lJuEcY9zbm5i4Pqe79UJJ8IJ9oiD6DhgI8KjYc+HtLzpQJNRdNYqb/hw==", - "license": "MIT", - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/safe-regex-test": { - "name": "@nolyfill/safe-regex-test", - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/@nolyfill/safe-regex-test/-/safe-regex-test-1.0.44.tgz", - "integrity": "sha512-Q6veatd1NebtD8Sre6zjvO35QzG21IskMVOOEbePFcNO9noanNJgsqHeOCr0c5yZz6Z0DAizLg2gIZWokJSkXw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/safe-stable-stringify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", - "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==", - "dev": true, - "license": "MIT" - }, - "node_modules/safer-buffer": { - "name": "@nolyfill/safer-buffer", - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/@nolyfill/safer-buffer/-/safer-buffer-1.0.44.tgz", - "integrity": "sha512-Ouw1fMwjAy1V4MpnDASfu1DCPgkP0nNFteiiWbFoEGSqa7Vnmkb6if2c522N2WcMk+RuaaabQbC1F1D4/kTXcg==", - "license": "MIT", - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, - "license": "ISC" - }, - "node_modules/schema-utils": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", - "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/scslre": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/scslre/-/scslre-0.3.0.tgz", - "integrity": "sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.8.0", - "refa": "^0.12.0", - "regexp-ast-analysis": "^0.7.0" - }, - "engines": { - "node": "^14.0.0 || >=16.0.0" - } - }, - "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/seroval": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.3.2.tgz", - "integrity": "sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/seroval-plugins": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.3.2.tgz", - "integrity": "sha512-0QvCV2lM3aj/U3YozDiVwx9zpH0q8A60CTWIv4Jszj/givcudPb48B+rkU5D51NJ0pTpweGMttHjboPa9/zoIQ==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "seroval": "^1.0" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true, - "license": "ISC" - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/simple-eval": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-eval/-/simple-eval-1.0.1.tgz", - "integrity": "sha512-LH7FpTAkeD+y5xQC4fzS+tFtaNlvt3Ib1zKzvhjv/Y+cioV4zIuw4IZr2yhRLu67CWL7FR9/6KXKnjRoZTvGGQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "jsep": "^1.3.6" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/smol-toml": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.3.4.tgz", - "integrity": "sha512-UOPtVuYkzYGee0Bd2Szz8d2G3RfMfJ2t3qVdZUAozZyAk+a0Sxa+QKix0YCwjL/A1RR0ar44nCxaoN9FxdJGwA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 18" - }, - "funding": { - "url": "https://github.com/sponsors/cyyynthia" - } - }, - "node_modules/solid-js": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.7.tgz", - "integrity": "sha512-/saTKi8iWEM233n5OSi1YHCCuh66ZIQ7aK2hsToPe4tqGm7qAejU1SwNuTPivbWAYq7SjuHVVYxxuZQNRbICiw==", - "license": "MIT", - "dependencies": { - "csstype": "^3.1.0", - "seroval": "~1.3.0", - "seroval-plugins": "~1.3.0" - } - }, - "node_modules/sortablejs": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.6.tgz", - "integrity": "sha512-aNfiuwMEpfBM/CN6LY0ibyhxPfPbyFeBTYJKCvzkJ2GkUpazIt3H+QIPAMHwqQ7tMKaHz1Qj+rJJCqljnf4p3A==", - "license": "MIT" - }, - "node_modules/source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "license": "MIT" - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", - "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "license": "MIT", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "deprecated": "Please use @jridgewell/sourcemap-codec instead", - "dev": true, - "license": "MIT" - }, - "node_modules/spdx-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz", - "integrity": "sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==", - "license": "MIT", - "dependencies": { - "array-find-index": "^1.0.2", - "spdx-expression-parse": "^3.0.0", - "spdx-ranges": "^2.0.0" - } - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-expression-validate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-validate/-/spdx-expression-validate-2.0.0.tgz", - "integrity": "sha512-b3wydZLM+Tc6CFvaRDBOF9d76oGIHNCLYFeHbftFXUWjnfZWganmDmvtM5sm1cRwJc/VDBMLyGGrsLFd1vOxbg==", - "license": "(MIT AND CC-BY-3.0)", - "dependencies": { - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.21", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", - "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", - "license": "CC0-1.0" - }, - "node_modules/spdx-ranges": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz", - "integrity": "sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==", - "license": "(MIT AND CC-BY-3.0)" - }, - "node_modules/spdx-satisfies": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/spdx-satisfies/-/spdx-satisfies-5.0.1.tgz", - "integrity": "sha512-Nwor6W6gzFp8XX4neaKQ7ChV4wmpSh2sSDemMFSzHxpTw460jxFYeOn+jq4ybnSSw/5sc3pjka9MQPouksQNpw==", - "license": "MIT", - "dependencies": { - "spdx-compare": "^1.0.0", - "spdx-expression-parse": "^3.0.0", - "spdx-ranges": "^2.0.0" - } - }, - "node_modules/stable-hash-x": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", - "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true, - "license": "MIT" - }, - "node_modules/stacktracey": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/stacktracey/-/stacktracey-2.1.8.tgz", - "integrity": "sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==", - "dev": true, - "license": "Unlicense", - "dependencies": { - "as-table": "^1.0.36", - "get-source": "^2.0.12" - } - }, - "node_modules/std-env": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", - "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", - "dev": true, - "license": "MIT" - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/string-width/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/string.prototype.includes": { - "name": "@nolyfill/string.prototype.includes", - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/@nolyfill/string.prototype.includes/-/string.prototype.includes-1.0.44.tgz", - "integrity": "sha512-d1t7rnoAYyoap0X3a/gCnusCvxzK6v7uMFzW8k0mI2WtAK8HiKuzaQUwAriyVPh63GsvQCqvXx8Y5gtdh4LjSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nolyfill/shared": "1.0.44" - }, - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/string.prototype.trimend": { - "name": "@nolyfill/string.prototype.trimend", - "version": "1.0.44", - "resolved": "https://registry.npmjs.org/@nolyfill/string.prototype.trimend/-/string.prototype.trimend-1.0.44.tgz", - "integrity": "sha512-3dsKlf4Ma7o+uxLIg5OI1Tgwfet2pE8WTbPjEGWvOe6CSjMtK0skJnnSVHaEVX4N4mYU81To0qDeZOPqjaUotg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nolyfill/shared": "1.0.44" - }, - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-literal": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", - "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", - "dev": true, - "license": "MIT", - "dependencies": { - "js-tokens": "^9.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/style-search": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", - "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==", - "dev": true, - "license": "ISC" - }, - "node_modules/stylelint": { - "version": "16.23.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.23.0.tgz", - "integrity": "sha512-69T5aS2LUY306ekt1Q1oaSPwz/jaG9HjyMix3UMrai1iEbuOafBe2Dh8xlyczrxFAy89qcKyZWWtc42XLx3Bbw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/stylelint" - }, - { - "type": "github", - "url": "https://github.com/sponsors/stylelint" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/media-query-list-parser": "^4.0.3", - "@csstools/selector-specificity": "^5.0.0", - "@dual-bundle/import-meta-resolve": "^4.1.0", - "balanced-match": "^2.0.0", - "colord": "^2.9.3", - "cosmiconfig": "^9.0.0", - "css-functions-list": "^3.2.3", - "css-tree": "^3.1.0", - "debug": "^4.4.1", - "fast-glob": "^3.3.3", - "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^10.1.3", - "global-modules": "^2.0.0", - "globby": "^11.1.0", - "globjoin": "^0.1.4", - "html-tags": "^3.3.1", - "ignore": "^7.0.5", - "imurmurhash": "^0.1.4", - "is-plain-object": "^5.0.0", - "known-css-properties": "^0.37.0", - "mathml-tag-names": "^2.1.3", - "meow": "^13.2.0", - "micromatch": "^4.0.8", - "normalize-path": "^3.0.0", - "picocolors": "^1.1.1", - "postcss": "^8.5.6", - "postcss-resolve-nested-selector": "^0.1.6", - "postcss-safe-parser": "^7.0.1", - "postcss-selector-parser": "^7.1.0", - "postcss-value-parser": "^4.2.0", - "resolve-from": "^5.0.0", - "string-width": "^4.2.3", - "supports-hyperlinks": "^3.2.0", - "svg-tags": "^1.0.0", - "table": "^6.9.0", - "write-file-atomic": "^5.0.1" - }, - "bin": { - "stylelint": "bin/stylelint.mjs" - }, - "engines": { - "node": ">=18.12.0" - } - }, - "node_modules/stylelint-config-recommended": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-17.0.0.tgz", - "integrity": "sha512-WaMSdEiPfZTSFVoYmJbxorJfA610O0tlYuU2aEwY33UQhSPgFbClrVJYWvy3jGJx+XW37O+LyNLiZOEXhKhJmA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/stylelint" - }, - { - "type": "github", - "url": "https://github.com/sponsors/stylelint" - } - ], - "license": "MIT", - "engines": { - "node": ">=18.12.0" - }, - "peerDependencies": { - "stylelint": "^16.23.0" - } - }, - "node_modules/stylelint-declaration-block-no-ignored-properties": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/stylelint-declaration-block-no-ignored-properties/-/stylelint-declaration-block-no-ignored-properties-2.8.0.tgz", - "integrity": "sha512-Ws8Cav7Y+SPN0JsV407LrnNXWOrqGjxShf+37GBtnU/C58Syve9c0+I/xpLcFOosST3ternykn3Lp77f3ITnFw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "stylelint": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" - } - }, - "node_modules/stylelint-declaration-strict-value": { - "version": "1.10.11", - "resolved": "https://registry.npmjs.org/stylelint-declaration-strict-value/-/stylelint-declaration-strict-value-1.10.11.tgz", - "integrity": "sha512-oVQvhZlFZAiDz9r2BPFZLtTGm1A2JVhdKObKAJoTjFfR4F/NpApC4bMBTxf4sZS76Na3njYKVOaAaKSZ4+FU+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12.0" - }, - "peerDependencies": { - "stylelint": ">=7 <=16" - } - }, - "node_modules/stylelint-define-config": { - "version": "16.22.0", - "resolved": "https://registry.npmjs.org/stylelint-define-config/-/stylelint-define-config-16.22.0.tgz", - "integrity": "sha512-EEgHRugsryKo7LpenYyd4yLoZon3lHvRAi7WsMaZoRX9GPOkeDXrMga+N4VA4nK4Zus02EQwyYkndNQ64jaB2A==", - "dev": true, - "license": "MIT", - "dependencies": { - "csstype": "^3.1.3" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=9.0.0", - "pnpm": ">=8.6.0" - }, - "peerDependencies": { - "stylelint": ">=16.0.0" - } - }, - "node_modules/stylelint-value-no-unknown-custom-properties": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/stylelint-value-no-unknown-custom-properties/-/stylelint-value-no-unknown-custom-properties-6.0.1.tgz", - "integrity": "sha512-N60PTdaTknB35j6D4FhW0GL2LlBRV++bRpXMMldWMQZ240yFQaoltzlLY4lXXs7Z0J5mNUYZQ/gjyVtU2DhCMA==", - "dev": true, - "license": "CC0-1.0", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "resolve": "^1.22.8" - }, - "engines": { - "node": ">=18.12.0" - }, - "peerDependencies": { - "stylelint": ">=16" - } - }, - "node_modules/stylelint/node_modules/file-entry-cache": { - "version": "10.1.3", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-10.1.3.tgz", - "integrity": "sha512-D+w75Ub8T55yor7fPgN06rkCAUbAYw2vpxJmmjv/GDAcvCnv9g7IvHhIZoxzRZThrXPFI2maeY24pPbtyYU7Lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^6.1.12" - } - }, - "node_modules/stylelint/node_modules/flat-cache": { - "version": "6.1.12", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.12.tgz", - "integrity": "sha512-U+HqqpZPPXP5d24bWuRzjGqVqUcw64k4nZAbruniDwdRg0H10tvN7H6ku1tjhA4rg5B9GS3siEvwO2qjJJ6f8Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "cacheable": "^1.10.3", - "flatted": "^3.3.3", - "hookified": "^1.10.0" - } - }, - "node_modules/stylelint/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/stylelint/node_modules/postcss-safe-parser": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz", - "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/stylelint/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/stylis": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", - "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", - "license": "MIT" - }, - "node_modules/stylus": { - "version": "0.57.0", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.57.0.tgz", - "integrity": "sha512-yOI6G8WYfr0q8v8rRvE91wbxFU+rJPo760Va4MF6K0I6BZjO4r+xSynkvyPBP9tV1CIEUeRsiidjIs2rzb1CnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "css": "^3.0.0", - "debug": "^4.3.2", - "glob": "^7.1.6", - "safer-buffer": "^2.1.2", - "sax": "~1.2.4", - "source-map": "^0.7.3" - }, - "bin": { - "stylus": "bin/stylus" - }, - "engines": { - "node": "*" - } - }, - "node_modules/stylus/node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 12" - } - }, - "node_modules/sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^10.3.10", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/sucrase/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/sucrase/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/sucrase/node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/sucrase/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/sucrase/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/sucrase/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" - }, - "node_modules/sucrase/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/sucrase/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/superstruct": { - "version": "0.10.13", - "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.10.13.tgz", - "integrity": "sha512-W4SitSZ9MOyMPbHreoZVEneSZyPEeNGbdfJo/7FkJyRs/M3wQRFzq+t3S/NBwlrFSWdx1ONLjLb9pB+UKe4IqQ==", - "license": "MIT" - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", - "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=14.18" - }, - "funding": { - "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svg-element-attributes": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/svg-element-attributes/-/svg-element-attributes-1.3.1.tgz", - "integrity": "sha512-Bh05dSOnJBf3miNMqpsormfNtfidA/GxQVakhtn0T4DECWKeXQRQUceYjJ+OxYiiLdGe4Jo9iFV8wICFapFeIA==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/svg-tags": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", - "dev": true - }, - "node_modules/svgo": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.0.tgz", - "integrity": "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "^11.1.0", - "css-select": "^5.1.0", - "css-tree": "^3.0.1", - "css-what": "^6.1.0", - "csso": "^5.0.5", - "picocolors": "^1.1.1", - "sax": "^1.4.1" - }, - "bin": { - "svgo": "bin/svgo.js" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/svgo" - } - }, - "node_modules/svgo/node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - } - }, - "node_modules/svgo/node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", - "dev": true, - "license": "ISC" - }, - "node_modules/svgson": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/svgson/-/svgson-5.3.1.tgz", - "integrity": "sha512-qdPgvUNWb40gWktBJnbJRelWcPzkLed/ShhnRsjbayXz8OtdPOzbil9jtiZdrYvSDumAz/VNQr6JaNfPx/gvPA==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-rename-keys": "^0.2.1", - "xml-reader": "2.4.3" - } - }, - "node_modules/swagger-ui-dist": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.27.0.tgz", - "integrity": "sha512-tS6LRyBhY6yAqxrfsA9IYpGWPUJOri6sclySa7TdC7XQfGLvTwDY531KLgfQwHEtQsn+sT4JlUspbeQDBVGWig==", - "license": "Apache-2.0", - "dependencies": { - "@scarf/scarf": "=1.4.0" - } - }, - "node_modules/sync-fetch": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/sync-fetch/-/sync-fetch-0.4.5.tgz", - "integrity": "sha512-esiWJ7ixSKGpd9DJPBTC4ckChqdOjIwJfYhVHkcQ2Gnm41323p1TRmEI+esTQ9ppD+b5opps2OTEGTCGX5kF+g==", - "license": "MIT", - "dependencies": { - "buffer": "^5.7.1", - "node-fetch": "^2.6.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/synckit": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", - "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@pkgr/core": "^0.2.9" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/synckit" - } - }, - "node_modules/table": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", - "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/tailwindcss": { - "version": "3.4.17", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", - "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", - "license": "MIT", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.6.0", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.2", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.6", - "lilconfig": "^3.1.3", - "micromatch": "^4.0.8", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.1.1", - "postcss": "^8.4.47", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.2", - "postcss-nested": "^6.2.0", - "postcss-selector-parser": "^6.1.2", - "resolve": "^1.22.8", - "sucrase": "^3.35.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tailwindcss/node_modules/postcss-load-config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", - "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "lilconfig": "^3.0.0", - "yaml": "^2.3.4" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/tailwindcss/node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tapable": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", - "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/terser": { - "version": "5.43.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", - "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", - "license": "BSD-2-Clause", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.14.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.14", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", - "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "jest-worker": "^27.4.5", - "schema-utils": "^4.3.0", - "serialize-javascript": "^6.0.2", - "terser": "^5.31.1" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "license": "MIT", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/three": { - "version": "0.176.0", - "resolved": "https://registry.npmjs.org/three/-/three-0.176.0.tgz", - "integrity": "sha512-PWRKYWQo23ojf9oZSlRGH8K09q7nRSWx6LY/HF/UUrMdYgN9i1e2OwJYHoQjwc6HF/4lvvYLC5YC1X8UJL2ZpA==", - "license": "MIT" - }, - "node_modules/throttle-debounce": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz", - "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==", - "license": "MIT", - "engines": { - "node": ">=12.22" - } - }, - "node_modules/tinybench": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", - "dev": true, - "license": "MIT" - }, - "node_modules/tinycolor2": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", - "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", - "license": "MIT" - }, - "node_modules/tinyexec": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", - "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", - "license": "MIT" - }, - "node_modules/tinyglobby": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", - "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.4.4", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", - "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/tinypool": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, - "node_modules/tinyrainbow": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", - "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz", - "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tippy.js": { - "version": "6.3.7", - "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", - "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==", - "license": "MIT", - "dependencies": { - "@popperjs/core": "^2.9.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toastify-js": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/toastify-js/-/toastify-js-1.12.0.tgz", - "integrity": "sha512-HeMHCO9yLPvP9k0apGSdPUWrUbLnxUKNFzgUoZp1PHCLploIX/4DSQ7V8H25ef+h4iO9n0he7ImfcndnN6nDrQ==", - "license": "MIT" - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/tributejs": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/tributejs/-/tributejs-5.1.3.tgz", - "integrity": "sha512-B5CXihaVzXw+1UHhNFyAwUTMDk1EfoLP5Tj1VhD9yybZ1I8DZJEv8tZ1l0RJo0t0tk9ZhR8eG5tEsaCvRigmdQ==", - "license": "MIT" - }, - "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" - } - }, - "node_modules/ts-dedent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", - "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", - "license": "MIT", - "engines": { - "node": ">=6.10" - } - }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "license": "Apache-2.0" - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, - "license": "0BSD" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typo-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.3.0.tgz", - "integrity": "sha512-ERVoYp5PG7jpj7+kzKmFZfp5+IYMOOQM3etNnlYu06Z2CL5UmC9ekT8Z/JVYpR7e7sXB4bOFq1fz/budv++Z0g==", - "license": "BSD-3-Clause" - }, - "node_modules/uc.micro": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", - "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "dev": true, - "license": "MIT" - }, - "node_modules/ufo": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", - "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", - "license": "MIT" - }, - "node_modules/uint8-to-base64": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/uint8-to-base64/-/uint8-to-base64-0.2.1.tgz", - "integrity": "sha512-uO/84GaoDUfiAxpa8EksjVLE77A9Kc7ZTziN4zRpq4de9yLaLcZn3jx1/sVjyupsywcVX6RKWbqLe7gUNyzH+Q==", - "license": "ISC" - }, - "node_modules/undici-types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", - "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", - "license": "MIT" - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unrs-resolver": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", - "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "napi-postinstall": "^0.3.0" - }, - "funding": { - "url": "https://opencollective.com/unrs-resolver" - }, - "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.11.1", - "@unrs/resolver-binding-android-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-x64": "1.11.1", - "@unrs/resolver-binding-freebsd-x64": "1.11.1", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", - "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-musl": "1.11.1", - "@unrs/resolver-binding-wasm32-wasi": "1.11.1", - "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", - "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", - "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/updates": { - "version": "16.5.2", - "resolved": "https://registry.npmjs.org/updates/-/updates-16.5.2.tgz", - "integrity": "sha512-CyxIT9TvUGe62hNWXW5FjbgNd8cPucqO5yrihmf+WgMtSUj31b4HyPuMsozxTnO0XQhTTLShIyV7ySJSSC5dsg==", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "updates": "dist/index.js" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urijs": { - "version": "1.19.11", - "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", - "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/utility-types": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", - "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/esm/bin/uuid" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/validate-npm-package-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==", - "dev": true, - "license": "ISC", - "dependencies": { - "builtins": "^1.0.3" - } - }, - "node_modules/vanilla-colorful": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/vanilla-colorful/-/vanilla-colorful-0.7.2.tgz", - "integrity": "sha512-z2YZusTFC6KnLERx1cgoIRX2CjPRP0W75N+3CC6gbvdX5Ch47rZkEMGO2Xnf+IEmi3RiFLxS18gayMA27iU7Kg==", - "license": "MIT" - }, - "node_modules/vite": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.6.tgz", - "integrity": "sha512-MHFiOENNBd+Bd9uvc8GEsIzdkn1JxMmEeYX35tI3fv0sJBUTfW5tQsoaOwuY4KhBI09A3dUJ/DXf2yxPVPUceg==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.4.6", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.40.0", - "tinyglobby": "^0.2.14" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", - "lightningcss": "^1.21.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/vite-node": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", - "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.4.1", - "es-module-lexer": "^1.7.0", - "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/vite-string-plugin": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/vite-string-plugin/-/vite-string-plugin-1.4.6.tgz", - "integrity": "sha512-Csjtny8/uVIynzlaRRj4RpHrPAakNwlH9jw6kgQ8tQhc2f0zzA6bCbAgWD0y84EgB8aLNrz7pZFUqSt3LOtk+w==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/vite/node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/vite/node_modules/fdir": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", - "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/vite/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/vite/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/vite/node_modules/rollup": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz", - "integrity": "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.46.2", - "@rollup/rollup-android-arm64": "4.46.2", - "@rollup/rollup-darwin-arm64": "4.46.2", - "@rollup/rollup-darwin-x64": "4.46.2", - "@rollup/rollup-freebsd-arm64": "4.46.2", - "@rollup/rollup-freebsd-x64": "4.46.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.46.2", - "@rollup/rollup-linux-arm-musleabihf": "4.46.2", - "@rollup/rollup-linux-arm64-gnu": "4.46.2", - "@rollup/rollup-linux-arm64-musl": "4.46.2", - "@rollup/rollup-linux-loongarch64-gnu": "4.46.2", - "@rollup/rollup-linux-ppc64-gnu": "4.46.2", - "@rollup/rollup-linux-riscv64-gnu": "4.46.2", - "@rollup/rollup-linux-riscv64-musl": "4.46.2", - "@rollup/rollup-linux-s390x-gnu": "4.46.2", - "@rollup/rollup-linux-x64-gnu": "4.46.2", - "@rollup/rollup-linux-x64-musl": "4.46.2", - "@rollup/rollup-win32-arm64-msvc": "4.46.2", - "@rollup/rollup-win32-ia32-msvc": "4.46.2", - "@rollup/rollup-win32-x64-msvc": "4.46.2", - "fsevents": "~2.3.2" - } - }, - "node_modules/vitest": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", - "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.4", - "@vitest/mocker": "3.2.4", - "@vitest/pretty-format": "^3.2.4", - "@vitest/runner": "3.2.4", - "@vitest/snapshot": "3.2.4", - "@vitest/spy": "3.2.4", - "@vitest/utils": "3.2.4", - "chai": "^5.2.0", - "debug": "^4.4.1", - "expect-type": "^1.2.1", - "magic-string": "^0.30.17", - "pathe": "^2.0.3", - "picomatch": "^4.0.2", - "std-env": "^3.9.0", - "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.14", - "tinypool": "^1.1.1", - "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", - "vite-node": "3.2.4", - "why-is-node-running": "^2.3.0" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@types/debug": "^4.1.12", - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.4", - "@vitest/ui": "3.2.4", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@types/debug": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } - } - }, - "node_modules/vitest/node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/vitest/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/vitest/node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/vscode-jsonrpc": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", - "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/vscode-languageserver": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", - "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", - "license": "MIT", - "dependencies": { - "vscode-languageserver-protocol": "3.17.5" - }, - "bin": { - "installServerIntoExtension": "bin/installServerIntoExtension" - } - }, - "node_modules/vscode-languageserver-protocol": { - "version": "3.17.5", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", - "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", - "license": "MIT", - "dependencies": { - "vscode-jsonrpc": "8.2.0", - "vscode-languageserver-types": "3.17.5" - } - }, - "node_modules/vscode-languageserver-textdocument": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", - "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", - "license": "MIT" - }, - "node_modules/vscode-languageserver-types": { - "version": "3.17.5", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", - "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", - "license": "MIT" - }, - "node_modules/vscode-uri": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", - "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", - "license": "MIT" - }, - "node_modules/vue": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.18.tgz", - "integrity": "sha512-7W4Y4ZbMiQ3SEo+m9lnoNpV9xG7QVMLa+/0RFwwiAVkeYoyGXqWE85jabU4pllJNUzqfLShJ5YLptewhCWUgNA==", - "license": "MIT", - "dependencies": { - "@vue/compiler-dom": "3.5.18", - "@vue/compiler-sfc": "3.5.18", - "@vue/runtime-dom": "3.5.18", - "@vue/server-renderer": "3.5.18", - "@vue/shared": "3.5.18" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/vue-bar-graph": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/vue-bar-graph/-/vue-bar-graph-2.2.0.tgz", - "integrity": "sha512-1xFPho2nM6nFDziExLu48vKO+Q90gjxz1NyHfc+MhgfYDSxR9BMyhOIXUO5EmwKIVEX5dBoP2n3Ius8SjKRD4g==", - "license": "MIT", - "dependencies": { - "vue": "^3.5.13" - } - }, - "node_modules/vue-chartjs": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-5.3.2.tgz", - "integrity": "sha512-NrkbRRoYshbXbWqJkTN6InoDVwVb90C0R7eAVgMWcB9dPikbruaOoTFjFYHE/+tNPdIe6qdLCDjfjPHQ0fw4jw==", - "license": "MIT", - "peerDependencies": { - "chart.js": "^4.1.1", - "vue": "^3.0.0-0 || ^2.7.0" - } - }, - "node_modules/vue-eslint-parser": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.2.0.tgz", - "integrity": "sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "debug": "^4.4.0", - "eslint-scope": "^8.2.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", - "esquery": "^1.6.0", - "semver": "^7.6.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - } - }, - "node_modules/vue-eslint-parser/node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/vue-loader": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-17.4.2.tgz", - "integrity": "sha512-yTKOA4R/VN4jqjw4y5HrynFL8AK0Z3/Jt7eOJXEitsm0GMRHDBjCfCiuTiLP7OESvsZYo2pATCWhDqxC5ZrM6w==", - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "hash-sum": "^2.0.0", - "watchpack": "^2.4.0" - }, - "peerDependencies": { - "webpack": "^4.1.0 || ^5.0.0-0" - }, - "peerDependenciesMeta": { - "@vue/compiler-sfc": { - "optional": true - }, - "vue": { - "optional": true - } - } - }, - "node_modules/vue-tsc": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.0.4.tgz", - "integrity": "sha512-kZmSEjGtROApVBuaIcoprrXZsFNGon5ggkTJokmhQ/H1hMzCFRPQ0Ed8IHYFsmYJYvHBcdmEQVGVcRuxzPzNbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@volar/typescript": "2.4.20", - "@vue/language-core": "3.0.4" - }, - "bin": { - "vue-tsc": "bin/vue-tsc.js" - }, - "peerDependencies": { - "typescript": ">=5.0.0" - } - }, - "node_modules/watchpack": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", - "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", - "license": "MIT", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "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==", - "license": "BSD-2-Clause" - }, - "node_modules/webpack": { - "version": "5.101.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.101.0.tgz", - "integrity": "sha512-B4t+nJqytPeuZlHuIKTbalhljIFXeNRqrUGAQgTGlfOl2lXXKXw+yZu6bicycP+PUlM44CxBjCFD6aciKFT3LQ==", - "license": "MIT", - "dependencies": { - "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.8", - "@types/json-schema": "^7.0.15", - "@webassemblyjs/ast": "^1.14.1", - "@webassemblyjs/wasm-edit": "^1.14.1", - "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.15.0", - "acorn-import-phases": "^1.0.3", - "browserslist": "^4.24.0", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.2", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^4.3.2", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.11", - "watchpack": "^2.4.1", - "webpack-sources": "^3.3.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-cli": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz", - "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==", - "license": "MIT", - "dependencies": { - "@discoveryjs/json-ext": "^0.6.1", - "@webpack-cli/configtest": "^3.0.1", - "@webpack-cli/info": "^3.0.1", - "@webpack-cli/serve": "^3.0.1", - "colorette": "^2.0.14", - "commander": "^12.1.0", - "cross-spawn": "^7.0.3", - "envinfo": "^7.14.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^6.0.1" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.82.0" - }, - "peerDependenciesMeta": { - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/webpack-merge": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", - "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", - "license": "MIT", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "license": "MIT", - "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "node_modules/webpack/node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "license": "MIT" - }, - "node_modules/webpack/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/webpack/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/webpack/node_modules/webpack-sources": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", - "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/whatwg-mimetype": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/why-is-node-running": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", - "dev": true, - "license": "MIT", - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "license": "MIT" - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", - "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", - "license": "MIT" - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/xml-lexer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/xml-lexer/-/xml-lexer-0.2.2.tgz", - "integrity": "sha512-G0i98epIwiUEiKmMcavmVdhtymW+pCAohMRgybyIME9ygfVu8QheIi+YoQh3ngiThsT0SQzJT4R0sKDEv8Ou0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "eventemitter3": "^2.0.0" - } - }, - "node_modules/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, - "license": "Apache-2.0", - "engines": { - "node": ">=12" - } - }, - "node_modules/xml-reader": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/xml-reader/-/xml-reader-2.4.3.tgz", - "integrity": "sha512-xWldrIxjeAMAu6+HSf9t50ot1uL5M+BtOidRCWHXIeewvSeIpscWCsp4Zxjk8kHHhdqFBrfK8U0EJeCcnyQ/gA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eventemitter3": "^2.0.0", - "xml-lexer": "^0.2.2" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yaml": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", - "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "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, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs/node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/package.json b/package.json index 8d12276d27..5fe8e70c3f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,9 @@ { "type": "module", + "packageManager": "pnpm@10.0.0", "engines": { - "node": ">= 20.0.0" + "node": ">= 22.6.0", + "pnpm": ">= 10.0.0" }, "dependencies": { "@citation-js/core": "0.7.18", @@ -12,8 +14,10 @@ "@github/relative-time-element": "4.4.8", "@github/text-expander-element": "2.9.2", "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", - "@primer/octicons": "19.15.5", + "@primer/octicons": "19.18.0", + "@resvg/resvg-wasm": "2.6.2", "@silverwind/vue3-calendar-heatmap": "2.0.6", + "@techknowlogick/license-checker-webpack-plugin": "0.3.0", "add-asset-webpack-plugin": "3.0.0", "ansi_up": "6.0.6", "asciinema-player": "3.10.0", @@ -23,54 +27,53 @@ "clippie": "4.1.7", "cropperjs": "1.6.2", "css-loader": "7.1.2", - "dayjs": "1.11.13", + "dayjs": "1.11.18", "dropzone": "6.0.0-beta.2", "easymde": "2.20.0", "esbuild-loader": "4.3.0", - "fast-glob": "3.3.3", - "htmx.org": "2.0.6", + "htmx.org": "2.0.7", "idiomorph": "0.7.3", "jquery": "3.7.1", "katex": "0.16.22", - "license-checker-webpack-plugin": "0.2.1", - "mermaid": "11.9.0", - "mini-css-extract-plugin": "2.9.2", + "mermaid": "11.11.0", + "mini-css-extract-plugin": "2.9.4", "minimatch": "10.0.3", - "monaco-editor": "0.52.2", + "monaco-editor": "0.53.0", "monaco-editor-webpack-plugin": "7.1.0", "online-3d-viewer": "0.16.0", "pdfobject": "2.3.1", - "perfect-debounce": "1.0.0", + "perfect-debounce": "2.0.0", "postcss": "8.5.6", - "postcss-loader": "8.1.1", + "postcss-loader": "8.2.0", "postcss-nesting": "13.0.2", "sortablejs": "1.15.6", - "swagger-ui-dist": "5.27.0", + "swagger-ui-dist": "5.29.0", "tailwindcss": "3.4.17", "throttle-debounce": "5.0.2", "tinycolor2": "1.6.0", "tippy.js": "6.3.7", "toastify-js": "1.12.0", "tributejs": "5.1.3", - "typescript": "5.8.3", + "typescript": "5.9.2", "uint8-to-base64": "0.2.1", "vanilla-colorful": "0.7.2", - "vue": "3.5.18", + "vue": "3.5.21", "vue-bar-graph": "2.2.0", "vue-chartjs": "5.3.2", "vue-loader": "17.4.2", - "webpack": "5.101.0", + "webpack": "5.101.3", "webpack-cli": "6.0.1", - "wrap-ansi": "9.0.0" + "wrap-ansi": "9.0.2" }, "devDependencies": { "@eslint-community/eslint-plugin-eslint-comments": "4.5.0", - "@playwright/test": "1.54.1", + "@playwright/test": "1.55.0", "@stoplight/spectral-cli": "6.15.0", "@stylistic/eslint-plugin-js": "3.1.0", "@stylistic/stylelint-plugin": "4.0.0", + "@types/codemirror": "5.60.16", "@types/dropzone": "5.7.9", - "@types/jquery": "3.5.32", + "@types/jquery": "3.5.33", "@types/katex": "0.16.7", "@types/license-checker-webpack-plugin": "0.2.5", "@types/pdfobject": "2.2.5", @@ -79,10 +82,10 @@ "@types/throttle-debounce": "5.0.2", "@types/tinycolor2": "1.4.6", "@types/toastify-js": "1.12.4", - "@typescript-eslint/eslint-plugin": "8.38.0", - "@typescript-eslint/parser": "8.38.0", + "@typescript-eslint/eslint-plugin": "8.43.0", + "@typescript-eslint/parser": "8.43.0", "@vitejs/plugin-vue": "6.0.1", - "@vitest/eslint-plugin": "1.3.4", + "@vitest/eslint-plugin": "1.3.9", "eslint": "8.57.0", "eslint-import-resolver-typescript": "4.4.4", "eslint-plugin-array-func": "4.0.0", @@ -91,56 +94,50 @@ "eslint-plugin-no-jquery": "3.1.1", "eslint-plugin-no-use-extend-native": "0.5.0", "eslint-plugin-playwright": "2.2.2", - "eslint-plugin-regexp": "2.9.0", - "eslint-plugin-sonarjs": "3.0.4", + "eslint-plugin-regexp": "2.10.0", + "eslint-plugin-sonarjs": "3.0.5", "eslint-plugin-unicorn": "56.0.1", "eslint-plugin-vue": "10.4.0", - "eslint-plugin-vue-scoped-css": "2.11.0", + "eslint-plugin-vue-scoped-css": "2.12.0", "eslint-plugin-wc": "3.0.1", "happy-dom": "18.0.1", "markdownlint-cli": "0.45.0", - "material-icon-theme": "5.24.0", + "material-icon-theme": "5.27.0", "nolyfill": "1.0.44", "postcss-html": "1.8.0", - "stylelint": "16.23.0", + "stylelint": "16.24.0", "stylelint-config-recommended": "17.0.0", "stylelint-declaration-block-no-ignored-properties": "2.8.0", "stylelint-declaration-strict-value": "1.10.11", - "stylelint-define-config": "16.22.0", "stylelint-value-no-unknown-custom-properties": "6.0.1", "svgo": "4.0.0", "type-fest": "4.41.0", - "updates": "16.5.2", + "updates": "16.7.0", "vite-string-plugin": "1.4.6", "vitest": "3.2.4", - "vue-tsc": "3.0.4" + "vue-tsc": "3.0.6" }, "browserslist": [ "defaults" ], - "overrides": { - "array-includes": "npm:@nolyfill/array-includes@^1", - "array.prototype.findlastindex": "npm:@nolyfill/array.prototype.findlastindex@^1", - "array.prototype.flat": "npm:@nolyfill/array.prototype.flat@^1", - "array.prototype.flatmap": "npm:@nolyfill/array.prototype.flatmap@^1", - "deep-equal": "npm:@nolyfill/deep-equal@^1", - "es-aggregate-error": "npm:@nolyfill/es-aggregate-error@^1", - "es-iterator-helpers": "npm:@nolyfill/es-iterator-helpers@^1", - "hasown": "npm:@nolyfill/hasown@^1", - "object.assign": "npm:@nolyfill/object.assign@^1", - "object.entries": "npm:@nolyfill/object.entries@^1", - "object.fromentries": "npm:@nolyfill/object.fromentries@^1", - "object.groupby": "npm:@nolyfill/object.groupby@^1", - "object.values": "npm:@nolyfill/object.values@^1", - "safe-regex-test": "npm:@nolyfill/safe-regex-test@^1", - "string.prototype.includes": "npm:@nolyfill/string.prototype.includes@^1", - "is-core-module": "npm:@nolyfill/is-core-module@^1", - "array.prototype.findlast": "npm:@nolyfill/array.prototype.findlast@^1", - "array.prototype.tosorted": "npm:@nolyfill/array.prototype.tosorted@^1", - "string.prototype.matchall": "npm:@nolyfill/string.prototype.matchall@^1", - "string.prototype.repeat": "npm:@nolyfill/string.prototype.repeat@^1", - "safe-buffer": "npm:@nolyfill/safe-buffer@^1", - "safer-buffer": "npm:@nolyfill/safer-buffer@^1", - "string.prototype.trimend": "npm:@nolyfill/string.prototype.trimend@^1" + "pnpm": { + "overrides": { + "array-includes": "npm:@nolyfill/array-includes@^1", + "array.prototype.findlastindex": "npm:@nolyfill/array.prototype.findlastindex@^1", + "array.prototype.flat": "npm:@nolyfill/array.prototype.flat@^1", + "array.prototype.flatmap": "npm:@nolyfill/array.prototype.flatmap@^1", + "es-aggregate-error": "npm:@nolyfill/es-aggregate-error@^1", + "hasown": "npm:@nolyfill/hasown@^1", + "is-core-module": "npm:@nolyfill/is-core-module@^1", + "object.assign": "npm:@nolyfill/object.assign@^1", + "object.fromentries": "npm:@nolyfill/object.fromentries@^1", + "object.groupby": "npm:@nolyfill/object.groupby@^1", + "object.values": "npm:@nolyfill/object.values@^1", + "safe-buffer": "npm:@nolyfill/safe-buffer@^1", + "safe-regex-test": "npm:@nolyfill/safe-regex-test@^1", + "safer-buffer": "npm:@nolyfill/safer-buffer@^1", + "string.prototype.includes": "npm:@nolyfill/string.prototype.includes@^1", + "string.prototype.trimend": "npm:@nolyfill/string.prototype.trimend@^1" + } } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000000..83a31ce8ad --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,9488 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + array-includes: npm:@nolyfill/array-includes@^1 + array.prototype.findlastindex: npm:@nolyfill/array.prototype.findlastindex@^1 + array.prototype.flat: npm:@nolyfill/array.prototype.flat@^1 + array.prototype.flatmap: npm:@nolyfill/array.prototype.flatmap@^1 + es-aggregate-error: npm:@nolyfill/es-aggregate-error@^1 + hasown: npm:@nolyfill/hasown@^1 + is-core-module: npm:@nolyfill/is-core-module@^1 + object.assign: npm:@nolyfill/object.assign@^1 + object.fromentries: npm:@nolyfill/object.fromentries@^1 + object.groupby: npm:@nolyfill/object.groupby@^1 + object.values: npm:@nolyfill/object.values@^1 + safe-buffer: npm:@nolyfill/safe-buffer@^1 + safe-regex-test: npm:@nolyfill/safe-regex-test@^1 + safer-buffer: npm:@nolyfill/safer-buffer@^1 + string.prototype.includes: npm:@nolyfill/string.prototype.includes@^1 + string.prototype.trimend: npm:@nolyfill/string.prototype.trimend@^1 + +importers: + + .: + dependencies: + '@citation-js/core': + specifier: 0.7.18 + version: 0.7.18 + '@citation-js/plugin-bibtex': + specifier: 0.7.18 + version: 0.7.18(@citation-js/core@0.7.18) + '@citation-js/plugin-csl': + specifier: 0.7.18 + version: 0.7.18(@citation-js/core@0.7.18) + '@citation-js/plugin-software-formats': + specifier: 0.6.1 + version: 0.6.1 + '@github/markdown-toolbar-element': + specifier: 2.2.3 + version: 2.2.3 + '@github/relative-time-element': + specifier: 4.4.8 + version: 4.4.8 + '@github/text-expander-element': + specifier: 2.9.2 + version: 2.9.2 + '@mcaptcha/vanilla-glue': + specifier: 0.1.0-alpha-3 + version: 0.1.0-alpha-3 + '@primer/octicons': + specifier: 19.18.0 + version: 19.18.0 + '@resvg/resvg-wasm': + specifier: 2.6.2 + version: 2.6.2 + '@silverwind/vue3-calendar-heatmap': + specifier: 2.0.6 + version: 2.0.6(tippy.js@6.3.7)(vue@3.5.21(typescript@5.9.2)) + '@techknowlogick/license-checker-webpack-plugin': + specifier: 0.3.0 + version: 0.3.0(webpack@5.101.3) + add-asset-webpack-plugin: + specifier: 3.0.0 + version: 3.0.0(webpack@5.101.3) + ansi_up: + specifier: 6.0.6 + version: 6.0.6 + asciinema-player: + specifier: 3.10.0 + version: 3.10.0 + chart.js: + specifier: 4.5.0 + version: 4.5.0 + chartjs-adapter-dayjs-4: + specifier: 1.0.4 + version: 1.0.4(chart.js@4.5.0)(dayjs@1.11.18) + chartjs-plugin-zoom: + specifier: 2.2.0 + version: 2.2.0(chart.js@4.5.0) + clippie: + specifier: 4.1.7 + version: 4.1.7 + cropperjs: + specifier: 1.6.2 + version: 1.6.2 + css-loader: + specifier: 7.1.2 + version: 7.1.2(webpack@5.101.3) + dayjs: + specifier: 1.11.18 + version: 1.11.18 + dropzone: + specifier: 6.0.0-beta.2 + version: 6.0.0-beta.2 + easymde: + specifier: 2.20.0 + version: 2.20.0 + esbuild-loader: + specifier: 4.3.0 + version: 4.3.0(webpack@5.101.3) + htmx.org: + specifier: 2.0.7 + version: 2.0.7 + idiomorph: + specifier: 0.7.3 + version: 0.7.3 + jquery: + specifier: 3.7.1 + version: 3.7.1 + katex: + specifier: 0.16.22 + version: 0.16.22 + mermaid: + specifier: 11.11.0 + version: 11.11.0 + mini-css-extract-plugin: + specifier: 2.9.4 + version: 2.9.4(webpack@5.101.3) + minimatch: + specifier: 10.0.3 + version: 10.0.3 + monaco-editor: + specifier: 0.53.0 + version: 0.53.0 + monaco-editor-webpack-plugin: + specifier: 7.1.0 + version: 7.1.0(monaco-editor@0.53.0)(webpack@5.101.3) + online-3d-viewer: + specifier: 0.16.0 + version: 0.16.0 + pdfobject: + specifier: 2.3.1 + version: 2.3.1 + perfect-debounce: + specifier: 2.0.0 + version: 2.0.0 + postcss: + specifier: 8.5.6 + version: 8.5.6 + postcss-loader: + specifier: 8.2.0 + version: 8.2.0(postcss@8.5.6)(typescript@5.9.2)(webpack@5.101.3) + postcss-nesting: + specifier: 13.0.2 + version: 13.0.2(postcss@8.5.6) + sortablejs: + specifier: 1.15.6 + version: 1.15.6 + swagger-ui-dist: + specifier: 5.29.0 + version: 5.29.0 + tailwindcss: + specifier: 3.4.17 + version: 3.4.17 + throttle-debounce: + specifier: 5.0.2 + version: 5.0.2 + tinycolor2: + specifier: 1.6.0 + version: 1.6.0 + tippy.js: + specifier: 6.3.7 + version: 6.3.7 + toastify-js: + specifier: 1.12.0 + version: 1.12.0 + tributejs: + specifier: 5.1.3 + version: 5.1.3 + typescript: + specifier: 5.9.2 + version: 5.9.2 + uint8-to-base64: + specifier: 0.2.1 + version: 0.2.1 + vanilla-colorful: + specifier: 0.7.2 + version: 0.7.2 + vue: + specifier: 3.5.21 + version: 3.5.21(typescript@5.9.2) + vue-bar-graph: + specifier: 2.2.0 + version: 2.2.0(typescript@5.9.2) + vue-chartjs: + specifier: 5.3.2 + version: 5.3.2(chart.js@4.5.0)(vue@3.5.21(typescript@5.9.2)) + vue-loader: + specifier: 17.4.2 + version: 17.4.2(vue@3.5.21(typescript@5.9.2))(webpack@5.101.3) + webpack: + specifier: 5.101.3 + version: 5.101.3(webpack-cli@6.0.1) + webpack-cli: + specifier: 6.0.1 + version: 6.0.1(webpack@5.101.3) + wrap-ansi: + specifier: 9.0.2 + version: 9.0.2 + devDependencies: + '@eslint-community/eslint-plugin-eslint-comments': + specifier: 4.5.0 + version: 4.5.0(eslint@8.57.0) + '@playwright/test': + specifier: 1.55.0 + version: 1.55.0 + '@stoplight/spectral-cli': + specifier: 6.15.0 + version: 6.15.0 + '@stylistic/eslint-plugin-js': + specifier: 3.1.0 + version: 3.1.0(eslint@8.57.0) + '@stylistic/stylelint-plugin': + specifier: 4.0.0 + version: 4.0.0(stylelint@16.24.0(typescript@5.9.2)) + '@types/codemirror': + specifier: 5.60.16 + version: 5.60.16 + '@types/dropzone': + specifier: 5.7.9 + version: 5.7.9 + '@types/jquery': + specifier: 3.5.33 + version: 3.5.33 + '@types/katex': + specifier: 0.16.7 + version: 0.16.7 + '@types/license-checker-webpack-plugin': + specifier: 0.2.5 + version: 0.2.5 + '@types/pdfobject': + specifier: 2.2.5 + version: 2.2.5 + '@types/sortablejs': + specifier: 1.15.8 + version: 1.15.8 + '@types/swagger-ui-dist': + specifier: 3.30.6 + version: 3.30.6 + '@types/throttle-debounce': + specifier: 5.0.2 + version: 5.0.2 + '@types/tinycolor2': + specifier: 1.4.6 + version: 1.4.6 + '@types/toastify-js': + specifier: 1.12.4 + version: 1.12.4 + '@typescript-eslint/eslint-plugin': + specifier: 8.43.0 + version: 8.43.0(@typescript-eslint/parser@8.43.0(eslint@8.57.0)(typescript@5.9.2))(eslint@8.57.0)(typescript@5.9.2) + '@typescript-eslint/parser': + specifier: 8.43.0 + version: 8.43.0(eslint@8.57.0)(typescript@5.9.2) + '@vitejs/plugin-vue': + specifier: 6.0.1 + version: 6.0.1(vite@7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.21(typescript@5.9.2)) + '@vitest/eslint-plugin': + specifier: 1.3.9 + version: 1.3.9(eslint@8.57.0)(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(happy-dom@18.0.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1)) + eslint: + specifier: 8.57.0 + version: 8.57.0 + eslint-import-resolver-typescript: + specifier: 4.4.4 + version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.43.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0))(eslint-plugin-import@2.32.0)(eslint@8.57.0) + eslint-plugin-array-func: + specifier: 4.0.0 + version: 4.0.0(eslint@8.57.0) + eslint-plugin-github: + specifier: 5.0.2 + version: 5.0.2(@types/eslint@9.6.1)(eslint-import-resolver-typescript@4.4.4)(eslint@8.57.0)(typescript@5.9.2) + eslint-plugin-import-x: + specifier: 4.16.1 + version: 4.16.1(@typescript-eslint/utils@8.43.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + eslint-plugin-no-jquery: + specifier: 3.1.1 + version: 3.1.1(eslint@8.57.0) + eslint-plugin-no-use-extend-native: + specifier: 0.5.0 + version: 0.5.0 + eslint-plugin-playwright: + specifier: 2.2.2 + version: 2.2.2(eslint@8.57.0) + eslint-plugin-regexp: + specifier: 2.10.0 + version: 2.10.0(eslint@8.57.0) + eslint-plugin-sonarjs: + specifier: 3.0.5 + version: 3.0.5(eslint@8.57.0) + eslint-plugin-unicorn: + specifier: 56.0.1 + version: 56.0.1(eslint@8.57.0) + eslint-plugin-vue: + specifier: 10.4.0 + version: 10.4.0(@typescript-eslint/parser@8.43.0(eslint@8.57.0)(typescript@5.9.2))(eslint@8.57.0)(vue-eslint-parser@10.2.0(eslint@8.57.0)) + eslint-plugin-vue-scoped-css: + specifier: 2.12.0 + version: 2.12.0(eslint@8.57.0)(vue-eslint-parser@10.2.0(eslint@8.57.0)) + eslint-plugin-wc: + specifier: 3.0.1 + version: 3.0.1(eslint@8.57.0) + happy-dom: + specifier: 18.0.1 + version: 18.0.1 + markdownlint-cli: + specifier: 0.45.0 + version: 0.45.0 + material-icon-theme: + specifier: 5.27.0 + version: 5.27.0 + nolyfill: + specifier: 1.0.44 + version: 1.0.44 + postcss-html: + specifier: 1.8.0 + version: 1.8.0 + stylelint: + specifier: 16.24.0 + version: 16.24.0(typescript@5.9.2) + stylelint-config-recommended: + specifier: 17.0.0 + version: 17.0.0(stylelint@16.24.0(typescript@5.9.2)) + stylelint-declaration-block-no-ignored-properties: + specifier: 2.8.0 + version: 2.8.0(stylelint@16.24.0(typescript@5.9.2)) + stylelint-declaration-strict-value: + specifier: 1.10.11 + version: 1.10.11(stylelint@16.24.0(typescript@5.9.2)) + stylelint-value-no-unknown-custom-properties: + specifier: 6.0.1 + version: 6.0.1(stylelint@16.24.0(typescript@5.9.2)) + svgo: + specifier: 4.0.0 + version: 4.0.0 + type-fest: + specifier: 4.41.0 + version: 4.41.0 + updates: + specifier: 16.7.0 + version: 16.7.0 + vite-string-plugin: + specifier: 1.4.6 + version: 1.4.6 + vitest: + specifier: 3.2.4 + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(happy-dom@18.0.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1) + vue-tsc: + specifier: 3.0.6 + version: 3.0.6(typescript@5.9.2) + +packages: + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + + '@antfu/utils@9.2.0': + resolution: {integrity: sha512-Oq1d9BGZakE/FyoEtcNeSwM7MpDO2vUBi11RWBZXf75zPsbUVWmUs03EqkRFrcgbXyKTas0BdZWC1wcuSoqSAw==} + + '@asyncapi/specs@6.10.0': + resolution: {integrity: sha512-vB5oKLsdrLUORIZ5BXortZTlVyGWWMC1Nud/0LtgxQ3Yn2738HigAD6EVqScvpPsDUI/bcLVsYEXN4dtXQHVng==} + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.28.4': + resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.28.4': + resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} + engines: {node: '>=6.9.0'} + + '@braintree/sanitize-url@7.1.1': + resolution: {integrity: sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==} + + '@chevrotain/cst-dts-gen@11.0.3': + resolution: {integrity: sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==} + + '@chevrotain/gast@11.0.3': + resolution: {integrity: sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==} + + '@chevrotain/regexp-to-ast@11.0.3': + resolution: {integrity: sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==} + + '@chevrotain/types@11.0.3': + resolution: {integrity: sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==} + + '@chevrotain/utils@11.0.3': + resolution: {integrity: sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==} + + '@citation-js/core@0.7.18': + resolution: {integrity: sha512-EjLuZWA5156dIFGdF7OnyPyWFBW43B8Ckje6Sn/W2RFxHDu0oACvW4/6TNgWT80jhEA4bVFm7ahrZe9MJ2B2UQ==} + engines: {node: '>=16.0.0'} + + '@citation-js/date@0.5.1': + resolution: {integrity: sha512-1iDKAZ4ie48PVhovsOXQ+C6o55dWJloXqtznnnKy6CltJBQLIuLLuUqa8zlIvma0ZigjVjgDUhnVaNU1MErtZw==} + engines: {node: '>=10.0.0'} + + '@citation-js/name@0.4.2': + resolution: {integrity: sha512-brSPsjs2fOVzSnARLKu0qncn6suWjHVQtrqSUrnqyaRH95r/Ad4wPF5EsoWr+Dx8HzkCGb/ogmoAzfCsqlTwTQ==} + engines: {node: '>=6'} + + '@citation-js/plugin-bibtex@0.7.18': + resolution: {integrity: sha512-TdsZSMpgpfcx2NMPu0KiulEoecllwT5EtRUzAJl2pDsdPD1tUqqbyj/NBi0l8fwNy1r7WwAqSFGiqGPjQWpFdg==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@citation-js/core': ^0.7.0 + + '@citation-js/plugin-cff@0.6.1': + resolution: {integrity: sha512-tLjTgsfzNOdQWGn5mNc2NAaydHnlRucSERoyAXLN7u0BQBfp7j5zwdxCmxcQD/N7hH3fpDKMG+qDzbqpJuKyNA==} + engines: {node: '>=14.0.0'} + + '@citation-js/plugin-csl@0.7.18': + resolution: {integrity: sha512-cJcOdEZurmtIxNj0d4cOERHpVQJB/mN3YPSDNqfI/xTFRN3bWDpFAsaqubPtMO2ZPpoDS+ZGIP1kggbwCfMmlA==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@citation-js/core': ^0.7.0 + + '@citation-js/plugin-github@0.6.1': + resolution: {integrity: sha512-1ZeSgQ5AoYsa8n2acVooUeRk76oA8rLszYNBjzj5z6MPa11BZlQJ9O+Gy4tHjlImvsENLbLPx5f8/V1VHXaCfQ==} + engines: {node: '>=14.0.0'} + + '@citation-js/plugin-npm@0.6.1': + resolution: {integrity: sha512-rojJA+l/p2KBpDoY+8n0YfNyQO1Aw03fQR5BN+gXD1LNAP1V+8wqvdPsaHnzPsrhrd4ZXDR7ch/Nk0yynPkJ3Q==} + engines: {node: '>=14.0.0'} + + '@citation-js/plugin-software-formats@0.6.1': + resolution: {integrity: sha512-BDF9rqi56K0hoTgYTVANCFVRSbWKC9V06Uap7oa8SjqCTgnHJAy8t/F3NxsyYPPG+zmRsLW9VNbcIsJOl0eu/w==} + engines: {node: '>=14.0.0'} + + '@citation-js/plugin-yaml@0.6.1': + resolution: {integrity: sha512-XEVVks1cJTqRbjy+nmthfw/puR6NwRB3fyJWi1tX13UYXlkhP/h45nsv4zjgLLGekdcMHQvhad9MAYunOftGKA==} + engines: {node: '>=14.0.0'} + + '@citation-js/plugin-zenodo@0.6.1': + resolution: {integrity: sha512-bUybENHoZqJ6gheUqgkumjI+mu+fA2bg6VoniDmZTb7Qng9iEpi+IWEAR26/vBE0gK0EWrJjczyDW3HCwrhvVw==} + engines: {node: '>=14.0.0'} + + '@csstools/css-parser-algorithms@3.0.5': + resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} + + '@csstools/media-query-list-parser@4.0.3': + resolution: {integrity: sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/selector-resolve-nested@3.1.0': + resolution: {integrity: sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g==} + engines: {node: '>=18'} + peerDependencies: + postcss-selector-parser: ^7.0.0 + + '@csstools/selector-specificity@5.0.0': + resolution: {integrity: sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==} + engines: {node: '>=18'} + peerDependencies: + postcss-selector-parser: ^7.0.0 + + '@discoveryjs/json-ext@0.6.3': + resolution: {integrity: sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==} + engines: {node: '>=14.17.0'} + + '@dual-bundle/import-meta-resolve@4.2.1': + resolution: {integrity: sha512-id+7YRUgoUX6CgV0DtuhirQWodeeA7Lf4i2x71JS/vtA5pRb/hIGWlw+G6MeXvsM+MXrz0VAydTGElX1rAfgPg==} + + '@emnapi/core@1.5.0': + resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==} + + '@emnapi/runtime@1.5.0': + resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} + + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + + '@esbuild/aix-ppc64@0.25.9': + resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.9': + resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.9': + resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.9': + resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.9': + resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.9': + resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.9': + resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.9': + resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.9': + resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.9': + resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.9': + resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.9': + resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.9': + resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.9': + resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.9': + resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.9': + resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.9': + resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.9': + resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.9': + resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.9': + resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.9': + resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.9': + resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.9': + resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.9': + resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.9': + resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.9': + resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-plugin-eslint-comments@4.5.0': + resolution: {integrity: sha512-MAhuTKlr4y/CE3WYX26raZjy+I/kS2PLKSzvfmDCGrBLTFHOYwqROZdr4XwPgXwX3K9rjzMr4pSmUWGnzsUyMg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@8.57.0': + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@github/browserslist-config@1.0.0': + resolution: {integrity: sha512-gIhjdJp/c2beaIWWIlsXdqXVRUz3r2BxBCpfz/F3JXHvSAQ1paMYjLH+maEATtENg+k5eLV7gA+9yPp762ieuw==} + + '@github/combobox-nav@2.3.1': + resolution: {integrity: sha512-gwxPzLw8XKecy1nP63i9lOBritS3bWmxl02UX6G0TwMQZbMem1BCS1tEZgYd3mkrkiDrUMWaX+DbFCuDFo3K+A==} + + '@github/markdown-toolbar-element@2.2.3': + resolution: {integrity: sha512-AlquKGee+IWiAMYVB0xyHFZRMnu4n3X4HTvJHu79GiVJ1ojTukCWyxMlF5NMsecoLcBKsuBhx3QPv2vkE/zQ0A==} + + '@github/relative-time-element@4.4.8': + resolution: {integrity: sha512-FSLYm6F3TSQnqHE1EMQUVVgi2XjbCvsESwwXfugHFpBnhyF1uhJOtu0Psp/BB/qqazfdkk7f5fVcu7WuXl3t8Q==} + + '@github/text-expander-element@2.9.2': + resolution: {integrity: sha512-XY8EUMqM4GAloNxXNA1Py1ny+engWwYntbgsnpstQN4piaTI9rIlfYldyd0nnPXhxjGCVqHPmP6yg17Q0/n9Vg==} + + '@humanwhocodes/config-array@0.11.14': + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@3.0.1': + resolution: {integrity: sha512-A78CUEnFGX8I/WlILxJCuIJXloL0j/OJ9PSchPAfCargEIKmUBWvvEMmKWB5oONwiUqlNt+5eRufdkLxeHIWYw==} + + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.30': + resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} + + '@jsep-plugin/assignment@1.3.0': + resolution: {integrity: sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==} + engines: {node: '>= 10.16.0'} + peerDependencies: + jsep: ^0.4.0||^1.0.0 + + '@jsep-plugin/regex@1.0.4': + resolution: {integrity: sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==} + engines: {node: '>= 10.16.0'} + peerDependencies: + jsep: ^0.4.0||^1.0.0 + + '@jsep-plugin/ternary@1.1.4': + resolution: {integrity: sha512-ck5wiqIbqdMX6WRQztBL7ASDty9YLgJ3sSAK5ZpBzXeySvFGCzIvM6UiAI4hTZ22fEcYQVV/zhUbNscggW+Ukg==} + engines: {node: '>= 10.16.0'} + peerDependencies: + jsep: ^0.4.0||^1.0.0 + + '@keyv/serialize@1.1.0': + resolution: {integrity: sha512-RlDgexML7Z63Q8BSaqhXdCYNBy/JQnqYIwxofUrNLGCblOMHp+xux2Q8nLMLlPpgHQPoU0Do8Z6btCpRBEqZ8g==} + + '@kurkle/color@0.3.4': + resolution: {integrity: sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==} + + '@mcaptcha/core-glue@0.1.0-alpha-5': + resolution: {integrity: sha512-16qWm5O5X0Y9LXULULaAks8Vf9FNlUUBcR5KDt49aWhFhG5++JzxNmCwQM9EJSHNU7y0U+FdyAWcGmjfKlkRLA==} + + '@mcaptcha/vanilla-glue@0.1.0-alpha-3': + resolution: {integrity: sha512-GT6TJBgmViGXcXiT5VOr+h/6iOnThSlZuCoOWncubyTZU9R3cgU5vWPkF7G6Ob6ee2CBe3yqBxxk24CFVGTVXw==} + + '@mermaid-js/parser@0.6.2': + resolution: {integrity: sha512-+PO02uGF6L6Cs0Bw8RpGhikVvMWEysfAyl27qTlroUB8jSWr1lL0Sf6zi78ZxlSnmgSY2AMMKVgghnN9jTtwkQ==} + + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nolyfill/array-includes@1.0.44': + resolution: {integrity: sha512-IVEqpEgFbLaU0hUoMwJYXNSdi6lq+FxHdxd8xTKDLxh8k6u5YNGz4Bo6bT46l7p0x8PbJmHViBtngqhvE528fA==} + engines: {node: '>=12.4.0'} + + '@nolyfill/array.prototype.findlastindex@1.0.44': + resolution: {integrity: sha512-BLeHS3SulsR3iFxxETL9q21lArV2KS7lh2wcUnhue1ppx19xah1W7MdFxepyeGbM3Umk9S90snfboXAds5HkTg==} + engines: {node: '>=12.4.0'} + + '@nolyfill/array.prototype.flat@1.0.44': + resolution: {integrity: sha512-HnOqOT4te0l+XU9UKhy3ry+pc+ZRNsUJFR7omMEtjXf4+dq6oXmIBk7vR35+hSTk4ldjwm/27jwV3ZIGp3l4IQ==} + engines: {node: '>=12.4.0'} + + '@nolyfill/array.prototype.flatmap@1.0.44': + resolution: {integrity: sha512-P6OsaEUrpBJ9NdNekFDQVM9LOFHPDKSJzwOWRBaC6LqREX+4lkZT2Q+to78R6aG6atuOQsxBVqPjMGCKjWdvyQ==} + engines: {node: '>=12.4.0'} + + '@nolyfill/es-aggregate-error@1.0.44': + resolution: {integrity: sha512-NBXDS4gpOiK4csFDGjqAF0WVKAMsqq/2ZU+/z+q+Mmvpr6CIrwKC/X+EbMpalEOZYT8kSTaCMVDUcXTDeMYOLw==} + engines: {node: '>=12.4.0'} + + '@nolyfill/hasown@1.0.44': + resolution: {integrity: sha512-GA/21lkTr2PAQuT6jGnhLuBD5IFd/AEhBXJ/tf33+/bVxPxg+5ejKx9jGQGnyV/P0eSmdup5E+s8b2HL6lOrwQ==} + engines: {node: '>=12.4.0'} + + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + + '@nolyfill/object.assign@1.0.44': + resolution: {integrity: sha512-cZoXq09YZXDgkxRMAP/TTb3kAsWm7p5OyBugWDe4fOfxf0XRI55mgDSkuyq41sV1qW1zVC5aSsKEh1hQo1KOvA==} + engines: {node: '>=12.4.0'} + + '@nolyfill/object.fromentries@1.0.44': + resolution: {integrity: sha512-/LrsCtpLmByZ6GwP/NeXULSgMyNsVr5d6FlgQy1HZatAiBc8c+WZ1VmFkK19ZLXCNNXBedXDultrp0x4Nz+QQw==} + engines: {node: '>=12.4.0'} + + '@nolyfill/object.groupby@1.0.44': + resolution: {integrity: sha512-jCt/8pN+10mlbeg0ZESpVVaqn5qqpv6kpjM+GDfEP7cXGDSPlIjtvfYWRZK4k4Gftkhhgqkzvcrr8z1wuNO1TQ==} + engines: {node: '>=12.4.0'} + + '@nolyfill/object.values@1.0.44': + resolution: {integrity: sha512-bwIpVzFMudUC0ofnvdSDB/OyGUizcU+r32ZZ0QTMbN03gUttMtdCFDekuSYT0XGFgufTQyZ4ONBnAeb3DFCPGQ==} + engines: {node: '>=12.4.0'} + + '@nolyfill/safe-buffer@1.0.44': + resolution: {integrity: sha512-SqlKXtlhNTDMeZKey9jnnuPhi8YTl1lJuEcY9zbm5i4Pqe79UJJ8IJ9oiD6DhgI8KjYc+HtLzpQJNRdNYqb/hw==} + engines: {node: '>=12.4.0'} + + '@nolyfill/safe-regex-test@1.0.44': + resolution: {integrity: sha512-Q6veatd1NebtD8Sre6zjvO35QzG21IskMVOOEbePFcNO9noanNJgsqHeOCr0c5yZz6Z0DAizLg2gIZWokJSkXw==} + engines: {node: '>=12.4.0'} + + '@nolyfill/safer-buffer@1.0.44': + resolution: {integrity: sha512-Ouw1fMwjAy1V4MpnDASfu1DCPgkP0nNFteiiWbFoEGSqa7Vnmkb6if2c522N2WcMk+RuaaabQbC1F1D4/kTXcg==} + engines: {node: '>=12.4.0'} + + '@nolyfill/shared@1.0.44': + resolution: {integrity: sha512-NI1zxDh4LYL7PYlKKCwojjuc5CEZslywrOTKBNyodjmWjRiZ4AlCMs3Gp+zDoPQPNkYCSQp/luNojHmJWWfCbw==} + + '@nolyfill/string.prototype.includes@1.0.44': + resolution: {integrity: sha512-d1t7rnoAYyoap0X3a/gCnusCvxzK6v7uMFzW8k0mI2WtAK8HiKuzaQUwAriyVPh63GsvQCqvXx8Y5gtdh4LjSA==} + engines: {node: '>=12.4.0'} + + '@nolyfill/string.prototype.trimend@1.0.44': + resolution: {integrity: sha512-3dsKlf4Ma7o+uxLIg5OI1Tgwfet2pE8WTbPjEGWvOe6CSjMtK0skJnnSVHaEVX4N4mYU81To0qDeZOPqjaUotg==} + engines: {node: '>=12.4.0'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@pkgr/core@0.2.9': + resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@playwright/test@1.55.0': + resolution: {integrity: sha512-04IXzPwHrW69XusN/SIdDdKZBzMfOT9UNT/YiJit/xpy2VuAoB8NHc8Aplb96zsWDddLnbkPL3TsmrS04ZU2xQ==} + engines: {node: '>=18'} + hasBin: true + + '@popperjs/core@2.11.8': + resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + + '@primer/octicons@19.18.0': + resolution: {integrity: sha512-4P8FS7slUp0vHE7zLtlfOQcgF99r0tdxpriT3ahp6iwwnf1hF3OlDWXEp5n6b6G5eIY1cNr1bCrjRL+DkRjFVw==} + + '@resvg/resvg-wasm@2.6.2': + resolution: {integrity: sha512-FqALmHI8D4o6lk/LRWDnhw95z5eO+eAa6ORjVg09YRR7BkcM6oPHU9uyC0gtQG5vpFLvgpeU4+zEAz2H8APHNw==} + engines: {node: '>= 10'} + + '@rolldown/pluginutils@1.0.0-beta.29': + resolution: {integrity: sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==} + + '@rollup/plugin-commonjs@22.0.2': + resolution: {integrity: sha512-//NdP6iIwPbMTcazYsiBMbJW7gfmpHom33u1beiIoHDEM0Q9clvtQB1T0efvMqHeKsGohiHo97BCPCkBXdscwg==} + engines: {node: '>= 12.0.0'} + peerDependencies: + rollup: ^2.68.0 + + '@rollup/pluginutils@3.1.0': + resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} + engines: {node: '>= 8.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0 + + '@rollup/rollup-android-arm-eabi@4.50.1': + resolution: {integrity: sha512-HJXwzoZN4eYTdD8bVV22DN8gsPCAj3V20NHKOs8ezfXanGpmVPR7kalUHd+Y31IJp9stdB87VKPFbsGY3H/2ag==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.50.1': + resolution: {integrity: sha512-PZlsJVcjHfcH53mOImyt3bc97Ep3FJDXRpk9sMdGX0qgLmY0EIWxCag6EigerGhLVuL8lDVYNnSo8qnTElO4xw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.50.1': + resolution: {integrity: sha512-xc6i2AuWh++oGi4ylOFPmzJOEeAa2lJeGUGb4MudOtgfyyjr4UPNK+eEWTPLvmPJIY/pgw6ssFIox23SyrkkJw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.50.1': + resolution: {integrity: sha512-2ofU89lEpDYhdLAbRdeyz/kX3Y2lpYc6ShRnDjY35bZhd2ipuDMDi6ZTQ9NIag94K28nFMofdnKeHR7BT0CATw==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.50.1': + resolution: {integrity: sha512-wOsE6H2u6PxsHY/BeFHA4VGQN3KUJFZp7QJBmDYI983fgxq5Th8FDkVuERb2l9vDMs1D5XhOrhBrnqcEY6l8ZA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.50.1': + resolution: {integrity: sha512-A/xeqaHTlKbQggxCqispFAcNjycpUEHP52mwMQZUNqDUJFFYtPHCXS1VAG29uMlDzIVr+i00tSFWFLivMcoIBQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.50.1': + resolution: {integrity: sha512-54v4okehwl5TaSIkpp97rAHGp7t3ghinRd/vyC1iXqXMfjYUTm7TfYmCzXDoHUPTTf36L8pr0E7YsD3CfB3ZDg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.50.1': + resolution: {integrity: sha512-p/LaFyajPN/0PUHjv8TNyxLiA7RwmDoVY3flXHPSzqrGcIp/c2FjwPPP5++u87DGHtw+5kSH5bCJz0mvXngYxw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.50.1': + resolution: {integrity: sha512-2AbMhFFkTo6Ptna1zO7kAXXDLi7H9fGTbVaIq2AAYO7yzcAsuTNWPHhb2aTA6GPiP+JXh85Y8CiS54iZoj4opw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.50.1': + resolution: {integrity: sha512-Cgef+5aZwuvesQNw9eX7g19FfKX5/pQRIyhoXLCiBOrWopjo7ycfB292TX9MDcDijiuIJlx1IzJz3IoCPfqs9w==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.50.1': + resolution: {integrity: sha512-RPhTwWMzpYYrHrJAS7CmpdtHNKtt2Ueo+BlLBjfZEhYBhK00OsEqM08/7f+eohiF6poe0YRDDd8nAvwtE/Y62Q==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.50.1': + resolution: {integrity: sha512-eSGMVQw9iekut62O7eBdbiccRguuDgiPMsw++BVUg+1K7WjZXHOg/YOT9SWMzPZA+w98G+Fa1VqJgHZOHHnY0Q==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.50.1': + resolution: {integrity: sha512-S208ojx8a4ciIPrLgazF6AgdcNJzQE4+S9rsmOmDJkusvctii+ZvEuIC4v/xFqzbuP8yDjn73oBlNDgF6YGSXQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.50.1': + resolution: {integrity: sha512-3Ag8Ls1ggqkGUvSZWYcdgFwriy2lWo+0QlYgEFra/5JGtAd6C5Hw59oojx1DeqcA2Wds2ayRgvJ4qxVTzCHgzg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.50.1': + resolution: {integrity: sha512-t9YrKfaxCYe7l7ldFERE1BRg/4TATxIg+YieHQ966jwvo7ddHJxPj9cNFWLAzhkVsbBvNA4qTbPVNsZKBO4NSg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.50.1': + resolution: {integrity: sha512-MCgtFB2+SVNuQmmjHf+wfI4CMxy3Tk8XjA5Z//A0AKD7QXUYFMQcns91K6dEHBvZPCnhJSyDWLApk40Iq/H3tA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.50.1': + resolution: {integrity: sha512-nEvqG+0jeRmqaUMuwzlfMKwcIVffy/9KGbAGyoa26iu6eSngAYQ512bMXuqqPrlTyfqdlB9FVINs93j534UJrg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.50.1': + resolution: {integrity: sha512-RDsLm+phmT3MJd9SNxA9MNuEAO/J2fhW8GXk62G/B4G7sLVumNFbRwDL6v5NrESb48k+QMqdGbHgEtfU0LCpbA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.50.1': + resolution: {integrity: sha512-hpZB/TImk2FlAFAIsoElM3tLzq57uxnGYwplg6WDyAxbYczSi8O2eQ+H2Lx74504rwKtZ3N2g4bCUkiamzS6TQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.50.1': + resolution: {integrity: sha512-SXjv8JlbzKM0fTJidX4eVsH+Wmnp0/WcD8gJxIZyR6Gay5Qcsmdbi9zVtnbkGPG8v2vMR1AD06lGWy5FLMcG7A==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.50.1': + resolution: {integrity: sha512-StxAO/8ts62KZVRAm4JZYq9+NqNsV7RvimNK+YM7ry//zebEH6meuugqW/P5OFUCjyQgui+9fUxT6d5NShvMvA==} + cpu: [x64] + os: [win32] + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@scarf/scarf@1.4.0': + resolution: {integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==} + + '@silverwind/vue3-calendar-heatmap@2.0.6': + resolution: {integrity: sha512-efX+nf2GR7EfA7iNgZDeM9Jue5ksglSXvN0C/ja0M1bTmkCpAxKlGJ3vki7wfTPQgX1O0nCfAM62IKqUUEM0cQ==} + engines: {node: '>=16'} + peerDependencies: + tippy.js: ^6.3.7 + vue: ^3.2.29 + + '@simonwep/pickr@1.9.0': + resolution: {integrity: sha512-oEYvv15PyfZzjoAzvXYt3UyNGwzsrpFxLaZKzkOSd0WYBVwLd19iJerePDONxC1iF6+DpcswPdLIM2KzCJuYFg==} + + '@stoplight/better-ajv-errors@1.0.3': + resolution: {integrity: sha512-0p9uXkuB22qGdNfy3VeEhxkU5uwvp/KrBTAbrLBURv6ilxIVwanKwjMc41lQfIVgPGcOkmLbTolfFrSsueu7zA==} + engines: {node: ^12.20 || >= 14.13} + peerDependencies: + ajv: '>=8' + + '@stoplight/json-ref-readers@1.2.2': + resolution: {integrity: sha512-nty0tHUq2f1IKuFYsLM4CXLZGHdMn+X/IwEUIpeSOXt0QjMUbL0Em57iJUDzz+2MkWG83smIigNZ3fauGjqgdQ==} + engines: {node: '>=8.3.0'} + + '@stoplight/json-ref-resolver@3.1.6': + resolution: {integrity: sha512-YNcWv3R3n3U6iQYBsFOiWSuRGE5su1tJSiX6pAPRVk7dP0L7lqCteXGzuVRQ0gMZqUl8v1P0+fAKxF6PLo9B5A==} + engines: {node: '>=8.3.0'} + + '@stoplight/json@3.21.7': + resolution: {integrity: sha512-xcJXgKFqv/uCEgtGlPxy3tPA+4I+ZI4vAuMJ885+ThkTHFVkC+0Fm58lA9NlsyjnkpxFh4YiQWpH+KefHdbA0A==} + engines: {node: '>=8.3.0'} + + '@stoplight/ordered-object-literal@1.0.5': + resolution: {integrity: sha512-COTiuCU5bgMUtbIFBuyyh2/yVVzlr5Om0v5utQDgBCuQUOPgU1DwoffkTfg4UBQOvByi5foF4w4T+H9CoRe5wg==} + engines: {node: '>=8'} + + '@stoplight/path@1.3.2': + resolution: {integrity: sha512-lyIc6JUlUA8Ve5ELywPC8I2Sdnh1zc1zmbYgVarhXIp9YeAB0ReeqmGEOWNtlHkbP2DAA1AL65Wfn2ncjK/jtQ==} + engines: {node: '>=8'} + + '@stoplight/spectral-cli@6.15.0': + resolution: {integrity: sha512-FVeQIuqQQnnLfa8vy+oatTKUve7uU+3SaaAfdjpX/B+uB1NcfkKRJYhKT9wMEehDRaMPL5AKIRYMCFerdEbIpw==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + hasBin: true + + '@stoplight/spectral-core@1.20.0': + resolution: {integrity: sha512-5hBP81nCC1zn1hJXL/uxPNRKNcB+/pEIHgCjPRpl/w/qy9yC9ver04tw1W0l/PMiv0UeB5dYgozXVQ4j5a6QQQ==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/spectral-formats@1.8.2': + resolution: {integrity: sha512-c06HB+rOKfe7tuxg0IdKDEA5XnjL2vrn/m/OVIIxtINtBzphZrOgtRn7epQ5bQF5SWp84Ue7UJWaGgDwVngMFw==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/spectral-formatters@1.5.0': + resolution: {integrity: sha512-lR7s41Z00Mf8TdXBBZQ3oi2uR8wqAtR6NO0KA8Ltk4FSpmAy0i6CKUmJG9hZQjanTnGmwpQkT/WP66p1GY3iXA==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/spectral-functions@1.10.1': + resolution: {integrity: sha512-obu8ZfoHxELOapfGsCJixKZXZcffjg+lSoNuttpmUFuDzVLT3VmH8QkPXfOGOL5Pz80BR35ClNAToDkdnYIURg==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/spectral-parsers@1.0.5': + resolution: {integrity: sha512-ANDTp2IHWGvsQDAY85/jQi9ZrF4mRrA5bciNHX+PUxPr4DwS6iv4h+FVWJMVwcEYdpyoIdyL+SRmHdJfQEPmwQ==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/spectral-ref-resolver@1.0.5': + resolution: {integrity: sha512-gj3TieX5a9zMW29z3mBlAtDOCgN3GEc1VgZnCVlr5irmR4Qi5LuECuFItAq4pTn5Zu+sW5bqutsCH7D4PkpyAA==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/spectral-ruleset-bundler@1.6.3': + resolution: {integrity: sha512-AQFRO6OCKg8SZJUupnr3+OzI1LrMieDTEUHsYgmaRpNiDRPvzImE3bzM1KyQg99q58kTQyZ8kpr7sG8Lp94RRA==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/spectral-ruleset-migrator@1.11.2': + resolution: {integrity: sha512-6r5i4hrDmppspSSxdUKKNHc07NGSSIkvwKNk3M5ukCwvSslImvDEimeWAhPBryhmSJ82YAsKr8erZZpKullxWw==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/spectral-rulesets@1.22.0': + resolution: {integrity: sha512-l2EY2jiKKLsvnPfGy+pXC0LeGsbJzcQP5G/AojHgf+cwN//VYxW1Wvv4WKFx/CLmLxc42mJYF2juwWofjWYNIQ==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/spectral-runtime@1.1.4': + resolution: {integrity: sha512-YHbhX3dqW0do6DhiPSgSGQzr6yQLlWybhKwWx0cqxjMwxej3TqLv3BXMfIUYFKKUqIwH4Q2mV8rrMM8qD2N0rQ==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} + + '@stoplight/types@13.20.0': + resolution: {integrity: sha512-2FNTv05If7ib79VPDA/r9eUet76jewXFH2y2K5vuge6SXbRHtWBhcaRmu+6QpF4/WRNoJj5XYRSwLGXDxysBGA==} + engines: {node: ^12.20 || >=14.13} + + '@stoplight/types@13.6.0': + resolution: {integrity: sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==} + engines: {node: ^12.20 || >=14.13} + + '@stoplight/types@14.1.1': + resolution: {integrity: sha512-/kjtr+0t0tjKr+heVfviO9FrU/uGLc+QNX3fHJc19xsCNYqU7lVhaXxDmEID9BZTjG+/r9pK9xP/xU02XGg65g==} + engines: {node: ^12.20 || >=14.13} + + '@stoplight/yaml-ast-parser@0.0.48': + resolution: {integrity: sha512-sV+51I7WYnLJnKPn2EMWgS4EUfoP4iWEbrWwbXsj0MZCB/xOK8j6+C9fntIdOM50kpx45ZLC3s6kwKivWuqvyg==} + + '@stoplight/yaml-ast-parser@0.0.50': + resolution: {integrity: sha512-Pb6M8TDO9DtSVla9yXSTAxmo9GVEouq5P40DWXdOie69bXogZTkgvopCq+yEvTMA0F6PEvdJmbtTV3ccIp11VQ==} + + '@stoplight/yaml@4.2.3': + resolution: {integrity: sha512-Mx01wjRAR9C7yLMUyYFTfbUf5DimEpHMkRDQ1PKLe9dfNILbgdxyrncsOXM3vCpsQ1Hfj4bPiGl+u4u6e9Akqw==} + engines: {node: '>=10.8'} + + '@stoplight/yaml@4.3.0': + resolution: {integrity: sha512-JZlVFE6/dYpP9tQmV0/ADfn32L9uFarHWxfcRhReKUnljz1ZiUM5zpX+PH8h5CJs6lao3TuFqnPm9IJJCEkE2w==} + engines: {node: '>=10.8'} + + '@stylistic/eslint-plugin-js@3.1.0': + resolution: {integrity: sha512-lQktsOiCr8S6StG29C5fzXYxLOD6ID1rp4j6TRS+E/qY1xd59Fm7dy5qm9UauJIEoSTlYx6yGsCHYh5UkgXPyg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=8.40.0' + + '@stylistic/stylelint-plugin@4.0.0': + resolution: {integrity: sha512-CFwt3K4Y/7bygNCLCQ8Sy4Hzgbhxq3BsNW0FIuYxl17HD3ywptm54ocyeiLVRrk5jtz1Zwks7Xr9eiZt8SWHAw==} + engines: {node: ^18.12 || >=20.9} + peerDependencies: + stylelint: ^16.22.0 + + '@swc/helpers@0.2.14': + resolution: {integrity: sha512-wpCQMhf5p5GhNg2MmGKXzUNwxe7zRiCsmqYsamez2beP7mKPCSiu+BjZcdN95yYSzO857kr0VfQewmGpS77nqA==} + + '@techknowlogick/license-checker-webpack-plugin@0.3.0': + resolution: {integrity: sha512-gqht/3IzjYttWGwVO5L+oPiQaO0SrPzpZCy/XGEcwTY5fpKs959+YhOHMiltJkLEfae60tE6s2jeOsxF547/sA==} + peerDependencies: + webpack: ^4.4.0 || ^5.4.0 + + '@tybys/wasm-util@0.10.0': + resolution: {integrity: sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==} + + '@types/chai@5.2.2': + resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + + '@types/codemirror@5.60.16': + resolution: {integrity: sha512-V/yHdamffSS075jit+fDxaOAmdP2liok8NSNJnAZfDJErzOheuygHZEhAJrfmk5TEyM32MhkZjwo/idX791yxw==} + + '@types/d3-array@3.2.1': + resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} + + '@types/d3-axis@3.0.6': + resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} + + '@types/d3-brush@3.0.6': + resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==} + + '@types/d3-chord@3.0.6': + resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-contour@3.0.6': + resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} + + '@types/d3-delaunay@6.0.4': + resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} + + '@types/d3-dispatch@3.0.7': + resolution: {integrity: sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==} + + '@types/d3-drag@3.0.7': + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} + + '@types/d3-dsv@3.0.7': + resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-fetch@3.0.7': + resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} + + '@types/d3-force@3.0.10': + resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==} + + '@types/d3-format@3.0.4': + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} + + '@types/d3-geo@3.1.0': + resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==} + + '@types/d3-hierarchy@3.1.7': + resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.1': + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + + '@types/d3-polygon@3.0.2': + resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==} + + '@types/d3-quadtree@3.0.6': + resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==} + + '@types/d3-random@3.0.3': + resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==} + + '@types/d3-scale-chromatic@3.1.0': + resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} + + '@types/d3-scale@4.0.9': + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + + '@types/d3-selection@3.0.11': + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} + + '@types/d3-shape@3.1.7': + resolution: {integrity: sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==} + + '@types/d3-time-format@4.0.3': + resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + + '@types/d3-transition@3.0.9': + resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==} + + '@types/d3-zoom@3.0.8': + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} + + '@types/d3@7.4.3': + resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/dropzone@5.7.9': + resolution: {integrity: sha512-c6IlUz+DeQ4gANzJKn8fdP5rO6UyDNOyWLjfPbDRUHCNsXaAVKQOpuOv6LWEyvaK7pLqmoIpvSIlvBgGsk1vGw==} + + '@types/es-aggregate-error@1.0.6': + resolution: {integrity: sha512-qJ7LIFp06h1QE1aVxbVd+zJP2wdaugYXYfd6JxsyRMrYHaxb6itXPogW2tz+ylUJ1n1b+JF1PHyYCfYHm0dvUg==} + + '@types/eslint-scope@3.7.7': + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + + '@types/estree@0.0.39': + resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/geojson@7946.0.16': + resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} + + '@types/hammerjs@2.0.46': + resolution: {integrity: sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==} + + '@types/jquery@3.5.33': + resolution: {integrity: sha512-SeyVJXlCZpEki5F0ghuYe+L+PprQta6nRZqhONt9F13dWBtR/ftoaIbdRQ7cis7womE+X2LKhsDdDtkkDhJS6g==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/katex@0.16.7': + resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} + + '@types/license-checker-webpack-plugin@0.2.5': + resolution: {integrity: sha512-raj3YPZxjkDlRrJJUq6So+C9i/fqYxUtVZzlXxm6bwwXONOnTHvGCfYmbQhzsHJneiJdlR6mMH76/bvWbZZN8Q==} + + '@types/markdown-escape@1.1.3': + resolution: {integrity: sha512-JIc1+s3y5ujKnt/+N+wq6s/QdL2qZ11fP79MijrVXsAAnzSxCbT2j/3prHRouJdZ2yFLN3vkP0HytfnoCczjOw==} + + '@types/marked@4.3.2': + resolution: {integrity: sha512-a79Yc3TOk6dGdituy8hmTTJXjOkZ7zsFYV10L337ttq/rec8lRMDBpV7fL3uLx6TgbFCa5DU/h8FmIBQPSbU0w==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node@20.19.13': + resolution: {integrity: sha512-yCAeZl7a0DxgNVteXFHt9+uyFbqXGy/ShC4BlcHkoE0AfGXYv/BUiplV72DjMYXHDBXFjhvr6DD1NiRVfB4j8g==} + + '@types/node@24.3.1': + resolution: {integrity: sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==} + + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + + '@types/pdfobject@2.2.5': + resolution: {integrity: sha512-7gD5tqc/RUDq0PyoLemL0vEHxBYi+zY0WVaFAx/Y0jBsXFgot1vB9No1GhDZGwRGJMCIZbgAb74QG9MTyTNU/g==} + + '@types/sarif@2.1.7': + resolution: {integrity: sha512-kRz0VEkJqWLf1LLVN4pT1cg1Z9wAuvI6L97V3m2f5B76Tg8d413ddvLBPTEHAZJlnn4XSvu0FkZtViCQGVyrXQ==} + + '@types/sizzle@2.3.10': + resolution: {integrity: sha512-TC0dmN0K8YcWEAEfiPi5gJP14eJe30TTGjkvek3iM/1NdHHsdCA/Td6GvNndMOo/iSnIsZ4HuuhrYPDAmbxzww==} + + '@types/sortablejs@1.15.8': + resolution: {integrity: sha512-b79830lW+RZfwaztgs1aVPgbasJ8e7AXtZYHTELNXZPsERt4ymJdjV4OccDbHQAvHrCcFpbF78jkm0R6h/pZVg==} + + '@types/source-list-map@0.1.6': + resolution: {integrity: sha512-5JcVt1u5HDmlXkwOD2nslZVllBBc7HDuOICfiZah2Z0is8M8g+ddAEawbmd3VjedfDHBzxCaXLs07QEmb7y54g==} + + '@types/swagger-ui-dist@3.30.6': + resolution: {integrity: sha512-FVxN7wjLYRtJsZBscOcOcf8oR++m38vbUFjT33Mr9HBuasX9bRDrJsp7iwixcOtKSHEEa2B7o2+4wEiXqC+Ebw==} + + '@types/tapable@1.0.12': + resolution: {integrity: sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q==} + + '@types/tern@0.23.9': + resolution: {integrity: sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==} + + '@types/throttle-debounce@5.0.2': + resolution: {integrity: sha512-pDzSNulqooSKvSNcksnV72nk8p7gRqN8As71Sp28nov1IgmPKWbOEIwAWvBME5pPTtaXJAvG3O4oc76HlQ4kqQ==} + + '@types/tinycolor2@1.4.6': + resolution: {integrity: sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw==} + + '@types/toastify-js@1.12.4': + resolution: {integrity: sha512-zfZHU4tKffPCnZRe7pjv/eFKzTVHozKewFCKaCjZ4gFinKgJRz/t0bkZiMCXJxPhv/ZoeDGNOeRD09R0kQZ/nw==} + + '@types/trusted-types@1.0.6': + resolution: {integrity: sha512-230RC8sFeHoT6sSUlRO6a8cAnclO06eeiq1QDfiv2FGCLWFvvERWgwIQD4FWqD9A69BN7Lzee4OXwoMVnnsWDw==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + + '@types/uglify-js@3.17.5': + resolution: {integrity: sha512-TU+fZFBTBcXj/GpDpDaBmgWk/gn96kMZ+uocaFUlV2f8a6WdMzzI44QBCmGcCiYR0Y6ZlNRiyUyKKt5nl/lbzQ==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/urijs@1.19.25': + resolution: {integrity: sha512-XOfUup9r3Y06nFAZh3WvO0rBU4OtlfPB/vgxpjg+NRdGU6CN6djdc6OEiH+PcqHCY6eFLo9Ista73uarf4gnBg==} + + '@types/webpack-sources@3.2.3': + resolution: {integrity: sha512-4nZOdMwSPHZ4pTEZzSp0AsTM4K7Qmu40UKW4tJDiOVs20UzYF9l+qUe4s0ftfN0pin06n+5cWWDJXH+sbhAiDw==} + + '@types/webpack@4.41.40': + resolution: {integrity: sha512-u6kMFSBM9HcoTpUXnL6mt2HSzftqb3JgYV6oxIgL2dl6sX6aCa5k6SOkzv5DuZjBTPUE/dJltKtwwuqrkZHpfw==} + + '@types/whatwg-mimetype@3.0.2': + resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} + + '@typescript-eslint/eslint-plugin@8.43.0': + resolution: {integrity: sha512-8tg+gt7ENL7KewsKMKDHXR1vm8tt9eMxjJBYINf6swonlWgkYn5NwyIgXpbbDxTNU5DgpDFfj95prcTq2clIQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.43.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.43.0': + resolution: {integrity: sha512-B7RIQiTsCBBmY+yW4+ILd6mF5h1FUwJsVvpqkrgpszYifetQ2Ke+Z4u6aZh0CblkUGIdR59iYVyXqqZGkZ3aBw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.43.0': + resolution: {integrity: sha512-htB/+D/BIGoNTQYffZw4uM4NzzuolCoaA/BusuSIcC8YjmBYQioew5VUZAYdAETPjeed0hqCaW7EHg+Robq8uw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.43.0': + resolution: {integrity: sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.43.0': + resolution: {integrity: sha512-ALC2prjZcj2YqqL5X/bwWQmHA2em6/94GcbB/KKu5SX3EBDOsqztmmX1kMkvAJHzxk7TazKzJfFiEIagNV3qEA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.43.0': + resolution: {integrity: sha512-qaH1uLBpBuBBuRf8c1mLJ6swOfzCXryhKND04Igr4pckzSEW9JX5Aw9AgW00kwfjWJF0kk0ps9ExKTfvXfw4Qg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.43.0': + resolution: {integrity: sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.43.0': + resolution: {integrity: sha512-7Vv6zlAhPb+cvEpP06WXXy/ZByph9iL6BQRBDj4kmBsW98AqEeQHlj/13X+sZOrKSo9/rNKH4Ul4f6EICREFdw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.43.0': + resolution: {integrity: sha512-S1/tEmkUeeswxd0GGcnwuVQPFWo8NzZTOMxCvw8BX7OMxnNae+i8Tm7REQen/SwUIPoPqfKn7EaZ+YLpiB3k9g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.43.0': + resolution: {integrity: sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + cpu: [x64] + os: [win32] + + '@vitejs/plugin-vue@6.0.1': + resolution: {integrity: sha512-+MaE752hU0wfPFJEUAIxqw18+20euHHdxVtMvbFcOEpjEyfqXH/5DCoTHiVJ0J29EhTJdoTkjEv5YBKU9dnoTw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vue: ^3.2.25 + + '@vitest/eslint-plugin@1.3.9': + resolution: {integrity: sha512-wsNe7xy44ovm/h9ISDkDNcv0aOnUsaOYDqan2y6qCFAUQ0odFr6df/+FdGKHZN+mCM+SvIDWoXuvm5T5V3Kh6w==} + peerDependencies: + eslint: '>= 8.57.0' + typescript: '>= 5.0.0' + vitest: '*' + peerDependenciesMeta: + typescript: + optional: true + vitest: + optional: true + + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + + '@vitest/mocker@3.2.4': + resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + + '@vitest/runner@3.2.4': + resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} + + '@vitest/snapshot@3.2.4': + resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} + + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + + '@volar/language-core@2.4.23': + resolution: {integrity: sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==} + + '@volar/source-map@2.4.23': + resolution: {integrity: sha512-Z1Uc8IB57Lm6k7q6KIDu/p+JWtf3xsXJqAX/5r18hYOTpJyBn0KXUR8oTJ4WFYOcDzWC9n3IflGgHowx6U6z9Q==} + + '@volar/typescript@2.4.23': + resolution: {integrity: sha512-lAB5zJghWxVPqfcStmAP1ZqQacMpe90UrP5RJ3arDyrhy4aCUQqmxPPLB2PWDKugvylmO41ljK7vZ+t6INMTag==} + + '@vue/compiler-core@3.5.21': + resolution: {integrity: sha512-8i+LZ0vf6ZgII5Z9XmUvrCyEzocvWT+TeR2VBUVlzIH6Tyv57E20mPZ1bCS+tbejgUgmjrEh7q/0F0bibskAmw==} + + '@vue/compiler-dom@3.5.21': + resolution: {integrity: sha512-jNtbu/u97wiyEBJlJ9kmdw7tAr5Vy0Aj5CgQmo+6pxWNQhXZDPsRr1UWPN4v3Zf82s2H3kF51IbzZ4jMWAgPlQ==} + + '@vue/compiler-sfc@3.5.21': + resolution: {integrity: sha512-SXlyk6I5eUGBd2v8Ie7tF6ADHE9kCR6mBEuPyH1nUZ0h6Xx6nZI29i12sJKQmzbDyr2tUHMhhTt51Z6blbkTTQ==} + + '@vue/compiler-ssr@3.5.21': + resolution: {integrity: sha512-vKQ5olH5edFZdf5ZrlEgSO1j1DMA4u23TVK5XR1uMhvwnYvVdDF0nHXJUblL/GvzlShQbjhZZ2uvYmDlAbgo9w==} + + '@vue/compiler-vue2@2.7.16': + resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} + + '@vue/language-core@3.0.6': + resolution: {integrity: sha512-e2RRzYWm+qGm8apUHW1wA5RQxzNhkqbbKdbKhiDUcmMrNAZGyM8aTiL3UrTqkaFI5s7wJRGGrp4u3jgusuBp2A==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/reactivity@3.5.21': + resolution: {integrity: sha512-3ah7sa+Cwr9iiYEERt9JfZKPw4A2UlbY8RbbnH2mGCE8NwHkhmlZt2VsH0oDA3P08X3jJd29ohBDtX+TbD9AsA==} + + '@vue/runtime-core@3.5.21': + resolution: {integrity: sha512-+DplQlRS4MXfIf9gfD1BOJpk5RSyGgGXD/R+cumhe8jdjUcq/qlxDawQlSI8hCKupBlvM+3eS1se5xW+SuNAwA==} + + '@vue/runtime-dom@3.5.21': + resolution: {integrity: sha512-3M2DZsOFwM5qI15wrMmNF5RJe1+ARijt2HM3TbzBbPSuBHOQpoidE+Pa+XEaVN+czbHf81ETRoG1ltztP2em8w==} + + '@vue/server-renderer@3.5.21': + resolution: {integrity: sha512-qr8AqgD3DJPJcGvLcJKQo2tAc8OnXRcfxhOJCPF+fcfn5bBGz7VCcO7t+qETOPxpWK1mgysXvVT/j+xWaHeMWA==} + peerDependencies: + vue: 3.5.21 + + '@vue/shared@3.5.21': + resolution: {integrity: sha512-+2k1EQpnYuVuu3N7atWyG3/xoFWIVJZq4Mz8XNOdScFI0etES75fbny/oU4lKWk/577P1zmg0ioYvpGEDZ3DLw==} + + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} + + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} + + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} + + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} + + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} + + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} + + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} + + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} + + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} + + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} + + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} + + '@webassemblyjs/wast-printer@1.14.1': + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} + + '@webpack-cli/configtest@3.0.1': + resolution: {integrity: sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==} + engines: {node: '>=18.12.0'} + peerDependencies: + webpack: ^5.82.0 + webpack-cli: 6.x.x + + '@webpack-cli/info@3.0.1': + resolution: {integrity: sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==} + engines: {node: '>=18.12.0'} + peerDependencies: + webpack: ^5.82.0 + webpack-cli: 6.x.x + + '@webpack-cli/serve@3.0.1': + resolution: {integrity: sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==} + engines: {node: '>=18.12.0'} + peerDependencies: + webpack: ^5.82.0 + webpack-cli: 6.x.x + webpack-dev-server: '*' + peerDependenciesMeta: + webpack-dev-server: + optional: true + + '@xtuc/ieee754@1.2.0': + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + + '@xtuc/long@4.2.2': + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + acorn-import-phases@1.0.4: + resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + acorn: ^8.14.0 + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + add-asset-webpack-plugin@3.0.0: + resolution: {integrity: sha512-mg6nL4E+dNZPQfTc/A4xcOYsIxCN7Cuy9OScZsjI9qOYPiJeFZfsYcdoYlqcNNQEC4w8yNwArhD1Gm+G1iWrNg==} + engines: {node: '>=18'} + peerDependencies: + webpack: '>=5' + + ajv-draft-04@1.0.0: + resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} + peerDependencies: + ajv: ^8.5.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-errors@3.0.0: + resolution: {integrity: sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==} + peerDependencies: + ajv: ^8.0.1 + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + alien-signals@2.0.7: + resolution: {integrity: sha512-wE7y3jmYeb0+h6mr5BOovuqhFv22O/MV9j5p0ndJsa7z1zJNPGQ4ph5pQk/kTTCWRC3xsA4SmtwmkzQO+7NCNg==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + ansi_up@6.0.6: + resolution: {integrity: sha512-yIa1x3Ecf8jWP4UWEunNjqNX6gzE4vg2gGz+xqRGY+TBSucnYp6RRdPV4brmtg6bQ1ljD48mZ5iGSEj7QEpRKA==} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-find-index@1.0.2: + resolution: {integrity: sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==} + engines: {node: '>=0.10.0'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + as-table@1.0.55: + resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + + asciinema-player@3.10.0: + resolution: {integrity: sha512-shoOK6F606nDKZxDVM7JuGSCAyWLePoGRFNlV+FqiP5Sqvyn0BlE7wlbjZyd2X4P1iRhv/HKfVNtnQIxmgphRA==} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + ast-types@0.14.2: + resolution: {integrity: sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==} + engines: {node: '>=4'} + + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + atob@2.1.2: + resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} + engines: {node: '>= 4.5.0'} + hasBin: true + + axe-core@4.10.3: + resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} + engines: {node: '>=4'} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@2.0.0: + resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + big.js@5.2.2: + resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.25.4: + resolution: {integrity: sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + + builtins@1.0.3: + resolution: {integrity: sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + cacheable@1.10.4: + resolution: {integrity: sha512-Gd7ccIUkZ9TE2odLQVS+PDjIvQCdJKUlLdJRVvZu0aipj07Qfx+XIej7hhDrKGGoIxV5m5fT/kOJNJPQhQneRg==} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + caniuse-lite@1.0.30001741: + resolution: {integrity: sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==} + + chai@5.3.3: + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + engines: {node: '>=18'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + chart.js@4.5.0: + resolution: {integrity: sha512-aYeC/jDgSEx8SHWZvANYMioYMZ2KX02W6f6uVfyteuCGcadDLcYVHdfdygsTQkQ4TKn5lghoojAsPj5pu0SnvQ==} + engines: {pnpm: '>=8'} + + chartjs-adapter-dayjs-4@1.0.4: + resolution: {integrity: sha512-yy9BAYW4aNzPVrCWZetbILegTRb7HokhgospPoC3b5iZ5qdlqNmXts2KdSp6AqnjkPAp/YWyHDxLvIvwt5x81w==} + engines: {node: '>=10'} + peerDependencies: + chart.js: '>=4.0.1' + dayjs: ^1.9.7 + + chartjs-plugin-zoom@2.2.0: + resolution: {integrity: sha512-in6kcdiTlP6npIVLMd4zXZ08PDUXC52gZ4FAy5oyjk1zX3gKarXMAof7B9eFiisf9WOC3bh2saHg+J5WtLXZeA==} + peerDependencies: + chart.js: '>=3.2.0' + + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + + chevrotain-allstar@0.3.1: + resolution: {integrity: sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==} + peerDependencies: + chevrotain: ^11.0.0 + + chevrotain@11.0.3: + resolution: {integrity: sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chroma-js@3.1.2: + resolution: {integrity: sha512-IJnETTalXbsLx1eKEgx19d5L6SRM7cH4vINw/99p/M11HCuXGRWL+6YmCm7FWFGIo6dtWuQoQi1dc5yQ7ESIHg==} + + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + + ci-info@4.3.0: + resolution: {integrity: sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==} + engines: {node: '>=8'} + + citeproc@2.4.63: + resolution: {integrity: sha512-68F95Bp4UbgZU/DBUGQn0qV3HDZLCdI9+Bb2ByrTaNJDL5VEm9LqaiNaxljsvoaExSLEXe1/r6n2Z06SCzW3/Q==} + + clean-regexp@1.0.0: + resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} + engines: {node: '>=4'} + + clippie@4.1.7: + resolution: {integrity: sha512-l8BmUmWqOt4mpxeSflcfODJJOU+DsE5atWj82k1zsxd2X82haz2+g12PJPMOt6e1Cs4/ZnOWdRAV+nY9n2o1Rg==} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone-deep@4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} + + codemirror-spell-checker@1.1.2: + resolution: {integrity: sha512-2Tl6n0v+GJRsC9K3MLCdLaMOmvWL0uukajNJseorZJsslaxZyZMgENocPU8R0DyoTAiKsyqiemSOZo7kjGV0LQ==} + + codemirror@5.65.20: + resolution: {integrity: sha512-i5dLDDxwkFCbhjvL2pNjShsojoL3XHyDwsGv1jqETUoW+lzpBKKqNTUWgQwVAOa0tUm4BwekT455ujafi8payA==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + comment-parser@1.4.1: + resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} + engines: {node: '>= 12.0.0'} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + confbox@0.2.2: + resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} + + core-js-compat@3.45.1: + resolution: {integrity: sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==} + + core-js@3.32.2: + resolution: {integrity: sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ==} + + cose-base@1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} + + cose-base@2.2.0: + resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} + + cosmiconfig@9.0.0: + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + cropperjs@1.6.2: + resolution: {integrity: sha512-nhymn9GdnV3CqiEHJVai54TULFAE3VshJTXSqSJKa8yXAKyBKDWdhHarnlIPrshJ0WMFTGuFvG02YjLXfPiuOA==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + css-functions-list@3.2.3: + resolution: {integrity: sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==} + engines: {node: '>=12 || >=16'} + + css-loader@7.1.2: + resolution: {integrity: sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==} + engines: {node: '>= 18.12.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + webpack: ^5.27.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@3.1.0: + resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + css@3.0.0: + resolution: {integrity: sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + cytoscape-cose-bilkent@4.1.0: + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape-fcose@2.2.0: + resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape@3.33.1: + resolution: {integrity: sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==} + engines: {node: '>=0.10'} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + + d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + + d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + + d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + + d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + + d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + + d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + + d3-geo@3.1.1: + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + engines: {node: '>=12'} + + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + + d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + + d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-transition@3.0.1: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + + d3@7.9.0: + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + engines: {node: '>=12'} + + dagre-d3-es@7.0.11: + resolution: {integrity: sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==} + + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + + data-uri-to-buffer@2.0.2: + resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} + + dayjs@1.11.18: + resolution: {integrity: sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==} + + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.2.0: + resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deep-rename-keys@0.2.1: + resolution: {integrity: sha512-RHd9ABw4Fvk+gYDWqwOftG849x0bYOySl/RgX0tLI9i27ZIeSO91mLZJEp7oPHOMFqHvpgu21YptmDt0FYD/0A==} + engines: {node: '>=0.10.0'} + + delaunator@5.0.1: + resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + + dependency-graph@0.11.0: + resolution: {integrity: sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==} + engines: {node: '>= 0.6.0'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-input-range@2.0.1: + resolution: {integrity: sha512-UMGnuQlEepIPCju5NrPe+8y52B+pRvSjIaSPW92KpukoDGSEVkI2iaCR4HxK7K6C7zmVsWE8PEjCYZaJMr3vpg==} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + dompurify@3.2.6: + resolution: {integrity: sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dropzone@6.0.0-beta.2: + resolution: {integrity: sha512-k44yLuFFhRk53M8zP71FaaNzJYIzr99SKmpbO/oZKNslDjNXQsBTdfLs+iONd0U0L94zzlFzRnFdqbLcs7h9fQ==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + easymde@2.20.0: + resolution: {integrity: sha512-V1Z5f92TfR42Na852OWnIZMbM7zotWQYTddNaLYZFVKj7APBbyZ3FYJ27gBw2grMW3R6Qdv9J8n5Ij7XRSIgXQ==} + + electron-to-chromium@1.5.215: + resolution: {integrity: sha512-TIvGp57UpeNetj/wV/xpFNpWGb0b/ROw372lHPx5Aafx02gjTBtWnEEcaSX3W2dLM3OSdGGyHX/cHl01JQsLaQ==} + + emoji-regex@10.5.0: + resolution: {integrity: sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + emojis-list@3.0.0: + resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} + engines: {node: '>= 4'} + + enhanced-resolve@5.18.3: + resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} + engines: {node: '>=10.13.0'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + envinfo@7.14.0: + resolution: {integrity: sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==} + engines: {node: '>=4'} + hasBin: true + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + esbuild-loader@4.3.0: + resolution: {integrity: sha512-D7HeJNdkDKKMarPQO/3dlJT6RwN2YJO7ENU6RPlpOz5YxSHnUNi2yvW41Bckvi1EVwctIaLzlb0ni5ag2GINYA==} + peerDependencies: + webpack: ^4.40.0 || ^5.0.0 + + esbuild@0.25.9: + resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-compat-utils@0.6.5: + resolution: {integrity: sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=6.0.0' + + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-context@0.1.9: + resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + peerDependencies: + unrs-resolver: ^1.0.0 + peerDependenciesMeta: + unrs-resolver: + optional: true + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@4.4.4: + resolution: {integrity: sha512-1iM2zeBvrYmUNTj2vSC/90JTHDth+dfOfiNKkxApWRsTJYNrc8rOdxxIf5vazX+BiAXTeOT0UvWpGI/7qIWQOw==} + engines: {node: ^16.17.0 || >=18.6.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.1: + resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-array-func@4.0.0: + resolution: {integrity: sha512-p3NY2idNIvgmQLF2/62ZskYt8gOuUgQ51smRc3Lh7FtSozpNc2sg+lniz9VaCagLZHEZTl8qGJKqE7xy8O/D/g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=8.40.0' + + eslint-plugin-escompat@3.11.4: + resolution: {integrity: sha512-j0ywwNnIufshOzgAu+PfIig1c7VRClKSNKzpniMT2vXQ4leL5q+e/SpMFQU0nrdL2WFFM44XmhSuwmxb3G0CJg==} + peerDependencies: + eslint: '>=5.14.1' + + eslint-plugin-eslint-comments@3.2.0: + resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} + engines: {node: '>=6.5.0'} + peerDependencies: + eslint: '>=4.19.1' + + eslint-plugin-filenames@1.3.2: + resolution: {integrity: sha512-tqxJTiEM5a0JmRCUYQmxw23vtTxrb2+a3Q2mMOPhFxvt7ZQQJmdiuMby9B/vUAuVMghyP7oET+nIf6EO6CBd/w==} + peerDependencies: + eslint: '*' + + eslint-plugin-github@5.0.2: + resolution: {integrity: sha512-nMdzWJQ5CimjQDY6SFeJ0KIXuNFf0dgDWEd4eP3UWfuTuP/dXcZJDg7MQRvAFt743T1zUi4+/HdOihfu8xJkLA==} + hasBin: true + peerDependencies: + eslint: ^8.0.1 + + eslint-plugin-i18n-text@1.0.1: + resolution: {integrity: sha512-3G3UetST6rdqhqW9SfcfzNYMpQXS7wNkJvp6dsXnjzGiku6Iu5hl3B0kmk6lIcFPwYjhQIY+tXVRtK9TlGT7RA==} + peerDependencies: + eslint: '>=5.0.0' + + eslint-plugin-import-x@4.16.1: + resolution: {integrity: sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/utils': ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 + eslint-import-resolver-node: '*' + peerDependenciesMeta: + '@typescript-eslint/utils': + optional: true + eslint-import-resolver-node: + optional: true + + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jsx-a11y@6.10.2: + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + + eslint-plugin-no-jquery@3.1.1: + resolution: {integrity: sha512-LTLO3jH/Tjr1pmxCEqtV6qmt+OChv8La4fwgG470JRpgxyFF4NOzoC9CRy92GIWD3Yjl0qLEgPmD2FLQWcNEjg==} + peerDependencies: + eslint: '>=8.0.0' + + eslint-plugin-no-only-tests@3.3.0: + resolution: {integrity: sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==} + engines: {node: '>=5.0.0'} + + eslint-plugin-no-use-extend-native@0.5.0: + resolution: {integrity: sha512-dBNjs8hor8rJgeXLH4HTut5eD3RGWf9JUsadIfuL7UosVQ/dnvOKwxEcRrXrFxrMZ8llUVWT+hOimxJABsAUzQ==} + engines: {node: '>=6.0.0'} + + eslint-plugin-playwright@2.2.2: + resolution: {integrity: sha512-j0jKpndIPOXRRP9uMkwb9l/nSmModOU3452nrFdgFJoEv/435J1onk8+aITzjDW8DfypxgmVaDMdmVIa6F7I0w==} + engines: {node: '>=16.6.0'} + peerDependencies: + eslint: '>=8.40.0' + + eslint-plugin-prettier@5.5.4: + resolution: {integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + + eslint-plugin-regexp@2.10.0: + resolution: {integrity: sha512-ovzQT8ESVn5oOe5a7gIDPD5v9bCSjIFJu57sVPDqgPRXicQzOnYfFN21WoQBQF18vrhT5o7UMKFwJQVVjyJ0ng==} + engines: {node: ^18 || >=20} + peerDependencies: + eslint: '>=8.44.0' + + eslint-plugin-sonarjs@3.0.5: + resolution: {integrity: sha512-dI62Ff3zMezUToi161hs2i1HX1ie8Ia2hO0jtNBfdgRBicAG4ydy2WPt0rMTrAe3ZrlqhpAO3w1jcQEdneYoFA==} + peerDependencies: + eslint: ^8.0.0 || ^9.0.0 + + eslint-plugin-unicorn@56.0.1: + resolution: {integrity: sha512-FwVV0Uwf8XPfVnKSGpMg7NtlZh0G0gBarCaFcMUOoqPxXryxdYxTRRv4kH6B9TFCVIrjRXG+emcxIk2ayZilog==} + engines: {node: '>=18.18'} + peerDependencies: + eslint: '>=8.56.0' + + eslint-plugin-vue-scoped-css@2.12.0: + resolution: {integrity: sha512-gEbuvYetNbsPA0IsmERFkVC2/vOHCInfFekNSOsAxWI/7C/bc8PoLal+fRibWfnzWryY6iL8YoluMtrEqWRj1A==} + engines: {node: ^12.22 || ^14.17 || >=16} + peerDependencies: + eslint: '>=5.0.0' + vue-eslint-parser: '>=7.1.0' + + eslint-plugin-vue@10.4.0: + resolution: {integrity: sha512-K6tP0dW8FJVZLQxa2S7LcE1lLw3X8VvB3t887Q6CLrFVxHYBXGANbXvwNzYIu6Ughx1bSJ5BDT0YB3ybPT39lw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 || ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 + vue-eslint-parser: ^10.0.0 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-wc@3.0.1: + resolution: {integrity: sha512-0p1wkSlA2Ue3FA4qW+5LZ+15sy0p1nUyVl1eyBMLq4rtN1LtE9IdI49BXNWMz8N8bM/y7Ulx8SWGAni5f8XO5g==} + peerDependencies: + eslint: '>=8.40.0' + + eslint-rule-documentation@1.0.23: + resolution: {integrity: sha512-pWReu3fkohwyvztx/oQWWgld2iad25TfUdi6wvhhaDPIQjHU/pyvlKgXFw1kX31SQK2Nq9MH+vRDWB0ZLy8fYw==} + engines: {node: '>=4.0.0'} + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@1.0.1: + resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + eventemitter3@2.0.3: + resolution: {integrity: sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + expect-type@1.2.2: + resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} + engines: {node: '>=12.0.0'} + + exsolve@1.0.7: + resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.2.12: + resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} + engines: {node: '>=8.6.0'} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-memoize@2.5.2: + resolution: {integrity: sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + + fastest-levenshtein@1.0.16: + resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} + engines: {node: '>= 4.9.1'} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fetch-ponyfill@7.1.0: + resolution: {integrity: sha512-FhbbL55dj/qdVO3YNK7ZEkshvj3eQ7EuIGV2I6ic/2YiocvyWv+7jg2s4AyS0wdRU75s3tA8ZxI/xPigb0v5Aw==} + + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + + file-entry-cache@10.1.4: + resolution: {integrity: sha512-5XRUFc0WTtUbjfGzEwXc42tiGxQHBmtbUG1h9L2apu4SulCGN3Hqm//9D6FAolf8MYNL7f/YlJl9vy08pj5JuA==} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flat-cache@6.1.13: + resolution: {integrity: sha512-gmtS2PaUjSPa4zjObEIn4WWliKyZzYljgxODBfxugpK6q6HU9ClXzgCJ+nlcPKY9Bt090ypTOLIFWkV0jbKFjw==} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + functional-red-black-tree@1.0.1: + resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.4.0: + resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} + engines: {node: '>=18'} + + get-set-props@0.1.0: + resolution: {integrity: sha512-7oKuKzAGKj0ag+eWZwcGw2fjiZ78tXnXQoBgY0aU7ZOxTu4bB7hSuQSDgtKy978EDH062P5FmD2EWiDpQS9K9Q==} + engines: {node: '>=0.10.0'} + + get-source@2.0.12: + resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} + + get-tsconfig@4.10.1: + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@11.0.3: + resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==} + engines: {node: 20 || >=22} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + global-modules@2.0.0: + resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} + engines: {node: '>=6'} + + global-prefix@3.0.0: + resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} + engines: {node: '>=6'} + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globals@15.15.0: + resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} + engines: {node: '>=18'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globjoin@0.1.4: + resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + hachure-fill@0.5.2: + resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} + + hammerjs@2.0.8: + resolution: {integrity: sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==} + engines: {node: '>=0.8.0'} + + happy-dom@18.0.1: + resolution: {integrity: sha512-qn+rKOW7KWpVTtgIUi6RVmTBZJSe2k0Db0vh1f7CWrWclkkc7/Q+FrOfkZIb2eiErLyqu5AXEzE7XthO9JVxRA==} + engines: {node: '>=20.0.0'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + hash-sum@2.0.0: + resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + hookified@1.12.0: + resolution: {integrity: sha512-hMr1Y9TCLshScrBbV2QxJ9BROddxZ12MX9KsCtuGGy/3SmmN5H1PllKerrVlSotur9dlE8hmUKAOSa3WDzsZmQ==} + + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + + hpagent@1.2.0: + resolution: {integrity: sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==} + engines: {node: '>=14'} + + html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + + htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + + htmx.org@2.0.7: + resolution: {integrity: sha512-YiJqF3U5KyO28VC5mPfehKJPF+n1Gni+cupK+D69TF0nm7wY6AXn3a4mPWIikfAXtl1u1F1+ZhSCS7KT8pVmqA==} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + icss-utils@5.1.0: + resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + idiomorph@0.7.3: + resolution: {integrity: sha512-YI/L1QQkBRDtiaGZN+/KolIkNoZuIsCgus1ciueosiqdyWz/weeP+ghFgDQpk2vzA3BkX6/M/kY5SCM03LBDkA==} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + immer@9.0.21: + resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + import-local@3.2.0: + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + engines: {node: '>=8'} + hasBin: true + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@4.1.3: + resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + + interpret@3.1.1: + resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==} + engines: {node: '>=10.13.0'} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + + is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-get-set-prop@1.0.0: + resolution: {integrity: sha512-DvAYZ1ZgGUz4lzxKMPYlt08qAUqyG9ckSg2pIjfvcQ7+pkVNUHk8yVLXOnCLe5WKXhLop8oorWFBJHpwWQpszQ==} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-js-type@2.0.0: + resolution: {integrity: sha512-Aj13l47+uyTjlQNHtXBV8Cji3jb037vxwMWCgopRR8h6xocgBGW3qG8qGlIOEmbXQtkKShKuBM9e8AA1OeQ+xw==} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-obj-prop@1.0.0: + resolution: {integrity: sha512-5Idb61slRlJlsAzi0Wsfwbp+zZY+9LXKUAZpvT/1ySw+NxKLRWfa0Bzj+wXI3fX5O9hiddm5c3DAaRSNP/yl2w==} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-proto-prop@2.0.0: + resolution: {integrity: sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==} + + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + + is-valid-element-name@1.0.0: + resolution: {integrity: sha512-GZITEJY2LkSjQfaIPBha7eyZv+ge0PhBR7KITeCCWvy7VBQrCUdFkvpI+HrAPQjVtVjy1LvlEkqQTHckoszruw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jackspeak@4.1.1: + resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} + engines: {node: 20 || >=22} + + jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + jiti@2.5.1: + resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==} + hasBin: true + + jquery@3.7.1: + resolution: {integrity: sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==} + + js-levenshtein-esm@2.0.0: + resolution: {integrity: sha512-1n4LEPOL4wRXY8rOQcuA7Iuaphe5xCMayvufCzlLAi+hRsnBRDbSS6XPuV58CBVJxj5D9ApFLyjQ7KzFToyHBw==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + + js-types@1.0.0: + resolution: {integrity: sha512-bfwqBW9cC/Lp7xcRpug7YrXm0IVw+T9e3g4mCYnv0Pjr3zIzU9PCQElYU9oSGAWzXlbdl9X5SAMPejO9sxkeUw==} + engines: {node: '>=0.10.0'} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsdoc-type-pratt-parser@4.8.0: + resolution: {integrity: sha512-iZ8Bdb84lWRuGHamRXFyML07r21pcwBrLkHEuHgEY5UbCouBwv7ECknDRKzsQIXMiqpPymqtIf8TC/shYKB5rw==} + engines: {node: '>=12.0.0'} + + jsep@1.4.0: + resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==} + engines: {node: '>= 10.16.0'} + + jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-parser@2.2.1: + resolution: {integrity: sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==} + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + + jsonpath-plus@10.3.0: + resolution: {integrity: sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==} + engines: {node: '>=18.0.0'} + hasBin: true + + jsonpointer@5.0.1: + resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} + engines: {node: '>=0.10.0'} + + jsx-ast-utils-x@0.1.0: + resolution: {integrity: sha512-eQQBjBnsVtGacsG9uJNB8qOr3yA8rga4wAaGG1qRcBzSIvfhERLrWxMAM1hp5fcS6Abo8M4+bUBTekYR0qTPQw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + just-extend@5.1.1: + resolution: {integrity: sha512-b+z6yF1d4EOyDgylzQo5IminlUmzSeqR1hs/bzjBNjuGras4FXq/6TrzjxfN0j+TmI0ltJzTNlqXUMCniciwKQ==} + + katex@0.16.22: + resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==} + hasBin: true + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + keyv@5.5.0: + resolution: {integrity: sha512-QG7qR2tijh1ftOvClut4YKKg1iW6cx3GZsKoGyJPxHkGWK9oJhG9P3j5deP0QQOGDowBMVQFaP+Vm4NpGYvmIQ==} + + khroma@2.1.0: + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + + kind-of@3.2.2: + resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} + engines: {node: '>=0.10.0'} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + known-css-properties@0.37.0: + resolution: {integrity: sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==} + + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + + langium@3.3.1: + resolution: {integrity: sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==} + engines: {node: '>=16.0.0'} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + layout-base@1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + + layout-base@2.0.1: + resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + + loader-runner@4.3.0: + resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + engines: {node: '>=6.11.5'} + + loader-utils@2.0.4: + resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} + engines: {node: '>=8.9.0'} + + local-pkg@1.1.2: + resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} + engines: {node: '>=14'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + lodash.kebabcase@4.1.1: + resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + + lodash.sortedlastindex@4.1.0: + resolution: {integrity: sha512-s8xEQdsp2Tu5zUqVdFSe9C0kR8YlnAJYLqMdkh+pIRBRxF6/apWseLdHl3/+jv2I61dhPwtI/Ff+EqvCpc+N8w==} + + lodash.topath@4.5.2: + resolution: {integrity: sha512-1/W4dM+35DwvE/iEd1M9ekewOSTlpFekhw9mhAtrwjVqUr83/ilQiyAvmg4tVX7Unkcfl1KC+i9WdaT4B6aQcg==} + + lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + + lodash.upperfirst@4.3.1: + resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + + lowercase-keys@1.0.1: + resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} + engines: {node: '>=0.10.0'} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@11.2.1: + resolution: {integrity: sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==} + engines: {node: 20 || >=22} + + magic-string@0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + + magic-string@0.30.19: + resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} + + markdown-escape@2.0.0: + resolution: {integrity: sha512-Trz4v0+XWlwy68LJIyw3bLbsJiC8XAbRCKF9DbEtZjyndKOGVx6n+wNB0VfoRmY2LKboQLeniap3xrb6LGSJ8A==} + + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + + markdownlint-cli@0.45.0: + resolution: {integrity: sha512-GiWr7GfJLVfcopL3t3pLumXCYs8sgWppjIA1F/Cc3zIMgD3tmkpyZ1xkm1Tej8mw53B93JsDjgA3KOftuYcfOw==} + engines: {node: '>=20'} + hasBin: true + + markdownlint@0.38.0: + resolution: {integrity: sha512-xaSxkaU7wY/0852zGApM8LdlIfGCW8ETZ0Rr62IQtAnUMlMuifsg09vWJcNYeL4f0anvr8Vo4ZQar8jGpV0btQ==} + engines: {node: '>=20'} + + marked@15.0.12: + resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==} + engines: {node: '>= 18'} + hasBin: true + + marked@4.3.0: + resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} + engines: {node: '>= 12'} + hasBin: true + + material-icon-theme@5.27.0: + resolution: {integrity: sha512-zB3LtPY2n6z4Kp5fSc7OT8KwAZIJRvcOq6PZR4jmAkvmW1Ot+y6lNJmNqERK9rYAT42tZD1YmkhHaMcA2KEObA==} + engines: {vscode: ^1.55.0} + + mathml-tag-names@2.1.3: + resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} + + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.12.2: + resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + + meow@13.2.0: + resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} + engines: {node: '>=18'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + mermaid@11.11.0: + resolution: {integrity: sha512-9lb/VNkZqWTRjVgCV+l1N+t4kyi94y+l5xrmBmbbxZYkfRl5hEDaTPMOcaWKCl1McG8nBEaMlWwkcAEEgjhBgg==} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-directive@4.0.0: + resolution: {integrity: sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-math@3.1.0: + resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + + mini-css-extract-plugin@2.9.4: + resolution: {integrity: sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ==} + engines: {node: '>= 12.13.0'} + peerDependencies: + webpack: ^5.0.0 + + minimatch@10.0.3: + resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} + engines: {node: 20 || >=22} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mlly@1.8.0: + resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + + monaco-editor-webpack-plugin@7.1.0: + resolution: {integrity: sha512-ZjnGINHN963JQkFqjjcBtn1XBtUATDZBMgNQhDQwd78w2ukRhFXAPNgWuacaQiDZsUr4h1rWv5Mv6eriKuOSzA==} + peerDependencies: + monaco-editor: '>= 0.31.0' + webpack: ^4.5.0 || 5.x + + monaco-editor@0.53.0: + resolution: {integrity: sha512-0WNThgC6CMWNXXBxTbaYYcunj08iB5rnx4/G56UOPeL9UVIUGGHA1GR0EWIh9Ebabj7NpCRawQ5b0hfN1jQmYQ==} + + moo@0.5.2: + resolution: {integrity: sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanopop@2.3.0: + resolution: {integrity: sha512-fzN+T2K7/Ah25XU02MJkPZ5q4Tj5FpjmIYq4rvoHX4yb16HzFdCO6JxFFn5Y/oBhQ8no8fUZavnyIv9/+xkBBw==} + + napi-postinstall@0.3.3: + resolution: {integrity: sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + nimma@0.2.3: + resolution: {integrity: sha512-1ZOI8J+1PKKGceo/5CT5GfQOG6H8I2BencSK06YarZ2wXwH37BSSUWldqJmMJYA5JfqDqffxDXynt6f11AyKcA==} + engines: {node: ^12.20 || >=14.13} + + node-fetch@2.6.13: + resolution: {integrity: sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-releases@2.0.20: + resolution: {integrity: sha512-7gK6zSXEH6neM212JgfYFXe+GmZQM+fia5SsusuBIUgnPheLFBmIPhtFoAQRj8/7wASYQnbDlHPVwY0BefoFgA==} + + node-sarif-builder@2.0.3: + resolution: {integrity: sha512-Pzr3rol8fvhG/oJjIq2NTVB0vmdNNlz22FENhhPojYRZ4/ee08CfK4YuKmuL54V9MLhI1kpzxfOJ/63LzmZzDg==} + engines: {node: '>=14'} + + nolyfill@1.0.44: + resolution: {integrity: sha512-PoggwVLiJUn0MnodpftsiC7EuknW5+6v62ntTOQ6T6l7g2r6aoaOwgk0tQW2BxGLYw9bF298LL8jDFTmEFuzlA==} + engines: {node: '>=12.4.0'} + hasBin: true + + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + obj-props@1.4.0: + resolution: {integrity: sha512-p7p/7ltzPDiBs6DqxOrIbtRdwxxVRBj5ROukeNb9RgA+fawhrz5n2hpNz8DDmYR//tviJSj7nUnlppGmONkjiQ==} + engines: {node: '>=0.10.0'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + online-3d-viewer@0.16.0: + resolution: {integrity: sha512-Mcmo41TM3K+svlMDRH8ySKSY2e8s7Sssdb5U9LV3gkFKVWGGuS304Vk5gqxopAJbE72DpsC67Ve3YNtcAuROwQ==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + package-manager-detector@1.3.0: + resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-data-parser@0.1.0: + resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-scurry@2.0.0: + resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + engines: {node: 20 || >=22} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pathval@2.0.1: + resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} + engines: {node: '>= 14.16'} + + pdfobject@2.3.1: + resolution: {integrity: sha512-vluuGiSDmMGpOvWFGiUY4trNB8aGKLDVxIXuuGHjX0kK3bMxCANUVtLivctE7uejLBScWCnbVarKatFVvdwXaQ==} + + perfect-debounce@2.0.0: + resolution: {integrity: sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pkg-types@2.3.0: + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + + playwright-core@1.55.0: + resolution: {integrity: sha512-GvZs4vU3U5ro2nZpeiwyb0zuFaqb9sUiAJuyrWpcGouD8y9/HLgGbNRjIph7zU9D3hnPaisMl9zG9CgFi/biIg==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.55.0: + resolution: {integrity: sha512-sdCWStblvV1YU909Xqx0DhOjPZE4/5lJsIS84IfN9dAZfcl/CIZ5O8l3o0j7hPMjDvqoTF8ZUcc+i/GL5erstA==} + engines: {node: '>=18'} + hasBin: true + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + points-on-curve@0.2.0: + resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} + + points-on-path@0.2.1: + resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} + + pony-cause@1.1.1: + resolution: {integrity: sha512-PxkIc/2ZpLiEzQXu5YRDOUgBlfGYBY8156HY5ZcRAwwonMk5W/MrJP2LLkG/hF7GEQzaHo2aS7ho6ZLCOvf+6g==} + engines: {node: '>=12.0.0'} + + postcss-html@1.8.0: + resolution: {integrity: sha512-5mMeb1TgLWoRKxZ0Xh9RZDfwUUIqRrcxO2uXO+Ezl1N5lqpCiSU5Gk6+1kZediBfBHFtPCdopr2UZ2SgUsKcgQ==} + engines: {node: ^12 || >=14} + + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.0.1: + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@4.0.2: + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + + postcss-loader@8.2.0: + resolution: {integrity: sha512-tHX+RkpsXVcc7st4dSdDGliI+r4aAQDuv+v3vFYHixb6YgjreG5AG4SEB0kDK8u2s6htqEEpKlkhSBUTvWKYnA==} + engines: {node: '>= 18.12.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + postcss: ^7.0.0 || ^8.0.1 + webpack: ^5.0.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true + + postcss-modules-extract-imports@3.1.0: + resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-local-by-default@4.2.0: + resolution: {integrity: sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-scope@3.2.1: + resolution: {integrity: sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-values@4.0.0: + resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-nesting@13.0.2: + resolution: {integrity: sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-resolve-nested-selector@0.1.6: + resolution: {integrity: sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==} + + postcss-safe-parser@6.0.0: + resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.3.3 + + postcss-safe-parser@7.0.1: + resolution: {integrity: sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==} + engines: {node: '>=18.0'} + peerDependencies: + postcss: ^8.4.31 + + postcss-scss@4.0.9: + resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.4.29 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-selector-parser@7.1.0: + resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} + engines: {node: '>=4'} + + postcss-styl@0.12.3: + resolution: {integrity: sha512-8I7Cd8sxiEITIp32xBK4K/Aj1ukX6vuWnx8oY/oAH35NfQI4OZaY5nd68Yx8HeN5S49uhQ6DL0rNk0ZBu/TaLg==} + engines: {node: ^8.10.0 || ^10.13.0 || ^11.10.1 || >=12.13.0} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + engines: {node: '>=14'} + hasBin: true + + printable-characters@1.0.42: + resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} + + proto-props@2.0.0: + resolution: {integrity: sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ==} + engines: {node: '>=4'} + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + + read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + rechoir@0.8.0: + resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} + engines: {node: '>= 10.13.0'} + + refa@0.12.1: + resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + regexp-ast-analysis@0.7.1: + resolution: {integrity: sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + regexp-tree@0.1.27: + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + hasBin: true + + regjsparser@0.10.0: + resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} + hasBin: true + + rename-keys@1.2.0: + resolution: {integrity: sha512-U7XpAktpbSgHTRSNRrjKSrjYkZKuhUukfoBlXWXUExCAqhzh1TU3BDRAfJmarcl5voKS+pbKU9MvyLWKZ4UEEg==} + engines: {node: '>= 0.8.0'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + reserved@0.1.2: + resolution: {integrity: sha512-/qO54MWj5L8WCBP9/UNe2iefJc+L9yETbH32xO/ft/EYPOTCR5k+azvDUgdCOKwZH8hXwPd0b8XBL78Nn2U69g==} + engines: {node: '>=0.8'} + + resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + robust-predicates@3.0.2: + resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + + rollup@2.79.2: + resolution: {integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==} + engines: {node: '>=10.0.0'} + hasBin: true + + rollup@4.50.1: + resolution: {integrity: sha512-78E9voJHwnXQMiQdiqswVLZwJIzdBKJ1GdI5Zx6XwoFKUIk09/sSrr+05QFzvYb8q6Y9pPV45zzDuYa3907TZA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + roughjs@4.6.6: + resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} + + run-con@1.3.2: + resolution: {integrity: sha512-CcfE+mYiTcKEzg0IqS08+efdnH0oJ3zV0wSUFBNrMHMuxCtXvBCLzCJHatwuXDcu/RlhjTziTo/a1ruQik6/Yg==} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + + safe-stable-stringify@1.1.1: + resolution: {integrity: sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==} + + sax@1.2.4: + resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} + + sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + + schema-utils@4.3.2: + resolution: {integrity: sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==} + engines: {node: '>= 10.13.0'} + + scslre@0.3.0: + resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} + engines: {node: ^14.0.0 || >=16.0.0} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + seroval-plugins@1.3.3: + resolution: {integrity: sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + + seroval@1.3.2: + resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==} + engines: {node: '>=10'} + + shallow-clone@3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-eval@1.0.1: + resolution: {integrity: sha512-LH7FpTAkeD+y5xQC4fzS+tFtaNlvt3Ib1zKzvhjv/Y+cioV4zIuw4IZr2yhRLu67CWL7FR9/6KXKnjRoZTvGGQ==} + engines: {node: '>=12'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + + smol-toml@1.3.4: + resolution: {integrity: sha512-UOPtVuYkzYGee0Bd2Szz8d2G3RfMfJ2t3qVdZUAozZyAk+a0Sxa+QKix0YCwjL/A1RR0ar44nCxaoN9FxdJGwA==} + engines: {node: '>= 18'} + + solid-js@1.9.9: + resolution: {integrity: sha512-A0ZBPJQldAeGCTW0YRYJmt7RCeh5rbFfPZ2aOttgYnctHE7HgKeHCBB/PVc2P7eOfmNXqMFFFoYYdm3S4dcbkA==} + + sortablejs@1.15.6: + resolution: {integrity: sha512-aNfiuwMEpfBM/CN6LY0ibyhxPfPbyFeBTYJKCvzkJ2GkUpazIt3H+QIPAMHwqQ7tMKaHz1Qj+rJJCqljnf4p3A==} + + source-list-map@2.0.1: + resolution: {integrity: sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-resolve@0.6.0: + resolution: {integrity: sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==} + deprecated: See https://github.com/lydell/source-map-resolve#deprecated + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + + spdx-compare@1.0.0: + resolution: {integrity: sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-expression-validate@2.0.0: + resolution: {integrity: sha512-b3wydZLM+Tc6CFvaRDBOF9d76oGIHNCLYFeHbftFXUWjnfZWganmDmvtM5sm1cRwJc/VDBMLyGGrsLFd1vOxbg==} + + spdx-license-ids@3.0.22: + resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} + + spdx-ranges@2.1.1: + resolution: {integrity: sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==} + + spdx-satisfies@5.0.1: + resolution: {integrity: sha512-Nwor6W6gzFp8XX4neaKQ7ChV4wmpSh2sSDemMFSzHxpTw460jxFYeOn+jq4ybnSSw/5sc3pjka9MQPouksQNpw==} + + stable-hash-x@0.2.0: + resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} + engines: {node: '>=12.0.0'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + stacktracey@2.1.8: + resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} + + std-env@3.9.0: + resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strip-literal@3.0.0: + resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} + + style-search@0.1.0: + resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==} + + stylelint-config-recommended@17.0.0: + resolution: {integrity: sha512-WaMSdEiPfZTSFVoYmJbxorJfA610O0tlYuU2aEwY33UQhSPgFbClrVJYWvy3jGJx+XW37O+LyNLiZOEXhKhJmA==} + engines: {node: '>=18.12.0'} + peerDependencies: + stylelint: ^16.23.0 + + stylelint-declaration-block-no-ignored-properties@2.8.0: + resolution: {integrity: sha512-Ws8Cav7Y+SPN0JsV407LrnNXWOrqGjxShf+37GBtnU/C58Syve9c0+I/xpLcFOosST3ternykn3Lp77f3ITnFw==} + engines: {node: '>=6'} + peerDependencies: + stylelint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + + stylelint-declaration-strict-value@1.10.11: + resolution: {integrity: sha512-oVQvhZlFZAiDz9r2BPFZLtTGm1A2JVhdKObKAJoTjFfR4F/NpApC4bMBTxf4sZS76Na3njYKVOaAaKSZ4+FU+g==} + engines: {node: '>=18.12.0'} + peerDependencies: + stylelint: '>=7 <=16' + + stylelint-value-no-unknown-custom-properties@6.0.1: + resolution: {integrity: sha512-N60PTdaTknB35j6D4FhW0GL2LlBRV++bRpXMMldWMQZ240yFQaoltzlLY4lXXs7Z0J5mNUYZQ/gjyVtU2DhCMA==} + engines: {node: '>=18.12.0'} + peerDependencies: + stylelint: '>=16' + + stylelint@16.24.0: + resolution: {integrity: sha512-7ksgz3zJaSbTUGr/ujMXvLVKdDhLbGl3R/3arNudH7z88+XZZGNLMTepsY28WlnvEFcuOmUe7fg40Q3lfhOfSQ==} + engines: {node: '>=18.12.0'} + hasBin: true + + stylis@4.3.6: + resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} + + stylus@0.57.0: + resolution: {integrity: sha512-yOI6G8WYfr0q8v8rRvE91wbxFU+rJPo760Va4MF6K0I6BZjO4r+xSynkvyPBP9tV1CIEUeRsiidjIs2rzb1CnQ==} + hasBin: true + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + superstruct@0.10.13: + resolution: {integrity: sha512-W4SitSZ9MOyMPbHreoZVEneSZyPEeNGbdfJo/7FkJyRs/M3wQRFzq+t3S/NBwlrFSWdx1ONLjLb9pB+UKe4IqQ==} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-hyperlinks@3.2.0: + resolution: {integrity: sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==} + engines: {node: '>=14.18'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svg-element-attributes@1.3.1: + resolution: {integrity: sha512-Bh05dSOnJBf3miNMqpsormfNtfidA/GxQVakhtn0T4DECWKeXQRQUceYjJ+OxYiiLdGe4Jo9iFV8wICFapFeIA==} + + svg-tags@1.0.0: + resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} + + svgo@4.0.0: + resolution: {integrity: sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==} + engines: {node: '>=16'} + hasBin: true + + svgson@5.3.1: + resolution: {integrity: sha512-qdPgvUNWb40gWktBJnbJRelWcPzkLed/ShhnRsjbayXz8OtdPOzbil9jtiZdrYvSDumAz/VNQr6JaNfPx/gvPA==} + + swagger-ui-dist@5.29.0: + resolution: {integrity: sha512-gqs7Md3AxP4mbpXAq31o5QW+wGUZsUzVatg70yXpUR245dfIis5jAzufBd+UQM/w2xSfrhvA1eqsrgnl2PbezQ==} + + sync-fetch@0.4.5: + resolution: {integrity: sha512-esiWJ7ixSKGpd9DJPBTC4ckChqdOjIwJfYhVHkcQ2Gnm41323p1TRmEI+esTQ9ppD+b5opps2OTEGTCGX5kF+g==} + engines: {node: '>=14'} + + synckit@0.11.11: + resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} + engines: {node: ^14.18.0 || >=16.0.0} + + table@6.9.0: + resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} + engines: {node: '>=10.0.0'} + + tailwindcss@3.4.17: + resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} + engines: {node: '>=14.0.0'} + hasBin: true + + tapable@2.2.3: + resolution: {integrity: sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==} + engines: {node: '>=6'} + + terser-webpack-plugin@5.3.14: + resolution: {integrity: sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + + terser@5.44.0: + resolution: {integrity: sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==} + engines: {node: '>=10'} + hasBin: true + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + three@0.176.0: + resolution: {integrity: sha512-PWRKYWQo23ojf9oZSlRGH8K09q7nRSWx6LY/HF/UUrMdYgN9i1e2OwJYHoQjwc6HF/4lvvYLC5YC1X8UJL2ZpA==} + + throttle-debounce@5.0.2: + resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==} + engines: {node: '>=12.22'} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinycolor2@1.6.0: + resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyexec@1.0.1: + resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@2.0.0: + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} + engines: {node: '>=14.0.0'} + + tinyspy@4.0.3: + resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} + engines: {node: '>=14.0.0'} + + tippy.js@6.3.7: + resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toastify-js@1.12.0: + resolution: {integrity: sha512-HeMHCO9yLPvP9k0apGSdPUWrUbLnxUKNFzgUoZp1PHCLploIX/4DSQ7V8H25ef+h4iO9n0he7ImfcndnN6nDrQ==} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tributejs@5.1.3: + resolution: {integrity: sha512-B5CXihaVzXw+1UHhNFyAwUTMDk1EfoLP5Tj1VhD9yybZ1I8DZJEv8tZ1l0RJo0t0tk9ZhR8eG5tEsaCvRigmdQ==} + + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + + type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typescript@5.9.2: + resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} + engines: {node: '>=14.17'} + hasBin: true + + typo-js@1.3.1: + resolution: {integrity: sha512-elJkpCL6Z77Ghw0Lv0lGnhBAjSTOQ5FhiVOCfOuxhaoTT2xtLVbqikYItK5HHchzPbHEUFAcjOH669T2ZzeCbg==} + + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + + uint8-to-base64@0.2.1: + resolution: {integrity: sha512-uO/84GaoDUfiAxpa8EksjVLE77A9Kc7ZTziN4zRpq4de9yLaLcZn3jx1/sVjyupsywcVX6RKWbqLe7gUNyzH+Q==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici-types@7.10.0: + resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + updates@16.7.0: + resolution: {integrity: sha512-GOqKdZREAlOR90YBBY8FpkmJOPjjxntYcuAKZRWXK5Pvt2CAcPREk+KeqClG3yqqk+NGWkqAsIxa1ORzQB1iQA==} + engines: {node: '>=20'} + hasBin: true + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + urijs@1.19.11: + resolution: {integrity: sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + utility-types@3.11.0: + resolution: {integrity: sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==} + engines: {node: '>= 4'} + + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + validate-npm-package-name@3.0.0: + resolution: {integrity: sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==} + + vanilla-colorful@0.7.2: + resolution: {integrity: sha512-z2YZusTFC6KnLERx1cgoIRX2CjPRP0W75N+3CC6gbvdX5Ch47rZkEMGO2Xnf+IEmi3RiFLxS18gayMA27iU7Kg==} + + vite-node@3.2.4: + resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + + vite-string-plugin@1.4.6: + resolution: {integrity: sha512-Csjtny8/uVIynzlaRRj4RpHrPAakNwlH9jw6kgQ8tQhc2f0zzA6bCbAgWD0y84EgB8aLNrz7pZFUqSt3LOtk+w==} + + vite@7.1.5: + resolution: {integrity: sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@3.2.4: + resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/debug': ^4.1.12 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@vitest/browser': 3.2.4 + '@vitest/ui': 3.2.4 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/debug': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + + vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + + vscode-languageserver-textdocument@1.0.12: + resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} + + vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + + vscode-languageserver@9.0.1: + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + hasBin: true + + vscode-uri@3.0.8: + resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} + + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + + vue-bar-graph@2.2.0: + resolution: {integrity: sha512-1xFPho2nM6nFDziExLu48vKO+Q90gjxz1NyHfc+MhgfYDSxR9BMyhOIXUO5EmwKIVEX5dBoP2n3Ius8SjKRD4g==} + + vue-chartjs@5.3.2: + resolution: {integrity: sha512-NrkbRRoYshbXbWqJkTN6InoDVwVb90C0R7eAVgMWcB9dPikbruaOoTFjFYHE/+tNPdIe6qdLCDjfjPHQ0fw4jw==} + peerDependencies: + chart.js: ^4.1.1 + vue: ^3.0.0-0 || ^2.7.0 + + vue-eslint-parser@10.2.0: + resolution: {integrity: sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + + vue-loader@17.4.2: + resolution: {integrity: sha512-yTKOA4R/VN4jqjw4y5HrynFL8AK0Z3/Jt7eOJXEitsm0GMRHDBjCfCiuTiLP7OESvsZYo2pATCWhDqxC5ZrM6w==} + peerDependencies: + '@vue/compiler-sfc': '*' + vue: '*' + webpack: ^4.1.0 || ^5.0.0-0 + peerDependenciesMeta: + '@vue/compiler-sfc': + optional: true + vue: + optional: true + + vue-tsc@3.0.6: + resolution: {integrity: sha512-Tbs8Whd43R2e2nxez4WXPvvdjGbW24rOSgRhLOHXzWiT4pcP4G7KeWh0YCn18rF4bVwv7tggLLZ6MJnO6jXPBg==} + hasBin: true + peerDependencies: + typescript: '>=5.0.0' + + vue@3.5.21: + resolution: {integrity: sha512-xxf9rum9KtOdwdRkiApWL+9hZEMWE90FHh8yS1+KJAiWYh+iGWV1FquPjoO9VUHQ+VIhsCXNNyZ5Sf4++RVZBA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + watchpack@2.4.4: + resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==} + engines: {node: '>=10.13.0'} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webpack-cli@6.0.1: + resolution: {integrity: sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==} + engines: {node: '>=18.12.0'} + hasBin: true + peerDependencies: + webpack: ^5.82.0 + webpack-bundle-analyzer: '*' + webpack-dev-server: '*' + peerDependenciesMeta: + webpack-bundle-analyzer: + optional: true + webpack-dev-server: + optional: true + + webpack-merge@6.0.1: + resolution: {integrity: sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==} + engines: {node: '>=18.0.0'} + + webpack-sources@1.4.3: + resolution: {integrity: sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==} + + webpack-sources@3.3.3: + resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} + engines: {node: '>=10.13.0'} + + webpack@5.101.3: + resolution: {integrity: sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + wildcard@2.0.1: + resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@5.0.1: + resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + xml-lexer@0.2.2: + resolution: {integrity: sha512-G0i98epIwiUEiKmMcavmVdhtymW+pCAohMRgybyIME9ygfVu8QheIi+YoQh3ngiThsT0SQzJT4R0sKDEv8Ou0w==} + + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + + xml-reader@2.4.3: + resolution: {integrity: sha512-xWldrIxjeAMAu6+HSf9t50ot1uL5M+BtOidRCWHXIeewvSeIpscWCsp4Zxjk8kHHhdqFBrfK8U0EJeCcnyQ/gA==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yaml@2.8.1: + resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@alloc/quick-lru@5.2.0': {} + + '@antfu/install-pkg@1.1.0': + dependencies: + package-manager-detector: 1.3.0 + tinyexec: 1.0.1 + + '@antfu/utils@9.2.0': {} + + '@asyncapi/specs@6.10.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.27.1': {} + + '@babel/parser@7.28.4': + dependencies: + '@babel/types': 7.28.4 + + '@babel/runtime@7.28.4': {} + + '@babel/types@7.28.4': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + + '@braintree/sanitize-url@7.1.1': {} + + '@chevrotain/cst-dts-gen@11.0.3': + dependencies: + '@chevrotain/gast': 11.0.3 + '@chevrotain/types': 11.0.3 + lodash-es: 4.17.21 + + '@chevrotain/gast@11.0.3': + dependencies: + '@chevrotain/types': 11.0.3 + lodash-es: 4.17.21 + + '@chevrotain/regexp-to-ast@11.0.3': {} + + '@chevrotain/types@11.0.3': {} + + '@chevrotain/utils@11.0.3': {} + + '@citation-js/core@0.7.18': + dependencies: + '@citation-js/date': 0.5.1 + '@citation-js/name': 0.4.2 + fetch-ponyfill: 7.1.0 + sync-fetch: 0.4.5 + transitivePeerDependencies: + - encoding + + '@citation-js/date@0.5.1': {} + + '@citation-js/name@0.4.2': {} + + '@citation-js/plugin-bibtex@0.7.18(@citation-js/core@0.7.18)': + dependencies: + '@citation-js/core': 0.7.18 + '@citation-js/date': 0.5.1 + '@citation-js/name': 0.4.2 + moo: 0.5.2 + + '@citation-js/plugin-cff@0.6.1': + dependencies: + '@citation-js/date': 0.5.1 + '@citation-js/plugin-yaml': 0.6.1 + + '@citation-js/plugin-csl@0.7.18(@citation-js/core@0.7.18)': + dependencies: + '@citation-js/core': 0.7.18 + '@citation-js/date': 0.5.1 + citeproc: 2.4.63 + + '@citation-js/plugin-github@0.6.1': + dependencies: + '@citation-js/date': 0.5.1 + '@citation-js/name': 0.4.2 + + '@citation-js/plugin-npm@0.6.1': + dependencies: + '@citation-js/date': 0.5.1 + '@citation-js/name': 0.4.2 + + '@citation-js/plugin-software-formats@0.6.1': + dependencies: + '@citation-js/plugin-cff': 0.6.1 + '@citation-js/plugin-github': 0.6.1 + '@citation-js/plugin-npm': 0.6.1 + '@citation-js/plugin-yaml': 0.6.1 + '@citation-js/plugin-zenodo': 0.6.1 + + '@citation-js/plugin-yaml@0.6.1': + dependencies: + js-yaml: 4.1.0 + + '@citation-js/plugin-zenodo@0.6.1': + dependencies: + '@citation-js/date': 0.5.1 + '@citation-js/name': 0.4.2 + + '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-tokenizer@3.0.4': {} + + '@csstools/media-query-list-parser@4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/selector-resolve-nested@3.1.0(postcss-selector-parser@7.1.0)': + dependencies: + postcss-selector-parser: 7.1.0 + + '@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.1.0)': + dependencies: + postcss-selector-parser: 7.1.0 + + '@discoveryjs/json-ext@0.6.3': {} + + '@dual-bundle/import-meta-resolve@4.2.1': {} + + '@emnapi/core@1.5.0': + dependencies: + '@emnapi/wasi-threads': 1.1.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.5.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.1.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.25.9': + optional: true + + '@esbuild/android-arm64@0.25.9': + optional: true + + '@esbuild/android-arm@0.25.9': + optional: true + + '@esbuild/android-x64@0.25.9': + optional: true + + '@esbuild/darwin-arm64@0.25.9': + optional: true + + '@esbuild/darwin-x64@0.25.9': + optional: true + + '@esbuild/freebsd-arm64@0.25.9': + optional: true + + '@esbuild/freebsd-x64@0.25.9': + optional: true + + '@esbuild/linux-arm64@0.25.9': + optional: true + + '@esbuild/linux-arm@0.25.9': + optional: true + + '@esbuild/linux-ia32@0.25.9': + optional: true + + '@esbuild/linux-loong64@0.25.9': + optional: true + + '@esbuild/linux-mips64el@0.25.9': + optional: true + + '@esbuild/linux-ppc64@0.25.9': + optional: true + + '@esbuild/linux-riscv64@0.25.9': + optional: true + + '@esbuild/linux-s390x@0.25.9': + optional: true + + '@esbuild/linux-x64@0.25.9': + optional: true + + '@esbuild/netbsd-arm64@0.25.9': + optional: true + + '@esbuild/netbsd-x64@0.25.9': + optional: true + + '@esbuild/openbsd-arm64@0.25.9': + optional: true + + '@esbuild/openbsd-x64@0.25.9': + optional: true + + '@esbuild/openharmony-arm64@0.25.9': + optional: true + + '@esbuild/sunos-x64@0.25.9': + optional: true + + '@esbuild/win32-arm64@0.25.9': + optional: true + + '@esbuild/win32-ia32@0.25.9': + optional: true + + '@esbuild/win32-x64@0.25.9': + optional: true + + '@eslint-community/eslint-plugin-eslint-comments@4.5.0(eslint@8.57.0)': + dependencies: + escape-string-regexp: 4.0.0 + eslint: 8.57.0 + ignore: 5.3.2 + + '@eslint-community/eslint-utils@4.9.0(eslint@8.57.0)': + dependencies: + eslint: 8.57.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.12.6 + debug: 4.4.1 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.0': {} + + '@github/browserslist-config@1.0.0': {} + + '@github/combobox-nav@2.3.1': {} + + '@github/markdown-toolbar-element@2.2.3': {} + + '@github/relative-time-element@4.4.8': {} + + '@github/text-expander-element@2.9.2': + dependencies: + '@github/combobox-nav': 2.3.1 + dom-input-range: 2.0.1 + + '@humanwhocodes/config-array@0.11.14': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.4.1 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@iconify/types@2.0.0': {} + + '@iconify/utils@3.0.1': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@antfu/utils': 9.2.0 + '@iconify/types': 2.0.0 + debug: 4.4.1 + globals: 15.15.0 + kolorist: 1.8.0 + local-pkg: 1.1.2 + mlly: 1.8.0 + transitivePeerDependencies: + - supports-color + + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.2 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.30 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/source-map@0.3.11': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.30 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.30': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@jsep-plugin/assignment@1.3.0(jsep@1.4.0)': + dependencies: + jsep: 1.4.0 + + '@jsep-plugin/regex@1.0.4(jsep@1.4.0)': + dependencies: + jsep: 1.4.0 + + '@jsep-plugin/ternary@1.1.4(jsep@1.4.0)': + dependencies: + jsep: 1.4.0 + + '@keyv/serialize@1.1.0': {} + + '@kurkle/color@0.3.4': {} + + '@mcaptcha/core-glue@0.1.0-alpha-5': {} + + '@mcaptcha/vanilla-glue@0.1.0-alpha-3': + dependencies: + '@mcaptcha/core-glue': 0.1.0-alpha-5 + + '@mermaid-js/parser@0.6.2': + dependencies: + langium: 3.3.1 + + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.5.0 + '@emnapi/runtime': 1.5.0 + '@tybys/wasm-util': 0.10.0 + optional: true + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@nolyfill/array-includes@1.0.44': + dependencies: + '@nolyfill/shared': 1.0.44 + + '@nolyfill/array.prototype.findlastindex@1.0.44': + dependencies: + '@nolyfill/shared': 1.0.44 + + '@nolyfill/array.prototype.flat@1.0.44': + dependencies: + '@nolyfill/shared': 1.0.44 + + '@nolyfill/array.prototype.flatmap@1.0.44': + dependencies: + '@nolyfill/shared': 1.0.44 + + '@nolyfill/es-aggregate-error@1.0.44': + dependencies: + '@nolyfill/shared': 1.0.44 + + '@nolyfill/hasown@1.0.44': {} + + '@nolyfill/is-core-module@1.0.39': {} + + '@nolyfill/object.assign@1.0.44': + dependencies: + '@nolyfill/shared': 1.0.44 + + '@nolyfill/object.fromentries@1.0.44': + dependencies: + '@nolyfill/shared': 1.0.44 + + '@nolyfill/object.groupby@1.0.44': + dependencies: + '@nolyfill/shared': 1.0.44 + + '@nolyfill/object.values@1.0.44': + dependencies: + '@nolyfill/shared': 1.0.44 + + '@nolyfill/safe-buffer@1.0.44': {} + + '@nolyfill/safe-regex-test@1.0.44': {} + + '@nolyfill/safer-buffer@1.0.44': {} + + '@nolyfill/shared@1.0.44': {} + + '@nolyfill/string.prototype.includes@1.0.44': + dependencies: + '@nolyfill/shared': 1.0.44 + + '@nolyfill/string.prototype.trimend@1.0.44': + dependencies: + '@nolyfill/shared': 1.0.44 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pkgr/core@0.2.9': {} + + '@playwright/test@1.55.0': + dependencies: + playwright: 1.55.0 + + '@popperjs/core@2.11.8': {} + + '@primer/octicons@19.18.0': + dependencies: + object-assign: 4.1.1 + + '@resvg/resvg-wasm@2.6.2': {} + + '@rolldown/pluginutils@1.0.0-beta.29': {} + + '@rollup/plugin-commonjs@22.0.2(rollup@2.79.2)': + dependencies: + '@rollup/pluginutils': 3.1.0(rollup@2.79.2) + commondir: 1.0.1 + estree-walker: 2.0.2 + glob: 7.2.3 + is-reference: 1.2.1 + magic-string: 0.25.9 + resolve: 1.22.10 + rollup: 2.79.2 + + '@rollup/pluginutils@3.1.0(rollup@2.79.2)': + dependencies: + '@types/estree': 0.0.39 + estree-walker: 1.0.1 + picomatch: 2.3.1 + rollup: 2.79.2 + + '@rollup/rollup-android-arm-eabi@4.50.1': + optional: true + + '@rollup/rollup-android-arm64@4.50.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.50.1': + optional: true + + '@rollup/rollup-darwin-x64@4.50.1': + optional: true + + '@rollup/rollup-freebsd-arm64@4.50.1': + optional: true + + '@rollup/rollup-freebsd-x64@4.50.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.50.1': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.50.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.50.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.50.1': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.50.1': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.50.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.50.1': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.50.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.50.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.50.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.50.1': + optional: true + + '@rollup/rollup-openharmony-arm64@4.50.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.50.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.50.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.50.1': + optional: true + + '@rtsao/scc@1.1.0': {} + + '@scarf/scarf@1.4.0': {} + + '@silverwind/vue3-calendar-heatmap@2.0.6(tippy.js@6.3.7)(vue@3.5.21(typescript@5.9.2))': + dependencies: + tippy.js: 6.3.7 + vue: 3.5.21(typescript@5.9.2) + + '@simonwep/pickr@1.9.0': + dependencies: + core-js: 3.32.2 + nanopop: 2.3.0 + + '@stoplight/better-ajv-errors@1.0.3(ajv@8.17.1)': + dependencies: + ajv: 8.17.1 + jsonpointer: 5.0.1 + leven: 3.1.0 + + '@stoplight/json-ref-readers@1.2.2': + dependencies: + node-fetch: 2.7.0 + tslib: 1.14.1 + transitivePeerDependencies: + - encoding + + '@stoplight/json-ref-resolver@3.1.6': + dependencies: + '@stoplight/json': 3.21.7 + '@stoplight/path': 1.3.2 + '@stoplight/types': 13.20.0 + '@types/urijs': 1.19.25 + dependency-graph: 0.11.0 + fast-memoize: 2.5.2 + immer: 9.0.21 + lodash: 4.17.21 + tslib: 2.8.1 + urijs: 1.19.11 + + '@stoplight/json@3.21.7': + dependencies: + '@stoplight/ordered-object-literal': 1.0.5 + '@stoplight/path': 1.3.2 + '@stoplight/types': 13.20.0 + jsonc-parser: 2.2.1 + lodash: 4.17.21 + safe-stable-stringify: 1.1.1 + + '@stoplight/ordered-object-literal@1.0.5': {} + + '@stoplight/path@1.3.2': {} + + '@stoplight/spectral-cli@6.15.0': + dependencies: + '@stoplight/json': 3.21.7 + '@stoplight/path': 1.3.2 + '@stoplight/spectral-core': 1.20.0 + '@stoplight/spectral-formatters': 1.5.0 + '@stoplight/spectral-parsers': 1.0.5 + '@stoplight/spectral-ref-resolver': 1.0.5 + '@stoplight/spectral-ruleset-bundler': 1.6.3 + '@stoplight/spectral-ruleset-migrator': 1.11.2 + '@stoplight/spectral-rulesets': 1.22.0 + '@stoplight/spectral-runtime': 1.1.4 + '@stoplight/types': 13.20.0 + chalk: 4.1.2 + fast-glob: 3.2.12 + hpagent: 1.2.0 + lodash: 4.17.21 + pony-cause: 1.1.1 + stacktracey: 2.1.8 + tslib: 2.8.1 + yargs: 17.7.2 + transitivePeerDependencies: + - encoding + + '@stoplight/spectral-core@1.20.0': + dependencies: + '@stoplight/better-ajv-errors': 1.0.3(ajv@8.17.1) + '@stoplight/json': 3.21.7 + '@stoplight/path': 1.3.2 + '@stoplight/spectral-parsers': 1.0.5 + '@stoplight/spectral-ref-resolver': 1.0.5 + '@stoplight/spectral-runtime': 1.1.4 + '@stoplight/types': 13.6.0 + '@types/es-aggregate-error': 1.0.6 + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-errors: 3.0.0(ajv@8.17.1) + ajv-formats: 2.1.1(ajv@8.17.1) + es-aggregate-error: '@nolyfill/es-aggregate-error@1.0.44' + jsonpath-plus: 10.3.0 + lodash: 4.17.21 + lodash.topath: 4.5.2 + minimatch: 3.1.2 + nimma: 0.2.3 + pony-cause: 1.1.1 + simple-eval: 1.0.1 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + + '@stoplight/spectral-formats@1.8.2': + dependencies: + '@stoplight/json': 3.21.7 + '@stoplight/spectral-core': 1.20.0 + '@types/json-schema': 7.0.15 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + + '@stoplight/spectral-formatters@1.5.0': + dependencies: + '@stoplight/path': 1.3.2 + '@stoplight/spectral-core': 1.20.0 + '@stoplight/spectral-runtime': 1.1.4 + '@stoplight/types': 13.20.0 + '@types/markdown-escape': 1.1.3 + chalk: 4.1.2 + cliui: 7.0.4 + lodash: 4.17.21 + markdown-escape: 2.0.0 + node-sarif-builder: 2.0.3 + strip-ansi: 6.0.1 + text-table: 0.2.0 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + + '@stoplight/spectral-functions@1.10.1': + dependencies: + '@stoplight/better-ajv-errors': 1.0.3(ajv@8.17.1) + '@stoplight/json': 3.21.7 + '@stoplight/spectral-core': 1.20.0 + '@stoplight/spectral-formats': 1.8.2 + '@stoplight/spectral-runtime': 1.1.4 + ajv: 8.17.1 + ajv-draft-04: 1.0.0(ajv@8.17.1) + ajv-errors: 3.0.0(ajv@8.17.1) + ajv-formats: 2.1.1(ajv@8.17.1) + lodash: 4.17.21 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + + '@stoplight/spectral-parsers@1.0.5': + dependencies: + '@stoplight/json': 3.21.7 + '@stoplight/types': 14.1.1 + '@stoplight/yaml': 4.3.0 + tslib: 2.8.1 + + '@stoplight/spectral-ref-resolver@1.0.5': + dependencies: + '@stoplight/json-ref-readers': 1.2.2 + '@stoplight/json-ref-resolver': 3.1.6 + '@stoplight/spectral-runtime': 1.1.4 + dependency-graph: 0.11.0 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + + '@stoplight/spectral-ruleset-bundler@1.6.3': + dependencies: + '@rollup/plugin-commonjs': 22.0.2(rollup@2.79.2) + '@stoplight/path': 1.3.2 + '@stoplight/spectral-core': 1.20.0 + '@stoplight/spectral-formats': 1.8.2 + '@stoplight/spectral-functions': 1.10.1 + '@stoplight/spectral-parsers': 1.0.5 + '@stoplight/spectral-ref-resolver': 1.0.5 + '@stoplight/spectral-ruleset-migrator': 1.11.2 + '@stoplight/spectral-rulesets': 1.22.0 + '@stoplight/spectral-runtime': 1.1.4 + '@stoplight/types': 13.20.0 + '@types/node': 24.3.1 + pony-cause: 1.1.1 + rollup: 2.79.2 + tslib: 2.8.1 + validate-npm-package-name: 3.0.0 + transitivePeerDependencies: + - encoding + + '@stoplight/spectral-ruleset-migrator@1.11.2': + dependencies: + '@stoplight/json': 3.21.7 + '@stoplight/ordered-object-literal': 1.0.5 + '@stoplight/path': 1.3.2 + '@stoplight/spectral-functions': 1.10.1 + '@stoplight/spectral-runtime': 1.1.4 + '@stoplight/types': 13.20.0 + '@stoplight/yaml': 4.2.3 + '@types/node': 24.3.1 + ajv: 8.17.1 + ast-types: 0.14.2 + astring: 1.9.0 + reserved: 0.1.2 + tslib: 2.8.1 + validate-npm-package-name: 3.0.0 + transitivePeerDependencies: + - encoding + + '@stoplight/spectral-rulesets@1.22.0': + dependencies: + '@asyncapi/specs': 6.10.0 + '@stoplight/better-ajv-errors': 1.0.3(ajv@8.17.1) + '@stoplight/json': 3.21.7 + '@stoplight/spectral-core': 1.20.0 + '@stoplight/spectral-formats': 1.8.2 + '@stoplight/spectral-functions': 1.10.1 + '@stoplight/spectral-runtime': 1.1.4 + '@stoplight/types': 13.20.0 + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + json-schema-traverse: 1.0.0 + leven: 3.1.0 + lodash: 4.17.21 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + + '@stoplight/spectral-runtime@1.1.4': + dependencies: + '@stoplight/json': 3.21.7 + '@stoplight/path': 1.3.2 + '@stoplight/types': 13.20.0 + abort-controller: 3.0.0 + lodash: 4.17.21 + node-fetch: 2.7.0 + tslib: 2.8.1 + transitivePeerDependencies: + - encoding + + '@stoplight/types@13.20.0': + dependencies: + '@types/json-schema': 7.0.15 + utility-types: 3.11.0 + + '@stoplight/types@13.6.0': + dependencies: + '@types/json-schema': 7.0.15 + utility-types: 3.11.0 + + '@stoplight/types@14.1.1': + dependencies: + '@types/json-schema': 7.0.15 + utility-types: 3.11.0 + + '@stoplight/yaml-ast-parser@0.0.48': {} + + '@stoplight/yaml-ast-parser@0.0.50': {} + + '@stoplight/yaml@4.2.3': + dependencies: + '@stoplight/ordered-object-literal': 1.0.5 + '@stoplight/types': 13.20.0 + '@stoplight/yaml-ast-parser': 0.0.48 + tslib: 2.8.1 + + '@stoplight/yaml@4.3.0': + dependencies: + '@stoplight/ordered-object-literal': 1.0.5 + '@stoplight/types': 14.1.1 + '@stoplight/yaml-ast-parser': 0.0.50 + tslib: 2.8.1 + + '@stylistic/eslint-plugin-js@3.1.0(eslint@8.57.0)': + dependencies: + eslint: 8.57.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + + '@stylistic/stylelint-plugin@4.0.0(stylelint@16.24.0(typescript@5.9.2))': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + postcss-value-parser: 4.2.0 + style-search: 0.1.0 + stylelint: 16.24.0(typescript@5.9.2) + + '@swc/helpers@0.2.14': {} + + '@techknowlogick/license-checker-webpack-plugin@0.3.0(webpack@5.101.3)': + dependencies: + glob: 7.2.3 + lodash: 4.17.21 + minimatch: 3.1.2 + semver: 6.3.1 + spdx-expression-validate: 2.0.0 + spdx-satisfies: 5.0.1 + superstruct: 0.10.13 + webpack: 5.101.3(webpack-cli@6.0.1) + webpack-sources: 1.4.3 + wrap-ansi: 6.2.0 + + '@tybys/wasm-util@0.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/chai@5.2.2': + dependencies: + '@types/deep-eql': 4.0.2 + + '@types/codemirror@5.60.16': + dependencies: + '@types/tern': 0.23.9 + + '@types/d3-array@3.2.1': {} + + '@types/d3-axis@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-brush@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-chord@3.0.6': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-contour@3.0.6': + dependencies: + '@types/d3-array': 3.2.1 + '@types/geojson': 7946.0.16 + + '@types/d3-delaunay@6.0.4': {} + + '@types/d3-dispatch@3.0.7': {} + + '@types/d3-drag@3.0.7': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-dsv@3.0.7': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-fetch@3.0.7': + dependencies: + '@types/d3-dsv': 3.0.7 + + '@types/d3-force@3.0.10': {} + + '@types/d3-format@3.0.4': {} + + '@types/d3-geo@3.1.0': + dependencies: + '@types/geojson': 7946.0.16 + + '@types/d3-hierarchy@3.1.7': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.1': {} + + '@types/d3-polygon@3.0.2': {} + + '@types/d3-quadtree@3.0.6': {} + + '@types/d3-random@3.0.3': {} + + '@types/d3-scale-chromatic@3.1.0': {} + + '@types/d3-scale@4.0.9': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-selection@3.0.11': {} + + '@types/d3-shape@3.1.7': + dependencies: + '@types/d3-path': 3.1.1 + + '@types/d3-time-format@4.0.3': {} + + '@types/d3-time@3.0.4': {} + + '@types/d3-timer@3.0.2': {} + + '@types/d3-transition@3.0.9': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-zoom@3.0.8': + dependencies: + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.11 + + '@types/d3@7.4.3': + dependencies: + '@types/d3-array': 3.2.1 + '@types/d3-axis': 3.0.6 + '@types/d3-brush': 3.0.6 + '@types/d3-chord': 3.0.6 + '@types/d3-color': 3.1.3 + '@types/d3-contour': 3.0.6 + '@types/d3-delaunay': 6.0.4 + '@types/d3-dispatch': 3.0.7 + '@types/d3-drag': 3.0.7 + '@types/d3-dsv': 3.0.7 + '@types/d3-ease': 3.0.2 + '@types/d3-fetch': 3.0.7 + '@types/d3-force': 3.0.10 + '@types/d3-format': 3.0.4 + '@types/d3-geo': 3.1.0 + '@types/d3-hierarchy': 3.1.7 + '@types/d3-interpolate': 3.0.4 + '@types/d3-path': 3.1.1 + '@types/d3-polygon': 3.0.2 + '@types/d3-quadtree': 3.0.6 + '@types/d3-random': 3.0.3 + '@types/d3-scale': 4.0.9 + '@types/d3-scale-chromatic': 3.1.0 + '@types/d3-selection': 3.0.11 + '@types/d3-shape': 3.1.7 + '@types/d3-time': 3.0.4 + '@types/d3-time-format': 4.0.3 + '@types/d3-timer': 3.0.2 + '@types/d3-transition': 3.0.9 + '@types/d3-zoom': 3.0.8 + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + + '@types/deep-eql@4.0.2': {} + + '@types/dropzone@5.7.9': + dependencies: + '@types/jquery': 3.5.33 + + '@types/es-aggregate-error@1.0.6': + dependencies: + '@types/node': 24.3.1 + + '@types/eslint-scope@3.7.7': + dependencies: + '@types/eslint': 9.6.1 + '@types/estree': 1.0.8 + + '@types/eslint@9.6.1': + dependencies: + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + + '@types/estree@0.0.39': {} + + '@types/estree@1.0.8': {} + + '@types/geojson@7946.0.16': {} + + '@types/hammerjs@2.0.46': {} + + '@types/jquery@3.5.33': + dependencies: + '@types/sizzle': 2.3.10 + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/katex@0.16.7': {} + + '@types/license-checker-webpack-plugin@0.2.5': + dependencies: + '@types/webpack': 4.41.40 + + '@types/markdown-escape@1.1.3': {} + + '@types/marked@4.3.2': {} + + '@types/ms@2.1.0': {} + + '@types/node@20.19.13': + dependencies: + undici-types: 6.21.0 + + '@types/node@24.3.1': + dependencies: + undici-types: 7.10.0 + + '@types/normalize-package-data@2.4.4': {} + + '@types/pdfobject@2.2.5': {} + + '@types/sarif@2.1.7': {} + + '@types/sizzle@2.3.10': {} + + '@types/sortablejs@1.15.8': {} + + '@types/source-list-map@0.1.6': {} + + '@types/swagger-ui-dist@3.30.6': {} + + '@types/tapable@1.0.12': {} + + '@types/tern@0.23.9': + dependencies: + '@types/estree': 1.0.8 + + '@types/throttle-debounce@5.0.2': {} + + '@types/tinycolor2@1.4.6': {} + + '@types/toastify-js@1.12.4': {} + + '@types/trusted-types@1.0.6': {} + + '@types/trusted-types@2.0.7': + optional: true + + '@types/uglify-js@3.17.5': + dependencies: + source-map: 0.6.1 + + '@types/unist@2.0.11': {} + + '@types/urijs@1.19.25': {} + + '@types/webpack-sources@3.2.3': + dependencies: + '@types/node': 24.3.1 + '@types/source-list-map': 0.1.6 + source-map: 0.7.6 + + '@types/webpack@4.41.40': + dependencies: + '@types/node': 24.3.1 + '@types/tapable': 1.0.12 + '@types/uglify-js': 3.17.5 + '@types/webpack-sources': 3.2.3 + anymatch: 3.1.3 + source-map: 0.6.1 + + '@types/whatwg-mimetype@3.0.2': {} + + '@typescript-eslint/eslint-plugin@8.43.0(@typescript-eslint/parser@8.43.0(eslint@8.57.0)(typescript@5.9.2))(eslint@8.57.0)(typescript@5.9.2)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.43.0(eslint@8.57.0)(typescript@5.9.2) + '@typescript-eslint/scope-manager': 8.43.0 + '@typescript-eslint/type-utils': 8.43.0(eslint@8.57.0)(typescript@5.9.2) + '@typescript-eslint/utils': 8.43.0(eslint@8.57.0)(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.43.0 + eslint: 8.57.0 + graphemer: 1.4.0 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.43.0(eslint@8.57.0)(typescript@5.9.2)': + dependencies: + '@typescript-eslint/scope-manager': 8.43.0 + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.43.0 + debug: 4.4.1 + eslint: 8.57.0 + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.43.0(typescript@5.9.2)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.9.2) + '@typescript-eslint/types': 8.43.0 + debug: 4.4.1 + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.43.0': + dependencies: + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/visitor-keys': 8.43.0 + + '@typescript-eslint/tsconfig-utils@8.43.0(typescript@5.9.2)': + dependencies: + typescript: 5.9.2 + + '@typescript-eslint/type-utils@8.43.0(eslint@8.57.0)(typescript@5.9.2)': + dependencies: + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2) + '@typescript-eslint/utils': 8.43.0(eslint@8.57.0)(typescript@5.9.2) + debug: 4.4.1 + eslint: 8.57.0 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.43.0': {} + + '@typescript-eslint/typescript-estree@8.43.0(typescript@5.9.2)': + dependencies: + '@typescript-eslint/project-service': 8.43.0(typescript@5.9.2) + '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.9.2) + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/visitor-keys': 8.43.0 + debug: 4.4.1 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.2 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.43.0(eslint@8.57.0)(typescript@5.9.2)': + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.0) + '@typescript-eslint/scope-manager': 8.43.0 + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2) + eslint: 8.57.0 + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.43.0': + dependencies: + '@typescript-eslint/types': 8.43.0 + eslint-visitor-keys: 4.2.1 + + '@ungap/structured-clone@1.3.0': {} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + optional: true + + '@unrs/resolver-binding-android-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + optional: true + + '@vitejs/plugin-vue@6.0.1(vite@7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.21(typescript@5.9.2))': + dependencies: + '@rolldown/pluginutils': 1.0.0-beta.29 + vite: 7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1) + vue: 3.5.21(typescript@5.9.2) + + '@vitest/eslint-plugin@1.3.9(eslint@8.57.0)(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(happy-dom@18.0.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1))': + dependencies: + '@typescript-eslint/scope-manager': 8.43.0 + '@typescript-eslint/utils': 8.43.0(eslint@8.57.0)(typescript@5.9.2) + eslint: 8.57.0 + optionalDependencies: + typescript: 5.9.2 + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(happy-dom@18.0.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1) + transitivePeerDependencies: + - supports-color + + '@vitest/expect@3.2.4': + dependencies: + '@types/chai': 5.2.2 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.3.3 + tinyrainbow: 2.0.0 + + '@vitest/mocker@3.2.4(vite@7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1))': + dependencies: + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.19 + optionalDependencies: + vite: 7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1) + + '@vitest/pretty-format@3.2.4': + dependencies: + tinyrainbow: 2.0.0 + + '@vitest/runner@3.2.4': + dependencies: + '@vitest/utils': 3.2.4 + pathe: 2.0.3 + strip-literal: 3.0.0 + + '@vitest/snapshot@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + magic-string: 0.30.19 + pathe: 2.0.3 + + '@vitest/spy@3.2.4': + dependencies: + tinyspy: 4.0.3 + + '@vitest/utils@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + loupe: 3.2.1 + tinyrainbow: 2.0.0 + + '@volar/language-core@2.4.23': + dependencies: + '@volar/source-map': 2.4.23 + + '@volar/source-map@2.4.23': {} + + '@volar/typescript@2.4.23': + dependencies: + '@volar/language-core': 2.4.23 + path-browserify: 1.0.1 + vscode-uri: 3.1.0 + + '@vue/compiler-core@3.5.21': + dependencies: + '@babel/parser': 7.28.4 + '@vue/shared': 3.5.21 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.21': + dependencies: + '@vue/compiler-core': 3.5.21 + '@vue/shared': 3.5.21 + + '@vue/compiler-sfc@3.5.21': + dependencies: + '@babel/parser': 7.28.4 + '@vue/compiler-core': 3.5.21 + '@vue/compiler-dom': 3.5.21 + '@vue/compiler-ssr': 3.5.21 + '@vue/shared': 3.5.21 + estree-walker: 2.0.2 + magic-string: 0.30.19 + postcss: 8.5.6 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.21': + dependencies: + '@vue/compiler-dom': 3.5.21 + '@vue/shared': 3.5.21 + + '@vue/compiler-vue2@2.7.16': + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + '@vue/language-core@3.0.6(typescript@5.9.2)': + dependencies: + '@volar/language-core': 2.4.23 + '@vue/compiler-dom': 3.5.21 + '@vue/compiler-vue2': 2.7.16 + '@vue/shared': 3.5.21 + alien-signals: 2.0.7 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + picomatch: 4.0.3 + optionalDependencies: + typescript: 5.9.2 + + '@vue/reactivity@3.5.21': + dependencies: + '@vue/shared': 3.5.21 + + '@vue/runtime-core@3.5.21': + dependencies: + '@vue/reactivity': 3.5.21 + '@vue/shared': 3.5.21 + + '@vue/runtime-dom@3.5.21': + dependencies: + '@vue/reactivity': 3.5.21 + '@vue/runtime-core': 3.5.21 + '@vue/shared': 3.5.21 + csstype: 3.1.3 + + '@vue/server-renderer@3.5.21(vue@3.5.21(typescript@5.9.2))': + dependencies: + '@vue/compiler-ssr': 3.5.21 + '@vue/shared': 3.5.21 + vue: 3.5.21(typescript@5.9.2) + + '@vue/shared@3.5.21': {} + + '@webassemblyjs/ast@1.14.1': + dependencies: + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} + + '@webassemblyjs/helper-api-error@1.13.2': {} + + '@webassemblyjs/helper-buffer@1.14.1': {} + + '@webassemblyjs/helper-numbers@1.13.2': + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} + + '@webassemblyjs/helper-wasm-section@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 + + '@webassemblyjs/ieee754@1.13.2': + dependencies: + '@xtuc/ieee754': 1.2.0 + + '@webassemblyjs/leb128@1.13.2': + dependencies: + '@xtuc/long': 4.2.2 + + '@webassemblyjs/utf8@1.13.2': {} + + '@webassemblyjs/wasm-edit@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 + + '@webassemblyjs/wasm-gen@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wasm-opt@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + + '@webassemblyjs/wasm-parser@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wast-printer@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@xtuc/long': 4.2.2 + + '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1)(webpack@5.101.3)': + dependencies: + webpack: 5.101.3(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack@5.101.3) + + '@webpack-cli/info@3.0.1(webpack-cli@6.0.1)(webpack@5.101.3)': + dependencies: + webpack: 5.101.3(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack@5.101.3) + + '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1)(webpack@5.101.3)': + dependencies: + webpack: 5.101.3(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack@5.101.3) + + '@xtuc/ieee754@1.2.0': {} + + '@xtuc/long@4.2.2': {} + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + acorn-import-phases@1.0.4(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn@8.15.0: {} + + add-asset-webpack-plugin@3.0.0(webpack@5.101.3): + dependencies: + webpack: 5.101.3(webpack-cli@6.0.1) + + ajv-draft-04@1.0.0(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv-errors@3.0.0(ajv@8.17.1): + dependencies: + ajv: 8.17.1 + + ajv-formats@2.1.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv-keywords@5.1.0(ajv@8.17.1): + dependencies: + ajv: 8.17.1 + fast-deep-equal: 3.1.3 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + alien-signals@2.0.7: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + ansi_up@6.0.6: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@5.0.2: {} + + argparse@2.0.1: {} + + aria-query@5.3.2: {} + + array-find-index@1.0.2: {} + + array-union@2.1.0: {} + + as-table@1.0.55: + dependencies: + printable-characters: 1.0.42 + + asciinema-player@3.10.0: + dependencies: + '@babel/runtime': 7.28.4 + solid-js: 1.9.9 + + assertion-error@2.0.1: {} + + ast-types-flow@0.0.8: {} + + ast-types@0.14.2: + dependencies: + tslib: 2.8.1 + + astral-regex@2.0.0: {} + + astring@1.9.0: {} + + atob@2.1.2: {} + + axe-core@4.10.3: {} + + axobject-query@4.1.0: {} + + balanced-match@1.0.2: {} + + balanced-match@2.0.0: {} + + base64-js@1.5.1: {} + + big.js@5.2.2: {} + + binary-extensions@2.3.0: {} + + boolbase@1.0.0: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.25.4: + dependencies: + caniuse-lite: 1.0.30001741 + electron-to-chromium: 1.5.215 + node-releases: 2.0.20 + update-browserslist-db: 1.1.3(browserslist@4.25.4) + + buffer-from@1.1.2: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + builtin-modules@3.3.0: {} + + builtins@1.0.3: {} + + bytes@3.1.2: {} + + cac@6.7.14: {} + + cacheable@1.10.4: + dependencies: + hookified: 1.12.0 + keyv: 5.5.0 + + callsites@3.1.0: {} + + camelcase-css@2.0.1: {} + + caniuse-lite@1.0.30001741: {} + + chai@5.3.3: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.2.1 + pathval: 2.0.1 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + chart.js@4.5.0: + dependencies: + '@kurkle/color': 0.3.4 + + chartjs-adapter-dayjs-4@1.0.4(chart.js@4.5.0)(dayjs@1.11.18): + dependencies: + chart.js: 4.5.0 + dayjs: 1.11.18 + + chartjs-plugin-zoom@2.2.0(chart.js@4.5.0): + dependencies: + '@types/hammerjs': 2.0.46 + chart.js: 4.5.0 + hammerjs: 2.0.8 + + check-error@2.1.1: {} + + chevrotain-allstar@0.3.1(chevrotain@11.0.3): + dependencies: + chevrotain: 11.0.3 + lodash-es: 4.17.21 + + chevrotain@11.0.3: + dependencies: + '@chevrotain/cst-dts-gen': 11.0.3 + '@chevrotain/gast': 11.0.3 + '@chevrotain/regexp-to-ast': 11.0.3 + '@chevrotain/types': 11.0.3 + '@chevrotain/utils': 11.0.3 + lodash-es: 4.17.21 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chroma-js@3.1.2: {} + + chrome-trace-event@1.0.4: {} + + ci-info@4.3.0: {} + + citeproc@2.4.63: {} + + clean-regexp@1.0.0: + dependencies: + escape-string-regexp: 1.0.5 + + clippie@4.1.7: {} + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone-deep@4.0.1: + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 + + codemirror-spell-checker@1.1.2: + dependencies: + typo-js: 1.3.1 + + codemirror@5.65.20: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + colord@2.9.3: {} + + colorette@2.0.20: {} + + commander@11.1.0: {} + + commander@12.1.0: {} + + commander@13.1.0: {} + + commander@2.20.3: {} + + commander@4.1.1: {} + + commander@7.2.0: {} + + commander@8.3.0: {} + + comment-parser@1.4.1: {} + + commondir@1.0.1: {} + + concat-map@0.0.1: {} + + confbox@0.1.8: {} + + confbox@0.2.2: {} + + core-js-compat@3.45.1: + dependencies: + browserslist: 4.25.4 + + core-js@3.32.2: {} + + cose-base@1.0.3: + dependencies: + layout-base: 1.0.2 + + cose-base@2.2.0: + dependencies: + layout-base: 2.0.1 + + cosmiconfig@9.0.0(typescript@5.9.2): + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + parse-json: 5.2.0 + optionalDependencies: + typescript: 5.9.2 + + cropperjs@1.6.2: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css-functions-list@3.2.3: {} + + css-loader@7.1.2(webpack@5.101.3): + dependencies: + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.6) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.6) + postcss-modules-scope: 3.2.1(postcss@8.5.6) + postcss-modules-values: 4.0.0(postcss@8.5.6) + postcss-value-parser: 4.2.0 + semver: 7.7.2 + optionalDependencies: + webpack: 5.101.3(webpack-cli@6.0.1) + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.1 + + css-tree@3.1.0: + dependencies: + mdn-data: 2.12.2 + source-map-js: 1.2.1 + + css-what@6.2.2: {} + + css@3.0.0: + dependencies: + inherits: 2.0.4 + source-map: 0.6.1 + source-map-resolve: 0.6.0 + + cssesc@3.0.0: {} + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + + csstype@3.1.3: {} + + cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.1): + dependencies: + cose-base: 1.0.3 + cytoscape: 3.33.1 + + cytoscape-fcose@2.2.0(cytoscape@3.33.1): + dependencies: + cose-base: 2.2.0 + cytoscape: 3.33.1 + + cytoscape@3.33.1: {} + + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-axis@3.0.0: {} + + d3-brush@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3-chord@3.0.1: + dependencies: + d3-path: 3.1.0 + + d3-color@3.1.0: {} + + d3-contour@4.0.2: + dependencies: + d3-array: 3.2.4 + + d3-delaunay@6.0.4: + dependencies: + delaunator: 5.0.1 + + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + + d3-ease@3.0.1: {} + + d3-fetch@3.0.1: + dependencies: + d3-dsv: 3.0.1 + + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + + d3-format@3.1.0: {} + + d3-geo@3.1.1: + dependencies: + d3-array: 3.2.4 + + d3-hierarchy@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-path@3.1.0: {} + + d3-polygon@3.0.1: {} + + d3-quadtree@3.0.1: {} + + d3-random@3.0.1: {} + + d3-sankey@0.12.3: + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-selection@3.0.0: {} + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3@7.9.0: + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.0 + d3-geo: 3.1.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + + dagre-d3-es@7.0.11: + dependencies: + d3: 7.9.0 + lodash-es: 4.17.21 + + damerau-levenshtein@1.0.8: {} + + data-uri-to-buffer@2.0.2: {} + + dayjs@1.11.18: {} + + de-indent@1.0.2: {} + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.4.1: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.2.0: + dependencies: + character-entities: 2.0.2 + + decode-uri-component@0.2.2: {} + + deep-eql@5.0.2: {} + + deep-extend@0.6.0: {} + + deep-is@0.1.4: {} + + deep-rename-keys@0.2.1: + dependencies: + kind-of: 3.2.2 + rename-keys: 1.2.0 + + delaunator@5.0.1: + dependencies: + robust-predicates: 3.0.2 + + dependency-graph@0.11.0: {} + + dequal@2.0.3: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + didyoumean@1.2.2: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dlv@1.1.3: {} + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-input-range@2.0.1: {} + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + dompurify@3.2.6: + optionalDependencies: + '@types/trusted-types': 2.0.7 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dropzone@6.0.0-beta.2: + dependencies: + '@swc/helpers': 0.2.14 + just-extend: 5.1.1 + + eastasianwidth@0.2.0: {} + + easymde@2.20.0: + dependencies: + '@types/codemirror': 5.60.16 + '@types/marked': 4.3.2 + codemirror: 5.65.20 + codemirror-spell-checker: 1.1.2 + marked: 4.3.0 + + electron-to-chromium@1.5.215: {} + + emoji-regex@10.5.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + emojis-list@3.0.0: {} + + enhanced-resolve@5.18.3: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.3 + + entities@4.5.0: {} + + env-paths@2.2.1: {} + + envinfo@7.14.0: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + es-module-lexer@1.7.0: {} + + esbuild-loader@4.3.0(webpack@5.101.3): + dependencies: + esbuild: 0.25.9 + get-tsconfig: 4.10.1 + loader-utils: 2.0.4 + webpack: 5.101.3(webpack-cli@6.0.1) + webpack-sources: 1.4.3 + + esbuild@0.25.9: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.9 + '@esbuild/android-arm': 0.25.9 + '@esbuild/android-arm64': 0.25.9 + '@esbuild/android-x64': 0.25.9 + '@esbuild/darwin-arm64': 0.25.9 + '@esbuild/darwin-x64': 0.25.9 + '@esbuild/freebsd-arm64': 0.25.9 + '@esbuild/freebsd-x64': 0.25.9 + '@esbuild/linux-arm': 0.25.9 + '@esbuild/linux-arm64': 0.25.9 + '@esbuild/linux-ia32': 0.25.9 + '@esbuild/linux-loong64': 0.25.9 + '@esbuild/linux-mips64el': 0.25.9 + '@esbuild/linux-ppc64': 0.25.9 + '@esbuild/linux-riscv64': 0.25.9 + '@esbuild/linux-s390x': 0.25.9 + '@esbuild/linux-x64': 0.25.9 + '@esbuild/netbsd-arm64': 0.25.9 + '@esbuild/netbsd-x64': 0.25.9 + '@esbuild/openbsd-arm64': 0.25.9 + '@esbuild/openbsd-x64': 0.25.9 + '@esbuild/openharmony-arm64': 0.25.9 + '@esbuild/sunos-x64': 0.25.9 + '@esbuild/win32-arm64': 0.25.9 + '@esbuild/win32-ia32': 0.25.9 + '@esbuild/win32-x64': 0.25.9 + + escalade@3.2.0: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + eslint-compat-utils@0.6.5(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + semver: 7.7.2 + + eslint-config-prettier@10.1.8(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + + eslint-import-context@0.1.9(unrs-resolver@1.11.1): + dependencies: + get-tsconfig: 4.10.1 + stable-hash-x: 0.2.0 + optionalDependencies: + unrs-resolver: 1.11.1 + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: '@nolyfill/is-core-module@1.0.39' + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.43.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0))(eslint-plugin-import@2.32.0)(eslint@8.57.0): + dependencies: + debug: 4.4.1 + eslint: 8.57.0 + eslint-import-context: 0.1.9(unrs-resolver@1.11.1) + get-tsconfig: 4.10.1 + is-bun-module: 2.0.0 + stable-hash-x: 0.2.0 + tinyglobby: 0.2.15 + unrs-resolver: 1.11.1 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.43.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@8.57.0) + eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.43.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.43.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@8.57.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.43.0(eslint@8.57.0)(typescript@5.9.2) + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.43.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0))(eslint-plugin-import@2.32.0)(eslint@8.57.0) + transitivePeerDependencies: + - supports-color + + eslint-plugin-array-func@4.0.0(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + + eslint-plugin-escompat@3.11.4(eslint@8.57.0): + dependencies: + browserslist: 4.25.4 + eslint: 8.57.0 + + eslint-plugin-eslint-comments@3.2.0(eslint@8.57.0): + dependencies: + escape-string-regexp: 1.0.5 + eslint: 8.57.0 + ignore: 5.3.2 + + eslint-plugin-filenames@1.3.2(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + lodash.camelcase: 4.3.0 + lodash.kebabcase: 4.1.1 + lodash.snakecase: 4.1.1 + lodash.upperfirst: 4.3.1 + + eslint-plugin-github@5.0.2(@types/eslint@9.6.1)(eslint-import-resolver-typescript@4.4.4)(eslint@8.57.0)(typescript@5.9.2): + dependencies: + '@github/browserslist-config': 1.0.0 + '@typescript-eslint/eslint-plugin': 8.43.0(@typescript-eslint/parser@8.43.0(eslint@8.57.0)(typescript@5.9.2))(eslint@8.57.0)(typescript@5.9.2) + '@typescript-eslint/parser': 8.43.0(eslint@8.57.0)(typescript@5.9.2) + aria-query: 5.3.2 + eslint: 8.57.0 + eslint-config-prettier: 10.1.8(eslint@8.57.0) + eslint-plugin-escompat: 3.11.4(eslint@8.57.0) + eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.0) + eslint-plugin-filenames: 1.3.2(eslint@8.57.0) + eslint-plugin-i18n-text: 1.0.1(eslint@8.57.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.43.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@8.57.0) + eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.0) + eslint-plugin-no-only-tests: 3.3.0 + eslint-plugin-prettier: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@8.57.0))(eslint@8.57.0)(prettier@3.6.2) + eslint-rule-documentation: 1.0.23 + jsx-ast-utils: 3.3.5 + prettier: 3.6.2 + svg-element-attributes: 1.3.1 + transitivePeerDependencies: + - '@types/eslint' + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + - typescript + + eslint-plugin-i18n-text@1.0.1(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + + eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.43.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): + dependencies: + '@typescript-eslint/types': 8.43.0 + comment-parser: 1.4.1 + debug: 4.4.1 + eslint: 8.57.0 + eslint-import-context: 0.1.9(unrs-resolver@1.11.1) + is-glob: 4.0.3 + minimatch: 10.0.3 + semver: 7.7.2 + stable-hash-x: 0.2.0 + unrs-resolver: 1.11.1 + optionalDependencies: + '@typescript-eslint/utils': 8.43.0(eslint@8.57.0)(typescript@5.9.2) + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.43.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@8.57.0): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: '@nolyfill/array-includes@1.0.44' + array.prototype.findlastindex: '@nolyfill/array.prototype.findlastindex@1.0.44' + array.prototype.flat: '@nolyfill/array.prototype.flat@1.0.44' + array.prototype.flatmap: '@nolyfill/array.prototype.flatmap@1.0.44' + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.43.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@8.57.0) + hasown: '@nolyfill/hasown@1.0.44' + is-core-module: '@nolyfill/is-core-module@1.0.39' + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: '@nolyfill/object.fromentries@1.0.44' + object.groupby: '@nolyfill/object.groupby@1.0.44' + object.values: '@nolyfill/object.values@1.0.44' + semver: 6.3.1 + string.prototype.trimend: '@nolyfill/string.prototype.trimend@1.0.44' + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.43.0(eslint@8.57.0)(typescript@5.9.2) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.0): + dependencies: + aria-query: 5.3.2 + array-includes: '@nolyfill/array-includes@1.0.44' + array.prototype.flatmap: '@nolyfill/array.prototype.flatmap@1.0.44' + ast-types-flow: 0.0.8 + axe-core: 4.10.3 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 8.57.0 + hasown: '@nolyfill/hasown@1.0.44' + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.fromentries: '@nolyfill/object.fromentries@1.0.44' + safe-regex-test: '@nolyfill/safe-regex-test@1.0.44' + string.prototype.includes: '@nolyfill/string.prototype.includes@1.0.44' + + eslint-plugin-no-jquery@3.1.1(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + + eslint-plugin-no-only-tests@3.3.0: {} + + eslint-plugin-no-use-extend-native@0.5.0: + dependencies: + is-get-set-prop: 1.0.0 + is-js-type: 2.0.0 + is-obj-prop: 1.0.0 + is-proto-prop: 2.0.0 + + eslint-plugin-playwright@2.2.2(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + globals: 13.24.0 + + eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@8.57.0))(eslint@8.57.0)(prettier@3.6.2): + dependencies: + eslint: 8.57.0 + prettier: 3.6.2 + prettier-linter-helpers: 1.0.0 + synckit: 0.11.11 + optionalDependencies: + '@types/eslint': 9.6.1 + eslint-config-prettier: 10.1.8(eslint@8.57.0) + + eslint-plugin-regexp@2.10.0(eslint@8.57.0): + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.12.1 + comment-parser: 1.4.1 + eslint: 8.57.0 + jsdoc-type-pratt-parser: 4.8.0 + refa: 0.12.1 + regexp-ast-analysis: 0.7.1 + scslre: 0.3.0 + + eslint-plugin-sonarjs@3.0.5(eslint@8.57.0): + dependencies: + '@eslint-community/regexpp': 4.12.1 + builtin-modules: 3.3.0 + bytes: 3.1.2 + eslint: 8.57.0 + functional-red-black-tree: 1.0.1 + jsx-ast-utils-x: 0.1.0 + lodash.merge: 4.6.2 + minimatch: 9.0.5 + scslre: 0.3.0 + semver: 7.7.2 + typescript: 5.9.2 + + eslint-plugin-unicorn@56.0.1(eslint@8.57.0): + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.0) + ci-info: 4.3.0 + clean-regexp: 1.0.0 + core-js-compat: 3.45.1 + eslint: 8.57.0 + esquery: 1.6.0 + globals: 15.15.0 + indent-string: 4.0.0 + is-builtin-module: 3.2.1 + jsesc: 3.1.0 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.27 + regjsparser: 0.10.0 + semver: 7.7.2 + strip-indent: 3.0.0 + + eslint-plugin-vue-scoped-css@2.12.0(eslint@8.57.0)(vue-eslint-parser@10.2.0(eslint@8.57.0)): + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.0) + eslint: 8.57.0 + eslint-compat-utils: 0.6.5(eslint@8.57.0) + lodash: 4.17.21 + postcss: 8.5.6 + postcss-safe-parser: 6.0.0(postcss@8.5.6) + postcss-scss: 4.0.9(postcss@8.5.6) + postcss-selector-parser: 7.1.0 + postcss-styl: 0.12.3 + vue-eslint-parser: 10.2.0(eslint@8.57.0) + transitivePeerDependencies: + - supports-color + + eslint-plugin-vue@10.4.0(@typescript-eslint/parser@8.43.0(eslint@8.57.0)(typescript@5.9.2))(eslint@8.57.0)(vue-eslint-parser@10.2.0(eslint@8.57.0)): + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.0) + eslint: 8.57.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.1.2 + semver: 7.7.2 + vue-eslint-parser: 10.2.0(eslint@8.57.0) + xml-name-validator: 4.0.0 + optionalDependencies: + '@typescript-eslint/parser': 8.43.0(eslint@8.57.0)(typescript@5.9.2) + + eslint-plugin-wc@3.0.1(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + is-valid-element-name: 1.0.0 + js-levenshtein-esm: 2.0.0 + + eslint-rule-documentation@1.0.23: {} + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint@8.57.0: + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.12.1 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.0 + '@humanwhocodes/config-array': 0.11.14 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.3.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.1 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + + espree@9.6.1: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 3.4.3 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + estree-walker@1.0.1: {} + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + esutils@2.0.3: {} + + event-target-shim@5.0.1: {} + + eventemitter3@2.0.3: {} + + events@3.3.0: {} + + expect-type@1.2.2: {} + + exsolve@1.0.7: {} + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-glob@3.2.12: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-memoize@2.5.2: {} + + fast-uri@3.1.0: {} + + fastest-levenshtein@1.0.16: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + fetch-ponyfill@7.1.0: + dependencies: + node-fetch: 2.6.13 + transitivePeerDependencies: + - encoding + + fflate@0.8.2: {} + + file-entry-cache@10.1.4: + dependencies: + flat-cache: 6.1.13 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@3.2.0: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + rimraf: 3.0.2 + + flat-cache@6.1.13: + dependencies: + cacheable: 1.10.4 + flatted: 3.3.3 + hookified: 1.12.0 + + flat@5.0.2: {} + + flatted@3.3.3: {} + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + + fs.realpath@1.0.0: {} + + fsevents@2.3.2: + optional: true + + fsevents@2.3.3: + optional: true + + functional-red-black-tree@1.0.1: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.4.0: {} + + get-set-props@0.1.0: {} + + get-source@2.0.12: + dependencies: + data-uri-to-buffer: 2.0.2 + source-map: 0.6.1 + + get-tsconfig@4.10.1: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regexp@0.4.1: {} + + glob@10.4.5: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@11.0.3: + dependencies: + foreground-child: 3.3.1 + jackspeak: 4.1.1 + minimatch: 10.0.3 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 2.0.0 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + global-modules@2.0.0: + dependencies: + global-prefix: 3.0.0 + + global-prefix@3.0.0: + dependencies: + ini: 1.3.8 + kind-of: 6.0.3 + which: 1.3.1 + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globals@15.15.0: {} + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + globjoin@0.1.4: {} + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + hachure-fill@0.5.2: {} + + hammerjs@2.0.8: {} + + happy-dom@18.0.1: + dependencies: + '@types/node': 20.19.13 + '@types/whatwg-mimetype': 3.0.2 + whatwg-mimetype: 3.0.0 + + has-flag@4.0.0: {} + + hash-sum@2.0.0: {} + + he@1.2.0: {} + + hookified@1.12.0: {} + + hosted-git-info@2.8.9: {} + + hpagent@1.2.0: {} + + html-tags@3.3.1: {} + + htmlparser2@8.0.2: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 4.5.0 + + htmx.org@2.0.7: {} + + iconv-lite@0.6.3: + dependencies: + safer-buffer: '@nolyfill/safer-buffer@1.0.44' + + icss-utils@5.1.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + idiomorph@0.7.3: {} + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + immer@9.0.21: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-local@3.2.0: + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ini@1.3.8: {} + + ini@4.1.3: {} + + internmap@1.0.1: {} + + internmap@2.0.3: {} + + interpret@3.1.1: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-arrayish@0.2.1: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-buffer@1.1.6: {} + + is-builtin-module@3.2.1: + dependencies: + builtin-modules: 3.3.0 + + is-bun-module@2.0.0: + dependencies: + semver: 7.7.2 + + is-decimal@2.0.1: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-get-set-prop@1.0.0: + dependencies: + get-set-props: 0.1.0 + lowercase-keys: 1.0.1 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hexadecimal@2.0.1: {} + + is-js-type@2.0.0: + dependencies: + js-types: 1.0.0 + + is-number@7.0.0: {} + + is-obj-prop@1.0.0: + dependencies: + lowercase-keys: 1.0.1 + obj-props: 1.4.0 + + is-path-inside@3.0.3: {} + + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 + + is-plain-object@5.0.0: {} + + is-potential-custom-element-name@1.0.1: {} + + is-proto-prop@2.0.0: + dependencies: + lowercase-keys: 1.0.1 + proto-props: 2.0.0 + + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.8 + + is-valid-element-name@1.0.0: + dependencies: + is-potential-custom-element-name: 1.0.1 + + isexe@2.0.0: {} + + isobject@3.0.1: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jackspeak@4.1.1: + dependencies: + '@isaacs/cliui': 8.0.2 + + jest-worker@27.5.1: + dependencies: + '@types/node': 24.3.1 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jiti@1.21.7: {} + + jiti@2.5.1: {} + + jquery@3.7.1: {} + + js-levenshtein-esm@2.0.0: {} + + js-tokens@4.0.0: {} + + js-tokens@9.0.1: {} + + js-types@1.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsdoc-type-pratt-parser@4.8.0: {} + + jsep@1.4.0: {} + + jsesc@0.5.0: {} + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + json5@2.2.3: {} + + jsonc-parser@2.2.1: {} + + jsonc-parser@3.3.1: {} + + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsonpath-plus@10.3.0: + dependencies: + '@jsep-plugin/assignment': 1.3.0(jsep@1.4.0) + '@jsep-plugin/regex': 1.0.4(jsep@1.4.0) + jsep: 1.4.0 + + jsonpointer@5.0.1: {} + + jsx-ast-utils-x@0.1.0: {} + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: '@nolyfill/array-includes@1.0.44' + array.prototype.flat: '@nolyfill/array.prototype.flat@1.0.44' + object.assign: '@nolyfill/object.assign@1.0.44' + object.values: '@nolyfill/object.values@1.0.44' + + just-extend@5.1.1: {} + + katex@0.16.22: + dependencies: + commander: 8.3.0 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + keyv@5.5.0: + dependencies: + '@keyv/serialize': 1.1.0 + + khroma@2.1.0: {} + + kind-of@3.2.2: + dependencies: + is-buffer: 1.1.6 + + kind-of@6.0.3: {} + + known-css-properties@0.37.0: {} + + kolorist@1.8.0: {} + + langium@3.3.1: + dependencies: + chevrotain: 11.0.3 + chevrotain-allstar: 0.3.1(chevrotain@11.0.3) + vscode-languageserver: 9.0.1 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.0.8 + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + layout-base@1.0.2: {} + + layout-base@2.0.1: {} + + leven@3.1.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + + loader-runner@4.3.0: {} + + loader-utils@2.0.4: + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 2.2.3 + + local-pkg@1.1.2: + dependencies: + mlly: 1.8.0 + pkg-types: 2.3.0 + quansync: 0.2.11 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash-es@4.17.21: {} + + lodash.camelcase@4.3.0: {} + + lodash.kebabcase@4.1.1: {} + + lodash.merge@4.6.2: {} + + lodash.snakecase@4.1.1: {} + + lodash.sortedlastindex@4.1.0: {} + + lodash.topath@4.5.2: {} + + lodash.truncate@4.4.2: {} + + lodash.upperfirst@4.3.1: {} + + lodash@4.17.21: {} + + loupe@3.2.1: {} + + lowercase-keys@1.0.1: {} + + lru-cache@10.4.3: {} + + lru-cache@11.2.1: {} + + magic-string@0.25.9: + dependencies: + sourcemap-codec: 1.4.8 + + magic-string@0.30.19: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + markdown-escape@2.0.0: {} + + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + markdownlint-cli@0.45.0: + dependencies: + commander: 13.1.0 + glob: 11.0.3 + ignore: 7.0.5 + js-yaml: 4.1.0 + jsonc-parser: 3.3.1 + jsonpointer: 5.0.1 + markdown-it: 14.1.0 + markdownlint: 0.38.0 + minimatch: 10.0.3 + run-con: 1.3.2 + smol-toml: 1.3.4 + transitivePeerDependencies: + - supports-color + + markdownlint@0.38.0: + dependencies: + micromark: 4.0.2 + micromark-core-commonmark: 2.0.3 + micromark-extension-directive: 4.0.0 + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-math: 3.1.0 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + marked@15.0.12: {} + + marked@4.3.0: {} + + material-icon-theme@5.27.0: + dependencies: + chroma-js: 3.1.2 + events: 3.3.0 + fast-deep-equal: 3.1.3 + svgson: 5.3.1 + + mathml-tag-names@2.1.3: {} + + mdn-data@2.0.28: {} + + mdn-data@2.12.2: {} + + mdurl@2.0.0: {} + + meow@13.2.0: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + mermaid@11.11.0: + dependencies: + '@braintree/sanitize-url': 7.1.1 + '@iconify/utils': 3.0.1 + '@mermaid-js/parser': 0.6.2 + '@types/d3': 7.4.3 + cytoscape: 3.33.1 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.1) + cytoscape-fcose: 2.2.0(cytoscape@3.33.1) + d3: 7.9.0 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.11 + dayjs: 1.11.18 + dompurify: 3.2.6 + katex: 0.16.22 + khroma: 2.1.0 + lodash-es: 4.17.21 + marked: 15.0.12 + roughjs: 4.6.6 + stylis: 4.3.6 + ts-dedent: 2.2.0 + uuid: 11.1.0 + transitivePeerDependencies: + - supports-color + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-directive@4.0.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + parse-entities: 4.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-math@3.1.0: + dependencies: + '@types/katex': 0.16.7 + devlop: 1.1.0 + katex: 0.16.22 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.12 + debug: 4.4.1 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + min-indent@1.0.1: {} + + mini-css-extract-plugin@2.9.4(webpack@5.101.3): + dependencies: + schema-utils: 4.3.2 + tapable: 2.2.3 + webpack: 5.101.3(webpack-cli@6.0.1) + + minimatch@10.0.3: + dependencies: + '@isaacs/brace-expansion': 5.0.0 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.2 + + minimist@1.2.8: {} + + minipass@7.1.2: {} + + mlly@1.8.0: + dependencies: + acorn: 8.15.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.1 + + monaco-editor-webpack-plugin@7.1.0(monaco-editor@0.53.0)(webpack@5.101.3): + dependencies: + loader-utils: 2.0.4 + monaco-editor: 0.53.0 + webpack: 5.101.3(webpack-cli@6.0.1) + + monaco-editor@0.53.0: + dependencies: + '@types/trusted-types': 1.0.6 + + moo@0.5.2: {} + + ms@2.1.3: {} + + muggle-string@0.4.1: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.11: {} + + nanopop@2.3.0: {} + + napi-postinstall@0.3.3: {} + + natural-compare@1.4.0: {} + + neo-async@2.6.2: {} + + nimma@0.2.3: + dependencies: + '@jsep-plugin/regex': 1.0.4(jsep@1.4.0) + '@jsep-plugin/ternary': 1.1.4(jsep@1.4.0) + astring: 1.9.0 + jsep: 1.4.0 + optionalDependencies: + jsonpath-plus: 10.3.0 + lodash.topath: 4.5.2 + + node-fetch@2.6.13: + dependencies: + whatwg-url: 5.0.0 + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-releases@2.0.20: {} + + node-sarif-builder@2.0.3: + dependencies: + '@types/sarif': 2.1.7 + fs-extra: 10.1.0 + + nolyfill@1.0.44: {} + + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.10 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + + normalize-path@3.0.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + obj-props@1.4.0: {} + + object-assign@4.1.1: {} + + object-hash@3.0.0: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + online-3d-viewer@0.16.0: + dependencies: + '@simonwep/pickr': 1.9.0 + fflate: 0.8.2 + three: 0.176.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-try@2.2.0: {} + + package-json-from-dist@1.0.1: {} + + package-manager-detector@1.3.0: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.2.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.27.1 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + path-browserify@1.0.1: {} + + path-data-parser@0.1.0: {} + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + path-scurry@2.0.0: + dependencies: + lru-cache: 11.2.1 + minipass: 7.1.2 + + path-type@4.0.0: {} + + pathe@2.0.3: {} + + pathval@2.0.1: {} + + pdfobject@2.3.1: {} + + perfect-debounce@2.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pify@2.3.0: {} + + pirates@4.0.7: {} + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.0 + pathe: 2.0.3 + + pkg-types@2.3.0: + dependencies: + confbox: 0.2.2 + exsolve: 1.0.7 + pathe: 2.0.3 + + playwright-core@1.55.0: {} + + playwright@1.55.0: + dependencies: + playwright-core: 1.55.0 + optionalDependencies: + fsevents: 2.3.2 + + pluralize@8.0.0: {} + + points-on-curve@0.2.0: {} + + points-on-path@0.2.1: + dependencies: + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + + pony-cause@1.1.1: {} + + postcss-html@1.8.0: + dependencies: + htmlparser2: 8.0.2 + js-tokens: 9.0.1 + postcss: 8.5.6 + postcss-safe-parser: 6.0.0(postcss@8.5.6) + + postcss-import@15.1.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.10 + + postcss-js@4.0.1(postcss@8.5.6): + dependencies: + camelcase-css: 2.0.1 + postcss: 8.5.6 + + postcss-load-config@4.0.2(postcss@8.5.6): + dependencies: + lilconfig: 3.1.3 + yaml: 2.8.1 + optionalDependencies: + postcss: 8.5.6 + + postcss-loader@8.2.0(postcss@8.5.6)(typescript@5.9.2)(webpack@5.101.3): + dependencies: + cosmiconfig: 9.0.0(typescript@5.9.2) + jiti: 2.5.1 + postcss: 8.5.6 + semver: 7.7.2 + optionalDependencies: + webpack: 5.101.3(webpack-cli@6.0.1) + transitivePeerDependencies: + - typescript + + postcss-modules-extract-imports@3.1.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-modules-local-by-default@4.2.0(postcss@8.5.6): + dependencies: + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + postcss-value-parser: 4.2.0 + + postcss-modules-scope@3.2.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + + postcss-modules-values@4.0.0(postcss@8.5.6): + dependencies: + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 + + postcss-nested@6.2.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 + + postcss-nesting@13.0.2(postcss@8.5.6): + dependencies: + '@csstools/selector-resolve-nested': 3.1.0(postcss-selector-parser@7.1.0) + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.0) + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + + postcss-resolve-nested-selector@0.1.6: {} + + postcss-safe-parser@6.0.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-safe-parser@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-scss@4.0.9(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-selector-parser@7.1.0: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-styl@0.12.3: + dependencies: + debug: 4.4.1 + fast-diff: 1.3.0 + lodash.sortedlastindex: 4.1.0 + postcss: 8.5.6 + stylus: 0.57.0 + transitivePeerDependencies: + - supports-color + + postcss-value-parser@4.2.0: {} + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier@3.6.2: {} + + printable-characters@1.0.42: {} + + proto-props@2.0.0: {} + + punycode.js@2.3.1: {} + + punycode@2.3.1: {} + + quansync@0.2.11: {} + + queue-microtask@1.2.3: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: '@nolyfill/safe-buffer@1.0.44' + + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + + read-pkg-up@7.0.1: + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + + read-pkg@5.2.0: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + rechoir@0.8.0: + dependencies: + resolve: 1.22.10 + + refa@0.12.1: + dependencies: + '@eslint-community/regexpp': 4.12.1 + + regexp-ast-analysis@0.7.1: + dependencies: + '@eslint-community/regexpp': 4.12.1 + refa: 0.12.1 + + regexp-tree@0.1.27: {} + + regjsparser@0.10.0: + dependencies: + jsesc: 0.5.0 + + rename-keys@1.2.0: {} + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + reserved@0.1.2: {} + + resolve-cwd@3.0.0: + dependencies: + resolve-from: 5.0.0 + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.10: + dependencies: + is-core-module: '@nolyfill/is-core-module@1.0.39' + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + robust-predicates@3.0.2: {} + + rollup@2.79.2: + optionalDependencies: + fsevents: 2.3.3 + + rollup@4.50.1: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.50.1 + '@rollup/rollup-android-arm64': 4.50.1 + '@rollup/rollup-darwin-arm64': 4.50.1 + '@rollup/rollup-darwin-x64': 4.50.1 + '@rollup/rollup-freebsd-arm64': 4.50.1 + '@rollup/rollup-freebsd-x64': 4.50.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.50.1 + '@rollup/rollup-linux-arm-musleabihf': 4.50.1 + '@rollup/rollup-linux-arm64-gnu': 4.50.1 + '@rollup/rollup-linux-arm64-musl': 4.50.1 + '@rollup/rollup-linux-loongarch64-gnu': 4.50.1 + '@rollup/rollup-linux-ppc64-gnu': 4.50.1 + '@rollup/rollup-linux-riscv64-gnu': 4.50.1 + '@rollup/rollup-linux-riscv64-musl': 4.50.1 + '@rollup/rollup-linux-s390x-gnu': 4.50.1 + '@rollup/rollup-linux-x64-gnu': 4.50.1 + '@rollup/rollup-linux-x64-musl': 4.50.1 + '@rollup/rollup-openharmony-arm64': 4.50.1 + '@rollup/rollup-win32-arm64-msvc': 4.50.1 + '@rollup/rollup-win32-ia32-msvc': 4.50.1 + '@rollup/rollup-win32-x64-msvc': 4.50.1 + fsevents: 2.3.3 + + roughjs@4.6.6: + dependencies: + hachure-fill: 0.5.2 + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + points-on-path: 0.2.1 + + run-con@1.3.2: + dependencies: + deep-extend: 0.6.0 + ini: 4.1.3 + minimist: 1.2.8 + strip-json-comments: 3.1.1 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + rw@1.3.3: {} + + safe-stable-stringify@1.1.1: {} + + sax@1.2.4: {} + + sax@1.4.1: {} + + schema-utils@4.3.2: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) + + scslre@0.3.0: + dependencies: + '@eslint-community/regexpp': 4.12.1 + refa: 0.12.1 + regexp-ast-analysis: 0.7.1 + + semver@5.7.2: {} + + semver@6.3.1: {} + + semver@7.7.2: {} + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + seroval-plugins@1.3.3(seroval@1.3.2): + dependencies: + seroval: 1.3.2 + + seroval@1.3.2: {} + + shallow-clone@3.0.1: + dependencies: + kind-of: 6.0.3 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + simple-eval@1.0.1: + dependencies: + jsep: 1.4.0 + + slash@3.0.0: {} + + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + + smol-toml@1.3.4: {} + + solid-js@1.9.9: + dependencies: + csstype: 3.1.3 + seroval: 1.3.2 + seroval-plugins: 1.3.3(seroval@1.3.2) + + sortablejs@1.15.6: {} + + source-list-map@2.0.1: {} + + source-map-js@1.2.1: {} + + source-map-resolve@0.6.0: + dependencies: + atob: 2.1.2 + decode-uri-component: 0.2.2 + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.7.6: {} + + sourcemap-codec@1.4.8: {} + + spdx-compare@1.0.0: + dependencies: + array-find-index: 1.0.2 + spdx-expression-parse: 3.0.1 + spdx-ranges: 2.1.1 + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.22 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.22 + + spdx-expression-validate@2.0.0: + dependencies: + spdx-expression-parse: 3.0.1 + + spdx-license-ids@3.0.22: {} + + spdx-ranges@2.1.1: {} + + spdx-satisfies@5.0.1: + dependencies: + spdx-compare: 1.0.0 + spdx-expression-parse: 3.0.1 + spdx-ranges: 2.1.1 + + stable-hash-x@0.2.0: {} + + stackback@0.0.2: {} + + stacktracey@2.1.8: + dependencies: + as-table: 1.0.55 + get-source: 2.0.12 + + std-env@3.9.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.2 + + string-width@7.2.0: + dependencies: + emoji-regex: 10.5.0 + get-east-asian-width: 1.4.0 + strip-ansi: 7.1.2 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.2: + dependencies: + ansi-regex: 6.2.2 + + strip-bom@3.0.0: {} + + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + + strip-json-comments@3.1.1: {} + + strip-literal@3.0.0: + dependencies: + js-tokens: 9.0.1 + + style-search@0.1.0: {} + + stylelint-config-recommended@17.0.0(stylelint@16.24.0(typescript@5.9.2)): + dependencies: + stylelint: 16.24.0(typescript@5.9.2) + + stylelint-declaration-block-no-ignored-properties@2.8.0(stylelint@16.24.0(typescript@5.9.2)): + dependencies: + stylelint: 16.24.0(typescript@5.9.2) + + stylelint-declaration-strict-value@1.10.11(stylelint@16.24.0(typescript@5.9.2)): + dependencies: + stylelint: 16.24.0(typescript@5.9.2) + + stylelint-value-no-unknown-custom-properties@6.0.1(stylelint@16.24.0(typescript@5.9.2)): + dependencies: + postcss-value-parser: 4.2.0 + resolve: 1.22.10 + stylelint: 16.24.0(typescript@5.9.2) + + stylelint@16.24.0(typescript@5.9.2): + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.0) + '@dual-bundle/import-meta-resolve': 4.2.1 + balanced-match: 2.0.0 + colord: 2.9.3 + cosmiconfig: 9.0.0(typescript@5.9.2) + css-functions-list: 3.2.3 + css-tree: 3.1.0 + debug: 4.4.1 + fast-glob: 3.3.3 + fastest-levenshtein: 1.0.16 + file-entry-cache: 10.1.4 + global-modules: 2.0.0 + globby: 11.1.0 + globjoin: 0.1.4 + html-tags: 3.3.1 + ignore: 7.0.5 + imurmurhash: 0.1.4 + is-plain-object: 5.0.0 + known-css-properties: 0.37.0 + mathml-tag-names: 2.1.3 + meow: 13.2.0 + micromatch: 4.0.8 + normalize-path: 3.0.0 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-resolve-nested-selector: 0.1.6 + postcss-safe-parser: 7.0.1(postcss@8.5.6) + postcss-selector-parser: 7.1.0 + postcss-value-parser: 4.2.0 + resolve-from: 5.0.0 + string-width: 4.2.3 + supports-hyperlinks: 3.2.0 + svg-tags: 1.0.0 + table: 6.9.0 + write-file-atomic: 5.0.1 + transitivePeerDependencies: + - supports-color + - typescript + + stylis@4.3.6: {} + + stylus@0.57.0: + dependencies: + css: 3.0.0 + debug: 4.4.1 + glob: 7.2.3 + safer-buffer: '@nolyfill/safer-buffer@1.0.44' + sax: 1.2.4 + source-map: 0.7.6 + transitivePeerDependencies: + - supports-color + + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + ts-interface-checker: 0.1.13 + + superstruct@0.10.13: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-hyperlinks@3.2.0: + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + svg-element-attributes@1.3.1: {} + + svg-tags@1.0.0: {} + + svgo@4.0.0: + dependencies: + commander: 11.1.0 + css-select: 5.2.2 + css-tree: 3.1.0 + css-what: 6.2.2 + csso: 5.0.5 + picocolors: 1.1.1 + sax: 1.4.1 + + svgson@5.3.1: + dependencies: + deep-rename-keys: 0.2.1 + xml-reader: 2.4.3 + + swagger-ui-dist@5.29.0: + dependencies: + '@scarf/scarf': 1.4.0 + + sync-fetch@0.4.5: + dependencies: + buffer: 5.7.1 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + synckit@0.11.11: + dependencies: + '@pkgr/core': 0.2.9 + + table@6.9.0: + dependencies: + ajv: 8.17.1 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + tailwindcss@3.4.17: + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.3 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.7 + lilconfig: 3.1.3 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-import: 15.1.0(postcss@8.5.6) + postcss-js: 4.0.1(postcss@8.5.6) + postcss-load-config: 4.0.2(postcss@8.5.6) + postcss-nested: 6.2.0(postcss@8.5.6) + postcss-selector-parser: 6.1.2 + resolve: 1.22.10 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + + tapable@2.2.3: {} + + terser-webpack-plugin@5.3.14(webpack@5.101.3): + dependencies: + '@jridgewell/trace-mapping': 0.3.30 + jest-worker: 27.5.1 + schema-utils: 4.3.2 + serialize-javascript: 6.0.2 + terser: 5.44.0 + webpack: 5.101.3(webpack-cli@6.0.1) + + terser@5.44.0: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.15.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + text-table@0.2.0: {} + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + three@0.176.0: {} + + throttle-debounce@5.0.2: {} + + tinybench@2.9.0: {} + + tinycolor2@1.6.0: {} + + tinyexec@0.3.2: {} + + tinyexec@1.0.1: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tinypool@1.1.1: {} + + tinyrainbow@2.0.0: {} + + tinyspy@4.0.3: {} + + tippy.js@6.3.7: + dependencies: + '@popperjs/core': 2.11.8 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toastify-js@1.12.0: {} + + tr46@0.0.3: {} + + tributejs@5.1.3: {} + + ts-api-utils@2.1.0(typescript@5.9.2): + dependencies: + typescript: 5.9.2 + + ts-dedent@2.2.0: {} + + ts-interface-checker@0.1.13: {} + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@1.14.1: {} + + tslib@2.8.1: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@0.20.2: {} + + type-fest@0.6.0: {} + + type-fest@0.8.1: {} + + type-fest@4.41.0: {} + + typescript@5.9.2: {} + + typo-js@1.3.1: {} + + uc.micro@2.1.0: {} + + ufo@1.6.1: {} + + uint8-to-base64@0.2.1: {} + + undici-types@6.21.0: {} + + undici-types@7.10.0: {} + + universalify@2.0.1: {} + + unrs-resolver@1.11.1: + dependencies: + napi-postinstall: 0.3.3 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.11.1 + '@unrs/resolver-binding-android-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-x64': 1.11.1 + '@unrs/resolver-binding-freebsd-x64': 1.11.1 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 + '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-musl': 1.11.1 + '@unrs/resolver-binding-wasm32-wasi': 1.11.1 + '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 + '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 + '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + + update-browserslist-db@1.1.3(browserslist@4.25.4): + dependencies: + browserslist: 4.25.4 + escalade: 3.2.0 + picocolors: 1.1.1 + + updates@16.7.0: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + urijs@1.19.11: {} + + util-deprecate@1.0.2: {} + + utility-types@3.11.0: {} + + uuid@11.1.0: {} + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + validate-npm-package-name@3.0.0: + dependencies: + builtins: 1.0.3 + + vanilla-colorful@0.7.2: {} + + vite-node@3.2.4(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1): + dependencies: + cac: 6.7.14 + debug: 4.4.1 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vite-string-plugin@1.4.6: {} + + vite@7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1): + dependencies: + esbuild: 0.25.9 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.50.1 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.3.1 + fsevents: 2.3.3 + jiti: 2.5.1 + stylus: 0.57.0 + terser: 5.44.0 + yaml: 2.8.1 + + vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(happy-dom@18.0.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1): + dependencies: + '@types/chai': 5.2.2 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(vite@7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.3.3 + debug: 4.4.1 + expect-type: 1.2.2 + magic-string: 0.30.19 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: 7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1) + vite-node: 3.2.4(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/debug': 4.1.12 + '@types/node': 24.3.1 + happy-dom: 18.0.1 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vscode-jsonrpc@8.2.0: {} + + vscode-languageserver-protocol@3.17.5: + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + + vscode-languageserver-textdocument@1.0.12: {} + + vscode-languageserver-types@3.17.5: {} + + vscode-languageserver@9.0.1: + dependencies: + vscode-languageserver-protocol: 3.17.5 + + vscode-uri@3.0.8: {} + + vscode-uri@3.1.0: {} + + vue-bar-graph@2.2.0(typescript@5.9.2): + dependencies: + vue: 3.5.21(typescript@5.9.2) + transitivePeerDependencies: + - typescript + + vue-chartjs@5.3.2(chart.js@4.5.0)(vue@3.5.21(typescript@5.9.2)): + dependencies: + chart.js: 4.5.0 + vue: 3.5.21(typescript@5.9.2) + + vue-eslint-parser@10.2.0(eslint@8.57.0): + dependencies: + debug: 4.4.1 + eslint: 8.57.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.6.0 + semver: 7.7.2 + transitivePeerDependencies: + - supports-color + + vue-loader@17.4.2(vue@3.5.21(typescript@5.9.2))(webpack@5.101.3): + dependencies: + chalk: 4.1.2 + hash-sum: 2.0.0 + watchpack: 2.4.4 + webpack: 5.101.3(webpack-cli@6.0.1) + optionalDependencies: + vue: 3.5.21(typescript@5.9.2) + + vue-tsc@3.0.6(typescript@5.9.2): + dependencies: + '@volar/typescript': 2.4.23 + '@vue/language-core': 3.0.6(typescript@5.9.2) + typescript: 5.9.2 + + vue@3.5.21(typescript@5.9.2): + dependencies: + '@vue/compiler-dom': 3.5.21 + '@vue/compiler-sfc': 3.5.21 + '@vue/runtime-dom': 3.5.21 + '@vue/server-renderer': 3.5.21(vue@3.5.21(typescript@5.9.2)) + '@vue/shared': 3.5.21 + optionalDependencies: + typescript: 5.9.2 + + watchpack@2.4.4: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + webidl-conversions@3.0.1: {} + + webpack-cli@6.0.1(webpack@5.101.3): + dependencies: + '@discoveryjs/json-ext': 0.6.3 + '@webpack-cli/configtest': 3.0.1(webpack-cli@6.0.1)(webpack@5.101.3) + '@webpack-cli/info': 3.0.1(webpack-cli@6.0.1)(webpack@5.101.3) + '@webpack-cli/serve': 3.0.1(webpack-cli@6.0.1)(webpack@5.101.3) + colorette: 2.0.20 + commander: 12.1.0 + cross-spawn: 7.0.6 + envinfo: 7.14.0 + fastest-levenshtein: 1.0.16 + import-local: 3.2.0 + interpret: 3.1.1 + rechoir: 0.8.0 + webpack: 5.101.3(webpack-cli@6.0.1) + webpack-merge: 6.0.1 + + webpack-merge@6.0.1: + dependencies: + clone-deep: 4.0.1 + flat: 5.0.2 + wildcard: 2.0.1 + + webpack-sources@1.4.3: + dependencies: + source-list-map: 2.0.1 + source-map: 0.6.1 + + webpack-sources@3.3.3: {} + + webpack@5.101.3(webpack-cli@6.0.1): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.15.0 + acorn-import-phases: 1.0.4(acorn@8.15.0) + browserslist: 4.25.4 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.18.3 + es-module-lexer: 1.7.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 4.3.2 + tapable: 2.2.3 + terser-webpack-plugin: 5.3.14(webpack@5.101.3) + watchpack: 2.4.4 + webpack-sources: 3.3.3 + optionalDependencies: + webpack-cli: 6.0.1(webpack@5.101.3) + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + + whatwg-mimetype@3.0.0: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + wildcard@2.0.1: {} + + word-wrap@1.2.5: {} + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.1.2 + + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.1.2 + + wrappy@1.0.2: {} + + write-file-atomic@5.0.1: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 4.1.0 + + xml-lexer@0.2.2: + dependencies: + eventemitter3: 2.0.3 + + xml-name-validator@4.0.0: {} + + xml-reader@2.4.3: + dependencies: + eventemitter3: 2.0.3 + xml-lexer: 0.2.2 + + y18n@5.0.8: {} + + yaml@2.8.1: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yocto-queue@0.1.0: {} diff --git a/public/assets/img/apple-touch-icon.png b/public/assets/img/apple-touch-icon.png index 0c803d35dc..5d7b9deccf 100644 Binary files a/public/assets/img/apple-touch-icon.png and b/public/assets/img/apple-touch-icon.png differ diff --git a/public/assets/img/avatar_default.png b/public/assets/img/avatar_default.png index 129967112d..c1adceff7b 100644 Binary files a/public/assets/img/avatar_default.png and b/public/assets/img/avatar_default.png differ diff --git a/public/assets/img/favicon.png b/public/assets/img/favicon.png index dcd4edb1a3..d0950548f2 100644 Binary files a/public/assets/img/favicon.png and b/public/assets/img/favicon.png differ diff --git a/public/assets/img/logo.png b/public/assets/img/logo.png index c7971f9183..c467f93ddc 100644 Binary files a/public/assets/img/logo.png and b/public/assets/img/logo.png differ diff --git a/public/assets/img/svg/octicon-checkbox-fill.svg b/public/assets/img/svg/octicon-checkbox-fill.svg new file mode 100644 index 0000000000..6e9085f61c --- /dev/null +++ b/public/assets/img/svg/octicon-checkbox-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/img/svg/octicon-maximize.svg b/public/assets/img/svg/octicon-maximize.svg new file mode 100644 index 0000000000..376772d694 --- /dev/null +++ b/public/assets/img/svg/octicon-maximize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/img/svg/octicon-mcp.svg b/public/assets/img/svg/octicon-mcp.svg new file mode 100644 index 0000000000..e68d45bcc0 --- /dev/null +++ b/public/assets/img/svg/octicon-mcp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/img/svg/octicon-minimize.svg b/public/assets/img/svg/octicon-minimize.svg new file mode 100644 index 0000000000..620d93f0ce --- /dev/null +++ b/public/assets/img/svg/octicon-minimize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/img/svg/octicon-repo-deleted.svg b/public/assets/img/svg/octicon-repo-deleted.svg index c79e3be28c..7d8c846987 100644 --- a/public/assets/img/svg/octicon-repo-deleted.svg +++ b/public/assets/img/svg/octicon-repo-deleted.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/assets/img/svg/octicon-repo-locked.svg b/public/assets/img/svg/octicon-repo-locked.svg index c6def5b514..5f2ba7f3b7 100644 --- a/public/assets/img/svg/octicon-repo-locked.svg +++ b/public/assets/img/svg/octicon-repo-locked.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/assets/img/svg/octicon-repo-push.svg b/public/assets/img/svg/octicon-repo-push.svg index 07bd7626e2..eec5b10235 100644 --- a/public/assets/img/svg/octicon-repo-push.svg +++ b/public/assets/img/svg/octicon-repo-push.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/routers/api/packages/swift/swift.go b/routers/api/packages/swift/swift.go index e1c3b36834..d84f79a0a8 100644 --- a/routers/api/packages/swift/swift.go +++ b/routers/api/packages/swift/swift.go @@ -227,6 +227,7 @@ func PackageVersionMetadata(ctx *context.Context) { }, Author: swift_module.Person{ Type: "Person", + Name: metadata.Author.String(), GivenName: metadata.Author.GivenName, MiddleName: metadata.Author.MiddleName, FamilyName: metadata.Author.FamilyName, diff --git a/routers/api/v1/activitypub/person.go b/routers/api/v1/activitypub/person.go index 0b0db011c6..f2ba2baf7f 100644 --- a/routers/api/v1/activitypub/person.go +++ b/routers/api/v1/activitypub/person.go @@ -52,7 +52,7 @@ func Person(ctx *context.APIContext) { return } - person.URL = ap.IRI(ctx.ContextUser.HTMLURL()) + person.URL = ap.IRI(ctx.ContextUser.HTMLURL(ctx)) person.Icon = ap.Image{ Type: ap.ImageType, diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index c046592524..d232a040f8 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -72,13 +72,13 @@ import ( actions_model "code.gitea.io/gitea/models/actions" auth_model "code.gitea.io/gitea/models/auth" - "code.gitea.io/gitea/models/db" "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/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" @@ -780,7 +780,7 @@ func buildAuthGroup() *auth.Group { group.Add(&auth.ReverseProxy{}) } - if setting.IsWindows && auth_model.IsSSPIEnabled(db.DefaultContext) { + if setting.IsWindows && auth_model.IsSSPIEnabled(graceful.GetManager().ShutdownContext()) { group.Add(&auth.SSPI{}) // it MUST be the last, see the comment of SSPI } @@ -1261,7 +1261,7 @@ func Routes() *web.Router { m.Get("/*", repo.GetBranch) m.Delete("/*", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, repo.DeleteBranch) m.Post("", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, bind(api.CreateBranchRepoOption{}), repo.CreateBranch) - m.Patch("/*", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, bind(api.UpdateBranchRepoOption{}), repo.UpdateBranch) + m.Patch("/*", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, bind(api.RenameBranchRepoOption{}), repo.RenameBranch) }, context.ReferencesGitRepo(), reqRepoReader(unit.TypeCode)) m.Group("/branch_protections", func() { m.Get("", repo.ListBranchProtections) diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index 9af958a5b7..65fac45aa1 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -380,11 +380,11 @@ func ListBranches(ctx *context.APIContext) { ctx.JSON(http.StatusOK, apiBranches) } -// UpdateBranch updates a repository's branch. -func UpdateBranch(ctx *context.APIContext) { - // swagger:operation PATCH /repos/{owner}/{repo}/branches/{branch} repository repoUpdateBranch +// RenameBranch renames a repository's branch. +func RenameBranch(ctx *context.APIContext) { + // swagger:operation PATCH /repos/{owner}/{repo}/branches/{branch} repository repoRenameBranch // --- - // summary: Update a branch + // summary: Rename a branch // consumes: // - application/json // produces: @@ -408,7 +408,7 @@ func UpdateBranch(ctx *context.APIContext) { // - name: body // in: body // schema: - // "$ref": "#/definitions/UpdateBranchRepoOption" + // "$ref": "#/definitions/RenameBranchRepoOption" // responses: // "204": // "$ref": "#/responses/empty" @@ -419,7 +419,7 @@ func UpdateBranch(ctx *context.APIContext) { // "422": // "$ref": "#/responses/validationError" - opt := web.GetForm(ctx).(*api.UpdateBranchRepoOption) + opt := web.GetForm(ctx).(*api.RenameBranchRepoOption) oldName := ctx.PathParam("*") repo := ctx.Repo.Repository diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index cc342a9313..4db1e878b1 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -721,8 +721,8 @@ func deleteIssueComment(ctx *context.APIContext) { if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) { ctx.Status(http.StatusForbidden) return - } else if comment.Type != issues_model.CommentTypeComment { - ctx.Status(http.StatusNoContent) + } else if !comment.Type.HasContentSupport() { + ctx.Status(http.StatusBadRequest) return } diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 09729200d5..ff6ddbce2d 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -1085,7 +1085,7 @@ func MergePullRequest(ctx *context.APIContext) { type parseCompareInfoResult struct { headRepo *repo_model.Repository headGitRepo *git.Repository - compareInfo *git.CompareInfo + compareInfo *pull_service.CompareInfo baseRef git.RefName headRef git.RefName } @@ -1201,7 +1201,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) return nil, nil } - compareInfo, err := headGitRepo.GetCompareInfo(repo_model.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseRef.ShortName(), headRef.ShortName(), false, false) + compareInfo, err := pull_service.GetCompareInfo(ctx, baseRepo, headRepo, headGitRepo, baseRef.ShortName(), headRef.ShortName(), false, false) if err != nil { ctx.APIErrorInternal(err) return nil, nil @@ -1452,7 +1452,7 @@ func GetPullRequestCommits(ctx *context.APIContext) { return } - var prInfo *git.CompareInfo + var prInfo *pull_service.CompareInfo baseGitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, pr.BaseRepo) if err != nil { ctx.APIErrorInternal(err) @@ -1461,9 +1461,9 @@ func GetPullRequestCommits(ctx *context.APIContext) { defer closer.Close() if pr.HasMerged { - prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.MergeBase, pr.GetGitHeadRefName(), false, false) + prInfo, err = pull_service.GetCompareInfo(ctx, pr.BaseRepo, pr.BaseRepo, baseGitRepo, pr.MergeBase, pr.GetGitHeadRefName(), false, false) } else { - prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitHeadRefName(), false, false) + prInfo, err = pull_service.GetCompareInfo(ctx, pr.BaseRepo, pr.BaseRepo, baseGitRepo, pr.BaseBranch, pr.GetGitHeadRefName(), false, false) } if err != nil { ctx.APIErrorInternal(err) @@ -1582,11 +1582,11 @@ func GetPullRequestFiles(ctx *context.APIContext) { baseGitRepo := ctx.Repo.GitRepo - var prInfo *git.CompareInfo + var prInfo *pull_service.CompareInfo if pr.HasMerged { - prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.MergeBase, pr.GetGitHeadRefName(), true, false) + prInfo, err = pull_service.GetCompareInfo(ctx, pr.BaseRepo, pr.BaseRepo, baseGitRepo, pr.MergeBase, pr.GetGitHeadRefName(), true, false) } else { - prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitHeadRefName(), true, false) + prInfo, err = pull_service.GetCompareInfo(ctx, pr.BaseRepo, pr.BaseRepo, baseGitRepo, pr.BaseBranch, pr.GetGitHeadRefName(), true, false) } if err != nil { ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 7b3858ccb1..2f5a969b6b 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -736,14 +736,14 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err // Default branch only updated if changed and exist or the repository is empty updateRepoLicense := false if opts.DefaultBranch != nil && repo.DefaultBranch != *opts.DefaultBranch && (repo.IsEmpty || gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, *opts.DefaultBranch)) { + repo.DefaultBranch = *opts.DefaultBranch if !repo.IsEmpty { - if err := gitrepo.SetDefaultBranch(ctx, ctx.Repo.Repository, *opts.DefaultBranch); err != nil { + if err := gitrepo.SetDefaultBranch(ctx, repo, repo.DefaultBranch); err != nil { ctx.APIErrorInternal(err) return err } updateRepoLicense = true } - repo.DefaultBranch = *opts.DefaultBranch } if err := repo_service.UpdateRepository(ctx, repo, visibilityChanged); err != nil { @@ -869,6 +869,18 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { } } + if opts.HasCode != nil && !unit_model.TypeCode.UnitGlobalDisabled() { + if *opts.HasCode { + units = append(units, repo_model.RepoUnit{ + RepoID: repo.ID, + Type: unit_model.TypeCode, + Config: &repo_model.UnitConfig{}, + }) + } else { + deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeCode) + } + } + if opts.HasPullRequests != nil && !unit_model.TypePullRequests.UnitGlobalDisabled() { if *opts.HasPullRequests { // We do allow setting individual PR settings through the API, so diff --git a/routers/api/v1/repo/status.go b/routers/api/v1/repo/status.go index 40007ea1e5..d632d5b5e1 100644 --- a/routers/api/v1/repo/status.go +++ b/routers/api/v1/repo/status.go @@ -271,11 +271,7 @@ func GetCombinedCommitStatusByRef(ctx *context.APIContext) { } ctx.SetTotalCountHeader(count) - if len(statuses) == 0 { - ctx.JSON(http.StatusOK, &api.CombinedStatus{}) - return - } - - combiStatus := convert.ToCombinedStatus(ctx, statuses, convert.ToRepo(ctx, repo, ctx.Repo.Permission)) + combiStatus := convert.ToCombinedStatus(ctx, refCommit.Commit.ID.String(), statuses, + convert.ToRepo(ctx, repo, ctx.Repo.Permission)) ctx.JSON(http.StatusOK, combiStatus) } diff --git a/routers/api/v1/swagger/options.go b/routers/api/v1/swagger/options.go index bafd5e04a2..4aba74b939 100644 --- a/routers/api/v1/swagger/options.go +++ b/routers/api/v1/swagger/options.go @@ -90,7 +90,7 @@ type swaggerParameterBodies struct { // in:body EditRepoOption api.EditRepoOption // in:body - UpdateBranchRepoOption api.UpdateBranchRepoOption + RenameBranchRepoOption api.RenameBranchRepoOption // in:body TransferRepoOption api.TransferRepoOption // in:body diff --git a/routers/common/compare.go b/routers/common/compare.go index 4d1cc2f0d8..fda31a07ba 100644 --- a/routers/common/compare.go +++ b/routers/common/compare.go @@ -7,6 +7,7 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" + pull_service "code.gitea.io/gitea/services/pull" ) // CompareInfo represents the collected results from ParseCompareInfo @@ -14,7 +15,7 @@ type CompareInfo struct { HeadUser *user_model.User HeadRepo *repo_model.Repository HeadGitRepo *git.Repository - CompareInfo *git.CompareInfo + CompareInfo *pull_service.CompareInfo BaseBranch string HeadBranch string DirectComparison bool diff --git a/routers/init.go b/routers/init.go index 744feee2f0..2281260a6f 100644 --- a/routers/init.go +++ b/routers/init.go @@ -111,9 +111,9 @@ func InitWebInstallPage(ctx context.Context) { mustInit(svg.Init) } -// InitWebInstalled is for global installed configuration. +// InitWebInstalled is for the global configuration of an installed instance func InitWebInstalled(ctx context.Context) { - mustInitCtx(ctx, git.InitFull) + mustInit(git.InitFull) log.Info("Git version: %s (home: %s)", git.DefaultFeatures().VersionInfo(), git.HomeDir()) if !git.DefaultFeatures().SupportHashSha256 { log.Warn("sha256 hash support is disabled - requires Git >= 2.42." + util.Iif(git.DefaultFeatures().UsingGogit, " Gogit is currently unsupported.", "")) diff --git a/routers/install/install.go b/routers/install/install.go index dc8f209f3b..4a9dabac6f 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -180,20 +180,20 @@ func checkDatabase(ctx *context.Context, form *forms.InstallForm) bool { return false } - err = db_install.CheckDatabaseConnection() + err = db_install.CheckDatabaseConnection(ctx) if err != nil { ctx.Data["Err_DbSetting"] = true ctx.RenderWithErr(ctx.Tr("install.invalid_db_setting", err), tplInstall, form) return false } - hasPostInstallationUser, err := db_install.HasPostInstallationUsers() + hasPostInstallationUser, err := db_install.HasPostInstallationUsers(ctx) if err != nil { ctx.Data["Err_DbSetting"] = true ctx.RenderWithErr(ctx.Tr("install.invalid_db_table", "user", err), tplInstall, form) return false } - dbMigrationVersion, err := db_install.GetMigrationVersion() + dbMigrationVersion, err := db_install.GetMigrationVersion(ctx) if err != nil { ctx.Data["Err_DbSetting"] = true ctx.RenderWithErr(ctx.Tr("install.invalid_db_table", "version", err), tplInstall, form) diff --git a/routers/private/hook_post_receive_test.go b/routers/private/hook_post_receive_test.go index ca721b16d1..23b8085e94 100644 --- a/routers/private/hook_post_receive_test.go +++ b/routers/private/hook_post_receive_test.go @@ -6,7 +6,6 @@ package private import ( "testing" - "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" pull_model "code.gitea.io/gitea/models/pull" repo_model "code.gitea.io/gitea/models/repo" @@ -21,13 +20,13 @@ import ( func TestHandlePullRequestMerging(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr, err := issues_model.GetUnmergedPullRequest(db.DefaultContext, 1, 1, "branch2", "master", issues_model.PullRequestFlowGithub) + pr, err := issues_model.GetUnmergedPullRequest(t.Context(), 1, 1, "branch2", "master", issues_model.PullRequestFlowGithub) assert.NoError(t, err) - assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext)) + assert.NoError(t, pr.LoadBaseRepo(t.Context())) user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - err = pull_model.ScheduleAutoMerge(db.DefaultContext, user1, pr.ID, repo_model.MergeStyleSquash, "squash merge a pr", false) + err = pull_model.ScheduleAutoMerge(t.Context(), user1, pr.ID, repo_model.MergeStyleSquash, "squash merge a pr", false) assert.NoError(t, err) autoMerge := unittest.AssertExistsAndLoadBean(t, &pull_model.AutoMerge{PullID: pr.ID}) @@ -40,7 +39,7 @@ func TestHandlePullRequestMerging(t *testing.T) { {NewCommitID: "01234567"}, }) assert.Empty(t, resp.Body.String()) - pr, err = issues_model.GetPullRequestByID(db.DefaultContext, pr.ID) + pr, err = issues_model.GetPullRequestByID(t.Context(), pr.ID) assert.NoError(t, err) assert.True(t, pr.HasMerged) assert.Equal(t, "01234567", pr.MergedCommitID) diff --git a/routers/private/serv.go b/routers/private/serv.go index b879be0dc2..3dfe4d21da 100644 --- a/routers/private/serv.go +++ b/routers/private/serv.go @@ -108,6 +108,18 @@ func ServCommand(ctx *context.PrivateContext) { results.RepoName = repoName[:len(repoName)-5] } + // Check if there is a user redirect for the requested owner + redirectedUserID, err := user_model.LookupUserRedirect(ctx, results.OwnerName) + if err == nil { + owner, err := user_model.GetUserByID(ctx, redirectedUserID) + if err == nil { + log.Info("User %s has been redirected to %s", results.OwnerName, owner.Name) + results.OwnerName = owner.Name + } else { + log.Warn("User %s has a redirect to user with ID %d, but no user with this ID could be found. Trying without redirect...", results.OwnerName, redirectedUserID) + } + } + owner, err := user_model.GetUserByName(ctx, results.OwnerName) if err != nil { if user_model.IsErrUserNotExist(err) { @@ -131,6 +143,19 @@ func ServCommand(ctx *context.PrivateContext) { return } + redirectedRepoID, err := repo_model.LookupRedirect(ctx, owner.ID, results.RepoName) + if err == nil { + redirectedRepo, err := repo_model.GetRepositoryByID(ctx, redirectedRepoID) + if err == nil { + log.Info("Repository %s/%s has been redirected to %s/%s", results.OwnerName, results.RepoName, redirectedRepo.OwnerName, redirectedRepo.Name) + results.RepoName = redirectedRepo.Name + results.OwnerName = redirectedRepo.OwnerName + owner.ID = redirectedRepo.OwnerID + } else { + log.Warn("Repo %s/%s has a redirect to repo with ID %d, but no repo with this ID could be found. Trying without redirect...", results.OwnerName, results.RepoName, redirectedRepoID) + } + } + // Now get the Repository and set the results section repoExist := true repo, err := repo_model.GetRepositoryByName(ctx, owner.ID, results.RepoName) diff --git a/routers/web/admin/auths.go b/routers/web/admin/auths.go index 56c384b970..fb1a7d9524 100644 --- a/routers/web/admin/auths.go +++ b/routers/web/admin/auths.go @@ -97,7 +97,7 @@ func NewAuthSource(ctx *context.Context) { ctx.Data["AuthSources"] = authSources ctx.Data["SecurityProtocols"] = securityProtocols ctx.Data["SMTPAuths"] = smtp.Authenticators - oauth2providers := oauth2.GetSupportedOAuth2Providers() + oauth2providers := oauth2.GetSupportedOAuth2Providers(ctx) ctx.Data["OAuth2Providers"] = oauth2providers ctx.Data["SSPIAutoCreateUsers"] = true @@ -107,7 +107,9 @@ func NewAuthSource(ctx *context.Context) { ctx.Data["SSPIDefaultLanguage"] = "" // only the first as default - ctx.Data["oauth2_provider"] = oauth2providers[0].Name() + if len(oauth2providers) > 0 { + ctx.Data["oauth2_provider"] = oauth2providers[0].Name() + } ctx.HTML(http.StatusOK, tplAuthNew) } @@ -240,7 +242,7 @@ func NewAuthSourcePost(ctx *context.Context) { ctx.Data["AuthSources"] = authSources ctx.Data["SecurityProtocols"] = securityProtocols ctx.Data["SMTPAuths"] = smtp.Authenticators - oauth2providers := oauth2.GetSupportedOAuth2Providers() + oauth2providers := oauth2.GetSupportedOAuth2Providers(ctx) ctx.Data["OAuth2Providers"] = oauth2providers ctx.Data["SSPIAutoCreateUsers"] = true @@ -332,7 +334,7 @@ func EditAuthSource(ctx *context.Context) { ctx.Data["SecurityProtocols"] = securityProtocols ctx.Data["SMTPAuths"] = smtp.Authenticators - oauth2providers := oauth2.GetSupportedOAuth2Providers() + oauth2providers := oauth2.GetSupportedOAuth2Providers(ctx) ctx.Data["OAuth2Providers"] = oauth2providers source, err := auth.GetSourceByID(ctx, ctx.PathParamInt64("authid")) @@ -366,7 +368,7 @@ func EditAuthSourcePost(ctx *context.Context) { ctx.Data["PageIsAdminAuthentications"] = true ctx.Data["SMTPAuths"] = smtp.Authenticators - oauth2providers := oauth2.GetSupportedOAuth2Providers() + oauth2providers := oauth2.GetSupportedOAuth2Providers(ctx) ctx.Data["OAuth2Providers"] = oauth2providers source, err := auth.GetSourceByID(ctx, ctx.PathParamInt64("authid")) diff --git a/routers/web/admin/config.go b/routers/web/admin/config.go index 0e5b23db6d..774b31ab98 100644 --- a/routers/web/admin/config.go +++ b/routers/web/admin/config.go @@ -27,7 +27,7 @@ import ( const ( tplConfig templates.TplName = "admin/config" - tplConfigSettings templates.TplName = "admin/config_settings" + tplConfigSettings templates.TplName = "admin/config_settings/config_settings" ) // SendTestMail send test mail to confirm mail service is OK @@ -196,17 +196,21 @@ func ConfigSettings(ctx *context.Context) { } func ChangeConfig(ctx *context.Context) { - key := strings.TrimSpace(ctx.FormString("key")) - value := ctx.FormString("value") cfg := setting.Config() - marshalBool := func(v string) (string, error) { //nolint:unparam // error is always nil - if b, _ := strconv.ParseBool(v); b { - return "true", nil - } - return "false", nil + marshalBool := func(v string) ([]byte, error) { + b, _ := strconv.ParseBool(v) + return json.Marshal(b) } - marshalOpenWithApps := func(value string) (string, error) { + + marshalString := func(emptyDefault string) func(v string) ([]byte, error) { + return func(v string) ([]byte, error) { + return json.Marshal(util.IfZero(v, emptyDefault)) + } + } + + marshalOpenWithApps := func(value string) ([]byte, error) { + // TODO: move the block alongside OpenWithEditorAppsType.ToTextareaString lines := strings.Split(value, "\n") var openWithEditorApps setting.OpenWithEditorAppsType for _, line := range lines { @@ -224,32 +228,47 @@ func ChangeConfig(ctx *context.Context) { OpenURL: strings.TrimSpace(openURL), }) } - b, err := json.Marshal(openWithEditorApps) - if err != nil { - return "", err - } - return string(b), nil + return json.Marshal(openWithEditorApps) } - marshallers := map[string]func(string) (string, error){ + marshallers := map[string]func(string) ([]byte, error){ cfg.Picture.DisableGravatar.DynKey(): marshalBool, cfg.Picture.EnableFederatedAvatar.DynKey(): marshalBool, cfg.Repository.OpenWithEditorApps.DynKey(): marshalOpenWithApps, - } - marshaller, hasMarshaller := marshallers[key] - if !hasMarshaller { - ctx.JSONError(ctx.Tr("admin.config.set_setting_failed", key)) - return - } - marshaledValue, err := marshaller(value) - if err != nil { - ctx.JSONError(ctx.Tr("admin.config.set_setting_failed", key)) - return - } - if err = system_model.SetSettings(ctx, map[string]string{key: marshaledValue}); err != nil { - ctx.JSONError(ctx.Tr("admin.config.set_setting_failed", key)) - return + cfg.Repository.GitGuideRemoteName.DynKey(): marshalString(cfg.Repository.GitGuideRemoteName.DefaultValue()), } + _ = ctx.Req.ParseForm() + configKeys := ctx.Req.Form["key"] + configValues := ctx.Req.Form["value"] + configSettings := map[string]string{} +loop: + for i, key := range configKeys { + if i >= len(configValues) { + ctx.JSONError(ctx.Tr("admin.config.set_setting_failed", key)) + break loop + } + value := configValues[i] + + marshaller, hasMarshaller := marshallers[key] + if !hasMarshaller { + ctx.JSONError(ctx.Tr("admin.config.set_setting_failed", key)) + break loop + } + + marshaledValue, err := marshaller(value) + if err != nil { + ctx.JSONError(ctx.Tr("admin.config.set_setting_failed", key)) + break loop + } + configSettings[key] = string(marshaledValue) + } + if ctx.Written() { + return + } + if err := system_model.SetSettings(ctx, configSettings); err != nil { + ctx.ServerError("SetSettings", err) + return + } config.GetDynGetter().InvalidateCache() ctx.JSONOK() } diff --git a/routers/web/auth/auth_test.go b/routers/web/auth/auth_test.go index a0fd5c0e50..5ccffe0d50 100644 --- a/routers/web/auth/auth_test.go +++ b/routers/web/auth/auth_test.go @@ -9,7 +9,6 @@ import ( "testing" auth_model "code.gitea.io/gitea/models/auth" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/session" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/test" @@ -24,7 +23,7 @@ import ( func addOAuth2Source(t *testing.T, authName string, cfg oauth2.Source) { cfg.Provider = util.IfZero(cfg.Provider, "gitea") - err := auth_model.CreateSource(db.DefaultContext, &auth_model.Source{ + err := auth_model.CreateSource(t.Context(), &auth_model.Source{ Type: auth_model.OAuth2, Name: authName, IsActive: true, diff --git a/routers/web/auth/oauth_test.go b/routers/web/auth/oauth_test.go index 8d9365fab4..36b0cf6eac 100644 --- a/routers/web/auth/oauth_test.go +++ b/routers/web/auth/oauth_test.go @@ -7,7 +7,6 @@ import ( "testing" "code.gitea.io/gitea/models/auth" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/services/oauth2_provider" @@ -21,7 +20,7 @@ func createAndParseToken(t *testing.T, grant *auth.OAuth2Grant) *oauth2_provider assert.NoError(t, err) assert.NotNil(t, signingKey) - response, terr := oauth2_provider.NewAccessTokenResponse(db.DefaultContext, grant, signingKey, signingKey) + response, terr := oauth2_provider.NewAccessTokenResponse(t.Context(), grant, signingKey, signingKey) assert.Nil(t, terr) assert.NotNil(t, response) @@ -43,7 +42,7 @@ func createAndParseToken(t *testing.T, grant *auth.OAuth2Grant) *oauth2_provider func TestNewAccessTokenResponse_OIDCToken(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - grants, err := auth.GetOAuth2GrantsByUserID(db.DefaultContext, 3) + grants, err := auth.GetOAuth2GrantsByUserID(t.Context(), 3) assert.NoError(t, err) assert.Len(t, grants, 1) @@ -59,7 +58,7 @@ func TestNewAccessTokenResponse_OIDCToken(t *testing.T) { assert.False(t, oidcToken.EmailVerified) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) - grants, err = auth.GetOAuth2GrantsByUserID(db.DefaultContext, user.ID) + grants, err = auth.GetOAuth2GrantsByUserID(t.Context(), user.ID) assert.NoError(t, err) assert.Len(t, grants, 1) @@ -67,8 +66,8 @@ func TestNewAccessTokenResponse_OIDCToken(t *testing.T) { oidcToken = createAndParseToken(t, grants[0]) assert.Equal(t, user.DisplayName(), oidcToken.Name) assert.Equal(t, user.Name, oidcToken.PreferredUsername) - assert.Equal(t, user.HTMLURL(), oidcToken.Profile) - assert.Equal(t, user.AvatarLink(db.DefaultContext), oidcToken.Picture) + assert.Equal(t, user.HTMLURL(t.Context()), oidcToken.Profile) + assert.Equal(t, user.AvatarLink(t.Context()), oidcToken.Picture) assert.Equal(t, user.Website, oidcToken.Website) assert.Equal(t, user.UpdatedUnix, oidcToken.UpdatedAt) assert.Equal(t, user.Email, oidcToken.Email) diff --git a/routers/web/explore/user.go b/routers/web/explore/user.go index af48e6fb79..3774be033d 100644 --- a/routers/web/explore/user.go +++ b/routers/web/explore/user.go @@ -103,7 +103,7 @@ func RenderUserSearch(ctx *context.Context, opts user_model.SearchUserOptions, t if isSitemap { m := sitemap.NewSitemap() for _, item := range users { - m.Add(sitemap.URL{URL: item.HTMLURL(), LastMod: item.UpdatedUnix.AsTimePtr()}) + m.Add(sitemap.URL{URL: item.HTMLURL(ctx), LastMod: item.UpdatedUnix.AsTimePtr()}) } ctx.Resp.Header().Set("Content-Type", "text/xml") if _, err := m.WriteTo(ctx.Resp); err != nil { diff --git a/routers/web/feed/profile.go b/routers/web/feed/profile.go index cecf9d409a..3ca4890e35 100644 --- a/routers/web/feed/profile.go +++ b/routers/web/feed/profile.go @@ -54,7 +54,7 @@ func showUserFeed(ctx *context.Context, formatType string) { return } - rctx := renderhelper.NewRenderContextSimpleDocument(ctx, ctx.ContextUser.HTMLURL()) + rctx := renderhelper.NewRenderContextSimpleDocument(ctx, ctx.ContextUser.HTMLURL(ctx)) ctxUserDescription, err := markdown.RenderString(rctx, ctx.ContextUser.Description) if err != nil { @@ -64,7 +64,7 @@ func showUserFeed(ctx *context.Context, formatType string) { feed := &feeds.Feed{ Title: ctx.Locale.TrString("home.feed_of", ctx.ContextUser.DisplayName()), - Link: &feeds.Link{Href: ctx.ContextUser.HTMLURL()}, + Link: &feeds.Link{Href: ctx.ContextUser.HTMLURL(ctx)}, Description: string(ctxUserDescription), Created: time.Now(), } diff --git a/routers/web/feed/render.go b/routers/web/feed/render.go index d1a229e5b2..014da253bd 100644 --- a/routers/web/feed/render.go +++ b/routers/web/feed/render.go @@ -8,11 +8,18 @@ import ( ) // RenderBranchFeed render format for branch or file -func RenderBranchFeed(ctx *context.Context) { - _, showFeedType := GetFeedType(ctx.PathParam("reponame"), ctx.Req) +func RenderBranchFeed(ctx *context.Context, feedType string) { if ctx.Repo.TreePath == "" { - ShowBranchFeed(ctx, ctx.Repo.Repository, showFeedType) + ShowBranchFeed(ctx, ctx.Repo.Repository, feedType) } else { - ShowFileFeed(ctx, ctx.Repo.Repository, showFeedType) + ShowFileFeed(ctx, ctx.Repo.Repository, feedType) } } + +func RenderBranchFeedRSS(ctx *context.Context) { + RenderBranchFeed(ctx, "rss") +} + +func RenderBranchFeedAtom(ctx *context.Context) { + RenderBranchFeed(ctx, "atom") +} diff --git a/routers/web/org/setting.go b/routers/web/org/setting.go index 2bc1e8bc43..fe585b3a00 100644 --- a/routers/web/org/setting.go +++ b/routers/web/org/setting.go @@ -17,6 +17,7 @@ import ( "code.gitea.io/gitea/modules/optional" 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/templates" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" @@ -25,7 +26,6 @@ import ( "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/forms" org_service "code.gitea.io/gitea/services/org" - repo_service "code.gitea.io/gitea/services/repository" user_service "code.gitea.io/gitea/services/user" ) @@ -83,38 +83,17 @@ func SettingsPost(ctx *context.Context) { Description: optional.Some(form.Description), Website: optional.Some(form.Website), Location: optional.Some(form.Location), - Visibility: optional.Some(form.Visibility), RepoAdminChangeTeamAccess: optional.Some(form.RepoAdminChangeTeamAccess), } if ctx.Doer.IsAdmin { opts.MaxRepoCreation = optional.Some(form.MaxRepoCreation) } - visibilityChanged := org.Visibility != form.Visibility - if err := user_service.UpdateUser(ctx, org.AsUser(), opts); err != nil { ctx.ServerError("UpdateUser", err) return } - // update forks visibility - if visibilityChanged { - repos, _, err := repo_model.GetUserRepositories(ctx, repo_model.SearchRepoOptions{ - Actor: org.AsUser(), Private: true, ListOptions: db.ListOptions{Page: 1, PageSize: org.NumRepos}, - }) - if err != nil { - ctx.ServerError("GetRepositories", err) - return - } - for _, repo := range repos { - repo.OwnerName = org.Name - if err := repo_service.UpdateRepository(ctx, repo, true); err != nil { - ctx.ServerError("UpdateRepository", err) - return - } - } - } - log.Trace("Organization setting updated: %s", org.Name) ctx.Flash.Success(ctx.Tr("org.settings.update_setting_success")) ctx.Redirect(ctx.Org.OrgLink + "/settings") @@ -251,3 +230,28 @@ func SettingsRenamePost(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("org.settings.rename_success", oldOrgName, newOrgName)) ctx.JSONRedirect(setting.AppSubURL + "/org/" + url.PathEscape(newOrgName) + "/settings") } + +// SettingsChangeVisibilityPost response for change organization visibility +func SettingsChangeVisibilityPost(ctx *context.Context) { + visibility, ok := structs.VisibilityModes[ctx.FormString("visibility")] + if !ok { + ctx.Flash.Error(ctx.Tr("invalid_data", visibility)) + ctx.JSONRedirect(setting.AppSubURL + "/org/" + url.PathEscape(ctx.Org.Organization.Name) + "/settings") + return + } + + if ctx.Org.Organization.Visibility == visibility { + ctx.Flash.Info(ctx.Tr("nothing_has_been_changed")) + ctx.JSONRedirect(setting.AppSubURL + "/org/" + url.PathEscape(ctx.Org.Organization.Name) + "/settings") + return + } + + if err := org_service.ChangeOrganizationVisibility(ctx, ctx.Org.Organization, visibility); err != nil { + log.Error("ChangeOrganizationVisibility: %v", err) + ctx.JSONError(ctx.Tr("error.occurred")) + return + } + + ctx.Flash.Success(ctx.Tr("org.settings.change_visibility_success", ctx.Org.Organization.Name)) + ctx.JSONRedirect(setting.AppSubURL + "/org/" + url.PathEscape(ctx.Org.Organization.Name) + "/settings") +} diff --git a/routers/web/org/worktime.go b/routers/web/org/worktime.go index c7b44baf7b..bf8db1a9a1 100644 --- a/routers/web/org/worktime.go +++ b/routers/web/org/worktime.go @@ -58,13 +58,13 @@ func Worktime(ctx *context.Context) { var err error switch worktimeBy { case "milestones": - worktimeSumResult, err = organization.GetWorktimeByMilestones(ctx.Org.Organization, unixFrom, unixTo) + worktimeSumResult, err = organization.GetWorktimeByMilestones(ctx, ctx.Org.Organization, unixFrom, unixTo) ctx.Data["WorktimeByMilestones"] = true case "members": - worktimeSumResult, err = organization.GetWorktimeByMembers(ctx.Org.Organization, unixFrom, unixTo) + worktimeSumResult, err = organization.GetWorktimeByMembers(ctx, ctx.Org.Organization, unixFrom, unixTo) ctx.Data["WorktimeByMembers"] = true default: /* by repos */ - worktimeSumResult, err = organization.GetWorktimeByRepos(ctx.Org.Organization, unixFrom, unixTo) + worktimeSumResult, err = organization.GetWorktimeByRepos(ctx, ctx.Org.Organization, unixFrom, unixTo) ctx.Data["WorktimeByRepos"] = true } if err != nil { diff --git a/routers/web/repo/actions/actions_test.go b/routers/web/repo/actions/actions_test.go index 6a976ed65c..9e83ff0fbb 100644 --- a/routers/web/repo/actions/actions_test.go +++ b/routers/web/repo/actions/actions_test.go @@ -162,7 +162,7 @@ func TestReadWorkflow_WorkflowDispatchConfig(t *testing.T) { func Test_loadIsRefDeleted(t *testing.T) { unittest.PrepareTestEnv(t) - runs, total, err := db.FindAndCount[actions_model.ActionRun](db.DefaultContext, + runs, total, err := db.FindAndCount[actions_model.ActionRun](t.Context(), actions_model.FindRunOptions{RepoID: 4, Ref: "refs/heads/test"}) assert.NoError(t, err) assert.Len(t, runs, 1) @@ -171,7 +171,7 @@ func Test_loadIsRefDeleted(t *testing.T) { assert.False(t, run.IsRefDeleted) } - assert.NoError(t, loadIsRefDeleted(db.DefaultContext, 4, runs)) + assert.NoError(t, loadIsRefDeleted(t.Context(), 4, runs)) for _, run := range runs { assert.True(t, run.IsRefDeleted) } diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index 52b2e9995e..3422128026 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -429,6 +429,12 @@ func Rerun(ctx *context_module.Context) { ctx.ServerError("UpdateRun", err) return } + + if err := run.LoadAttributes(ctx); err != nil { + ctx.ServerError("run.LoadAttributes", err) + return + } + notify_service.WorkflowRunStatusUpdate(ctx, run.Repo, run.TriggerUser, run) } job, jobs := getRunJobs(ctx, runIndex, jobIndex) @@ -485,7 +491,6 @@ func rerunJob(ctx *context_module.Context, job *actions_model.ActionRunJob, shou } actions_service.CreateCommitStatus(ctx, job) - actions_service.NotifyWorkflowRunStatusUpdateWithReload(ctx, job) notify_service.WorkflowJobStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job, nil) return nil @@ -560,9 +565,8 @@ func Cancel(ctx *context_module.Context) { if len(updatedjobs) > 0 { job := updatedjobs[0] actions_service.NotifyWorkflowRunStatusUpdateWithReload(ctx, job) - notify_service.WorkflowRunStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job.Run) } - ctx.JSON(http.StatusOK, struct{}{}) + ctx.JSONOK() } func Approve(ctx *context_module.Context) { @@ -606,7 +610,6 @@ func Approve(ctx *context_module.Context) { if len(updatedjobs) > 0 { job := updatedjobs[0] actions_service.NotifyWorkflowRunStatusUpdateWithReload(ctx, job) - notify_service.WorkflowRunStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job.Run) } for _, job := range updatedjobs { @@ -614,7 +617,7 @@ func Approve(ctx *context_module.Context) { notify_service.WorkflowJobStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job, nil) } - ctx.JSON(http.StatusOK, struct{}{}) + ctx.JSONOK() } func Delete(ctx *context_module.Context) { diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index c771b30e5f..a7084bf0ae 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -41,6 +41,7 @@ import ( "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/context/upload" "code.gitea.io/gitea/services/gitdiff" + pull_service "code.gitea.io/gitea/services/pull" ) const ( @@ -523,7 +524,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo { // Treat as pull request if both references are branches if ctx.Data["PageIsComparePull"] == nil { - ctx.Data["PageIsComparePull"] = headIsBranch && baseIsBranch + ctx.Data["PageIsComparePull"] = headIsBranch && baseIsBranch && permBase.CanReadIssuesOrPulls(true) } if ctx.Data["PageIsComparePull"] == true && !permBase.CanReadIssuesOrPulls(true) { @@ -550,7 +551,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo { headBranchRef = git.TagPrefix + ci.HeadBranch } - ci.CompareInfo, err = ci.HeadGitRepo.GetCompareInfo(baseRepo.RepoPath(), baseBranchRef, headBranchRef, ci.DirectComparison, fileOnly) + ci.CompareInfo, err = pull_service.GetCompareInfo(ctx, baseRepo, ci.HeadRepo, ci.HeadGitRepo, baseBranchRef, headBranchRef, ci.DirectComparison, fileOnly) if err != nil { ctx.ServerError("GetCompareInfo", err) return nil @@ -707,12 +708,6 @@ func PrepareCompareDiff( } func getBranchesAndTagsForRepo(ctx gocontext.Context, repo *repo_model.Repository) (branches, tags []string, err error) { - gitRepo, err := gitrepo.OpenRepository(ctx, repo) - if err != nil { - return nil, nil, err - } - defer gitRepo.Close() - branches, err = git_model.FindBranchNames(ctx, git_model.FindBranchOptions{ RepoID: repo.ID, ListOptions: db.ListOptionsAll, @@ -721,7 +716,7 @@ func getBranchesAndTagsForRepo(ctx gocontext.Context, repo *repo_model.Repositor if err != nil { return nil, nil, err } - tags, err = gitRepo.GetTags(0, 0) + tags, err = repo_model.GetTagNamesByRepoID(ctx, repo.ID) if err != nil { return nil, nil, err } @@ -735,6 +730,7 @@ func CompareDiff(ctx *context.Context) { return } + ctx.Data["PageIsViewCode"] = true ctx.Data["PullRequestWorkInProgressPrefixes"] = setting.Repository.PullRequest.WorkInProgressPrefixes ctx.Data["DirectComparison"] = ci.DirectComparison ctx.Data["OtherCompareSeparator"] = ".." diff --git a/routers/web/repo/editor_test.go b/routers/web/repo/editor_test.go index 6e2c1d6219..3ba75d5d70 100644 --- a/routers/web/repo/editor_test.go +++ b/routers/web/repo/editor_test.go @@ -8,7 +8,6 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "github.com/stretchr/testify/assert" @@ -22,7 +21,7 @@ func TestEditorUtils(t *testing.T) { assert.Equal(t, "user2-patch-1", branchName) }) t.Run("getClosestParentWithFiles", func(t *testing.T) { - gitRepo, _ := gitrepo.OpenRepository(git.DefaultContext, repo) + gitRepo, _ := gitrepo.OpenRepository(t.Context(), repo) defer gitRepo.Close() treePath := getClosestParentWithFiles(gitRepo, "sub-home-md-img-check", "docs/foo/bar") assert.Equal(t, "docs", treePath) diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index bc58efeb6f..83aaf75363 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -254,7 +254,7 @@ func GetMergedBaseCommitID(ctx *context.Context, issue *issues_model.Issue) stri return baseCommit } -func preparePullViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.CompareInfo { +func preparePullViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *pull_service.CompareInfo { if !issue.IsPull { return nil } @@ -265,7 +265,7 @@ func preparePullViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *g } // prepareMergedViewPullInfo show meta information for a merged pull request view page -func prepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.CompareInfo { +func prepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *pull_service.CompareInfo { pull := issue.PullRequest setMergeTarget(ctx, pull) @@ -273,7 +273,7 @@ func prepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue) baseCommit := GetMergedBaseCommitID(ctx, issue) - compareInfo, err := ctx.Repo.GitRepo.GetCompareInfo(ctx.Repo.Repository.RepoPath(), + compareInfo, err := pull_service.GetCompareInfo(ctx, ctx.Repo.Repository, ctx.Repo.Repository, ctx.Repo.GitRepo, baseCommit, pull.GetGitHeadRefName(), false, false) if err != nil { if strings.Contains(err.Error(), "fatal: Not a valid object name") || strings.Contains(err.Error(), "unknown revision or path not in the working tree") { @@ -311,7 +311,7 @@ func prepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue) } // prepareViewPullInfo show meta information for a pull request preview page -func prepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.CompareInfo { +func prepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *pull_service.CompareInfo { ctx.Data["PullRequestWorkInProgressPrefixes"] = setting.Repository.PullRequest.WorkInProgressPrefixes repo := ctx.Repo.Repository @@ -373,7 +373,7 @@ func prepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(commitStatuses) } - compareInfo, err := baseGitRepo.GetCompareInfo(pull.BaseRepo.RepoPath(), + compareInfo, err := pull_service.GetCompareInfo(ctx, pull.BaseRepo, pull.BaseRepo, baseGitRepo, pull.MergeBase, pull.GetGitHeadRefName(), false, false) if err != nil { if strings.Contains(err.Error(), "fatal: Not a valid object name") { @@ -521,7 +521,7 @@ func prepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C } } - compareInfo, err := baseGitRepo.GetCompareInfo(pull.BaseRepo.RepoPath(), + compareInfo, err := pull_service.GetCompareInfo(ctx, pull.BaseRepo, pull.BaseRepo, baseGitRepo, git.BranchPrefix+pull.BaseBranch, pull.GetGitHeadRefName(), false, false) if err != nil { if strings.Contains(err.Error(), "fatal: Not a valid object name") { diff --git a/routers/web/repo/pull_review_test.go b/routers/web/repo/pull_review_test.go index 3d0997ab4d..42223c1d9c 100644 --- a/routers/web/repo/pull_review_test.go +++ b/routers/web/repo/pull_review_test.go @@ -23,10 +23,10 @@ import ( func TestRenderConversation(t *testing.T) { unittest.PrepareTestEnv(t) - pr, _ := issues_model.GetPullRequestByID(db.DefaultContext, 2) - _ = pr.LoadIssue(db.DefaultContext) - _ = pr.Issue.LoadPoster(db.DefaultContext) - _ = pr.Issue.LoadRepo(db.DefaultContext) + pr, _ := issues_model.GetPullRequestByID(t.Context(), 2) + _ = pr.LoadIssue(t.Context()) + _ = pr.Issue.LoadPoster(t.Context()) + _ = pr.Issue.LoadRepo(t.Context()) run := func(name string, cb func(t *testing.T, ctx *context.Context, resp *httptest.ResponseRecorder)) { t.Run(name, func(t *testing.T) { @@ -73,7 +73,7 @@ func TestRenderConversation(t *testing.T) { assert.Contains(t, resp.Body.String(), `
= perm.AccessModeWrite || ctx.IsUserSiteAdmin() + if pd.Package.RepoID > 0 { + repo, err := repo_model.GetRepositoryByID(ctx, pd.Package.RepoID) + if err != nil { + ctx.ServerError("GetRepositoryByID", err) + return + } + ctx.Data["LinkedRepoName"] = repo.Name + } + ctx.HTML(http.StatusOK, tplPackagesSettings) } // PackageSettingsPost updates the package settings func PackageSettingsPost(ctx *context.Context) { - pd := ctx.Package.Descriptor - form := web.GetForm(ctx).(*forms.PackageSettingForm) switch form.Action { case "link": - success := func() bool { - repoID := int64(0) - if form.RepoID != 0 { - repo, err := repo_model.GetRepositoryByID(ctx, form.RepoID) - if err != nil { - log.Error("Error getting repository: %v", err) - return false - } - - if repo.OwnerID != pd.Owner.ID { - return false - } - - repoID = repo.ID - } - - if err := packages_model.SetRepositoryLink(ctx, pd.Package.ID, repoID); err != nil { - log.Error("Error updating package: %v", err) - return false - } - - return true - }() - - if success { - ctx.Flash.Success(ctx.Tr("packages.settings.link.success")) - } else { - ctx.Flash.Error(ctx.Tr("packages.settings.link.error")) - } - - ctx.Redirect(ctx.Link) - return + packageSettingsPostActionLink(ctx, form) case "delete": - err := packages_service.RemovePackageVersion(ctx, ctx.Doer, ctx.Package.Descriptor.Version) - if err != nil { - log.Error("Error deleting package: %v", err) - ctx.Flash.Error(ctx.Tr("packages.settings.delete.error")) - } else { - ctx.Flash.Success(ctx.Tr("packages.settings.delete.success")) + packageSettingsPostActionDelete(ctx) + default: + ctx.NotFound(nil) + } +} + +func packageSettingsPostActionLink(ctx *context.Context, form *forms.PackageSettingForm) { + pd := ctx.Package.Descriptor + if form.RepoName == "" { // remove the link + if err := packages_model.SetRepositoryLink(ctx, pd.Package.ID, 0); err != nil { + ctx.JSONError(ctx.Tr("packages.settings.unlink.error")) + return } - redirectURL := ctx.Package.Owner.HomeLink() + "/-/packages" - // redirect to the package if there are still versions available - if has, _ := packages_model.ExistVersion(ctx, &packages_model.PackageSearchOptions{PackageID: ctx.Package.Descriptor.Package.ID, IsInternal: optional.Some(false)}); has { - redirectURL = ctx.Package.Descriptor.PackageWebLink() - } - - ctx.Redirect(redirectURL) + ctx.Flash.Success(ctx.Tr("packages.settings.unlink.success")) + ctx.JSONRedirect("") return } + + repo, err := repo_model.GetRepositoryByName(ctx, pd.Owner.ID, form.RepoName) + if err != nil { + if repo_model.IsErrRepoNotExist(err) { + ctx.JSONError(ctx.Tr("packages.settings.link.repo_not_found", form.RepoName)) + } else { + ctx.ServerError("GetRepositoryByOwnerAndName", err) + } + return + } + + if err := packages_model.SetRepositoryLink(ctx, pd.Package.ID, repo.ID); err != nil { + ctx.JSONError(ctx.Tr("packages.settings.link.error")) + return + } + + ctx.Flash.Success(ctx.Tr("packages.settings.link.success")) + ctx.JSONRedirect("") +} + +func packageSettingsPostActionDelete(ctx *context.Context) { + err := packages_service.RemovePackageVersion(ctx, ctx.Doer, ctx.Package.Descriptor.Version) + if err != nil { + log.Error("Error deleting package: %v", err) + ctx.Flash.Error(ctx.Tr("packages.settings.delete.error")) + } else { + ctx.Flash.Success(ctx.Tr("packages.settings.delete.success")) + } + + redirectURL := ctx.Package.Owner.HomeLink() + "/-/packages" + // redirect to the package if there are still versions available + if has, _ := packages_model.ExistVersion(ctx, &packages_model.PackageSearchOptions{PackageID: ctx.Package.Descriptor.Package.ID, IsInternal: optional.Some(false)}); has { + redirectURL = ctx.Package.Descriptor.PackageWebLink() + } + + ctx.Redirect(redirectURL) } // DownloadPackageFile serves the content of a package file diff --git a/routers/web/web.go b/routers/web/web.go index 8fb0fc02ee..3a7a3ba6b3 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -8,10 +8,10 @@ import ( "strings" auth_model "code.gitea.io/gitea/models/auth" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/metrics" "code.gitea.io/gitea/modules/public" @@ -107,7 +107,7 @@ func buildAuthGroup() *auth_service.Group { } group.Add(&auth_service.Session{}) - if setting.IsWindows && auth_model.IsSSPIEnabled(db.DefaultContext) { + if setting.IsWindows && auth_model.IsSSPIEnabled(graceful.GetManager().ShutdownContext()) { group.Add(&auth_service.SSPI{}) // it MUST be the last, see the comment of SSPI } @@ -977,6 +977,7 @@ func registerWebRoutes(m *web.Router) { m.Post("/rename", web.Bind(forms.RenameOrgForm{}), org.SettingsRenamePost) m.Post("/delete", org.SettingsDeleteOrgPost) + m.Post("/visibility", org.SettingsChangeVisibilityPost) m.Group("/packages", func() { m.Get("", org.Packages) @@ -1230,10 +1231,11 @@ func registerWebRoutes(m *web.Router) { // end "/{username}/{reponame}": view milestone, label, issue, pull, etc m.Group("/{username}/{reponame}/{type:issues}", func() { + // these handlers also check unit permissions internally m.Get("", repo.Issues) - m.Get("/{index}", repo.ViewIssue) - }, optSignIn, context.RepoAssignment, context.RequireUnitReader(unit.TypeIssues, unit.TypeExternalTracker)) - // end "/{username}/{reponame}": issue/pull list, issue/pull view, external tracker + m.Get("/{index}", repo.ViewIssue) // also do pull-request redirection (".../issues/{PR-number}" -> ".../pulls/{PR-number}") + }, optSignIn, context.RepoAssignment, context.RequireUnitReader(unit.TypeIssues, unit.TypePullRequests, unit.TypeExternalTracker)) + // end "/{username}/{reponame}": issue list, issue view (pull-request redirection), external tracker m.Group("/{username}/{reponame}", func() { // edit issues, pulls, labels, milestones, etc m.Group("/issues", func() { @@ -1620,8 +1622,8 @@ func registerWebRoutes(m *web.Router) { m.Get("/cherry-pick/{sha:([a-f0-9]{7,64})$}", repo.SetEditorconfigIfExists, context.RepoRefByDefaultBranch(), repo.CherryPick) }, repo.MustBeNotEmpty) - m.Get("/rss/branch/*", context.RepoRefByType(git.RefTypeBranch), feedEnabled, feed.RenderBranchFeed) - m.Get("/atom/branch/*", context.RepoRefByType(git.RefTypeBranch), feedEnabled, feed.RenderBranchFeed) + m.Get("/rss/branch/*", context.RepoRefByType(git.RefTypeBranch), feedEnabled, feed.RenderBranchFeedRSS) + m.Get("/atom/branch/*", context.RepoRefByType(git.RefTypeBranch), feedEnabled, feed.RenderBranchFeedAtom) m.Group("/src", func() { m.Get("", func(ctx *context.Context) { ctx.Redirect(ctx.Repo.RepoLink) }) // there is no "{owner}/{repo}/src" page, so redirect to "{owner}/{repo}" to avoid 404 diff --git a/routers/web/webfinger.go b/routers/web/webfinger.go index a4c9bf902b..9d65b48ac7 100644 --- a/routers/web/webfinger.go +++ b/routers/web/webfinger.go @@ -85,7 +85,7 @@ func WebfingerQuery(ctx *context.Context) { } aliases := []string{ - u.HTMLURL(), + u.HTMLURL(ctx), appURL.String() + "api/v1/activitypub/user-id/" + strconv.FormatInt(u.ID, 10), } if !u.KeepEmailPrivate { @@ -96,7 +96,7 @@ func WebfingerQuery(ctx *context.Context) { { Rel: "http://webfinger.net/rel/profile-page", Type: "text/html", - Href: u.HTMLURL(), + Href: u.HTMLURL(ctx), }, { Rel: "http://webfinger.net/rel/avatar", diff --git a/services/actions/auth.go b/services/actions/auth.go index 12a8fba53f..c742e19c60 100644 --- a/services/actions/auth.go +++ b/services/actions/auth.go @@ -53,7 +53,7 @@ func CreateAuthorizationToken(taskID, runID, jobID int64) (string, error) { claims := actionsClaims{ RegisteredClaims: jwt.RegisteredClaims{ - ExpiresAt: jwt.NewNumericDate(now.Add(24 * time.Hour)), + ExpiresAt: jwt.NewNumericDate(now.Add(1*time.Hour + setting.Actions.EndlessTaskTimeout)), NotBefore: jwt.NewNumericDate(now), }, Scp: fmt.Sprintf("Actions.Results:%d:%d", runID, jobID), diff --git a/services/actions/clear_tasks.go b/services/actions/clear_tasks.go index 274c04aa57..3c7aa0b1a5 100644 --- a/services/actions/clear_tasks.go +++ b/services/actions/clear_tasks.go @@ -42,10 +42,8 @@ func notifyWorkflowJobStatusUpdate(ctx context.Context, jobs []*actions_model.Ac _ = job.LoadAttributes(ctx) notify_service.WorkflowJobStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job, nil) } - if len(jobs) > 0 { - job := jobs[0] - notify_service.WorkflowRunStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job.Run) - } + job := jobs[0] + notify_service.WorkflowRunStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job.Run) } } @@ -101,7 +99,7 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error { return nil } -// CancelAbandonedJobs cancels the jobs which have waiting status, but haven't been picked by a runner for a long time +// CancelAbandonedJobs cancels jobs that have not been picked by any runner for a long time func CancelAbandonedJobs(ctx context.Context) error { jobs, err := db.Find[actions_model.ActionRunJob](ctx, actions_model.FindRunJobOptions{ Statuses: []actions_model.Status{actions_model.StatusWaiting, actions_model.StatusBlocked}, @@ -113,24 +111,40 @@ func CancelAbandonedJobs(ctx context.Context) error { } now := timeutil.TimeStampNow() + + // Collect one job per run to send workflow run status update + updatedRuns := map[int64]*actions_model.ActionRunJob{} + for _, job := range jobs { job.Status = actions_model.StatusCancelled job.Stopped = now updated := false if err := db.WithTx(ctx, func(ctx context.Context) error { n, err := actions_model.UpdateRunJob(ctx, job, nil, "status", "stopped") - updated = err == nil && n > 0 - return err + if err != nil { + return err + } + if err := job.LoadAttributes(ctx); err != nil { + return err + } + updated = n > 0 + if updated && job.Run.Status.IsDone() { + updatedRuns[job.RunID] = job + } + return nil }); err != nil { log.Warn("cancel abandoned job %v: %v", job.ID, err) // go on } CreateCommitStatus(ctx, job) if updated { - NotifyWorkflowRunStatusUpdateWithReload(ctx, job) notify_service.WorkflowJobStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job, nil) } } + for _, job := range updatedRuns { + notify_service.WorkflowRunStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job.Run) + } + return nil } diff --git a/services/actions/init_test.go b/services/actions/init_test.go index 7ef0702204..2d33a4e5cc 100644 --- a/services/actions/init_test.go +++ b/services/actions/init_test.go @@ -25,10 +25,10 @@ func TestInitToken(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) t.Run("NoToken", func(t *testing.T) { - _, _ = db.Exec(db.DefaultContext, "DELETE FROM action_runner_token") + _, _ = db.Exec(t.Context(), "DELETE FROM action_runner_token") t.Setenv("GITEA_RUNNER_REGISTRATION_TOKEN", "") t.Setenv("GITEA_RUNNER_REGISTRATION_TOKEN_FILE", "") - err := initGlobalRunnerToken(db.DefaultContext) + err := initGlobalRunnerToken(t.Context()) require.NoError(t, err) notEmpty, err := db.IsTableNotEmpty(&actions_model.ActionRunnerToken{}) require.NoError(t, err) @@ -39,13 +39,13 @@ func TestInitToken(t *testing.T) { tokenValue, _ := util.CryptoRandomString(32) t.Setenv("GITEA_RUNNER_REGISTRATION_TOKEN", tokenValue) t.Setenv("GITEA_RUNNER_REGISTRATION_TOKEN_FILE", "") - err := initGlobalRunnerToken(db.DefaultContext) + err := initGlobalRunnerToken(t.Context()) require.NoError(t, err) token := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunnerToken{Token: tokenValue}) assert.True(t, token.IsActive) // init with the same token again, should not create a new token - err = initGlobalRunnerToken(db.DefaultContext) + err = initGlobalRunnerToken(t.Context()) require.NoError(t, err) token2 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunnerToken{Token: tokenValue}) assert.Equal(t, token.ID, token2.ID) @@ -58,13 +58,13 @@ func TestInitToken(t *testing.T) { _ = os.WriteFile(f, []byte(tokenValue), 0o644) t.Setenv("GITEA_RUNNER_REGISTRATION_TOKEN", "") t.Setenv("GITEA_RUNNER_REGISTRATION_TOKEN_FILE", f) - err := initGlobalRunnerToken(db.DefaultContext) + err := initGlobalRunnerToken(t.Context()) require.NoError(t, err) token := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunnerToken{Token: tokenValue}) assert.True(t, token.IsActive) // if the env token is invalidated by another new token, then it shouldn't be active anymore - _, err = actions_model.NewRunnerToken(db.DefaultContext, 0, 0) + _, err = actions_model.NewRunnerToken(t.Context(), 0, 0) require.NoError(t, err) token = unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunnerToken{Token: tokenValue}) assert.False(t, token.IsActive) @@ -72,7 +72,7 @@ func TestInitToken(t *testing.T) { t.Run("InvalidToken", func(t *testing.T) { t.Setenv("GITEA_RUNNER_REGISTRATION_TOKEN", "abc") - err := initGlobalRunnerToken(db.DefaultContext) + err := initGlobalRunnerToken(t.Context()) assert.ErrorContains(t, err, "must be at least") }) } diff --git a/services/actions/notifier.go b/services/actions/notifier.go index d10cc0ab34..110e330f68 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -263,11 +263,6 @@ func (n *actionsNotifier) CreateIssueComment(ctx context.Context, doer *user_mod func (n *actionsNotifier) UpdateComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment, oldContent string) { ctx = withMethod(ctx, "UpdateComment") - if err := c.LoadIssue(ctx); err != nil { - log.Error("LoadIssue: %v", err) - return - } - if c.Issue.IsPull { notifyIssueCommentChange(ctx, doer, c, oldContent, webhook_module.HookEventPullRequestComment, api.HookIssueCommentEdited) return @@ -278,11 +273,6 @@ func (n *actionsNotifier) UpdateComment(ctx context.Context, doer *user_model.Us func (n *actionsNotifier) DeleteComment(ctx context.Context, doer *user_model.User, comment *issues_model.Comment) { ctx = withMethod(ctx, "DeleteComment") - if err := comment.LoadIssue(ctx); err != nil { - log.Error("LoadIssue: %v", err) - return - } - if comment.Issue.IsPull { notifyIssueCommentChange(ctx, doer, comment, "", webhook_module.HookEventPullRequestComment, api.HookIssueCommentDeleted) return @@ -291,6 +281,7 @@ func (n *actionsNotifier) DeleteComment(ctx context.Context, doer *user_model.Us } func notifyIssueCommentChange(ctx context.Context, doer *user_model.User, comment *issues_model.Comment, oldContent string, event webhook_module.HookEventType, action api.HookIssueCommentAction) { + comment.Issue = nil // force issue to be loaded if err := comment.LoadIssue(ctx); err != nil { log.Error("LoadIssue: %v", err) return diff --git a/services/agit/agit.go b/services/agit/agit.go index 63b3eab4f2..9d2d122cfb 100644 --- a/services/agit/agit.go +++ b/services/agit/agit.go @@ -250,7 +250,7 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. if err != nil { return nil, fmt.Errorf("failed to load pull issue. Error: %w", err) } - comment, err := pull_service.CreatePushPullComment(ctx, pusher, pr, oldCommitID, opts.NewCommitIDs[i]) + comment, err := pull_service.CreatePushPullComment(ctx, pusher, pr, oldCommitID, opts.NewCommitIDs[i], forcePush.Value()) if err == nil && comment != nil { notify_service.PullRequestPushCommits(ctx, pusher, pr, comment) } diff --git a/services/asymkey/sign.go b/services/asymkey/sign.go index f94462ea46..8fd2adc8b4 100644 --- a/services/asymkey/sign.go +++ b/services/asymkey/sign.go @@ -69,6 +69,29 @@ func signingModeFromStrings(modeStrings []string) []signingMode { return returnable } +func userHasPubkeysGPG(ctx context.Context, userID int64) (bool, error) { + return db.Exist[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{ + OwnerID: userID, + IncludeSubKeys: true, + }.ToConds()) +} + +func userHasPubkeysSSH(ctx context.Context, userID int64) (bool, error) { + return db.Exist[asymkey_model.PublicKey](ctx, asymkey_model.FindPublicKeyOptions{ + OwnerID: userID, + NotKeytype: asymkey_model.KeyTypePrincipal, + }.ToConds()) +} + +// userHasPubkeys checks if a user has any public keys (GPG or SSH) +func userHasPubkeys(ctx context.Context, userID int64) (bool, error) { + has, err := userHasPubkeysGPG(ctx, userID) + if has || err != nil { + return has, err + } + return userHasPubkeysSSH(ctx, userID) +} + // ErrWontSign explains the first reason why a commit would not be signed // There may be other reasons - this is just the first reason found type ErrWontSign struct { @@ -170,14 +193,11 @@ Loop: case always: break Loop case pubkey: - keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{ - OwnerID: u.ID, - IncludeSubKeys: true, - }) + hasKeys, err := userHasPubkeys(ctx, u.ID) if err != nil { return false, nil, nil, err } - if len(keys) == 0 { + if !hasKeys { return false, nil, nil, &ErrWontSign{pubkey} } case twofa: @@ -210,14 +230,11 @@ Loop: case always: break Loop case pubkey: - keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{ - OwnerID: u.ID, - IncludeSubKeys: true, - }) + hasKeys, err := userHasPubkeys(ctx, u.ID) if err != nil { return false, nil, nil, err } - if len(keys) == 0 { + if !hasKeys { return false, nil, nil, &ErrWontSign{pubkey} } case twofa: @@ -266,14 +283,11 @@ Loop: case always: break Loop case pubkey: - keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{ - OwnerID: u.ID, - IncludeSubKeys: true, - }) + hasKeys, err := userHasPubkeys(ctx, u.ID) if err != nil { return false, nil, nil, err } - if len(keys) == 0 { + if !hasKeys { return false, nil, nil, &ErrWontSign{pubkey} } case twofa: @@ -290,16 +304,22 @@ Loop: return false, nil, nil, err } defer gitRepo.Close() - commit, err := gitRepo.GetCommit(parentCommit) + isEmpty, err := gitRepo.IsEmpty() if err != nil { return false, nil, nil, err } - if commit.Signature == nil { - return false, nil, nil, &ErrWontSign{parentSigned} - } - verification := ParseCommitWithSignature(ctx, commit) - if !verification.Verified { - return false, nil, nil, &ErrWontSign{parentSigned} + if !isEmpty { + commit, err := gitRepo.GetCommit(parentCommit) + if err != nil { + return false, nil, nil, err + } + if commit.Signature == nil { + return false, nil, nil, &ErrWontSign{parentSigned} + } + verification := ParseCommitWithSignature(ctx, commit) + if !verification.Verified { + return false, nil, nil, &ErrWontSign{parentSigned} + } } } } @@ -331,14 +351,11 @@ Loop: case always: break Loop case pubkey: - keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{ - OwnerID: u.ID, - IncludeSubKeys: true, - }) + hasKeys, err := userHasPubkeys(ctx, u.ID) if err != nil { return false, nil, nil, err } - if len(keys) == 0 { + if !hasKeys { return false, nil, nil, &ErrWontSign{pubkey} } case twofa: diff --git a/services/asymkey/sign_test.go b/services/asymkey/sign_test.go new file mode 100644 index 0000000000..fbcf078cf8 --- /dev/null +++ b/services/asymkey/sign_test.go @@ -0,0 +1,39 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package asymkey + +import ( + "testing" + + "code.gitea.io/gitea/models/unittest" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestUserHasPubkeys(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + test := func(t *testing.T, userID int64, expectedHasGPG, expectedHasSSH bool) { + ctx := t.Context() + hasGPG, err := userHasPubkeysGPG(ctx, userID) + require.NoError(t, err) + hasSSH, err := userHasPubkeysSSH(ctx, userID) + require.NoError(t, err) + hasPubkeys, err := userHasPubkeys(ctx, userID) + require.NoError(t, err) + assert.Equal(t, expectedHasGPG, hasGPG) + assert.Equal(t, expectedHasSSH, hasSSH) + assert.Equal(t, expectedHasGPG || expectedHasSSH, hasPubkeys) + } + + t.Run("AllowUserWithGPGKey", func(t *testing.T) { + test(t, 36, true, false) // has gpg + }) + t.Run("AllowUserWithSSHKey", func(t *testing.T) { + test(t, 2, false, true) // has ssh + }) + t.Run("DenyUserWithNoKeys", func(t *testing.T) { + test(t, 1, false, false) // no pubkey + }) +} diff --git a/services/asymkey/ssh_key_test.go b/services/asymkey/ssh_key_test.go index fbd5d13ab2..3605bd1e64 100644 --- a/services/asymkey/ssh_key_test.go +++ b/services/asymkey/ssh_key_test.go @@ -66,8 +66,8 @@ ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ib for i, kase := range testCases { s.ID = int64(i) + 20 - asymkey_model.AddPublicKeysBySource(db.DefaultContext, user, s, []string{kase.keyString}) - keys, err := db.Find[asymkey_model.PublicKey](db.DefaultContext, asymkey_model.FindPublicKeyOptions{ + asymkey_model.AddPublicKeysBySource(t.Context(), user, s, []string{kase.keyString}) + keys, err := db.Find[asymkey_model.PublicKey](t.Context(), asymkey_model.FindPublicKeyOptions{ OwnerID: user.ID, LoginSourceID: s.ID, }) @@ -81,7 +81,7 @@ ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ib assert.Contains(t, kase.keyContents, key.Content) } for _, key := range keys { - DeletePublicKey(db.DefaultContext, user, key.ID) + DeletePublicKey(t.Context(), user, key.ID) } } } diff --git a/services/attachment/attachment_test.go b/services/attachment/attachment_test.go index 65475836be..8ecac8d7a3 100644 --- a/services/attachment/attachment_test.go +++ b/services/attachment/attachment_test.go @@ -8,7 +8,6 @@ import ( "path/filepath" "testing" - "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" @@ -32,14 +31,14 @@ func TestUploadAttachment(t *testing.T) { assert.NoError(t, err) defer f.Close() - attach, err := NewAttachment(db.DefaultContext, &repo_model.Attachment{ + attach, err := NewAttachment(t.Context(), &repo_model.Attachment{ RepoID: 1, UploaderID: user.ID, Name: filepath.Base(fPath), }, f, -1) assert.NoError(t, err) - attachment, err := repo_model.GetAttachmentByUUID(db.DefaultContext, attach.UUID) + attachment, err := repo_model.GetAttachmentByUUID(t.Context(), attach.UUID) assert.NoError(t, err) assert.Equal(t, user.ID, attachment.UploaderID) assert.Equal(t, int64(0), attachment.DownloadCount) diff --git a/services/auth/auth_token_test.go b/services/auth/auth_token_test.go index 23c8d17e59..6b04caab85 100644 --- a/services/auth/auth_token_test.go +++ b/services/auth/auth_token_test.go @@ -8,7 +8,6 @@ import ( "time" 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/timeutil" @@ -19,19 +18,19 @@ func TestCheckAuthToken(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) t.Run("Empty", func(t *testing.T) { - token, err := CheckAuthToken(db.DefaultContext, "") + token, err := CheckAuthToken(t.Context(), "") assert.NoError(t, err) assert.Nil(t, token) }) t.Run("InvalidFormat", func(t *testing.T) { - token, err := CheckAuthToken(db.DefaultContext, "dummy") + token, err := CheckAuthToken(t.Context(), "dummy") assert.ErrorIs(t, err, ErrAuthTokenInvalidFormat) assert.Nil(t, token) }) t.Run("NotFound", func(t *testing.T) { - token, err := CheckAuthToken(db.DefaultContext, "notexists:dummy") + token, err := CheckAuthToken(t.Context(), "notexists:dummy") assert.ErrorIs(t, err, ErrAuthTokenExpired) assert.Nil(t, token) }) @@ -39,44 +38,44 @@ func TestCheckAuthToken(t *testing.T) { t.Run("Expired", func(t *testing.T) { timeutil.MockSet(time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)) - at, token, err := CreateAuthTokenForUserID(db.DefaultContext, 2) + at, token, err := CreateAuthTokenForUserID(t.Context(), 2) assert.NoError(t, err) assert.NotNil(t, at) assert.NotEmpty(t, token) timeutil.MockUnset() - at2, err := CheckAuthToken(db.DefaultContext, at.ID+":"+token) + at2, err := CheckAuthToken(t.Context(), at.ID+":"+token) assert.ErrorIs(t, err, ErrAuthTokenExpired) assert.Nil(t, at2) - assert.NoError(t, auth_model.DeleteAuthTokenByID(db.DefaultContext, at.ID)) + assert.NoError(t, auth_model.DeleteAuthTokenByID(t.Context(), at.ID)) }) t.Run("InvalidHash", func(t *testing.T) { - at, token, err := CreateAuthTokenForUserID(db.DefaultContext, 2) + at, token, err := CreateAuthTokenForUserID(t.Context(), 2) assert.NoError(t, err) assert.NotNil(t, at) assert.NotEmpty(t, token) - at2, err := CheckAuthToken(db.DefaultContext, at.ID+":"+token+"dummy") + at2, err := CheckAuthToken(t.Context(), at.ID+":"+token+"dummy") assert.ErrorIs(t, err, ErrAuthTokenInvalidHash) assert.Nil(t, at2) - assert.NoError(t, auth_model.DeleteAuthTokenByID(db.DefaultContext, at.ID)) + assert.NoError(t, auth_model.DeleteAuthTokenByID(t.Context(), at.ID)) }) t.Run("Valid", func(t *testing.T) { - at, token, err := CreateAuthTokenForUserID(db.DefaultContext, 2) + at, token, err := CreateAuthTokenForUserID(t.Context(), 2) assert.NoError(t, err) assert.NotNil(t, at) assert.NotEmpty(t, token) - at2, err := CheckAuthToken(db.DefaultContext, at.ID+":"+token) + at2, err := CheckAuthToken(t.Context(), at.ID+":"+token) assert.NoError(t, err) assert.NotNil(t, at2) - assert.NoError(t, auth_model.DeleteAuthTokenByID(db.DefaultContext, at.ID)) + assert.NoError(t, auth_model.DeleteAuthTokenByID(t.Context(), at.ID)) }) } @@ -86,14 +85,14 @@ func TestRegenerateAuthToken(t *testing.T) { timeutil.MockSet(time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)) defer timeutil.MockUnset() - at, token, err := CreateAuthTokenForUserID(db.DefaultContext, 2) + at, token, err := CreateAuthTokenForUserID(t.Context(), 2) assert.NoError(t, err) assert.NotNil(t, at) assert.NotEmpty(t, token) timeutil.MockSet(time.Date(2023, 1, 1, 0, 0, 1, 0, time.UTC)) - at2, token2, err := RegenerateAuthToken(db.DefaultContext, at) + at2, token2, err := RegenerateAuthToken(t.Context(), at) assert.NoError(t, err) assert.NotNil(t, at2) assert.NotEmpty(t, token2) @@ -103,5 +102,5 @@ func TestRegenerateAuthToken(t *testing.T) { assert.NotEqual(t, token, token2) assert.NotEqual(t, at.ExpiresUnix, at2.ExpiresUnix) - assert.NoError(t, auth_model.DeleteAuthTokenByID(db.DefaultContext, at.ID)) + assert.NoError(t, auth_model.DeleteAuthTokenByID(t.Context(), at.ID)) } diff --git a/services/auth/source/oauth2/providers.go b/services/auth/source/oauth2/providers.go index 75ed41ba66..bb21cb53fe 100644 --- a/services/auth/source/oauth2/providers.go +++ b/services/auth/source/oauth2/providers.go @@ -10,6 +10,7 @@ import ( "html" "html/template" "net/url" + "slices" "sort" "code.gitea.io/gitea/models/auth" @@ -75,6 +76,10 @@ func (p *AuthSourceProvider) IconHTML(size int) template.HTML { // value is used to store display data var gothProviders = map[string]GothProvider{} +func isAzureProvider(name string) bool { + return name == "azuread" || name == "microsoftonline" || name == "azureadv2" +} + // RegisterGothProvider registers a GothProvider func RegisterGothProvider(provider GothProvider) { if _, has := gothProviders[provider.Name()]; has { @@ -83,13 +88,42 @@ func RegisterGothProvider(provider GothProvider) { gothProviders[provider.Name()] = provider } -// GetSupportedOAuth2Providers returns the map of unconfigured OAuth2 providers +// getExistingAzureADAuthSources returns a list of Azure AD provider names that are already configured +func getExistingAzureADAuthSources(ctx context.Context) ([]string, error) { + authSources, err := db.Find[auth.Source](ctx, auth.FindSourcesOptions{ + LoginType: auth.OAuth2, + }) + if err != nil { + return nil, err + } + + var existingAzureProviders []string + for _, source := range authSources { + if oauth2Cfg, ok := source.Cfg.(*Source); ok { + if isAzureProvider(oauth2Cfg.Provider) { + existingAzureProviders = append(existingAzureProviders, oauth2Cfg.Provider) + } + } + } + return existingAzureProviders, nil +} + +// GetSupportedOAuth2Providers returns the list of supported OAuth2 providers with context for filtering // key is used as technical name (like in the callbackURL) // values to display -func GetSupportedOAuth2Providers() []Provider { +// Note: Azure AD providers (azuread, microsoftonline, azureadv2) are filtered out +// unless they already exist in the system to encourage use of OpenID Connect +func GetSupportedOAuth2Providers(ctx context.Context) []Provider { providers := make([]Provider, 0, len(gothProviders)) + existingAzureSources, err := getExistingAzureADAuthSources(ctx) + if err != nil { + log.Error("Failed to get existing OAuth2 auth sources: %v", err) + } for _, provider := range gothProviders { + if isAzureProvider(provider.Name()) && !slices.Contains(existingAzureSources, provider.Name()) { + continue + } providers = append(providers, provider) } sort.Slice(providers, func(i, j int) bool { diff --git a/services/convert/issue.go b/services/convert/issue.go index 7f386e6293..ecb3b93af1 100644 --- a/services/convert/issue.go +++ b/services/convert/issue.go @@ -66,7 +66,7 @@ func toIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Iss return &api.Issue{} } apiIssue.URL = issue.APIURL(ctx) - apiIssue.HTMLURL = issue.HTMLURL() + apiIssue.HTMLURL = issue.HTMLURL(ctx) if err := issue.LoadLabels(ctx); err != nil { return &api.Issue{} } @@ -112,7 +112,7 @@ func toIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Iss apiIssue.PullRequest.Merged = issue.PullRequest.MergedUnix.AsTimePtr() } // Add pr's html url - apiIssue.PullRequest.HTMLURL = issue.HTMLURL() + apiIssue.PullRequest.HTMLURL = issue.HTMLURL(ctx) } } if issue.DeadlineUnix != 0 { diff --git a/services/convert/notification.go b/services/convert/notification.go index 41063cf399..69470638be 100644 --- a/services/convert/notification.go +++ b/services/convert/notification.go @@ -40,7 +40,7 @@ func ToNotificationThread(ctx context.Context, n *activities_model.Notification) if n.Issue != nil { result.Subject.Title = n.Issue.Title result.Subject.URL = n.Issue.APIURL(ctx) - result.Subject.HTMLURL = n.Issue.HTMLURL() + result.Subject.HTMLURL = n.Issue.HTMLURL(ctx) result.Subject.State = n.Issue.State() comment, err := n.Issue.GetLastComment(ctx) if err == nil && comment != nil { @@ -53,7 +53,7 @@ func ToNotificationThread(ctx context.Context, n *activities_model.Notification) if n.Issue != nil { result.Subject.Title = n.Issue.Title result.Subject.URL = n.Issue.APIURL(ctx) - result.Subject.HTMLURL = n.Issue.HTMLURL() + result.Subject.HTMLURL = n.Issue.HTMLURL(ctx) result.Subject.State = n.Issue.State() comment, err := n.Issue.GetLastComment(ctx) if err == nil && comment != nil { diff --git a/services/convert/package.go b/services/convert/package.go index b27992bea9..08310dd7f6 100644 --- a/services/convert/package.go +++ b/services/convert/package.go @@ -35,7 +35,7 @@ func ToPackage(ctx context.Context, pd *packages.PackageDescriptor, doer *user_m Name: pd.Package.Name, Version: pd.Version.Version, CreatedAt: pd.Version.CreatedUnix.AsTime(), - HTMLURL: pd.VersionHTMLURL(), + HTMLURL: pd.VersionHTMLURL(ctx), }, nil } diff --git a/services/convert/pull.go b/services/convert/pull.go index 4acbd880dc..82ab0125d5 100644 --- a/services/convert/pull.go +++ b/services/convert/pull.go @@ -73,7 +73,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u apiPullRequest := &api.PullRequest{ ID: pr.ID, - URL: pr.Issue.HTMLURL(), + URL: pr.Issue.HTMLURL(ctx), Index: pr.Index, Poster: apiIssue.Poster, Title: apiIssue.Title, @@ -87,7 +87,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u IsLocked: apiIssue.IsLocked, Comments: apiIssue.Comments, ReviewComments: pr.GetReviewCommentsCount(ctx), - HTMLURL: pr.Issue.HTMLURL(), + HTMLURL: pr.Issue.HTMLURL(ctx), DiffURL: pr.Issue.DiffURL(), PatchURL: pr.Issue.PatchURL(), HasMerged: pr.HasMerged, @@ -348,7 +348,7 @@ func ToAPIPullRequests(ctx context.Context, baseRepo *repo_model.Repository, prs apiPullRequest := &api.PullRequest{ ID: pr.ID, - URL: pr.Issue.HTMLURL(), + URL: pr.Issue.HTMLURL(ctx), Index: pr.Index, Poster: apiIssue.Poster, Title: apiIssue.Title, @@ -362,7 +362,7 @@ func ToAPIPullRequests(ctx context.Context, baseRepo *repo_model.Repository, prs IsLocked: apiIssue.IsLocked, Comments: apiIssue.Comments, ReviewComments: reviewCounts[pr.IssueID], - HTMLURL: pr.Issue.HTMLURL(), + HTMLURL: pr.Issue.HTMLURL(ctx), DiffURL: pr.Issue.DiffURL(), PatchURL: pr.Issue.PatchURL(), HasMerged: pr.HasMerged, diff --git a/services/convert/pull_review.go b/services/convert/pull_review.go index 29a5ab7466..574f34fa17 100644 --- a/services/convert/pull_review.go +++ b/services/convert/pull_review.go @@ -34,7 +34,7 @@ func ToPullReview(ctx context.Context, r *issues_model.Review, doer *user_model. Submitted: r.CreatedUnix.AsTime(), Updated: r.UpdatedUnix.AsTime(), HTMLURL: r.HTMLURL(ctx), - HTMLPullURL: r.Issue.HTMLURL(), + HTMLPullURL: r.Issue.HTMLURL(ctx), } if r.ReviewerTeam != nil { @@ -105,7 +105,7 @@ func ToPullReviewCommentList(ctx context.Context, review *issues_model.Review, d OrigCommitID: comment.OldRef, DiffHunk: patch2diff(comment.Patch), HTMLURL: comment.HTMLURL(ctx), - HTMLPullURL: review.Issue.HTMLURL(), + HTMLPullURL: review.Issue.HTMLURL(ctx), } if comment.Line < 0 { diff --git a/services/convert/pull_review_test.go b/services/convert/pull_review_test.go index d0a077ab24..c6e1165991 100644 --- a/services/convert/pull_review_test.go +++ b/services/convert/pull_review_test.go @@ -6,7 +6,6 @@ package convert import ( "testing" - "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -25,27 +24,27 @@ func Test_ToPullReview(t *testing.T) { reviewList := []*issues_model.Review{review} t.Run("Anonymous User", func(t *testing.T) { - prList, err := ToPullReviewList(db.DefaultContext, reviewList, nil) + prList, err := ToPullReviewList(t.Context(), reviewList, nil) assert.NoError(t, err) assert.Empty(t, prList) }) t.Run("Reviewer Himself", func(t *testing.T) { - prList, err := ToPullReviewList(db.DefaultContext, reviewList, reviewer) + prList, err := ToPullReviewList(t.Context(), reviewList, reviewer) assert.NoError(t, err) assert.Len(t, prList, 1) }) t.Run("Other User", func(t *testing.T) { user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) - prList, err := ToPullReviewList(db.DefaultContext, reviewList, user4) + prList, err := ToPullReviewList(t.Context(), reviewList, user4) assert.NoError(t, err) assert.Empty(t, prList) }) t.Run("Admin User", func(t *testing.T) { adminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - prList, err := ToPullReviewList(db.DefaultContext, reviewList, adminUser) + prList, err := ToPullReviewList(t.Context(), reviewList, adminUser) assert.NoError(t, err) assert.Len(t, prList, 1) }) diff --git a/services/convert/pull_test.go b/services/convert/pull_test.go index dfbe24d184..dc8e4c637e 100644 --- a/services/convert/pull_test.go +++ b/services/convert/pull_test.go @@ -6,13 +6,11 @@ package convert import ( "testing" - "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" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/structs" "github.com/stretchr/testify/assert" @@ -23,31 +21,31 @@ func TestPullRequest_APIFormat(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) - assert.NoError(t, pr.LoadAttributes(db.DefaultContext)) - assert.NoError(t, pr.LoadIssue(db.DefaultContext)) - apiPullRequest := ToAPIPullRequest(git.DefaultContext, pr, nil) + assert.NoError(t, pr.LoadAttributes(t.Context())) + assert.NoError(t, pr.LoadIssue(t.Context())) + apiPullRequest := ToAPIPullRequest(t.Context(), pr, nil) assert.NotNil(t, apiPullRequest) assert.Equal(t, &structs.PRBranchInfo{ Name: "branch1", Ref: "refs/pull/2/head", Sha: "4a357436d925b5c974181ff12a994538ddc5a269", RepoID: 1, - Repository: ToRepo(db.DefaultContext, headRepo, access_model.Permission{AccessMode: perm.AccessModeRead}), + Repository: ToRepo(t.Context(), headRepo, access_model.Permission{AccessMode: perm.AccessModeRead}), }, apiPullRequest.Head) // withOut HeadRepo pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) - assert.NoError(t, pr.LoadIssue(db.DefaultContext)) - assert.NoError(t, pr.LoadAttributes(db.DefaultContext)) + assert.NoError(t, pr.LoadIssue(t.Context())) + assert.NoError(t, pr.LoadAttributes(t.Context())) // simulate fork deletion pr.HeadRepo = nil pr.HeadRepoID = 100000 - apiPullRequest = ToAPIPullRequest(git.DefaultContext, pr, nil) + apiPullRequest = ToAPIPullRequest(t.Context(), pr, nil) assert.NotNil(t, apiPullRequest) assert.Nil(t, apiPullRequest.Head.Repository) assert.EqualValues(t, -1, apiPullRequest.Head.RepoID) - apiPullRequests, err := ToAPIPullRequests(git.DefaultContext, pr.BaseRepo, []*issues_model.PullRequest{pr}, nil) + apiPullRequests, err := ToAPIPullRequests(t.Context(), pr.BaseRepo, []*issues_model.PullRequest{pr}, nil) assert.NoError(t, err) assert.Len(t, apiPullRequests, 1) assert.NotNil(t, apiPullRequests[0]) diff --git a/services/convert/release_test.go b/services/convert/release_test.go index bb618c9ca3..a03a90abc7 100644 --- a/services/convert/release_test.go +++ b/services/convert/release_test.go @@ -6,7 +6,6 @@ package convert import ( "testing" - "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -18,9 +17,9 @@ func TestRelease_ToRelease(t *testing.T) { repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) release1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Release{ID: 1}) - release1.LoadAttributes(db.DefaultContext) + release1.LoadAttributes(t.Context()) - apiRelease := ToAPIRelease(db.DefaultContext, repo1, release1) + apiRelease := ToAPIRelease(t.Context(), repo1, release1) assert.NotNil(t, apiRelease) assert.EqualValues(t, 1, apiRelease.ID) assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/releases/1", apiRelease.URL) diff --git a/services/convert/status.go b/services/convert/status.go index b4864a0307..fe8240a8f7 100644 --- a/services/convert/status.go +++ b/services/convert/status.go @@ -42,20 +42,19 @@ func ToCommitStatuses(ctx context.Context, statuses []*git_model.CommitStatus) [ } // ToCombinedStatus converts List of CommitStatus to a CombinedStatus -func ToCombinedStatus(ctx context.Context, statuses []*git_model.CommitStatus, repo *api.Repository) *api.CombinedStatus { - if len(statuses) == 0 { - return nil +func ToCombinedStatus(ctx context.Context, commitID string, statuses []*git_model.CommitStatus, repo *api.Repository) *api.CombinedStatus { + status := api.CombinedStatus{ + SHA: commitID, + TotalCount: len(statuses), + Repository: repo, + CommitURL: repo.URL + "/commits/" + url.PathEscape(commitID), + URL: repo.URL + "/commits/" + url.PathEscape(commitID) + "/status", } combinedStatus := git_model.CalcCommitStatus(statuses) - - return &api.CombinedStatus{ - State: combinedStatus.State, - Statuses: ToCommitStatuses(ctx, statuses), - SHA: combinedStatus.SHA, - TotalCount: len(statuses), - Repository: repo, - CommitURL: repo.URL + "/commits/" + url.PathEscape(combinedStatus.SHA), - URL: repo.URL + "/commits/" + url.PathEscape(combinedStatus.SHA) + "/status", + if combinedStatus != nil { + status.Statuses = ToCommitStatuses(ctx, statuses) + status.State = combinedStatus.State } + return &status } diff --git a/services/convert/user.go b/services/convert/user.go index 90bcf35cf6..cee4de5091 100644 --- a/services/convert/user.go +++ b/services/convert/user.go @@ -53,7 +53,7 @@ func toUser(ctx context.Context, user *user_model.User, signed, authed bool) *ap FullName: user.FullName, Email: user.GetPlaceholderEmail(), AvatarURL: user.AvatarLink(ctx), - HTMLURL: user.HTMLURL(), + HTMLURL: user.HTMLURL(ctx), Created: user.CreatedUnix.AsTime(), Restricted: user.IsRestricted, Location: user.Location, diff --git a/services/convert/user_test.go b/services/convert/user_test.go index 199d500732..d32cffb512 100644 --- a/services/convert/user_test.go +++ b/services/convert/user_test.go @@ -6,7 +6,6 @@ package convert import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" api "code.gitea.io/gitea/modules/structs" @@ -19,22 +18,22 @@ func TestUser_ToUser(t *testing.T) { user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1, IsAdmin: true}) - apiUser := toUser(db.DefaultContext, user1, true, true) + apiUser := toUser(t.Context(), user1, true, true) assert.True(t, apiUser.IsAdmin) assert.Contains(t, apiUser.AvatarURL, "://") user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2, IsAdmin: false}) - apiUser = toUser(db.DefaultContext, user2, true, true) + apiUser = toUser(t.Context(), user2, true, true) assert.False(t, apiUser.IsAdmin) - apiUser = toUser(db.DefaultContext, user1, false, false) + apiUser = toUser(t.Context(), user1, false, false) assert.False(t, apiUser.IsAdmin) assert.Equal(t, api.VisibleTypePublic.String(), apiUser.Visibility) user31 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 31, IsAdmin: false, Visibility: api.VisibleTypePrivate}) - apiUser = toUser(db.DefaultContext, user31, true, true) + apiUser = toUser(t.Context(), user31, true, true) assert.False(t, apiUser.IsAdmin) assert.Equal(t, api.VisibleTypePrivate.String(), apiUser.Visibility) } diff --git a/services/cron/tasks_extended.go b/services/cron/tasks_extended.go index 0018c5facc..3747111984 100644 --- a/services/cron/tasks_extended.go +++ b/services/cron/tasks_extended.go @@ -171,34 +171,35 @@ func registerDeleteOldSystemNotices() { }) } +type GCLFSConfig struct { + BaseConfig + OlderThan time.Duration + LastUpdatedMoreThanAgo time.Duration + NumberToCheckPerRepo int64 + ProportionToCheckPerRepo float64 +} + func registerGCLFS() { if !setting.LFS.StartServer { return } - type GCLFSConfig struct { - OlderThanConfig - LastUpdatedMoreThanAgo time.Duration - NumberToCheckPerRepo int64 - ProportionToCheckPerRepo float64 - } RegisterTaskFatal("gc_lfs", &GCLFSConfig{ - OlderThanConfig: OlderThanConfig{ - BaseConfig: BaseConfig{ - Enabled: false, - RunAtStart: false, - Schedule: "@every 24h", - }, - // Only attempt to garbage collect lfs meta objects older than a week as the order of git lfs upload - // and git object upload is not necessarily guaranteed. It's possible to imagine a situation whereby - // an LFS object is uploaded but the git branch is not uploaded immediately, or there are some rapid - // changes in new branches that might lead to lfs objects becoming temporarily unassociated with git - // objects. - // - // It is likely that a week is potentially excessive but it should definitely be enough that any - // unassociated LFS object is genuinely unassociated. - OlderThan: 24 * time.Hour * 7, + BaseConfig: BaseConfig{ + Enabled: false, + RunAtStart: false, + Schedule: "@every 24h", }, + // Only attempt to garbage collect lfs meta objects older than a week as the order of git lfs upload + // and git object upload is not necessarily guaranteed. It's possible to imagine a situation whereby + // an LFS object is uploaded but the git branch is not uploaded immediately, or there are some rapid + // changes in new branches that might lead to lfs objects becoming temporarily unassociated with git + // objects. + // + // It is likely that a week is potentially excessive but it should definitely be enough that any + // unassociated LFS object is genuinely unassociated. + OlderThan: 24 * time.Hour * 7, + // Only GC things that haven't been looked at in the past 3 days LastUpdatedMoreThanAgo: 24 * time.Hour * 3, NumberToCheckPerRepo: 100, diff --git a/services/cron/tasks_extended_test.go b/services/cron/tasks_extended_test.go new file mode 100644 index 0000000000..a3d40630a3 --- /dev/null +++ b/services/cron/tasks_extended_test.go @@ -0,0 +1,51 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package cron + +import ( + "testing" + "time" + + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/test" + + "github.com/stretchr/testify/assert" +) + +func Test_GCLFSConfig(t *testing.T) { + cfg, err := setting.NewConfigProviderFromData(` +[cron.gc_lfs] +ENABLED = true +RUN_AT_START = true +SCHEDULE = "@every 2h" +OLDER_THAN = "1h" +LAST_UPDATED_MORE_THAN_AGO = "7h" +NUMBER_TO_CHECK_PER_REPO = 10 +PROPORTION_TO_CHECK_PER_REPO = 0.1 +`) + assert.NoError(t, err) + defer test.MockVariableValue(&setting.CfgProvider, cfg)() + + config := &GCLFSConfig{ + BaseConfig: BaseConfig{ + Enabled: false, + RunAtStart: false, + Schedule: "@every 24h", + }, + OlderThan: 24 * time.Hour * 7, + LastUpdatedMoreThanAgo: 24 * time.Hour * 3, + NumberToCheckPerRepo: 100, + ProportionToCheckPerRepo: 0.6, + } + + _, err = setting.GetCronSettings("gc_lfs", config) + assert.NoError(t, err) + assert.True(t, config.Enabled) + assert.True(t, config.RunAtStart) + assert.Equal(t, "@every 2h", config.Schedule) + assert.Equal(t, 1*time.Hour, config.OlderThan) + assert.Equal(t, 7*time.Hour, config.LastUpdatedMoreThanAgo) + assert.Equal(t, int64(10), config.NumberToCheckPerRepo) + assert.InDelta(t, 0.1, config.ProportionToCheckPerRepo, 0.001) +} diff --git a/services/doctor/dbconsistency_test.go b/services/doctor/dbconsistency_test.go index eb427dee73..d2cf2c4725 100644 --- a/services/doctor/dbconsistency_test.go +++ b/services/doctor/dbconsistency_test.go @@ -24,16 +24,16 @@ func TestConsistencyCheck(t *testing.T) { }) require.NotEqual(t, -1, idx) - _ = db.TruncateBeans(db.DefaultContext, &auth.OAuth2Application{}, &user.User{}) - _ = db.TruncateBeans(db.DefaultContext, &auth.OAuth2Application{}, &auth.OAuth2Application{}) + _ = db.TruncateBeans(t.Context(), &auth.OAuth2Application{}, &user.User{}) + _ = db.TruncateBeans(t.Context(), &auth.OAuth2Application{}, &auth.OAuth2Application{}) - err := db.Insert(db.DefaultContext, &user.User{ID: 1}) + err := db.Insert(t.Context(), &user.User{ID: 1}) assert.NoError(t, err) - err = db.Insert(db.DefaultContext, &auth.OAuth2Application{Name: "test-oauth2-app-1", ClientID: "client-id-1"}) + err = db.Insert(t.Context(), &auth.OAuth2Application{Name: "test-oauth2-app-1", ClientID: "client-id-1"}) assert.NoError(t, err) - err = db.Insert(db.DefaultContext, &auth.OAuth2Application{Name: "test-oauth2-app-2", ClientID: "client-id-2", UID: 1}) + err = db.Insert(t.Context(), &auth.OAuth2Application{Name: "test-oauth2-app-2", ClientID: "client-id-2", UID: 1}) assert.NoError(t, err) - err = db.Insert(db.DefaultContext, &auth.OAuth2Application{Name: "test-oauth2-app-3", ClientID: "client-id-3", UID: 99999999}) + err = db.Insert(t.Context(), &auth.OAuth2Application{Name: "test-oauth2-app-3", ClientID: "client-id-3", UID: 99999999}) assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{ClientID: "client-id-1"}) @@ -41,7 +41,7 @@ func TestConsistencyCheck(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{ClientID: "client-id-3"}) oauth2AppCheck := checks[idx] - err = oauth2AppCheck.Run(db.DefaultContext, log.GetManager().GetLogger(log.DEFAULT), true) + err = oauth2AppCheck.Run(t.Context(), log.GetManager().GetLogger(log.DEFAULT), true) assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{ClientID: "client-id-1"}) diff --git a/services/doctor/doctor.go b/services/doctor/doctor.go index c6810a5fa0..e7fe29d8ee 100644 --- a/services/doctor/doctor.go +++ b/services/doctor/doctor.go @@ -36,7 +36,7 @@ func initDBSkipLogger(ctx context.Context) error { return fmt.Errorf("db.InitEngine: %w", err) } // some doctor sub-commands need to use git command - if err := git.InitFull(ctx); err != nil { + if err := git.InitFull(); err != nil { return fmt.Errorf("git.InitFull: %w", err) } return nil diff --git a/services/doctor/misc.go b/services/doctor/misc.go index 1269d088c3..ce7eea1dcc 100644 --- a/services/doctor/misc.go +++ b/services/doctor/misc.go @@ -91,18 +91,12 @@ func checkEnablePushOptions(ctx context.Context, logger log.Logger, autofix bool if err := iterateRepositories(ctx, func(repo *repo_model.Repository) error { numRepos++ - r, err := gitrepo.OpenRepository(ctx, repo) - if err != nil { - return err - } - defer r.Close() if autofix { - _, _, err := git.NewCommand("config", "receive.advertisePushOptions", "true").RunStdString(ctx, &git.RunOpts{Dir: r.Path}) - return err + return gitrepo.GitConfigSet(ctx, repo, "receive.advertisePushOptions", "true") } - value, _, err := git.NewCommand("config", "receive.advertisePushOptions").RunStdString(ctx, &git.RunOpts{Dir: r.Path}) + value, err := gitrepo.GitConfigGet(ctx, repo, "receive.advertisePushOptions") if err != nil { return err } diff --git a/services/feed/feed_test.go b/services/feed/feed_test.go index 705d42a2eb..136344cd28 100644 --- a/services/feed/feed_test.go +++ b/services/feed/feed_test.go @@ -20,7 +20,7 @@ func TestGetFeeds(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - actions, count, err := GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ + actions, count, err := GetFeeds(t.Context(), activities_model.GetFeedsOptions{ RequestedUser: user, Actor: user, IncludePrivate: true, @@ -34,7 +34,7 @@ func TestGetFeeds(t *testing.T) { } assert.Equal(t, int64(1), count) - actions, count, err = GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ + actions, count, err = GetFeeds(t.Context(), activities_model.GetFeedsOptions{ RequestedUser: user, Actor: user, IncludePrivate: false, @@ -52,7 +52,7 @@ func TestGetFeedsForRepos(t *testing.T) { pubRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8}) // private repo & no login - actions, count, err := GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ + actions, count, err := GetFeeds(t.Context(), activities_model.GetFeedsOptions{ RequestedRepo: privRepo, IncludePrivate: true, }) @@ -61,7 +61,7 @@ func TestGetFeedsForRepos(t *testing.T) { assert.Equal(t, int64(0), count) // public repo & no login - actions, count, err = GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ + actions, count, err = GetFeeds(t.Context(), activities_model.GetFeedsOptions{ RequestedRepo: pubRepo, IncludePrivate: true, }) @@ -70,7 +70,7 @@ func TestGetFeedsForRepos(t *testing.T) { assert.Equal(t, int64(1), count) // private repo and login - actions, count, err = GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ + actions, count, err = GetFeeds(t.Context(), activities_model.GetFeedsOptions{ RequestedRepo: privRepo, IncludePrivate: true, Actor: user, @@ -80,7 +80,7 @@ func TestGetFeedsForRepos(t *testing.T) { assert.Equal(t, int64(1), count) // public repo & login - actions, count, err = GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ + actions, count, err = GetFeeds(t.Context(), activities_model.GetFeedsOptions{ RequestedRepo: pubRepo, IncludePrivate: true, Actor: user, @@ -96,7 +96,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, count, err := GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ + actions, count, err := GetFeeds(t.Context(), activities_model.GetFeedsOptions{ RequestedUser: org, Actor: user, IncludePrivate: true, @@ -111,7 +111,7 @@ func TestGetFeeds2(t *testing.T) { } assert.Equal(t, int64(1), count) - actions, count, err = GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ + actions, count, err = GetFeeds(t.Context(), activities_model.GetFeedsOptions{ RequestedUser: org, Actor: user, IncludePrivate: false, @@ -133,7 +133,7 @@ func TestGetFeedsCorrupted(t *testing.T) { RepoID: 1700, }) - actions, count, err := GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ + actions, count, err := GetFeeds(t.Context(), activities_model.GetFeedsOptions{ RequestedUser: user, Actor: user, IncludePrivate: true, @@ -146,18 +146,18 @@ func TestGetFeedsCorrupted(t *testing.T) { func TestRepoActions(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - _ = db.TruncateBeans(db.DefaultContext, &activities_model.Action{}) + _ = db.TruncateBeans(t.Context(), &activities_model.Action{}) for i := range 3 { - _ = db.Insert(db.DefaultContext, &activities_model.Action{ + _ = db.Insert(t.Context(), &activities_model.Action{ UserID: 2 + int64(i), ActUserID: 2, RepoID: repo.ID, OpType: activities_model.ActionCommentIssue, }) } - count, _ := db.Count[activities_model.Action](db.DefaultContext, &db.ListOptions{}) + count, _ := db.Count[activities_model.Action](t.Context(), &db.ListOptions{}) assert.EqualValues(t, 3, count) - actions, _, err := GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ + actions, _, err := GetFeeds(t.Context(), activities_model.GetFeedsOptions{ RequestedRepo: repo, }) assert.NoError(t, err) @@ -172,7 +172,7 @@ func TestNotifyWatchers(t *testing.T) { RepoID: 1, OpType: activities_model.ActionStarRepo, } - assert.NoError(t, NotifyWatchers(db.DefaultContext, action)) + assert.NoError(t, NotifyWatchers(t.Context(), action)) // One watchers are inactive, thus action is only created for user 8, 1, 4, 11 unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ diff --git a/services/feed/notifier_test.go b/services/feed/notifier_test.go index 60cf7fbb49..ef70facd1e 100644 --- a/services/feed/notifier_test.go +++ b/services/feed/notifier_test.go @@ -8,7 +8,6 @@ import ( "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" user_model "code.gitea.io/gitea/models/user" @@ -46,7 +45,7 @@ func TestRenameRepoAction(t *testing.T) { } unittest.AssertNotExistsBean(t, actionBean) - NewNotifier().RenameRepository(db.DefaultContext, user, repo, oldRepoName) + NewNotifier().RenameRepository(t.Context(), user, repo, oldRepoName) unittest.AssertExistsAndLoadBean(t, actionBean) unittest.CheckConsistencyFor(t, &activities_model.Action{}) diff --git a/services/forms/org.go b/services/forms/org.go index 2ac18ef25c..3997e1da84 100644 --- a/services/forms/org.go +++ b/services/forms/org.go @@ -41,7 +41,6 @@ type UpdateOrgSettingForm struct { Description string `binding:"MaxSize(255)"` Website string `binding:"ValidUrl;MaxSize(255)"` Location string `binding:"MaxSize(50)"` - Visibility structs.VisibleType MaxRepoCreation int RepoAdminChangeTeamAccess bool } diff --git a/services/forms/user_form.go b/services/forms/user_form.go index ddf2bd09b0..618294d434 100644 --- a/services/forms/user_form.go +++ b/services/forms/user_form.go @@ -416,8 +416,8 @@ func (f *WebauthnDeleteForm) Validate(req *http.Request, errs binding.Errors) bi // PackageSettingForm form for package settings type PackageSettingForm struct { - Action string - RepoID int64 `form:"repo_id"` + Action string + RepoName string `form:"repo_name"` } // Validate validates the fields diff --git a/services/gitdiff/csv_test.go b/services/gitdiff/csv_test.go index f91e0e9aa7..b45433d8c2 100644 --- a/services/gitdiff/csv_test.go +++ b/services/gitdiff/csv_test.go @@ -8,7 +8,6 @@ import ( "strings" "testing" - "code.gitea.io/gitea/models/db" csv_module "code.gitea.io/gitea/modules/csv" "code.gitea.io/gitea/modules/setting" @@ -191,7 +190,7 @@ c,d,e`, } for n, c := range cases { - diff, err := ParsePatch(db.DefaultContext, setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(c.diff), "") + diff, err := ParsePatch(t.Context(), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(c.diff), "") assert.NoError(t, err) var baseReader *csv.Reader diff --git a/services/gitdiff/git_diff_tree_test.go b/services/gitdiff/git_diff_tree_test.go index 313d279e95..c6e3fbab81 100644 --- a/services/gitdiff/git_diff_tree_test.go +++ b/services/gitdiff/git_diff_tree_test.go @@ -7,7 +7,6 @@ import ( "strings" "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/git" "github.com/stretchr/testify/assert" @@ -206,11 +205,11 @@ func TestGitDiffTree(t *testing.T) { for _, tt := range test { t.Run(tt.Name, func(t *testing.T) { - gitRepo, err := git.OpenRepository(git.DefaultContext, tt.RepoPath) + gitRepo, err := git.OpenRepository(t.Context(), tt.RepoPath) assert.NoError(t, err) defer gitRepo.Close() - diffPaths, err := GetDiffTree(db.DefaultContext, gitRepo, tt.useMergeBase, tt.BaseSha, tt.HeadSha) + diffPaths, err := GetDiffTree(t.Context(), gitRepo, tt.useMergeBase, tt.BaseSha, tt.HeadSha) require.NoError(t, err) assert.Equal(t, tt.Expected, diffPaths) @@ -415,11 +414,11 @@ func TestGitDiffTreeErrors(t *testing.T) { for _, tt := range test { t.Run(tt.Name, func(t *testing.T) { - gitRepo, err := git.OpenRepository(git.DefaultContext, tt.RepoPath) + gitRepo, err := git.OpenRepository(t.Context(), tt.RepoPath) assert.NoError(t, err) defer gitRepo.Close() - diffPaths, err := GetDiffTree(db.DefaultContext, gitRepo, true, tt.BaseSha, tt.HeadSha) + diffPaths, err := GetDiffTree(t.Context(), gitRepo, true, tt.BaseSha, tt.HeadSha) assert.Error(t, err) assert.Nil(t, diffPaths) }) diff --git a/services/gitdiff/gitdiff_test.go b/services/gitdiff/gitdiff_test.go index b84530043a..83815caeb5 100644 --- a/services/gitdiff/gitdiff_test.go +++ b/services/gitdiff/gitdiff_test.go @@ -9,7 +9,6 @@ import ( "strings" "testing" - "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -158,7 +157,7 @@ diff --git "\\a/README.md" "\\b/README.md" } for _, testcase := range tests { t.Run(testcase.name, func(t *testing.T) { - got, err := ParsePatch(db.DefaultContext, setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(testcase.gitdiff), testcase.skipTo) + got, err := ParsePatch(t.Context(), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(testcase.gitdiff), testcase.skipTo) if (err != nil) != testcase.wantErr { t.Errorf("ParsePatch(%q) error = %v, wantErr %v", testcase.name, err, testcase.wantErr) return @@ -377,7 +376,7 @@ index 6961180..9ba1a00 100644 for _, testcase := range tests { t.Run(testcase.name, func(t *testing.T) { - got, err := ParsePatch(db.DefaultContext, setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(testcase.gitdiff), "") + got, err := ParsePatch(t.Context(), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(testcase.gitdiff), "") if (err != nil) != testcase.wantErr { t.Errorf("ParsePatch(%q) error = %v, wantErr %v", testcase.name, err, testcase.wantErr) return @@ -420,21 +419,21 @@ index 0000000..6bb8f39 diffBuilder.WriteString("+line" + strconv.Itoa(i) + "\n") } diff = diffBuilder.String() - result, err := ParsePatch(db.DefaultContext, 20, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "") + result, err := ParsePatch(t.Context(), 20, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "") if err != nil { t.Errorf("There should not be an error: %v", err) } if !result.Files[0].IsIncomplete { t.Errorf("Files should be incomplete! %v", result.Files[0]) } - result, err = ParsePatch(db.DefaultContext, 40, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "") + result, err = ParsePatch(t.Context(), 40, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "") if err != nil { t.Errorf("There should not be an error: %v", err) } if result.Files[0].IsIncomplete { t.Errorf("Files should not be incomplete! %v", result.Files[0]) } - result, err = ParsePatch(db.DefaultContext, 40, 5, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "") + result, err = ParsePatch(t.Context(), 40, 5, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "") if err != nil { t.Errorf("There should not be an error: %v", err) } @@ -465,14 +464,14 @@ index 0000000..6bb8f39 diffBuilder.WriteString("+line" + strconv.Itoa(35) + "\n") diff = diffBuilder.String() - result, err = ParsePatch(db.DefaultContext, 20, 4096, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "") + result, err = ParsePatch(t.Context(), 20, 4096, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "") if err != nil { t.Errorf("There should not be an error: %v", err) } if !result.Files[0].IsIncomplete { t.Errorf("Files should be incomplete! %v", result.Files[0]) } - result, err = ParsePatch(db.DefaultContext, 40, 4096, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "") + result, err = ParsePatch(t.Context(), 40, 4096, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "") if err != nil { t.Errorf("There should not be an error: %v", err) } @@ -491,7 +490,7 @@ index 0000000..6bb8f39 Docker Pulls + cut off + cut off` - _, err = ParsePatch(db.DefaultContext, setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "") + _, err = ParsePatch(t.Context(), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "") if err != nil { t.Errorf("ParsePatch failed: %s", err) } @@ -507,7 +506,7 @@ index 0000000..6bb8f39 Docker Pulls + cut off + cut off` - _, err = ParsePatch(db.DefaultContext, setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2), "") + _, err = ParsePatch(t.Context(), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2), "") if err != nil { t.Errorf("ParsePatch failed: %s", err) } @@ -523,7 +522,7 @@ index 0000000..6bb8f39 Docker Pulls + cut off + cut off` - _, err = ParsePatch(db.DefaultContext, setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2a), "") + _, err = ParsePatch(t.Context(), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2a), "") if err != nil { t.Errorf("ParsePatch failed: %s", err) } @@ -539,7 +538,7 @@ index 0000000..6bb8f39 Docker Pulls + cut off + cut off` - _, err = ParsePatch(db.DefaultContext, setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff3), "") + _, err = ParsePatch(t.Context(), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff3), "") if err != nil { t.Errorf("ParsePatch failed: %s", err) } @@ -571,7 +570,7 @@ func TestDiff_LoadCommentsNoOutdated(t *testing.T) { issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) diff := setupDefaultDiff() - assert.NoError(t, diff.LoadComments(db.DefaultContext, issue, user, false)) + assert.NoError(t, diff.LoadComments(t.Context(), issue, user, false)) assert.Len(t, diff.Files[0].Sections[0].Lines[0].Comments, 2) } @@ -581,7 +580,7 @@ func TestDiff_LoadCommentsWithOutdated(t *testing.T) { issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) diff := setupDefaultDiff() - assert.NoError(t, diff.LoadComments(db.DefaultContext, issue, user, true)) + assert.NoError(t, diff.LoadComments(t.Context(), issue, user, true)) assert.Len(t, diff.Files[0].Sections[0].Lines[0].Comments, 3) } @@ -637,6 +636,6 @@ func TestNoCrashes(t *testing.T) { } for _, testcase := range tests { // It shouldn't crash, so don't care about the output. - ParsePatch(db.DefaultContext, setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(testcase.gitdiff), "") + ParsePatch(t.Context(), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(testcase.gitdiff), "") } } diff --git a/services/gitdiff/submodule_test.go b/services/gitdiff/submodule_test.go index c793969f0e..9f2cf1d1c6 100644 --- a/services/gitdiff/submodule_test.go +++ b/services/gitdiff/submodule_test.go @@ -7,7 +7,6 @@ import ( "strings" "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" @@ -204,7 +203,7 @@ index 0000000..68972a9 for _, testcase := range tests { t.Run(testcase.name, func(t *testing.T) { - diff, err := ParsePatch(db.DefaultContext, setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(testcase.gitdiff), "") + diff, err := ParsePatch(t.Context(), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(testcase.gitdiff), "") assert.NoError(t, err) for i, expected := range testcase.infos { diff --git a/services/issue/assignee_test.go b/services/issue/assignee_test.go index 38d56f9d9d..4bf0884f52 100644 --- a/services/issue/assignee_test.go +++ b/services/issue/assignee_test.go @@ -6,7 +6,6 @@ package issue import ( "testing" - "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -18,30 +17,30 @@ func TestDeleteNotPassedAssignee(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // Fake issue with assignees - issue, err := issues_model.GetIssueByID(db.DefaultContext, 1) + issue, err := issues_model.GetIssueByID(t.Context(), 1) assert.NoError(t, err) - err = issue.LoadAttributes(db.DefaultContext) + err = issue.LoadAttributes(t.Context()) assert.NoError(t, err) assert.Len(t, issue.Assignees, 1) - user1, err := user_model.GetUserByID(db.DefaultContext, 1) // This user is already assigned (see the definition in fixtures), so running UpdateAssignee should unassign him + user1, err := user_model.GetUserByID(t.Context(), 1) // This user is already assigned (see the definition in fixtures), so running UpdateAssignee should unassign him assert.NoError(t, err) // Check if he got removed - isAssigned, err := issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, user1) + isAssigned, err := issues_model.IsUserAssignedToIssue(t.Context(), issue, user1) assert.NoError(t, err) assert.True(t, isAssigned) // Clean everyone - err = DeleteNotPassedAssignee(db.DefaultContext, issue, user1, []*user_model.User{}) + err = DeleteNotPassedAssignee(t.Context(), issue, user1, []*user_model.User{}) assert.NoError(t, err) assert.Empty(t, issue.Assignees) // Reload to check they're gone issue.ResetAttributesLoaded() - assert.NoError(t, issue.LoadAssignees(db.DefaultContext)) + assert.NoError(t, issue.LoadAssignees(t.Context())) assert.Empty(t, issue.Assignees) assert.Empty(t, issue.Assignee) } diff --git a/services/issue/comments.go b/services/issue/comments.go index 10c81198d5..9442701029 100644 --- a/services/issue/comments.go +++ b/services/issue/comments.go @@ -80,6 +80,12 @@ func CreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_m return nil, err } + // reload issue to ensure it has the latest data, especially the number of comments + issue, err = issues_model.GetIssueByID(ctx, issue.ID) + if err != nil { + return nil, err + } + notify_service.CreateIssueComment(ctx, doer, repo, issue, comment, mentions) return comment, nil diff --git a/services/issue/commit_test.go b/services/issue/commit_test.go index 0518803683..d19702269a 100644 --- a/services/issue/commit_test.go +++ b/services/issue/commit_test.go @@ -7,7 +7,6 @@ import ( "testing" 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" "code.gitea.io/gitea/models/unittest" @@ -61,7 +60,7 @@ func TestUpdateIssuesCommit(t *testing.T) { unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1") - assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch)) + assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") unittest.CheckConsistencyFor(t, &activities_model.Action{}) @@ -88,7 +87,7 @@ func TestUpdateIssuesCommit(t *testing.T) { unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1") - assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, "non-existing-branch")) + assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, "non-existing-branch")) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertNotExistsBean(t, issueBean, "is_closed=1") unittest.CheckConsistencyFor(t, &activities_model.Action{}) @@ -114,7 +113,7 @@ func TestUpdateIssuesCommit(t *testing.T) { unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1") - assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch)) + assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") unittest.CheckConsistencyFor(t, &activities_model.Action{}) @@ -140,7 +139,7 @@ func TestUpdateIssuesCommit_Colon(t *testing.T) { issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 4} unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1") - assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch)) + assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") unittest.CheckConsistencyFor(t, &activities_model.Action{}) } @@ -173,7 +172,7 @@ func TestUpdateIssuesCommit_Issue5957(t *testing.T) { unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, issueBean, "is_closed=1") - assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, "non-existing-branch")) + assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, "non-existing-branch")) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") unittest.CheckConsistencyFor(t, &activities_model.Action{}) @@ -208,7 +207,7 @@ func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) { unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, issueBean, "is_closed=1") - assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch)) + assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") unittest.CheckConsistencyFor(t, &activities_model.Action{}) @@ -243,7 +242,7 @@ func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) { unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, issueBean, "is_closed=1") - assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch)) + assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") unittest.CheckConsistencyFor(t, &activities_model.Action{}) @@ -293,7 +292,7 @@ func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) { unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, commentBean2) unittest.AssertNotExistsBean(t, issueBean, "is_closed=1") - assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch)) + assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, commentBean2) unittest.AssertNotExistsBean(t, issueBean, "is_closed=1") diff --git a/services/issue/issue.go b/services/issue/issue.go index f03be3e18f..ae81b9f48b 100644 --- a/services/issue/issue.go +++ b/services/issue/issue.go @@ -261,74 +261,67 @@ func GetRefEndNamesAndURLs(issues []*issues_model.Issue, repoLink string) (map[i // deleteIssue deletes the issue func deleteIssue(ctx context.Context, issue *issues_model.Issue) ([]string, error) { - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return nil, err - } - defer committer.Close() - - if _, err := db.GetEngine(ctx).ID(issue.ID).NoAutoCondition().Delete(issue); err != nil { - return nil, err - } - - // update the total issue numbers - if err := repo_model.UpdateRepoIssueNumbers(ctx, issue.RepoID, issue.IsPull, false); err != nil { - return nil, err - } - // if the issue is closed, update the closed issue numbers - if issue.IsClosed { - if err := repo_model.UpdateRepoIssueNumbers(ctx, issue.RepoID, issue.IsPull, true); err != nil { + return db.WithTx2(ctx, func(ctx context.Context) ([]string, error) { + if _, err := db.GetEngine(ctx).ID(issue.ID).NoAutoCondition().Delete(issue); err != nil { return nil, err } - } - if err := issues_model.UpdateMilestoneCounters(ctx, issue.MilestoneID); err != nil { - return nil, fmt.Errorf("error updating counters for milestone id %d: %w", - issue.MilestoneID, err) - } + // update the total issue numbers + if err := repo_model.UpdateRepoIssueNumbers(ctx, issue.RepoID, issue.IsPull, false); err != nil { + return nil, err + } + // if the issue is closed, update the closed issue numbers + if issue.IsClosed { + if err := repo_model.UpdateRepoIssueNumbers(ctx, issue.RepoID, issue.IsPull, true); err != nil { + return nil, err + } + } - if err := activities_model.DeleteIssueActions(ctx, issue.RepoID, issue.ID, issue.Index); err != nil { - return nil, err - } + if err := issues_model.UpdateMilestoneCounters(ctx, issue.MilestoneID); err != nil { + return nil, fmt.Errorf("error updating counters for milestone id %d: %w", + issue.MilestoneID, err) + } - // find attachments related to this issue and remove them - if err := issue.LoadAttachments(ctx); err != nil { - return nil, err - } + if err := activities_model.DeleteIssueActions(ctx, issue.RepoID, issue.ID, issue.Index); err != nil { + return nil, err + } - var attachmentPaths []string - for i := range issue.Attachments { - attachmentPaths = append(attachmentPaths, issue.Attachments[i].RelativePath()) - } + // find attachments related to this issue and remove them + if err := issue.LoadAttachments(ctx); err != nil { + return nil, err + } - // delete all database data still assigned to this issue - if err := db.DeleteBeans(ctx, - &issues_model.ContentHistory{IssueID: issue.ID}, - &issues_model.Comment{IssueID: issue.ID}, - &issues_model.IssueLabel{IssueID: issue.ID}, - &issues_model.IssueDependency{IssueID: issue.ID}, - &issues_model.IssueAssignees{IssueID: issue.ID}, - &issues_model.IssueUser{IssueID: issue.ID}, - &activities_model.Notification{IssueID: issue.ID}, - &issues_model.Reaction{IssueID: issue.ID}, - &issues_model.IssueWatch{IssueID: issue.ID}, - &issues_model.Stopwatch{IssueID: issue.ID}, - &issues_model.TrackedTime{IssueID: issue.ID}, - &project_model.ProjectIssue{IssueID: issue.ID}, - &repo_model.Attachment{IssueID: issue.ID}, - &issues_model.PullRequest{IssueID: issue.ID}, - &issues_model.Comment{RefIssueID: issue.ID}, - &issues_model.IssueDependency{DependencyID: issue.ID}, - &issues_model.Comment{DependentIssueID: issue.ID}, - &issues_model.IssuePin{IssueID: issue.ID}, - ); err != nil { - return nil, err - } + var attachmentPaths []string + for i := range issue.Attachments { + attachmentPaths = append(attachmentPaths, issue.Attachments[i].RelativePath()) + } - if err := committer.Commit(); err != nil { - return nil, err - } - return attachmentPaths, nil + // delete all database data still assigned to this issue + if err := db.DeleteBeans(ctx, + &issues_model.ContentHistory{IssueID: issue.ID}, + &issues_model.Comment{IssueID: issue.ID}, + &issues_model.IssueLabel{IssueID: issue.ID}, + &issues_model.IssueDependency{IssueID: issue.ID}, + &issues_model.IssueAssignees{IssueID: issue.ID}, + &issues_model.IssueUser{IssueID: issue.ID}, + &activities_model.Notification{IssueID: issue.ID}, + &issues_model.Reaction{IssueID: issue.ID}, + &issues_model.IssueWatch{IssueID: issue.ID}, + &issues_model.Stopwatch{IssueID: issue.ID}, + &issues_model.TrackedTime{IssueID: issue.ID}, + &project_model.ProjectIssue{IssueID: issue.ID}, + &repo_model.Attachment{IssueID: issue.ID}, + &issues_model.PullRequest{IssueID: issue.ID}, + &issues_model.Comment{RefIssueID: issue.ID}, + &issues_model.IssueDependency{DependencyID: issue.ID}, + &issues_model.Comment{DependentIssueID: issue.ID}, + &issues_model.IssuePin{IssueID: issue.ID}, + ); err != nil { + return nil, err + } + + return attachmentPaths, nil + }) } // DeleteOrphanedIssues delete issues without a repo diff --git a/services/issue/issue_test.go b/services/issue/issue_test.go index bad0d65d1e..61ed13ed2f 100644 --- a/services/issue/issue_test.go +++ b/services/issue/issue_test.go @@ -6,7 +6,6 @@ package issue import ( "testing" - "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/models/unittest" @@ -35,7 +34,7 @@ func TestGetRefEndNamesAndURLs(t *testing.T) { func TestIssue_DeleteIssue(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issueIDs, err := issues_model.GetIssueIDsByRepoID(db.DefaultContext, 1) + issueIDs, err := issues_model.GetIssueIDsByRepoID(t.Context(), 1) assert.NoError(t, err) assert.Len(t, issueIDs, 5) @@ -44,43 +43,43 @@ func TestIssue_DeleteIssue(t *testing.T) { ID: issueIDs[2], } - _, err = deleteIssue(db.DefaultContext, issue) + _, err = deleteIssue(t.Context(), issue) assert.NoError(t, err) - issueIDs, err = issues_model.GetIssueIDsByRepoID(db.DefaultContext, 1) + issueIDs, err = issues_model.GetIssueIDsByRepoID(t.Context(), 1) assert.NoError(t, err) assert.Len(t, issueIDs, 4) // check attachment removal - attachments, err := repo_model.GetAttachmentsByIssueID(db.DefaultContext, 4) + attachments, err := repo_model.GetAttachmentsByIssueID(t.Context(), 4) assert.NoError(t, err) - issue, err = issues_model.GetIssueByID(db.DefaultContext, 4) + issue, err = issues_model.GetIssueByID(t.Context(), 4) assert.NoError(t, err) - _, err = deleteIssue(db.DefaultContext, issue) + _, err = deleteIssue(t.Context(), issue) assert.NoError(t, err) assert.Len(t, attachments, 2) for i := range attachments { - attachment, err := repo_model.GetAttachmentByUUID(db.DefaultContext, attachments[i].UUID) + attachment, err := repo_model.GetAttachmentByUUID(t.Context(), attachments[i].UUID) assert.Error(t, err) assert.True(t, repo_model.IsErrAttachmentNotExist(err)) assert.Nil(t, attachment) } // check issue dependencies - user, err := user_model.GetUserByID(db.DefaultContext, 1) + user, err := user_model.GetUserByID(t.Context(), 1) assert.NoError(t, err) - issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1) + issue1, err := issues_model.GetIssueByID(t.Context(), 1) assert.NoError(t, err) - issue2, err := issues_model.GetIssueByID(db.DefaultContext, 2) + issue2, err := issues_model.GetIssueByID(t.Context(), 2) assert.NoError(t, err) - err = issues_model.CreateIssueDependency(db.DefaultContext, user, issue1, issue2) + err = issues_model.CreateIssueDependency(t.Context(), user, issue1, issue2) assert.NoError(t, err) - left, err := issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1) + left, err := issues_model.IssueNoDependenciesLeft(t.Context(), issue1) assert.NoError(t, err) assert.False(t, left) - _, err = deleteIssue(db.DefaultContext, issue2) + _, err = deleteIssue(t.Context(), issue2) assert.NoError(t, err) - left, err = issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1) + left, err = issues_model.IssueNoDependenciesLeft(t.Context(), issue1) assert.NoError(t, err) assert.True(t, left) } diff --git a/services/issue/label_test.go b/services/issue/label_test.go index 90608c9e26..093b16b53f 100644 --- a/services/issue/label_test.go +++ b/services/issue/label_test.go @@ -6,7 +6,6 @@ package issue import ( "testing" - "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -33,7 +32,7 @@ func TestIssue_AddLabels(t *testing.T) { labels[i] = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}) } doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}) - assert.NoError(t, AddLabels(db.DefaultContext, issue, doer, labels)) + assert.NoError(t, AddLabels(t.Context(), issue, doer, labels)) for _, labelID := range test.labelIDs { unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: test.issueID, LabelID: labelID}) } @@ -56,7 +55,7 @@ func TestIssue_AddLabel(t *testing.T) { issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}) label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: test.labelID}) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}) - assert.NoError(t, AddLabel(db.DefaultContext, issue, doer, label)) + assert.NoError(t, AddLabel(t.Context(), issue, doer, label)) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: test.issueID, LabelID: test.labelID}) } } diff --git a/services/issue/milestone_test.go b/services/issue/milestone_test.go index bf5abc85b7..2ef482e23c 100644 --- a/services/issue/milestone_test.go +++ b/services/issue/milestone_test.go @@ -6,7 +6,6 @@ package issue import ( "testing" - "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -23,8 +22,8 @@ func TestChangeMilestoneAssign(t *testing.T) { oldMilestoneID := issue.MilestoneID issue.MilestoneID = 2 - assert.NoError(t, issue.LoadMilestone(db.DefaultContext)) - assert.NoError(t, ChangeMilestoneAssign(db.DefaultContext, issue, doer, oldMilestoneID)) + assert.NoError(t, issue.LoadMilestone(t.Context())) + assert.NoError(t, ChangeMilestoneAssign(t.Context(), issue, doer, oldMilestoneID)) unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ IssueID: issue.ID, Type: issues_model.CommentTypeMilestone, @@ -36,7 +35,7 @@ func TestChangeMilestoneAssign(t *testing.T) { oldMilestoneID = issue.MilestoneID issue.MilestoneID = 0 - assert.NoError(t, ChangeMilestoneAssign(db.DefaultContext, issue, doer, oldMilestoneID)) + assert.NoError(t, ChangeMilestoneAssign(t.Context(), issue, doer, oldMilestoneID)) assert.EqualValues(t, 0, issue.MilestoneID) assert.Nil(t, issue.Milestone) } diff --git a/services/issue/pull.go b/services/issue/pull.go index 512fdf78e8..8ee14c0a4b 100644 --- a/services/issue/pull.go +++ b/services/issue/pull.go @@ -11,26 +11,28 @@ import ( issues_model "code.gitea.io/gitea/models/issues" org_model "code.gitea.io/gitea/models/organization" + repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" + "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" ) -func getMergeBase(repo *git.Repository, pr *issues_model.PullRequest, baseBranch, headBranch string) (string, error) { +func getMergeBase(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, pr *issues_model.PullRequest, baseBranch, headBranch string) (string, error) { // Add a temporary remote tmpRemote := fmt.Sprintf("mergebase-%d-%d", pr.ID, time.Now().UnixNano()) - if err := repo.AddRemote(tmpRemote, repo.Path, false); err != nil { - return "", fmt.Errorf("AddRemote: %w", err) + if err := gitrepo.GitRemoteAdd(ctx, repo, tmpRemote, gitRepo.Path); err != nil { + return "", fmt.Errorf("GitRemoteAdd: %w", err) } defer func() { - if err := repo.RemoveRemote(tmpRemote); err != nil { - log.Error("getMergeBase: RemoveRemote: %v", err) + if err := gitrepo.GitRemoteRemove(graceful.GetManager().ShutdownContext(), repo, tmpRemote); err != nil { + log.Error("getMergeBase: GitRemoteRemove: %v", err) } }() - mergeBase, _, err := repo.GetMergeBase(tmpRemote, baseBranch, headBranch) + mergeBase, _, err := gitRepo.GetMergeBase(tmpRemote, baseBranch, headBranch) return mergeBase, err } @@ -97,7 +99,7 @@ func PullRequestCodeOwnersReview(ctx context.Context, pr *issues_model.PullReque } // get the mergebase - mergeBase, err := getMergeBase(repo, pr, git.BranchPrefix+pr.BaseBranch, pr.GetGitHeadRefName()) + mergeBase, err := getMergeBase(ctx, pr.BaseRepo, repo, pr, git.BranchPrefix+pr.BaseBranch, pr.GetGitHeadRefName()) if err != nil { return nil, err } diff --git a/services/issue/reaction_test.go b/services/issue/reaction_test.go index 7734860fc0..bf2e554d41 100644 --- a/services/issue/reaction_test.go +++ b/services/issue/reaction_test.go @@ -6,7 +6,6 @@ package issue import ( "testing" - "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/models/unittest" @@ -20,9 +19,9 @@ func addReaction(t *testing.T, doer *user_model.User, issue *issues_model.Issue, var reaction *issues_model.Reaction var err error if comment == nil { - reaction, err = CreateIssueReaction(db.DefaultContext, doer, issue, content) + reaction, err = CreateIssueReaction(t.Context(), doer, issue, content) } else { - reaction, err = CreateCommentReaction(db.DefaultContext, doer, comment, content) + reaction, err = CreateCommentReaction(t.Context(), doer, comment, content) } assert.NoError(t, err) assert.NotNil(t, reaction) @@ -47,7 +46,7 @@ func TestIssueAddDuplicateReaction(t *testing.T) { addReaction(t, user1, issue, nil, "heart") - reaction, err := CreateIssueReaction(db.DefaultContext, user1, issue, "heart") + reaction, err := CreateIssueReaction(t.Context(), user1, issue, "heart") assert.Error(t, err) assert.Equal(t, issues_model.ErrReactionAlreadyExist{Reaction: "heart"}, err) @@ -63,7 +62,7 @@ func TestIssueDeleteReaction(t *testing.T) { addReaction(t, user1, issue, nil, "heart") - err := issues_model.DeleteIssueReaction(db.DefaultContext, user1.ID, issue.ID, "heart") + err := issues_model.DeleteIssueReaction(t.Context(), user1.ID, issue.ID, "heart") assert.NoError(t, err) unittest.AssertNotExistsBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue.ID}) @@ -91,12 +90,12 @@ func TestIssueReactionCount(t *testing.T) { addReaction(t, user4, issue, nil, "heart") addReaction(t, ghost, issue, nil, "-1") - reactionsList, _, err := issues_model.FindReactions(db.DefaultContext, issues_model.FindReactionsOptions{ + reactionsList, _, err := issues_model.FindReactions(t.Context(), issues_model.FindReactionsOptions{ IssueID: issue.ID, }) assert.NoError(t, err) assert.Len(t, reactionsList, 7) - _, err = reactionsList.LoadUsers(db.DefaultContext, repo) + _, err = reactionsList.LoadUsers(t.Context(), repo) assert.NoError(t, err) reactions := reactionsList.GroupByType() @@ -137,7 +136,7 @@ func TestIssueCommentDeleteReaction(t *testing.T) { addReaction(t, org3, nil, comment, "heart") addReaction(t, user4, nil, comment, "+1") - reactionsList, _, err := issues_model.FindReactions(db.DefaultContext, issues_model.FindReactionsOptions{ + reactionsList, _, err := issues_model.FindReactions(t.Context(), issues_model.FindReactionsOptions{ IssueID: comment.IssueID, CommentID: comment.ID, }) @@ -156,7 +155,7 @@ func TestIssueCommentReactionCount(t *testing.T) { comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 1}) addReaction(t, user1, nil, comment, "heart") - assert.NoError(t, issues_model.DeleteCommentReaction(db.DefaultContext, user1.ID, comment.IssueID, comment.ID, "heart")) + assert.NoError(t, issues_model.DeleteCommentReaction(t.Context(), user1.ID, comment.IssueID, comment.ID, "heart")) unittest.AssertNotExistsBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: comment.IssueID, CommentID: comment.ID}) } diff --git a/services/issue/suggestion_test.go b/services/issue/suggestion_test.go index a5b39d27bb..9b23e5aca3 100644 --- a/services/issue/suggestion_test.go +++ b/services/issue/suggestion_test.go @@ -6,7 +6,6 @@ package issue import ( "testing" - "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/optional" @@ -44,7 +43,7 @@ func Test_Suggestion(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.keyword, func(t *testing.T) { - issues, err := GetSuggestion(db.DefaultContext, repo1, testCase.isPull, testCase.keyword) + issues, err := GetSuggestion(t.Context(), repo1, testCase.isPull, testCase.keyword) assert.NoError(t, err) issueIndexes := make([]int64, 0, len(issues)) diff --git a/services/lfs/server.go b/services/lfs/server.go index c9d9f164bf..9f2e532f23 100644 --- a/services/lfs/server.go +++ b/services/lfs/server.go @@ -114,7 +114,7 @@ func DownloadHandler(ctx *context.Context) { } } - ctx.Resp.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", fromByte, toByte, meta.Size-fromByte)) + ctx.Resp.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", fromByte, toByte, meta.Size)) ctx.Resp.Header().Set("Access-Control-Expose-Headers", "Content-Range") } } diff --git a/services/mailer/mail_issue_common.go b/services/mailer/mail_issue_common.go index a34d8a68c9..d65e310288 100644 --- a/services/mailer/mail_issue_common.go +++ b/services/mailer/mail_issue_common.go @@ -56,9 +56,9 @@ func composeIssueCommentMessages(ctx context.Context, comment *mailComment, lang commentType := issues_model.CommentTypeComment if comment.Comment != nil { commentType = comment.Comment.Type - link = comment.Issue.HTMLURL() + "#" + comment.Comment.HashTag() + link = comment.Issue.HTMLURL(ctx) + "#" + comment.Comment.HashTag() } else { - link = comment.Issue.HTMLURL() + link = comment.Issue.HTMLURL(ctx) } reviewType := issues_model.ReviewTypeComment @@ -175,7 +175,7 @@ func composeIssueCommentMessages(ctx context.Context, comment *mailComment, lang msg.SetHeader("In-Reply-To", reference) references := []string{reference} - listUnsubscribe := []string{"<" + comment.Issue.HTMLURL() + ">"} + listUnsubscribe := []string{"<" + comment.Issue.HTMLURL(ctx) + ">"} if setting.IncomingEmail.Enabled { if replyPayload != nil { @@ -260,18 +260,18 @@ func actionToTemplate(issue *issues_model.Issue, actionType activities_model.Act } } - template = typeName + "/" + name + template = "repo/" + typeName + "/" + name ok := LoadedTemplates().BodyTemplates.Lookup(template) != nil if !ok && typeName != "issue" { - template = "issue/" + name + template = "repo/issue/" + name ok = LoadedTemplates().BodyTemplates.Lookup(template) != nil } if !ok { - template = typeName + "/default" + template = "repo/" + typeName + "/default" ok = LoadedTemplates().BodyTemplates.Lookup(template) != nil } if !ok { - template = "issue/default" + template = "repo/issue/default" } return typeName, name, template } @@ -313,7 +313,7 @@ func generateAdditionalHeadersForIssue(ctx *mailComment, reason string, recipien maps.Copy(headers, generateReasonHeaders(reason)) headers["X-Gitea-Issue-ID"] = issueID - headers["X-Gitea-Issue-Link"] = ctx.Issue.HTMLURL() + headers["X-Gitea-Issue-Link"] = ctx.Issue.HTMLURL(context.TODO()) // FIXME: use proper context headers["X-GitLab-Issue-IID"] = issueID return headers diff --git a/services/mailer/mail_release.go b/services/mailer/mail_release.go index fd97fb5312..248cf0ab90 100644 --- a/services/mailer/mail_release.go +++ b/services/mailer/mail_release.go @@ -19,7 +19,7 @@ import ( sender_service "code.gitea.io/gitea/services/mailer/sender" ) -const tplNewReleaseMail templates.TplName = "release" +const tplNewReleaseMail templates.TplName = "repo/release" func generateMessageIDForRelease(release *repo_model.Release) string { return fmt.Sprintf("<%s/releases/%d@%s>", release.Repo.FullName(), release.ID, setting.Domain) diff --git a/services/mailer/mail_repo.go b/services/mailer/mail_repo.go index 1ec7995ab9..b5fdfbf2e4 100644 --- a/services/mailer/mail_repo.go +++ b/services/mailer/mail_repo.go @@ -11,13 +11,17 @@ import ( "code.gitea.io/gitea/models/organization" 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/setting" "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/translation" sender_service "code.gitea.io/gitea/services/mailer/sender" ) -const mailRepoTransferNotify templates.TplName = "notify/repo_transfer" +const ( + mailNotifyCollaborator templates.TplName = "repo/collaborator" + mailRepoTransferNotify templates.TplName = "repo/transfer" +) // SendRepoTransferNotifyMail triggers a notification e-mail when a pending repository transfer was created func SendRepoTransferNotifyMail(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) error { @@ -91,3 +95,33 @@ func sendRepoTransferNotifyMailPerLang(lang string, newOwner, doer *user_model.U return nil } + +// SendCollaboratorMail sends mail notification to new collaborator. +func SendCollaboratorMail(u, doer *user_model.User, repo *repo_model.Repository) { + if setting.MailService == nil || !u.IsActive { + return + } + locale := translation.NewLocale(u.Language) + repoName := repo.FullName() + + subject := locale.TrString("mail.repo.collaborator.added.subject", doer.DisplayName(), repoName) + data := map[string]any{ + "locale": locale, + "Subject": subject, + "RepoName": repoName, + "Link": repo.HTMLURL(), + "Language": locale.Language(), + } + + var content bytes.Buffer + + if err := LoadedTemplates().BodyTemplates.ExecuteTemplate(&content, string(mailNotifyCollaborator), data); err != nil { + log.Error("Template: %v", err) + return + } + + msg := sender_service.NewMessage(u.EmailTo(), subject, content.String()) + msg.Info = fmt.Sprintf("UID: %d, add collaborator", u.ID) + + SendAsync(msg) +} diff --git a/services/mailer/mail_team_invite.go b/services/mailer/mail_team_invite.go index 034dc14e3d..4819f29942 100644 --- a/services/mailer/mail_team_invite.go +++ b/services/mailer/mail_team_invite.go @@ -19,7 +19,7 @@ import ( sender_service "code.gitea.io/gitea/services/mailer/sender" ) -const tplTeamInviteMail templates.TplName = "team_invite" +const tplTeamInviteMail templates.TplName = "org/team_invite" // MailTeamInvite sends team invites func MailTeamInvite(ctx context.Context, inviter *user_model.User, team *org_model.Team, invite *org_model.TeamInvite) error { diff --git a/services/mailer/mail_test.go b/services/mailer/mail_test.go index 24f5d39d50..8a4a589357 100644 --- a/services/mailer/mail_test.go +++ b/services/mailer/mail_test.go @@ -18,7 +18,6 @@ import ( actions_model "code.gitea.io/gitea/models/actions" 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" "code.gitea.io/gitea/models/unittest" @@ -68,7 +67,7 @@ func prepareMailerTest(t *testing.T) (doer *user_model.User, repo *repo_model.Re repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1, Owner: doer}) issue = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1, Repo: repo, Poster: doer}) comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2, Issue: issue}) - require.NoError(t, issue.LoadRepo(db.DefaultContext)) + require.NoError(t, issue.LoadRepo(t.Context())) return doer, repo, issue, comment } @@ -116,7 +115,7 @@ func TestComposeIssueComment(t *testing.T) { setting.IncomingEmail.Enabled = true defer func() { setting.IncomingEmail.Enabled = false }() - prepareMailTemplates("issue/comment", subjectTpl, bodyTpl) + prepareMailTemplates("repo/issue/comment", subjectTpl, bodyTpl) recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}, {Name: "Test2", Email: "test2@gitea.com"}} msgs, err := composeIssueCommentMessages(t.Context(), &mailComment{ @@ -150,18 +149,18 @@ func TestComposeIssueComment(t *testing.T) { assert.NoError(t, err) // text/plain - assert.Contains(t, string(b), fmt.Sprintf(`( %s )`, doer.HTMLURL())) - assert.Contains(t, string(b), fmt.Sprintf(`( %s )`, issue.HTMLURL())) + assert.Contains(t, string(b), fmt.Sprintf(`( %s )`, doer.HTMLURL(t.Context()))) + assert.Contains(t, string(b), fmt.Sprintf(`( %s )`, issue.HTMLURL(t.Context()))) // text/html - assert.Contains(t, string(b), fmt.Sprintf(`href="%s"`, doer.HTMLURL())) - assert.Contains(t, string(b), fmt.Sprintf(`href="%s"`, issue.HTMLURL())) + assert.Contains(t, string(b), fmt.Sprintf(`href="%s"`, doer.HTMLURL(t.Context()))) + assert.Contains(t, string(b), fmt.Sprintf(`href="%s"`, issue.HTMLURL(t.Context()))) } func TestMailMentionsComment(t *testing.T) { doer, _, issue, comment := prepareMailerTest(t) comment.Poster = doer - prepareMailTemplates("issue/comment", subjectTpl, bodyTpl) + prepareMailTemplates("repo/issue/comment", subjectTpl, bodyTpl) mails := 0 defer test.MockVariableValue(&SendAsync, func(msgs ...*sender_service.Message) { @@ -176,7 +175,7 @@ func TestMailMentionsComment(t *testing.T) { func TestComposeIssueMessage(t *testing.T) { doer, _, issue, _ := prepareMailerTest(t) - prepareMailTemplates("issue/new", subjectTpl, bodyTpl) + prepareMailTemplates("repo/issue/new", subjectTpl, bodyTpl) recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}, {Name: "Test2", Email: "test2@gitea.com"}} msgs, err := composeIssueCommentMessages(t.Context(), &mailComment{ Issue: issue, Doer: doer, ActionType: activities_model.ActionCreateIssue, @@ -205,14 +204,14 @@ func TestTemplateSelection(t *testing.T) { doer, repo, issue, comment := prepareMailerTest(t) recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}} - prepareMailTemplates("issue/default", "issue/default/subject", "issue/default/body") + prepareMailTemplates("repo/issue/default", "repo/issue/default/subject", "repo/issue/default/body") - texttmpl.Must(LoadedTemplates().SubjectTemplates.New("issue/new").Parse("issue/new/subject")) - texttmpl.Must(LoadedTemplates().SubjectTemplates.New("pull/comment").Parse("pull/comment/subject")) - texttmpl.Must(LoadedTemplates().SubjectTemplates.New("issue/close").Parse("")) // Must default to a fallback subject - template.Must(LoadedTemplates().BodyTemplates.New("issue/new").Parse("issue/new/body")) - template.Must(LoadedTemplates().BodyTemplates.New("pull/comment").Parse("pull/comment/body")) - template.Must(LoadedTemplates().BodyTemplates.New("issue/close").Parse("issue/close/body")) + texttmpl.Must(LoadedTemplates().SubjectTemplates.New("repo/issue/new").Parse("repo/issue/new/subject")) + texttmpl.Must(LoadedTemplates().SubjectTemplates.New("repo/pull/comment").Parse("repo/pull/comment/subject")) + texttmpl.Must(LoadedTemplates().SubjectTemplates.New("repo/issue/close").Parse("")) // Must default to a fallback subject + template.Must(LoadedTemplates().BodyTemplates.New("repo/issue/new").Parse("repo/issue/new/body")) + template.Must(LoadedTemplates().BodyTemplates.New("repo/pull/comment").Parse("repo/pull/comment/body")) + template.Must(LoadedTemplates().BodyTemplates.New("repo/issue/close").Parse("repo/issue/close/body")) expect := func(t *testing.T, msg *sender_service.Message, expSubject, expBody string) { subject := msg.ToMessage().GetGenHeader("Subject") @@ -227,13 +226,13 @@ func TestTemplateSelection(t *testing.T) { Issue: issue, Doer: doer, ActionType: activities_model.ActionCreateIssue, Content: "test body", }, recipients, false, "TestTemplateSelection") - expect(t, msg, "issue/new/subject", "issue/new/body") + expect(t, msg, "repo/issue/new/subject", "repo/issue/new/body") msg = testComposeIssueCommentMessage(t, &mailComment{ 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") + expect(t, msg, "repo/issue/default/subject", "repo/issue/default/body") pull := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2, Repo: repo, Poster: doer}) comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 4, Issue: pull}) @@ -241,23 +240,23 @@ func TestTemplateSelection(t *testing.T) { 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") + expect(t, msg, "repo/pull/comment/subject", "repo/pull/comment/body") msg = testComposeIssueCommentMessage(t, &mailComment{ 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") + expect(t, msg, "Re: [user2/repo1] issue1 (#1)", "repo/issue/close/body") } func TestTemplateServices(t *testing.T) { doer, _, issue, comment := prepareMailerTest(t) - assert.NoError(t, issue.LoadRepo(db.DefaultContext)) + assert.NoError(t, issue.LoadRepo(t.Context())) expect := func(t *testing.T, issue *issues_model.Issue, comment *issues_model.Comment, doer *user_model.User, actionType activities_model.ActionType, fromMention bool, tplSubject, tplBody, expSubject, expBody string, ) { - prepareMailTemplates("issue/default", tplSubject, tplBody) + prepareMailTemplates("repo/issue/default", tplSubject, tplBody) recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}} msg := testComposeIssueCommentMessage(t, &mailComment{ Issue: issue, Doer: doer, ActionType: actionType, @@ -447,7 +446,7 @@ func TestGenerateMessageIDForActionsWorkflowRunStatusEmail(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{ID: 795, RepoID: repo.ID}) - assert.NoError(t, run.LoadAttributes(db.DefaultContext)) + assert.NoError(t, run.LoadAttributes(t.Context())) msgID := generateMessageIDForActionsWorkflowRunStatusEmail(repo, run) assert.Equal(t, "", msgID) } @@ -524,7 +523,7 @@ func TestEmbedBase64Images(t *testing.T) { att2ImgBase64 := fmt.Sprintf(``, att2Base64) t.Run("ComposeMessage", func(t *testing.T) { - prepareMailTemplates("issue/new", subjectTpl, bodyTpl) + prepareMailTemplates("repo/issue/new", subjectTpl, bodyTpl) issue.Content = fmt.Sprintf(`MSG-BEFORE MSG-AFTER`, att1.UUID) require.NoError(t, issues_model.UpdateIssueCols(t.Context(), issue, "content")) diff --git a/services/mailer/mail_user.go b/services/mailer/mail_user.go index 68df81f6a3..867a8b2a8f 100644 --- a/services/mailer/mail_user.go +++ b/services/mailer/mail_user.go @@ -7,7 +7,6 @@ import ( "bytes" "fmt" - 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/setting" @@ -18,11 +17,10 @@ import ( ) const ( - mailAuthActivate templates.TplName = "auth/activate" - mailAuthActivateEmail templates.TplName = "auth/activate_email" - mailAuthResetPassword templates.TplName = "auth/reset_passwd" - mailAuthRegisterNotify templates.TplName = "auth/register_notify" - mailNotifyCollaborator templates.TplName = "notify/collaborator" + mailAuthActivate templates.TplName = "user/auth/activate" + mailAuthActivateEmail templates.TplName = "user/auth/activate_email" + mailAuthResetPassword templates.TplName = "user/auth/reset_passwd" + mailAuthRegisterNotify templates.TplName = "user/auth/register_notify" ) // sendUserMail sends a mail to the user @@ -128,34 +126,3 @@ func SendRegisterNotifyMail(u *user_model.User) { SendAsync(msg) } - -// SendCollaboratorMail sends mail notification to new collaborator. -func SendCollaboratorMail(u, doer *user_model.User, repo *repo_model.Repository) { - if setting.MailService == nil || !u.IsActive { - // No mail service configured OR the user is inactive - return - } - locale := translation.NewLocale(u.Language) - repoName := repo.FullName() - - subject := locale.TrString("mail.repo.collaborator.added.subject", doer.DisplayName(), repoName) - data := map[string]any{ - "locale": locale, - "Subject": subject, - "RepoName": repoName, - "Link": repo.HTMLURL(), - "Language": locale.Language(), - } - - var content bytes.Buffer - - if err := LoadedTemplates().BodyTemplates.ExecuteTemplate(&content, string(mailNotifyCollaborator), data); err != nil { - log.Error("Template: %v", err) - return - } - - msg := sender_service.NewMessage(u.EmailTo(), subject, content.String()) - msg.Info = fmt.Sprintf("UID: %d, add collaborator", u.ID) - - SendAsync(msg) -} diff --git a/services/mailer/mail_workflow_run.go b/services/mailer/mail_workflow_run.go index 29b3abda8e..3789102812 100644 --- a/services/mailer/mail_workflow_run.go +++ b/services/mailer/mail_workflow_run.go @@ -8,6 +8,7 @@ import ( "context" "fmt" "sort" + "time" actions_model "code.gitea.io/gitea/models/actions" repo_model "code.gitea.io/gitea/models/repo" @@ -15,44 +16,51 @@ import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/translation" "code.gitea.io/gitea/services/convert" sender_service "code.gitea.io/gitea/services/mailer/sender" ) -const tplWorkflowRun = "notify/workflow_run" +const tplWorkflowRun templates.TplName = "repo/actions/workflow_run" type convertedWorkflowJob struct { - HTMLURL string - Status actions_model.Status - Name string - Attempt int64 + HTMLURL string + Name string + Status actions_model.Status + Attempt int64 + Duration time.Duration } func generateMessageIDForActionsWorkflowRunStatusEmail(repo *repo_model.Repository, run *actions_model.ActionRun) string { return fmt.Sprintf("<%s/actions/runs/%d@%s>", repo.FullName(), run.Index, setting.Domain) } -func composeAndSendActionsWorkflowRunStatusEmail(ctx context.Context, repo *repo_model.Repository, run *actions_model.ActionRun, sender *user_model.User, recipients []*user_model.User) { - subject := "Run" +func composeAndSendActionsWorkflowRunStatusEmail(ctx context.Context, repo *repo_model.Repository, run *actions_model.ActionRun, sender *user_model.User, recipients []*user_model.User) error { + jobs, err := actions_model.GetRunJobsByRunID(ctx, run.ID) + if err != nil { + return err + } + for _, job := range jobs { + if !job.Status.IsDone() { + log.Debug("composeAndSendActionsWorkflowRunStatusEmail: A job is not done. Will not compose and send actions email.") + return nil + } + } + + var subjectTrString string switch run.Status { case actions_model.StatusFailure: - subject += " failed" + subjectTrString = "mail.repo.actions.run.failed" case actions_model.StatusCancelled: - subject += " cancelled" + subjectTrString = "mail.repo.actions.run.cancelled" case actions_model.StatusSuccess: - subject += " succeeded" + subjectTrString = "mail.repo.actions.run.succeeded" } - subject = fmt.Sprintf("%s: %s (%s)", subject, run.WorkflowID, base.ShortSha(run.CommitSHA)) displayName := fromDisplayName(sender) messageID := generateMessageIDForActionsWorkflowRunStatusEmail(repo, run) metadataHeaders := generateMetadataHeaders(repo) - jobs, err := actions_model.GetRunJobsByRunID(ctx, run.ID) - if err != nil { - log.Error("GetRunJobsByRunID: %v", err) - return - } sort.SliceStable(jobs, func(i, j int) bool { si, sj := jobs[i].Status, jobs[j].Status /* @@ -74,10 +82,11 @@ func composeAndSendActionsWorkflowRunStatusEmail(ctx context.Context, repo *repo continue } convertedJobs = append(convertedJobs, convertedWorkflowJob{ - HTMLURL: converted0.HTMLURL, - Name: converted0.Name, - Status: job.Status, - Attempt: converted0.RunAttempt, + HTMLURL: converted0.HTMLURL, + Name: converted0.Name, + Status: job.Status, + Attempt: converted0.RunAttempt, + Duration: job.Duration(), }) } @@ -87,35 +96,36 @@ func composeAndSendActionsWorkflowRunStatusEmail(ctx context.Context, repo *repo } for lang, tos := range langMap { locale := translation.NewLocale(lang) - var runStatusText string + var runStatusTrString string switch run.Status { case actions_model.StatusSuccess: - runStatusText = "All jobs have succeeded" + runStatusTrString = "mail.repo.actions.jobs.all_succeeded" case actions_model.StatusFailure: - runStatusText = "All jobs have failed" + runStatusTrString = "mail.repo.actions.jobs.all_failed" for _, job := range jobs { if !job.Status.IsFailure() { - runStatusText = "Some jobs were not successful" + runStatusTrString = "mail.repo.actions.jobs.some_not_successful" break } } case actions_model.StatusCancelled: - runStatusText = "All jobs have been cancelled" + runStatusTrString = "mail.repo.actions.jobs.all_cancelled" } + subject := fmt.Sprintf("%s: %s (%s)", locale.TrString(subjectTrString), run.WorkflowID, base.ShortSha(run.CommitSHA)) var mailBody bytes.Buffer - if err := LoadedTemplates().BodyTemplates.ExecuteTemplate(&mailBody, tplWorkflowRun, map[string]any{ + if err := LoadedTemplates().BodyTemplates.ExecuteTemplate(&mailBody, string(tplWorkflowRun), map[string]any{ "Subject": subject, "Repo": repo, "Run": run, - "RunStatusText": runStatusText, + "RunStatusText": locale.TrString(runStatusTrString), "Jobs": convertedJobs, "locale": locale, }); err != nil { - log.Error("ExecuteTemplate [%s]: %v", tplWorkflowRun, err) - return + return err } msgs := make([]*sender_service.Message, 0, len(tos)) for _, rec := range tos { + log.Trace("Sending actions email to %s (UID: %d)", rec.Name, rec.ID) msg := sender_service.NewMessageFrom( rec.Email, displayName, @@ -135,14 +145,16 @@ func composeAndSendActionsWorkflowRunStatusEmail(ctx context.Context, repo *repo } SendAsync(msgs...) } + + return nil } -func MailActionsTrigger(ctx context.Context, sender *user_model.User, repo *repo_model.Repository, run *actions_model.ActionRun) { +func MailActionsTrigger(ctx context.Context, sender *user_model.User, repo *repo_model.Repository, run *actions_model.ActionRun) error { if setting.MailService == nil { - return + return nil } - if run.Status.IsSkipped() { - return + if !run.Status.IsDone() || run.Status.IsSkipped() { + return nil } recipients := make([]*user_model.User, 0) @@ -151,8 +163,7 @@ func MailActionsTrigger(ctx context.Context, sender *user_model.User, repo *repo notifyPref, err := user_model.GetUserSetting(ctx, sender.ID, user_model.SettingsKeyEmailNotificationGiteaActions, user_model.SettingEmailNotificationGiteaActionsFailureOnly) if err != nil { - log.Error("GetUserSetting: %v", err) - return + return err } if notifyPref == user_model.SettingEmailNotificationGiteaActionsAll || !run.Status.IsSuccess() && notifyPref != user_model.SettingEmailNotificationGiteaActionsDisabled { recipients = append(recipients, sender) @@ -160,6 +171,8 @@ func MailActionsTrigger(ctx context.Context, sender *user_model.User, repo *repo } if len(recipients) > 0 { - composeAndSendActionsWorkflowRunStatusEmail(ctx, repo, run, sender, recipients) + log.Debug("MailActionsTrigger: Initiate email composition") + return composeAndSendActionsWorkflowRunStatusEmail(ctx, repo, run, sender, recipients) } + return nil } diff --git a/services/mailer/notify.go b/services/mailer/notify.go index c008685e13..5921021ce8 100644 --- a/services/mailer/notify.go +++ b/services/mailer/notify.go @@ -128,7 +128,7 @@ func (m *mailNotifier) IssueChangeAssignee(ctx context.Context, doer *user_model func (m *mailNotifier) PullRequestReviewRequest(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) { if isRequest && doer.ID != reviewer.ID && reviewer.EmailNotificationsPreference != user_model.EmailNotificationsDisabled { - ct := fmt.Sprintf("Requested to review %s.", issue.HTMLURL()) + ct := fmt.Sprintf("Requested to review %s.", issue.HTMLURL(ctx)) if err := SendIssueAssignedMail(ctx, issue, doer, ct, comment, []*user_model.User{reviewer}); err != nil { log.Error("Error in SendIssueAssignedMail for issue[%d] to reviewer[%d]: %v", issue.ID, reviewer.ID, err) } @@ -208,8 +208,7 @@ func (m *mailNotifier) RepoPendingTransfer(ctx context.Context, doer, newOwner * } func (m *mailNotifier) WorkflowRunStatusUpdate(ctx context.Context, repo *repo_model.Repository, sender *user_model.User, run *actions_model.ActionRun) { - if !run.Status.IsDone() { - return + if err := MailActionsTrigger(ctx, sender, repo, run); err != nil { + log.Error("MailActionsTrigger: %v", err) } - MailActionsTrigger(ctx, sender, repo, run) } diff --git a/services/markup/renderhelper_mention_test.go b/services/markup/renderhelper_mention_test.go index d54ab13a48..11aa7b2132 100644 --- a/services/markup/renderhelper_mention_test.go +++ b/services/markup/renderhelper_mention_test.go @@ -8,7 +8,6 @@ import ( "net/http/httptest" "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/user" gitea_context "code.gitea.io/gitea/services/context" @@ -45,7 +44,7 @@ func TestRenderHelperMention(t *testing.T) { assert.True(t, FormalRenderHelperFuncs().IsUsernameMentionable(giteaCtx, userPublic)) assert.False(t, FormalRenderHelperFuncs().IsUsernameMentionable(giteaCtx, userPrivate)) - giteaCtx.Doer, err = user.GetUserByName(db.DefaultContext, userPrivate) + giteaCtx.Doer, err = user.GetUserByName(t.Context(), userPrivate) assert.NoError(t, err) assert.True(t, FormalRenderHelperFuncs().IsUsernameMentionable(giteaCtx, userPublic)) assert.True(t, FormalRenderHelperFuncs().IsUsernameMentionable(giteaCtx, userPrivate)) diff --git a/services/migrations/error.go b/services/migrations/error.go index 9b470149bf..2dd9647d95 100644 --- a/services/migrations/error.go +++ b/services/migrations/error.go @@ -7,7 +7,7 @@ package migrations import ( "errors" - "github.com/google/go-github/v71/github" + "github.com/google/go-github/v74/github" ) // ErrRepoNotCreated returns the error that repository not created diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go index 1970c0550c..4856b66c6e 100644 --- a/services/migrations/gitea_uploader_test.go +++ b/services/migrations/gitea_uploader_test.go @@ -45,7 +45,7 @@ func TestGiteaUploadRepo(t *testing.T) { uploader = NewGiteaLocalUploader(graceful.GetManager().HammerContext(), user, user.Name, repoName) ) - err := migrateRepository(db.DefaultContext, user, downloader, uploader, base.MigrateOptions{ + err := migrateRepository(t.Context(), user, downloader, uploader, base.MigrateOptions{ CloneAddr: "https://github.com/go-xorm/builder", RepoName: repoName, AuthUsername: "", @@ -63,17 +63,17 @@ func TestGiteaUploadRepo(t *testing.T) { assert.NoError(t, err) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, Name: repoName}) - assert.True(t, repo.HasWiki()) + assert.True(t, repo_service.HasWiki(ctx, repo)) assert.Equal(t, repo_model.RepositoryReady, repo.Status) - milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + milestones, err := db.Find[issues_model.Milestone](t.Context(), issues_model.FindMilestoneOptions{ RepoID: repo.ID, IsClosed: optional.Some(false), }) assert.NoError(t, err) assert.Len(t, milestones, 1) - milestones, err = db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + milestones, err = db.Find[issues_model.Milestone](t.Context(), issues_model.FindMilestoneOptions{ RepoID: repo.ID, IsClosed: optional.Some(true), }) @@ -84,7 +84,7 @@ func TestGiteaUploadRepo(t *testing.T) { assert.NoError(t, err) assert.Len(t, labels, 12) - releases, err := db.Find[repo_model.Release](db.DefaultContext, repo_model.FindReleasesOptions{ + releases, err := db.Find[repo_model.Release](t.Context(), repo_model.FindReleasesOptions{ ListOptions: db.ListOptions{ PageSize: 10, Page: 0, @@ -95,7 +95,7 @@ func TestGiteaUploadRepo(t *testing.T) { assert.NoError(t, err) assert.Len(t, releases, 8) - releases, err = db.Find[repo_model.Release](db.DefaultContext, repo_model.FindReleasesOptions{ + releases, err = db.Find[repo_model.Release](t.Context(), repo_model.FindReleasesOptions{ ListOptions: db.ListOptions{ PageSize: 10, Page: 0, @@ -106,23 +106,23 @@ func TestGiteaUploadRepo(t *testing.T) { assert.NoError(t, err) assert.Len(t, releases, 1) - issues, err := issues_model.Issues(db.DefaultContext, &issues_model.IssuesOptions{ + issues, err := issues_model.Issues(t.Context(), &issues_model.IssuesOptions{ RepoIDs: []int64{repo.ID}, IsPull: optional.Some(false), SortType: "oldest", }) assert.NoError(t, err) assert.Len(t, issues, 15) - assert.NoError(t, issues[0].LoadDiscussComments(db.DefaultContext)) + assert.NoError(t, issues[0].LoadDiscussComments(t.Context())) assert.Empty(t, issues[0].Comments) - pulls, _, err := issues_model.PullRequests(db.DefaultContext, repo.ID, &issues_model.PullRequestsOptions{ + pulls, _, err := issues_model.PullRequests(t.Context(), repo.ID, &issues_model.PullRequestsOptions{ SortType: "oldest", }) assert.NoError(t, err) assert.Len(t, pulls, 30) - assert.NoError(t, pulls[0].LoadIssue(db.DefaultContext)) - assert.NoError(t, pulls[0].Issue.LoadDiscussComments(db.DefaultContext)) + assert.NoError(t, pulls[0].LoadIssue(t.Context())) + assert.NoError(t, pulls[0].Issue.LoadDiscussComments(t.Context())) assert.Len(t, pulls[0].Issue.Comments, 2) } @@ -214,7 +214,7 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) { LoginSourceID: 0, Provider: structs.GiteaService.Name(), } - err = user_model.LinkExternalToUser(db.DefaultContext, linkedUser, externalLoginUser) + err = user_model.LinkExternalToUser(t.Context(), linkedUser, externalLoginUser) assert.NoError(t, err) // @@ -236,22 +236,23 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { // fromRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) baseRef := "master" - assert.NoError(t, git.InitRepository(git.DefaultContext, fromRepo.RepoPath(), false, fromRepo.ObjectFormatName)) - err := git.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseRef).Run(git.DefaultContext, &git.RunOpts{Dir: fromRepo.RepoPath()}) + // this is very different from the real situation. It should be a bare repository for all the Gitea managed repositories + assert.NoError(t, git.InitRepository(t.Context(), fromRepo.RepoPath(), false, fromRepo.ObjectFormatName)) + err := git.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseRef).Run(t.Context(), &git.RunOpts{Dir: fromRepo.RepoPath()}) assert.NoError(t, err) assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte("# Testing Repository\n\nOriginally created in: "+fromRepo.RepoPath()), 0o644)) - assert.NoError(t, git.AddChanges(fromRepo.RepoPath(), true)) + assert.NoError(t, git.AddChanges(t.Context(), fromRepo.RepoPath(), true)) signature := git.Signature{ Email: "test@example.com", Name: "test", When: time.Now(), } - assert.NoError(t, git.CommitChanges(fromRepo.RepoPath(), git.CommitChangesOptions{ + assert.NoError(t, git.CommitChanges(t.Context(), fromRepo.RepoPath(), git.CommitChangesOptions{ Committer: &signature, Author: &signature, Message: "Initial Commit", })) - fromGitRepo, err := gitrepo.OpenRepository(git.DefaultContext, fromRepo) + fromGitRepo, err := gitrepo.OpenRepository(t.Context(), fromRepo) assert.NoError(t, err) defer fromGitRepo.Close() baseSHA, err := fromGitRepo.GetBranchCommitID(baseRef) @@ -261,12 +262,12 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { // fromRepo branch1 // headRef := "branch1" - _, _, err = git.NewCommand("checkout", "-b").AddDynamicArguments(headRef).RunStdString(git.DefaultContext, &git.RunOpts{Dir: fromRepo.RepoPath()}) + _, _, err = git.NewCommand("checkout", "-b").AddDynamicArguments(headRef).RunStdString(t.Context(), &git.RunOpts{Dir: fromRepo.RepoPath()}) assert.NoError(t, err) assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte("SOMETHING"), 0o644)) - assert.NoError(t, git.AddChanges(fromRepo.RepoPath(), true)) + assert.NoError(t, git.AddChanges(t.Context(), fromRepo.RepoPath(), true)) signature.When = time.Now() - assert.NoError(t, git.CommitChanges(fromRepo.RepoPath(), git.CommitChangesOptions{ + assert.NoError(t, git.CommitChanges(t.Context(), fromRepo.RepoPath(), git.CommitChangesOptions{ Committer: &signature, Author: &signature, Message: "Pull request", @@ -282,19 +283,19 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { // forkHeadRef := "branch2" forkRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8}) - assert.NoError(t, git.CloneWithArgs(git.DefaultContext, nil, fromRepo.RepoPath(), forkRepo.RepoPath(), git.CloneRepoOptions{ + assert.NoError(t, git.Clone(t.Context(), fromRepo.RepoPath(), forkRepo.RepoPath(), git.CloneRepoOptions{ Branch: headRef, })) - _, _, err = git.NewCommand("checkout", "-b").AddDynamicArguments(forkHeadRef).RunStdString(git.DefaultContext, &git.RunOpts{Dir: forkRepo.RepoPath()}) + _, _, err = git.NewCommand("checkout", "-b").AddDynamicArguments(forkHeadRef).RunStdString(t.Context(), &git.RunOpts{Dir: forkRepo.RepoPath()}) assert.NoError(t, err) assert.NoError(t, os.WriteFile(filepath.Join(forkRepo.RepoPath(), "README.md"), []byte("# branch2 "+forkRepo.RepoPath()), 0o644)) - assert.NoError(t, git.AddChanges(forkRepo.RepoPath(), true)) - assert.NoError(t, git.CommitChanges(forkRepo.RepoPath(), git.CommitChangesOptions{ + assert.NoError(t, git.AddChanges(t.Context(), forkRepo.RepoPath(), true)) + assert.NoError(t, git.CommitChanges(t.Context(), forkRepo.RepoPath(), git.CommitChangesOptions{ Committer: &signature, Author: &signature, Message: "branch2 commit", })) - forkGitRepo, err := gitrepo.OpenRepository(git.DefaultContext, forkRepo) + forkGitRepo, err := gitrepo.OpenRepository(t.Context(), forkRepo) assert.NoError(t, err) defer forkGitRepo.Close() forkHeadSHA, err := forkGitRepo.GetBranchCommitID(forkHeadRef) diff --git a/services/migrations/github.go b/services/migrations/github.go index c6cd6ea173..ae7350c016 100644 --- a/services/migrations/github.go +++ b/services/migrations/github.go @@ -20,7 +20,7 @@ import ( "code.gitea.io/gitea/modules/proxy" "code.gitea.io/gitea/modules/structs" - "github.com/google/go-github/v71/github" + "github.com/google/go-github/v74/github" "golang.org/x/oauth2" ) @@ -354,7 +354,8 @@ func (g *GithubDownloaderV3) convertGithubRelease(ctx context.Context, rel *gith // Prevent open redirect if !hasBaseURL(redirectURL, g.baseURL) && - !hasBaseURL(redirectURL, "https://objects.githubusercontent.com/") { + !hasBaseURL(redirectURL, "https://objects.githubusercontent.com/") && + !hasBaseURL(redirectURL, "https://release-assets.githubusercontent.com/") { WarnAndNotice("Unexpected AssetURL for assetID[%d] in %s: %s", asset.GetID(), g, redirectURL) return io.NopCloser(strings.NewReader(redirectURL)), nil diff --git a/services/migrations/gitlab.go b/services/migrations/gitlab.go index a19a04bc44..260fa9cd5d 100644 --- a/services/migrations/gitlab.go +++ b/services/migrations/gitlab.go @@ -50,7 +50,7 @@ func (f *GitlabDownloaderFactory) New(ctx context.Context, opts base.MigrateOpti log.Trace("Create gitlab downloader. BaseURL: %s RepoName: %s", baseURL, repoNameSpace) - return NewGitlabDownloader(ctx, baseURL, repoNameSpace, opts.AuthUsername, opts.AuthPassword, opts.AuthToken) + return NewGitlabDownloader(ctx, baseURL, repoNameSpace, opts.AuthToken) } // GitServiceType returns the type of git service @@ -93,14 +93,8 @@ type GitlabDownloader struct { // // 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) { +func NewGitlabDownloader(ctx context.Context, baseURL, repoPath, 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 - // Basic auth will fail with empty strings, but empty token will allow anonymous public API usage - if token == "" && password != "" { - gitlabClient, err = gitlab.NewBasicAuthClient(username, password, gitlab.WithBaseURL(baseURL), gitlab.WithHTTPClient(NewMigrationHTTPClient())) - } - if err != nil { log.Trace("Error logging into gitlab: %v", err) return nil, err @@ -206,7 +200,7 @@ func (g *GitlabDownloader) GetTopics(ctx context.Context) ([]string, error) { if err != nil { return nil, err } - return gr.TagList, err + return gr.Topics, err } // GetMilestones returns milestones diff --git a/services/migrations/gitlab_test.go b/services/migrations/gitlab_test.go index 73a1b6a276..a9ae89a2a3 100644 --- a/services/migrations/gitlab_test.go +++ b/services/migrations/gitlab_test.go @@ -31,7 +31,7 @@ func TestGitlabDownloadRepo(t *testing.T) { t.Skipf("Can't access test repo, skipping %s", t.Name()) } ctx := t.Context() - downloader, err := NewGitlabDownloader(ctx, "https://gitlab.com", "gitea/test_repo", "", "", gitlabPersonalAccessToken) + downloader, err := NewGitlabDownloader(ctx, "https://gitlab.com", "gitea/test_repo", gitlabPersonalAccessToken) if err != nil { t.Fatalf("NewGitlabDownloader is nil: %v", err) } diff --git a/services/migrations/onedev.go b/services/migrations/onedev.go index e052cba0cc..9917bdae3c 100644 --- a/services/migrations/onedev.go +++ b/services/migrations/onedev.go @@ -6,6 +6,7 @@ package migrations import ( "context" "fmt" + "io" "net/http" "net/url" "strconv" @@ -16,8 +17,12 @@ import ( "code.gitea.io/gitea/modules/log" base "code.gitea.io/gitea/modules/migration" "code.gitea.io/gitea/modules/structs" + + "github.com/hashicorp/go-version" ) +const OneDevRequiredVersion = "12.0.1" + var ( _ base.Downloader = &OneDevDownloader{} _ base.DownloaderFactory = &OneDevDownloaderFactory{} @@ -37,23 +42,14 @@ func (f *OneDevDownloaderFactory) New(ctx context.Context, opts base.MigrateOpti return nil, err } - var repoName string - - fields := strings.Split(strings.Trim(u.Path, "/"), "/") - if len(fields) == 2 && fields[0] == "projects" { - repoName = fields[1] - } else if len(fields) == 1 { - repoName = fields[0] - } else { - return nil, fmt.Errorf("invalid path: %s", u.Path) - } + repoPath := strings.Trim(u.Path, "/") u.Path = "" u.Fragment = "" - log.Trace("Create onedev downloader. BaseURL: %v RepoName: %s", u, repoName) + log.Trace("Create onedev downloader. BaseURL: %v RepoPath: %s", u, repoPath) - return NewOneDevDownloader(ctx, u, opts.AuthUsername, opts.AuthPassword, repoName), nil + return NewOneDevDownloader(ctx, u, opts.AuthUsername, opts.AuthPassword, repoPath), nil } // GitServiceType returns the type of git service @@ -62,9 +58,9 @@ func (f *OneDevDownloaderFactory) GitServiceType() structs.GitServiceType { } type onedevUser struct { - ID int64 `json:"id"` - Name string `json:"name"` - Email string `json:"email"` + ID int64 + Name string + Email string } // OneDevDownloader implements a Downloader interface to get repository information @@ -73,7 +69,7 @@ type OneDevDownloader struct { base.NullDownloader client *http.Client baseURL *url.URL - repoName string + repoPath string repoID int64 maxIssueIndex int64 userMap map[int64]*onedevUser @@ -81,10 +77,10 @@ type OneDevDownloader struct { } // NewOneDevDownloader creates a new downloader -func NewOneDevDownloader(_ context.Context, baseURL *url.URL, username, password, repoName string) *OneDevDownloader { +func NewOneDevDownloader(_ context.Context, baseURL *url.URL, username, password, repoPath string) *OneDevDownloader { downloader := &OneDevDownloader{ baseURL: baseURL, - repoName: repoName, + repoPath: repoPath, client: &http.Client{ Transport: &http.Transport{ Proxy: func(req *http.Request) (*url.URL, error) { @@ -104,14 +100,14 @@ func NewOneDevDownloader(_ context.Context, baseURL *url.URL, username, password // String implements Stringer func (d *OneDevDownloader) String() string { - return fmt.Sprintf("migration from oneDev server %s [%d]/%s", d.baseURL, d.repoID, d.repoName) + return fmt.Sprintf("migration from oneDev server %s [%d]/%s", d.baseURL, d.repoID, d.repoPath) } func (d *OneDevDownloader) LogString() string { if d == nil { return "" } - return fmt.Sprintf("", d.baseURL, d.repoID, d.repoName) + return fmt.Sprintf("", d.baseURL, d.repoID, d.repoPath) } func (d *OneDevDownloader) callAPI(ctx context.Context, endpoint string, parameter map[string]string, result any) error { @@ -139,23 +135,54 @@ func (d *OneDevDownloader) callAPI(ctx context.Context, endpoint string, paramet } defer resp.Body.Close() + // special case to read OneDev server version, which is not valid JSON + if presult, ok := result.(**version.Version); ok { + bytes, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + vers, err := version.NewVersion(string(bytes)) + if err != nil { + return err + } + *presult = vers + return nil + } + decoder := json.NewDecoder(resp.Body) return decoder.Decode(&result) } // GetRepoInfo returns repository information func (d *OneDevDownloader) GetRepoInfo(ctx context.Context) (*base.Repository, error) { + // check OneDev server version + var serverVersion *version.Version + err := d.callAPI( + ctx, + "/~api/version/server", + nil, + &serverVersion, + ) + if err != nil { + return nil, fmt.Errorf("failed to get OneDev server version; OneDev %s or newer required", OneDevRequiredVersion) + } + requiredVersion, _ := version.NewVersion(OneDevRequiredVersion) + if serverVersion.LessThan(requiredVersion) { + return nil, fmt.Errorf("OneDev %s or newer required; currently running OneDev %s", OneDevRequiredVersion, serverVersion) + } + info := make([]struct { ID int64 `json:"id"` Name string `json:"name"` + Path string `json:"path"` Description string `json:"description"` }, 0, 1) - err := d.callAPI( + err = d.callAPI( ctx, - "/api/projects", + "/~api/projects", map[string]string{ - "query": `"Name" is "` + d.repoName + `"`, + "query": `"Path" is "` + d.repoPath + `"`, "offset": "0", "count": "1", }, @@ -165,16 +192,12 @@ func (d *OneDevDownloader) GetRepoInfo(ctx context.Context) (*base.Repository, e return nil, err } if len(info) != 1 { - return nil, fmt.Errorf("Project %s not found", d.repoName) + return nil, fmt.Errorf("Project %s not found", d.repoPath) } d.repoID = info[0].ID - cloneURL, err := d.baseURL.Parse(info[0].Name) - if err != nil { - return nil, err - } - originalURL, err := d.baseURL.Parse("/projects/" + info[0].Name) + cloneURL, err := d.baseURL.Parse(info[0].Path) if err != nil { return nil, err } @@ -183,25 +206,25 @@ func (d *OneDevDownloader) GetRepoInfo(ctx context.Context) (*base.Repository, e Name: info[0].Name, Description: info[0].Description, CloneURL: cloneURL.String(), - OriginalURL: originalURL.String(), + OriginalURL: cloneURL.String(), }, nil } // GetMilestones returns milestones func (d *OneDevDownloader) GetMilestones(ctx context.Context) ([]*base.Milestone, error) { - rawMilestones := make([]struct { - ID int64 `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - DueDate *time.Time `json:"dueDate"` - Closed bool `json:"closed"` - }, 0, 100) - - endpoint := fmt.Sprintf("/api/projects/%d/milestones", d.repoID) + endpoint := fmt.Sprintf("/~api/projects/%d/iterations", d.repoID) milestones := make([]*base.Milestone, 0, 100) offset := 0 for { + rawMilestones := make([]struct { + ID int64 `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + DueDay int64 `json:"dueDay"` + Closed bool `json:"closed"` + }, 0, 100) + err := d.callAPI( ctx, endpoint, @@ -221,16 +244,26 @@ func (d *OneDevDownloader) GetMilestones(ctx context.Context) ([]*base.Milestone for _, milestone := range rawMilestones { d.milestoneMap[milestone.ID] = milestone.Name - closed := milestone.DueDate - if !milestone.Closed { - closed = nil + + var dueDate *time.Time + if milestone.DueDay != 0 { + d := time.Unix(milestone.DueDay*24*60*60, 0) + dueDate = &d + } + + var closedDate *time.Time + state := "open" + if milestone.Closed { + closedDate = dueDate + state = "closed" } milestones = append(milestones, &base.Milestone{ Title: milestone.Name, Description: milestone.Description, - Deadline: milestone.DueDate, - Closed: closed, + Deadline: dueDate, + Closed: closedDate, + State: state, }) } } @@ -273,6 +306,10 @@ type onedevIssueContext struct { // GetIssues returns issues func (d *OneDevDownloader) GetIssues(ctx context.Context, page, perPage int) ([]*base.Issue, bool, error) { + type Field struct { + Name string `json:"name"` + Value string `json:"value"` + } rawIssues := make([]struct { ID int64 `json:"id"` Number int64 `json:"number"` @@ -281,15 +318,17 @@ func (d *OneDevDownloader) GetIssues(ctx context.Context, page, perPage int) ([] Description string `json:"description"` SubmitterID int64 `json:"submitterId"` SubmitDate time.Time `json:"submitDate"` + Fields []Field `json:"fields"` }, 0, perPage) err := d.callAPI( ctx, - "/api/issues", + "/~api/issues", map[string]string{ - "query": `"Project" is "` + d.repoName + `"`, - "offset": strconv.Itoa((page - 1) * perPage), - "count": strconv.Itoa(perPage), + "query": `"Project" is "` + d.repoPath + `"`, + "offset": strconv.Itoa((page - 1) * perPage), + "count": strconv.Itoa(perPage), + "withFields": "true", }, &rawIssues, ) @@ -299,22 +338,8 @@ func (d *OneDevDownloader) GetIssues(ctx context.Context, page, perPage int) ([] issues := make([]*base.Issue, 0, len(rawIssues)) for _, issue := range rawIssues { - fields := make([]struct { - Name string `json:"name"` - Value string `json:"value"` - }, 0, 10) - err := d.callAPI( - ctx, - fmt.Sprintf("/api/issues/%d/fields", issue.ID), - nil, - &fields, - ) - if err != nil { - return nil, false, err - } - var label *base.Label - for _, field := range fields { + for _, field := range issue.Fields { if field.Name == "Type" { label = &base.Label{Name: field.Value} break @@ -327,7 +352,7 @@ func (d *OneDevDownloader) GetIssues(ctx context.Context, page, perPage int) ([] }, 0, 10) err = d.callAPI( ctx, - fmt.Sprintf("/api/issues/%d/milestones", issue.ID), + fmt.Sprintf("/~api/issues/%d/iterations", issue.ID), nil, &milestones, ) @@ -383,9 +408,9 @@ func (d *OneDevDownloader) GetComments(ctx context.Context, commentable base.Com var endpoint string if context.IsPullRequest { - endpoint = fmt.Sprintf("/api/pull-requests/%d/comments", commentable.GetForeignIndex()) + endpoint = fmt.Sprintf("/~api/pulls/%d/comments", commentable.GetForeignIndex()) } else { - endpoint = fmt.Sprintf("/api/issues/%d/comments", commentable.GetForeignIndex()) + endpoint = fmt.Sprintf("/~api/issues/%d/comments", commentable.GetForeignIndex()) } err := d.callAPI( @@ -405,9 +430,9 @@ func (d *OneDevDownloader) GetComments(ctx context.Context, commentable base.Com }, 0, 100) if context.IsPullRequest { - endpoint = fmt.Sprintf("/api/pull-requests/%d/changes", commentable.GetForeignIndex()) + endpoint = fmt.Sprintf("/~api/pulls/%d/changes", commentable.GetForeignIndex()) } else { - endpoint = fmt.Sprintf("/api/issues/%d/changes", commentable.GetForeignIndex()) + endpoint = fmt.Sprintf("/~api/issues/%d/changes", commentable.GetForeignIndex()) } err = d.callAPI( @@ -468,26 +493,24 @@ func (d *OneDevDownloader) GetComments(ctx context.Context, commentable base.Com // GetPullRequests returns pull requests func (d *OneDevDownloader) GetPullRequests(ctx context.Context, page, perPage int) ([]*base.PullRequest, bool, error) { rawPullRequests := make([]struct { - ID int64 `json:"id"` - Number int64 `json:"number"` - Title string `json:"title"` - SubmitterID int64 `json:"submitterId"` - SubmitDate time.Time `json:"submitDate"` - Description string `json:"description"` - TargetBranch string `json:"targetBranch"` - SourceBranch string `json:"sourceBranch"` - BaseCommitHash string `json:"baseCommitHash"` - CloseInfo *struct { - Date *time.Time `json:"date"` - Status string `json:"status"` - } + ID int64 `json:"id"` + Number int64 `json:"number"` + Title string `json:"title"` + SubmitterID int64 `json:"submitterId"` + SubmitDate time.Time `json:"submitDate"` + Description string `json:"description"` + TargetBranch string `json:"targetBranch"` + SourceBranch string `json:"sourceBranch"` + BaseCommitHash string `json:"baseCommitHash"` + CloseDate *time.Time `json:"closeDate"` + Status string `json:"status"` // Possible values: OPEN, MERGED, DISCARDED }, 0, perPage) err := d.callAPI( ctx, - "/api/pull-requests", + "/~api/pulls", map[string]string{ - "query": `"Target Project" is "` + d.repoName + `"`, + "query": `"Target Project" is "` + d.repoPath + `"`, "offset": strconv.Itoa((page - 1) * perPage), "count": strconv.Itoa(perPage), }, @@ -507,7 +530,7 @@ func (d *OneDevDownloader) GetPullRequests(ctx context.Context, page, perPage in } err := d.callAPI( ctx, - fmt.Sprintf("/api/pull-requests/%d/merge-preview", pr.ID), + fmt.Sprintf("/~api/pulls/%d/merge-preview", pr.ID), nil, &mergePreview, ) @@ -519,12 +542,12 @@ func (d *OneDevDownloader) GetPullRequests(ctx context.Context, page, perPage in merged := false var closeTime *time.Time var mergedTime *time.Time - if pr.CloseInfo != nil { + if pr.Status != "OPEN" { state = "closed" - closeTime = pr.CloseInfo.Date - if pr.CloseInfo.Status == "MERGED" { // "DISCARDED" + closeTime = pr.CloseDate + if pr.Status == "MERGED" { // "DISCARDED" merged = true - mergedTime = pr.CloseInfo.Date + mergedTime = pr.CloseDate } } poster := d.tryGetUser(ctx, pr.SubmitterID) @@ -545,12 +568,12 @@ func (d *OneDevDownloader) GetPullRequests(ctx context.Context, page, perPage in Head: base.PullRequestBranch{ Ref: pr.SourceBranch, SHA: mergePreview.HeadCommitHash, - RepoName: d.repoName, + RepoName: d.repoPath, }, Base: base.PullRequestBranch{ Ref: pr.TargetBranch, SHA: mergePreview.TargetHeadCommitHash, - RepoName: d.repoName, + RepoName: d.repoPath, }, ForeignIndex: pr.ID, Context: onedevIssueContext{IsPullRequest: true}, @@ -566,18 +589,14 @@ func (d *OneDevDownloader) GetPullRequests(ctx context.Context, page, perPage in // GetReviews returns pull requests reviews func (d *OneDevDownloader) GetReviews(ctx context.Context, reviewable base.Reviewable) ([]*base.Review, error) { rawReviews := make([]struct { - ID int64 `json:"id"` - UserID int64 `json:"userId"` - Result *struct { - Commit string `json:"commit"` - Approved bool `json:"approved"` - Comment string `json:"comment"` - } + ID int64 `json:"id"` + UserID int64 `json:"userId"` + Status string `json:"status"` // Possible values: PENDING, APPROVED, REQUESTED_FOR_CHANGES, EXCLUDED }, 0, 100) err := d.callAPI( ctx, - fmt.Sprintf("/api/pull-requests/%d/reviews", reviewable.GetForeignIndex()), + fmt.Sprintf("/~api/pulls/%d/reviews", reviewable.GetForeignIndex()), nil, &rawReviews, ) @@ -589,14 +608,11 @@ func (d *OneDevDownloader) GetReviews(ctx context.Context, reviewable base.Revie for _, review := range rawReviews { state := base.ReviewStatePending content := "" - if review.Result != nil { - if len(review.Result.Comment) > 0 { - state = base.ReviewStateCommented - content = review.Result.Comment - } - if review.Result.Approved { - state = base.ReviewStateApproved - } + switch review.Status { + case "APPROVED": + state = base.ReviewStateApproved + case "REQUESTED_FOR_CHANGES": + state = base.ReviewStateChangesRequested } poster := d.tryGetUser(ctx, review.UserID) @@ -620,17 +636,52 @@ func (d *OneDevDownloader) GetTopics(_ context.Context) ([]string, error) { func (d *OneDevDownloader) tryGetUser(ctx context.Context, userID int64) *onedevUser { user, ok := d.userMap[userID] if !ok { + // get user name + type RawUser struct { + Name string `json:"name"` + } + var rawUser RawUser err := d.callAPI( ctx, - fmt.Sprintf("/api/users/%d", userID), + fmt.Sprintf("/~api/users/%d", userID), nil, - &user, + &rawUser, ) - if err != nil { - user = &onedevUser{ - Name: fmt.Sprintf("User %d", userID), + var userName string + if err == nil { + userName = rawUser.Name + } else { + userName = fmt.Sprintf("User %d", userID) + } + + // get (primary) user Email address + rawEmailAddresses := make([]struct { + Value string `json:"value"` + Primary bool `json:"primary"` + }, 0, 10) + err = d.callAPI( + ctx, + fmt.Sprintf("/~api/users/%d/email-addresses", userID), + nil, + &rawEmailAddresses, + ) + var userEmail string + if err == nil { + for _, email := range rawEmailAddresses { + if userEmail == "" || email.Primary { + userEmail = email.Value + } + if email.Primary { + break + } } } + + user = &onedevUser{ + ID: userID, + Name: userName, + Email: userEmail, + } d.userMap[userID] = user } diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go index 81c06b5ec3..f436e3e066 100644 --- a/services/mirror/mirror_pull.go +++ b/services/mirror/mirror_pull.go @@ -40,30 +40,27 @@ func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error } remoteName := m.GetRemoteName() - repoPath := m.GetRepository(ctx).RepoPath() + repo := m.GetRepository(ctx) // Remove old remote - _, _, err = git.NewCommand("remote", "rm").AddDynamicArguments(remoteName).RunStdString(ctx, &git.RunOpts{Dir: repoPath}) + err = gitrepo.GitRemoteRemove(ctx, repo, remoteName) if err != nil && !git.IsRemoteNotExistError(err) { return err } - cmd := git.NewCommand("remote", "add").AddDynamicArguments(remoteName).AddArguments("--mirror=fetch").AddDynamicArguments(addr) - _, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath}) + err = gitrepo.GitRemoteAdd(ctx, repo, remoteName, addr, gitrepo.RemoteOptionMirrorFetch) if err != nil && !git.IsRemoteNotExistError(err) { return err } - if m.Repo.HasWiki() { - wikiPath := m.Repo.WikiPath() + if repo_service.HasWiki(ctx, m.Repo) { wikiRemotePath := repo_module.WikiRemoteURL(ctx, addr) // Remove old remote of wiki - _, _, err = git.NewCommand("remote", "rm").AddDynamicArguments(remoteName).RunStdString(ctx, &git.RunOpts{Dir: wikiPath}) + err = gitrepo.GitRemoteRemove(ctx, repo.WikiStorageRepo(), remoteName) if err != nil && !git.IsRemoteNotExistError(err) { return err } - cmd = git.NewCommand("remote", "add").AddDynamicArguments(remoteName).AddArguments("--mirror=fetch").AddDynamicArguments(wikiRemotePath) - _, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: wikiPath}) + err = gitrepo.GitRemoteAdd(ctx, repo.WikiStorageRepo(), remoteName, wikiRemotePath, gitrepo.RemoteOptionMirrorFetch) if err != nil && !git.IsRemoteNotExistError(err) { return err } @@ -198,25 +195,21 @@ func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult { func pruneBrokenReferences(ctx context.Context, m *repo_model.Mirror, - repoPath string, timeout time.Duration, stdoutBuilder, stderrBuilder *strings.Builder, isWiki bool, ) error { wiki := "" + var storageRepo gitrepo.Repository = m.Repo if isWiki { wiki = "Wiki " + storageRepo = m.Repo.WikiStorageRepo() } stderrBuilder.Reset() stdoutBuilder.Reset() - pruneErr := git.NewCommand("remote", "prune").AddDynamicArguments(m.GetRemoteName()). - Run(ctx, &git.RunOpts{ - Timeout: timeout, - Dir: repoPath, - Stdout: stdoutBuilder, - Stderr: stderrBuilder, - }) + + pruneErr := gitrepo.GitRemotePrune(ctx, storageRepo, m.GetRemoteName(), timeout, stdoutBuilder, stderrBuilder) if pruneErr != nil { stdout := stdoutBuilder.String() stderr := stderrBuilder.String() @@ -227,7 +220,7 @@ func pruneBrokenReferences(ctx context.Context, stdoutMessage := util.SanitizeCredentialURLs(stdout) log.Error("Failed to prune mirror repository %s%-v references:\nStdout: %s\nStderr: %s\nErr: %v", wiki, m.Repo, stdoutMessage, stderrMessage, pruneErr) - desc := fmt.Sprintf("Failed to prune mirror repository %s'%s' references: %s", wiki, repoPath, stderrMessage) + desc := fmt.Sprintf("Failed to prune mirror repository %s'%s' references: %s", wiki, storageRepo.RelativePath(), stderrMessage) if err := system_model.CreateRepositoryNotice(desc); err != nil { log.Error("CreateRepositoryNotice: %v", err) } @@ -299,9 +292,9 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo } cmd.AddArguments("--tags").AddDynamicArguments(m.GetRemoteName()) - remoteURL, remoteErr := git.GetRemoteURL(ctx, repoPath, m.GetRemoteName()) + remoteURL, remoteErr := gitrepo.GitRemoteGetURL(ctx, m.Repo, m.GetRemoteName()) if remoteErr != nil { - log.Error("SyncMirrors [repo: %-v]: GetRemoteAddress Error %v", m.Repo, remoteErr) + log.Error("SyncMirrors [repo: %-v]: GetRemoteURL Error %v", m.Repo, remoteErr) return nil, false } @@ -339,7 +332,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo err = nil // Attempt prune - pruneErr := pruneBrokenReferences(ctx, m, repoPath, timeout, &stdoutBuilder, &stderrBuilder, false) + pruneErr := pruneBrokenReferences(ctx, m, timeout, &stdoutBuilder, &stderrBuilder, false) if pruneErr == nil { // Successful prune - reattempt mirror stderrBuilder.Reset() @@ -397,7 +390,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo endpoint := lfs.DetermineEndpoint(remoteURL.String(), m.LFSEndpoint) lfsClient := lfs.NewClient(endpoint, nil) if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, m.Repo, gitRepo, lfsClient); err != nil { - log.Error("SyncMirrors [repo: %-v]: failed to synchronize LFS objects for repository: %v", m.Repo, err) + log.Error("SyncMirrors [repo: %-v]: failed to synchronize LFS objects for repository: %v", m.Repo.FullName(), err) } } @@ -414,20 +407,16 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo log.Trace("SyncMirrors [repo: %-v]: updating size of repository", m.Repo) if err := repo_module.UpdateRepoSize(ctx, m.Repo); err != nil { - log.Error("SyncMirrors [repo: %-v]: failed to update size for mirror repository: %v", m.Repo, err) + log.Error("SyncMirrors [repo: %-v]: failed to update size for mirror repository: %v", m.Repo.FullName(), err) } - if m.Repo.HasWiki() { + if repo_service.HasWiki(ctx, m.Repo) { log.Trace("SyncMirrors [repo: %-v Wiki]: running git remote update...", m.Repo) stderrBuilder.Reset() stdoutBuilder.Reset() - if err := git.NewCommand("remote", "update", "--prune").AddDynamicArguments(m.GetRemoteName()). - Run(ctx, &git.RunOpts{ - Timeout: timeout, - Dir: wikiPath, - Stdout: &stdoutBuilder, - Stderr: &stderrBuilder, - }); err != nil { + + if err := gitrepo.GitRemoteUpdatePrune(ctx, m.Repo.WikiStorageRepo(), m.GetRemoteName(), + timeout, &stdoutBuilder, &stderrBuilder); err != nil { stdout := stdoutBuilder.String() stderr := stderrBuilder.String() @@ -441,19 +430,14 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo err = nil // Attempt prune - pruneErr := pruneBrokenReferences(ctx, m, repoPath, timeout, &stdoutBuilder, &stderrBuilder, true) + pruneErr := pruneBrokenReferences(ctx, m, timeout, &stdoutBuilder, &stderrBuilder, true) if pruneErr == nil { // Successful prune - reattempt mirror stderrBuilder.Reset() stdoutBuilder.Reset() - if err = git.NewCommand("remote", "update", "--prune").AddDynamicArguments(m.GetRemoteName()). - Run(ctx, &git.RunOpts{ - Timeout: timeout, - Dir: wikiPath, - Stdout: &stdoutBuilder, - Stderr: &stderrBuilder, - }); err != nil { + if err = gitrepo.GitRemoteUpdatePrune(ctx, m.Repo.WikiStorageRepo(), m.GetRemoteName(), + timeout, &stdoutBuilder, &stderrBuilder); err != nil { stdout := stdoutBuilder.String() stderr := stderrBuilder.String() stderrMessage = util.SanitizeCredentialURLs(stderr) diff --git a/services/mirror/mirror_push.go b/services/mirror/mirror_push.go index 6a20a1ff92..add38c915c 100644 --- a/services/mirror/mirror_push.go +++ b/services/mirror/mirror_push.go @@ -24,34 +24,31 @@ import ( ssh_module "code.gitea.io/gitea/modules/ssh" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" + repo_service "code.gitea.io/gitea/services/repository" ) var stripExitStatus = regexp.MustCompile(`exit status \d+ - `) // AddPushMirrorRemote registers the push mirror remote. func AddPushMirrorRemote(ctx context.Context, m *repo_model.PushMirror, addr string) error { - addRemoteAndConfig := func(addr, path string) error { - cmd := git.NewCommand("remote", "add", "--mirror=push").AddDynamicArguments(m.RemoteName, addr) - if _, _, err := cmd.RunStdString(ctx, &git.RunOpts{Dir: path}); err != nil { + addRemoteAndConfig := func(storageRepo gitrepo.Repository, addr string) error { + if err := gitrepo.GitRemoteAdd(ctx, storageRepo, m.RemoteName, addr, gitrepo.RemoteOptionMirrorPush); err != nil { return err } - if _, _, err := git.NewCommand("config", "--add").AddDynamicArguments("remote."+m.RemoteName+".push", "+refs/heads/*:refs/heads/*").RunStdString(ctx, &git.RunOpts{Dir: path}); err != nil { + if err := gitrepo.GitConfigAdd(ctx, storageRepo, "remote."+m.RemoteName+".push", "+refs/heads/*:refs/heads/*"); err != nil { return err } - if _, _, err := git.NewCommand("config", "--add").AddDynamicArguments("remote."+m.RemoteName+".push", "+refs/tags/*:refs/tags/*").RunStdString(ctx, &git.RunOpts{Dir: path}); err != nil { - return err - } - return nil + return gitrepo.GitConfigAdd(ctx, storageRepo, "remote."+m.RemoteName+".push", "+refs/tags/*:refs/tags/*") } - if err := addRemoteAndConfig(addr, m.Repo.RepoPath()); err != nil { + if err := addRemoteAndConfig(m.Repo, addr); err != nil { return err } - if m.Repo.HasWiki() { + if repo_service.HasWiki(ctx, m.Repo) { wikiRemoteURL := repository.WikiRemoteURL(ctx, addr) if len(wikiRemoteURL) > 0 { - if err := addRemoteAndConfig(wikiRemoteURL, m.Repo.WikiPath()); err != nil { + if err := addRemoteAndConfig(m.Repo.WikiStorageRepo(), wikiRemoteURL); err != nil { return err } } @@ -62,15 +59,13 @@ func AddPushMirrorRemote(ctx context.Context, m *repo_model.PushMirror, addr str // RemovePushMirrorRemote removes the push mirror remote. func RemovePushMirrorRemote(ctx context.Context, m *repo_model.PushMirror) error { - cmd := git.NewCommand("remote", "rm").AddDynamicArguments(m.RemoteName) _ = m.GetRepository(ctx) - - if _, _, err := cmd.RunStdString(ctx, &git.RunOpts{Dir: m.Repo.RepoPath()}); err != nil { + if err := gitrepo.GitRemoteRemove(ctx, m.Repo, m.RemoteName); err != nil { return err } - if m.Repo.HasWiki() { - if _, _, err := cmd.RunStdString(ctx, &git.RunOpts{Dir: m.Repo.WikiPath()}); err != nil { + if repo_service.HasWiki(ctx, m.Repo) { + if err := gitrepo.GitRemoteRemove(ctx, m.Repo.WikiStorageRepo(), m.RemoteName); err != nil { // The wiki remote may not exist log.Warn("Wiki Remote[%d] could not be removed: %v", m.ID, err) } @@ -132,25 +127,22 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error { timeout := time.Duration(setting.Git.Timeout.Mirror) * time.Second performPush := func(repo *repo_model.Repository, isWiki bool) error { + var storageRepo gitrepo.Repository = repo path := repo.RepoPath() if isWiki { + storageRepo = repo.WikiStorageRepo() path = repo.WikiPath() } - remoteURL, err := git.GetRemoteURL(ctx, path, m.RemoteName) + remoteURL, err := gitrepo.GitRemoteGetURL(ctx, storageRepo, m.RemoteName) if err != nil { - log.Error("GetRemoteAddress(%s) Error %v", path, err) + log.Error("GetRemoteURL(%s) Error %v", path, err) return errors.New("Unexpected error") } if setting.LFS.StartServer && !IsSSHURL(remoteURL.String()) { log.Trace("SyncMirrors [repo: %-v]: syncing LFS objects...", m.Repo) - var gitRepo *git.Repository - if isWiki { - gitRepo, err = gitrepo.OpenRepository(ctx, repo.WikiStorageRepo()) - } else { - gitRepo, err = gitrepo.OpenRepository(ctx, repo) - } + gitRepo, err := gitrepo.OpenRepository(ctx, storageRepo) if err != nil { log.Error("OpenRepository: %v", err) return errors.New("Unexpected error") @@ -222,15 +214,14 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error { return err } - if m.Repo.HasWiki() { - _, err := git.GetRemoteAddress(ctx, m.Repo.WikiPath(), m.RemoteName) - if err == nil { + if repo_service.HasWiki(ctx, m.Repo) { + if _, err := gitrepo.GitRemoteGetURL(ctx, m.Repo.WikiStorageRepo(), m.RemoteName); err == nil { err := performPush(m.Repo, true) if err != nil { return err } - } else { - log.Trace("Skipping wiki: No remote configured") + } else if !errors.Is(err, util.ErrNotExist) { + log.Error("GetRemote of wiki failed: %v", err) } } diff --git a/services/oauth2_provider/access_token.go b/services/oauth2_provider/access_token.go index 5a190d8616..dce4ac765b 100644 --- a/services/oauth2_provider/access_token.go +++ b/services/oauth2_provider/access_token.go @@ -196,7 +196,7 @@ func NewAccessTokenResponse(ctx context.Context, grant *auth.OAuth2Grant, server if grant.ScopeContains("profile") { idToken.Name = user.DisplayName() idToken.PreferredUsername = user.Name - idToken.Profile = user.HTMLURL() + idToken.Profile = user.HTMLURL(ctx) idToken.Picture = user.AvatarLink(ctx) idToken.Website = user.Website idToken.Locale = user.Language diff --git a/services/org/org.go b/services/org/org.go index 3d30ae21a3..8da77c691c 100644 --- a/services/org/org.go +++ b/services/org/org.go @@ -8,13 +8,17 @@ import ( "fmt" actions_model "code.gitea.io/gitea/models/actions" + activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" org_model "code.gitea.io/gitea/models/organization" packages_model "code.gitea.io/gitea/models/packages" + access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" secret_model "code.gitea.io/gitea/models/secret" user_model "code.gitea.io/gitea/models/user" + issue_indexer "code.gitea.io/gitea/modules/indexer/issues" "code.gitea.io/gitea/modules/storage" + "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" repo_service "code.gitea.io/gitea/services/repository" ) @@ -48,39 +52,34 @@ func deleteOrganization(ctx context.Context, org *org_model.Organization) error // DeleteOrganization completely and permanently deletes everything of organization. func DeleteOrganization(ctx context.Context, org *org_model.Organization, purge bool) error { - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return err - } - defer committer.Close() - - if purge { - err := repo_service.DeleteOwnerRepositoriesDirectly(ctx, org.AsUser()) - if err != nil { - return err + if err := db.WithTx(ctx, func(ctx context.Context) error { + if purge { + err := repo_service.DeleteOwnerRepositoriesDirectly(ctx, org.AsUser()) + if err != nil { + return err + } } - } - // Check ownership of repository. - count, err := repo_model.CountRepositories(ctx, repo_model.CountRepositoryOptions{OwnerID: org.ID}) - if err != nil { - return fmt.Errorf("GetRepositoryCount: %w", err) - } else if count > 0 { - return repo_model.ErrUserOwnRepos{UID: org.ID} - } + // Check ownership of repository. + count, err := repo_model.CountRepositories(ctx, repo_model.CountRepositoryOptions{OwnerID: org.ID}) + if err != nil { + return fmt.Errorf("GetRepositoryCount: %w", err) + } else if count > 0 { + return repo_model.ErrUserOwnRepos{UID: org.ID} + } - // Check ownership of packages. - if ownsPackages, err := packages_model.HasOwnerPackages(ctx, org.ID); err != nil { - return fmt.Errorf("HasOwnerPackages: %w", err) - } else if ownsPackages { - return packages_model.ErrUserOwnPackages{UID: org.ID} - } + // Check ownership of packages. + if ownsPackages, err := packages_model.HasOwnerPackages(ctx, org.ID); err != nil { + return fmt.Errorf("HasOwnerPackages: %w", err) + } else if ownsPackages { + return packages_model.ErrUserOwnPackages{UID: org.ID} + } - if err := deleteOrganization(ctx, org); err != nil { - return fmt.Errorf("DeleteOrganization: %w", err) - } - - if err := committer.Commit(); err != nil { + if err := deleteOrganization(ctx, org); err != nil { + return fmt.Errorf("DeleteOrganization: %w", err) + } + return nil + }); err != nil { return err } @@ -102,3 +101,70 @@ func DeleteOrganization(ctx context.Context, org *org_model.Organization, purge return nil } + +func updateOrgRepoForVisibilityChanged(ctx context.Context, repo *repo_model.Repository, makePrivate bool) error { + // Organization repository need to recalculate access table when visibility is changed. + if err := access_model.RecalculateTeamAccesses(ctx, repo, 0); err != nil { + return fmt.Errorf("recalculateTeamAccesses: %w", err) + } + + if makePrivate { + if _, err := db.GetEngine(ctx).Where("repo_id = ?", repo.ID).Cols("is_private").Update(&activities_model.Action{ + IsPrivate: true, + }); err != nil { + return err + } + + if err := repo_model.ClearRepoStars(ctx, repo.ID); err != nil { + return err + } + } + + // Create/Remove git-daemon-export-ok for git-daemon... + if err := repo_service.CheckDaemonExportOK(ctx, repo); err != nil { + return err + } + + // If visibility is changed, we need to update the issue indexer. + // Since the data in the issue indexer have field to indicate if the repo is public or not. + // FIXME: it should check organization visibility instead of repository visibility only. + issue_indexer.UpdateRepoIndexer(ctx, repo.ID) + + forkRepos, err := repo_model.GetRepositoriesByForkID(ctx, repo.ID) + if err != nil { + return fmt.Errorf("getRepositoriesByForkID: %w", err) + } + for i := range forkRepos { + if err := updateOrgRepoForVisibilityChanged(ctx, forkRepos[i], makePrivate); err != nil { + return fmt.Errorf("updateRepoForVisibilityChanged[%s]: %w", forkRepos[i].FullName(), err) + } + } + return nil +} + +func ChangeOrganizationVisibility(ctx context.Context, org *org_model.Organization, visibility structs.VisibleType) error { + if org.Visibility == visibility { + return nil + } + + org.Visibility = visibility + // FIXME: If it's a big forks network(forks and sub forks), the database transaction will be too long to fail. + return db.WithTx(ctx, func(ctx context.Context) error { + if err := user_model.UpdateUserColsNoAutoTime(ctx, org.AsUser(), "visibility"); err != nil { + return err + } + + repos, _, err := repo_model.GetUserRepositories(ctx, repo_model.SearchRepoOptions{ + Actor: org.AsUser(), Private: true, ListOptions: db.ListOptionsAll, + }) + if err != nil { + return err + } + for _, repo := range repos { + if err := updateOrgRepoForVisibilityChanged(ctx, repo, visibility == structs.VisibleTypePrivate); err != nil { + return fmt.Errorf("updateOrgRepoForVisibilityChanged: %w", err) + } + } + return nil + }) +} diff --git a/services/org/org_test.go b/services/org/org_test.go index 791404c5c8..5fdc1a6fd5 100644 --- a/services/org/org_test.go +++ b/services/org/org_test.go @@ -6,7 +6,6 @@ package org import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -22,17 +21,17 @@ func TestMain(m *testing.M) { func TestDeleteOrganization(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 6}) - assert.NoError(t, DeleteOrganization(db.DefaultContext, org, false)) + assert.NoError(t, DeleteOrganization(t.Context(), org, false)) unittest.AssertNotExistsBean(t, &organization.Organization{ID: 6}) unittest.AssertNotExistsBean(t, &organization.OrgUser{OrgID: 6}) unittest.AssertNotExistsBean(t, &organization.Team{OrgID: 6}) org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) - err := DeleteOrganization(db.DefaultContext, org, false) + err := DeleteOrganization(t.Context(), org, false) assert.Error(t, err) assert.True(t, repo_model.IsErrUserOwnRepos(err)) user := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 5}) - assert.Error(t, DeleteOrganization(db.DefaultContext, user, false)) + assert.Error(t, DeleteOrganization(t.Context(), user, false)) unittest.CheckConsistencyFor(t, &user_model.User{}, &organization.Team{}) } diff --git a/services/org/team.go b/services/org/team.go index 773bd11f49..633056cf95 100644 --- a/services/org/team.go +++ b/services/org/team.go @@ -15,6 +15,7 @@ import ( 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/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" @@ -259,10 +260,9 @@ func AddTeamMember(ctx context.Context, team *organization.Team, user *user_mode log.Error("GetTeamRepositories failed: %v", err) } - // FIXME: in the goroutine, it can't access the "ctx", it could only use db.DefaultContext at the moment go func(repos []*repo_model.Repository) { for _, repo := range repos { - if err = repo_model.WatchRepo(db.DefaultContext, user, repo, true); err != nil { + if err = repo_model.WatchRepo(graceful.GetManager().ShutdownContext(), user, repo, true); err != nil { log.Error("watch repo failed: %v", err) } } diff --git a/services/org/team_test.go b/services/org/team_test.go index c1a69d8ee7..a5e01e7a54 100644 --- a/services/org/team_test.go +++ b/services/org/team_test.go @@ -8,7 +8,6 @@ import ( "strings" "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" @@ -25,7 +24,7 @@ func TestTeam_AddMember(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(team *organization.Team, user *user_model.User) { - assert.NoError(t, AddTeamMember(db.DefaultContext, team, user)) + assert.NoError(t, AddTeamMember(t.Context(), team, user)) unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: user.ID, TeamID: team.ID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID}, &user_model.User{ID: team.OrgID}) } @@ -44,7 +43,7 @@ func TestTeam_RemoveMember(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(team *organization.Team, user *user_model.User) { - assert.NoError(t, RemoveTeamMember(db.DefaultContext, team, user)) + assert.NoError(t, RemoveTeamMember(t.Context(), team, user)) unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: user.ID, TeamID: team.ID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID}) } @@ -59,7 +58,7 @@ func TestTeam_RemoveMember(t *testing.T) { testSuccess(team2, user2) testSuccess(team3, user2) - err := RemoveTeamMember(db.DefaultContext, team1, user2) + err := RemoveTeamMember(t.Context(), team1, user2) assert.True(t, organization.IsErrLastOrgOwner(err)) } @@ -68,7 +67,7 @@ func TestNewTeam(t *testing.T) { const teamName = "newTeamName" team := &organization.Team{Name: teamName, OrgID: 3} - assert.NoError(t, NewTeam(db.DefaultContext, team)) + assert.NoError(t, NewTeam(t.Context(), team)) unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: teamName}) unittest.CheckConsistencyFor(t, &organization.Team{}, &user_model.User{ID: team.OrgID}) } @@ -82,7 +81,7 @@ func TestUpdateTeam(t *testing.T) { team.Name = "newName" team.Description = strings.Repeat("A long description!", 100) team.AccessMode = perm.AccessModeAdmin - assert.NoError(t, UpdateTeam(db.DefaultContext, team, true, false)) + assert.NoError(t, UpdateTeam(t.Context(), team, true, false)) team = unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: "newName"}) assert.True(t, strings.HasPrefix(team.Description, "A long description!")) @@ -101,7 +100,7 @@ func TestUpdateTeam2(t *testing.T) { team.LowerName = "owners" team.Name = "Owners" team.Description = strings.Repeat("A long description!", 100) - err := UpdateTeam(db.DefaultContext, team, true, false) + err := UpdateTeam(t.Context(), team, true, false) assert.True(t, organization.IsErrTeamAlreadyExist(err)) unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID}) @@ -111,7 +110,7 @@ func TestDeleteTeam(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}) - assert.NoError(t, DeleteTeam(db.DefaultContext, team)) + assert.NoError(t, DeleteTeam(t.Context(), team)) unittest.AssertNotExistsBean(t, &organization.Team{ID: team.ID}) unittest.AssertNotExistsBean(t, &organization.TeamRepo{TeamID: team.ID}) unittest.AssertNotExistsBean(t, &organization.TeamUser{TeamID: team.ID}) @@ -119,7 +118,7 @@ func TestDeleteTeam(t *testing.T) { // check that team members don't have "leftover" access to repos user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) - accessMode, err := access_model.AccessLevel(db.DefaultContext, user, repo) + accessMode, err := access_model.AccessLevel(t.Context(), user, repo) assert.NoError(t, err) assert.Less(t, accessMode, perm.AccessModeWrite) } @@ -128,7 +127,7 @@ func TestAddTeamMember(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(team *organization.Team, user *user_model.User) { - assert.NoError(t, AddTeamMember(db.DefaultContext, team, user)) + assert.NoError(t, AddTeamMember(t.Context(), team, user)) unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: user.ID, TeamID: team.ID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID}, &user_model.User{ID: team.OrgID}) } @@ -147,7 +146,7 @@ func TestRemoveTeamMember(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(team *organization.Team, user *user_model.User) { - assert.NoError(t, RemoveTeamMember(db.DefaultContext, team, user)) + assert.NoError(t, RemoveTeamMember(t.Context(), team, user)) unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: user.ID, TeamID: team.ID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID}) } @@ -162,7 +161,7 @@ func TestRemoveTeamMember(t *testing.T) { testSuccess(team2, user2) testSuccess(team3, user2) - err := RemoveTeamMember(db.DefaultContext, team1, user2) + err := RemoveTeamMember(t.Context(), team1, user2) assert.True(t, organization.IsErrLastOrgOwner(err)) } @@ -171,7 +170,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { testTeamRepositories := func(teamID int64, repoIDs []int64) { team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) - repos, err := repo_model.GetTeamRepositories(db.DefaultContext, &repo_model.SearchTeamRepoOptions{ + repos, err := repo_model.GetTeamRepositories(t.Context(), &repo_model.SearchTeamRepoOptions{ TeamID: team.ID, }) assert.NoError(t, err, "%s: GetTeamRepositories", team.Name) @@ -179,13 +178,13 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { assert.Len(t, repos, len(repoIDs), "%s: repo count", team.Name) for i, rid := range repoIDs { if rid > 0 { - assert.True(t, repo_service.HasRepository(db.DefaultContext, team, rid), "%s: HasRepository(%d) %d", rid, i) + assert.True(t, repo_service.HasRepository(t.Context(), team, rid), "%s: HasRepository(%d) %d", rid, i) } } } // Get an admin user. - user, err := user_model.GetUserByID(db.DefaultContext, 1) + user, err := user_model.GetUserByID(t.Context(), 1) assert.NoError(t, err, "GetUserByID") // Create org. @@ -195,17 +194,17 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { Type: user_model.UserTypeOrganization, Visibility: structs.VisibleTypePublic, } - assert.NoError(t, organization.CreateOrganization(db.DefaultContext, org, user), "CreateOrganization") + assert.NoError(t, organization.CreateOrganization(t.Context(), org, user), "CreateOrganization") // Check Owner team. - ownerTeam, err := org.GetOwnerTeam(db.DefaultContext) + ownerTeam, err := org.GetOwnerTeam(t.Context()) assert.NoError(t, err, "GetOwnerTeam") assert.True(t, ownerTeam.IncludesAllRepositories, "Owner team includes all repositories") // Create repos. repoIDs := make([]int64, 0) for i := range 3 { - r, err := repo_service.CreateRepositoryDirectly(db.DefaultContext, user, org.AsUser(), + r, err := repo_service.CreateRepositoryDirectly(t.Context(), user, org.AsUser(), repo_service.CreateRepoOptions{Name: fmt.Sprintf("repo-%d", i)}, true) assert.NoError(t, err, "CreateRepository %d", i) if r != nil { @@ -213,7 +212,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { } } // Get fresh copy of Owner team after creating repos. - ownerTeam, err = org.GetOwnerTeam(db.DefaultContext) + ownerTeam, err = org.GetOwnerTeam(t.Context()) assert.NoError(t, err, "GetOwnerTeam") // Create teams and check repositories. @@ -253,7 +252,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { } for i, team := range teams { if i > 0 { // first team is Owner. - assert.NoError(t, NewTeam(db.DefaultContext, team), "%s: NewTeam", team.Name) + assert.NoError(t, NewTeam(t.Context(), team), "%s: NewTeam", team.Name) } testTeamRepositories(team.ID, teamRepos[i]) } @@ -263,12 +262,12 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { teams[4].IncludesAllRepositories = true teamRepos[4] = repoIDs for i, team := range teams { - assert.NoError(t, UpdateTeam(db.DefaultContext, team, false, true), "%s: UpdateTeam", team.Name) + assert.NoError(t, UpdateTeam(t.Context(), team, false, true), "%s: UpdateTeam", team.Name) testTeamRepositories(team.ID, teamRepos[i]) } // Create repo and check teams repositories. - r, err := repo_service.CreateRepositoryDirectly(db.DefaultContext, user, org.AsUser(), repo_service.CreateRepoOptions{Name: "repo-last"}, true) + r, err := repo_service.CreateRepositoryDirectly(t.Context(), user, org.AsUser(), repo_service.CreateRepoOptions{Name: "repo-last"}, true) assert.NoError(t, err, "CreateRepository last") if r != nil { repoIDs = append(repoIDs, r.ID) @@ -281,7 +280,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { } // Remove repo and check teams repositories. - assert.NoError(t, repo_service.DeleteRepositoryDirectly(db.DefaultContext, repoIDs[0]), "DeleteRepository") + assert.NoError(t, repo_service.DeleteRepositoryDirectly(t.Context(), repoIDs[0]), "DeleteRepository") teamRepos[0] = repoIDs[1:] teamRepos[1] = repoIDs[1:] teamRepos[3] = repoIDs[1:3] @@ -293,8 +292,8 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { // Wipe created items. for i, rid := range repoIDs { if i > 0 { // first repo already deleted. - assert.NoError(t, repo_service.DeleteRepositoryDirectly(db.DefaultContext, rid), "DeleteRepository %d", i) + assert.NoError(t, repo_service.DeleteRepositoryDirectly(t.Context(), rid), "DeleteRepository %d", i) } } - assert.NoError(t, DeleteOrganization(db.DefaultContext, org, false), "DeleteOrganization") + assert.NoError(t, DeleteOrganization(t.Context(), org, false), "DeleteOrganization") } diff --git a/services/org/user.go b/services/org/user.go index 26927253d2..6858271858 100644 --- a/services/org/user.go +++ b/services/org/user.go @@ -47,57 +47,52 @@ func RemoveOrgUser(ctx context.Context, org *organization.Organization, user *us } } - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return err - } - defer committer.Close() + return db.WithTx(ctx, func(ctx context.Context) error { + if _, err := db.DeleteByID[organization.OrgUser](ctx, ou.ID); err != nil { + return err + } else if _, err = db.Exec(ctx, "UPDATE `user` SET num_members=num_members-1 WHERE id=?", org.ID); err != nil { + return err + } - if _, err := db.DeleteByID[organization.OrgUser](ctx, ou.ID); err != nil { - return err - } else if _, err = db.Exec(ctx, "UPDATE `user` SET num_members=num_members-1 WHERE id=?", org.ID); err != nil { - return err - } + // Delete all repository accesses and unwatch them. + env, err := repo_model.AccessibleReposEnv(ctx, org, user.ID) + if err != nil { + return fmt.Errorf("AccessibleReposEnv: %w", err) + } + repoIDs, err := env.RepoIDs(ctx) + if err != nil { + return fmt.Errorf("GetUserRepositories [%d]: %w", user.ID, err) + } - // Delete all repository accesses and unwatch them. - env, err := repo_model.AccessibleReposEnv(ctx, org, user.ID) - if err != nil { - return fmt.Errorf("AccessibleReposEnv: %w", err) - } - repoIDs, err := env.RepoIDs(ctx) - if err != nil { - return fmt.Errorf("GetUserRepositories [%d]: %w", user.ID, err) - } + for _, repoID := range repoIDs { + repo, err := repo_model.GetRepositoryByID(ctx, repoID) + if err != nil { + return err + } + if err = repo_model.WatchRepo(ctx, user, repo, false); err != nil { + return err + } + } - for _, repoID := range repoIDs { - repo, err := repo_model.GetRepositoryByID(ctx, repoID) + if len(repoIDs) > 0 { + if _, err = db.GetEngine(ctx). + Where("user_id = ?", user.ID). + In("repo_id", repoIDs). + Delete(new(access_model.Access)); err != nil { + return err + } + } + + // Delete member in their teams. + teams, err := organization.GetUserOrgTeams(ctx, org.ID, user.ID) if err != nil { return err } - if err = repo_model.WatchRepo(ctx, user, repo, false); err != nil { - return err + for _, t := range teams { + if err = removeTeamMember(ctx, t, user); err != nil { + return err + } } - } - - if len(repoIDs) > 0 { - if _, err = db.GetEngine(ctx). - Where("user_id = ?", user.ID). - In("repo_id", repoIDs). - Delete(new(access_model.Access)); err != nil { - return err - } - } - - // Delete member in their teams. - teams, err := organization.GetUserOrgTeams(ctx, org.ID, user.ID) - if err != nil { - return err - } - for _, t := range teams { - if err = removeTeamMember(ctx, t, user); err != nil { - return err - } - } - - return committer.Commit() + return nil + }) } diff --git a/services/org/user_test.go b/services/org/user_test.go index c61d600d90..3df9d53356 100644 --- a/services/org/user_test.go +++ b/services/org/user_test.go @@ -6,7 +6,6 @@ package org import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -24,7 +23,7 @@ func TestUser_RemoveMember(t *testing.T) { // remove a user that is a member unittest.AssertExistsAndLoadBean(t, &organization.OrgUser{UID: user4.ID, OrgID: org.ID}) prevNumMembers := org.NumMembers - assert.NoError(t, RemoveOrgUser(db.DefaultContext, org, user4)) + assert.NoError(t, RemoveOrgUser(t.Context(), org, user4)) unittest.AssertNotExistsBean(t, &organization.OrgUser{UID: user4.ID, OrgID: org.ID}) org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: org.ID}) @@ -33,7 +32,7 @@ func TestUser_RemoveMember(t *testing.T) { // remove a user that is not a member unittest.AssertNotExistsBean(t, &organization.OrgUser{UID: user5.ID, OrgID: org.ID}) prevNumMembers = org.NumMembers - assert.NoError(t, RemoveOrgUser(db.DefaultContext, org, user5)) + assert.NoError(t, RemoveOrgUser(t.Context(), org, user5)) unittest.AssertNotExistsBean(t, &organization.OrgUser{UID: user5.ID, OrgID: org.ID}) org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: org.ID}) @@ -50,7 +49,7 @@ func TestRemoveOrgUser(t *testing.T) { if unittest.GetBean(t, &organization.OrgUser{OrgID: org.ID, UID: user.ID}) != nil { expectedNumMembers-- } - assert.NoError(t, RemoveOrgUser(db.DefaultContext, org, user)) + assert.NoError(t, RemoveOrgUser(t.Context(), org, user)) unittest.AssertNotExistsBean(t, &organization.OrgUser{OrgID: org.ID, UID: user.ID}) org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: org.ID}) assert.Equal(t, expectedNumMembers, org.NumMembers) @@ -66,7 +65,7 @@ func TestRemoveOrgUser(t *testing.T) { org3 = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) testSuccess(org3, user4) - err := RemoveOrgUser(db.DefaultContext, org7, user5) + err := RemoveOrgUser(t.Context(), org7, user5) assert.Error(t, err) assert.True(t, organization.IsErrLastOrgOwner(err)) unittest.AssertExistsAndLoadBean(t, &organization.OrgUser{OrgID: org7.ID, UID: user5.ID}) diff --git a/services/packages/arch/vercmp.go b/services/packages/arch/vercmp.go index d44aa530f0..f4a83d5eb1 100644 --- a/services/packages/arch/vercmp.go +++ b/services/packages/arch/vercmp.go @@ -4,16 +4,13 @@ package arch import ( + "strconv" "strings" "unicode" ) // https://gitlab.archlinux.org/pacman/pacman/-/blob/d55b47e5512808b67bc944feb20c2bcc6c1a4c45/lib/libalpm/version.c -import ( - "strconv" -) - func parseEVR(evr string) (epoch, version, release string) { if before, after, f := strings.Cut(evr, ":"); f { epoch = before diff --git a/services/packages/container/common.go b/services/packages/container/common.go index 02cbff2286..d3e2996a52 100644 --- a/services/packages/container/common.go +++ b/services/packages/container/common.go @@ -15,7 +15,7 @@ import ( "code.gitea.io/gitea/modules/packages" container_module "code.gitea.io/gitea/modules/packages/container" - "github.com/opencontainers/image-spec/specs-go/v1" + v1 "github.com/opencontainers/image-spec/specs-go/v1" ) // UpdateRepositoryNames updates the repository name property for all packages of the specific owner diff --git a/services/projects/issue_test.go b/services/projects/issue_test.go index e76d31e757..7255cdfe52 100644 --- a/services/projects/issue_test.go +++ b/services/projects/issue_test.go @@ -31,10 +31,10 @@ func Test_Projects(t *testing.T) { IssueID: 1, ProjectColumnID: 4, } - err := db.Insert(db.DefaultContext, &pi1) + err := db.Insert(t.Context(), &pi1) assert.NoError(t, err) defer func() { - _, err = db.DeleteByID[project_model.ProjectIssue](db.DefaultContext, pi1.ID) + _, err = db.DeleteByID[project_model.ProjectIssue](t.Context(), pi1.ID) assert.NoError(t, err) }() @@ -43,14 +43,14 @@ func Test_Projects(t *testing.T) { IssueID: 4, ProjectColumnID: 4, } - err = db.Insert(db.DefaultContext, &pi2) + err = db.Insert(t.Context(), &pi2) assert.NoError(t, err) defer func() { - _, err = db.DeleteByID[project_model.ProjectIssue](db.DefaultContext, pi2.ID) + _, err = db.DeleteByID[project_model.ProjectIssue](t.Context(), pi2.ID) assert.NoError(t, err) }() - projects, err := db.Find[project_model.Project](db.DefaultContext, project_model.SearchOptions{ + projects, err := db.Find[project_model.Project](t.Context(), project_model.SearchOptions{ OwnerID: user2.ID, }) assert.NoError(t, err) @@ -58,7 +58,7 @@ func Test_Projects(t *testing.T) { assert.EqualValues(t, 4, projects[0].ID) t.Run("Authenticated user", func(t *testing.T) { - columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{ Owner: user2, Doer: user2, }) @@ -68,7 +68,7 @@ func Test_Projects(t *testing.T) { }) t.Run("Anonymous user", func(t *testing.T) { - columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{ AllPublic: true, }) assert.NoError(t, err) @@ -77,7 +77,7 @@ func Test_Projects(t *testing.T) { }) t.Run("Authenticated user with no permission to the private repo", func(t *testing.T) { - columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{ Owner: user2, Doer: user4, }) @@ -94,10 +94,10 @@ func Test_Projects(t *testing.T) { Type: project_model.TypeOrganization, TemplateType: project_model.TemplateTypeBasicKanban, } - err := project_model.NewProject(db.DefaultContext, &project1) + err := project_model.NewProject(t.Context(), &project1) assert.NoError(t, err) defer func() { - err := project_model.DeleteProjectByID(db.DefaultContext, project1.ID) + err := project_model.DeleteProjectByID(t.Context(), project1.ID) assert.NoError(t, err) }() @@ -105,27 +105,27 @@ func Test_Projects(t *testing.T) { Title: "column 1", ProjectID: project1.ID, } - err = project_model.NewColumn(db.DefaultContext, &column1) + err = project_model.NewColumn(t.Context(), &column1) assert.NoError(t, err) column2 := project_model.Column{ Title: "column 2", ProjectID: project1.ID, } - err = project_model.NewColumn(db.DefaultContext, &column2) + err = project_model.NewColumn(t.Context(), &column2) assert.NoError(t, err) // issue 6 belongs to private repo 3 under org 3 issue6 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 6}) - err = issues_model.IssueAssignOrRemoveProject(db.DefaultContext, issue6, user2, project1.ID, column1.ID) + err = issues_model.IssueAssignOrRemoveProject(t.Context(), issue6, user2, project1.ID, column1.ID) assert.NoError(t, err) // issue 16 belongs to public repo 16 under org 3 issue16 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 16}) - err = issues_model.IssueAssignOrRemoveProject(db.DefaultContext, issue16, user2, project1.ID, column1.ID) + err = issues_model.IssueAssignOrRemoveProject(t.Context(), issue16, user2, project1.ID, column1.ID) assert.NoError(t, err) - projects, err := db.Find[project_model.Project](db.DefaultContext, project_model.SearchOptions{ + projects, err := db.Find[project_model.Project](t.Context(), project_model.SearchOptions{ OwnerID: org3.ID, }) assert.NoError(t, err) @@ -133,7 +133,7 @@ func Test_Projects(t *testing.T) { assert.Equal(t, project1.ID, projects[0].ID) t.Run("Authenticated user", func(t *testing.T) { - columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{ Owner: org3.AsUser(), Doer: userAdmin, }) @@ -143,7 +143,7 @@ func Test_Projects(t *testing.T) { }) t.Run("Anonymous user", func(t *testing.T) { - columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{ AllPublic: true, }) assert.NoError(t, err) @@ -152,7 +152,7 @@ func Test_Projects(t *testing.T) { }) t.Run("Authenticated user with no permission to the private repo", func(t *testing.T) { - columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{ Owner: org3.AsUser(), Doer: user2, }) @@ -165,7 +165,7 @@ func Test_Projects(t *testing.T) { t.Run("Repository projects", func(t *testing.T) { repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - projects, err := db.Find[project_model.Project](db.DefaultContext, project_model.SearchOptions{ + projects, err := db.Find[project_model.Project](t.Context(), project_model.SearchOptions{ RepoID: repo1.ID, }) assert.NoError(t, err) @@ -173,7 +173,7 @@ func Test_Projects(t *testing.T) { assert.EqualValues(t, 1, projects[0].ID) t.Run("Authenticated user", func(t *testing.T) { - columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{ RepoIDs: []int64{repo1.ID}, Doer: userAdmin, }) @@ -185,7 +185,7 @@ func Test_Projects(t *testing.T) { }) t.Run("Anonymous user", func(t *testing.T) { - columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{ AllPublic: true, }) assert.NoError(t, err) @@ -196,7 +196,7 @@ func Test_Projects(t *testing.T) { }) t.Run("Authenticated user with no permission to the private repo", func(t *testing.T) { - columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + columnIssues, err := LoadIssuesFromProject(t.Context(), projects[0], &issues_model.IssuesOptions{ RepoIDs: []int64{repo1.ID}, Doer: user2, }) diff --git a/services/pull/check_test.go b/services/pull/check_test.go index eb66615dcf..0f39237932 100644 --- a/services/pull/check_test.go +++ b/services/pull/check_test.go @@ -42,7 +42,7 @@ func TestPullRequest_AddToTaskQueue(t *testing.T) { assert.NoError(t, err) pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) - StartPullRequestCheckImmediately(db.DefaultContext, pr) + StartPullRequestCheckImmediately(t.Context(), pr) assert.Eventually(t, func() bool { pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) diff --git a/services/pull/comment.go b/services/pull/comment.go index 53587d4f54..f12edaf032 100644 --- a/services/pull/comment.go +++ b/services/pull/comment.go @@ -14,42 +14,28 @@ import ( ) // getCommitIDsFromRepo get commit IDs from repo in between oldCommitID and newCommitID -// isForcePush will be true if oldCommit isn't on the branch // Commit on baseBranch will skip -func getCommitIDsFromRepo(ctx context.Context, repo *repo_model.Repository, oldCommitID, newCommitID, baseBranch string) (commitIDs []string, isForcePush bool, err error) { +func getCommitIDsFromRepo(ctx context.Context, repo *repo_model.Repository, oldCommitID, newCommitID, baseBranch string) (commitIDs []string, err error) { gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo) if err != nil { - return nil, false, err + return nil, err } defer closer.Close() oldCommit, err := gitRepo.GetCommit(oldCommitID) if err != nil { - return nil, false, err + return nil, err } newCommit, err := gitRepo.GetCommit(newCommitID) if err != nil { - return nil, false, err - } - - isForcePush, err = newCommit.IsForcePush(oldCommitID) - if err != nil { - return nil, false, err - } - - if isForcePush { - commitIDs = make([]string, 2) - commitIDs[0] = oldCommitID - commitIDs[1] = newCommitID - - return commitIDs, isForcePush, err + return nil, err } // Find commits between new and old commit excluding base branch commits commits, err := gitRepo.CommitsBetweenNotBase(newCommit, oldCommit, baseBranch) if err != nil { - return nil, false, err + return nil, err } commitIDs = make([]string, 0, len(commits)) @@ -57,38 +43,40 @@ func getCommitIDsFromRepo(ctx context.Context, repo *repo_model.Repository, oldC commitIDs = append(commitIDs, commits[i].ID.String()) } - return commitIDs, isForcePush, err + return commitIDs, err } // CreatePushPullComment create push code to pull base comment -func CreatePushPullComment(ctx context.Context, pusher *user_model.User, pr *issues_model.PullRequest, oldCommitID, newCommitID string) (comment *issues_model.Comment, err error) { +func CreatePushPullComment(ctx context.Context, pusher *user_model.User, pr *issues_model.PullRequest, oldCommitID, newCommitID string, isForcePush bool) (comment *issues_model.Comment, err error) { if pr.HasMerged || oldCommitID == "" || newCommitID == "" { return nil, nil } - ops := &issues_model.CreateCommentOptions{ - Type: issues_model.CommentTypePullRequestPush, - Doer: pusher, - Repo: pr.BaseRepo, + opts := &issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypePullRequestPush, + Doer: pusher, + Repo: pr.BaseRepo, + IsForcePush: isForcePush, + Issue: pr.Issue, } var data issues_model.PushActionContent - - data.CommitIDs, data.IsForcePush, err = getCommitIDsFromRepo(ctx, pr.BaseRepo, oldCommitID, newCommitID, pr.BaseBranch) - if err != nil { - return nil, err + if opts.IsForcePush { + data.CommitIDs = []string{oldCommitID, newCommitID} + } else { + data.CommitIDs, err = getCommitIDsFromRepo(ctx, pr.BaseRepo, oldCommitID, newCommitID, pr.BaseBranch) + if err != nil { + return nil, err + } } - ops.Issue = pr.Issue - dataJSON, err := json.Marshal(data) if err != nil { return nil, err } - ops.Content = string(dataJSON) - - comment, err = issues_model.CreateComment(ctx, ops) + opts.Content = string(dataJSON) + comment, err = issues_model.CreateComment(ctx, opts) return comment, err } diff --git a/services/pull/compare.go b/services/pull/compare.go new file mode 100644 index 0000000000..2c4b77a772 --- /dev/null +++ b/services/pull/compare.go @@ -0,0 +1,95 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package pull + +import ( + "context" + "fmt" + "strconv" + "time" + + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/gitrepo" + "code.gitea.io/gitea/modules/graceful" + logger "code.gitea.io/gitea/modules/log" +) + +// CompareInfo represents needed information for comparing references. +type CompareInfo struct { + MergeBase string + BaseCommitID string + HeadCommitID string + Commits []*git.Commit + NumFiles int +} + +// GetCompareInfo generates and returns compare information between base and head branches of repositories. +func GetCompareInfo(ctx context.Context, baseRepo, headRepo *repo_model.Repository, headGitRepo *git.Repository, baseBranch, headBranch string, directComparison, fileOnly bool) (_ *CompareInfo, err error) { + var ( + remoteBranch string + tmpRemote string + ) + + // We don't need a temporary remote for same repository. + if headGitRepo.Path != baseRepo.RepoPath() { + // Add a temporary remote + tmpRemote = strconv.FormatInt(time.Now().UnixNano(), 10) + if err = gitrepo.GitRemoteAdd(ctx, headRepo, tmpRemote, baseRepo.RepoPath()); err != nil { + return nil, fmt.Errorf("GitRemoteAdd: %w", err) + } + defer func() { + if err := gitrepo.GitRemoteRemove(graceful.GetManager().ShutdownContext(), headRepo, tmpRemote); err != nil { + logger.Error("GetPullRequestInfo: GitRemoteRemove: %v", err) + } + }() + } + + compareInfo := new(CompareInfo) + + compareInfo.HeadCommitID, err = git.GetFullCommitID(ctx, headGitRepo.Path, headBranch) + if err != nil { + compareInfo.HeadCommitID = headBranch + } + + compareInfo.MergeBase, remoteBranch, err = headGitRepo.GetMergeBase(tmpRemote, baseBranch, headBranch) + if err == nil { + compareInfo.BaseCommitID, err = git.GetFullCommitID(ctx, headGitRepo.Path, remoteBranch) + if err != nil { + compareInfo.BaseCommitID = remoteBranch + } + separator := "..." + baseCommitID := compareInfo.MergeBase + if directComparison { + separator = ".." + baseCommitID = compareInfo.BaseCommitID + } + + // We have a common base - therefore we know that ... should work + if !fileOnly { + compareInfo.Commits, err = headGitRepo.ShowPrettyFormatLogToList(ctx, baseCommitID+separator+headBranch) + if err != nil { + return nil, fmt.Errorf("ShowPrettyFormatLogToList: %w", err) + } + } else { + compareInfo.Commits = []*git.Commit{} + } + } else { + compareInfo.Commits = []*git.Commit{} + compareInfo.MergeBase, err = git.GetFullCommitID(ctx, headGitRepo.Path, remoteBranch) + if err != nil { + compareInfo.MergeBase = remoteBranch + } + compareInfo.BaseCommitID = compareInfo.MergeBase + } + + // Count number of changed files. + // This probably should be removed as we need to use shortstat elsewhere + // Now there is git diff --shortstat but this appears to be slower than simply iterating with --nameonly + compareInfo.NumFiles, err = headGitRepo.GetDiffNumChangedFiles(remoteBranch, headBranch, directComparison) + if err != nil { + return nil, err + } + return compareInfo, nil +} diff --git a/services/pull/lfs.go b/services/pull/lfs.go index ed03583d4f..eb2a08ed8d 100644 --- a/services/pull/lfs.go +++ b/services/pull/lfs.go @@ -11,7 +11,6 @@ import ( "strconv" "sync" - "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/modules/git/pipeline" @@ -40,7 +39,7 @@ func LFSPush(ctx context.Context, tmpBasePath, mergeHeadSHA, mergeBaseSHA string // 6. Take the output of cat-file --batch and check if each file in turn // to see if they're pointers to files in the LFS store associated with // the head repo and add them to the base repo if so - go createLFSMetaObjectsFromCatFileBatch(db.DefaultContext, catFileBatchReader, &wg, pr) + go createLFSMetaObjectsFromCatFileBatch(ctx, catFileBatchReader, &wg, pr) // 5. Take the shas of the blobs and batch read them go pipeline.CatFileBatch(ctx, shasToBatchReader, catFileBatchWriter, &wg, tmpBasePath) diff --git a/services/pull/pull.go b/services/pull/pull.go index e55d4f5bb1..20d33b5331 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -28,7 +28,6 @@ import ( "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/globallock" "code.gitea.io/gitea/modules/graceful" - "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" @@ -141,36 +140,7 @@ func NewPullRequest(ctx context.Context, opts *NewPullRequestOptions) error { return err } - compareInfo, err := baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), - git.BranchPrefix+pr.BaseBranch, pr.GetGitHeadRefName(), false, false) - if err != nil { - return err - } - if len(compareInfo.Commits) == 0 { - return nil - } - - data := issues_model.PushActionContent{IsForcePush: false} - data.CommitIDs = make([]string, 0, len(compareInfo.Commits)) - for i := len(compareInfo.Commits) - 1; i >= 0; i-- { - data.CommitIDs = append(data.CommitIDs, compareInfo.Commits[i].ID.String()) - } - - dataJSON, err := json.Marshal(data) - if err != nil { - return err - } - - ops := &issues_model.CreateCommentOptions{ - Type: issues_model.CommentTypePullRequestPush, - Doer: issue.Poster, - Repo: repo, - Issue: pr.Issue, - IsForcePush: false, - Content: string(dataJSON), - } - - if _, err = issues_model.CreateComment(ctx, ops); err != nil { + if _, err := CreatePushPullComment(ctx, issue.Poster, pr, git.BranchPrefix+pr.BaseBranch, pr.GetGitHeadRefName(), false); err != nil { return err } @@ -331,24 +301,42 @@ func ChangeTargetBranch(ctx context.Context, pr *issues_model.PullRequest, doer pr.CommitsAhead = divergence.Ahead pr.CommitsBehind = divergence.Behind - if err := pr.UpdateColsIfNotMerged(ctx, "merge_base", "status", "conflicted_files", "changed_protected_files", "base_branch", "commits_ahead", "commits_behind"); err != nil { + // add first push codes comment + baseGitRepo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo) + if err != nil { return err } + defer baseGitRepo.Close() - // Create comment - options := &issues_model.CreateCommentOptions{ - Type: issues_model.CommentTypeChangeTargetBranch, - Doer: doer, - Repo: pr.Issue.Repo, - Issue: pr.Issue, - OldRef: oldBranch, - NewRef: targetBranch, - } - if _, err = issues_model.CreateComment(ctx, options); err != nil { - return fmt.Errorf("CreateChangeTargetBranchComment: %w", err) - } + return db.WithTx(ctx, func(ctx context.Context) error { + if err := pr.UpdateColsIfNotMerged(ctx, "merge_base", "status", "conflicted_files", "changed_protected_files", "base_branch", "commits_ahead", "commits_behind"); err != nil { + return err + } - return nil + // Create comment + options := &issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypeChangeTargetBranch, + Doer: doer, + Repo: pr.Issue.Repo, + Issue: pr.Issue, + OldRef: oldBranch, + NewRef: targetBranch, + } + if _, err = issues_model.CreateComment(ctx, options); err != nil { + return fmt.Errorf("CreateChangeTargetBranchComment: %w", err) + } + + // Delete all old push comments and insert new push comments + if _, err := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID). + And("type = ?", issues_model.CommentTypePullRequestPush). + NoAutoCondition(). + Delete(new(issues_model.Comment)); err != nil { + return err + } + + _, err = CreatePushPullComment(ctx, doer, pr, git.BranchPrefix+pr.BaseBranch, pr.GetGitHeadRefName(), false) + return err + }) } func checkForInvalidation(ctx context.Context, requests issues_model.PullRequestList, repoID int64, doer *user_model.User, branch string) error { @@ -409,7 +397,7 @@ func AddTestPullRequestTask(opts TestPullRequestOptions) { } StartPullRequestCheckImmediately(ctx, pr) - comment, err := CreatePushPullComment(ctx, opts.Doer, pr, opts.OldCommitID, opts.NewCommitID) + comment, err := CreatePushPullComment(ctx, opts.Doer, pr, opts.OldCommitID, opts.NewCommitID, opts.IsForcePush) if err == nil && comment != nil { notify_service.PullRequestPushCommits(ctx, opts.Doer, pr, comment) } @@ -1074,7 +1062,7 @@ func GetPullCommits(ctx context.Context, baseGitRepo *git.Repository, doer *user if pull.HasMerged { baseBranch = pull.MergeBase } - prInfo, err := baseGitRepo.GetCompareInfo(pull.BaseRepo.RepoPath(), baseBranch, pull.GetGitHeadRefName(), true, false) + prInfo, err := GetCompareInfo(ctx, pull.BaseRepo, pull.BaseRepo, baseGitRepo, baseBranch, pull.GetGitHeadRefName(), true, false) if err != nil { return nil, "", err } diff --git a/services/pull/pull_test.go b/services/pull/pull_test.go index 787910bf76..1c03ab45ae 100644 --- a/services/pull/pull_test.go +++ b/services/pull/pull_test.go @@ -7,12 +7,10 @@ package pull import ( "testing" - "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/models/unit" "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "github.com/stretchr/testify/assert" @@ -41,18 +39,18 @@ func TestPullRequest_GetDefaultMergeMessage_InternalTracker(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) - assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext)) - gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, pr.BaseRepo) + assert.NoError(t, pr.LoadBaseRepo(t.Context())) + gitRepo, err := gitrepo.OpenRepository(t.Context(), pr.BaseRepo) assert.NoError(t, err) defer gitRepo.Close() - mergeMessage, _, err := GetDefaultMergeMessage(db.DefaultContext, gitRepo, pr, "") + mergeMessage, _, err := GetDefaultMergeMessage(t.Context(), gitRepo, pr, "") assert.NoError(t, err) assert.Equal(t, "Merge pull request 'issue3' (#3) from branch2 into master", mergeMessage) pr.BaseRepoID = 1 pr.HeadRepoID = 2 - mergeMessage, _, err = GetDefaultMergeMessage(db.DefaultContext, gitRepo, pr, "") + mergeMessage, _, err = GetDefaultMergeMessage(t.Context(), gitRepo, pr, "") assert.NoError(t, err) assert.Equal(t, "Merge pull request 'issue3' (#3) from user2/repo1:branch2 into master", mergeMessage) } @@ -71,12 +69,12 @@ func TestPullRequest_GetDefaultMergeMessage_ExternalTracker(t *testing.T) { pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2, BaseRepo: baseRepo}) - assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext)) - gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, pr.BaseRepo) + assert.NoError(t, pr.LoadBaseRepo(t.Context())) + gitRepo, err := gitrepo.OpenRepository(t.Context(), pr.BaseRepo) assert.NoError(t, err) defer gitRepo.Close() - mergeMessage, _, err := GetDefaultMergeMessage(db.DefaultContext, gitRepo, pr, "") + mergeMessage, _, err := GetDefaultMergeMessage(t.Context(), gitRepo, pr, "") assert.NoError(t, err) assert.Equal(t, "Merge pull request 'issue3' (!3) from branch2 into master", mergeMessage) @@ -85,7 +83,7 @@ func TestPullRequest_GetDefaultMergeMessage_ExternalTracker(t *testing.T) { pr.HeadRepoID = 2 pr.BaseRepo = nil pr.HeadRepo = nil - mergeMessage, _, err = GetDefaultMergeMessage(db.DefaultContext, gitRepo, pr, "") + mergeMessage, _, err = GetDefaultMergeMessage(t.Context(), gitRepo, pr, "") assert.NoError(t, err) assert.Equal(t, "Merge pull request 'issue3' (#3) from user2/repo2:branch2 into master", mergeMessage) diff --git a/services/pull/review_test.go b/services/pull/review_test.go index 3bce1e523d..ddb2c04eaa 100644 --- a/services/pull/review_test.go +++ b/services/pull/review_test.go @@ -6,7 +6,6 @@ package pull_test import ( "testing" - "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -19,11 +18,11 @@ func TestDismissReview(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{}) - assert.NoError(t, pull.LoadIssue(db.DefaultContext)) + assert.NoError(t, pull.LoadIssue(t.Context())) issue := pull.Issue - assert.NoError(t, issue.LoadRepo(db.DefaultContext)) + assert.NoError(t, issue.LoadRepo(t.Context())) reviewer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - review, err := issues_model.CreateReview(db.DefaultContext, issues_model.CreateReviewOptions{ + review, err := issues_model.CreateReview(t.Context(), issues_model.CreateReviewOptions{ Issue: issue, Reviewer: reviewer, Type: issues_model.ReviewTypeReject, @@ -32,17 +31,17 @@ func TestDismissReview(t *testing.T) { assert.NoError(t, err) issue.IsClosed = true pull.HasMerged = false - assert.NoError(t, issues_model.UpdateIssueCols(db.DefaultContext, issue, "is_closed")) - assert.NoError(t, pull.UpdateCols(db.DefaultContext, "has_merged")) - _, err = pull_service.DismissReview(db.DefaultContext, review.ID, issue.RepoID, "", &user_model.User{}, false, false) + assert.NoError(t, issues_model.UpdateIssueCols(t.Context(), issue, "is_closed")) + assert.NoError(t, pull.UpdateCols(t.Context(), "has_merged")) + _, err = pull_service.DismissReview(t.Context(), review.ID, issue.RepoID, "", &user_model.User{}, false, false) assert.Error(t, err) assert.True(t, pull_service.IsErrDismissRequestOnClosedPR(err)) pull.HasMerged = true pull.Issue.IsClosed = false - assert.NoError(t, issues_model.UpdateIssueCols(db.DefaultContext, issue, "is_closed")) - assert.NoError(t, pull.UpdateCols(db.DefaultContext, "has_merged")) - _, err = pull_service.DismissReview(db.DefaultContext, review.ID, issue.RepoID, "", &user_model.User{}, false, false) + assert.NoError(t, issues_model.UpdateIssueCols(t.Context(), issue, "is_closed")) + assert.NoError(t, pull.UpdateCols(t.Context(), "has_merged")) + _, err = pull_service.DismissReview(t.Context(), review.ID, issue.RepoID, "", &user_model.User{}, false, false) assert.Error(t, err) assert.True(t, pull_service.IsErrDismissRequestOnClosedPR(err)) } diff --git a/services/pull/reviewer_test.go b/services/pull/reviewer_test.go index b106e2e89f..9fab65ce72 100644 --- a/services/pull/reviewer_test.go +++ b/services/pull/reviewer_test.go @@ -6,7 +6,6 @@ package pull_test import ( "testing" - "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" pull_service "code.gitea.io/gitea/services/pull" @@ -20,7 +19,7 @@ func TestRepoGetReviewers(t *testing.T) { // test public repo repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - ctx := db.DefaultContext + ctx := t.Context() reviewers, err := pull_service.GetReviewers(ctx, repo1, 2, 0) assert.NoError(t, err) if assert.Len(t, reviewers, 1) { @@ -61,12 +60,12 @@ func TestRepoGetReviewerTeams(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) - teams, err := pull_service.GetReviewerTeams(db.DefaultContext, repo2) + teams, err := pull_service.GetReviewerTeams(t.Context(), repo2) assert.NoError(t, err) assert.Empty(t, teams) repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) - teams, err = pull_service.GetReviewerTeams(db.DefaultContext, repo3) + teams, err = pull_service.GetReviewerTeams(t.Context(), repo3) assert.NoError(t, err) assert.Len(t, teams, 2) } diff --git a/services/release/release.go b/services/release/release.go index 0b8a74252a..1e2132bb60 100644 --- a/services/release/release.go +++ b/services/release/release.go @@ -267,74 +267,69 @@ func UpdateRelease(ctx context.Context, doer *user_model.User, gitRepo *git.Repo } rel.LowerTagName = strings.ToLower(rel.TagName) - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return err - } - defer committer.Close() - oldRelease, err := repo_model.GetReleaseByID(ctx, rel.ID) if err != nil { return err } isConvertedFromTag := oldRelease.IsTag && !rel.IsTag - if err = repo_model.UpdateRelease(ctx, rel); err != nil { - return err - } - - if err = repo_model.AddReleaseAttachments(ctx, rel.ID, addAttachmentUUIDs); err != nil { - return fmt.Errorf("AddReleaseAttachments: %w", err) - } - - deletedUUIDs := make(container.Set[string]) - if len(delAttachmentUUIDs) > 0 { - // Check attachments - attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, delAttachmentUUIDs) - if err != nil { - return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %w", delAttachmentUUIDs, err) + if err := db.WithTx(ctx, func(ctx context.Context) error { + if err = repo_model.UpdateRelease(ctx, rel); err != nil { + return err } - for _, attach := range attachments { - if attach.ReleaseID != rel.ID { - return util.NewPermissionDeniedErrorf("delete attachment of release permission denied") + + if err = repo_model.AddReleaseAttachments(ctx, rel.ID, addAttachmentUUIDs); err != nil { + return fmt.Errorf("AddReleaseAttachments: %w", err) + } + + deletedUUIDs := make(container.Set[string]) + if len(delAttachmentUUIDs) > 0 { + // Check attachments + attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, delAttachmentUUIDs) + if err != nil { + return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %w", delAttachmentUUIDs, err) + } + for _, attach := range attachments { + if attach.ReleaseID != rel.ID { + return util.NewPermissionDeniedErrorf("delete attachment of release permission denied") + } + deletedUUIDs.Add(attach.UUID) } - deletedUUIDs.Add(attach.UUID) - } - if _, err := repo_model.DeleteAttachments(ctx, attachments, true); err != nil { - return fmt.Errorf("DeleteAttachments [uuids: %v]: %w", delAttachmentUUIDs, err) - } - } - - if len(editAttachments) > 0 { - updateAttachmentsList := make([]string, 0, len(editAttachments)) - for k := range editAttachments { - updateAttachmentsList = append(updateAttachmentsList, k) - } - // Check attachments - attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, updateAttachmentsList) - if err != nil { - return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %w", updateAttachmentsList, err) - } - for _, attach := range attachments { - if attach.ReleaseID != rel.ID { - return util.NewPermissionDeniedErrorf("update attachment of release permission denied") + if _, err := repo_model.DeleteAttachments(ctx, attachments, true); err != nil { + return fmt.Errorf("DeleteAttachments [uuids: %v]: %w", delAttachmentUUIDs, err) } } - for uuid, newName := range editAttachments { - if !deletedUUIDs.Contains(uuid) { - if err = repo_model.UpdateAttachmentByUUID(ctx, &repo_model.Attachment{ - UUID: uuid, - Name: newName, - }, "name"); err != nil { - return err + if len(editAttachments) > 0 { + updateAttachmentsList := make([]string, 0, len(editAttachments)) + for k := range editAttachments { + updateAttachmentsList = append(updateAttachmentsList, k) + } + // Check attachments + attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, updateAttachmentsList) + if err != nil { + return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %w", updateAttachmentsList, err) + } + for _, attach := range attachments { + if attach.ReleaseID != rel.ID { + return util.NewPermissionDeniedErrorf("update attachment of release permission denied") + } + } + + for uuid, newName := range editAttachments { + if !deletedUUIDs.Contains(uuid) { + if err = repo_model.UpdateAttachmentByUUID(ctx, &repo_model.Attachment{ + UUID: uuid, + Name: newName, + }, "name"); err != nil { + return err + } } } } - } - - if err := committer.Commit(); err != nil { + return nil + }); err != nil { return err } diff --git a/services/release/release_test.go b/services/release/release_test.go index 36a9f667d6..ef495632a7 100644 --- a/services/release/release_test.go +++ b/services/release/release_test.go @@ -8,11 +8,9 @@ import ( "testing" "time" - "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" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/services/attachment" @@ -31,7 +29,7 @@ func TestRelease_Create(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo) + gitRepo, err := gitrepo.OpenRepository(t.Context(), repo) assert.NoError(t, err) defer gitRepo.Close() @@ -107,7 +105,7 @@ func TestRelease_Create(t *testing.T) { testPlayload := "testtest" - attach, err := attachment.NewAttachment(db.DefaultContext, &repo_model.Attachment{ + attach, err := attachment.NewAttachment(t.Context(), &repo_model.Attachment{ RepoID: repo.ID, UploaderID: user.ID, Name: "test.txt", @@ -136,7 +134,7 @@ func TestRelease_Update(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo) + gitRepo, err := gitrepo.OpenRepository(t.Context(), repo) assert.NoError(t, err) defer gitRepo.Close() @@ -154,13 +152,13 @@ func TestRelease_Update(t *testing.T) { IsPrerelease: false, IsTag: false, }, nil, "")) - release, err := repo_model.GetRelease(db.DefaultContext, repo.ID, "v1.1.1") + release, err := repo_model.GetRelease(t.Context(), 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(db.DefaultContext, user, gitRepo, release, nil, nil, nil)) - release, err = repo_model.GetReleaseByID(db.DefaultContext, release.ID) + assert.NoError(t, UpdateRelease(t.Context(), user, gitRepo, release, nil, nil, nil)) + release, err = repo_model.GetReleaseByID(t.Context(), release.ID) assert.NoError(t, err) assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix)) @@ -178,13 +176,13 @@ func TestRelease_Update(t *testing.T) { IsPrerelease: false, IsTag: false, }, nil, "")) - release, err = repo_model.GetRelease(db.DefaultContext, repo.ID, "v1.2.1") + release, err = repo_model.GetRelease(t.Context(), 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(db.DefaultContext, user, gitRepo, release, nil, nil, nil)) - release, err = repo_model.GetReleaseByID(db.DefaultContext, release.ID) + assert.NoError(t, UpdateRelease(t.Context(), user, gitRepo, release, nil, nil, nil)) + release, err = repo_model.GetReleaseByID(t.Context(), release.ID) assert.NoError(t, err) assert.Less(t, int64(releaseCreatedUnix), int64(release.CreatedUnix)) @@ -202,14 +200,14 @@ func TestRelease_Update(t *testing.T) { IsPrerelease: true, IsTag: false, }, nil, "")) - release, err = repo_model.GetRelease(db.DefaultContext, repo.ID, "v1.3.1") + release, err = repo_model.GetRelease(t.Context(), 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(db.DefaultContext, user, gitRepo, release, nil, nil, nil)) - release, err = repo_model.GetReleaseByID(db.DefaultContext, release.ID) + assert.NoError(t, UpdateRelease(t.Context(), user, gitRepo, release, nil, nil, nil)) + release, err = repo_model.GetReleaseByID(t.Context(), release.ID) assert.NoError(t, err) assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix)) @@ -233,42 +231,42 @@ func TestRelease_Update(t *testing.T) { release.IsDraft = false tagName := release.TagName - assert.NoError(t, UpdateRelease(db.DefaultContext, user, gitRepo, release, nil, nil, nil)) - release, err = repo_model.GetReleaseByID(db.DefaultContext, release.ID) + assert.NoError(t, UpdateRelease(t.Context(), user, gitRepo, release, nil, nil, nil)) + release, err = repo_model.GetReleaseByID(t.Context(), release.ID) assert.NoError(t, err) assert.Equal(t, tagName, release.TagName) // Add new attachments samplePayload := "testtest" - attach, err := attachment.NewAttachment(db.DefaultContext, &repo_model.Attachment{ + attach, err := attachment.NewAttachment(t.Context(), &repo_model.Attachment{ RepoID: repo.ID, UploaderID: user.ID, Name: "test.txt", }, strings.NewReader(samplePayload), int64(len([]byte(samplePayload)))) assert.NoError(t, err) - assert.NoError(t, UpdateRelease(db.DefaultContext, user, gitRepo, release, []string{attach.UUID}, nil, nil)) - assert.NoError(t, repo_model.GetReleaseAttachments(db.DefaultContext, release)) + assert.NoError(t, UpdateRelease(t.Context(), user, gitRepo, release, []string{attach.UUID}, nil, nil)) + assert.NoError(t, repo_model.GetReleaseAttachments(t.Context(), release)) assert.Len(t, release.Attachments, 1) assert.Equal(t, attach.UUID, release.Attachments[0].UUID) assert.Equal(t, release.ID, release.Attachments[0].ReleaseID) assert.Equal(t, attach.Name, release.Attachments[0].Name) // update the attachment name - assert.NoError(t, UpdateRelease(db.DefaultContext, user, gitRepo, release, nil, nil, map[string]string{ + assert.NoError(t, UpdateRelease(t.Context(), user, gitRepo, release, nil, nil, map[string]string{ attach.UUID: "test2.txt", })) release.Attachments = nil - assert.NoError(t, repo_model.GetReleaseAttachments(db.DefaultContext, release)) + assert.NoError(t, repo_model.GetReleaseAttachments(t.Context(), release)) assert.Len(t, release.Attachments, 1) assert.Equal(t, attach.UUID, release.Attachments[0].UUID) assert.Equal(t, release.ID, release.Attachments[0].ReleaseID) assert.Equal(t, "test2.txt", release.Attachments[0].Name) // delete the attachment - assert.NoError(t, UpdateRelease(db.DefaultContext, user, gitRepo, release, nil, []string{attach.UUID}, nil)) + assert.NoError(t, UpdateRelease(t.Context(), user, gitRepo, release, nil, []string{attach.UUID}, nil)) release.Attachments = nil - assert.NoError(t, repo_model.GetReleaseAttachments(db.DefaultContext, release)) + assert.NoError(t, repo_model.GetReleaseAttachments(t.Context(), release)) assert.Empty(t, release.Attachments) } @@ -278,7 +276,7 @@ func TestRelease_createTag(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo) + gitRepo, err := gitrepo.OpenRepository(t.Context(), repo) assert.NoError(t, err) defer gitRepo.Close() @@ -296,13 +294,13 @@ func TestRelease_createTag(t *testing.T) { IsPrerelease: false, IsTag: false, } - _, err = createTag(db.DefaultContext, gitRepo, release, "") + _, err = createTag(t.Context(), gitRepo, release, "") assert.NoError(t, err) assert.NotEmpty(t, release.CreatedUnix) releaseCreatedUnix := release.CreatedUnix time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp release.Note = "Changed note" - _, err = createTag(db.DefaultContext, gitRepo, release, "") + _, err = createTag(t.Context(), gitRepo, release, "") assert.NoError(t, err) assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix)) @@ -320,12 +318,12 @@ func TestRelease_createTag(t *testing.T) { IsPrerelease: false, IsTag: false, } - _, err = createTag(db.DefaultContext, gitRepo, release, "") + _, err = createTag(t.Context(), gitRepo, release, "") assert.NoError(t, err) releaseCreatedUnix = release.CreatedUnix time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp release.Title = "Changed title" - _, err = createTag(db.DefaultContext, gitRepo, release, "") + _, err = createTag(t.Context(), gitRepo, release, "") assert.NoError(t, err) assert.Less(t, int64(releaseCreatedUnix), int64(release.CreatedUnix)) @@ -343,13 +341,13 @@ func TestRelease_createTag(t *testing.T) { IsPrerelease: true, IsTag: false, } - _, err = createTag(db.DefaultContext, gitRepo, release, "") + _, err = createTag(t.Context(), gitRepo, release, "") 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" - _, err = createTag(db.DefaultContext, gitRepo, release, "") + _, err = createTag(t.Context(), gitRepo, release, "") assert.NoError(t, err) assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix)) } @@ -359,6 +357,6 @@ func TestCreateNewTag(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - assert.NoError(t, CreateNewTag(git.DefaultContext, user, repo, "master", "v2.0", + assert.NoError(t, CreateNewTag(t.Context(), user, repo, "master", "v2.0", "v2.0 is released \n\n BUGFIX: .... \n\n 123")) } diff --git a/services/repository/adopt.go b/services/repository/adopt.go index 2bd1c55de4..a17111dfaf 100644 --- a/services/repository/adopt.go +++ b/services/repository/adopt.go @@ -17,6 +17,7 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/gitrepo" + "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" repo_module "code.gitea.io/gitea/modules/repository" @@ -28,7 +29,7 @@ import ( ) func deleteFailedAdoptRepository(repoID int64) error { - return db.WithTx(db.DefaultContext, func(ctx context.Context) error { + return db.WithTx(graceful.GetManager().ShutdownContext(), func(ctx context.Context) error { if err := deleteDBRepository(ctx, repoID); err != nil { return fmt.Errorf("deleteDBRepository: %w", err) } diff --git a/services/repository/adopt_test.go b/services/repository/adopt_test.go index 86f586c748..46f2f48417 100644 --- a/services/repository/adopt_test.go +++ b/services/repository/adopt_test.go @@ -43,7 +43,7 @@ func TestCheckUnadoptedRepositories(t *testing.T) { // Non existent user // unadopted := &unadoptedRepositories{start: 0, end: 100} - err := checkUnadoptedRepositories(db.DefaultContext, "notauser", []string{"repo"}, unadopted) + err := checkUnadoptedRepositories(t.Context(), "notauser", []string{"repo"}, unadopted) assert.NoError(t, err) assert.Empty(t, unadopted.repositories) // @@ -54,14 +54,14 @@ func TestCheckUnadoptedRepositories(t *testing.T) { repoName := "repo2" unadoptedRepoName := "unadopted" unadopted = &unadoptedRepositories{start: 0, end: 100} - err = checkUnadoptedRepositories(db.DefaultContext, userName, []string{repoName, unadoptedRepoName}, unadopted) + err = checkUnadoptedRepositories(t.Context(), userName, []string{repoName, unadoptedRepoName}, unadopted) assert.NoError(t, err) assert.Equal(t, []string{path.Join(userName, unadoptedRepoName)}, unadopted.repositories) // // Existing (adopted) repository is not returned // unadopted = &unadoptedRepositories{start: 0, end: 100} - err = checkUnadoptedRepositories(db.DefaultContext, userName, []string{repoName}, unadopted) + err = checkUnadoptedRepositories(t.Context(), userName, []string{repoName}, unadopted) assert.NoError(t, err) assert.Empty(t, unadopted.repositories) assert.Equal(t, 0, unadopted.index) @@ -76,13 +76,13 @@ func TestListUnadoptedRepositories_ListOptions(t *testing.T) { } opts := db.ListOptions{Page: 1, PageSize: 1} - repoNames, count, err := ListUnadoptedRepositories(db.DefaultContext, "", &opts) + repoNames, count, err := ListUnadoptedRepositories(t.Context(), "", &opts) assert.NoError(t, err) assert.Equal(t, 2, count) assert.Equal(t, unadoptedList[0], repoNames[0]) opts = db.ListOptions{Page: 2, PageSize: 1} - repoNames, count, err = ListUnadoptedRepositories(db.DefaultContext, "", &opts) + repoNames, count, err = ListUnadoptedRepositories(t.Context(), "", &opts) assert.NoError(t, err) assert.Equal(t, 2, count) assert.Equal(t, unadoptedList[1], repoNames[0]) @@ -97,7 +97,7 @@ func TestAdoptRepository(t *testing.T) { destDir := filepath.Join(setting.RepoRootPath, user2.Name, "test-adopt.git") assert.NoError(t, unittest.SyncDirs(filepath.Join(setting.RepoRootPath, user2.Name, "repo1.git"), destDir)) - adoptedRepo, err := AdoptRepository(db.DefaultContext, user2, user2, CreateRepoOptions{Name: "test-adopt"}) + adoptedRepo, err := AdoptRepository(t.Context(), user2, user2, CreateRepoOptions{Name: "test-adopt"}) assert.NoError(t, err) repoTestAdopt := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "test-adopt"}) assert.Equal(t, "sha1", repoTestAdopt.ObjectFormatName) @@ -113,7 +113,7 @@ func TestAdoptRepository(t *testing.T) { _ = os.RemoveAll(filepath.Join(destDir, "hooks", "update.d")) assert.NoError(t, os.WriteFile(filepath.Join(destDir, "hooks", "update.d"), []byte("tests"), os.ModePerm)) - adoptedRepo, err = AdoptRepository(db.DefaultContext, user2, user2, CreateRepoOptions{Name: "test-adopt"}) + adoptedRepo, err = AdoptRepository(t.Context(), user2, user2, CreateRepoOptions{Name: "test-adopt"}) assert.Error(t, err) assert.Nil(t, adoptedRepo) diff --git a/services/repository/archiver/archiver_test.go b/services/repository/archiver/archiver_test.go index 87324ad38c..4ba193ccb6 100644 --- a/services/repository/archiver/archiver_test.go +++ b/services/repository/archiver/archiver_test.go @@ -7,7 +7,6 @@ import ( "testing" "time" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/services/contexttest" @@ -79,13 +78,13 @@ func TestArchive_Basic(t *testing.T) { inFlight[1] = tgzReq inFlight[2] = secondReq - doArchive(db.DefaultContext, zipReq) - doArchive(db.DefaultContext, tgzReq) - doArchive(db.DefaultContext, secondReq) + doArchive(t.Context(), zipReq) + doArchive(t.Context(), tgzReq) + doArchive(t.Context(), secondReq) // Make sure sending an unprocessed request through doesn't affect the queue // count. - doArchive(db.DefaultContext, zipReq) + doArchive(t.Context(), zipReq) // Sleep two seconds to make sure the queue doesn't change. time.Sleep(2 * time.Second) @@ -100,7 +99,7 @@ func TestArchive_Basic(t *testing.T) { // We still have the other three stalled at completion, waiting to remove // from archiveInProgress. Try to submit this new one before its // predecessor has cleared out of the queue. - doArchive(db.DefaultContext, zipReq2) + doArchive(t.Context(), zipReq2) // Now we'll submit a request and TimedWaitForCompletion twice, before and // after we release it. We should trigger both the timeout and non-timeout @@ -108,7 +107,7 @@ func TestArchive_Basic(t *testing.T) { timedReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit+".tar.gz") assert.NoError(t, err) assert.NotNil(t, timedReq) - doArchive(db.DefaultContext, timedReq) + doArchive(t.Context(), timedReq) zipReq2, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip") assert.NoError(t, err) diff --git a/services/repository/avatar_test.go b/services/repository/avatar_test.go index 2dc5173eec..6c7b9e6d26 100644 --- a/services/repository/avatar_test.go +++ b/services/repository/avatar_test.go @@ -9,7 +9,6 @@ import ( "image/png" "testing" - "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/avatar" @@ -26,7 +25,7 @@ func TestUploadAvatar(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) - err := UploadAvatar(db.DefaultContext, repo, buff.Bytes()) + err := UploadAvatar(t.Context(), repo, buff.Bytes()) assert.NoError(t, err) assert.Equal(t, avatar.HashAvatar(10, buff.Bytes()), repo.Avatar) } @@ -40,7 +39,7 @@ func TestUploadBigAvatar(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) - err := UploadAvatar(db.DefaultContext, repo, buff.Bytes()) + err := UploadAvatar(t.Context(), repo, buff.Bytes()) assert.Error(t, err) } @@ -53,10 +52,10 @@ func TestDeleteAvatar(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) - err := UploadAvatar(db.DefaultContext, repo, buff.Bytes()) + err := UploadAvatar(t.Context(), repo, buff.Bytes()) assert.NoError(t, err) - err = DeleteAvatar(db.DefaultContext, repo) + err = DeleteAvatar(t.Context(), repo) assert.NoError(t, err) assert.Empty(t, repo.Avatar) @@ -65,7 +64,7 @@ func TestDeleteAvatar(t *testing.T) { func TestGenerateAvatar(t *testing.T) { templateRepo := &repo_model.Repository{ID: 10, Avatar: "a"} generateRepo := &repo_model.Repository{ID: 11} - _ = generateAvatar(db.DefaultContext, templateRepo, generateRepo) + _ = generateAvatar(t.Context(), templateRepo, generateRepo) assert.NotEmpty(t, generateRepo.Avatar) assert.NotEqual(t, templateRepo.Avatar, generateRepo.Avatar) } diff --git a/services/repository/branch.go b/services/repository/branch.go index 6e0065b277..df7202227a 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -532,8 +532,8 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R // database branch record not exist or it's a deleted branch notExist := git_model.IsErrBranchNotExist(err) || rawBranch.IsDeleted - commit, err := gitRepo.GetBranchCommit(branchName) - if err != nil { + branchCommit, err := gitRepo.GetBranchCommit(branchName) + if err != nil && !errors.Is(err, util.ErrNotExist) { return err } @@ -549,6 +549,9 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R return fmt.Errorf("DeleteBranch: %v", err) } } + if branchCommit == nil { + return nil + } return gitRepo.DeleteBranch(branchName, git.DeleteBranchOptions{ Force: true, @@ -557,20 +560,24 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R return err } - objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName) + if branchCommit == nil { + return nil + } // Don't return error below this + + objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName) if err := PushUpdate( &repo_module.PushUpdateOptions{ RefFullName: git.RefNameFromBranch(branchName), - OldCommitID: commit.ID.String(), + OldCommitID: branchCommit.ID.String(), NewCommitID: objectFormat.EmptyObjectID().String(), PusherID: doer.ID, PusherName: doer.Name, RepoUserName: repo.OwnerName, RepoName: repo.Name, }); err != nil { - log.Error("Update: %v", err) + log.Error("PushUpdateOptions: %v", err) } return nil diff --git a/services/repository/check.go b/services/repository/check.go index ffcd5ac749..46eb4d7e7c 100644 --- a/services/repository/check.go +++ b/services/repository/check.go @@ -14,6 +14,7 @@ import ( system_model "code.gitea.io/gitea/models/system" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/util" @@ -47,10 +48,9 @@ func GitFsckRepos(ctx context.Context, timeout time.Duration, args git.TrustedCm // GitFsckRepo calls 'git fsck' to check an individual repository's health. func GitFsckRepo(ctx context.Context, repo *repo_model.Repository, timeout time.Duration, args git.TrustedCmdArgs) error { - log.Trace("Running health check on repository %-v", repo) - repoPath := repo.RepoPath() - if err := git.Fsck(ctx, repoPath, timeout, args); err != nil { - log.Warn("Failed to health check repository (%-v): %v", repo, err) + log.Trace("Running health check on repository %-v", repo.FullName()) + if err := gitrepo.Fsck(ctx, repo, timeout, args); err != nil { + log.Warn("Failed to health check repository (%-v): %v", repo.FullName(), err) if err = system_model.CreateRepositoryNotice("Failed to health check repository (%s): %v", repo.FullName(), err); err != nil { log.Error("CreateRepositoryNotice: %v", err) } @@ -190,7 +190,7 @@ func ReinitMissingRepositories(ctx context.Context) error { default: } log.Trace("Initializing %d/%d...", repo.OwnerID, repo.ID) - if err := git.InitRepository(ctx, repo.RepoPath(), true, repo.ObjectFormatName); err != nil { + if err := gitrepo.InitRepository(ctx, repo, repo.ObjectFormatName); err != nil { log.Error("Unable (re)initialize repository %d at %s. Error: %v", repo.ID, repo.RepoPath(), err) if err2 := system_model.CreateRepositoryNotice("InitRepository [%d]: %v", repo.ID, err); err2 != nil { log.Error("CreateRepositoryNotice: %v", err2) diff --git a/services/repository/collaboration_test.go b/services/repository/collaboration_test.go index 2b9a5d0b8b..5e33c50366 100644 --- a/services/repository/collaboration_test.go +++ b/services/repository/collaboration_test.go @@ -6,7 +6,6 @@ package repository import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -20,9 +19,9 @@ func TestRepository_AddCollaborator(t *testing.T) { testSuccess := func(repoID, userID int64) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) - assert.NoError(t, repo.LoadOwner(db.DefaultContext)) + assert.NoError(t, repo.LoadOwner(t.Context())) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}) - assert.NoError(t, AddOrUpdateCollaborator(db.DefaultContext, repo, user, perm.AccessModeWrite)) + assert.NoError(t, AddOrUpdateCollaborator(t.Context(), repo, user, perm.AccessModeWrite)) unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID}, &user_model.User{ID: userID}) } testSuccess(1, 4) @@ -36,11 +35,11 @@ func TestRepository_DeleteCollaboration(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) - assert.NoError(t, repo.LoadOwner(db.DefaultContext)) - assert.NoError(t, DeleteCollaboration(db.DefaultContext, repo, user)) + assert.NoError(t, repo.LoadOwner(t.Context())) + assert.NoError(t, DeleteCollaboration(t.Context(), repo, user)) unittest.AssertNotExistsBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: user.ID}) - assert.NoError(t, DeleteCollaboration(db.DefaultContext, repo, user)) + assert.NoError(t, DeleteCollaboration(t.Context(), repo, user)) unittest.AssertNotExistsBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: user.ID}) unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repo.ID}) diff --git a/services/repository/contributors_graph_test.go b/services/repository/contributors_graph_test.go index 7d32b1c931..efdecf4b81 100644 --- a/services/repository/contributors_graph_test.go +++ b/services/repository/contributors_graph_test.go @@ -7,7 +7,6 @@ import ( "slices" "testing" - "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/cache" @@ -20,7 +19,7 @@ func TestRepository_ContributorsGraph(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) - assert.NoError(t, repo.LoadOwner(db.DefaultContext)) + assert.NoError(t, repo.LoadOwner(t.Context())) mockCache, err := cache.NewStringCache(setting.Cache{}) assert.NoError(t, err) diff --git a/services/repository/create.go b/services/repository/create.go index bed02e5d7e..9f0716c191 100644 --- a/services/repository/create.go +++ b/services/repository/create.go @@ -23,6 +23,7 @@ import ( "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" + "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/options" repo_module "code.gitea.io/gitea/modules/repository" @@ -141,7 +142,7 @@ func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir // InitRepository initializes README and .gitignore if needed. func initRepository(ctx context.Context, u *user_model.User, repo *repo_model.Repository, opts CreateRepoOptions) (err error) { // Init git bare new repository. - if err = git.InitRepository(ctx, repo.RepoPath(), true, repo.ObjectFormatName); err != nil { + if err = gitrepo.InitRepository(ctx, repo, repo.ObjectFormatName); err != nil { return fmt.Errorf("git.InitRepository: %w", err) } else if err = gitrepo.CreateDelegateHooks(ctx, repo); err != nil { return fmt.Errorf("createDelegateHooks: %w", err) @@ -459,7 +460,7 @@ func createRepositoryInDB(ctx context.Context, doer, u *user_model.User, repo *r } func cleanupRepository(repoID int64) { - if errDelete := DeleteRepositoryDirectly(db.DefaultContext, repoID); errDelete != nil { + if errDelete := DeleteRepositoryDirectly(graceful.GetManager().ShutdownContext(), repoID); errDelete != nil { log.Error("cleanupRepository failed: %v", errDelete) // add system notice if err := system_model.CreateRepositoryNotice("DeleteRepositoryDirectly failed when cleanup repository: %v", errDelete); err != nil { @@ -469,7 +470,7 @@ func cleanupRepository(repoID int64) { } func updateGitRepoAfterCreate(ctx context.Context, repo *repo_model.Repository) error { - if err := checkDaemonExportOK(ctx, repo); err != nil { + if err := CheckDaemonExportOK(ctx, repo); err != nil { return fmt.Errorf("checkDaemonExportOK: %w", err) } diff --git a/services/repository/create_test.go b/services/repository/create_test.go index fe464c1441..b8c2ea59dd 100644 --- a/services/repository/create_test.go +++ b/services/repository/create_test.go @@ -7,11 +7,9 @@ import ( "os" "testing" - "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" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/assert" @@ -23,7 +21,7 @@ func TestCreateRepositoryDirectly(t *testing.T) { // a successful creating repository user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - createdRepo, err := CreateRepositoryDirectly(git.DefaultContext, user2, user2, CreateRepoOptions{ + createdRepo, err := CreateRepositoryDirectly(t.Context(), user2, user2, CreateRepoOptions{ Name: "created-repo", }, true) assert.NoError(t, err) @@ -35,14 +33,14 @@ func TestCreateRepositoryDirectly(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: user2.Name, Name: createdRepo.Name}) - err = DeleteRepositoryDirectly(db.DefaultContext, createdRepo.ID) + err = DeleteRepositoryDirectly(t.Context(), createdRepo.ID) assert.NoError(t, err) // a failed creating because some mock data // create the repository directory so that the creation will fail after database record created. assert.NoError(t, os.MkdirAll(repo_model.RepoPath(user2.Name, createdRepo.Name), os.ModePerm)) - createdRepo2, err := CreateRepositoryDirectly(db.DefaultContext, user2, user2, CreateRepoOptions{ + createdRepo2, err := CreateRepositoryDirectly(t.Context(), user2, user2, CreateRepoOptions{ Name: "created-repo", }, true) assert.Nil(t, createdRepo2) diff --git a/services/repository/delete.go b/services/repository/delete.go index c48d6e1d56..040280c8a8 100644 --- a/services/repository/delete.go +++ b/services/repository/delete.go @@ -24,6 +24,7 @@ import ( "code.gitea.io/gitea/models/webhook" actions_module "code.gitea.io/gitea/modules/actions" "code.gitea.io/gitea/modules/gitrepo" + "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/storage" @@ -309,15 +310,18 @@ func DeleteRepositoryDirectly(ctx context.Context, repoID int64, ignoreOrgTeams // Remove repository files. if err := gitrepo.DeleteRepository(ctx, repo); err != nil { desc := fmt.Sprintf("Delete repository files [%s]: %v", repo.FullName(), err) - // Note we use the db.DefaultContext here rather than passing in a context as the context may be cancelled - if err = system_model.CreateNotice(db.DefaultContext, system_model.NoticeRepository, desc); err != nil { + if err = system_model.CreateNotice(graceful.GetManager().ShutdownContext(), system_model.NoticeRepository, desc); err != nil { log.Error("CreateRepositoryNotice: %v", err) } } - // Remove wiki files - if repo.HasWiki() { - system_model.RemoveAllWithNotice(ctx, "Delete repository wiki", repo.WikiPath()) + // Remove wiki files if it exists. + if err := gitrepo.DeleteRepository(ctx, repo.WikiStorageRepo()); err != nil { + desc := fmt.Sprintf("Delete wiki repository files [%s]: %v", repo.FullName(), err) + // Note we use the db.DefaultContext here rather than passing in a context as the context may be cancelled + if err = system_model.CreateNotice(graceful.GetManager().ShutdownContext(), system_model.NoticeRepository, desc); err != nil { + log.Error("CreateRepositoryNotice: %v", err) + } } // Remove archives diff --git a/services/repository/delete_test.go b/services/repository/delete_test.go index 869b8af11d..f06373f24a 100644 --- a/services/repository/delete_test.go +++ b/services/repository/delete_test.go @@ -6,7 +6,6 @@ package repository_test import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -21,7 +20,7 @@ func TestTeam_HasRepository(t *testing.T) { test := func(teamID, repoID int64, expected bool) { team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) - assert.Equal(t, expected, repo_service.HasRepository(db.DefaultContext, team, repoID)) + assert.Equal(t, expected, repo_service.HasRepository(t.Context(), team, repoID)) } test(1, 1, false) test(1, 3, true) @@ -37,7 +36,7 @@ func TestTeam_RemoveRepository(t *testing.T) { testSuccess := func(teamID, repoID int64) { team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) - assert.NoError(t, repo_service.RemoveRepositoryFromTeam(db.DefaultContext, team, repoID)) + assert.NoError(t, repo_service.RemoveRepositoryFromTeam(t.Context(), team, repoID)) unittest.AssertNotExistsBean(t, &organization.TeamRepo{TeamID: teamID, RepoID: repoID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &repo_model.Repository{ID: repoID}) } @@ -51,5 +50,5 @@ func TestDeleteOwnerRepositoriesDirectly(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - assert.NoError(t, repo_service.DeleteOwnerRepositoriesDirectly(db.DefaultContext, user)) + assert.NoError(t, repo_service.DeleteOwnerRepositoriesDirectly(t.Context(), user)) } diff --git a/services/repository/fork_test.go b/services/repository/fork_test.go index 5375f79028..680a7f3207 100644 --- a/services/repository/fork_test.go +++ b/services/repository/fork_test.go @@ -7,11 +7,9 @@ import ( "os" "testing" - "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" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/util" @@ -26,7 +24,7 @@ func TestForkRepository(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 13}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) - fork, err := ForkRepository(git.DefaultContext, user, user, ForkRepoOptions{ + fork, err := ForkRepository(t.Context(), user, user, ForkRepoOptions{ BaseRepo: repo, Name: "test", Description: "test", @@ -42,7 +40,7 @@ func TestForkRepository(t *testing.T) { defer test.MockVariableValue(&setting.Repository.AllowForkWithoutMaximumLimit, false)() // user has reached maximum limit of repositories user.MaxRepoCreation = 0 - fork2, err := ForkRepository(git.DefaultContext, user, user, ForkRepoOptions{ + fork2, err := ForkRepository(t.Context(), user, user, ForkRepoOptions{ BaseRepo: repo, Name: "test", Description: "test", @@ -58,7 +56,7 @@ func TestForkRepositoryCleanup(t *testing.T) { user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) - fork, err := ForkRepository(git.DefaultContext, user2, user2, ForkRepoOptions{ + fork, err := ForkRepository(t.Context(), user2, user2, ForkRepoOptions{ BaseRepo: repo10, Name: "test", }) @@ -69,14 +67,14 @@ func TestForkRepositoryCleanup(t *testing.T) { assert.NoError(t, err) assert.True(t, exist) - err = DeleteRepositoryDirectly(db.DefaultContext, fork.ID) + err = DeleteRepositoryDirectly(t.Context(), fork.ID) assert.NoError(t, err) // a failed creating because some mock data // create the repository directory so that the creation will fail after database record created. assert.NoError(t, os.MkdirAll(repo_model.RepoPath(user2.Name, "test"), os.ModePerm)) - fork2, err := ForkRepository(db.DefaultContext, user2, user2, ForkRepoOptions{ + fork2, err := ForkRepository(t.Context(), user2, user2, ForkRepoOptions{ BaseRepo: repo10, Name: "test", }) diff --git a/services/repository/gitgraph/graph_test.go b/services/repository/gitgraph/graph_test.go index 93fa1aec6a..eda499840b 100644 --- a/services/repository/gitgraph/graph_test.go +++ b/services/repository/gitgraph/graph_test.go @@ -16,7 +16,7 @@ import ( ) func BenchmarkGetCommitGraph(b *testing.B) { - currentRepo, err := git.OpenRepository(git.DefaultContext, ".") + currentRepo, err := git.OpenRepository(b.Context(), ".") if err != nil || currentRepo == nil { b.Error("Could not open repository") } diff --git a/services/repository/hooks.go b/services/repository/hooks.go index c13b272550..c5bd3b8a7e 100644 --- a/services/repository/hooks.go +++ b/services/repository/hooks.go @@ -32,11 +32,12 @@ func SyncRepositoryHooks(ctx context.Context) error { } if err := gitrepo.CreateDelegateHooks(ctx, repo); err != nil { - return fmt.Errorf("SyncRepositoryHook: %w", err) + return fmt.Errorf("CreateDelegateHooks: %w", err) } - if repo.HasWiki() { + + if HasWiki(ctx, repo) { if err := gitrepo.CreateDelegateHooks(ctx, repo.WikiStorageRepo()); err != nil { - return fmt.Errorf("SyncRepositoryHook: %w", err) + return fmt.Errorf("CreateDelegateHooks: %w", err) } } return nil diff --git a/services/repository/lfs_test.go b/services/repository/lfs_test.go index 78ff8c853e..7fb202f42d 100644 --- a/services/repository/lfs_test.go +++ b/services/repository/lfs_test.go @@ -8,7 +8,6 @@ import ( "testing" "time" - "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -27,7 +26,7 @@ func TestGarbageCollectLFSMetaObjects(t *testing.T) { err := storage.Init() assert.NoError(t, err) - repo, err := repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, "user2", "repo1") + repo, err := repo_model.GetRepositoryByOwnerAndName(t.Context(), "user2", "repo1") assert.NoError(t, err) // add lfs object @@ -43,7 +42,7 @@ func TestGarbageCollectLFSMetaObjects(t *testing.T) { assert.NoError(t, err) // lfs meta has been deleted - _, err = git_model.GetLFSMetaObjectByOid(db.DefaultContext, repo.ID, lfsOid) + _, err = git_model.GetLFSMetaObjectByOid(t.Context(), repo.ID, lfsOid) assert.ErrorIs(t, err, git_model.ErrLFSObjectNotExist) } @@ -51,7 +50,7 @@ func storeObjectInRepo(t *testing.T, repositoryID int64, content *[]byte) string pointer, err := lfs.GeneratePointer(bytes.NewReader(*content)) assert.NoError(t, err) - _, err = git_model.NewLFSMetaObject(db.DefaultContext, repositoryID, pointer) + _, err = git_model.NewLFSMetaObject(t.Context(), repositoryID, pointer) assert.NoError(t, err) contentStore := lfs.NewContentStore() exist, err := contentStore.Exists(pointer) diff --git a/services/repository/migrate.go b/services/repository/migrate.go index 220d18bb2f..d468af314c 100644 --- a/services/repository/migrate.go +++ b/services/repository/migrate.go @@ -229,106 +229,88 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User, } } - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return nil, err - } - defer committer.Close() - - if opts.Mirror { - remoteAddress, err := util.SanitizeURL(opts.CloneAddr) - if err != nil { - return repo, err - } - mirrorModel := repo_model.Mirror{ - RepoID: repo.ID, - Interval: setting.Mirror.DefaultInterval, - EnablePrune: true, - NextUpdateUnix: timeutil.TimeStampNow().AddDuration(setting.Mirror.DefaultInterval), - LFS: opts.LFS, - RemoteAddress: remoteAddress, - } - if opts.LFS { - mirrorModel.LFSEndpoint = opts.LFSEndpoint - } - - if opts.MirrorInterval != "" { - parsedInterval, err := time.ParseDuration(opts.MirrorInterval) + return db.WithTx2(ctx, func(ctx context.Context) (*repo_model.Repository, error) { + if opts.Mirror { + remoteAddress, err := util.SanitizeURL(opts.CloneAddr) if err != nil { - log.Error("Failed to set Interval: %v", err) return repo, err } - if parsedInterval == 0 { - mirrorModel.Interval = 0 - mirrorModel.NextUpdateUnix = 0 - } else if parsedInterval < setting.Mirror.MinInterval { - err := fmt.Errorf("interval %s is set below Minimum Interval of %s", parsedInterval, setting.Mirror.MinInterval) - log.Error("Interval: %s is too frequent", opts.MirrorInterval) - return repo, err - } else { - mirrorModel.Interval = parsedInterval - mirrorModel.NextUpdateUnix = timeutil.TimeStampNow().AddDuration(parsedInterval) + mirrorModel := repo_model.Mirror{ + RepoID: repo.ID, + Interval: setting.Mirror.DefaultInterval, + EnablePrune: true, + NextUpdateUnix: timeutil.TimeStampNow().AddDuration(setting.Mirror.DefaultInterval), + LFS: opts.LFS, + RemoteAddress: remoteAddress, + } + if opts.LFS { + mirrorModel.LFSEndpoint = opts.LFSEndpoint + } + + if opts.MirrorInterval != "" { + parsedInterval, err := time.ParseDuration(opts.MirrorInterval) + if err != nil { + log.Error("Failed to set Interval: %v", err) + return repo, err + } + if parsedInterval == 0 { + mirrorModel.Interval = 0 + mirrorModel.NextUpdateUnix = 0 + } else if parsedInterval < setting.Mirror.MinInterval { + err := fmt.Errorf("interval %s is set below Minimum Interval of %s", parsedInterval, setting.Mirror.MinInterval) + log.Error("Interval: %s is too frequent", opts.MirrorInterval) + return repo, err + } else { + mirrorModel.Interval = parsedInterval + mirrorModel.NextUpdateUnix = timeutil.TimeStampNow().AddDuration(parsedInterval) + } + } + + if err = repo_model.InsertMirror(ctx, &mirrorModel); err != nil { + return repo, fmt.Errorf("InsertOne: %w", err) + } + + repo.IsMirror = true + if err = repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "num_watches", "is_empty", "default_branch", "default_wiki_branch", "is_mirror"); err != nil { + return nil, err + } + + if err = repo_module.UpdateRepoSize(ctx, repo); err != nil { + log.Error("Failed to update size for repository: %v", err) + } + + // this is necessary for sync local tags from remote + configName := fmt.Sprintf("remote.%s.fetch", mirrorModel.GetRemoteName()) + if stdout, _, err := git.NewCommand("config"). + AddOptionValues("--add", configName, `+refs/tags/*:refs/tags/*`). + RunStdString(ctx, &git.RunOpts{Dir: repoPath}); err != nil { + log.Error("MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*) in %v: Stdout: %s\nError: %v", repo, stdout, err) + return repo, fmt.Errorf("error in MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*): %w", err) + } + } else { + if err = repo_module.UpdateRepoSize(ctx, repo); err != nil { + log.Error("Failed to update size for repository: %v", err) + } + if repo, err = CleanUpMigrateInfo(ctx, repo); err != nil { + return nil, err } } - if err = repo_model.InsertMirror(ctx, &mirrorModel); err != nil { - return repo, fmt.Errorf("InsertOne: %w", err) + var enableRepoUnits []repo_model.RepoUnit + if opts.Releases && !unit_model.TypeReleases.UnitGlobalDisabled() { + enableRepoUnits = append(enableRepoUnits, repo_model.RepoUnit{RepoID: repo.ID, Type: unit_model.TypeReleases}) } - - repo.IsMirror = true - if err = repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "num_watches", "is_empty", "default_branch", "default_wiki_branch", "is_mirror"); err != nil { - return nil, err + if opts.Wiki && !unit_model.TypeWiki.UnitGlobalDisabled() { + enableRepoUnits = append(enableRepoUnits, repo_model.RepoUnit{RepoID: repo.ID, Type: unit_model.TypeWiki}) } - - if err = repo_module.UpdateRepoSize(ctx, repo); err != nil { - log.Error("Failed to update size for repository: %v", err) + if len(enableRepoUnits) > 0 { + err = UpdateRepositoryUnits(ctx, repo, enableRepoUnits, nil) + if err != nil { + return nil, err + } } - - // this is necessary for sync local tags from remote - configName := fmt.Sprintf("remote.%s.fetch", mirrorModel.GetRemoteName()) - if stdout, _, err := git.NewCommand("config"). - AddOptionValues("--add", configName, `+refs/tags/*:refs/tags/*`). - RunStdString(ctx, &git.RunOpts{Dir: repoPath}); err != nil { - log.Error("MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*) in %v: Stdout: %s\nError: %v", repo, stdout, err) - return repo, fmt.Errorf("error in MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*): %w", err) - } - } else { - if err = repo_module.UpdateRepoSize(ctx, repo); err != nil { - log.Error("Failed to update size for repository: %v", err) - } - if repo, err = CleanUpMigrateInfo(ctx, repo); err != nil { - return nil, err - } - } - - var enableRepoUnits []repo_model.RepoUnit - if opts.Releases && !unit_model.TypeReleases.UnitGlobalDisabled() { - enableRepoUnits = append(enableRepoUnits, repo_model.RepoUnit{RepoID: repo.ID, Type: unit_model.TypeReleases}) - } - if opts.Wiki && !unit_model.TypeWiki.UnitGlobalDisabled() { - enableRepoUnits = append(enableRepoUnits, repo_model.RepoUnit{RepoID: repo.ID, Type: unit_model.TypeWiki}) - } - if len(enableRepoUnits) > 0 { - err = UpdateRepositoryUnits(ctx, repo, enableRepoUnits, nil) - if err != nil { - return nil, err - } - } - return repo, committer.Commit() -} - -// cleanUpMigrateGitConfig removes mirror info which prevents "push --all". -// This also removes possible user credentials. -func cleanUpMigrateGitConfig(ctx context.Context, repoPath string) error { - cmd := git.NewCommand("remote", "rm", "origin") - // if the origin does not exist - _, _, err := cmd.RunStdString(ctx, &git.RunOpts{ - Dir: repoPath, + return repo, nil }) - if err != nil && !git.IsRemoteNotExistError(err) { - return err - } - return nil } // CleanUpMigrateInfo finishes migrating repository and/or wiki with things that don't need to be done for mirrors. @@ -336,19 +318,22 @@ func CleanUpMigrateInfo(ctx context.Context, repo *repo_model.Repository) (*repo if err := gitrepo.CreateDelegateHooks(ctx, repo); err != nil { return repo, fmt.Errorf("createDelegateHooks: %w", err) } - if repo.HasWiki() { + + hasWiki := HasWiki(ctx, repo) + if hasWiki { if err := gitrepo.CreateDelegateHooks(ctx, repo.WikiStorageRepo()); err != nil { return repo, fmt.Errorf("createDelegateHooks.(wiki): %w", err) } } - _, _, err := git.NewCommand("remote", "rm", "origin").RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}) + err := gitrepo.GitRemoteRemove(ctx, repo, "origin") if err != nil && !git.IsRemoteNotExistError(err) { return repo, fmt.Errorf("CleanUpMigrateInfo: %w", err) } - if repo.HasWiki() { - if err := cleanUpMigrateGitConfig(ctx, repo.WikiPath()); err != nil { + if hasWiki { + err = gitrepo.GitRemoteRemove(ctx, repo.WikiStorageRepo(), "origin") + if err != nil && !git.IsRemoteNotExistError(err) { return repo, fmt.Errorf("cleanUpMigrateGitConfig (wiki): %w", err) } } diff --git a/services/repository/repo_team_test.go b/services/repository/repo_team_test.go index 70b1b47d0a..1139d06cf8 100644 --- a/services/repository/repo_team_test.go +++ b/services/repository/repo_team_test.go @@ -6,7 +6,6 @@ package repository import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -20,7 +19,7 @@ func TestTeam_AddRepository(t *testing.T) { 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(db.DefaultContext, team, repo)) + assert.NoError(t, TeamAddRepository(t.Context(), team, repo)) unittest.AssertExistsAndLoadBean(t, &organization.TeamRepo{TeamID: teamID, RepoID: repoID}) unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &repo_model.Repository{ID: repoID}) } @@ -29,6 +28,6 @@ func TestTeam_AddRepository(t *testing.T) { team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - assert.Error(t, TeamAddRepository(db.DefaultContext, team, repo)) + assert.Error(t, TeamAddRepository(t.Context(), team, repo)) unittest.CheckConsistencyFor(t, &organization.Team{ID: 1}, &repo_model.Repository{ID: 1}) } diff --git a/services/repository/repository.go b/services/repository/repository.go index e574dc6c01..acc5ce56cf 100644 --- a/services/repository/repository.go +++ b/services/repository/repository.go @@ -20,6 +20,7 @@ import ( 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/gitrepo" "code.gitea.io/gitea/modules/graceful" issue_indexer "code.gitea.io/gitea/modules/indexer/issues" "code.gitea.io/gitea/modules/log" @@ -142,7 +143,7 @@ func MakeRepoPublic(ctx context.Context, repo *repo_model.Repository) (err error } // Create/Remove git-daemon-export-ok for git-daemon... - if err := checkDaemonExportOK(ctx, repo); err != nil { + if err := CheckDaemonExportOK(ctx, repo); err != nil { return err } @@ -197,7 +198,7 @@ func MakeRepoPrivate(ctx context.Context, repo *repo_model.Repository) (err erro } // Create/Remove git-daemon-export-ok for git-daemon... - if err := checkDaemonExportOK(ctx, repo); err != nil { + if err := CheckDaemonExportOK(ctx, repo); err != nil { return err } @@ -243,8 +244,8 @@ func LinkedRepository(ctx context.Context, a *repo_model.Attachment) (*repo_mode return nil, -1, nil } -// checkDaemonExportOK creates/removes git-daemon-export-ok for git-daemon... -func checkDaemonExportOK(ctx context.Context, repo *repo_model.Repository) error { +// CheckDaemonExportOK creates/removes git-daemon-export-ok for git-daemon... +func CheckDaemonExportOK(ctx context.Context, repo *repo_model.Repository) error { if err := repo.LoadOwner(ctx); err != nil { return err } @@ -314,7 +315,7 @@ func updateRepository(ctx context.Context, repo *repo_model.Repository, visibili } // Create/Remove git-daemon-export-ok for git-daemon... - if err := checkDaemonExportOK(ctx, repo); err != nil { + if err := CheckDaemonExportOK(ctx, repo); err != nil { return err } @@ -336,3 +337,11 @@ func updateRepository(ctx context.Context, repo *repo_model.Repository, visibili return nil } + +func HasWiki(ctx context.Context, repo *repo_model.Repository) bool { + hasWiki, err := gitrepo.IsRepositoryExist(ctx, repo.WikiStorageRepo()) + if err != nil { + log.Error("gitrepo.IsRepositoryExist: %v", err) + } + return hasWiki && err == nil +} diff --git a/services/repository/repository_test.go b/services/repository/repository_test.go index 8f9fdf8fa1..5673a4a161 100644 --- a/services/repository/repository_test.go +++ b/services/repository/repository_test.go @@ -30,9 +30,9 @@ func TestLinkedRepository(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - attach, err := repo_model.GetAttachmentByID(db.DefaultContext, tc.attachID) + attach, err := repo_model.GetAttachmentByID(t.Context(), tc.attachID) assert.NoError(t, err) - repo, unitType, err := LinkedRepository(db.DefaultContext, attach) + repo, unitType, err := LinkedRepository(t.Context(), attach) assert.NoError(t, err) if tc.expectedRepo != nil { assert.Equal(t, tc.expectedRepo.ID, repo.ID) @@ -46,18 +46,27 @@ func TestUpdateRepositoryVisibilityChanged(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // Get sample repo and change visibility - repo, err := repo_model.GetRepositoryByID(db.DefaultContext, 9) + repo, err := repo_model.GetRepositoryByID(t.Context(), 9) assert.NoError(t, err) repo.IsPrivate = true // Update it - err = updateRepository(db.DefaultContext, repo, true) + err = updateRepository(t.Context(), repo, true) assert.NoError(t, err) // Check visibility of action has become private act := activities_model.Action{} - _, err = db.GetEngine(db.DefaultContext).ID(3).Get(&act) + _, err = db.GetEngine(t.Context()).ID(3).Get(&act) assert.NoError(t, err) assert.True(t, act.IsPrivate) } + +func TestRepository_HasWiki(t *testing.T) { + unittest.PrepareTestEnv(t) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + assert.True(t, HasWiki(t.Context(), repo1)) + + repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) + assert.False(t, HasWiki(t.Context(), repo2)) +} diff --git a/services/repository/template.go b/services/repository/template.go index 6906a60083..7444bf7b60 100644 --- a/services/repository/template.go +++ b/services/repository/template.go @@ -13,7 +13,6 @@ import ( issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" notify_service "code.gitea.io/gitea/services/notify" @@ -122,7 +121,7 @@ func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templ } // 3 -Init git bare new repository. - if err = git.InitRepository(ctx, generateRepo.RepoPath(), true, generateRepo.ObjectFormatName); err != nil { + if err = gitrepo.InitRepository(ctx, generateRepo, generateRepo.ObjectFormatName); err != nil { return nil, fmt.Errorf("git.InitRepository: %w", err) } else if err = gitrepo.CreateDelegateHooks(ctx, generateRepo); err != nil { return nil, fmt.Errorf("createDelegateHooks: %w", err) diff --git a/services/repository/transfer.go b/services/repository/transfer.go index 5ad63cca67..c30a540137 100644 --- a/services/repository/transfer.go +++ b/services/repository/transfer.go @@ -358,14 +358,9 @@ func changeRepositoryName(ctx context.Context, repo *repo_model.Repository, newR return fmt.Errorf("rename repository directory: %w", err) } - wikiPath := repo.WikiPath() - isExist, err := util.IsExist(wikiPath) - if err != nil { - log.Error("Unable to check if %s exists. Error: %v", wikiPath, err) - return err - } - if isExist { - if err = util.Rename(wikiPath, repo_model.WikiPath(repo.Owner.Name, newRepoName)); err != nil { + if HasWiki(ctx, repo) { + if err = gitrepo.RenameRepository(ctx, repo.WikiStorageRepo(), repo_model.StorageRepo( + repo_model.RelativeWikiPath(repo.OwnerName, newRepoName))); err != nil { return fmt.Errorf("rename repository wiki: %w", err) } } diff --git a/services/repository/transfer_test.go b/services/repository/transfer_test.go index 80a073e9f9..8d73fef7f4 100644 --- a/services/repository/transfer_test.go +++ b/services/repository/transfer_test.go @@ -8,7 +8,6 @@ import ( "testing" 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" repo_model "code.gitea.io/gitea/models/repo" @@ -39,10 +38,10 @@ func TestTransferOwnership(t *testing.T) { doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) - assert.NoError(t, repo.LoadOwner(db.DefaultContext)) + assert.NoError(t, repo.LoadOwner(t.Context())) repoTransfer := unittest.AssertExistsAndLoadBean(t, &repo_model.RepoTransfer{ID: 1}) - assert.NoError(t, repoTransfer.LoadAttributes(db.DefaultContext)) - assert.NoError(t, AcceptTransferOwnership(db.DefaultContext, repo, doer)) + assert.NoError(t, repoTransfer.LoadAttributes(t.Context())) + assert.NoError(t, AcceptTransferOwnership(t.Context(), repo, doer)) transferredRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) assert.EqualValues(t, 1, transferredRepo.OwnerID) // repo_transfer.yml id=1 @@ -70,15 +69,15 @@ func TestStartRepositoryTransferSetPermission(t *testing.T) { doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) recipient := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) - assert.NoError(t, repo.LoadOwner(db.DefaultContext)) + assert.NoError(t, repo.LoadOwner(t.Context())) - hasAccess, err := access_model.HasAnyUnitAccess(db.DefaultContext, recipient.ID, repo) + hasAccess, err := access_model.HasAnyUnitAccess(t.Context(), recipient.ID, repo) assert.NoError(t, err) assert.False(t, hasAccess) - assert.NoError(t, StartRepositoryTransfer(db.DefaultContext, doer, recipient, repo, nil)) + assert.NoError(t, StartRepositoryTransfer(t.Context(), doer, recipient, repo, nil)) - hasAccess, err = access_model.HasAnyUnitAccess(db.DefaultContext, recipient.ID, repo) + hasAccess, err = access_model.HasAnyUnitAccess(t.Context(), recipient.ID, repo) assert.NoError(t, err) assert.True(t, hasAccess) @@ -91,41 +90,41 @@ func TestRepositoryTransfer(t *testing.T) { doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) - transfer, err := repo_model.GetPendingRepositoryTransfer(db.DefaultContext, repo) + transfer, err := repo_model.GetPendingRepositoryTransfer(t.Context(), repo) assert.NoError(t, err) assert.NotNil(t, transfer) // Cancel transfer - assert.NoError(t, CancelRepositoryTransfer(db.DefaultContext, transfer, doer)) + assert.NoError(t, CancelRepositoryTransfer(t.Context(), transfer, doer)) - transfer, err = repo_model.GetPendingRepositoryTransfer(db.DefaultContext, repo) + transfer, err = repo_model.GetPendingRepositoryTransfer(t.Context(), repo) assert.Error(t, err) assert.Nil(t, transfer) assert.True(t, repo_model.IsErrNoPendingTransfer(err)) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - assert.NoError(t, repo_model.CreatePendingRepositoryTransfer(db.DefaultContext, doer, user2, repo.ID, nil)) + assert.NoError(t, repo_model.CreatePendingRepositoryTransfer(t.Context(), doer, user2, repo.ID, nil)) - transfer, err = repo_model.GetPendingRepositoryTransfer(db.DefaultContext, repo) + transfer, err = repo_model.GetPendingRepositoryTransfer(t.Context(), repo) assert.NoError(t, err) - assert.NoError(t, transfer.LoadAttributes(db.DefaultContext)) + assert.NoError(t, transfer.LoadAttributes(t.Context())) assert.Equal(t, "user2", transfer.Recipient.Name) org6 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Only transfer can be started at any given time - err = repo_model.CreatePendingRepositoryTransfer(db.DefaultContext, doer, org6, repo.ID, nil) + err = repo_model.CreatePendingRepositoryTransfer(t.Context(), doer, org6, repo.ID, nil) assert.Error(t, err) assert.True(t, repo_model.IsErrRepoTransferInProgress(err)) repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) // Unknown user, transfer non-existent transfer repo id = 2 - err = repo_model.CreatePendingRepositoryTransfer(db.DefaultContext, doer, &user_model.User{ID: 1000, LowerName: "user1000"}, repo2.ID, nil) + err = repo_model.CreatePendingRepositoryTransfer(t.Context(), doer, &user_model.User{ID: 1000, LowerName: "user1000"}, repo2.ID, nil) assert.Error(t, err) // Reject transfer - err = RejectRepositoryTransfer(db.DefaultContext, repo2, doer) + err = RejectRepositoryTransfer(t.Context(), repo2, doer) assert.True(t, repo_model.IsErrNoPendingTransfer(err)) } @@ -139,29 +138,29 @@ func TestRepositoryTransferRejection(t *testing.T) { doerAdmin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 5}) - transfer, err := repo_model.GetPendingRepositoryTransfer(db.DefaultContext, repo) + transfer, err := repo_model.GetPendingRepositoryTransfer(t.Context(), repo) require.NoError(t, err) require.NotNil(t, transfer) - require.NoError(t, transfer.LoadRecipient(db.DefaultContext)) + require.NoError(t, transfer.LoadRecipient(t.Context())) require.True(t, doerAdmin.CanCreateRepoIn(transfer.Recipient)) // admin is not subject to limits // Administrator should not be affected by the limits so transfer should be successful - assert.NoError(t, AcceptTransferOwnership(db.DefaultContext, repo, doerAdmin)) + assert.NoError(t, AcceptTransferOwnership(t.Context(), repo, doerAdmin)) // Non admin user case doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10}) repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 21}) - transfer, err = repo_model.GetPendingRepositoryTransfer(db.DefaultContext, repo) + transfer, err = repo_model.GetPendingRepositoryTransfer(t.Context(), repo) require.NoError(t, err) require.NotNil(t, transfer) - require.NoError(t, transfer.LoadRecipient(db.DefaultContext)) + require.NoError(t, transfer.LoadRecipient(t.Context())) require.False(t, doer.CanCreateRepoIn(transfer.Recipient)) // regular user is subject to limits // Cannot accept because of the limit - err = AcceptTransferOwnership(db.DefaultContext, repo, doer) + err = AcceptTransferOwnership(t.Context(), repo, doer) assert.Error(t, err) assert.True(t, IsRepositoryLimitReached(err)) } diff --git a/services/task/task.go b/services/task/task.go index ee5fa1f348..86cf6a041f 100644 --- a/services/task/task.go +++ b/services/task/task.go @@ -9,7 +9,6 @@ import ( "fmt" 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" "code.gitea.io/gitea/modules/graceful" @@ -50,7 +49,7 @@ func Init() error { func handler(items ...*admin_model.Task) []*admin_model.Task { for _, task := range items { - if err := Run(db.DefaultContext, task); err != nil { + if err := Run(graceful.GetManager().ShutdownContext(), task); err != nil { log.Error("Run task failed: %v", err) } } diff --git a/services/uinotification/notify.go b/services/uinotification/notify.go index be5f7019a2..dd3f1557c6 100644 --- a/services/uinotification/notify.go +++ b/services/uinotification/notify.go @@ -52,7 +52,7 @@ func NewNotifier() notify_service.Notifier { func handler(items ...issueNotificationOpts) []issueNotificationOpts { for _, opts := range items { - if err := activities_model.CreateOrUpdateIssueNotifications(db.DefaultContext, opts.IssueID, opts.CommentID, opts.NotificationAuthorID, opts.ReceiverID); err != nil { + if err := activities_model.CreateOrUpdateIssueNotifications(graceful.GetManager().ShutdownContext(), opts.IssueID, opts.CommentID, opts.NotificationAuthorID, opts.ReceiverID); err != nil { log.Error("Was unable to create issue notification: %v", err) } } diff --git a/services/user/block_test.go b/services/user/block_test.go index aec3e03cf3..5dc6c1210d 100644 --- a/services/user/block_test.go +++ b/services/user/block_test.go @@ -6,7 +6,6 @@ package user import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -23,23 +22,23 @@ func TestCanBlockUser(t *testing.T) { org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // Doer can't self block - assert.False(t, CanBlockUser(db.DefaultContext, user1, user2, user1)) + assert.False(t, CanBlockUser(t.Context(), user1, user2, user1)) // Blocker can't be blockee - assert.False(t, CanBlockUser(db.DefaultContext, user1, user2, user2)) + assert.False(t, CanBlockUser(t.Context(), user1, user2, user2)) // Can't block already blocked user - assert.False(t, CanBlockUser(db.DefaultContext, user1, user2, user29)) + assert.False(t, CanBlockUser(t.Context(), user1, user2, user29)) // Blockee can't be an organization - assert.False(t, CanBlockUser(db.DefaultContext, user1, user2, org3)) + assert.False(t, CanBlockUser(t.Context(), user1, user2, org3)) // Doer must be blocker or admin - assert.False(t, CanBlockUser(db.DefaultContext, user2, user4, user29)) + assert.False(t, CanBlockUser(t.Context(), user2, user4, user29)) // Organization can't block a member - assert.False(t, CanBlockUser(db.DefaultContext, user1, org3, user4)) + assert.False(t, CanBlockUser(t.Context(), user1, org3, user4)) // Doer must be organization owner or admin if blocker is an organization - assert.False(t, CanBlockUser(db.DefaultContext, user4, org3, user2)) + assert.False(t, CanBlockUser(t.Context(), user4, org3, user2)) - assert.True(t, CanBlockUser(db.DefaultContext, user1, user2, user4)) - assert.True(t, CanBlockUser(db.DefaultContext, user2, user2, user4)) - assert.True(t, CanBlockUser(db.DefaultContext, user2, org3, user29)) + assert.True(t, CanBlockUser(t.Context(), user1, user2, user4)) + assert.True(t, CanBlockUser(t.Context(), user2, user2, user4)) + assert.True(t, CanBlockUser(t.Context(), user2, org3, user29)) } func TestCanUnblockUser(t *testing.T) { @@ -52,15 +51,15 @@ func TestCanUnblockUser(t *testing.T) { org17 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 17}) // Doer can't self unblock - assert.False(t, CanUnblockUser(db.DefaultContext, user1, user2, user1)) + assert.False(t, CanUnblockUser(t.Context(), user1, user2, user1)) // Can't unblock not blocked user - assert.False(t, CanUnblockUser(db.DefaultContext, user1, user2, user28)) + assert.False(t, CanUnblockUser(t.Context(), user1, user2, user28)) // Doer must be blocker or admin - assert.False(t, CanUnblockUser(db.DefaultContext, user28, user2, user29)) + assert.False(t, CanUnblockUser(t.Context(), user28, user2, user29)) // Doer must be organization owner or admin if blocker is an organization - assert.False(t, CanUnblockUser(db.DefaultContext, user2, org17, user28)) + assert.False(t, CanUnblockUser(t.Context(), user2, org17, user28)) - assert.True(t, CanUnblockUser(db.DefaultContext, user1, user2, user29)) - assert.True(t, CanUnblockUser(db.DefaultContext, user2, user2, user29)) - assert.True(t, CanUnblockUser(db.DefaultContext, user1, org17, user28)) + assert.True(t, CanUnblockUser(t.Context(), user1, user2, user29)) + assert.True(t, CanUnblockUser(t.Context(), user2, user2, user29)) + assert.True(t, CanUnblockUser(t.Context(), user1, org17, user28)) } diff --git a/services/user/email_test.go b/services/user/email_test.go index b40f86b6a6..78770633d2 100644 --- a/services/user/email_test.go +++ b/services/user/email_test.go @@ -6,7 +6,6 @@ package user import ( "testing" - "code.gitea.io/gitea/models/db" organization_model "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -21,23 +20,23 @@ func TestAdminAddOrSetPrimaryEmailAddress(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 27}) - emails, err := user_model.GetEmailAddresses(db.DefaultContext, user.ID) + emails, err := user_model.GetEmailAddresses(t.Context(), user.ID) assert.NoError(t, err) assert.Len(t, emails, 1) - primary, err := user_model.GetPrimaryEmailAddressOfUser(db.DefaultContext, user.ID) + primary, err := user_model.GetPrimaryEmailAddressOfUser(t.Context(), user.ID) assert.NoError(t, err) assert.NotEqual(t, "new-primary@example.com", primary.Email) assert.Equal(t, user.Email, primary.Email) - assert.NoError(t, AdminAddOrSetPrimaryEmailAddress(db.DefaultContext, user, "new-primary@example.com")) + assert.NoError(t, AdminAddOrSetPrimaryEmailAddress(t.Context(), user, "new-primary@example.com")) - primary, err = user_model.GetPrimaryEmailAddressOfUser(db.DefaultContext, user.ID) + primary, err = user_model.GetPrimaryEmailAddressOfUser(t.Context(), user.ID) assert.NoError(t, err) assert.Equal(t, "new-primary@example.com", primary.Email) assert.Equal(t, user.Email, primary.Email) - emails, err = user_model.GetEmailAddresses(db.DefaultContext, user.ID) + emails, err = user_model.GetEmailAddresses(t.Context(), user.ID) assert.NoError(t, err) assert.Len(t, emails, 2) @@ -46,21 +45,21 @@ func TestAdminAddOrSetPrimaryEmailAddress(t *testing.T) { setting.Service.EmailDomainAllowList = []glob.Glob{} }() - assert.NoError(t, AdminAddOrSetPrimaryEmailAddress(db.DefaultContext, user, "new-primary2@example2.com")) + assert.NoError(t, AdminAddOrSetPrimaryEmailAddress(t.Context(), user, "new-primary2@example2.com")) - primary, err = user_model.GetPrimaryEmailAddressOfUser(db.DefaultContext, user.ID) + primary, err = user_model.GetPrimaryEmailAddressOfUser(t.Context(), user.ID) assert.NoError(t, err) assert.Equal(t, "new-primary2@example2.com", primary.Email) assert.Equal(t, user.Email, primary.Email) - assert.NoError(t, AdminAddOrSetPrimaryEmailAddress(db.DefaultContext, user, "user27@example.com")) + assert.NoError(t, AdminAddOrSetPrimaryEmailAddress(t.Context(), user, "user27@example.com")) - primary, err = user_model.GetPrimaryEmailAddressOfUser(db.DefaultContext, user.ID) + primary, err = user_model.GetPrimaryEmailAddressOfUser(t.Context(), user.ID) assert.NoError(t, err) assert.Equal(t, "user27@example.com", primary.Email) assert.Equal(t, user.Email, primary.Email) - emails, err = user_model.GetEmailAddresses(db.DefaultContext, user.ID) + emails, err = user_model.GetEmailAddresses(t.Context(), user.ID) assert.NoError(t, err) assert.Len(t, emails, 3) } @@ -71,27 +70,27 @@ func TestReplacePrimaryEmailAddress(t *testing.T) { t.Run("User", func(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 13}) - emails, err := user_model.GetEmailAddresses(db.DefaultContext, user.ID) + emails, err := user_model.GetEmailAddresses(t.Context(), user.ID) assert.NoError(t, err) assert.Len(t, emails, 1) - primary, err := user_model.GetPrimaryEmailAddressOfUser(db.DefaultContext, user.ID) + primary, err := user_model.GetPrimaryEmailAddressOfUser(t.Context(), user.ID) assert.NoError(t, err) assert.NotEqual(t, "primary-13@example.com", primary.Email) assert.Equal(t, user.Email, primary.Email) - assert.NoError(t, ReplacePrimaryEmailAddress(db.DefaultContext, user, "primary-13@example.com")) + assert.NoError(t, ReplacePrimaryEmailAddress(t.Context(), user, "primary-13@example.com")) - primary, err = user_model.GetPrimaryEmailAddressOfUser(db.DefaultContext, user.ID) + primary, err = user_model.GetPrimaryEmailAddressOfUser(t.Context(), user.ID) assert.NoError(t, err) assert.Equal(t, "primary-13@example.com", primary.Email) assert.Equal(t, user.Email, primary.Email) - emails, err = user_model.GetEmailAddresses(db.DefaultContext, user.ID) + emails, err = user_model.GetEmailAddresses(t.Context(), user.ID) assert.NoError(t, err) assert.Len(t, emails, 1) - assert.NoError(t, ReplacePrimaryEmailAddress(db.DefaultContext, user, "primary-13@example.com")) + assert.NoError(t, ReplacePrimaryEmailAddress(t.Context(), user, "primary-13@example.com")) }) t.Run("Organization", func(t *testing.T) { @@ -99,7 +98,7 @@ func TestReplacePrimaryEmailAddress(t *testing.T) { assert.Equal(t, "org3@example.com", org.Email) - assert.NoError(t, ReplacePrimaryEmailAddress(db.DefaultContext, org.AsUser(), "primary-org@example.com")) + assert.NoError(t, ReplacePrimaryEmailAddress(t.Context(), org.AsUser(), "primary-org@example.com")) assert.Equal(t, "primary-org@example.com", org.Email) }) @@ -110,13 +109,13 @@ func TestAddEmailAddresses(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - assert.Error(t, AddEmailAddresses(db.DefaultContext, user, []string{" invalid email "})) + assert.Error(t, AddEmailAddresses(t.Context(), user, []string{" invalid email "})) emails := []string{"user1234@example.com", "user5678@example.com"} - assert.NoError(t, AddEmailAddresses(db.DefaultContext, user, emails)) + assert.NoError(t, AddEmailAddresses(t.Context(), user, emails)) - err := AddEmailAddresses(db.DefaultContext, user, emails) + err := AddEmailAddresses(t.Context(), user, emails) assert.Error(t, err) assert.True(t, user_model.IsErrEmailAlreadyUsed(err)) } @@ -128,16 +127,16 @@ func TestDeleteEmailAddresses(t *testing.T) { emails := []string{"user2-2@example.com"} - err := DeleteEmailAddresses(db.DefaultContext, user, emails) + err := DeleteEmailAddresses(t.Context(), user, emails) assert.NoError(t, err) - err = DeleteEmailAddresses(db.DefaultContext, user, emails) + err = DeleteEmailAddresses(t.Context(), user, emails) assert.Error(t, err) assert.True(t, user_model.IsErrEmailAddressNotExist(err)) emails = []string{"user2@example.com"} - err = DeleteEmailAddresses(db.DefaultContext, user, emails) + err = DeleteEmailAddresses(t.Context(), user, emails) assert.Error(t, err) assert.True(t, user_model.IsErrPrimaryEmailCannotDelete(err)) } diff --git a/services/user/update_test.go b/services/user/update_test.go index 27513e8040..b81ac95783 100644 --- a/services/user/update_test.go +++ b/services/user/update_test.go @@ -6,7 +6,6 @@ package user import ( "testing" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" password_module "code.gitea.io/gitea/modules/auth/password" @@ -21,11 +20,11 @@ func TestUpdateUser(t *testing.T) { admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - assert.Error(t, UpdateUser(db.DefaultContext, admin, &UpdateOptions{ + assert.Error(t, UpdateUser(t.Context(), admin, &UpdateOptions{ IsAdmin: UpdateOptionFieldFromValue(false), })) - assert.NoError(t, UpdateUser(db.DefaultContext, admin, &UpdateOptions{ + assert.NoError(t, UpdateUser(t.Context(), admin, &UpdateOptions{ IsAdmin: UpdateOptionFieldFromSync(false), })) @@ -52,7 +51,7 @@ func TestUpdateUser(t *testing.T) { EmailNotificationsPreference: optional.Some("disabled"), SetLastLogin: true, } - assert.NoError(t, UpdateUser(db.DefaultContext, user, opts)) + assert.NoError(t, UpdateUser(t.Context(), user, opts)) assert.Equal(t, opts.KeepEmailPrivate.Value(), user.KeepEmailPrivate) assert.Equal(t, opts.FullName.Value(), user.FullName) @@ -100,12 +99,12 @@ func TestUpdateAuth(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 28}) userCopy := *user - assert.NoError(t, UpdateAuth(db.DefaultContext, user, &UpdateAuthOptions{ + assert.NoError(t, UpdateAuth(t.Context(), user, &UpdateAuthOptions{ LoginName: optional.Some("new-login"), })) assert.Equal(t, "new-login", user.LoginName) - assert.NoError(t, UpdateAuth(db.DefaultContext, user, &UpdateAuthOptions{ + assert.NoError(t, UpdateAuth(t.Context(), user, &UpdateAuthOptions{ Password: optional.Some("%$DRZUVB576tfzgu"), MustChangePassword: optional.Some(true), })) @@ -113,12 +112,12 @@ func TestUpdateAuth(t *testing.T) { assert.NotEqual(t, userCopy.Passwd, user.Passwd) assert.NotEqual(t, userCopy.Salt, user.Salt) - assert.NoError(t, UpdateAuth(db.DefaultContext, user, &UpdateAuthOptions{ + assert.NoError(t, UpdateAuth(t.Context(), user, &UpdateAuthOptions{ ProhibitLogin: optional.Some(true), })) assert.True(t, user.ProhibitLogin) - assert.ErrorIs(t, UpdateAuth(db.DefaultContext, user, &UpdateAuthOptions{ + assert.ErrorIs(t, UpdateAuth(t.Context(), user, &UpdateAuthOptions{ Password: optional.Some("aaaa"), }), password_module.ErrMinLength) } diff --git a/services/user/user.go b/services/user/user.go index c7252430de..d8abf199c3 100644 --- a/services/user/user.go +++ b/services/user/user.go @@ -210,65 +210,59 @@ func DeleteUser(ctx context.Context, u *user_model.User, purge bool) error { } } - ctx, committer, err := db.TxContext(ctx) - if err != nil { + if err := db.WithTx(ctx, func(ctx context.Context) error { + // Note: A user owns any repository or belongs to any organization + // cannot perform delete operation. This causes a race with the purge above + // however consistency requires that we ensure that this is the case + + // Check ownership of repository. + count, err := repo_model.CountRepositories(ctx, repo_model.CountRepositoryOptions{OwnerID: u.ID}) + if err != nil { + return fmt.Errorf("GetRepositoryCount: %w", err) + } else if count > 0 { + return repo_model.ErrUserOwnRepos{UID: u.ID} + } + + // Check membership of organization. + count, err = organization.GetOrganizationCount(ctx, u) + if err != nil { + return fmt.Errorf("GetOrganizationCount: %w", err) + } else if count > 0 { + return organization.ErrUserHasOrgs{UID: u.ID} + } + + // Check ownership of packages. + if ownsPackages, err := packages_model.HasOwnerPackages(ctx, u.ID); err != nil { + return fmt.Errorf("HasOwnerPackages: %w", err) + } else if ownsPackages { + return packages_model.ErrUserOwnPackages{UID: u.ID} + } + + if err := deleteUser(ctx, u, purge); err != nil { + return fmt.Errorf("DeleteUser: %w", err) + } + return nil + }); err != nil { return err } - defer committer.Close() - // Note: A user owns any repository or belongs to any organization - // cannot perform delete operation. This causes a race with the purge above - // however consistency requires that we ensure that this is the case - - // Check ownership of repository. - count, err := repo_model.CountRepositories(ctx, repo_model.CountRepositoryOptions{OwnerID: u.ID}) - if err != nil { - return fmt.Errorf("GetRepositoryCount: %w", err) - } else if count > 0 { - return repo_model.ErrUserOwnRepos{UID: u.ID} - } - - // Check membership of organization. - count, err = organization.GetOrganizationCount(ctx, u) - if err != nil { - return fmt.Errorf("GetOrganizationCount: %w", err) - } else if count > 0 { - return organization.ErrUserHasOrgs{UID: u.ID} - } - - // Check ownership of packages. - if ownsPackages, err := packages_model.HasOwnerPackages(ctx, u.ID); err != nil { - return fmt.Errorf("HasOwnerPackages: %w", err) - } else if ownsPackages { - return packages_model.ErrUserOwnPackages{UID: u.ID} - } - - if err := deleteUser(ctx, u, purge); err != nil { - return fmt.Errorf("DeleteUser: %w", err) - } - - if err := committer.Commit(); err != nil { + if err := asymkey_service.RewriteAllPublicKeys(ctx); err != nil { return err } - _ = committer.Close() - - if err = asymkey_service.RewriteAllPublicKeys(ctx); err != nil { - return err - } - if err = asymkey_service.RewriteAllPrincipalKeys(ctx); err != nil { + if err := asymkey_service.RewriteAllPrincipalKeys(ctx); err != nil { return err } // Note: There are something just cannot be roll back, so just keep error logs of those operations. path := user_model.UserPath(u.Name) - if err = util.RemoveAll(path); err != nil { + if err := util.RemoveAll(path); err != nil { err = fmt.Errorf("failed to RemoveAll %s: %w", path, err) _ = system_model.CreateNotice(ctx, system_model.NoticeTask, fmt.Sprintf("delete user '%s': %v", u.Name, err)) } if u.Avatar != "" { avatarPath := u.CustomAvatarRelativePath() - if err = storage.Avatars.Delete(avatarPath); err != nil { + if err := storage.Avatars.Delete(avatarPath); err != nil { err = fmt.Errorf("failed to remove %s: %w", avatarPath, err) _ = system_model.CreateNotice(ctx, system_model.NoticeTask, fmt.Sprintf("delete user '%s': %v", u.Name, err)) } diff --git a/services/user/user_test.go b/services/user/user_test.go index 28a0df8628..48852b4cb9 100644 --- a/services/user/user_test.go +++ b/services/user/user_test.go @@ -32,24 +32,24 @@ func TestDeleteUser(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}) ownedRepos := make([]*repo_model.Repository, 0, 10) - assert.NoError(t, db.GetEngine(db.DefaultContext).Find(&ownedRepos, &repo_model.Repository{OwnerID: userID})) + assert.NoError(t, db.GetEngine(t.Context()).Find(&ownedRepos, &repo_model.Repository{OwnerID: userID})) if len(ownedRepos) > 0 { - err := DeleteUser(db.DefaultContext, user, false) + err := DeleteUser(t.Context(), user, false) assert.Error(t, err) assert.True(t, repo_model.IsErrUserOwnRepos(err)) return } orgUsers := make([]*organization.OrgUser, 0, 10) - assert.NoError(t, db.GetEngine(db.DefaultContext).Find(&orgUsers, &organization.OrgUser{UID: userID})) + assert.NoError(t, db.GetEngine(t.Context()).Find(&orgUsers, &organization.OrgUser{UID: userID})) for _, orgUser := range orgUsers { org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: orgUser.OrgID}) - if err := org_service.RemoveOrgUser(db.DefaultContext, org, user); err != nil { + if err := org_service.RemoveOrgUser(t.Context(), org, user); err != nil { assert.True(t, organization.IsErrLastOrgOwner(err)) return } } - assert.NoError(t, DeleteUser(db.DefaultContext, user, false)) + assert.NoError(t, DeleteUser(t.Context(), user, false)) unittest.AssertNotExistsBean(t, &user_model.User{ID: userID}) unittest.CheckConsistencyFor(t, &user_model.User{}, &repo_model.Repository{}) } @@ -59,7 +59,7 @@ func TestDeleteUser(t *testing.T) { test(11) org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) - assert.Error(t, DeleteUser(db.DefaultContext, org, false)) + assert.Error(t, DeleteUser(t.Context(), org, false)) } func TestPurgeUser(t *testing.T) { @@ -67,7 +67,7 @@ func TestPurgeUser(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}) - err := DeleteUser(db.DefaultContext, user, true) + err := DeleteUser(t.Context(), user, true) assert.NoError(t, err) unittest.AssertNotExistsBean(t, &user_model.User{ID: userID}) @@ -79,7 +79,7 @@ func TestPurgeUser(t *testing.T) { test(11) org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) - assert.Error(t, DeleteUser(db.DefaultContext, org, false)) + assert.Error(t, DeleteUser(t.Context(), org, false)) } func TestCreateUser(t *testing.T) { @@ -92,9 +92,9 @@ func TestCreateUser(t *testing.T) { MustChangePassword: false, } - assert.NoError(t, user_model.CreateUser(db.DefaultContext, user, &user_model.Meta{})) + assert.NoError(t, user_model.CreateUser(t.Context(), user, &user_model.Meta{})) - assert.NoError(t, DeleteUser(db.DefaultContext, user, false)) + assert.NoError(t, DeleteUser(t.Context(), user, false)) } func TestRenameUser(t *testing.T) { @@ -106,18 +106,18 @@ func TestRenameUser(t *testing.T) { Type: user_model.UserTypeIndividual, LoginType: auth.OAuth2, } - assert.ErrorIs(t, RenameUser(db.DefaultContext, u, "user_rename"), user_model.ErrUserIsNotLocal{}) + assert.ErrorIs(t, RenameUser(t.Context(), u, "user_rename"), user_model.ErrUserIsNotLocal{}) }) t.Run("Same username", func(t *testing.T) { - assert.NoError(t, RenameUser(db.DefaultContext, user, user.Name)) + assert.NoError(t, RenameUser(t.Context(), user, user.Name)) }) t.Run("Non usable username", func(t *testing.T) { usernames := []string{"--diff", ".well-known", "gitea-actions", "aaa.atom", "aa.png"} for _, username := range usernames { assert.Error(t, user_model.IsUsableUsername(username), "non-usable username: %s", username) - assert.Error(t, RenameUser(db.DefaultContext, user, username), "non-usable username: %s", username) + assert.Error(t, RenameUser(t.Context(), user, username), "non-usable username: %s", username) } }) @@ -126,7 +126,7 @@ func TestRenameUser(t *testing.T) { unittest.AssertNotExistsBean(t, &user_model.User{ID: user.ID, Name: caps}) unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, OwnerName: user.Name}) - assert.NoError(t, RenameUser(db.DefaultContext, user, caps)) + assert.NoError(t, RenameUser(t.Context(), user, caps)) unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: user.ID, Name: caps}) unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, OwnerName: caps}) @@ -135,20 +135,20 @@ func TestRenameUser(t *testing.T) { t.Run("Already exists", func(t *testing.T) { existUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - assert.ErrorIs(t, RenameUser(db.DefaultContext, user, existUser.Name), user_model.ErrUserAlreadyExist{Name: existUser.Name}) - assert.ErrorIs(t, RenameUser(db.DefaultContext, user, existUser.LowerName), user_model.ErrUserAlreadyExist{Name: existUser.LowerName}) + assert.ErrorIs(t, RenameUser(t.Context(), user, existUser.Name), user_model.ErrUserAlreadyExist{Name: existUser.Name}) + assert.ErrorIs(t, RenameUser(t.Context(), user, existUser.LowerName), user_model.ErrUserAlreadyExist{Name: existUser.LowerName}) newUsername := fmt.Sprintf("uSEr%d", existUser.ID) - assert.ErrorIs(t, RenameUser(db.DefaultContext, user, newUsername), user_model.ErrUserAlreadyExist{Name: newUsername}) + assert.ErrorIs(t, RenameUser(t.Context(), user, newUsername), user_model.ErrUserAlreadyExist{Name: newUsername}) }) t.Run("Normal", func(t *testing.T) { oldUsername := user.Name newUsername := "User_Rename" - assert.NoError(t, RenameUser(db.DefaultContext, user, newUsername)) + assert.NoError(t, RenameUser(t.Context(), user, newUsername)) unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: user.ID, Name: newUsername, LowerName: strings.ToLower(newUsername)}) - redirectUID, err := user_model.LookupUserRedirect(db.DefaultContext, oldUsername) + redirectUID, err := user_model.LookupUserRedirect(t.Context(), oldUsername) assert.NoError(t, err) assert.Equal(t, user.ID, redirectUID) @@ -175,24 +175,24 @@ func TestCreateUser_Issue5882(t *testing.T) { for _, v := range tt { setting.Admin.DisableRegularOrgCreation = v.disableOrgCreation - assert.NoError(t, user_model.CreateUser(db.DefaultContext, v.user, &user_model.Meta{})) + assert.NoError(t, user_model.CreateUser(t.Context(), v.user, &user_model.Meta{})) - u, err := user_model.GetUserByEmail(db.DefaultContext, v.user.Email) + u, err := user_model.GetUserByEmail(t.Context(), v.user.Email) assert.NoError(t, err) assert.Equal(t, !u.AllowCreateOrganization, v.disableOrgCreation) - assert.NoError(t, DeleteUser(db.DefaultContext, v.user, false)) + assert.NoError(t, DeleteUser(t.Context(), v.user, false)) } } func TestDeleteInactiveUsers(t *testing.T) { addUser := func(name, email string, createdUnix timeutil.TimeStamp, active bool) { inactiveUser := &user_model.User{Name: name, LowerName: strings.ToLower(name), Email: email, CreatedUnix: createdUnix, IsActive: active} - _, err := db.GetEngine(db.DefaultContext).NoAutoTime().Insert(inactiveUser) + _, err := db.GetEngine(t.Context()).NoAutoTime().Insert(inactiveUser) assert.NoError(t, err) inactiveUserEmail := &user_model.EmailAddress{UID: inactiveUser.ID, IsPrimary: true, Email: email, LowerEmail: strings.ToLower(email), IsActivated: active} - err = db.Insert(db.DefaultContext, inactiveUserEmail) + err = db.Insert(t.Context(), inactiveUserEmail) assert.NoError(t, err) } addUser("user-inactive-10", "user-inactive-10@test.com", timeutil.TimeStampNow().Add(-600), false) @@ -201,7 +201,7 @@ func TestDeleteInactiveUsers(t *testing.T) { addUser("user-active-5", "user-active-5@test.com", timeutil.TimeStampNow().Add(-300), true) unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user-inactive-10"}) unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "user-inactive-10@test.com"}) - assert.NoError(t, DeleteInactiveUsers(db.DefaultContext, 8*time.Minute)) + assert.NoError(t, DeleteInactiveUsers(t.Context(), 8*time.Minute)) unittest.AssertNotExistsBean(t, &user_model.User{Name: "user-inactive-10"}) unittest.AssertNotExistsBean(t, &user_model.EmailAddress{Email: "user-inactive-10@test.com"}) unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user-inactive-5"}) diff --git a/services/versioned_migration/migration.go b/services/versioned_migration/migration.go index b66d853531..c064bf7913 100644 --- a/services/versioned_migration/migration.go +++ b/services/versioned_migration/migration.go @@ -20,5 +20,5 @@ func Migrate(ctx context.Context, x *xorm.Engine) error { } defer release() - return migrations.Migrate(x) + return migrations.Migrate(ctx, x) } diff --git a/services/webhook/deliver_test.go b/services/webhook/deliver_test.go index 1d32d7b772..efbef1fc89 100644 --- a/services/webhook/deliver_test.go +++ b/services/webhook/deliver_test.go @@ -12,7 +12,6 @@ import ( "testing" "time" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" webhook_model "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/hostmatcher" @@ -105,7 +104,7 @@ func TestWebhookDeliverAuthorizationHeader(t *testing.T) { } err := hook.SetHeaderAuthorization("Bearer s3cr3t-t0ken") assert.NoError(t, err) - assert.NoError(t, webhook_model.CreateWebhook(db.DefaultContext, hook)) + assert.NoError(t, webhook_model.CreateWebhook(t.Context(), hook)) hookTask := &webhook_model.HookTask{ HookID: hook.ID, @@ -113,7 +112,7 @@ func TestWebhookDeliverAuthorizationHeader(t *testing.T) { PayloadVersion: 2, } - hookTask, err = webhook_model.CreateHookTask(db.DefaultContext, hookTask) + hookTask, err = webhook_model.CreateHookTask(t.Context(), hookTask) assert.NoError(t, err) assert.NotNil(t, hookTask) @@ -170,7 +169,7 @@ func TestWebhookDeliverHookTask(t *testing.T) { ContentType: webhook_model.ContentTypeJSON, Meta: `{"message_type":0}`, // text } - assert.NoError(t, webhook_model.CreateWebhook(db.DefaultContext, hook)) + assert.NoError(t, webhook_model.CreateWebhook(t.Context(), hook)) t.Run("Version 1", func(t *testing.T) { hookTask := &webhook_model.HookTask{ @@ -180,7 +179,7 @@ func TestWebhookDeliverHookTask(t *testing.T) { PayloadVersion: 1, } - hookTask, err := webhook_model.CreateHookTask(db.DefaultContext, hookTask) + hookTask, err := webhook_model.CreateHookTask(t.Context(), hookTask) assert.NoError(t, err) assert.NotNil(t, hookTask) @@ -206,7 +205,7 @@ func TestWebhookDeliverHookTask(t *testing.T) { PayloadVersion: 2, } - hookTask, err = webhook_model.CreateHookTask(db.DefaultContext, hookTask) + hookTask, err = webhook_model.CreateHookTask(t.Context(), hookTask) assert.NoError(t, err) assert.NotNil(t, hookTask) @@ -266,7 +265,7 @@ func TestWebhookDeliverSpecificTypes(t *testing.T) { URL: s.URL + "/" + typ, Meta: "{}", } - assert.NoError(t, webhook_model.CreateWebhook(db.DefaultContext, hook)) + assert.NoError(t, webhook_model.CreateWebhook(t.Context(), hook)) hookTask := &webhook_model.HookTask{ HookID: hook.ID, @@ -275,7 +274,7 @@ func TestWebhookDeliverSpecificTypes(t *testing.T) { PayloadVersion: 2, } - hookTask, err := webhook_model.CreateHookTask(db.DefaultContext, hookTask) + hookTask, err := webhook_model.CreateHookTask(t.Context(), hookTask) assert.NoError(t, err) assert.NotNil(t, hookTask) diff --git a/services/webhook/discord.go b/services/webhook/discord.go index 0426964181..6f045bd112 100644 --- a/services/webhook/discord.go +++ b/services/webhook/discord.go @@ -57,7 +57,7 @@ type ( DiscordPayload struct { Wait bool `json:"wait"` Content string `json:"content"` - Username string `json:"username"` + Username string `json:"username,omitempty"` AvatarURL string `json:"avatar_url,omitempty"` TTS bool `json:"tts"` Embeds []DiscordEmbed `json:"embeds"` diff --git a/services/webhook/notifier.go b/services/webhook/notifier.go index 672abd5c95..80de6b00fd 100644 --- a/services/webhook/notifier.go +++ b/services/webhook/notifier.go @@ -481,6 +481,7 @@ func (m *webhookNotifier) DeleteComment(ctx context.Context, doer *user_model.Us log.Error("LoadPoster: %v", err) return } + comment.Issue = nil // reload issue to ensure it has the latest data, especially the number of comments if err = comment.LoadIssue(ctx); err != nil { log.Error("LoadIssue: %v", err) return diff --git a/services/webhook/webhook_test.go b/services/webhook/webhook_test.go index 5a805347e3..34bcfd3df9 100644 --- a/services/webhook/webhook_test.go +++ b/services/webhook/webhook_test.go @@ -6,7 +6,6 @@ package webhook import ( "testing" - "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" @@ -43,7 +42,7 @@ func TestPrepareWebhooks(t *testing.T) { for _, hookTask := range hookTasks { unittest.AssertNotExistsBean(t, hookTask) } - assert.NoError(t, PrepareWebhooks(db.DefaultContext, EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{Commits: []*api.PayloadCommit{{}}})) + assert.NoError(t, PrepareWebhooks(t.Context(), EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{Commits: []*api.PayloadCommit{{}}})) for _, hookTask := range hookTasks { unittest.AssertExistsAndLoadBean(t, hookTask) } @@ -60,7 +59,7 @@ func TestPrepareWebhooksBranchFilterMatch(t *testing.T) { unittest.AssertNotExistsBean(t, hookTask) } // this test also ensures that * doesn't handle / in any special way (like shell would) - assert.NoError(t, PrepareWebhooks(db.DefaultContext, EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{Ref: "refs/heads/feature/7791", Commits: []*api.PayloadCommit{{}}})) + assert.NoError(t, PrepareWebhooks(t.Context(), EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{Ref: "refs/heads/feature/7791", Commits: []*api.PayloadCommit{{}}})) for _, hookTask := range hookTasks { unittest.AssertExistsAndLoadBean(t, hookTask) } @@ -76,7 +75,7 @@ func TestPrepareWebhooksBranchFilterNoMatch(t *testing.T) { for _, hookTask := range hookTasks { unittest.AssertNotExistsBean(t, hookTask) } - assert.NoError(t, PrepareWebhooks(db.DefaultContext, EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{Ref: "refs/heads/fix_weird_bug"})) + assert.NoError(t, PrepareWebhooks(t.Context(), EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{Ref: "refs/heads/fix_weird_bug"})) for _, hookTask := range hookTasks { unittest.AssertNotExistsBean(t, hookTask) @@ -88,6 +87,6 @@ func TestWebhookUserMail(t *testing.T) { defer test.MockVariableValue(&setting.Service.NoReplyAddress, "no-reply.com")() user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - assert.Equal(t, user.GetPlaceholderEmail(), convert.ToUser(db.DefaultContext, user, nil).Email) - assert.Equal(t, user.Email, convert.ToUser(db.DefaultContext, user, user).Email) + assert.Equal(t, user.GetPlaceholderEmail(), convert.ToUser(t.Context(), user, nil).Email) + assert.Equal(t, user.Email, convert.ToUser(t.Context(), user, user).Email) } diff --git a/services/wiki/wiki.go b/services/wiki/wiki.go index 0a955406e2..7848e0f46d 100644 --- a/services/wiki/wiki.go +++ b/services/wiki/wiki.go @@ -19,6 +19,7 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/globallock" + "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/util" @@ -35,15 +36,19 @@ func getWikiWorkingLockKey(repoID int64) string { // InitWiki initializes a wiki for repository, // it does nothing when repository already has wiki. func InitWiki(ctx context.Context, repo *repo_model.Repository) error { - if repo.HasWiki() { + // don't use HasWiki because the error should not be ignored. + if exist, err := gitrepo.IsRepositoryExist(ctx, repo.WikiStorageRepo()); err != nil { + return err + } else if exist { return nil } - if err := git.InitRepository(ctx, repo.WikiPath(), true, repo.ObjectFormatName); err != nil { + // wiki's object format should be the same as repository's + if err := gitrepo.InitRepository(ctx, repo.WikiStorageRepo(), repo.ObjectFormatName); err != nil { return fmt.Errorf("InitRepository: %w", err) } else if err = gitrepo.CreateDelegateHooks(ctx, repo.WikiStorageRepo()); err != nil { return fmt.Errorf("createDelegateHooks: %w", err) - } else if _, _, err = git.NewCommand("symbolic-ref", "HEAD").AddDynamicArguments(git.BranchPrefix+repo.DefaultWikiBranch).RunStdString(ctx, &git.RunOpts{Dir: repo.WikiPath()}); err != nil { + } else if err = gitrepo.SetDefaultBranch(ctx, repo.WikiStorageRepo(), repo.DefaultWikiBranch); err != nil { return fmt.Errorf("unable to set default wiki branch to %q: %w", repo.DefaultWikiBranch, err) } return nil @@ -355,7 +360,14 @@ func DeleteWiki(ctx context.Context, repo *repo_model.Repository) error { return err } - system_model.RemoveAllWithNotice(ctx, "Delete repository wiki", repo.WikiPath()) + if err := gitrepo.DeleteRepository(ctx, repo.WikiStorageRepo()); err != nil { + desc := fmt.Sprintf("Delete wiki repository files [%s]: %v", repo.FullName(), err) + // Note we use the db.DefaultContext here rather than passing in a context as the context may be cancelled + if err = system_model.CreateNotice(graceful.GetManager().ShutdownContext(), system_model.NoticeRepository, desc); err != nil { + log.Error("CreateRepositoryNotice: %v", err) + } + } + return nil } @@ -369,7 +381,7 @@ func ChangeDefaultWikiBranch(ctx context.Context, repo *repo_model.Repository, n return fmt.Errorf("unable to update database: %w", err) } - if !repo.HasWiki() { + if !repo_service.HasWiki(ctx, repo) { return nil } diff --git a/services/wiki/wiki_test.go b/services/wiki/wiki_test.go index 6ea3ca9c1b..e571e093b6 100644 --- a/services/wiki/wiki_test.go +++ b/services/wiki/wiki_test.go @@ -13,6 +13,7 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" + repo_service "code.gitea.io/gitea/services/repository" _ "code.gitea.io/gitea/models/actions" @@ -144,12 +145,12 @@ func TestRepository_InitWiki(t *testing.T) { unittest.PrepareTestEnv(t) // repo1 already has a wiki repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - assert.NoError(t, InitWiki(git.DefaultContext, repo1)) + assert.NoError(t, InitWiki(t.Context(), repo1)) // repo2 does not already have a wiki repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) - assert.NoError(t, InitWiki(git.DefaultContext, repo2)) - assert.True(t, repo2.HasWiki()) + assert.NoError(t, InitWiki(t.Context(), repo2)) + assert.True(t, repo_service.HasWiki(t.Context(), repo2)) } func TestRepository_AddWikiPage(t *testing.T) { @@ -164,9 +165,9 @@ func TestRepository_AddWikiPage(t *testing.T) { } { t.Run("test wiki exist: "+userTitle, func(t *testing.T) { webPath := UserTitleToWebPath("", userTitle) - assert.NoError(t, AddWikiPage(git.DefaultContext, doer, repo, webPath, wikiContent, commitMsg)) + assert.NoError(t, AddWikiPage(t.Context(), doer, repo, webPath, wikiContent, commitMsg)) // Now need to show that the page has been added: - gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo.WikiStorageRepo()) + gitRepo, err := gitrepo.OpenRepository(t.Context(), repo.WikiStorageRepo()) require.NoError(t, err) defer gitRepo.Close() @@ -182,7 +183,7 @@ func TestRepository_AddWikiPage(t *testing.T) { t.Run("check wiki already exist", func(t *testing.T) { t.Parallel() // test for already-existing wiki name - err := AddWikiPage(git.DefaultContext, doer, repo, "Home", wikiContent, commitMsg) + err := AddWikiPage(t.Context(), doer, repo, "Home", wikiContent, commitMsg) assert.Error(t, err) assert.True(t, repo_model.IsErrWikiAlreadyExist(err)) }) @@ -190,7 +191,7 @@ func TestRepository_AddWikiPage(t *testing.T) { t.Run("check wiki reserved name", func(t *testing.T) { t.Parallel() // test for reserved wiki name - err := AddWikiPage(git.DefaultContext, doer, repo, "_edit", wikiContent, commitMsg) + err := AddWikiPage(t.Context(), doer, repo, "_edit", wikiContent, commitMsg) assert.Error(t, err) assert.True(t, repo_model.IsErrWikiReservedName(err)) }) @@ -210,10 +211,10 @@ func TestRepository_EditWikiPage(t *testing.T) { } { webPath := UserTitleToWebPath("", newWikiName) unittest.PrepareTestEnv(t) - assert.NoError(t, EditWikiPage(git.DefaultContext, doer, repo, "Home", webPath, newWikiContent, commitMsg)) + assert.NoError(t, EditWikiPage(t.Context(), doer, repo, "Home", webPath, newWikiContent, commitMsg)) // Now need to show that the page has been added: - gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo.WikiStorageRepo()) + gitRepo, err := gitrepo.OpenRepository(t.Context(), repo.WikiStorageRepo()) assert.NoError(t, err) masterTree, err := gitRepo.GetTree(repo.DefaultWikiBranch) assert.NoError(t, err) @@ -234,10 +235,10 @@ func TestRepository_DeleteWikiPage(t *testing.T) { unittest.PrepareTestEnv(t) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - assert.NoError(t, DeleteWikiPage(git.DefaultContext, doer, repo, "Home")) + assert.NoError(t, DeleteWikiPage(t.Context(), doer, repo, "Home")) // Now need to show that the page has been added: - gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo.WikiStorageRepo()) + gitRepo, err := gitrepo.OpenRepository(t.Context(), repo.WikiStorageRepo()) require.NoError(t, err) defer gitRepo.Close() @@ -251,7 +252,7 @@ func TestRepository_DeleteWikiPage(t *testing.T) { func TestPrepareWikiFileName(t *testing.T) { unittest.PrepareTestEnv(t) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo.WikiStorageRepo()) + gitRepo, err := gitrepo.OpenRepository(t.Context(), repo.WikiStorageRepo()) require.NoError(t, err) defer gitRepo.Close() @@ -301,10 +302,10 @@ func TestPrepareWikiFileName_FirstPage(t *testing.T) { // Now create a temporaryDirectory tmpDir := t.TempDir() - err := git.InitRepository(git.DefaultContext, tmpDir, true, git.Sha1ObjectFormat.Name()) + err := git.InitRepository(t.Context(), tmpDir, true, git.Sha1ObjectFormat.Name()) assert.NoError(t, err) - gitRepo, err := git.OpenRepository(git.DefaultContext, tmpDir) + gitRepo, err := git.OpenRepository(t.Context(), tmpDir) require.NoError(t, err) defer gitRepo.Close() diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 596f703131..46900f7b85 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -44,7 +44,7 @@ parts: source: . stage-packages: [ git, sqlite3, openssh-client ] build-packages: [ git, libpam0g-dev, libsqlite3-dev, build-essential] - build-snaps: [ go/1.24/stable, node/22/stable ] + build-snaps: [ go/1.25/stable, node/22/stable ] build-environment: - LDFLAGS: "" override-pull: | diff --git a/stylelint.config.js b/stylelint.config.ts similarity index 97% rename from stylelint.config.js rename to stylelint.config.ts index c57c1fd3a3..8a5b87e17c 100644 --- a/stylelint.config.js +++ b/stylelint.config.ts @@ -1,6 +1,5 @@ -// @ts-check -import {defineConfig} from 'stylelint-define-config'; import {fileURLToPath} from 'node:url'; +import type {Config} from 'stylelint'; const cssVarFiles = [ fileURLToPath(new URL('web_src/css/base.css', import.meta.url)), @@ -8,8 +7,11 @@ const cssVarFiles = [ fileURLToPath(new URL('web_src/css/themes/theme-gitea-dark.css', import.meta.url)), ]; -export default defineConfig({ +export default { extends: 'stylelint-config-recommended', + reportUnscopedDisables: true, + reportNeedlessDisables: true, + reportInvalidScopeDisables: true, plugins: [ 'stylelint-declaration-strict-value', 'stylelint-declaration-block-no-ignored-properties', @@ -121,7 +123,6 @@ export default defineConfig({ 'csstools/value-no-unknown-custom-properties': [true, {importFrom: cssVarFiles}], 'declaration-block-no-duplicate-properties': [true, {ignore: ['consecutive-duplicates-with-different-values']}], 'declaration-block-no-redundant-longhand-properties': [true, {ignoreShorthands: ['flex-flow', 'overflow', 'grid-template']}], - // @ts-expect-error - https://github.com/stylelint-types/stylelint-define-config/issues/1 'declaration-property-unit-disallowed-list': {'line-height': ['em']}, 'declaration-property-value-disallowed-list': {'word-break': ['break-word']}, 'font-family-name-quotes': 'always-where-recommended', @@ -145,4 +146,4 @@ export default defineConfig({ 'shorthand-property-no-redundant-values': true, 'value-no-vendor-prefix': [true, {ignoreValues: ['box', 'inline-box']}], }, -}); +} satisfies Config; diff --git a/tailwind.config.js b/tailwind.config.ts similarity index 93% rename from tailwind.config.js rename to tailwind.config.ts index fa233a9814..624ae47a5c 100644 --- a/tailwind.config.js +++ b/tailwind.config.ts @@ -2,17 +2,18 @@ import {readFileSync} from 'node:fs'; import {env} from 'node:process'; import {parse} from 'postcss'; import plugin from 'tailwindcss/plugin.js'; +import type {Config} from 'tailwindcss'; const isProduction = env.NODE_ENV !== 'development'; -function extractRootVars(css) { +function extractRootVars(css: string) { const root = parse(css); - const vars = new Set(); + const vars = new Set(); root.walkRules((rule) => { if (rule.selector !== ':root') return; - rule.each((decl) => { - if (decl.value && decl.prop.startsWith('--')) { - vars.add(decl.prop.substring(2)); + rule.each((node) => { + if (node.type === 'decl' && node.value && node.prop.startsWith('--')) { + vars.add(node.prop.substring(2)); } }); }); @@ -120,4 +121,4 @@ export default { }); }), ], -}; +} satisfies Config; diff --git a/templates/admin/config_settings.tmpl b/templates/admin/config_settings/avatars.tmpl similarity index 52% rename from templates/admin/config_settings.tmpl rename to templates/admin/config_settings/avatars.tmpl index 6b9bb8275c..1fc761034d 100644 --- a/templates/admin/config_settings.tmpl +++ b/templates/admin/config_settings/avatars.tmpl @@ -1,4 +1,3 @@ -{{template "admin/layout_head" (dict "ctxData" . "pageClass" "admin config")}}

{{ctx.Locale.Tr "admin.config.picture_config"}}

@@ -19,24 +18,3 @@
- -

- {{ctx.Locale.Tr "repository"}} -

-
-
-
-
- {{ctx.Locale.Tr "admin.config.open_with_editor_app_help"}} -
{{.DefaultOpenWithEditorAppsString}}
-
-
-
- -
-
- -
-
-
-{{template "admin/layout_footer" .}} diff --git a/templates/admin/config_settings/config_settings.tmpl b/templates/admin/config_settings/config_settings.tmpl new file mode 100644 index 0000000000..1ef764a58b --- /dev/null +++ b/templates/admin/config_settings/config_settings.tmpl @@ -0,0 +1,7 @@ +{{template "admin/layout_head" (dict "ctxData" . "pageClass" "admin config")}} + +{{template "admin/config_settings/avatars" .}} + +{{template "admin/config_settings/repository" .}} + +{{template "admin/layout_footer" .}} diff --git a/templates/admin/config_settings/repository.tmpl b/templates/admin/config_settings/repository.tmpl new file mode 100644 index 0000000000..9a37707835 --- /dev/null +++ b/templates/admin/config_settings/repository.tmpl @@ -0,0 +1,28 @@ +

+ {{ctx.Locale.Tr "repository"}} +

+
+
+
+
+ {{ctx.Locale.Tr "admin.config.open_with_editor_app_help"}} +
{{.DefaultOpenWithEditorAppsString}}
+
+
+
+ {{$cfg := .SystemConfig.Repository.OpenWithEditorApps}} + + +
+ +
+ + {{$cfg = .SystemConfig.Repository.GitGuideRemoteName}} + + +
+
+ +
+
+
diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl index e9526818e3..62bc625bda 100644 --- a/templates/base/head.tmpl +++ b/templates/base/head.tmpl @@ -18,9 +18,9 @@ {{end}} - {{template "base/head_script" .}} {{template "base/head_opengraph" .}} {{template "base/head_style" .}} + {{template "base/head_script" .}} {{template "custom/header" .}} diff --git a/templates/base/head_opengraph.tmpl b/templates/base/head_opengraph.tmpl index f1f38999d2..cb96fb6d6d 100644 --- a/templates/base/head_opengraph.tmpl +++ b/templates/base/head_opengraph.tmpl @@ -3,14 +3,14 @@ - + {{if .ContextUser.Description}} {{end}} {{else if .Repository}} {{if .Issue}} - + {{if .Issue.Content}} {{end}} @@ -26,7 +26,7 @@ {{end}} {{else}} - + {{if .Repository.Description}} {{end}} diff --git a/templates/mail/org/team_invite.devtest.yml b/templates/mail/org/team_invite.devtest.yml new file mode 100644 index 0000000000..dc51a74d64 --- /dev/null +++ b/templates/mail/org/team_invite.devtest.yml @@ -0,0 +1,13 @@ +Inviter: + DisplayName: Inviter Display Name + +Team: + Name: Team name + +Organization: + DisplayName: Organization Display Name + +InviteURL: http://localhost/org/team/invite + +Invite: + Email: invited@example.com diff --git a/templates/mail/team_invite.tmpl b/templates/mail/org/team_invite.tmpl similarity index 86% rename from templates/mail/team_invite.tmpl rename to templates/mail/org/team_invite.tmpl index cb0c0c0a50..a531e8c3b5 100644 --- a/templates/mail/team_invite.tmpl +++ b/templates/mail/org/team_invite.tmpl @@ -10,6 +10,6 @@

{{.locale.Tr "mail.link_not_working_do_paste"}}

{{.locale.Tr "mail.team_invite.text_3" .Invite.Email}}

-

© {{AppName}}

+

© {{AppName}}

diff --git a/templates/mail/notify/workflow_run.devtest.yml b/templates/mail/repo/actions/workflow_run.devtest.yml similarity index 59% rename from templates/mail/notify/workflow_run.devtest.yml rename to templates/mail/repo/actions/workflow_run.devtest.yml index 1e285be328..a45b26a6ee 100644 --- a/templates/mail/notify/workflow_run.devtest.yml +++ b/templates/mail/repo/actions/workflow_run.devtest.yml @@ -1,10 +1,10 @@ -RunStatusText: run status text .... +RunStatusText: Jobs status aggregation Repo: - FullName: RepoName + FullName: Repo/Name Run: - WorkflowID: WorkflowID + WorkflowID: workflow.yml HTMLURL: http://localhost/run/1 Jobs: @@ -12,7 +12,9 @@ Jobs: Status: success Attempt: 1 HTMLURL: http://localhost/job/1 + Duration: 1h2m3s - Name: Job-Name-2 - Status: failed + Status: failure Attempt: 2 HTMLURL: http://localhost/job/2 + Duration: 1h2m3s diff --git a/templates/mail/notify/workflow_run.tmpl b/templates/mail/repo/actions/workflow_run.tmpl similarity index 96% rename from templates/mail/notify/workflow_run.tmpl rename to templates/mail/repo/actions/workflow_run.tmpl index f6dd8ad510..619ee6fa20 100644 --- a/templates/mail/notify/workflow_run.tmpl +++ b/templates/mail/repo/actions/workflow_run.tmpl @@ -15,7 +15,7 @@ {{range $job := .Jobs}}
  • - {{$job.Status}}: {{$job.Name}}{{if gt $job.Attempt 1}}, Attempt #{{$job.Attempt}}{{end}} + {{$job.Status}}: {{$job.Name}}{{if gt $job.Attempt 1}}, Attempt #{{$job.Attempt}}{{end}}, {{$job.Duration}}
  • {{end}} diff --git a/templates/mail/repo/collaborator.devtest.yml b/templates/mail/repo/collaborator.devtest.yml new file mode 100644 index 0000000000..8d8f2b2733 --- /dev/null +++ b/templates/mail/repo/collaborator.devtest.yml @@ -0,0 +1,3 @@ +Subject: Collaborator added +Link: http://localhost +RepoName: Repo/Name diff --git a/templates/mail/notify/collaborator.tmpl b/templates/mail/repo/collaborator.tmpl similarity index 80% rename from templates/mail/notify/collaborator.tmpl rename to templates/mail/repo/collaborator.tmpl index 9810c70984..3fe490e221 100644 --- a/templates/mail/notify/collaborator.tmpl +++ b/templates/mail/repo/collaborator.tmpl @@ -1,16 +1,13 @@ - {{.Subject}}

    {{.locale.Tr "mail.repo.collaborator.added.text"}} {{.RepoName}}

    -