diff --git a/.golangci.yml b/.golangci.yml index ba4f81b521..2b85c89fdc 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -67,35 +67,24 @@ linters: revive: severity: error rules: - - name: atomic - - name: bare-return - name: blank-imports - name: constant-logical-expr - name: context-as-argument - name: context-keys-type - name: dot-imports - - name: duplicated-imports - name: empty-lines - - name: error-naming - name: error-return - name: error-strings - - name: errorf - name: exported - name: identical-branches - name: if-return - name: increment-decrement - - name: indent-error-flow - name: modifies-value-receiver - name: package-comments - - name: range - - name: receiver-naming - name: redefines-builtin-id - - name: string-of-int - name: superfluous-else - name: time-naming - - name: unconditional-recursion - name: unexported-return - - name: unreachable-code - name: var-declaration - name: var-naming arguments: @@ -133,16 +122,12 @@ linters: - linters: - dupl - errcheck - - gocyclo - - gosec - staticcheck - unparam path: _test\.go - linters: - dupl - errcheck - - gocyclo - - gosec path: models/migrations/v - linters: - forbidigo @@ -154,7 +139,6 @@ linters: - gocritic text: (?i)`ID' should not be capitalized - linters: - - deadcode - unused text: (?i)swagger - linters: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 52e4aefb6b..c64d91a7eb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -183,7 +183,7 @@ Here's how to run the test suite: ## Translation All translation work happens on [Crowdin](https://translate.gitea.com). -The only translation that is maintained in this repository is [the English translation](https://github.com/go-gitea/gitea/blob/main/options/locale/locale_en-US.ini). +The only translation that is maintained in this repository is [the English translation](https://github.com/go-gitea/gitea/blob/main/options/locale/locale_en-US.json). It is synced regularly with Crowdin. \ Other locales on main branch **should not** be updated manually as they will be overwritten with each sync. \ Once a language has reached a **satisfactory percentage** of translated keys (~25%), it will be synced back into this repo and included in the next released version. diff --git a/Dockerfile b/Dockerfile index 79f507dbc6..f71b13e8f3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,12 @@ # syntax=docker/dockerfile:1 -# Build stage +# Build frontend on the native platform to avoid QEMU-related issues with esbuild/webpack +FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.26-alpine3.23 AS frontend-build +RUN apk --no-cache add build-base git nodejs pnpm +WORKDIR /src +COPY --exclude=.git/ . . +RUN --mount=type=cache,target=/root/.local/share/pnpm/store make frontend + +# Build backend for each target platform FROM docker.io/library/golang:1.26-alpine3.23 AS build-env ARG GOPROXY=direct @@ -12,22 +19,19 @@ ARG CGO_EXTRA_CFLAGS # Build deps RUN apk --no-cache add \ build-base \ - git \ - nodejs \ - pnpm + git WORKDIR ${GOPATH}/src/code.gitea.io/gitea -# Use COPY but not "mount" because some directories like "node_modules" contain platform-depended contents and these directories need to be ignored. -# ".git" directory will be mounted later separately for getting version data. -# TODO: in the future, maybe we can pre-build the frontend assets on one platform and share them for different platforms, the benefit is that it won't be affected by webpack plugin compatibility problems, then the working directory can be fully mounted and the COPY is not needed. +# Use COPY instead of bind mount as read-only one breaks makefile state tracking and read-write one needs binary to be moved as it's discarded. +# ".git" directory is mounted separately later only for version data extraction. COPY --exclude=.git/ . . +COPY --from=frontend-build /src/public/assets public/assets # Build gitea, .git mount is required for version data RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target="/root/.cache/go-build" \ - --mount=type=cache,target=/root/.local/share/pnpm/store \ --mount=type=bind,source=".git/",target=".git/" \ - make + make backend COPY docker/root /tmp/local diff --git a/Dockerfile.rootless b/Dockerfile.rootless index fe94774add..bc210132c5 100644 --- a/Dockerfile.rootless +++ b/Dockerfile.rootless @@ -1,5 +1,12 @@ # syntax=docker/dockerfile:1 -# Build stage +# Build frontend on the native platform to avoid QEMU-related issues with esbuild/webpack +FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.26-alpine3.23 AS frontend-build +RUN apk --no-cache add build-base git nodejs pnpm +WORKDIR /src +COPY --exclude=.git/ . . +RUN --mount=type=cache,target=/root/.local/share/pnpm/store make frontend + +# Build backend for each target platform FROM docker.io/library/golang:1.26-alpine3.23 AS build-env ARG GOPROXY=direct @@ -12,20 +19,18 @@ ARG CGO_EXTRA_CFLAGS # Build deps RUN apk --no-cache add \ build-base \ - git \ - nodejs \ - pnpm + git WORKDIR ${GOPATH}/src/code.gitea.io/gitea # See the comments in Dockerfile COPY --exclude=.git/ . . +COPY --from=frontend-build /src/public/assets public/assets # Build gitea, .git mount is required for version data RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target="/root/.cache/go-build" \ - --mount=type=cache,target=/root/.local/share/pnpm/store \ --mount=type=bind,source=".git/",target=".git/" \ - make + make backend COPY docker/rootless /tmp/local diff --git a/build/backport-locales.go b/build/backport-locales.go deleted file mode 100644 index d112dd72bd..0000000000 --- a/build/backport-locales.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2023 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -//go:build ignore - -package main - -import ( - "fmt" - "os" - "os/exec" - "path/filepath" - "strings" - - "code.gitea.io/gitea/modules/container" - "code.gitea.io/gitea/modules/setting" -) - -func main() { - if len(os.Args) != 2 { - println("usage: backport-locales ") - println("eg: backport-locales release/v1.19") - os.Exit(1) - } - - mustNoErr := func(err error) { - if err != nil { - panic(err) - } - } - collectInis := func(ref string) map[string]setting.ConfigProvider { - inis := map[string]setting.ConfigProvider{} - err := filepath.WalkDir("options/locale", func(path string, d os.DirEntry, err error) error { - if err != nil { - return err - } - if d.IsDir() || !strings.HasSuffix(d.Name(), ".ini") { - return nil - } - cfg, err := setting.NewConfigProviderForLocale(path) - mustNoErr(err) - inis[path] = cfg - fmt.Printf("collecting: %s @ %s\n", path, ref) - return nil - }) - mustNoErr(err) - return inis - } - - // collect new locales from current working directory - inisNew := collectInis("HEAD") - - // switch to the target ref, and collect the old locales - cmd := exec.Command("git", "checkout", os.Args[1]) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - mustNoErr(cmd.Run()) - inisOld := collectInis(os.Args[1]) - - // use old en-US as the base, and copy the new translations to the old locales - enUsOld := inisOld["options/locale/locale_en-US.ini"] - brokenWarned := make(container.Set[string]) - for path, iniOld := range inisOld { - if iniOld == enUsOld { - continue - } - iniNew := inisNew[path] - if iniNew == nil { - continue - } - for _, secEnUS := range enUsOld.Sections() { - secOld := iniOld.Section(secEnUS.Name()) - secNew := iniNew.Section(secEnUS.Name()) - for _, keyEnUs := range secEnUS.Keys() { - if secNew.HasKey(keyEnUs.Name()) { - oldStr := secOld.Key(keyEnUs.Name()).String() - newStr := secNew.Key(keyEnUs.Name()).String() - broken := oldStr != "" && strings.Count(oldStr, "%") != strings.Count(newStr, "%") - broken = broken || strings.Contains(oldStr, "\n") || strings.Contains(oldStr, "\n") - if broken { - brokenWarned.Add(secOld.Name() + "." + keyEnUs.Name()) - fmt.Println("----") - fmt.Printf("WARNING: skip broken locale: %s , [%s] %s\n", path, secEnUS.Name(), keyEnUs.Name()) - fmt.Printf("\told: %s\n", strings.ReplaceAll(oldStr, "\n", "\\n")) - fmt.Printf("\tnew: %s\n", strings.ReplaceAll(newStr, "\n", "\\n")) - continue - } - secOld.Key(keyEnUs.Name()).SetValue(newStr) - } - } - } - mustNoErr(iniOld.SaveTo(path)) - } - - fmt.Println("========") - - for path, iniNew := range inisNew { - for _, sec := range iniNew.Sections() { - for _, key := range sec.Keys() { - str := sec.Key(key.Name()).String() - broken := strings.Contains(str, "\n") - broken = broken || strings.HasPrefix(str, "`") != strings.HasSuffix(str, "`") - broken = broken || strings.HasPrefix(str, "\"`") - broken = broken || strings.HasPrefix(str, "`\"") - broken = broken || strings.Count(str, `"`)%2 == 1 - broken = broken || strings.Count(str, "`")%2 == 1 - if broken && !brokenWarned.Contains(sec.Name()+"."+key.Name()) { - fmt.Printf("WARNING: found broken locale: %s , [%s] %s\n", path, sec.Name(), key.Name()) - fmt.Printf("\tstr: %s\n", strings.ReplaceAll(str, "\n", "\\n")) - fmt.Println("----") - } - } - } - } -} diff --git a/eslint.config.ts b/eslint.config.ts index 5815702c89..cd37c4321e 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -211,7 +211,7 @@ export default defineConfig([ '@typescript-eslint/no-non-null-asserted-nullish-coalescing': [0], '@typescript-eslint/no-non-null-asserted-optional-chain': [2], '@typescript-eslint/no-non-null-assertion': [0], - '@typescript-eslint/no-redeclare': [0], + '@typescript-eslint/no-redeclare': [2], '@typescript-eslint/no-redundant-type-constituents': [2], '@typescript-eslint/no-require-imports': [2], '@typescript-eslint/no-restricted-imports': [0], @@ -437,7 +437,7 @@ export default defineConfig([ 'no-import-assign': [2], 'no-inline-comments': [0], 'no-inner-declarations': [2], - 'no-invalid-regexp': [2], + 'no-invalid-regexp': [0], // handled by regexp/no-invalid-regexp 'no-invalid-this': [0], 'no-irregular-whitespace': [2], 'no-iterator': [2], @@ -551,7 +551,7 @@ export default defineConfig([ 'no-new-func': [0], // handled by @typescript-eslint/no-implied-eval 'no-new-native-nonconstructor': [2], 'no-new-object': [2], - 'no-new-symbol': [2], + 'no-new-symbol': [0], // handled by no-new-native-nonconstructor 'no-new-wrappers': [2], 'no-new': [0], 'no-nonoctal-decimal-escape': [2], @@ -582,7 +582,7 @@ export default defineConfig([ 'no-template-curly-in-string': [2], 'no-ternary': [0], 'no-this-before-super': [2], - 'no-throw-literal': [2], + 'no-throw-literal': [0], // handled by @typescript-eslint/only-throw-error 'no-undef-init': [2], 'no-undef': [2], // it is still needed by eslint & IDE to prompt undefined names in real time 'no-undefined': [0], @@ -600,7 +600,7 @@ export default defineConfig([ 'no-unused-vars': [0], // handled by @typescript-eslint/no-unused-vars 'no-use-before-define': [0], // handled by @typescript-eslint/no-use-before-define 'no-useless-assignment': [2], - 'no-useless-backreference': [2], + 'no-useless-backreference': [0], // handled by regexp/no-useless-backreference 'no-useless-call': [2], 'no-useless-catch': [2], 'no-useless-computed-key': [2], @@ -608,7 +608,7 @@ export default defineConfig([ 'no-useless-constructor': [2], 'no-useless-escape': [2], 'no-useless-rename': [2], - 'no-useless-return': [2], + 'no-useless-return': [0], // handled by sonarjs/no-redundant-jump 'no-var': [2], 'no-void': [2], 'no-warning-comments': [0], @@ -617,7 +617,7 @@ export default defineConfig([ 'one-var-declaration-per-line': [0], 'one-var': [0], 'operator-assignment': [2, 'always'], - 'operator-linebreak': [2, 'after'], + 'operator-linebreak': [0], // handled by @stylistic/operator-linebreak 'prefer-arrow-callback': [2, {allowNamedFunctions: true, allowUnboundThis: true}], 'prefer-const': [2, {destructuring: 'all', ignoreReadBeforeAssign: true}], 'prefer-destructuring': [0], @@ -697,7 +697,7 @@ export default defineConfig([ 'regexp/prefer-question-quantifier': [2], 'regexp/prefer-range': [2], 'regexp/prefer-regexp-exec': [2], - 'regexp/prefer-regexp-test': [2], + 'regexp/prefer-regexp-test': [0], // handled by unicorn/prefer-regexp-test 'regexp/prefer-result-array-groups': [0], 'regexp/prefer-set-operation': [2], 'regexp/prefer-star-quantifier': [2], @@ -727,7 +727,7 @@ export default defineConfig([ 'sonarjs/no-empty-collection': [2], 'sonarjs/no-extra-arguments': [2], 'sonarjs/no-gratuitous-expressions': [2], - 'sonarjs/no-identical-conditions': [2], + 'sonarjs/no-identical-conditions': [0], // handled by no-dupe-else-if 'sonarjs/no-identical-expressions': [2], 'sonarjs/no-identical-functions': [2, 5], 'sonarjs/no-ignored-return': [2], @@ -740,7 +740,7 @@ export default defineConfig([ 'sonarjs/no-small-switch': [0], 'sonarjs/no-unused-collection': [2], 'sonarjs/no-use-of-empty-return-value': [2], - 'sonarjs/no-useless-catch': [2], + 'sonarjs/no-useless-catch': [0], // handled by no-useless-catch 'sonarjs/non-existent-operator': [2], 'sonarjs/prefer-immediate-return': [0], 'sonarjs/prefer-object-literal': [0], @@ -767,6 +767,7 @@ export default defineConfig([ 'unicorn/filename-case': [0], 'unicorn/import-index': [0], 'unicorn/import-style': [0], + 'unicorn/isolated-functions': [2, {functions: []}], 'unicorn/new-for-builtins': [2], 'unicorn/no-abusive-eslint-disable': [0], 'unicorn/no-anonymous-default-export': [0], @@ -806,7 +807,7 @@ export default defineConfig([ 'unicorn/no-unnecessary-await': [2], 'unicorn/no-unnecessary-polyfills': [2], 'unicorn/no-unreadable-array-destructuring': [0], - 'unicorn/no-unreadable-iife': [2], + 'unicorn/no-unreadable-iife': [0], 'unicorn/no-unused-properties': [2], 'unicorn/no-useless-collection-argument': [2], 'unicorn/no-useless-fallback-in-spread': [2], @@ -819,7 +820,7 @@ export default defineConfig([ 'unicorn/number-literal-case': [0], 'unicorn/numeric-separators-style': [0], 'unicorn/prefer-add-event-listener': [2], - 'unicorn/prefer-array-find': [2], + 'unicorn/prefer-array-find': [0], // handled by @typescript-eslint/prefer-find 'unicorn/prefer-array-flat': [2], 'unicorn/prefer-array-flat-map': [2], 'unicorn/prefer-array-index-of': [2], @@ -836,7 +837,7 @@ export default defineConfig([ 'unicorn/prefer-event-target': [2], 'unicorn/prefer-export-from': [0], 'unicorn/prefer-global-this': [0], - 'unicorn/prefer-includes': [2], + 'unicorn/prefer-includes': [0], // handled by @typescript-eslint/prefer-includes 'unicorn/prefer-json-parse-buffer': [0], 'unicorn/prefer-keyboard-event-key': [2], 'unicorn/prefer-logical-operator-over-ternary': [2], @@ -863,7 +864,7 @@ export default defineConfig([ 'unicorn/prefer-string-raw': [0], 'unicorn/prefer-string-replace-all': [0], 'unicorn/prefer-string-slice': [0], - 'unicorn/prefer-string-starts-ends-with': [2], + 'unicorn/prefer-string-starts-ends-with': [0], // handled by @typescript-eslint/prefer-string-starts-ends-with 'unicorn/prefer-string-trim-start-end': [2], 'unicorn/prefer-structured-clone': [2], 'unicorn/prefer-switch': [0], diff --git a/models/actions/task.go b/models/actions/task.go index 8b4ecf28f7..4f41b69c97 100644 --- a/models/actions/task.go +++ b/models/actions/task.go @@ -8,6 +8,7 @@ import ( "crypto/subtle" "errors" "fmt" + "strings" "time" auth_model "code.gitea.io/gitea/models/auth" @@ -20,6 +21,7 @@ import ( runnerv1 "code.gitea.io/actions-proto-go/runner/v1" lru "github.com/hashicorp/golang-lru/v2" + "github.com/nektos/act/pkg/jobparser" "google.golang.org/protobuf/types/known/timestamppb" "xorm.io/builder" ) @@ -214,6 +216,20 @@ func GetRunningTaskByToken(ctx context.Context, token string) (*ActionTask, erro return nil, errNotExist } +func makeTaskStepDisplayName(step *jobparser.Step, limit int) (name string) { + if step.Name != "" { + name = step.Name // the step has an explicit name + } else { + // for unnamed step, its "String()" method tries to get a display name by its "name", "uses", + // "run" or "id" (last fallback), we add the "Run " prefix for unnamed steps for better display + // for multi-line "run" scripts, only use the first line to match GitHub's behavior + // https://github.com/actions/runner/blob/66800900843747f37591b077091dd2c8cf2c1796/src/Runner.Worker/Handlers/ScriptHandler.cs#L45-L58 + runStr, _, _ := strings.Cut(strings.TrimSpace(step.Run), "\n") + name = "Run " + util.IfZero(strings.TrimSpace(runStr), step.String()) + } + return util.EllipsisDisplayString(name, limit) // database column has a length limit +} + func CreateTaskForRunner(ctx context.Context, runner *ActionRunner) (*ActionTask, bool, error) { ctx, committer, err := db.TxContext(ctx) if err != nil { @@ -293,9 +309,8 @@ func CreateTaskForRunner(ctx context.Context, runner *ActionRunner) (*ActionTask if len(workflowJob.Steps) > 0 { steps := make([]*ActionTaskStep, len(workflowJob.Steps)) for i, v := range workflowJob.Steps { - name := util.EllipsisDisplayString(v.String(), 255) steps[i] = &ActionTaskStep{ - Name: name, + Name: makeTaskStepDisplayName(v, 255), TaskID: task.ID, Index: int64(i), RepoID: task.RepoID, diff --git a/models/actions/task_step.go b/models/actions/task_step.go index 3af1fe3f5a..03ffbf1931 100644 --- a/models/actions/task_step.go +++ b/models/actions/task_step.go @@ -14,7 +14,7 @@ import ( // ActionTaskStep represents a step of ActionTask type ActionTaskStep struct { ID int64 - Name string `xorm:"VARCHAR(255)"` + Name string `xorm:"VARCHAR(255)"` // the step name, for display purpose only, it will be truncated if it is too long TaskID int64 `xorm:"index unique(task_index)"` Index int64 `xorm:"index unique(task_index)"` RepoID int64 `xorm:"index"` diff --git a/models/actions/task_test.go b/models/actions/task_test.go new file mode 100644 index 0000000000..15d4e16f42 --- /dev/null +++ b/models/actions/task_test.go @@ -0,0 +1,76 @@ +// Copyright 2026 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package actions + +import ( + "strings" + "testing" + + "github.com/nektos/act/pkg/jobparser" + "github.com/stretchr/testify/assert" +) + +func TestMakeTaskStepDisplayName(t *testing.T) { + tests := []struct { + name string + jobStep *jobparser.Step + expected string + }{ + { + name: "explicit name", + jobStep: &jobparser.Step{ + Name: "Test Step", + }, + expected: "Test Step", + }, + { + name: "uses step", + jobStep: &jobparser.Step{ + Uses: "actions/checkout@v4", + }, + expected: "Run actions/checkout@v4", + }, + { + name: "single-line run", + jobStep: &jobparser.Step{ + Run: "echo hello", + }, + expected: "Run echo hello", + }, + { + name: "multi-line run block scalar", + jobStep: &jobparser.Step{ + Run: "\n echo hello \r\n echo world \n ", + }, + expected: "Run echo hello", + }, + { + name: "fallback to id", + jobStep: &jobparser.Step{ + ID: "step-id", + }, + expected: "Run step-id", + }, + { + name: "very long name truncated", + jobStep: &jobparser.Step{ + Name: strings.Repeat("a", 300), + }, + expected: strings.Repeat("a", 252) + "…", + }, + { + name: "very long run truncated", + jobStep: &jobparser.Step{ + Run: strings.Repeat("a", 300), + }, + expected: "Run " + strings.Repeat("a", 248) + "…", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := makeTaskStepDisplayName(tt.jobStep, 255) + assert.Equal(t, tt.expected, result) + }) + } +} diff --git a/models/activities/user_heatmap.go b/models/activities/user_heatmap.go index ef67838be7..e24d44c519 100644 --- a/models/activities/user_heatmap.go +++ b/models/activities/user_heatmap.go @@ -19,14 +19,14 @@ type UserHeatmapData struct { Contributions int64 `json:"contributions"` } -// GetUserHeatmapDataByUser returns an array of UserHeatmapData +// GetUserHeatmapDataByUser returns an array of UserHeatmapData, it checks whether doer can access user's activity func GetUserHeatmapDataByUser(ctx context.Context, user, doer *user_model.User) ([]*UserHeatmapData, error) { return getUserHeatmapData(ctx, user, nil, doer) } -// GetUserHeatmapDataByUserTeam returns an array of UserHeatmapData -func GetUserHeatmapDataByUserTeam(ctx context.Context, user *user_model.User, team *organization.Team, doer *user_model.User) ([]*UserHeatmapData, error) { - return getUserHeatmapData(ctx, user, team, doer) +// GetUserHeatmapDataByOrgTeam returns an array of UserHeatmapData, it checks whether doer can access org's activity +func GetUserHeatmapDataByOrgTeam(ctx context.Context, org *organization.Organization, team *organization.Team, doer *user_model.User) ([]*UserHeatmapData, error) { + return getUserHeatmapData(ctx, org.AsUser(), team, doer) } func getUserHeatmapData(ctx context.Context, user *user_model.User, team *organization.Team, doer *user_model.User) ([]*UserHeatmapData, error) { @@ -71,12 +71,3 @@ func getUserHeatmapData(ctx context.Context, user *user_model.User, team *organi OrderBy("timestamp"). Find(&hdata) } - -// GetTotalContributionsInHeatmap returns the total number of contributions in a heatmap -func GetTotalContributionsInHeatmap(hdata []*UserHeatmapData) int64 { - var total int64 - for _, v := range hdata { - total += v.Contributions - } - return total -} diff --git a/models/fixtures/action_run.yml b/models/fixtures/action_run.yml index 44b131c961..ac5e8303c3 100644 --- a/models/fixtures/action_run.yml +++ b/models/fixtures/action_run.yml @@ -139,26 +139,7 @@ updated: 1683636626 need_approval: 0 approved_by: 0 -- - id: 804 - title: "use a private action" - repo_id: 60 - owner_id: 40 - workflow_id: "run.yaml" - index: 189 - trigger_user_id: 40 - ref: "refs/heads/master" - commit_sha: "6e64b26de7ba966d01d90ecfaf5c7f14ef203e86" - event: "push" - trigger_event: "push" - is_fork_pull_request: 0 - status: 1 - started: 1683636528 - stopped: 1683636626 - created: 1683636108 - updated: 1683636626 - need_approval: 0 - approved_by: 0 + - id: 805 title: "update actions" diff --git a/models/fixtures/action_run_job.yml b/models/fixtures/action_run_job.yml index c5aeb4931c..04799b73ca 100644 --- a/models/fixtures/action_run_job.yml +++ b/models/fixtures/action_run_job.yml @@ -129,20 +129,7 @@ status: 5 started: 1683636528 stopped: 1683636626 -- - id: 205 - run_id: 804 - repo_id: 6 - owner_id: 10 - commit_sha: 6e64b26de7ba966d01d90ecfaf5c7f14ef203e86 - is_fork_pull_request: 0 - name: job_2 - attempt: 1 - job_id: job_2 - task_id: 48 - status: 1 - started: 1683636528 - stopped: 1683636626 + - id: 206 run_id: 805 diff --git a/models/fixtures/action_task.yml b/models/fixtures/action_task.yml index a28ddd0add..e1bc588dc5 100644 --- a/models/fixtures/action_task.yml +++ b/models/fixtures/action_task.yml @@ -177,26 +177,7 @@ log_length: 0 log_size: 0 log_expired: 0 -- - id: 55 - job_id: 205 - attempt: 1 - runner_id: 1 - status: 6 # 6 is the status code for "running" - started: 1683636528 - stopped: 1683636626 - repo_id: 6 - owner_id: 10 - commit_sha: 6e64b26de7ba966d01d90ecfaf5c7f14ef203e86 - is_fork_pull_request: 0 - token_hash: b8d3962425466b6709b9ac51446f93260c54afe8e7b6d3686e34f991fb8a8953822b0deed86fe41a103f34bc48dbc478422b - token_salt: ERxJGHvg3I - token_last_eight: 182199eb - log_filename: collaborative-owner-test/1a/49.log - log_in_storage: 1 - log_length: 707 - log_size: 90179 - log_expired: 0 + - id: 56 attempt: 1 diff --git a/models/git/branch.go b/models/git/branch.go index e5b73fb3e7..1d6eeb6868 100644 --- a/models/git/branch.go +++ b/models/git/branch.go @@ -397,10 +397,16 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, from, to str 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 { + existingRule, err := GetProtectedBranchRuleByName(ctx, repo.ID, to) + if err != nil { return err } + if existingRule == nil || existingRule.ID == protectedBranch.ID { + 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) diff --git a/models/git/branch_test.go b/models/git/branch_test.go index 7728d72f3e..6de3ea552c 100644 --- a/models/git/branch_test.go +++ b/models/git/branch_test.go @@ -159,6 +159,53 @@ func TestRenameBranch(t *testing.T) { }) } +func TestRenameBranchProtectedRuleConflict(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + master := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{RepoID: repo1.ID, Name: "master"}) + + devBranch := &git_model.Branch{ + RepoID: repo1.ID, + Name: "dev", + CommitID: master.CommitID, + CommitMessage: master.CommitMessage, + CommitTime: master.CommitTime, + PusherID: master.PusherID, + } + assert.NoError(t, db.Insert(t.Context(), devBranch)) + + pbDev := git_model.ProtectedBranch{ + RepoID: repo1.ID, + RuleName: "dev", + CanPush: true, + } + assert.NoError(t, git_model.UpdateProtectBranch(t.Context(), repo1, &pbDev, git_model.WhitelistOptions{})) + + pbMain := git_model.ProtectedBranch{ + RepoID: repo1.ID, + RuleName: "main", + CanPush: true, + } + assert.NoError(t, git_model.UpdateProtectBranch(t.Context(), repo1, &pbMain, git_model.WhitelistOptions{})) + + assert.NoError(t, git_model.RenameBranch(t.Context(), repo1, "dev", "main", func(ctx context.Context, isDefault bool) error { + return nil + })) + + unittest.AssertNotExistsBean(t, &git_model.Branch{RepoID: repo1.ID, Name: "dev"}) + unittest.AssertExistsAndLoadBean(t, &git_model.Branch{RepoID: repo1.ID, Name: "main"}) + + protectedDev, err := git_model.GetProtectedBranchRuleByName(t.Context(), repo1.ID, "dev") + assert.NoError(t, err) + assert.NotNil(t, protectedDev) + assert.Equal(t, "dev", protectedDev.RuleName) + + protectedMainByID, err := git_model.GetProtectedBranchRuleByID(t.Context(), repo1.ID, pbMain.ID) + assert.NoError(t, err) + assert.NotNil(t, protectedMainByID) + assert.Equal(t, "main", protectedMainByID.RuleName) +} + func TestOnlyGetDeletedBranchOnCorrectRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) diff --git a/modules/git/commit.go b/modules/git/commit.go index e66a33ef98..b98d36d946 100644 --- a/modules/git/commit.go +++ b/modules/git/commit.go @@ -37,6 +37,10 @@ type CommitSignature struct { // Message returns the commit message. Same as retrieving CommitMessage directly. func (c *Commit) Message() string { + // FIXME: GIT-COMMIT-MESSAGE-ENCODING: this logic is not right + // * When need to use commit message in templates/database, it should be valid UTF-8 + // * When need to get the original commit message, it should just use "c.CommitMessage" + // It's not easy to refactor at the moment, many templates need to be updated and tested return c.CommitMessage } diff --git a/package.json b/package.json index a01ece0379..e8f1c55816 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "type": "module", - "packageManager": "pnpm@10.29.2", + "packageManager": "pnpm@10.30.0", "engines": { "node": ">= 22.6.0", "pnpm": ">= 10.0.0" @@ -16,20 +16,20 @@ "@github/text-expander-element": "2.9.4", "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", "@mermaid-js/layout-elk": "0.2.0", - "@primer/octicons": "19.21.2", + "@primer/octicons": "19.22.0", "@resvg/resvg-wasm": "2.6.2", "@silverwind/vue3-calendar-heatmap": "2.1.1", "@techknowlogick/license-checker-webpack-plugin": "0.3.0", "add-asset-webpack-plugin": "3.1.1", "ansi_up": "6.0.6", - "asciinema-player": "3.14.0", + "asciinema-player": "3.14.15", "chart.js": "4.5.1", "chartjs-adapter-dayjs-4": "1.0.4", "chartjs-plugin-zoom": "2.2.0", "clippie": "4.1.10", "compare-versions": "6.1.1", "cropperjs": "1.6.2", - "css-loader": "7.1.3", + "css-loader": "7.1.4", "dayjs": "1.11.19", "dropzone": "6.0.0-beta.2", "easymde": "2.20.0", @@ -39,7 +39,7 @@ "jquery": "4.0.0", "js-yaml": "4.1.1", "katex": "0.16.28", - "mermaid": "11.12.2", + "mermaid": "11.12.3", "mini-css-extract-plugin": "2.10.0", "monaco-editor": "0.55.1", "monaco-editor-webpack-plugin": "7.1.1", @@ -47,9 +47,9 @@ "pdfobject": "2.3.1", "perfect-debounce": "2.1.0", "postcss": "8.5.6", - "postcss-loader": "8.2.0", - "sortablejs": "1.15.6", - "swagger-ui-dist": "5.31.0", + "postcss-loader": "8.2.1", + "sortablejs": "1.15.7", + "swagger-ui-dist": "5.31.1", "tailwindcss": "3.4.17", "throttle-debounce": "5.0.2", "tinycolor2": "1.6.0", @@ -62,7 +62,7 @@ "vue-bar-graph": "2.2.0", "vue-chartjs": "5.3.3", "vue-loader": "17.4.2", - "webpack": "5.105.0", + "webpack": "5.105.2", "webpack-cli": "6.0.1", "wrap-ansi": "9.0.2" }, @@ -83,9 +83,9 @@ "@types/throttle-debounce": "5.0.2", "@types/tinycolor2": "1.4.6", "@types/toastify-js": "1.12.4", - "@typescript-eslint/parser": "8.55.0", + "@typescript-eslint/parser": "8.56.0", "@vitejs/plugin-vue": "6.0.4", - "@vitest/eslint-plugin": "1.6.7", + "@vitest/eslint-plugin": "1.6.9", "eslint": "9.39.2", "eslint-import-resolver-typescript": "4.4.4", "eslint-plugin-array-func": "5.1.0", @@ -93,28 +93,28 @@ "eslint-plugin-import-x": "4.16.1", "eslint-plugin-playwright": "2.5.1", "eslint-plugin-regexp": "3.0.0", - "eslint-plugin-sonarjs": "3.0.6", - "eslint-plugin-unicorn": "62.0.0", - "eslint-plugin-vue": "10.7.0", + "eslint-plugin-sonarjs": "3.0.7", + "eslint-plugin-unicorn": "63.0.0", + "eslint-plugin-vue": "10.8.0", "eslint-plugin-vue-scoped-css": "2.12.0", "eslint-plugin-wc": "3.1.0", "globals": "17.3.0", - "happy-dom": "20.6.0", + "happy-dom": "20.6.1", "jiti": "2.6.1", "markdownlint-cli": "0.47.0", "material-icon-theme": "5.31.0", "nolyfill": "1.0.44", "postcss-html": "1.8.1", - "spectral-cli-bundle": "1.0.4", - "stylelint": "17.1.1", + "spectral-cli-bundle": "1.0.7", + "stylelint": "17.3.0", "stylelint-config-recommended": "18.0.0", "stylelint-declaration-block-no-ignored-properties": "3.0.0", "stylelint-declaration-strict-value": "1.10.11", "stylelint-value-no-unknown-custom-properties": "6.1.1", "svgo": "4.0.0", "typescript": "5.9.3", - "typescript-eslint": "8.55.0", - "updates": "17.4.0", + "typescript-eslint": "8.56.0", + "updates": "17.5.7", "vite-string-plugin": "2.0.1", "vitest": "4.0.18", "vue-tsc": "3.2.4" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7642d8dc82..f273662cad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -55,10 +55,10 @@ importers: version: 0.1.0-alpha-3 '@mermaid-js/layout-elk': specifier: 0.2.0 - version: 0.2.0(mermaid@11.12.2) + version: 0.2.0(mermaid@11.12.3) '@primer/octicons': - specifier: 19.21.2 - version: 19.21.2 + specifier: 19.22.0 + version: 19.22.0 '@resvg/resvg-wasm': specifier: 2.6.2 version: 2.6.2 @@ -67,16 +67,16 @@ importers: version: 2.1.1(tippy.js@6.3.7)(vue@3.5.28(typescript@5.9.3)) '@techknowlogick/license-checker-webpack-plugin': specifier: 0.3.0 - version: 0.3.0(webpack@5.105.0) + version: 0.3.0(webpack@5.105.2) add-asset-webpack-plugin: specifier: 3.1.1 - version: 3.1.1(webpack@5.105.0) + version: 3.1.1(webpack@5.105.2) ansi_up: specifier: 6.0.6 version: 6.0.6 asciinema-player: - specifier: 3.14.0 - version: 3.14.0 + specifier: 3.14.15 + version: 3.14.15 chart.js: specifier: 4.5.1 version: 4.5.1 @@ -96,8 +96,8 @@ importers: specifier: 1.6.2 version: 1.6.2 css-loader: - specifier: 7.1.3 - version: 7.1.3(webpack@5.105.0) + specifier: 7.1.4 + version: 7.1.4(webpack@5.105.2) dayjs: specifier: 1.11.19 version: 1.11.19 @@ -109,7 +109,7 @@ importers: version: 2.20.0 esbuild-loader: specifier: 4.4.2 - version: 4.4.2(webpack@5.105.0) + version: 4.4.2(webpack@5.105.2) htmx.org: specifier: 2.0.8 version: 2.0.8 @@ -126,17 +126,17 @@ importers: specifier: 0.16.28 version: 0.16.28 mermaid: - specifier: 11.12.2 - version: 11.12.2 + specifier: 11.12.3 + version: 11.12.3 mini-css-extract-plugin: specifier: 2.10.0 - version: 2.10.0(webpack@5.105.0) + version: 2.10.0(webpack@5.105.2) monaco-editor: specifier: 0.55.1 version: 0.55.1 monaco-editor-webpack-plugin: specifier: 7.1.1 - version: 7.1.1(monaco-editor@0.55.1)(webpack@5.105.0) + version: 7.1.1(monaco-editor@0.55.1)(webpack@5.105.2) online-3d-viewer: specifier: 0.18.0 version: 0.18.0 @@ -150,14 +150,14 @@ importers: 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.3)(webpack@5.105.0) + specifier: 8.2.1 + version: 8.2.1(postcss@8.5.6)(typescript@5.9.3)(webpack@5.105.2) sortablejs: - specifier: 1.15.6 - version: 1.15.6 + specifier: 1.15.7 + version: 1.15.7 swagger-ui-dist: - specifier: 5.31.0 - version: 5.31.0 + specifier: 5.31.1 + version: 5.31.1 tailwindcss: specifier: 3.4.17 version: 3.4.17 @@ -193,13 +193,13 @@ importers: version: 5.3.3(chart.js@4.5.1)(vue@3.5.28(typescript@5.9.3)) vue-loader: specifier: 17.4.2 - version: 17.4.2(vue@3.5.28(typescript@5.9.3))(webpack@5.105.0) + version: 17.4.2(vue@3.5.28(typescript@5.9.3))(webpack@5.105.2) webpack: - specifier: 5.105.0 - version: 5.105.0(webpack-cli@6.0.1) + specifier: 5.105.2 + version: 5.105.2(webpack-cli@6.0.1) webpack-cli: specifier: 6.0.1 - version: 6.0.1(webpack@5.105.0) + version: 6.0.1(webpack@5.105.2) wrap-ansi: specifier: 9.0.2 version: 9.0.2 @@ -218,7 +218,7 @@ importers: version: 5.8.0(eslint@9.39.2(jiti@2.6.1)) '@stylistic/stylelint-plugin': specifier: 5.0.1 - version: 5.0.1(stylelint@17.1.1(typescript@5.9.3)) + version: 5.0.1(stylelint@17.3.0(typescript@5.9.3)) '@types/codemirror': specifier: 5.60.17 version: 5.60.17 @@ -253,20 +253,20 @@ importers: specifier: 1.12.4 version: 1.12.4 '@typescript-eslint/parser': - specifier: 8.55.0 - version: 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + specifier: 8.56.0 + version: 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@vitejs/plugin-vue': specifier: 6.0.4 - version: 6.0.4(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.28(typescript@5.9.3)) + version: 6.0.4(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.28(typescript@5.9.3)) '@vitest/eslint-plugin': - specifier: 1.6.7 - version: 1.6.7(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)(vitest@4.0.18(@types/node@25.2.2)(happy-dom@20.6.0)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2)) + specifier: 1.6.9 + version: 1.6.9(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)(vitest@4.0.18(@types/node@25.2.3)(happy-dom@20.6.1)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2)) eslint: specifier: 9.39.2 version: 9.39.2(jiti@2.6.1) eslint-import-resolver-typescript: specifier: 4.4.4 - version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)) + version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-array-func: specifier: 5.1.0 version: 5.1.0(eslint@9.39.2(jiti@2.6.1)) @@ -275,7 +275,7 @@ importers: version: 6.0.0(@types/eslint@9.6.1)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-import-x: specifier: 4.16.1 - version: 4.16.1(@typescript-eslint/utils@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)) + version: 4.16.1(@typescript-eslint/utils@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-playwright: specifier: 2.5.1 version: 2.5.1(eslint@9.39.2(jiti@2.6.1)) @@ -283,17 +283,17 @@ importers: specifier: 3.0.0 version: 3.0.0(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-sonarjs: - specifier: 3.0.6 - version: 3.0.6(eslint@9.39.2(jiti@2.6.1)) + specifier: 3.0.7 + version: 3.0.7(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-unicorn: - specifier: 62.0.0 - version: 62.0.0(eslint@9.39.2(jiti@2.6.1)) + specifier: 63.0.0 + version: 63.0.0(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-vue: - specifier: 10.7.0 - version: 10.7.0(@stylistic/eslint-plugin@5.8.0(eslint@9.39.2(jiti@2.6.1)))(@typescript-eslint/parser@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.39.2(jiti@2.6.1))) + specifier: 10.8.0 + version: 10.8.0(@stylistic/eslint-plugin@5.8.0(eslint@9.39.2(jiti@2.6.1)))(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.2(jiti@2.6.1))) eslint-plugin-vue-scoped-css: specifier: 2.12.0 - version: 2.12.0(eslint@9.39.2(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.39.2(jiti@2.6.1))) + version: 2.12.0(eslint@9.39.2(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.2(jiti@2.6.1))) eslint-plugin-wc: specifier: 3.1.0 version: 3.1.0(eslint@9.39.2(jiti@2.6.1)) @@ -301,8 +301,8 @@ importers: specifier: 17.3.0 version: 17.3.0 happy-dom: - specifier: 20.6.0 - version: 20.6.0 + specifier: 20.6.1 + version: 20.6.1 jiti: specifier: 2.6.1 version: 2.6.1 @@ -319,23 +319,23 @@ importers: specifier: 1.8.1 version: 1.8.1 spectral-cli-bundle: - specifier: 1.0.4 - version: 1.0.4 + specifier: 1.0.7 + version: 1.0.7 stylelint: - specifier: 17.1.1 - version: 17.1.1(typescript@5.9.3) + specifier: 17.3.0 + version: 17.3.0(typescript@5.9.3) stylelint-config-recommended: specifier: 18.0.0 - version: 18.0.0(stylelint@17.1.1(typescript@5.9.3)) + version: 18.0.0(stylelint@17.3.0(typescript@5.9.3)) stylelint-declaration-block-no-ignored-properties: specifier: 3.0.0 - version: 3.0.0(stylelint@17.1.1(typescript@5.9.3)) + version: 3.0.0(stylelint@17.3.0(typescript@5.9.3)) stylelint-declaration-strict-value: specifier: 1.10.11 - version: 1.10.11(stylelint@17.1.1(typescript@5.9.3)) + version: 1.10.11(stylelint@17.3.0(typescript@5.9.3)) stylelint-value-no-unknown-custom-properties: specifier: 6.1.1 - version: 6.1.1(stylelint@17.1.1(typescript@5.9.3)) + version: 6.1.1(stylelint@17.3.0(typescript@5.9.3)) svgo: specifier: 4.0.0 version: 4.0.0 @@ -343,17 +343,17 @@ importers: specifier: 5.9.3 version: 5.9.3 typescript-eslint: - specifier: 8.55.0 - version: 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + specifier: 8.56.0 + version: 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) updates: - specifier: 17.4.0 - version: 17.4.0 + specifier: 17.5.7 + version: 17.5.7 vite-string-plugin: specifier: 2.0.1 - version: 2.0.1(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2)) + version: 2.0.1(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2)) vitest: specifier: 4.0.18 - version: 4.0.18(@types/node@25.2.2)(happy-dom@20.6.0)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2) + version: 4.0.18(@types/node@25.2.3)(happy-dom@20.6.1)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2) vue-tsc: specifier: 3.2.4 version: 3.2.4(typescript@5.9.3) @@ -401,20 +401,20 @@ packages: '@cacheable/utils@2.3.4': resolution: {integrity: sha512-knwKUJEYgIfwShABS1BX6JyJJTglAFcEU7EXqzTdiGCXur4voqkiJkdgZIQtWNFhynzDWERcTYv/sETMu3uJWA==} - '@chevrotain/cst-dts-gen@11.0.3': - resolution: {integrity: sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==} + '@chevrotain/cst-dts-gen@11.1.1': + resolution: {integrity: sha512-fRHyv6/f542qQqiRGalrfJl/evD39mAvbJLCekPazhiextEatq1Jx1K/i9gSd5NNO0ds03ek0Cbo/4uVKmOBcw==} - '@chevrotain/gast@11.0.3': - resolution: {integrity: sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==} + '@chevrotain/gast@11.1.1': + resolution: {integrity: sha512-Ko/5vPEYy1vn5CbCjjvnSO4U7GgxyGm+dfUZZJIWTlQFkXkyym0jFYrWEU10hyCjrA7rQtiHtBr0EaZqvHFZvg==} - '@chevrotain/regexp-to-ast@11.0.3': - resolution: {integrity: sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==} + '@chevrotain/regexp-to-ast@11.1.1': + resolution: {integrity: sha512-ctRw1OKSXkOrR8VTvOxrQ5USEc4sNrfwXHa1NuTcR7wre4YbjPcKw+82C2uylg/TEwFRgwLmbhlln4qkmDyteg==} - '@chevrotain/types@11.0.3': - resolution: {integrity: sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==} + '@chevrotain/types@11.1.1': + resolution: {integrity: sha512-wb2ToxG8LkgPYnKe9FH8oGn3TMCBdnwiuNC5l5y+CtlaVRbCytU0kbVsk6CGrqTL4ZN4ksJa0TXOYbxpbthtqw==} - '@chevrotain/utils@11.0.3': - resolution: {integrity: sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==} + '@chevrotain/utils@11.1.1': + resolution: {integrity: sha512-71eTYMzYXYSFPrbg/ZwftSaSDld7UYlS8OQa3lNnn9jzNtpFbaReRRyghzqS7rI3CDaorqpPJJcXGHK+FE1TVQ==} '@citation-js/core@0.7.21': resolution: {integrity: sha512-Vobv2/Yfnn6C6BVO/pvj7madQ7Mfzl83/jAWwixbemGF6ZThhGMz8++FD9hWHyHXDMYuLGa6fK68c2VsolZmTA==} @@ -464,6 +464,13 @@ packages: resolution: {integrity: sha512-3XQOO3u4WXY/7AWZyQ+9SuBzS8bYTlJ+NF1uCgrZO64g36nK5iIc5YV9cBl2TL2QhHF6S36nvAsXsj5fX9FeHw==} engines: {node: '>=14.0.0'} + '@csstools/css-calc@3.1.1': + resolution: {integrity: sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-parser-algorithms': ^4.0.0 + '@csstools/css-tokenizer': ^4.0.0 + '@csstools/css-parser-algorithms@4.0.0': resolution: {integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==} engines: {node: '>=20.19.0'} @@ -774,6 +781,10 @@ packages: resolution: {integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==} engines: {node: 20 || >=22} + '@isaacs/cliui@9.0.0': + resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==} + engines: {node: '>=18'} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -813,8 +824,8 @@ packages: peerDependencies: mermaid: ^11.0.2 - '@mermaid-js/parser@0.6.3': - resolution: {integrity: sha512-lnjOhe7zyHjc+If7yT4zoedx2vo4sHaTmtkl1+or8BRTnCtDmcTpAjpzDSfCZrshM5bCoz0GyidzadJAH1xobA==} + '@mermaid-js/parser@1.0.0': + resolution: {integrity: sha512-vvK0Hi/VWndxoh03Mmz6wa1KDriSPjS2XMZL/1l19HFwygiObEEoEwSDxOqyLzzAI6J2PU3261JjTMTO7x+BPw==} '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} @@ -906,8 +917,8 @@ packages: '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} - '@primer/octicons@19.21.2': - resolution: {integrity: sha512-SRTcpAZtKYh2266VQpAqNkXAQpPvYWk6dxggkHDzwI95NrE5mEzJ7cfFt/bSVbqDffKQ+tm7TEdLHoSjEcggfQ==} + '@primer/octicons@19.22.0': + resolution: {integrity: sha512-nWoh9PlE6u7xbiZF3KcUm3ktLpN2rQPt11trwp/t4EsKuYRNVWVbBp1LkCBsvZq7ScckNKUURLigIU0wS1FQdw==} '@resvg/resvg-wasm@2.6.2': resolution: {integrity: sha512-FqALmHI8D4o6lk/LRWDnhw95z5eO+eAa6ORjVg09YRR7BkcM6oPHU9uyC0gtQG5vpFLvgpeU4+zEAz2H8APHNw==} @@ -1229,6 +1240,9 @@ packages: '@types/eslint@9.6.1': resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + '@types/esrecurse@4.3.1': + resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -1259,8 +1273,8 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@25.2.2': - resolution: {integrity: sha512-BkmoP5/FhRYek5izySdkOneRyXYN35I860MFAGupTdebyE66uZaR+bXLHq8k4DirE5DwQi3NuhvRU1jqTVwUrQ==} + '@types/node@25.2.3': + resolution: {integrity: sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==} '@types/pdfobject@2.2.5': resolution: {integrity: sha512-7gD5tqc/RUDq0PyoLemL0vEHxBYi+zY0WVaFAx/Y0jBsXFgot1vB9No1GhDZGwRGJMCIZbgAb74QG9MTyTNU/g==} @@ -1298,63 +1312,63 @@ packages: '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - '@typescript-eslint/eslint-plugin@8.55.0': - resolution: {integrity: sha512-1y/MVSz0NglV1ijHC8OT49mPJ4qhPYjiK08YUQVbIOyu+5k862LKUHFkpKHWu//zmr7hDR2rhwUm6gnCGNmGBQ==} + '@typescript-eslint/eslint-plugin@8.56.0': + resolution: {integrity: sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.55.0 - eslint: ^8.57.0 || ^9.0.0 + '@typescript-eslint/parser': ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.55.0': - resolution: {integrity: sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==} + '@typescript-eslint/parser@8.56.0': + resolution: {integrity: sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.55.0': - resolution: {integrity: sha512-zRcVVPFUYWa3kNnjaZGXSu3xkKV1zXy8M4nO/pElzQhFweb7PPtluDLQtKArEOGmjXoRjnUZ29NjOiF0eCDkcQ==} + '@typescript-eslint/project-service@8.56.0': + resolution: {integrity: sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.55.0': - resolution: {integrity: sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q==} + '@typescript-eslint/scope-manager@8.56.0': + resolution: {integrity: sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.55.0': - resolution: {integrity: sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q==} + '@typescript-eslint/tsconfig-utils@8.56.0': + resolution: {integrity: sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.55.0': - resolution: {integrity: sha512-x1iH2unH4qAt6I37I2CGlsNs+B9WGxurP2uyZLRz6UJoZWDBx9cJL1xVN/FiOmHEONEg6RIufdvyT0TEYIgC5g==} + '@typescript-eslint/type-utils@8.56.0': + resolution: {integrity: sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.55.0': - resolution: {integrity: sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==} + '@typescript-eslint/types@8.56.0': + resolution: {integrity: sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.55.0': - resolution: {integrity: sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==} + '@typescript-eslint/typescript-estree@8.56.0': + resolution: {integrity: sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.55.0': - resolution: {integrity: sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow==} + '@typescript-eslint/utils@8.56.0': + resolution: {integrity: sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.55.0': - resolution: {integrity: sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==} + '@typescript-eslint/visitor-keys@8.56.0': + resolution: {integrity: sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@unrs/resolver-binding-android-arm-eabi@1.11.1': @@ -1467,8 +1481,8 @@ packages: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 vue: ^3.2.25 - '@vitest/eslint-plugin@1.6.7': - resolution: {integrity: sha512-sd2QJirEscSQk3Pywtelbs7z8RQp1gyF5BfeZVtTHE8y3suyzbAA71NuT9z01uTRMHoCf5p6M2t2WYNJ7m5FlA==} + '@vitest/eslint-plugin@1.6.9': + resolution: {integrity: sha512-9WfPx1OwJ19QLCSRLkqVO7//1WcWnK3fE/3fJhKMAmDe8+9G4rB47xCNIIeCq3FdEzkIoLTfDlwDlPBaUTMhow==} engines: {node: '>=18'} peerDependencies: eslint: '>=8.57.0' @@ -1667,8 +1681,8 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - ajv@8.17.1: - resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} alien-signals@3.1.2: resolution: {integrity: sha512-d9dYqZTS90WLiU0I5c6DHj/HcKkF8ZyGN3G5x8wSbslulz70KOxaqCT0hQCo9KOyhVqzqGojvNdJXoTumZOtcw==} @@ -1713,8 +1727,8 @@ packages: resolution: {integrity: sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==} engines: {node: '>=0.10.0'} - asciinema-player@3.14.0: - resolution: {integrity: sha512-44m3CpNavn8i7DSr/AeeV+rJpHpcqc/OCildCs9FAu5gnXB6XNBdbhfg6mHMG4uU3R1rxFNA3ZRTt8FMhHC48Q==} + asciinema-player@3.14.15: + resolution: {integrity: sha512-M+6n0GXMc9X4Oaz9qOr5pfQGcmnPOW8QIBzf67eZvtSpyqiKexMA03CpP4S9ZaDuUQNQIF2RSjHl6QLgJYvJ9g==} assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} @@ -1747,6 +1761,10 @@ packages: resolution: {integrity: sha512-vjtV3hiLqYDNRoiAv0zC4QaGAMPomEoq83PRmYIofPswwZurCeWR5LByXm7SyoL0Zh5+2z0+HC7jG8gSZJUh0w==} engines: {node: '>= 16'} + balanced-match@4.0.2: + resolution: {integrity: sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==} + engines: {node: 20 || >=22} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -1770,6 +1788,10 @@ packages: brace-expansion@2.0.2: resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + brace-expansion@5.0.2: + resolution: {integrity: sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==} + engines: {node: 20 || >=22} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -1808,8 +1830,8 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} - caniuse-lite@1.0.30001769: - resolution: {integrity: sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==} + caniuse-lite@1.0.30001770: + resolution: {integrity: sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==} chai@6.2.2: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} @@ -1852,8 +1874,8 @@ packages: peerDependencies: chevrotain: ^11.0.0 - chevrotain@11.0.3: - resolution: {integrity: sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==} + chevrotain@11.1.1: + resolution: {integrity: sha512-f0yv5CPKaFxfsPTBzX7vGuim4oIC1/gcS7LUGdBSwl2dU6+FON6LVUksdOo1qJjoUvXNn45urgh8C+0a24pACQ==} chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} @@ -1971,15 +1993,15 @@ packages: 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-functions-list@3.3.3: + resolution: {integrity: sha512-8HFEBPKhOpJPEPu70wJJetjKta86Gw9+CCyCnB3sui2qQfOvRyqBy4IKLKKAwdMpWb2lHXWk9Wb4Z6AmaUT1Pg==} + engines: {node: '>=12'} - css-loader@7.1.3: - resolution: {integrity: sha512-frbERmjT0UC5lMheWpJmMilnt9GEhbZJN/heUb7/zaJYeIzj5St9HvDcfshzzOqbsS+rYpMk++2SD3vGETDSyA==} + css-loader@7.1.4: + resolution: {integrity: sha512-vv3J9tlOl04WjiMvHQI/9tmIrCxVrj6PFbHemBB1iihpeRbi/I4h033eoFIhwxBBqLhI0KYFS7yvynBFhIZfTw==} engines: {node: '>= 18.12.0'} peerDependencies: - '@rspack/core': 0.x || 1.x + '@rspack/core': 0.x || ^1.0.0 || ^2.0.0-0 webpack: ^5.27.0 peerDependenciesMeta: '@rspack/core': @@ -2487,13 +2509,13 @@ packages: peerDependencies: eslint: '>=9.38.0' - eslint-plugin-sonarjs@3.0.6: - resolution: {integrity: sha512-3mVUqsAUSylGfkJMj2v0aC2Cu/eUunDLm+XMjLf0uLjAZao205NWF3g6EXxcCAFO+rCZiQ6Or1WQkUcU9/sKFQ==} + eslint-plugin-sonarjs@3.0.7: + resolution: {integrity: sha512-62jB20krIPvcwBLAyG3VVKa2ce2j2lL1yCb8Y0ylMRR/dLvCCTiQx8gQbXb+G81k1alPZ2/I3muZinqWQdBbzw==} peerDependencies: eslint: ^8.0.0 || ^9.0.0 - eslint-plugin-unicorn@62.0.0: - resolution: {integrity: sha512-HIlIkGLkvf29YEiS/ImuDZQbP12gWyx5i3C6XrRxMvVdqMroCI9qoVYCoIl17ChN+U89pn9sVwLxhIWj5nEc7g==} + eslint-plugin-unicorn@63.0.0: + resolution: {integrity: sha512-Iqecl9118uQEXYh7adylgEmGfkn5es3/mlQTLLkd4pXkIk9CTGrAbeUux+YljSa2ohXCBmQQ0+Ej1kZaFgcfkA==} engines: {node: ^20.10.0 || >=21.0.0} peerDependencies: eslint: '>=9.38.0' @@ -2505,13 +2527,13 @@ packages: eslint: '>=5.0.0' vue-eslint-parser: '>=7.1.0' - eslint-plugin-vue@10.7.0: - resolution: {integrity: sha512-r2XFCK4qlo1sxEoAMIoTTX0PZAdla0JJDt1fmYiworZUX67WeEGqm+JbyAg3M+pGiJ5U6Mp5WQbontXWtIW7TA==} + eslint-plugin-vue@10.8.0: + resolution: {integrity: sha512-f1J/tcbnrpgC8suPN5AtdJ5MQjuXbSU9pGRSSYAuF3SHoiYCOdEX6O22pLaRyLHXvDcOe+O5ENgc1owQ587agA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@stylistic/eslint-plugin': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 '@typescript-eslint/parser': ^7.0.0 || ^8.0.0 - eslint: ^8.57.0 || ^9.0.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 vue-eslint-parser: ^10.0.0 peerDependenciesMeta: '@stylistic/eslint-plugin': @@ -2536,6 +2558,10 @@ packages: resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-scope@9.1.0: + resolution: {integrity: sha512-CkWE42hOJsNj9FJRaoMX9waUFYhqY4jmyLFdAdzZr6VaCg3ynLYx4WnOdkaIifGfH4gsUcBTn4OZbHXkpLD0FQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + 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} @@ -2544,6 +2570,10 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@5.0.0: + resolution: {integrity: sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + eslint@9.39.2: resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2558,6 +2588,10 @@ packages: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@11.1.0: + resolution: {integrity: sha512-WFWYhO1fV4iYkqOOvq8FbqIhr2pYfoDY0kCotMkDeNtGpiGGkZ1iov2u8ydjtgM8yF8rzK7oaTbw2NAzbAbehw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + esquery@1.7.0: resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} @@ -2748,8 +2782,8 @@ packages: resolution: {integrity: sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==} engines: {node: '>=0.8.0'} - happy-dom@20.6.0: - resolution: {integrity: sha512-a+Sz2bPai3rajDuE82Y4B0OxlXJ19ckUjyfWDmeCAs8ZbEbnqtwzV9d4CVhQjWIuOBTOw8rhlxNeaSCHeknXRQ==} + happy-dom@20.6.1: + resolution: {integrity: sha512-+0vhESXXhFwkdjZnJ5DlmJIfUYGgIEEjzIjB+aKJbFuqlvvKyOi+XkI1fYbgYR9QCxG5T08koxsQ6HrQfa5gCQ==} engines: {node: '>=20.0.0'} has-flag@4.0.0: @@ -2919,6 +2953,10 @@ packages: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} + jackspeak@4.2.3: + resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==} + engines: {node: 20 || >=22} + jest-worker@27.5.1: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} @@ -3022,9 +3060,9 @@ packages: known-css-properties@0.37.0: resolution: {integrity: sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==} - langium@3.3.1: - resolution: {integrity: sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==} - engines: {node: '>=16.0.0'} + langium@4.2.1: + resolution: {integrity: sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==} + engines: {node: '>=20.10.0', npm: '>=10.2.3'} language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -3069,9 +3107,6 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} - lodash-es@4.17.21: - resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} - lodash-es@4.17.23: resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} @@ -3102,8 +3137,8 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - markdown-it@14.1.0: - resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + markdown-it@14.1.1: + resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} hasBin: true markdownlint-cli@0.47.0: @@ -3157,8 +3192,8 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - mermaid@11.12.2: - resolution: {integrity: sha512-n34QPDPEKmaeCG4WDMGy0OT6PSyxKCfy2pJgShP+Qow2KLrvWjclwbc3yXfSIf4BanqWEhQEpngWwNp/XhZt6w==} + mermaid@11.12.3: + resolution: {integrity: sha512-wN5ZSgJQIC+CHJut9xaKWsknLxaFBwCPwPkGTSUYrTiHORWvpT8RxGk849HPnpUAQ+/9BPRqYb80jTpearrHzQ==} micromark-core-commonmark@2.0.3: resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} @@ -3253,14 +3288,18 @@ packages: peerDependencies: webpack: ^5.0.0 - minimatch@10.1.1: - resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} - engines: {node: 20 || >=22} - minimatch@10.1.2: resolution: {integrity: sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==} engines: {node: 20 || >=22} + minimatch@10.1.3: + resolution: {integrity: sha512-IF6URNyBX7Z6XfvjpaNy5meRxPZiIf2OqtOoSLs+hLJ9pJAScnM1RjrFcbCaD85y42KcI+oZmKjFIJKYDFjQfg==} + engines: {node: 20 || >=22} + + minimatch@10.2.1: + resolution: {integrity: sha512-MClCe8IL5nRRmawL6ib/eT4oLyeKMGCghibcDWK+J0hh0Q8kqSdia6BvbRMVk6mPa6WqUa5uR2oxt6C5jd533A==} + engines: {node: 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -3506,11 +3545,11 @@ packages: ts-node: optional: true - postcss-loader@8.2.0: - resolution: {integrity: sha512-tHX+RkpsXVcc7st4dSdDGliI+r4aAQDuv+v3vFYHixb6YgjreG5AG4SEB0kDK8u2s6htqEEpKlkhSBUTvWKYnA==} + postcss-loader@8.2.1: + resolution: {integrity: sha512-k98jtRzthjj3f76MYTs9JTpRqV1RaaMhEU0Lpw9OTmQZQdppg4B30VZ74BojuBHt3F4KyubHJoXCMUeM8Bqeow==} engines: {node: '>= 18.12.0'} peerDependencies: - '@rspack/core': 0.x || 1.x + '@rspack/core': 0.x || ^1.0.0 || ^2.0.0-0 postcss: ^7.0.0 || ^8.0.1 webpack: ^5.0.0 peerDependenciesMeta: @@ -3716,11 +3755,6 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.3: - resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} - engines: {node: '>=10'} - hasBin: true - semver@7.7.4: resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} engines: {node: '>=10'} @@ -3779,8 +3813,8 @@ packages: peerDependencies: solid-js: ^1.6.12 - sortablejs@1.15.6: - resolution: {integrity: sha512-aNfiuwMEpfBM/CN6LY0ibyhxPfPbyFeBTYJKCvzkJ2GkUpazIt3H+QIPAMHwqQ7tMKaHz1Qj+rJJCqljnf4p3A==} + sortablejs@1.15.7: + resolution: {integrity: sha512-Kk8wLQPlS+yi1ZEf48a4+fzHa4yxjC30M/Sr2AnQu+f/MPwvvX9XjZ6OWejiz8crBsLwSq8GHqaxaET7u6ux0A==} source-list-map@2.0.1: resolution: {integrity: sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==} @@ -3825,8 +3859,8 @@ packages: spdx-satisfies@5.0.1: resolution: {integrity: sha512-Nwor6W6gzFp8XX4neaKQ7ChV4wmpSh2sSDemMFSzHxpTw460jxFYeOn+jq4ybnSSw/5sc3pjka9MQPouksQNpw==} - spectral-cli-bundle@1.0.4: - resolution: {integrity: sha512-DfArdHmRj8zMlDclROso5sWQzYzn2FZ616bYPstd/+SWdspP99YuUsWRePR32dd2Vj2ic9kfs2INlL749s9Puw==} + spectral-cli-bundle@1.0.7: + resolution: {integrity: sha512-vIUC0nwv9tYxWV1xHdR3CTVDOEEtLKaDCcQpARZgO0Db7VmSpSWJ4xrnVPNSmO59hBtGwW2CVzHf0OimJBaKAA==} engines: {node: '>=20'} hasBin: true @@ -3903,8 +3937,8 @@ packages: peerDependencies: stylelint: '>=16' - stylelint@17.1.1: - resolution: {integrity: sha512-SBHVcLEcRF1M9OkD3oT0hT2PayDNLw2hd+aovmzfNQ2ys4Xd3oS9ZNizILWqhQvW802AqKN/vUTMwJqQYMBlWw==} + stylelint@17.3.0: + resolution: {integrity: sha512-1POV91lcEMhj6SLVaOeA0KlS9yattS+qq+cyWqP/nYzWco7K5jznpGH1ExngvPlTM9QF1Kjd2bmuzJu9TH2OcA==} engines: {node: '>=20.19.0'} hasBin: true @@ -3957,8 +3991,8 @@ packages: svgson@5.3.1: resolution: {integrity: sha512-qdPgvUNWb40gWktBJnbJRelWcPzkLed/ShhnRsjbayXz8OtdPOzbil9jtiZdrYvSDumAz/VNQr6JaNfPx/gvPA==} - swagger-ui-dist@5.31.0: - resolution: {integrity: sha512-zSUTIck02fSga6rc0RZP3b7J7wgHXwLea8ZjgLA3Vgnb8QeOl3Wou2/j5QkzSGeoz6HusP/coYuJl33aQxQZpg==} + swagger-ui-dist@5.31.1: + resolution: {integrity: sha512-XdgQ8wkRGj1P0H0Vvo0TRMOQNz+8Q8J64/vcPOhxlaFx9eB3PYvHMXeyNrP46PXa9SUs/cg7OW/jm9U34KzUfA==} sync-fetch@0.4.5: resolution: {integrity: sha512-esiWJ7ixSKGpd9DJPBTC4ckChqdOjIwJfYhVHkcQ2Gnm41323p1TRmEI+esTQ9ppD+b5opps2OTEGTCGX5kF+g==} @@ -4073,11 +4107,11 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - typescript-eslint@8.55.0: - resolution: {integrity: sha512-HE4wj+r5lmDVS9gdaN0/+iqNvPZwGfnJ5lZuz7s5vLlg9ODw0bIiiETaios9LvFI1U94/VBXGm3CB2Y5cNFMpw==} + typescript-eslint@8.56.0: + resolution: {integrity: sha512-c7toRLrotJ9oixgdW7liukZpsnq5CZ7PuKztubGYlNppuTqhIoWfhgHo/7EU0v06gS2l/x0i2NEFK1qMIf0rIg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' typescript@5.9.3: @@ -4113,8 +4147,8 @@ packages: peerDependencies: browserslist: '>= 4.21.0' - updates@17.4.0: - resolution: {integrity: sha512-7Lnof1TshAdMw9u/R3Deobcd53sYlaU3ZwULNhOtAVu6DMPEmdi2G7ERnyPZpFThbMLxNX2scCGz3wWTcNjY2Q==} + updates@17.5.7: + resolution: {integrity: sha512-tL/MWd5iQ04J2CP9PYIjKxgM/ZM2J5CCq1M1yY4wUB/LNKU/7Sh0Ss5SnZ/aOzSlzQlWlOVgI/7ABJ/pAUp6dw==} engines: {node: '>=22'} hasBin: true @@ -4227,9 +4261,6 @@ packages: 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==} @@ -4242,11 +4273,11 @@ packages: 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==} + vue-eslint-parser@10.4.0: + resolution: {integrity: sha512-Vxi9pJdbN3ZnVGLODVtZ7y4Y2kzAAE2Cm0CZ3ZDRvydVYxZ6VrnBhLikBsRS+dpwj4Jv4UCv21PTEwF5rQ9WXg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 vue-loader@17.4.2: resolution: {integrity: sha512-yTKOA4R/VN4jqjw4y5HrynFL8AK0Z3/Jt7eOJXEitsm0GMRHDBjCfCiuTiLP7OESvsZYo2pATCWhDqxC5ZrM6w==} @@ -4302,12 +4333,12 @@ packages: webpack-sources@1.4.3: resolution: {integrity: sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==} - webpack-sources@3.3.3: - resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} + webpack-sources@3.3.4: + resolution: {integrity: sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==} engines: {node: '>=10.13.0'} - webpack@5.105.0: - resolution: {integrity: sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==} + webpack@5.105.2: + resolution: {integrity: sha512-dRXm0a2qcHPUBEzVk8uph0xWSjV/xZxenQQbLwnwP7caQCYpqG1qddwlyEkIDkYn0K8tvmcrZ+bOrzoQ3HxCDw==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -4434,22 +4465,22 @@ snapshots: hashery: 1.4.0 keyv: 5.6.0 - '@chevrotain/cst-dts-gen@11.0.3': + '@chevrotain/cst-dts-gen@11.1.1': dependencies: - '@chevrotain/gast': 11.0.3 - '@chevrotain/types': 11.0.3 - lodash-es: 4.17.21 + '@chevrotain/gast': 11.1.1 + '@chevrotain/types': 11.1.1 + lodash-es: 4.17.23 - '@chevrotain/gast@11.0.3': + '@chevrotain/gast@11.1.1': dependencies: - '@chevrotain/types': 11.0.3 - lodash-es: 4.17.21 + '@chevrotain/types': 11.1.1 + lodash-es: 4.17.23 - '@chevrotain/regexp-to-ast@11.0.3': {} + '@chevrotain/regexp-to-ast@11.1.1': {} - '@chevrotain/types@11.0.3': {} + '@chevrotain/types@11.1.1': {} - '@chevrotain/utils@11.0.3': {} + '@chevrotain/utils@11.1.1': {} '@citation-js/core@0.7.21': dependencies: @@ -4509,6 +4540,11 @@ snapshots: '@citation-js/date': 0.5.1 '@citation-js/name': 0.4.2 + '@csstools/css-calc@3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 + '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)': dependencies: '@csstools/css-tokenizer': 4.0.0 @@ -4733,6 +4769,8 @@ snapshots: dependencies: '@isaacs/balanced-match': 4.0.1 + '@isaacs/cliui@9.0.0': {} + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -4768,15 +4806,15 @@ snapshots: dependencies: '@mcaptcha/core-glue': 0.1.0-alpha-5 - '@mermaid-js/layout-elk@0.2.0(mermaid@11.12.2)': + '@mermaid-js/layout-elk@0.2.0(mermaid@11.12.3)': dependencies: d3: 7.9.0 elkjs: 0.9.3 - mermaid: 11.12.2 + mermaid: 11.12.3 - '@mermaid-js/parser@0.6.3': + '@mermaid-js/parser@1.0.0': dependencies: - langium: 3.3.1 + langium: 4.2.1 '@napi-rs/wasm-runtime@0.2.12': dependencies: @@ -4857,7 +4895,7 @@ snapshots: '@popperjs/core@2.11.8': {} - '@primer/octicons@19.21.2': + '@primer/octicons@19.22.0': dependencies: object-assign: 4.1.1 @@ -4974,14 +5012,14 @@ snapshots: '@stylistic/eslint-plugin@5.8.0(eslint@9.39.2(jiti@2.6.1))': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) - '@typescript-eslint/types': 8.55.0 + '@typescript-eslint/types': 8.56.0 eslint: 9.39.2(jiti@2.6.1) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 picomatch: 4.0.3 - '@stylistic/stylelint-plugin@5.0.1(stylelint@17.1.1(typescript@5.9.3))': + '@stylistic/stylelint-plugin@5.0.1(stylelint@17.3.0(typescript@5.9.3))': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 @@ -4990,11 +5028,11 @@ snapshots: postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 style-search: 0.1.0 - stylelint: 17.1.1(typescript@5.9.3) + stylelint: 17.3.0(typescript@5.9.3) '@swc/helpers@0.2.14': {} - '@techknowlogick/license-checker-webpack-plugin@0.3.0(webpack@5.105.0)': + '@techknowlogick/license-checker-webpack-plugin@0.3.0(webpack@5.105.2)': dependencies: glob: 7.2.3 lodash: 4.17.23 @@ -5003,7 +5041,7 @@ snapshots: spdx-expression-validate: 2.0.0 spdx-satisfies: 5.0.1 superstruct: 0.10.13 - webpack: 5.105.0(webpack-cli@6.0.1) + webpack: 5.105.2(webpack-cli@6.0.1) webpack-sources: 1.4.3 wrap-ansi: 6.2.0 @@ -5158,6 +5196,8 @@ snapshots: '@types/estree': 1.0.8 '@types/json-schema': 7.0.15 + '@types/esrecurse@4.3.1': {} + '@types/estree@1.0.8': {} '@types/geojson@7946.0.16': {} @@ -5180,7 +5220,7 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node@25.2.2': + '@types/node@25.2.3': dependencies: undici-types: 7.16.0 @@ -5211,16 +5251,16 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 25.2.2 + '@types/node': 25.2.3 - '@typescript-eslint/eslint-plugin@8.55.0(@typescript-eslint/parser@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.55.0 - '@typescript-eslint/type-utils': 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.55.0 + '@typescript-eslint/parser': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.56.0 + '@typescript-eslint/type-utils': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.56.0 eslint: 9.39.2(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 @@ -5229,41 +5269,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.55.0 - '@typescript-eslint/types': 8.55.0 - '@typescript-eslint/typescript-estree': 8.55.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.55.0 + '@typescript-eslint/scope-manager': 8.56.0 + '@typescript-eslint/types': 8.56.0 + '@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.56.0 debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.55.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.56.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.55.0(typescript@5.9.3) - '@typescript-eslint/types': 8.55.0 + '@typescript-eslint/tsconfig-utils': 8.56.0(typescript@5.9.3) + '@typescript-eslint/types': 8.56.0 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.55.0': + '@typescript-eslint/scope-manager@8.56.0': dependencies: - '@typescript-eslint/types': 8.55.0 - '@typescript-eslint/visitor-keys': 8.55.0 + '@typescript-eslint/types': 8.56.0 + '@typescript-eslint/visitor-keys': 8.56.0 - '@typescript-eslint/tsconfig-utils@8.55.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.56.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.55.0 - '@typescript-eslint/typescript-estree': 8.55.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.56.0 + '@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) ts-api-utils: 2.4.0(typescript@5.9.3) @@ -5271,14 +5311,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.55.0': {} + '@typescript-eslint/types@8.56.0': {} - '@typescript-eslint/typescript-estree@8.55.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.56.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.55.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.55.0(typescript@5.9.3) - '@typescript-eslint/types': 8.55.0 - '@typescript-eslint/visitor-keys': 8.55.0 + '@typescript-eslint/project-service': 8.56.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.56.0(typescript@5.9.3) + '@typescript-eslint/types': 8.56.0 + '@typescript-eslint/visitor-keys': 8.56.0 debug: 4.4.3 minimatch: 9.0.5 semver: 7.7.4 @@ -5288,21 +5328,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.55.0 - '@typescript-eslint/types': 8.55.0 - '@typescript-eslint/typescript-estree': 8.55.0(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.56.0 + '@typescript-eslint/types': 8.56.0 + '@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.55.0': + '@typescript-eslint/visitor-keys@8.56.0': dependencies: - '@typescript-eslint/types': 8.55.0 - eslint-visitor-keys: 4.2.1 + '@typescript-eslint/types': 8.56.0 + eslint-visitor-keys: 5.0.0 '@unrs/resolver-binding-android-arm-eabi@1.11.1': optional: true @@ -5363,20 +5403,20 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true - '@vitejs/plugin-vue@6.0.4(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.28(typescript@5.9.3))': + '@vitejs/plugin-vue@6.0.4(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.28(typescript@5.9.3))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.2 - vite: 7.3.1(@types/node@25.2.2)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2) vue: 3.5.28(typescript@5.9.3) - '@vitest/eslint-plugin@1.6.7(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)(vitest@4.0.18(@types/node@25.2.2)(happy-dom@20.6.0)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2))': + '@vitest/eslint-plugin@1.6.9(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)(vitest@4.0.18(@types/node@25.2.3)(happy-dom@20.6.1)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2))': dependencies: - '@typescript-eslint/scope-manager': 8.55.0 - '@typescript-eslint/utils': 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.56.0 + '@typescript-eslint/utils': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) optionalDependencies: typescript: 5.9.3 - vitest: 4.0.18(@types/node@25.2.2)(happy-dom@20.6.0)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2) + vitest: 4.0.18(@types/node@25.2.3)(happy-dom@20.6.1)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color @@ -5389,13 +5429,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2))': + '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@25.2.2)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2) '@vitest/pretty-format@4.0.18': dependencies: @@ -5571,20 +5611,20 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 - '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1)(webpack@5.105.0)': + '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1)(webpack@5.105.2)': dependencies: - webpack: 5.105.0(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack@5.105.0) + webpack: 5.105.2(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack@5.105.2) - '@webpack-cli/info@3.0.1(webpack-cli@6.0.1)(webpack@5.105.0)': + '@webpack-cli/info@3.0.1(webpack-cli@6.0.1)(webpack@5.105.2)': dependencies: - webpack: 5.105.0(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack@5.105.0) + webpack: 5.105.2(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack@5.105.2) - '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1)(webpack@5.105.0)': + '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1)(webpack@5.105.2)': dependencies: - webpack: 5.105.0(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack@5.105.0) + webpack: 5.105.2(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack@5.105.2) '@xtuc/ieee754@1.2.0': {} @@ -5600,17 +5640,17 @@ snapshots: acorn@8.15.0: {} - add-asset-webpack-plugin@3.1.1(webpack@5.105.0): + add-asset-webpack-plugin@3.1.1(webpack@5.105.2): optionalDependencies: - webpack: 5.105.0(webpack-cli@6.0.1) + webpack: 5.105.2(webpack-cli@6.0.1) - ajv-formats@2.1.1(ajv@8.17.1): + ajv-formats@2.1.1(ajv@8.18.0): optionalDependencies: - ajv: 8.17.1 + ajv: 8.18.0 - ajv-keywords@5.1.0(ajv@8.17.1): + ajv-keywords@5.1.0(ajv@8.18.0): dependencies: - ajv: 8.17.1 + ajv: 8.18.0 fast-deep-equal: 3.1.3 ajv@6.12.6: @@ -5620,7 +5660,7 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - ajv@8.17.1: + ajv@8.18.0: dependencies: fast-deep-equal: 3.1.3 fast-uri: 3.1.0 @@ -5656,7 +5696,7 @@ snapshots: array-find-index@1.0.2: {} - asciinema-player@3.14.0: + asciinema-player@3.14.15: dependencies: '@babel/runtime': 7.28.6 solid-js: 1.9.11 @@ -5678,6 +5718,10 @@ snapshots: balanced-match@3.0.1: {} + balanced-match@4.0.2: + dependencies: + jackspeak: 4.2.3 + base64-js@1.5.1: {} baseline-browser-mapping@2.9.19: {} @@ -5697,6 +5741,10 @@ snapshots: dependencies: balanced-match: 1.0.2 + brace-expansion@5.0.2: + dependencies: + balanced-match: 4.0.2 + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -5704,7 +5752,7 @@ snapshots: browserslist@4.28.1: dependencies: baseline-browser-mapping: 2.9.19 - caniuse-lite: 1.0.30001769 + caniuse-lite: 1.0.30001770 electron-to-chromium: 1.5.286 node-releases: 2.0.27 update-browserslist-db: 1.2.3(browserslist@4.28.1) @@ -5734,7 +5782,7 @@ snapshots: camelcase-css@2.0.1: {} - caniuse-lite@1.0.30001769: {} + caniuse-lite@1.0.30001770: {} chai@6.2.2: {} @@ -5766,19 +5814,19 @@ snapshots: chart.js: 4.5.1 hammerjs: 2.0.8 - chevrotain-allstar@0.3.1(chevrotain@11.0.3): + chevrotain-allstar@0.3.1(chevrotain@11.1.1): dependencies: - chevrotain: 11.0.3 + chevrotain: 11.1.1 lodash-es: 4.17.23 - chevrotain@11.0.3: + chevrotain@11.1.1: 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 + '@chevrotain/cst-dts-gen': 11.1.1 + '@chevrotain/gast': 11.1.1 + '@chevrotain/regexp-to-ast': 11.1.1 + '@chevrotain/types': 11.1.1 + '@chevrotain/utils': 11.1.1 + lodash-es: 4.17.23 chokidar@3.6.0: dependencies: @@ -5881,9 +5929,9 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-functions-list@3.2.3: {} + css-functions-list@3.3.3: {} - css-loader@7.1.3(webpack@5.105.0): + css-loader@7.1.4(webpack@5.105.2): dependencies: icss-utils: 5.1.0(postcss@8.5.6) postcss: 8.5.6 @@ -5894,7 +5942,7 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.7.4 optionalDependencies: - webpack: 5.105.0(webpack-cli@6.0.1) + webpack: 5.105.2(webpack-cli@6.0.1) css-select@5.2.2: dependencies: @@ -6235,12 +6283,12 @@ snapshots: es-module-lexer@2.0.0: {} - esbuild-loader@4.4.2(webpack@5.105.0): + esbuild-loader@4.4.2(webpack@5.105.2): dependencies: esbuild: 0.27.3 get-tsconfig: 4.13.6 loader-utils: 2.0.4 - webpack: 5.105.0(webpack-cli@6.0.1) + webpack: 5.105.2(webpack-cli@6.0.1) webpack-sources: 1.4.3 esbuild@0.27.3: @@ -6302,7 +6350,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)): + eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)): dependencies: debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) @@ -6313,19 +6361,19 @@ snapshots: tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)) - eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) 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.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)) + eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)) transitivePeerDependencies: - supports-color @@ -6358,8 +6406,8 @@ snapshots: '@eslint/eslintrc': 3.3.3 '@eslint/js': 9.39.2 '@github/browserslist-config': 1.0.0 - '@typescript-eslint/eslint-plugin': 8.55.0(@typescript-eslint/parser@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) aria-query: 5.3.2 eslint: 9.39.2(jiti@2.6.1) eslint-config-prettier: 10.1.8(eslint@9.39.2(jiti@2.6.1)) @@ -6367,7 +6415,7 @@ snapshots: eslint-plugin-eslint-comments: 3.2.0(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-filenames: 1.3.2(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-i18n-text: 1.0.1(eslint@9.39.2(jiti@2.6.1)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-no-only-tests: 3.3.0 eslint-plugin-prettier: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1))(prettier@3.8.1) @@ -6377,7 +6425,7 @@ snapshots: prettier: 3.8.1 svg-element-attributes: 1.3.1 typescript: 5.9.3 - typescript-eslint: 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + typescript-eslint: 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) transitivePeerDependencies: - '@types/eslint' - eslint-import-resolver-typescript @@ -6388,25 +6436,25 @@ snapshots: dependencies: eslint: 9.39.2(jiti@2.6.1) - eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)): + eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)): dependencies: - '@typescript-eslint/types': 8.55.0 + '@typescript-eslint/types': 8.56.0 comment-parser: 1.4.5 debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) eslint-import-context: 0.1.9(unrs-resolver@1.11.1) is-glob: 4.0.3 - minimatch: 10.1.2 + minimatch: 10.2.1 semver: 7.7.4 stable-hash-x: 0.2.0 unrs-resolver: 1.11.1 optionalDependencies: - '@typescript-eslint/utils': 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: '@nolyfill/array-includes@1.0.44' @@ -6417,7 +6465,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.2(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)) hasown: '@nolyfill/hasown@1.0.44' is-core-module: '@nolyfill/is-core-module@1.0.39' is-glob: 4.0.3 @@ -6429,7 +6477,7 @@ snapshots: string.prototype.trimend: '@nolyfill/string.prototype.trimend@1.0.44' tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -6482,7 +6530,7 @@ snapshots: regexp-ast-analysis: 0.7.1 scslre: 0.3.0 - eslint-plugin-sonarjs@3.0.6(eslint@9.39.2(jiti@2.6.1)): + eslint-plugin-sonarjs@3.0.7(eslint@9.39.2(jiti@2.6.1)): dependencies: '@eslint-community/regexpp': 4.12.2 builtin-modules: 3.3.0 @@ -6491,22 +6539,20 @@ snapshots: functional-red-black-tree: 1.0.1 jsx-ast-utils-x: 0.1.0 lodash.merge: 4.6.2 - minimatch: 10.1.1 + minimatch: 10.1.2 scslre: 0.3.0 - semver: 7.7.3 + semver: 7.7.4 typescript: 5.9.3 - eslint-plugin-unicorn@62.0.0(eslint@9.39.2(jiti@2.6.1)): + eslint-plugin-unicorn@63.0.0(eslint@9.39.2(jiti@2.6.1)): dependencies: '@babel/helper-validator-identifier': 7.28.5 '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) - '@eslint/plugin-kit': 0.4.1 change-case: 5.4.4 ci-info: 4.4.0 clean-regexp: 1.0.0 core-js-compat: 3.48.0 eslint: 9.39.2(jiti@2.6.1) - esquery: 1.7.0 find-up-simple: 1.0.1 globals: 16.5.0 indent-string: 5.0.0 @@ -6518,7 +6564,7 @@ snapshots: semver: 7.7.4 strip-indent: 4.1.1 - eslint-plugin-vue-scoped-css@2.12.0(eslint@9.39.2(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.39.2(jiti@2.6.1))): + eslint-plugin-vue-scoped-css@2.12.0(eslint@9.39.2(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.2(jiti@2.6.1))): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) eslint: 9.39.2(jiti@2.6.1) @@ -6529,11 +6575,11 @@ snapshots: postcss-scss: 4.0.9(postcss@8.5.6) postcss-selector-parser: 7.1.1 postcss-styl: 0.12.3 - vue-eslint-parser: 10.2.0(eslint@9.39.2(jiti@2.6.1)) + vue-eslint-parser: 10.4.0(eslint@9.39.2(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-plugin-vue@10.7.0(@stylistic/eslint-plugin@5.8.0(eslint@9.39.2(jiti@2.6.1)))(@typescript-eslint/parser@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.39.2(jiti@2.6.1))): + eslint-plugin-vue@10.8.0(@stylistic/eslint-plugin@5.8.0(eslint@9.39.2(jiti@2.6.1)))(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@9.39.2(jiti@2.6.1))): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) eslint: 9.39.2(jiti@2.6.1) @@ -6541,11 +6587,11 @@ snapshots: nth-check: 2.1.1 postcss-selector-parser: 7.1.1 semver: 7.7.4 - vue-eslint-parser: 10.2.0(eslint@9.39.2(jiti@2.6.1)) + vue-eslint-parser: 10.4.0(eslint@9.39.2(jiti@2.6.1)) xml-name-validator: 4.0.0 optionalDependencies: '@stylistic/eslint-plugin': 5.8.0(eslint@9.39.2(jiti@2.6.1)) - '@typescript-eslint/parser': 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint-plugin-wc@3.1.0(eslint@9.39.2(jiti@2.6.1)): dependencies: @@ -6565,10 +6611,19 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 + eslint-scope@9.1.0: + dependencies: + '@types/esrecurse': 4.3.1 + '@types/estree': 1.0.8 + esrecurse: 4.3.0 + estraverse: 5.3.0 + eslint-visitor-keys@3.4.3: {} eslint-visitor-keys@4.2.1: {} + eslint-visitor-keys@5.0.0: {} + eslint@9.39.2(jiti@2.6.1): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) @@ -6616,6 +6671,12 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 4.2.1 + espree@11.1.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 5.0.0 + esquery@1.7.0: dependencies: estraverse: 5.3.0 @@ -6785,9 +6846,9 @@ snapshots: hammerjs@2.0.8: {} - happy-dom@20.6.0: + happy-dom@20.6.1: dependencies: - '@types/node': 25.2.2 + '@types/node': 25.2.3 '@types/whatwg-mimetype': 3.0.2 '@types/ws': 8.18.1 entities: 6.0.1 @@ -6924,9 +6985,13 @@ snapshots: isobject@3.0.1: {} + jackspeak@4.2.3: + dependencies: + '@isaacs/cliui': 9.0.0 + jest-worker@27.5.1: dependencies: - '@types/node': 25.2.2 + '@types/node': 25.2.3 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -7003,13 +7068,13 @@ snapshots: known-css-properties@0.37.0: {} - langium@3.3.1: + langium@4.2.1: dependencies: - chevrotain: 11.0.3 - chevrotain-allstar: 0.3.1(chevrotain@11.0.3) + chevrotain: 11.1.1 + chevrotain-allstar: 0.3.1(chevrotain@11.1.1) vscode-languageserver: 9.0.1 vscode-languageserver-textdocument: 1.0.12 - vscode-uri: 3.0.8 + vscode-uri: 3.1.0 language-subtag-registry@0.3.23: {} @@ -7050,8 +7115,6 @@ snapshots: dependencies: p-locate: 5.0.0 - lodash-es@4.17.21: {} - lodash-es@4.17.23: {} lodash.camelcase@4.3.0: {} @@ -7074,7 +7137,7 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - markdown-it@14.1.0: + markdown-it@14.1.1: dependencies: argparse: 2.0.1 entities: 4.5.0 @@ -7091,9 +7154,9 @@ snapshots: js-yaml: 4.1.1 jsonc-parser: 3.3.1 jsonpointer: 5.0.1 - markdown-it: 14.1.0 + markdown-it: 14.1.1 markdownlint: 0.40.0 - minimatch: 10.1.2 + minimatch: 10.1.3 run-con: 1.3.2 smol-toml: 1.5.2 tinyglobby: 0.2.15 @@ -7141,11 +7204,11 @@ snapshots: merge2@1.4.1: {} - mermaid@11.12.2: + mermaid@11.12.3: dependencies: '@braintree/sanitize-url': 7.1.2 '@iconify/utils': 3.1.0 - '@mermaid-js/parser': 0.6.3 + '@mermaid-js/parser': 1.0.0 '@types/d3': 7.4.3 cytoscape: 3.33.1 cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.1) @@ -7347,20 +7410,24 @@ snapshots: dependencies: mime-db: 1.52.0 - mini-css-extract-plugin@2.10.0(webpack@5.105.0): + mini-css-extract-plugin@2.10.0(webpack@5.105.2): dependencies: schema-utils: 4.3.3 tapable: 2.3.0 - webpack: 5.105.0(webpack-cli@6.0.1) - - minimatch@10.1.1: - dependencies: - '@isaacs/brace-expansion': 5.0.1 + webpack: 5.105.2(webpack-cli@6.0.1) minimatch@10.1.2: dependencies: '@isaacs/brace-expansion': 5.0.1 + minimatch@10.1.3: + dependencies: + brace-expansion: 5.0.2 + + minimatch@10.2.1: + dependencies: + brace-expansion: 5.0.2 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.12 @@ -7378,11 +7445,11 @@ snapshots: pkg-types: 1.3.1 ufo: 1.6.3 - monaco-editor-webpack-plugin@7.1.1(monaco-editor@0.55.1)(webpack@5.105.0): + monaco-editor-webpack-plugin@7.1.1(monaco-editor@0.55.1)(webpack@5.105.2): dependencies: loader-utils: 2.0.4 monaco-editor: 0.55.1 - webpack: 5.105.0(webpack-cli@6.0.1) + webpack: 5.105.2(webpack-cli@6.0.1) monaco-editor@0.55.1: dependencies: @@ -7576,14 +7643,14 @@ snapshots: optionalDependencies: postcss: 8.5.6 - postcss-loader@8.2.0(postcss@8.5.6)(typescript@5.9.3)(webpack@5.105.0): + postcss-loader@8.2.1(postcss@8.5.6)(typescript@5.9.3)(webpack@5.105.2): dependencies: cosmiconfig: 9.0.0(typescript@5.9.3) jiti: 2.6.1 postcss: 8.5.6 semver: 7.7.4 optionalDependencies: - webpack: 5.105.0(webpack-cli@6.0.1) + webpack: 5.105.2(webpack-cli@6.0.1) transitivePeerDependencies: - typescript @@ -7784,9 +7851,9 @@ snapshots: schema-utils@4.3.3: 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) + ajv: 8.18.0 + ajv-formats: 2.1.1(ajv@8.18.0) + ajv-keywords: 5.1.0(ajv@8.18.0) scslre@0.3.0: dependencies: @@ -7796,8 +7863,6 @@ snapshots: semver@6.3.1: {} - semver@7.7.3: {} - semver@7.7.4: {} serialize-javascript@6.0.2: @@ -7846,7 +7911,7 @@ snapshots: '@solid-primitives/transition-group': 1.1.2(solid-js@1.9.11) solid-js: 1.9.11 - sortablejs@1.15.6: {} + sortablejs@1.15.7: {} source-list-map@2.0.1: {} @@ -7893,7 +7958,7 @@ snapshots: spdx-expression-parse: 3.0.1 spdx-ranges: 2.1.1 - spectral-cli-bundle@1.0.4: + spectral-cli-bundle@1.0.7: optionalDependencies: fsevents: 2.3.3 @@ -7941,26 +8006,27 @@ snapshots: style-search@0.1.0: {} - stylelint-config-recommended@18.0.0(stylelint@17.1.1(typescript@5.9.3)): + stylelint-config-recommended@18.0.0(stylelint@17.3.0(typescript@5.9.3)): dependencies: - stylelint: 17.1.1(typescript@5.9.3) + stylelint: 17.3.0(typescript@5.9.3) - stylelint-declaration-block-no-ignored-properties@3.0.0(stylelint@17.1.1(typescript@5.9.3)): + stylelint-declaration-block-no-ignored-properties@3.0.0(stylelint@17.3.0(typescript@5.9.3)): dependencies: - stylelint: 17.1.1(typescript@5.9.3) + stylelint: 17.3.0(typescript@5.9.3) - stylelint-declaration-strict-value@1.10.11(stylelint@17.1.1(typescript@5.9.3)): + stylelint-declaration-strict-value@1.10.11(stylelint@17.3.0(typescript@5.9.3)): dependencies: - stylelint: 17.1.1(typescript@5.9.3) + stylelint: 17.3.0(typescript@5.9.3) - stylelint-value-no-unknown-custom-properties@6.1.1(stylelint@17.1.1(typescript@5.9.3)): + stylelint-value-no-unknown-custom-properties@6.1.1(stylelint@17.3.0(typescript@5.9.3)): dependencies: postcss-value-parser: 4.2.0 resolve: 1.22.11 - stylelint: 17.1.1(typescript@5.9.3) + stylelint: 17.3.0(typescript@5.9.3) - stylelint@17.1.1(typescript@5.9.3): + stylelint@17.3.0(typescript@5.9.3): dependencies: + '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-syntax-patches-for-csstree': 1.0.27 '@csstools/css-tokenizer': 4.0.0 @@ -7970,7 +8036,7 @@ snapshots: balanced-match: 3.0.1 colord: 2.9.3 cosmiconfig: 9.0.0(typescript@5.9.3) - css-functions-list: 3.2.3 + css-functions-list: 3.3.3 css-tree: 3.1.0 debug: 4.4.3 fast-glob: 3.3.3 @@ -8064,7 +8130,7 @@ snapshots: deep-rename-keys: 0.2.1 xml-reader: 2.4.3 - swagger-ui-dist@5.31.0: + swagger-ui-dist@5.31.1: dependencies: '@scarf/scarf': 1.4.0 @@ -8081,7 +8147,7 @@ snapshots: table@6.9.0: dependencies: - ajv: 8.17.1 + ajv: 8.18.0 lodash.truncate: 4.4.2 slice-ansi: 4.0.0 string-width: 4.2.3 @@ -8116,14 +8182,14 @@ snapshots: tapable@2.3.0: {} - terser-webpack-plugin@5.3.16(webpack@5.105.0): + terser-webpack-plugin@5.3.16(webpack@5.105.2): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 serialize-javascript: 6.0.2 terser: 5.46.0 - webpack: 5.105.0(webpack-cli@6.0.1) + webpack: 5.105.2(webpack-cli@6.0.1) terser@5.46.0: dependencies: @@ -8193,12 +8259,12 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.55.0(@typescript-eslint/parser@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.55.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: @@ -8248,7 +8314,7 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 - updates@17.4.0: {} + updates@17.5.7: {} uri-js@4.4.1: dependencies: @@ -8260,11 +8326,11 @@ snapshots: vanilla-colorful@0.7.2: {} - vite-string-plugin@2.0.1(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2)): + vite-string-plugin@2.0.1(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2)): dependencies: - vite: 7.3.1(@types/node@25.2.2)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2) - vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2): + vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2): dependencies: esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) @@ -8273,17 +8339,17 @@ snapshots: rollup: 4.57.1 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 25.2.2 + '@types/node': 25.2.3 fsevents: 2.3.3 jiti: 2.6.1 stylus: 0.57.0 terser: 5.46.0 yaml: 2.8.2 - vitest@4.0.18(@types/node@25.2.2)(happy-dom@20.6.0)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2): + vitest@4.0.18(@types/node@25.2.3)(happy-dom@20.6.1)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.2.2)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2)) + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2)) '@vitest/pretty-format': 4.0.18 '@vitest/runner': 4.0.18 '@vitest/snapshot': 4.0.18 @@ -8300,11 +8366,11 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@25.2.2)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(stylus@0.57.0)(terser@5.46.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 25.2.2 - happy-dom: 20.6.0 + '@types/node': 25.2.3 + happy-dom: 20.6.1 transitivePeerDependencies: - jiti - less @@ -8333,8 +8399,6 @@ snapshots: 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.3): @@ -8348,24 +8412,24 @@ snapshots: chart.js: 4.5.1 vue: 3.5.28(typescript@5.9.3) - vue-eslint-parser@10.2.0(eslint@9.39.2(jiti@2.6.1)): + vue-eslint-parser@10.4.0(eslint@9.39.2(jiti@2.6.1)): dependencies: debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 + eslint-scope: 9.1.0 + eslint-visitor-keys: 5.0.0 + espree: 11.1.0 esquery: 1.7.0 semver: 7.7.4 transitivePeerDependencies: - supports-color - vue-loader@17.4.2(vue@3.5.28(typescript@5.9.3))(webpack@5.105.0): + vue-loader@17.4.2(vue@3.5.28(typescript@5.9.3))(webpack@5.105.2): dependencies: chalk: 4.1.2 hash-sum: 2.0.0 watchpack: 2.5.1 - webpack: 5.105.0(webpack-cli@6.0.1) + webpack: 5.105.2(webpack-cli@6.0.1) optionalDependencies: vue: 3.5.28(typescript@5.9.3) @@ -8392,12 +8456,12 @@ snapshots: webidl-conversions@3.0.1: {} - webpack-cli@6.0.1(webpack@5.105.0): + webpack-cli@6.0.1(webpack@5.105.2): dependencies: '@discoveryjs/json-ext': 0.6.3 - '@webpack-cli/configtest': 3.0.1(webpack-cli@6.0.1)(webpack@5.105.0) - '@webpack-cli/info': 3.0.1(webpack-cli@6.0.1)(webpack@5.105.0) - '@webpack-cli/serve': 3.0.1(webpack-cli@6.0.1)(webpack@5.105.0) + '@webpack-cli/configtest': 3.0.1(webpack-cli@6.0.1)(webpack@5.105.2) + '@webpack-cli/info': 3.0.1(webpack-cli@6.0.1)(webpack@5.105.2) + '@webpack-cli/serve': 3.0.1(webpack-cli@6.0.1)(webpack@5.105.2) colorette: 2.0.20 commander: 12.1.0 cross-spawn: 7.0.6 @@ -8406,7 +8470,7 @@ snapshots: import-local: 3.2.0 interpret: 3.1.1 rechoir: 0.8.0 - webpack: 5.105.0(webpack-cli@6.0.1) + webpack: 5.105.2(webpack-cli@6.0.1) webpack-merge: 6.0.1 webpack-merge@6.0.1: @@ -8420,9 +8484,9 @@ snapshots: source-list-map: 2.0.1 source-map: 0.6.1 - webpack-sources@3.3.3: {} + webpack-sources@3.3.4: {} - webpack@5.105.0(webpack-cli@6.0.1): + webpack@5.105.2(webpack-cli@6.0.1): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -8446,11 +8510,11 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.16(webpack@5.105.0) + terser-webpack-plugin: 5.3.16(webpack@5.105.2) watchpack: 2.5.1 - webpack-sources: 3.3.3 + webpack-sources: 3.3.4 optionalDependencies: - webpack-cli: 6.0.1(webpack@5.105.0) + webpack-cli: 6.0.1(webpack@5.105.2) transitivePeerDependencies: - '@swc/core' - esbuild diff --git a/public/assets/img/svg/octicon-book-locked.svg b/public/assets/img/svg/octicon-book-locked.svg new file mode 100644 index 0000000000..a72d10f96c --- /dev/null +++ b/public/assets/img/svg/octicon-book-locked.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/img/svg/octicon-comment-locked.svg b/public/assets/img/svg/octicon-comment-locked.svg new file mode 100644 index 0000000000..d8e9274715 --- /dev/null +++ b/public/assets/img/svg/octicon-comment-locked.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/img/svg/octicon-git-pull-request-locked.svg b/public/assets/img/svg/octicon-git-pull-request-locked.svg new file mode 100644 index 0000000000..d9ea190491 --- /dev/null +++ b/public/assets/img/svg/octicon-git-pull-request-locked.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/img/svg/octicon-issue-locked.svg b/public/assets/img/svg/octicon-issue-locked.svg new file mode 100644 index 0000000000..24af659c4f --- /dev/null +++ b/public/assets/img/svg/octicon-issue-locked.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index cc70cd4e06..195df464b8 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -27,6 +27,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/templates" + "code.gitea.io/gitea/modules/translation" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/common" @@ -302,7 +303,7 @@ func ViewPost(ctx *context_module.Context) { resp.State.CurrentJob.Steps = make([]*ViewJobStep, 0) // marshal to '[]' instead fo 'null' in json resp.Logs.StepsLog = make([]*ViewStepLog, 0) // marshal to '[]' instead fo 'null' in json if task != nil { - steps, logs, err := convertToViewModel(ctx, req.LogCursors, task) + steps, logs, err := convertToViewModel(ctx, ctx.Locale, req.LogCursors, task) if err != nil { ctx.ServerError("convertToViewModel", err) return @@ -314,7 +315,7 @@ func ViewPost(ctx *context_module.Context) { ctx.JSON(http.StatusOK, resp) } -func convertToViewModel(ctx *context_module.Context, cursors []LogCursor, task *actions_model.ActionTask) ([]*ViewJobStep, []*ViewStepLog, error) { +func convertToViewModel(ctx context.Context, locale translation.Locale, cursors []LogCursor, task *actions_model.ActionTask) ([]*ViewJobStep, []*ViewStepLog, error) { var viewJobs []*ViewJobStep var logs []*ViewStepLog @@ -344,7 +345,7 @@ func convertToViewModel(ctx *context_module.Context, cursors []LogCursor, task * Lines: []*ViewStepLogLine{ { Index: 1, - Message: ctx.Locale.TrString("actions.runs.expire_log_message"), + Message: locale.TrString("actions.runs.expire_log_message"), // Timestamp doesn't mean anything when the log is expired. // Set it to the task's updated time since it's probably the time when the log has expired. Timestamp: float64(task.Updated.AsTime().UnixNano()) / float64(time.Second), diff --git a/routers/web/repo/actions/view_test.go b/routers/web/repo/actions/view_test.go new file mode 100644 index 0000000000..7296ea6849 --- /dev/null +++ b/routers/web/repo/actions/view_test.go @@ -0,0 +1,47 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package actions + +import ( + "testing" + + actions_model "code.gitea.io/gitea/models/actions" + "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/translation" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestConvertToViewModel(t *testing.T) { + task := &actions_model.ActionTask{ + Status: actions_model.StatusSuccess, + Steps: []*actions_model.ActionTaskStep{ + {Name: "Run step-name", Index: 0, Status: actions_model.StatusSuccess, LogLength: 1, Started: timeutil.TimeStamp(1), Stopped: timeutil.TimeStamp(5)}, + }, + Stopped: timeutil.TimeStamp(20), + } + + viewJobSteps, _, err := convertToViewModel(t.Context(), translation.MockLocale{}, nil, task) + require.NoError(t, err) + + expectedViewJobs := []*ViewJobStep{ + { + Summary: "Set up job", + Duration: "0s", + Status: "success", + }, + { + Summary: "Run step-name", + Duration: "4s", + Status: "success", + }, + { + Summary: "Complete job", + Duration: "15s", + Status: "success", + }, + } + assert.Equal(t, expectedViewJobs, viewJobSteps) +} diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 1e2486f5f1..e034731e5c 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -7,7 +7,6 @@ import ( gocontext "context" "encoding/csv" "errors" - "fmt" "io" "net/http" "net/url" @@ -426,6 +425,36 @@ func ParseCompareInfo(ctx *context.Context) *git_service.CompareInfo { return compareInfo } +func prepareNewPullRequestTitleContent(ci *git_service.CompareInfo, commits []*git_model.SignCommitWithStatuses) (title, content string) { + title = ci.HeadRef.ShortName() + + if len(commits) > 0 { + // the "commits" are from "ShowPrettyFormatLogToList", which is ordered from newest to oldest, here take the oldest one + c := commits[len(commits)-1] + title = strings.TrimSpace(c.UserCommit.Summary()) + } + + if len(commits) == 1 { + // FIXME: GIT-COMMIT-MESSAGE-ENCODING: try to convert the encoding for commit message explicitly, ideally it should be done by a git commit struct method + c := commits[0] + _, content, _ = strings.Cut(strings.TrimSpace(c.UserCommit.CommitMessage), "\n") + content = strings.TrimSpace(content) + content = string(charset.ToUTF8([]byte(content), charset.ConvertOpts{})) + } + + var titleTrailer string + // TODO: 255 doesn't seem to be a good limit for title, just keep the old behavior + title, titleTrailer = util.EllipsisDisplayStringX(title, 255) + if titleTrailer != "" { + if content != "" { + content = titleTrailer + "\n\n" + content + } else { + content = titleTrailer + "\n" + } + } + return title, content +} + // PrepareCompareDiff renders compare diff page func PrepareCompareDiff( ctx *context.Context, @@ -539,30 +568,7 @@ func PrepareCompareDiff( ctx.Data["Commits"] = commits ctx.Data["CommitCount"] = len(commits) - title := ci.HeadRef.ShortName() - if len(commits) == 1 { - c := commits[0] - title = strings.TrimSpace(c.UserCommit.Summary()) - - body := strings.Split(strings.TrimSpace(c.UserCommit.Message()), "\n") - if len(body) > 1 { - ctx.Data["content"] = strings.Join(body[1:], "\n") - } - } - - if len(title) > 255 { - var trailer string - title, trailer = util.EllipsisDisplayStringX(title, 255) - if len(trailer) > 0 { - if ctx.Data["content"] != nil { - ctx.Data["content"] = fmt.Sprintf("%s\n\n%s", trailer, ctx.Data["content"]) - } else { - ctx.Data["content"] = trailer + "\n" - } - } - } - - ctx.Data["title"] = title + ctx.Data["title"], ctx.Data["content"] = prepareNewPullRequestTitleContent(ci, commits) ctx.Data["Username"] = ci.HeadRepo.OwnerName ctx.Data["Reponame"] = ci.HeadRepo.Name diff --git a/routers/web/repo/compare_test.go b/routers/web/repo/compare_test.go index 61472dc71e..700aba8821 100644 --- a/routers/web/repo/compare_test.go +++ b/routers/web/repo/compare_test.go @@ -4,9 +4,16 @@ package repo import ( + "strings" "testing" + "unicode/utf8" + asymkey_model "code.gitea.io/gitea/models/asymkey" + git_model "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/git" + git_service "code.gitea.io/gitea/services/git" "code.gitea.io/gitea/services/gitdiff" "github.com/stretchr/testify/assert" @@ -38,3 +45,47 @@ func TestAttachCommentsToLines(t *testing.T) { assert.Equal(t, int64(300), section.Lines[1].Comments[0].ID) assert.Equal(t, int64(301), section.Lines[1].Comments[1].ID) } + +func TestNewPullRequestTitleContent(t *testing.T) { + ci := &git_service.CompareInfo{HeadRef: "refs/heads/head-branch"} + + mockCommit := func(msg string) *git_model.SignCommitWithStatuses { + return &git_model.SignCommitWithStatuses{ + SignCommit: &asymkey_model.SignCommit{ + UserCommit: &user_model.UserCommit{ + Commit: &git.Commit{ + CommitMessage: msg, + }, + }, + }, + } + } + + title, content := prepareNewPullRequestTitleContent(ci, nil) + assert.Equal(t, "head-branch", title) + assert.Empty(t, content) + + title, content = prepareNewPullRequestTitleContent(ci, []*git_model.SignCommitWithStatuses{mockCommit("title-only")}) + assert.Equal(t, "title-only", title) + assert.Empty(t, content) + + title, content = prepareNewPullRequestTitleContent(ci, []*git_model.SignCommitWithStatuses{mockCommit("title-" + strings.Repeat("a", 255))}) + assert.Equal(t, "title-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…", title) + assert.Equal(t, "…aaaaaaaaa\n", content) + + title, content = prepareNewPullRequestTitleContent(ci, []*git_model.SignCommitWithStatuses{mockCommit("title\nbody")}) + assert.Equal(t, "title", title) + assert.Equal(t, "body", content) + + title, content = prepareNewPullRequestTitleContent(ci, []*git_model.SignCommitWithStatuses{mockCommit("a\xf0\xf0\xf0\nb\xf0\xf0\xf0")}) + assert.Equal(t, "a?", title) // FIXME: GIT-COMMIT-MESSAGE-ENCODING: "title" doesn't use the same charset converting logic as "content" + assert.Equal(t, "b"+string(utf8.RuneError)+string(utf8.RuneError), content) + + title, content = prepareNewPullRequestTitleContent(ci, []*git_model.SignCommitWithStatuses{ + // ordered from newest to oldest + mockCommit("title2\nbody2"), + mockCommit("title1\nbody1"), + }) + assert.Equal(t, "title1", title) + assert.Empty(t, content) +} diff --git a/routers/web/user/heatmap.go b/routers/web/user/heatmap.go new file mode 100644 index 0000000000..e81739e5b8 --- /dev/null +++ b/routers/web/user/heatmap.go @@ -0,0 +1,66 @@ +// Copyright 2026 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package user + +import ( + "net/http" + "net/url" + + activities_model "code.gitea.io/gitea/models/activities" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/context" +) + +func prepareHeatmapURL(ctx *context.Context) { + ctx.Data["EnableHeatmap"] = setting.Service.EnableUserHeatmap + if !setting.Service.EnableUserHeatmap { + return + } + + if ctx.Org.Organization == nil { + // for individual user + ctx.Data["HeatmapURL"] = ctx.Doer.HomeLink() + "/-/heatmap" + return + } + + // for org or team + heatmapURL := ctx.Org.Organization.OrganisationLink() + "/dashboard/-/heatmap" + if ctx.Org.Team != nil { + heatmapURL += "/" + url.PathEscape(ctx.Org.Team.LowerName) + } + ctx.Data["HeatmapURL"] = heatmapURL +} + +func writeHeatmapJSON(ctx *context.Context, hdata []*activities_model.UserHeatmapData) { + data := make([][2]int64, len(hdata)) + var total int64 + for i, v := range hdata { + data[i] = [2]int64{int64(v.Timestamp), v.Contributions} + total += v.Contributions + } + ctx.JSON(http.StatusOK, map[string]any{ + "heatmapData": data, + "totalContributions": total, + }) +} + +// DashboardHeatmap returns heatmap data as JSON, for the individual user, organization or team dashboard. +func DashboardHeatmap(ctx *context.Context) { + if !setting.Service.EnableUserHeatmap { + ctx.NotFound(nil) + return + } + var data []*activities_model.UserHeatmapData + var err error + if ctx.Org.Organization == nil { + data, err = activities_model.GetUserHeatmapDataByUser(ctx, ctx.ContextUser, ctx.Doer) + } else { + data, err = activities_model.GetUserHeatmapDataByOrgTeam(ctx, ctx.Org.Organization, ctx.Org.Team, ctx.Doer) + } + if err != nil { + ctx.ServerError("GetUserHeatmapData", err) + return + } + writeHeatmapJSON(ctx, data) +} diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 9e77c51d12..afdba9a75f 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -54,8 +54,8 @@ const ( tplProfile templates.TplName = "user/profile" ) -// getDashboardContextUser finds out which context user dashboard is being viewed as . -func getDashboardContextUser(ctx *context.Context) *user_model.User { +// prepareDashboardContextUserOrgTeams finds out which context user dashboard is being viewed as . +func prepareDashboardContextUserOrgTeams(ctx *context.Context) *user_model.User { ctxUser := ctx.Doer orgName := ctx.PathParam("org") if len(orgName) > 0 { @@ -76,7 +76,7 @@ func getDashboardContextUser(ctx *context.Context) *user_model.User { // Dashboard render the dashboard page func Dashboard(ctx *context.Context) { - ctxUser := getDashboardContextUser(ctx) + ctxUser := prepareDashboardContextUserOrgTeams(ctx) if ctx.Written() { return } @@ -109,15 +109,7 @@ func Dashboard(ctx *context.Context) { "uid": uid, } - if setting.Service.EnableUserHeatmap { - data, err := activities_model.GetUserHeatmapDataByUserTeam(ctx, ctxUser, ctx.Org.Team, ctx.Doer) - if err != nil { - ctx.ServerError("GetUserHeatmapDataByUserTeam", err) - return - } - ctx.Data["HeatmapData"] = data - ctx.Data["HeatmapTotalContributions"] = activities_model.GetTotalContributionsInHeatmap(data) - } + prepareHeatmapURL(ctx) feeds, count, err := feed_service.GetFeedsForDashboard(ctx, activities_model.GetFeedsOptions{ RequestedUser: ctxUser, @@ -156,7 +148,7 @@ func Milestones(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("milestones") ctx.Data["PageIsMilestonesDashboard"] = true - ctxUser := getDashboardContextUser(ctx) + ctxUser := prepareDashboardContextUserOrgTeams(ctx) if ctx.Written() { return } @@ -371,7 +363,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { // Return with NotFound or ServerError if unsuccessful. // ---------------------------------------------------- - ctxUser := getDashboardContextUser(ctx) + ctxUser := prepareDashboardContextUserOrgTeams(ctx) if ctx.Written() { return } diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go index d7052914b6..f580055030 100644 --- a/routers/web/user/profile.go +++ b/routers/web/user/profile.go @@ -103,6 +103,7 @@ func prepareUserProfileTabData(ctx *context.Context, profileDbRepo *repo_model.R repos []*repo_model.Repository count int64 total int + curRows int orderBy db.SearchOrderBy ) @@ -161,21 +162,15 @@ func prepareUserProfileTabData(ctx *context.Context, profileDbRepo *repo_model.R ctx.Data["Cards"] = following total = int(numFollowing) case "activity": - // prepare heatmap data - if setting.Service.EnableUserHeatmap { - data, err := activities_model.GetUserHeatmapDataByUser(ctx, ctx.ContextUser, ctx.Doer) - if err != nil { - ctx.ServerError("GetUserHeatmapDataByUser", err) - return - } - ctx.Data["HeatmapData"] = data - ctx.Data["HeatmapTotalContributions"] = activities_model.GetTotalContributionsInHeatmap(data) + if setting.Service.EnableUserHeatmap && activities_model.ActivityReadable(ctx.ContextUser, ctx.Doer) { + ctx.Data["EnableHeatmap"] = true + ctx.Data["HeatmapURL"] = ctx.ContextUser.HomeLink() + "/-/heatmap" } date := ctx.FormString("date") pagingNum = setting.UI.FeedPagingNum showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID) - items, count, err := feed_service.GetFeeds(ctx, activities_model.GetFeedsOptions{ + items, feedCount, err := feed_service.GetFeedsForDashboard(ctx, activities_model.GetFeedsOptions{ RequestedUser: ctx.ContextUser, Actor: ctx.Doer, IncludePrivate: showPrivate, @@ -193,8 +188,8 @@ func prepareUserProfileTabData(ctx *context.Context, profileDbRepo *repo_model.R } ctx.Data["Feeds"] = items ctx.Data["Date"] = date - - total = int(count) + curRows = len(items) + total = feedCount case "stars": ctx.Data["PageIsProfileStarList"] = true ctx.Data["ShowRepoOwnerOnList"] = true @@ -316,6 +311,9 @@ func prepareUserProfileTabData(ctx *context.Context, profileDbRepo *repo_model.R } pager := context.NewPagination(total, pagingNum, page, 5) + if tab == "activity" { + pager.WithCurRows(curRows) + } pager.AddParamFromRequest(ctx.Req) ctx.Data["Page"] = pager } diff --git a/routers/web/web.go b/routers/web/web.go index 22b78793ef..9e6354e138 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -888,6 +888,8 @@ func registerWebRoutes(m *web.Router) { m.Group("/{org}", func() { m.Get("/dashboard", user.Dashboard) m.Get("/dashboard/{team}", user.Dashboard) + m.Get("/dashboard/-/heatmap", user.DashboardHeatmap) + m.Get("/dashboard/-/heatmap/{team}", user.DashboardHeatmap) m.Get("/issues", user.Issues) m.Get("/issues/{team}", user.Issues) m.Get("/pulls", user.Pulls) @@ -1024,6 +1026,7 @@ func registerWebRoutes(m *web.Router) { } m.Get("/repositories", org.Repositories) + m.Get("/heatmap", user.DashboardHeatmap) m.Group("/projects", func() { m.Group("", func() { diff --git a/services/webtheme/webtheme.go b/services/webtheme/webtheme.go index 8091c25713..a0beec2902 100644 --- a/services/webtheme/webtheme.go +++ b/services/webtheme/webtheme.go @@ -16,10 +16,14 @@ import ( "code.gitea.io/gitea/modules/util" ) +type themeCollection struct { + themeList []*ThemeMetaInfo + themeMap map[string]*ThemeMetaInfo +} + var ( - availableThemes []*ThemeMetaInfo - availableThemeMap map[string]*ThemeMetaInfo - themeOnce sync.Once + themeMu sync.RWMutex + availableThemes *themeCollection ) const ( @@ -129,23 +133,13 @@ func parseThemeMetaInfo(fileName, cssContent string) *ThemeMetaInfo { return themeInfo } -func initThemes() { - availableThemes = nil - defer func() { - availableThemeMap = map[string]*ThemeMetaInfo{} - for _, theme := range availableThemes { - availableThemeMap[theme.InternalName] = theme - } - if availableThemeMap[setting.UI.DefaultTheme] == nil { - setting.LogStartupProblem(1, log.ERROR, "Default theme %q is not available, please correct the '[ui].DEFAULT_THEME' setting in the config file", setting.UI.DefaultTheme) - } - }() +func loadThemesFromAssets() (themeList []*ThemeMetaInfo, themeMap map[string]*ThemeMetaInfo) { cssFiles, err := public.AssetFS().ListFiles("assets/css") if err != nil { log.Error("Failed to list themes: %v", err) - availableThemes = []*ThemeMetaInfo{defaultThemeMetaInfoByInternalName(setting.UI.DefaultTheme)} - return + return nil, nil } + var foundThemes []*ThemeMetaInfo for _, fileName := range cssFiles { if strings.HasPrefix(fileName, fileNamePrefix) && strings.HasSuffix(fileName, fileNameSuffix) { @@ -157,39 +151,84 @@ func initThemes() { foundThemes = append(foundThemes, parseThemeMetaInfo(fileName, util.UnsafeBytesToString(content))) } } + + themeList = foundThemes if len(setting.UI.Themes) > 0 { + themeList = nil // only allow the themes specified in the setting allowedThemes := container.SetOf(setting.UI.Themes...) for _, theme := range foundThemes { if allowedThemes.Contains(theme.InternalName) { - availableThemes = append(availableThemes, theme) + themeList = append(themeList, theme) } } - } else { - availableThemes = foundThemes } - sort.Slice(availableThemes, func(i, j int) bool { - if availableThemes[i].InternalName == setting.UI.DefaultTheme { + + sort.Slice(themeList, func(i, j int) bool { + if themeList[i].InternalName == setting.UI.DefaultTheme { return true } - if availableThemes[i].ColorblindType != availableThemes[j].ColorblindType { - return availableThemes[i].ColorblindType < availableThemes[j].ColorblindType + if themeList[i].ColorblindType != themeList[j].ColorblindType { + return themeList[i].ColorblindType < themeList[j].ColorblindType } - return availableThemes[i].DisplayName < availableThemes[j].DisplayName + return themeList[i].DisplayName < themeList[j].DisplayName }) - if len(availableThemes) == 0 { - setting.LogStartupProblem(1, log.ERROR, "No theme candidate in asset files, but Gitea requires there should be at least one usable theme") - availableThemes = []*ThemeMetaInfo{defaultThemeMetaInfoByInternalName(setting.UI.DefaultTheme)} + + themeMap = map[string]*ThemeMetaInfo{} + for _, theme := range themeList { + themeMap[theme.InternalName] = theme } + return themeList, themeMap +} + +func getAvailableThemes() (themeList []*ThemeMetaInfo, themeMap map[string]*ThemeMetaInfo) { + themeMu.RLock() + if availableThemes != nil { + themeList, themeMap = availableThemes.themeList, availableThemes.themeMap + } + themeMu.RUnlock() + if len(themeList) != 0 { + return themeList, themeMap + } + + themeMu.Lock() + defer themeMu.Unlock() + // no need to double-check "availableThemes.themeList" since the loading isn't really slow, to keep code simple + themeList, themeMap = loadThemesFromAssets() + hasAvailableThemes := len(themeList) > 0 + if !hasAvailableThemes { + defaultTheme := defaultThemeMetaInfoByInternalName(setting.UI.DefaultTheme) + themeList = []*ThemeMetaInfo{defaultTheme} + themeMap = map[string]*ThemeMetaInfo{setting.UI.DefaultTheme: defaultTheme} + } + + if setting.IsProd { + if !hasAvailableThemes { + setting.LogStartupProblem(1, log.ERROR, "No theme candidate in asset files, but Gitea requires there should be at least one usable theme") + } + if themeMap[setting.UI.DefaultTheme] == nil { + setting.LogStartupProblem(1, log.ERROR, "Default theme %q is not available, please correct the '[ui].DEFAULT_THEME' setting in the config file", setting.UI.DefaultTheme) + } + availableThemes = &themeCollection{themeList, themeMap} + return themeList, themeMap + } + + // In dev mode, only store the loaded themes if the list is not empty, in case the frontend is still being built. + // TBH, there still could be a data-race that the themes are only partially built then the list is incomplete for first time loading. + // Such edge case can be handled by checking whether the loaded themes are the same in a period or there is a flag file, but it is an over-kill, so, no. + if hasAvailableThemes { + availableThemes = &themeCollection{themeList, themeMap} + } + return themeList, themeMap } func GetAvailableThemes() []*ThemeMetaInfo { - themeOnce.Do(initThemes) - return availableThemes + themes, _ := getAvailableThemes() + return themes } func GetThemeMetaInfo(internalName string) *ThemeMetaInfo { - themeOnce.Do(initThemes) - return availableThemeMap[internalName] + _, themeMap := getAvailableThemes() + return themeMap[internalName] } // GuaranteeGetThemeMetaInfo guarantees to return a non-nil ThemeMetaInfo, diff --git a/templates/repo/issue/new_form.tmpl b/templates/repo/issue/new_form.tmpl index e4c8008c19..5475224750 100644 --- a/templates/repo/issue/new_form.tmpl +++ b/templates/repo/issue/new_form.tmpl @@ -6,7 +6,7 @@
{{ctx.AvatarUtils.Avatar .SignedUser 40}}
- diff --git a/templates/user/heatmap.tmpl b/templates/user/heatmap.tmpl index 6186edd4dd..22368e78c1 100644 --- a/templates/user/heatmap.tmpl +++ b/templates/user/heatmap.tmpl @@ -1,8 +1,8 @@ -{{if .HeatmapData}} +{{if .EnableHeatmap}}
{ @@ -88,7 +89,7 @@ function onShowPanelClick(el: HTMLElement, e: MouseEvent) { const elems = el.classList.contains('toggle') ? toggleElem(sel) : showElem(sel); for (const elem of elems) { if (isElemVisible(elem as HTMLElement)) { - elem.querySelector('[autofocus]')?.focus(); + applyAutoFocus(elem); } } } diff --git a/web_src/js/features/common-page.ts b/web_src/js/features/common-page.ts index 5ecc271c0b..36af087089 100644 --- a/web_src/js/features/common-page.ts +++ b/web_src/js/features/common-page.ts @@ -116,12 +116,30 @@ function attachInputDirAuto(el: Partial) } } +function autoFocusEnd(el: HTMLInputElement | HTMLTextAreaElement) { + el.focus(); + el.setSelectionRange(el.value.length, el.value.length); +} + +export function applyAutoFocus(container: Element) { + // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/autofocus + // "autofocus" behavior is defined by the standard: when a container (e.g.: dialog) becomes visible, focus the element with "autofocus" attribute + // Fomantic UI already supports it for its modal dialog, we need to cover more cases (e.g.: ".show-panel" button) + // Here is just a simple support, we don't expect more than one element that need "autofocus" appearing in the same container + container.querySelector('[autofocus]')?.focus(); + // Also, apply our autoFocusEnd behavior + // TODO: GLOBAL-INIT-MULTIPLE-FUNCTIONS: use "~=" operator in case we would extend the "data-global-init" to support more functions in the future. + const el = container.querySelector('[data-global-init~="autoFocusEnd"]'); + if (el) autoFocusEnd(el); +} + export function initGlobalInput() { registerGlobalSelectorFunc('input, textarea', attachInputDirAuto); - registerGlobalInitFunc('initInputAutoFocusEnd', (el: HTMLInputElement) => { - el.focus(); // expects only one such element on one page. If there are many, then the last one gets the focus. - el.setSelectionRange(el.value.length, el.value.length); - }); + + // autoFocusEnd is used for autofocus an input/textarea and move the cursor to the end of the text. + // It is useful for "New Issue"/"New PR" pages when the title is pre-filled with prefix text (e.g.: from template or commit message) + // The native "autofocus" isn't used because there is a delay between "focused (DOM rendering)" and "move cursor to end (our JS)", it causes flickers. + registerGlobalInitFunc('autoFocusEnd', autoFocusEnd); } /** diff --git a/web_src/js/features/heatmap.ts b/web_src/js/features/heatmap.ts index 0c13d1c98a..5e26bcc685 100644 --- a/web_src/js/features/heatmap.ts +++ b/web_src/js/features/heatmap.ts @@ -1,14 +1,25 @@ import {createApp} from 'vue'; import ActivityHeatmap from '../components/ActivityHeatmap.vue'; import {translateMonth, translateDay} from '../utils.ts'; +import {GET} from '../modules/fetch.ts'; -export function initHeatmap() { - const el = document.querySelector('#user-heatmap'); +type HeatmapResponse = { + heatmapData: Array<[number, number]>; // [[1617235200, 2]] = [unix timestamp, count] + totalContributions: number; +}; + +export async function initHeatmap() { + const el = document.querySelector('#user-heatmap'); if (!el) return; try { + const url = el.getAttribute('data-heatmap-url')!; + const resp = await GET(url); + if (!resp.ok) throw new Error(`Failed to load heatmap data: ${resp.status} ${resp.statusText}`); + const {heatmapData, totalContributions} = await resp.json() as HeatmapResponse; + const heatmap: Record = {}; - for (const {contributions, timestamp} of JSON.parse(el.getAttribute('data-heatmap-data')!)) { + for (const [timestamp, contributions] of heatmapData) { // Convert to user timezone and sum contributions by date const dateStr = new Date(timestamp * 1000).toDateString(); heatmap[dateStr] = (heatmap[dateStr] || 0) + contributions; @@ -18,6 +29,9 @@ export function initHeatmap() { return {date: new Date(v), count: heatmap[v]}; }); + const totalFormatted = totalContributions.toLocaleString(); + const textTotalContributions = el.getAttribute('data-locale-total-contributions')!.replace('%s', totalFormatted); + // last heatmap tooltip localization attempt https://github.com/go-gitea/gitea/pull/24131/commits/a83761cbbae3c2e3b4bced71e680f44432073ac8 const locale = { heatMapLocale: { @@ -28,7 +42,7 @@ export function initHeatmap() { less: el.getAttribute('data-locale-less'), }, tooltipUnit: 'contributions', - textTotalContributions: el.getAttribute('data-locale-total-contributions'), + textTotalContributions, noDataText: el.getAttribute('data-locale-no-contributions'), }; diff --git a/web_src/js/modules/observer.ts b/web_src/js/modules/observer.ts index 1bbf304b27..1dbad1aed1 100644 --- a/web_src/js/modules/observer.ts +++ b/web_src/js/modules/observer.ts @@ -42,6 +42,7 @@ export function registerGlobalInitFunc(name: string, hand } function callGlobalInitFunc(el: HTMLElement) { + // TODO: GLOBAL-INIT-MULTIPLE-FUNCTIONS: maybe in the future we need to extend it to support multiple functions, for example: `data-global-init="func1 func2 func3"` const initFunc = el.getAttribute('data-global-init')!; const func = globalInitFuncs[initFunc]; if (!func) throw new Error(`Global init function "${initFunc}" not found`);