diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index b4f877b11..f0cb12459 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -41,10 +41,10 @@ jobs: - uses: actions/checkout@v6 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: Login to GitHub Container Registry - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} @@ -52,7 +52,7 @@ jobs: - name: Docker metadata id: dockerMetadata - uses: docker/metadata-action@v5 + uses: docker/metadata-action@v6 with: images: ${{ env.DOCKER_IMAGE_NAME }} tags: | @@ -60,7 +60,7 @@ jobs: type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }} - name: Build and push image - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: ./backend tags: ${{ steps.dockerMetadata.outputs.tags }} diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index f7c7eb19b..29cdd0c00 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -24,7 +24,7 @@ jobs: - name: Docker metadata id: dockerMetadata - uses: docker/metadata-action@v5 + uses: docker/metadata-action@v6 with: images: "dummyImageName" tags: | diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml index 6ba0d4a9b..276b649aa 100644 --- a/.github/workflows/website.yml +++ b/.github/workflows/website.yml @@ -57,10 +57,10 @@ jobs: - uses: actions/checkout@v6 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: Login to GitHub Container Registry - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} @@ -68,7 +68,7 @@ jobs: - name: Docker metadata id: dockerMetadata - uses: docker/metadata-action@v5 + uses: docker/metadata-action@v6 with: images: ${{ env.DOCKER_IMAGE_NAME }} tags: | @@ -76,7 +76,7 @@ jobs: type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }} - name: Build and push image - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: . file: Dockerfile_website diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index 669a3747e..b3739d878 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -1,11 +1,11 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat plugins { - kotlin("jvm") version "2.3.10" - kotlin("plugin.spring") version "2.3.10" + kotlin("jvm") version "2.3.20" + kotlin("plugin.spring") version "2.3.20" id("org.springframework.boot") version "3.4.0" id("io.spring.dependency-management") version "1.1.7" - id("org.jlleitschuh.gradle.ktlint") version "14.0.1" + id("org.jlleitschuh.gradle.ktlint") version "14.2.0" id("org.springdoc.openapi-gradle-plugin") version "1.9.0" } @@ -29,7 +29,7 @@ dependencies { implementation("org.jetbrains.kotlin:kotlin-stdlib") implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0") implementation("org.flywaydb:flyway-database-postgresql:11.0.0") - implementation("org.postgresql:postgresql:42.7.9") + implementation("org.postgresql:postgresql:42.7.10") implementation("org.jetbrains.exposed:exposed-spring-boot-starter:0.56.0") implementation("org.jetbrains.exposed:exposed-json:0.56.0") implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.7.1-0.6.x-compat") diff --git a/backend/gradle/wrapper/gradle-wrapper.jar b/backend/gradle/wrapper/gradle-wrapper.jar index 1b33c55ba..d997cfc60 100644 Binary files a/backend/gradle/wrapper/gradle-wrapper.jar and b/backend/gradle/wrapper/gradle-wrapper.jar differ diff --git a/backend/gradle/wrapper/gradle-wrapper.properties b/backend/gradle/wrapper/gradle-wrapper.properties index 37f78a6af..dbc3ce4a0 100644 --- a/backend/gradle/wrapper/gradle-wrapper.properties +++ b/backend/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/backend/gradlew b/backend/gradlew index 23d15a936..0262dcbd5 100755 --- a/backend/gradlew +++ b/backend/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -57,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/b631911858264c0b6e4d6603d677ff5218766cee/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -114,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -172,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" diff --git a/backend/gradlew.bat b/backend/gradlew.bat index 5eed7ee84..e509b2dd8 100644 --- a/backend/gradlew.bat +++ b/backend/gradlew.bat @@ -70,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/website/package-lock.json b/website/package-lock.json index f99755b13..50dc0d460 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -11,14 +11,14 @@ "dependencies": { "@astrojs/node": "^9.5.3", "@auth/core": "^0.37.4", - "@genspectrum/dashboard-components": "^1.15.0", + "@genspectrum/dashboard-components": "^1.16.0", "@tanstack/react-query": "^5.90.21", "astro": "^5.17.2", "auth-astro": "^4.2.0", - "axios": "^1.13.5", + "axios": "^1.13.6", "cookie": "^1.1.1", - "dayjs": "^1.11.19", - "katex": "^0.16.28", + "dayjs": "^1.11.20", + "katex": "^0.16.38", "patch-package": "^8.0.1", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -30,14 +30,14 @@ "yaml": "^2.8.2" }, "devDependencies": { - "@astrojs/check": "^0.9.6", + "@astrojs/check": "^0.9.8", "@astrojs/react": "^4.4.2", "@eslint/js": "^9.39.2", "@iconify-json/mdi": "^1.2.3", "@iconify-json/mdi-light": "^1.2.2", - "@iconify/tailwind4": "^1.2.1", + "@iconify/tailwind4": "^1.2.3", "@playwright/test": "^1.58.2", - "@tailwindcss/vite": "^4.1.18", + "@tailwindcss/vite": "^4.2.1", "@tanstack/eslint-plugin-query": "^5.91.4", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", @@ -48,25 +48,25 @@ "@types/react-dom": "^18.3.1", "@types/react-katex": "^3.0.4", "@types/topojson-specification": "^1.0.5", - "@typescript-eslint/eslint-plugin": "^8.56.0", - "@typescript-eslint/parser": "^8.56.0", + "@typescript-eslint/eslint-plugin": "^8.57.1", + "@typescript-eslint/parser": "^8.57.1", "@vitest/browser": "^3.2.4", "astro-eslint-parser": "^1.3.0", - "daisyui": "^5.5.18", + "daisyui": "^5.5.19", "dotenv": "^16.5.0", "eslint": "^9.39.2", "eslint-plugin-astro": "^1.6.0", "eslint-plugin-import": "^2.32.0", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^5.2.0", - "msw": "^2.12.10", + "msw": "^2.12.11", "playwright": "^1.55.0", "prettier": "^3.8.1", "prettier-plugin-astro": "^0.14.1", "prettier-plugin-tailwindcss": "^0.7.2", "tailwindcss": "^4.0.9", "typescript": "^5.9.3", - "typescript-eslint": "^8.56.0", + "typescript-eslint": "^8.57.1", "vitest": "^3.2.4", "vitest-browser-react": "^1.0.1", "zod": "^3.25.74" @@ -94,9 +94,9 @@ } }, "node_modules/@antfu/install-pkg/node_modules/tinyexec": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", - "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz", + "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==", "dev": true, "license": "MIT", "engines": { @@ -104,14 +104,14 @@ } }, "node_modules/@astrojs/check": { - "version": "0.9.6", - "resolved": "https://registry.npmjs.org/@astrojs/check/-/check-0.9.6.tgz", - "integrity": "sha512-jlaEu5SxvSgmfGIFfNgcn5/f+29H61NJzEMfAZ82Xopr4XBchXB1GVlcJsE+elUlsYSbXlptZLX+JMG3b/wZEA==", + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/@astrojs/check/-/check-0.9.8.tgz", + "integrity": "sha512-LDng8446QLS5ToKjRHd3bgUdirvemVVExV7nRyJfW2wV36xuv7vDxwy5NWN9zqeSEDgg0Tv84sP+T3yEq+Zlkw==", "dev": true, "license": "MIT", "dependencies": { - "@astrojs/language-server": "^2.16.1", - "chokidar": "^4.0.1", + "@astrojs/language-server": "^2.16.5", + "chokidar": "^4.0.3", "kleur": "^4.1.5", "yargs": "^17.7.2" }, @@ -123,9 +123,9 @@ } }, "node_modules/@astrojs/compiler": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.0.tgz", - "integrity": "sha512-mqVORhUJViA28fwHYaWmsXSzLO9osbdZ5ImUfxBarqsYdMlPbqAqGJCxsNzvppp1BEzc1mJNjOVvQqeDN8Vspw==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.1.tgz", + "integrity": "sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg==", "license": "MIT" }, "node_modules/@astrojs/internal-helpers": { @@ -135,29 +135,29 @@ "license": "MIT" }, "node_modules/@astrojs/language-server": { - "version": "2.16.2", - "resolved": "https://registry.npmjs.org/@astrojs/language-server/-/language-server-2.16.2.tgz", - "integrity": "sha512-J3hVx/mFi3FwEzKf8ExYXQNERogD6RXswtbU+TyrxoXRBiQoBO5ooo7/lRWJ+rlUKUd7+rziMPI9jYB7TRlh0w==", + "version": "2.16.5", + "resolved": "https://registry.npmjs.org/@astrojs/language-server/-/language-server-2.16.5.tgz", + "integrity": "sha512-MEQvrbuiFDEo+LCO4vvYuTr3eZ4IluZ/n4BbUv77AWAJNEj/n0j7VqTvdL1rGloNTIKZTUd46p5RwYKsxQGY8w==", "dev": true, "license": "MIT", "dependencies": { - "@astrojs/compiler": "^2.10.3", - "@astrojs/yaml2ts": "^0.2.2", - "@jridgewell/sourcemap-codec": "^1.4.15", - "@volar/kit": "~2.4.23", - "@volar/language-core": "~2.4.23", - "@volar/language-server": "~2.4.23", - "@volar/language-service": "~2.4.23", - "fast-glob": "^3.2.12", + "@astrojs/compiler": "^2.13.1", + "@astrojs/yaml2ts": "^0.2.3", + "@jridgewell/sourcemap-codec": "^1.5.5", + "@volar/kit": "~2.4.28", + "@volar/language-core": "~2.4.28", + "@volar/language-server": "~2.4.28", + "@volar/language-service": "~2.4.28", "muggle-string": "^0.4.1", - "volar-service-css": "0.0.67", - "volar-service-emmet": "0.0.67", - "volar-service-html": "0.0.67", - "volar-service-prettier": "0.0.67", - "volar-service-typescript": "0.0.67", - "volar-service-typescript-twoslash-queries": "0.0.67", - "volar-service-yaml": "0.0.67", - "vscode-html-languageservice": "^5.5.2", + "tinyglobby": "^0.2.15", + "volar-service-css": "0.0.70", + "volar-service-emmet": "0.0.70", + "volar-service-html": "0.0.70", + "volar-service-prettier": "0.0.70", + "volar-service-typescript": "0.0.70", + "volar-service-typescript-twoslash-queries": "0.0.70", + "volar-service-yaml": "0.0.70", + "vscode-html-languageservice": "^5.6.2", "vscode-uri": "^3.1.0" }, "bin": { @@ -271,13 +271,13 @@ } }, "node_modules/@astrojs/yaml2ts": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@astrojs/yaml2ts/-/yaml2ts-0.2.2.tgz", - "integrity": "sha512-GOfvSr5Nqy2z5XiwqTouBBpy5FyI6DEe+/g/Mk5am9SjILN1S5fOEvYK0GuWHg98yS/dobP4m8qyqw/URW35fQ==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@astrojs/yaml2ts/-/yaml2ts-0.2.3.tgz", + "integrity": "sha512-PJzRmgQzUxI2uwpdX2lXSHtP4G8ocp24/t+bZyf5Fy0SZLSF9f9KXZoMlFM/XCGue+B0nH/2IZ7FpBYQATBsCg==", "dev": true, "license": "MIT", "dependencies": { - "yaml": "^2.5.0" + "yaml": "^2.8.2" } }, "node_modules/@auth/core": { @@ -641,9 +641,9 @@ } }, "node_modules/@cyberalien/svg-utils": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@cyberalien/svg-utils/-/svg-utils-1.0.11.tgz", - "integrity": "sha512-qEE9mnyI+avfGT3emKuRs3ucYkITeaV0Xi7VlYN41f+uGnZBecQP3jwz/AF437H9J4Q7qPClHKm4NiTYpNE6hA==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@cyberalien/svg-utils/-/svg-utils-1.2.6.tgz", + "integrity": "sha512-x24BZpZ//OQZebYowWV8muilk9p4DJBGDYCVxeFiX+T/68VLKFJNBqSrJZ/XBNgmcQz3RCf4GjWj0DSt2NfM6w==", "dev": true, "license": "MIT", "dependencies": { @@ -1367,9 +1367,9 @@ "license": "MIT" }, "node_modules/@genspectrum/dashboard-components": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@genspectrum/dashboard-components/-/dashboard-components-1.15.0.tgz", - "integrity": "sha512-CpPC1ZIY9MtjxC1Zzy+afafqJXb4pavXr52tWfcSxzTER74CW8C8YRlIvDoYHrWzFuP1d6oeaSZTzSgQpsa0bw==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@genspectrum/dashboard-components/-/dashboard-components-1.16.0.tgz", + "integrity": "sha512-LPT1x1VsDfquEWx145dp95psdhkquoorYqZNXX8b+BVAiLSFudaP87QckAXAg2283cv8BLckh3n65UcmG3Pu3Q==", "license": "AGPL-3.0-only", "dependencies": { "@floating-ui/dom": "^1.6.5", @@ -1480,13 +1480,13 @@ } }, "node_modules/@iconify/tailwind4": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@iconify/tailwind4/-/tailwind4-1.2.1.tgz", - "integrity": "sha512-Hd7k8y7uzT3hk8ltw0jGku0r0wA8sc3d2iMvVTYv/9tMxBb+frZtWZGD9hDMU3EYuE+lMn58wi2lS8R2ZbwFcQ==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@iconify/tailwind4/-/tailwind4-1.2.3.tgz", + "integrity": "sha512-z8SKiMHRASJKF/IY//87MF88lcB7ulxh8vlhQXXLWsBkNtOh6ese9R41MyGpQeqXdRvQVt+/fX2glQtHFjQ+MA==", "dev": true, "license": "MIT", "dependencies": { - "@iconify/tools": "^5.0.2", + "@iconify/tools": "^5.0.5", "@iconify/types": "^2.0.0", "@iconify/utils": "^3.1.0" }, @@ -1498,19 +1498,19 @@ } }, "node_modules/@iconify/tools": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@iconify/tools/-/tools-5.0.2.tgz", - "integrity": "sha512-esoFiH0LYpiqqVAO+RTenh6qqGKf0V8T0T6IG7dFLCw26cjcYGG34UMHjkbuq+MMl23U39FtkzhWZsCDDtOhew==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@iconify/tools/-/tools-5.0.5.tgz", + "integrity": "sha512-JE3uqne+l89kggZYKIukaYDIae4lHKMNVDg7Oc+L+8rPwiMcfD5C56YLWyynyH/ib6I9xDFH1aamdfoL+m7OFA==", "dev": true, "license": "MIT", "dependencies": { - "@cyberalien/svg-utils": "^1.0.11", + "@cyberalien/svg-utils": "^1.2.4", "@iconify/types": "^2.0.0", "@iconify/utils": "^3.1.0", "fflate": "^0.8.2", - "modern-tar": "^0.7.3", + "modern-tar": "^0.7.5", "pathe": "^2.0.3", - "svgo": "^4.0.0" + "svgo": "^4.0.1" } }, "node_modules/@iconify/types": { @@ -2711,49 +2711,49 @@ } }, "node_modules/@tailwindcss/node": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz", - "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", + "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/remapping": "^2.3.4", - "enhanced-resolve": "^5.18.3", + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", - "lightningcss": "1.30.2", + "lightningcss": "1.31.1", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.1.18" + "tailwindcss": "4.2.1" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz", - "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz", + "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", "dev": true, "license": "MIT", "engines": { - "node": ">= 10" + "node": ">= 20" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.18", - "@tailwindcss/oxide-darwin-arm64": "4.1.18", - "@tailwindcss/oxide-darwin-x64": "4.1.18", - "@tailwindcss/oxide-freebsd-x64": "4.1.18", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", - "@tailwindcss/oxide-linux-x64-musl": "4.1.18", - "@tailwindcss/oxide-wasm32-wasi": "4.1.18", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" + "@tailwindcss/oxide-android-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-x64": "4.2.1", + "@tailwindcss/oxide-freebsd-x64": "4.2.1", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-x64-musl": "4.2.1", + "@tailwindcss/oxide-wasm32-wasi": "4.2.1", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz", - "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz", + "integrity": "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==", "cpu": [ "arm64" ], @@ -2764,13 +2764,13 @@ "android" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz", - "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", + "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", "cpu": [ "arm64" ], @@ -2781,13 +2781,13 @@ "darwin" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz", - "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz", + "integrity": "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==", "cpu": [ "x64" ], @@ -2798,13 +2798,13 @@ "darwin" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz", - "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz", + "integrity": "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==", "cpu": [ "x64" ], @@ -2815,13 +2815,13 @@ "freebsd" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz", - "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz", + "integrity": "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==", "cpu": [ "arm" ], @@ -2832,13 +2832,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz", - "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz", + "integrity": "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==", "cpu": [ "arm64" ], @@ -2849,13 +2849,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz", - "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz", + "integrity": "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==", "cpu": [ "arm64" ], @@ -2866,13 +2866,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz", - "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz", + "integrity": "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==", "cpu": [ "x64" ], @@ -2883,13 +2883,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz", - "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz", + "integrity": "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==", "cpu": [ "x64" ], @@ -2900,13 +2900,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz", - "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz", + "integrity": "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -2922,19 +2922,19 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1", + "@emnapi/core": "^1.8.1", + "@emnapi/runtime": "^1.8.1", "@emnapi/wasi-threads": "^1.1.0", - "@napi-rs/wasm-runtime": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.1", "@tybys/wasm-util": "^0.10.1", - "tslib": "^2.4.0" + "tslib": "^2.8.1" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.7.1", + "version": "1.8.1", "dev": true, "inBundle": true, "license": "MIT", @@ -2945,7 +2945,7 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.7.1", + "version": "1.8.1", "dev": true, "inBundle": true, "license": "MIT", @@ -2965,7 +2965,7 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.0", + "version": "1.1.1", "dev": true, "inBundle": true, "license": "MIT", @@ -2974,6 +2974,10 @@ "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" } }, "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { @@ -2994,9 +2998,9 @@ "optional": true }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz", - "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz", + "integrity": "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==", "cpu": [ "arm64" ], @@ -3007,13 +3011,13 @@ "win32" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz", - "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz", + "integrity": "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==", "cpu": [ "x64" ], @@ -3024,19 +3028,19 @@ "win32" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/vite": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.18.tgz", - "integrity": "sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.1.tgz", + "integrity": "sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w==", "dev": true, "license": "MIT", "dependencies": { - "@tailwindcss/node": "4.1.18", - "@tailwindcss/oxide": "4.1.18", - "tailwindcss": "4.1.18" + "@tailwindcss/node": "4.2.1", + "@tailwindcss/oxide": "4.2.1", + "tailwindcss": "4.2.1" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" @@ -3415,17 +3419,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz", - "integrity": "sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.1.tgz", + "integrity": "sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/type-utils": "8.56.0", - "@typescript-eslint/utils": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/scope-manager": "8.57.1", + "@typescript-eslint/type-utils": "8.57.1", + "@typescript-eslint/utils": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -3438,7 +3442,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.56.0", + "@typescript-eslint/parser": "^8.57.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } @@ -3454,16 +3458,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.0.tgz", - "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.1.tgz", + "integrity": "sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/scope-manager": "8.57.1", + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/typescript-estree": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.1", "debug": "^4.4.3" }, "engines": { @@ -3479,14 +3483,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz", - "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.1.tgz", + "integrity": "sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.56.0", - "@typescript-eslint/types": "^8.56.0", + "@typescript-eslint/tsconfig-utils": "^8.57.1", + "@typescript-eslint/types": "^8.57.1", "debug": "^4.4.3" }, "engines": { @@ -3501,14 +3505,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", - "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.1.tgz", + "integrity": "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0" + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3519,9 +3523,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz", - "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.1.tgz", + "integrity": "sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==", "dev": true, "license": "MIT", "engines": { @@ -3536,15 +3540,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.0.tgz", - "integrity": "sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.1.tgz", + "integrity": "sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0", - "@typescript-eslint/utils": "8.56.0", + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/typescript-estree": "8.57.1", + "@typescript-eslint/utils": "8.57.1", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -3561,9 +3565,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", - "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz", + "integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==", "dev": true, "license": "MIT", "engines": { @@ -3575,18 +3579,18 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", - "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.1.tgz", + "integrity": "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.56.0", - "@typescript-eslint/tsconfig-utils": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/project-service": "8.57.1", + "@typescript-eslint/tsconfig-utils": "8.57.1", + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.1", "debug": "^4.4.3", - "minimatch": "^9.0.5", + "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" @@ -3603,16 +3607,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", - "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.1.tgz", + "integrity": "sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0" + "@typescript-eslint/scope-manager": "8.57.1", + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/typescript-estree": "8.57.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3627,13 +3631,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", - "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.1.tgz", + "integrity": "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/types": "8.57.1", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -3645,9 +3649,9 @@ } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz", - "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3846,14 +3850,14 @@ } }, "node_modules/@volar/kit": { - "version": "2.4.27", - "resolved": "https://registry.npmjs.org/@volar/kit/-/kit-2.4.27.tgz", - "integrity": "sha512-ilZoQDMLzqmSsImJRWx4YiZ4FcvvPrPnFVmL6hSsIWB6Bn3qc7k88J9yP32dagrs5Y8EXIlvvD/mAFaiuEOACQ==", + "version": "2.4.28", + "resolved": "https://registry.npmjs.org/@volar/kit/-/kit-2.4.28.tgz", + "integrity": "sha512-cKX4vK9dtZvDRaAzeoUdaAJEew6IdxHNCRrdp5Kvcl6zZOqb6jTOfk3kXkIkG3T7oTFXguEMt5+9ptyqYR84Pg==", "dev": true, "license": "MIT", "dependencies": { - "@volar/language-service": "2.4.27", - "@volar/typescript": "2.4.27", + "@volar/language-service": "2.4.28", + "@volar/typescript": "2.4.28", "typesafe-path": "^0.2.2", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" @@ -3863,25 +3867,25 @@ } }, "node_modules/@volar/language-core": { - "version": "2.4.27", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.27.tgz", - "integrity": "sha512-DjmjBWZ4tJKxfNC1F6HyYERNHPYS7L7OPFyCrestykNdUZMFYzI9WTyvwPcaNaHlrEUwESHYsfEw3isInncZxQ==", + "version": "2.4.28", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.28.tgz", + "integrity": "sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==", "dev": true, "license": "MIT", "dependencies": { - "@volar/source-map": "2.4.27" + "@volar/source-map": "2.4.28" } }, "node_modules/@volar/language-server": { - "version": "2.4.27", - "resolved": "https://registry.npmjs.org/@volar/language-server/-/language-server-2.4.27.tgz", - "integrity": "sha512-SymGNkErcHg8GjiG65iQN8sLkhqu1pwKhFySmxeBuYq5xFYagKBW36eiNITXQTdvT0tutI1GXcXdq/FdE/IyjA==", + "version": "2.4.28", + "resolved": "https://registry.npmjs.org/@volar/language-server/-/language-server-2.4.28.tgz", + "integrity": "sha512-NqcLnE5gERKuS4PUFwlhMxf6vqYo7hXtbMFbViXcbVkbZ905AIVWhnSo0ZNBC2V127H1/2zP7RvVOVnyITFfBw==", "dev": true, "license": "MIT", "dependencies": { - "@volar/language-core": "2.4.27", - "@volar/language-service": "2.4.27", - "@volar/typescript": "2.4.27", + "@volar/language-core": "2.4.28", + "@volar/language-service": "2.4.28", + "@volar/typescript": "2.4.28", "path-browserify": "^1.0.1", "request-light": "^0.7.0", "vscode-languageserver": "^9.0.1", @@ -3891,33 +3895,33 @@ } }, "node_modules/@volar/language-service": { - "version": "2.4.27", - "resolved": "https://registry.npmjs.org/@volar/language-service/-/language-service-2.4.27.tgz", - "integrity": "sha512-SxKZ8yLhpWa7Y5e/RDxtNfm7j7xsXp/uf2urijXEffRNpPSmVdfzQrFFy5d7l8PNpZy+bHg+yakmqBPjQN+MOw==", + "version": "2.4.28", + "resolved": "https://registry.npmjs.org/@volar/language-service/-/language-service-2.4.28.tgz", + "integrity": "sha512-Rh/wYCZJrI5vCwMk9xyw/Z+MsWxlJY1rmMZPsxUoJKfzIRjS/NF1NmnuEcrMbEVGja00aVpCsInJfixQTMdvLw==", "dev": true, "license": "MIT", "dependencies": { - "@volar/language-core": "2.4.27", + "@volar/language-core": "2.4.28", "vscode-languageserver-protocol": "^3.17.5", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" } }, "node_modules/@volar/source-map": { - "version": "2.4.27", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.27.tgz", - "integrity": "sha512-ynlcBReMgOZj2i6po+qVswtDUeeBRCTgDurjMGShbm8WYZgJ0PA4RmtebBJ0BCYol1qPv3GQF6jK7C9qoVc7lg==", + "version": "2.4.28", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.28.tgz", + "integrity": "sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==", "dev": true, "license": "MIT" }, "node_modules/@volar/typescript": { - "version": "2.4.27", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.27.tgz", - "integrity": "sha512-eWaYCcl/uAPInSK2Lze6IqVWaBu/itVqR5InXcHXFyles4zO++Mglt3oxdgj75BDcv1Knr9Y93nowS8U3wqhxg==", + "version": "2.4.28", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.28.tgz", + "integrity": "sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==", "dev": true, "license": "MIT", "dependencies": { - "@volar/language-core": "2.4.27", + "@volar/language-core": "2.4.28", "path-browserify": "^1.0.1", "vscode-uri": "^3.0.8" } @@ -3950,9 +3954,9 @@ "license": "BSD-2-Clause" }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -5095,9 +5099,9 @@ } }, "node_modules/axios": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", - "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", @@ -5178,13 +5182,26 @@ } }, "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/brace-expansion/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/braces": { @@ -5908,9 +5925,9 @@ } }, "node_modules/daisyui": { - "version": "5.5.18", - "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.5.18.tgz", - "integrity": "sha512-VVzjpOitMGB6DWIBeRSapbjdOevFqyzpk9u5Um6a4tyId3JFrU5pbtF0vgjXDth76mJZbueN/j9Ok03SPrh/og==", + "version": "5.5.19", + "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.5.19.tgz", + "integrity": "sha512-pbFAkl1VCEh/MPCeclKL61I/MqRIFFhNU7yiXoDDRapXN4/qNCoMxeCCswyxEEhqL5eiTTfwHvucFtOE71C9sA==", "dev": true, "license": "MIT", "funding": { @@ -5972,9 +5989,9 @@ } }, "node_modules/dayjs": { - "version": "1.11.19", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz", - "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==", + "version": "1.11.20", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", + "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", "license": "MIT" }, "node_modules/debug": { @@ -6354,14 +6371,14 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.18.4", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", - "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz", + "integrity": "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==", "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "tapable": "^2.3.0" }, "engines": { "node": ">=10.13.0" @@ -8755,9 +8772,9 @@ } }, "node_modules/katex": { - "version": "0.16.28", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.28.tgz", - "integrity": "sha512-YHzO7721WbmAL6Ov1uzN/l5mY5WWWhJBSW+jq4tkfZfsxmo1hu6frS0EOswvjBUnWE6NtjEs48SFn5CQESRLZg==", + "version": "0.16.38", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.38.tgz", + "integrity": "sha512-cjHooZUmIAUmDsHBN+1n8LaZdpmbj03LtYeYPyuYB7OuloiaeaV6N4LcfjcnHVzGWjVQmKrxxTrpDcmSzEZQwQ==", "funding": [ "https://opencollective.com/katex", "https://github.com/sponsors/katex" @@ -8835,9 +8852,9 @@ } }, "node_modules/lightningcss": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", - "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz", + "integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==", "devOptional": true, "license": "MPL-2.0", "dependencies": { @@ -8851,23 +8868,23 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-android-arm64": "1.30.2", - "lightningcss-darwin-arm64": "1.30.2", - "lightningcss-darwin-x64": "1.30.2", - "lightningcss-freebsd-x64": "1.30.2", - "lightningcss-linux-arm-gnueabihf": "1.30.2", - "lightningcss-linux-arm64-gnu": "1.30.2", - "lightningcss-linux-arm64-musl": "1.30.2", - "lightningcss-linux-x64-gnu": "1.30.2", - "lightningcss-linux-x64-musl": "1.30.2", - "lightningcss-win32-arm64-msvc": "1.30.2", - "lightningcss-win32-x64-msvc": "1.30.2" + "lightningcss-android-arm64": "1.31.1", + "lightningcss-darwin-arm64": "1.31.1", + "lightningcss-darwin-x64": "1.31.1", + "lightningcss-freebsd-x64": "1.31.1", + "lightningcss-linux-arm-gnueabihf": "1.31.1", + "lightningcss-linux-arm64-gnu": "1.31.1", + "lightningcss-linux-arm64-musl": "1.31.1", + "lightningcss-linux-x64-gnu": "1.31.1", + "lightningcss-linux-x64-musl": "1.31.1", + "lightningcss-win32-arm64-msvc": "1.31.1", + "lightningcss-win32-x64-msvc": "1.31.1" } }, "node_modules/lightningcss-android-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", - "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", + "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", "cpu": [ "arm64" ], @@ -8885,9 +8902,9 @@ } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", - "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", + "integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==", "cpu": [ "arm64" ], @@ -8905,9 +8922,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", - "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", + "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", "cpu": [ "x64" ], @@ -8925,9 +8942,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", - "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", + "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", "cpu": [ "x64" ], @@ -8945,9 +8962,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", - "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", + "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", "cpu": [ "arm" ], @@ -8965,9 +8982,9 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", - "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", + "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", "cpu": [ "arm64" ], @@ -8985,9 +9002,9 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", - "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", + "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", "cpu": [ "arm64" ], @@ -9005,9 +9022,9 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", - "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", + "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", "cpu": [ "x64" ], @@ -9025,9 +9042,9 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", - "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", + "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", "cpu": [ "x64" ], @@ -9045,9 +9062,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", - "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", + "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", "cpu": [ "arm64" ], @@ -9065,9 +9082,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", - "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", + "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", "cpu": [ "x64" ], @@ -9131,13 +9148,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -10123,16 +10133,16 @@ } }, "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -10148,22 +10158,22 @@ } }, "node_modules/mlly": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", - "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.1.tgz", + "integrity": "sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ==", "dev": true, "license": "MIT", "dependencies": { - "acorn": "^8.15.0", + "acorn": "^8.16.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", - "ufo": "^1.6.1" + "ufo": "^1.6.3" } }, "node_modules/modern-tar": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/modern-tar/-/modern-tar-0.7.3.tgz", - "integrity": "sha512-4W79zekKGyYU4JXVmB78DOscMFaJth2gGhgfTl2alWE4rNe3nf4N2pqenQ0rEtIewrnD79M687Ouba3YGTLOvg==", + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/modern-tar/-/modern-tar-0.7.5.tgz", + "integrity": "sha512-YTefgdpKKFgoTDbEUqXqgUJct2OG6/4hs4XWLsxcHkDLj/x/V8WmKIRppPnXP5feQ7d1vuYWSp3qKkxfwaFaxA==", "dev": true, "license": "MIT", "engines": { @@ -10195,9 +10205,9 @@ "license": "MIT" }, "node_modules/msw": { - "version": "2.12.10", - "resolved": "https://registry.npmjs.org/msw/-/msw-2.12.10.tgz", - "integrity": "sha512-G3VUymSE0/iegFnuipujpwyTM2GuZAKXNeerUSrG2+Eg391wW63xFs5ixWsK9MWzr1AGoSkYGmyAzNgbR3+urw==", + "version": "2.12.11", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.12.11.tgz", + "integrity": "sha512-dVg20zi2I2EvnwH/+WupzsOC2mCa7qsIhyMAWtfRikn6RKtwL9+7SaF1IQ5LyZry4tlUtf6KyTVhnlQiZXozTQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -11919,10 +11929,13 @@ } }, "node_modules/sax": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.3.tgz", - "integrity": "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==", - "license": "BlueOak-1.0.0" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", + "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } }, "node_modules/scheduler": { "version": "0.23.2", @@ -12619,9 +12632,9 @@ } }, "node_modules/svgo": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.0.tgz", - "integrity": "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz", + "integrity": "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==", "license": "MIT", "dependencies": { "commander": "^11.1.0", @@ -12630,7 +12643,7 @@ "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.1.1", - "sax": "^1.4.1" + "sax": "^1.5.0" }, "bin": { "svgo": "bin/svgo.js" @@ -12683,9 +12696,9 @@ } }, "node_modules/tailwindcss": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", - "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz", + "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", "dev": true, "license": "MIT" }, @@ -13090,16 +13103,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.56.0.tgz", - "integrity": "sha512-c7toRLrotJ9oixgdW7liukZpsnq5CZ7PuKztubGYlNppuTqhIoWfhgHo/7EU0v06gS2l/x0i2NEFK1qMIf0rIg==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.57.1.tgz", + "integrity": "sha512-fLvZWf+cAGw3tqMCYzGIU6yR8K+Y9NT2z23RwOjlNFF2HwSB3KhdEFI5lSBv8tNmFkkBShSjsCjzx1vahZfISA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.56.0", - "@typescript-eslint/parser": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0", - "@typescript-eslint/utils": "8.56.0" + "@typescript-eslint/eslint-plugin": "8.57.1", + "@typescript-eslint/parser": "8.57.1", + "@typescript-eslint/typescript-estree": "8.57.1", + "@typescript-eslint/utils": "8.57.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -13664,9 +13677,9 @@ } }, "node_modules/volar-service-css": { - "version": "0.0.67", - "resolved": "https://registry.npmjs.org/volar-service-css/-/volar-service-css-0.0.67.tgz", - "integrity": "sha512-zV7C6enn9T9tuvQ6iSUyYEs34iPXR69Pf9YYWpbFYPWzVs22w96BtE8p04XYXbmjU6unt5oFt+iLL77bMB5fhA==", + "version": "0.0.70", + "resolved": "https://registry.npmjs.org/volar-service-css/-/volar-service-css-0.0.70.tgz", + "integrity": "sha512-K1qyOvBpE3rzdAv3e4/6Rv5yizrYPy5R/ne3IWCAzLBuMO4qBMV3kSqWzj6KUVe6S0AnN6wxF7cRkiaKfYMYJw==", "dev": true, "license": "MIT", "dependencies": { @@ -13684,9 +13697,9 @@ } }, "node_modules/volar-service-emmet": { - "version": "0.0.67", - "resolved": "https://registry.npmjs.org/volar-service-emmet/-/volar-service-emmet-0.0.67.tgz", - "integrity": "sha512-UDBL5x7KptmuJZNCCXMlCndMhFult/tj+9jXq3FH1ZGS1E4M/1U5hC06pg1c6e4kn+vnR6bqmvX0vIhL4f98+A==", + "version": "0.0.70", + "resolved": "https://registry.npmjs.org/volar-service-emmet/-/volar-service-emmet-0.0.70.tgz", + "integrity": "sha512-xi5bC4m/VyE3zy/n2CXspKeDZs3qA41tHLTw275/7dNWM/RqE2z3BnDICQybHIVp/6G1iOQj5c1qXMgQC08TNg==", "dev": true, "license": "MIT", "dependencies": { @@ -13705,9 +13718,9 @@ } }, "node_modules/volar-service-html": { - "version": "0.0.67", - "resolved": "https://registry.npmjs.org/volar-service-html/-/volar-service-html-0.0.67.tgz", - "integrity": "sha512-ljREMF79JbcjNvObiv69HK2HCl5UT7WTD10zi6CRFUHMbPfiF2UZ42HGLsEGSzaHGZz6H4IFjSS/qfENRLUviQ==", + "version": "0.0.70", + "resolved": "https://registry.npmjs.org/volar-service-html/-/volar-service-html-0.0.70.tgz", + "integrity": "sha512-eR6vCgMdmYAo4n+gcT7DSyBQbwB8S3HZZvSagTf0sxNaD4WppMCFfpqWnkrlGStPKMZvMiejRRVmqsX9dYcTvQ==", "dev": true, "license": "MIT", "dependencies": { @@ -13725,9 +13738,9 @@ } }, "node_modules/volar-service-prettier": { - "version": "0.0.67", - "resolved": "https://registry.npmjs.org/volar-service-prettier/-/volar-service-prettier-0.0.67.tgz", - "integrity": "sha512-B4KnPJPNWFTkEDa6Fn08i5PpO6T1CecmLLTFZoXz2eI4Fxwba/3nDaaVSsEP7e/vEe+U5YqV9fBzayJT71G5xg==", + "version": "0.0.70", + "resolved": "https://registry.npmjs.org/volar-service-prettier/-/volar-service-prettier-0.0.70.tgz", + "integrity": "sha512-Z6BCFSpGVCd8BPAsZ785Kce1BGlWd5ODqmqZGVuB14MJvrR4+CYz6cDy4F+igmE1gMifqfvMhdgT8Aud4M5ngg==", "dev": true, "license": "MIT", "dependencies": { @@ -13747,9 +13760,9 @@ } }, "node_modules/volar-service-typescript": { - "version": "0.0.67", - "resolved": "https://registry.npmjs.org/volar-service-typescript/-/volar-service-typescript-0.0.67.tgz", - "integrity": "sha512-rfQBy36Rm1PU9vLWHk8BYJ4r2j/CI024vocJcH4Nb6K2RTc2Irmw6UOVY5DdGiPRV5r+e10wLMK5njj/EcL8sA==", + "version": "0.0.70", + "resolved": "https://registry.npmjs.org/volar-service-typescript/-/volar-service-typescript-0.0.70.tgz", + "integrity": "sha512-l46Bx4cokkUedTd74ojO5H/zqHZJ8SUuyZ0IB8JN4jfRqUM3bQFBHoOwlZCyZmOeO0A3RQNkMnFclxO4c++gsg==", "dev": true, "license": "MIT", "dependencies": { @@ -13770,9 +13783,9 @@ } }, "node_modules/volar-service-typescript-twoslash-queries": { - "version": "0.0.67", - "resolved": "https://registry.npmjs.org/volar-service-typescript-twoslash-queries/-/volar-service-typescript-twoslash-queries-0.0.67.tgz", - "integrity": "sha512-LD2R7WivDYp1SPgZrxx/0222xVTitDjm36oKo5+bfYG5kEgnw+BOPVHdwmvpJKg/RfssfxDI1ouwD4XkEDEfbA==", + "version": "0.0.70", + "resolved": "https://registry.npmjs.org/volar-service-typescript-twoslash-queries/-/volar-service-typescript-twoslash-queries-0.0.70.tgz", + "integrity": "sha512-IdD13Z9N2Bu8EM6CM0fDV1E69olEYGHDU25X51YXmq8Y0CmJ2LNj6gOiBJgpS5JGUqFzECVhMNBW7R0sPdRTMQ==", "dev": true, "license": "MIT", "dependencies": { @@ -13788,14 +13801,14 @@ } }, "node_modules/volar-service-yaml": { - "version": "0.0.67", - "resolved": "https://registry.npmjs.org/volar-service-yaml/-/volar-service-yaml-0.0.67.tgz", - "integrity": "sha512-jkdP/RF6wPIXEE3Ktnd81oJPn7aAvnVSiaqQHThC2Hrvo6xd9pEcqtbBUI+YfqVgvcMtXAkbtNO61K2GPhAiuA==", + "version": "0.0.70", + "resolved": "https://registry.npmjs.org/volar-service-yaml/-/volar-service-yaml-0.0.70.tgz", + "integrity": "sha512-0c8bXDBeoATF9F6iPIlOuYTuZAC4c+yi0siQo920u7eiBJk8oQmUmg9cDUbR4+Gl++bvGP4plj3fErbJuPqdcQ==", "dev": true, "license": "MIT", "dependencies": { "vscode-uri": "^3.0.8", - "yaml-language-server": "~1.19.2" + "yaml-language-server": "~1.20.0" }, "peerDependencies": { "@volar/language-service": "~2.4.0" @@ -13807,9 +13820,9 @@ } }, "node_modules/vscode-css-languageservice": { - "version": "6.3.9", - "resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-6.3.9.tgz", - "integrity": "sha512-1tLWfp+TDM5ZuVWht3jmaY5y7O6aZmpeXLoHl5bv1QtRsRKt4xYGRMmdJa5Pqx/FTkgRbsna9R+Gn2xE+evVuA==", + "version": "6.3.10", + "resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-6.3.10.tgz", + "integrity": "sha512-eq5N9Er3fC4vA9zd9EFhyBG90wtCCuXgRSpAndaOgXMh1Wgep5lBgRIeDgjZBW9pa+332yC9+49cZMW8jcL3MA==", "dev": true, "license": "MIT", "dependencies": { @@ -13820,9 +13833,9 @@ } }, "node_modules/vscode-html-languageservice": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-5.6.1.tgz", - "integrity": "sha512-5Mrqy5CLfFZUgkyhNZLA1Ye5g12Cb/v6VM7SxUzZUaRKWMDz4md+y26PrfRTSU0/eQAl3XpO9m2og+GGtDMuaA==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-5.6.2.tgz", + "integrity": "sha512-ulCrSnFnfQ16YzvwnYUgEbUEl/ZG7u2eV27YhvLObSHKkb8fw1Z9cgsnUwjTEeDIdJDoTDTDpxuhQwoenoLNMg==", "dev": true, "license": "MIT", "dependencies": { @@ -14227,16 +14240,15 @@ } }, "node_modules/yaml-language-server": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-1.19.2.tgz", - "integrity": "sha512-9F3myNmJzUN/679jycdMxqtydPSDRAarSj3wPiF7pchEPnO9Dg07Oc+gIYLqXR4L+g+FSEVXXv2+mr54StLFOg==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-1.20.0.tgz", + "integrity": "sha512-qhjK/bzSRZ6HtTvgeFvjNPJGWdZ0+x5NREV/9XZWFjIGezew2b4r5JPy66IfOhd5OA7KeFwk1JfmEbnTvev0cA==", "dev": true, "license": "MIT", "dependencies": { "@vscode/l10n": "^0.0.18", "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", - "lodash": "4.17.21", "prettier": "^3.5.0", "request-light": "^0.5.7", "vscode-json-languageservice": "4.1.8", @@ -14251,9 +14263,9 @@ } }, "node_modules/yaml-language-server/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { diff --git a/website/package.json b/website/package.json index eac6efc8e..35d56b962 100644 --- a/website/package.json +++ b/website/package.json @@ -27,14 +27,14 @@ "dependencies": { "@astrojs/node": "^9.5.3", "@auth/core": "^0.37.4", - "@genspectrum/dashboard-components": "^1.15.0", + "@genspectrum/dashboard-components": "^1.16.0", "@tanstack/react-query": "^5.90.21", "astro": "^5.17.2", "auth-astro": "^4.2.0", - "axios": "^1.13.5", + "axios": "^1.13.6", "cookie": "^1.1.1", - "dayjs": "^1.11.19", - "katex": "^0.16.28", + "dayjs": "^1.11.20", + "katex": "^0.16.38", "patch-package": "^8.0.1", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -46,14 +46,14 @@ "yaml": "^2.8.2" }, "devDependencies": { - "@astrojs/check": "^0.9.6", + "@astrojs/check": "^0.9.8", "@astrojs/react": "^4.4.2", "@eslint/js": "^9.39.2", "@iconify-json/mdi": "^1.2.3", "@iconify-json/mdi-light": "^1.2.2", - "@iconify/tailwind4": "^1.2.1", + "@iconify/tailwind4": "^1.2.3", "@playwright/test": "^1.58.2", - "@tailwindcss/vite": "^4.1.18", + "@tailwindcss/vite": "^4.2.1", "@tanstack/eslint-plugin-query": "^5.91.4", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", @@ -64,25 +64,25 @@ "@types/react-dom": "^18.3.1", "@types/react-katex": "^3.0.4", "@types/topojson-specification": "^1.0.5", - "@typescript-eslint/eslint-plugin": "^8.56.0", - "@typescript-eslint/parser": "^8.56.0", + "@typescript-eslint/eslint-plugin": "^8.57.1", + "@typescript-eslint/parser": "^8.57.1", "@vitest/browser": "^3.2.4", "astro-eslint-parser": "^1.3.0", - "daisyui": "^5.5.18", + "daisyui": "^5.5.19", "dotenv": "^16.5.0", "eslint": "^9.39.2", "eslint-plugin-astro": "^1.6.0", "eslint-plugin-import": "^2.32.0", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^5.2.0", - "msw": "^2.12.10", + "msw": "^2.12.11", "playwright": "^1.55.0", "prettier": "^3.8.1", "prettier-plugin-astro": "^0.14.1", "prettier-plugin-tailwindcss": "^0.7.2", "tailwindcss": "^4.0.9", "typescript": "^5.9.3", - "typescript-eslint": "^8.56.0", + "typescript-eslint": "^8.57.1", "vitest": "^3.2.4", "vitest-browser-react": "^1.0.1", "zod": "^3.25.74" diff --git a/website/src/components/genspectrum/GsAggregate.astro b/website/src/components/genspectrum/GsAggregate.astro deleted file mode 100644 index 24cdb6c38..000000000 --- a/website/src/components/genspectrum/GsAggregate.astro +++ /dev/null @@ -1,27 +0,0 @@ ---- -import { type AggregateView, type LapisFilter } from '@genspectrum/dashboard-components/util'; - -import { defaultTablePageSize } from '../../views/View'; -import ComponentWrapper from '../ComponentWrapper.astro'; - -interface Props { - title: string; - fields: string[]; - lapisFilter: LapisFilter; - views: AggregateView[]; - height?: string; - pageSize?: number; -} - -const { title, height, fields, lapisFilter, views, pageSize } = Astro.props; ---- - - - - diff --git a/website/src/components/genspectrum/GsMutations.astro b/website/src/components/genspectrum/GsMutations.astro deleted file mode 100644 index 80d4c6787..000000000 --- a/website/src/components/genspectrum/GsMutations.astro +++ /dev/null @@ -1,30 +0,0 @@ ---- -import type { LapisFilter, SequenceType } from '@genspectrum/dashboard-components/util'; - -import { defaultTablePageSize } from '../../views/View'; -import ComponentWrapper from '../ComponentWrapper.astro'; - -interface Props { - lapisFilter: LapisFilter; - baselineLapisFilter?: LapisFilter; - sequenceType: SequenceType; - pageSize?: number; - height?: string; -} - -const { lapisFilter, baselineLapisFilter, sequenceType, pageSize, height } = Astro.props; ---- - - - - diff --git a/website/src/components/genspectrum/GsMutationsOverTime.astro b/website/src/components/genspectrum/GsMutationsOverTime.astro deleted file mode 100644 index 2bc42351b..000000000 --- a/website/src/components/genspectrum/GsMutationsOverTime.astro +++ /dev/null @@ -1,29 +0,0 @@ ---- -import type { TemporalGranularity, LapisFilter, SequenceType } from '@genspectrum/dashboard-components/util'; - -import ComponentWrapper from '../ComponentWrapper.astro'; - -interface Props { - lapisFilter: LapisFilter; - sequenceType: SequenceType; - granularity: TemporalGranularity; - lapisDateField: string; - height?: string; -} - -const { lapisFilter, sequenceType, granularity, lapisDateField, height } = Astro.props; ---- - - - - diff --git a/website/src/components/genspectrum/GsMutationsOverTime.tsx b/website/src/components/genspectrum/GsMutationsOverTime.tsx index c3b93e6b1..b5981a1fd 100644 --- a/website/src/components/genspectrum/GsMutationsOverTime.tsx +++ b/website/src/components/genspectrum/GsMutationsOverTime.tsx @@ -18,7 +18,6 @@ export type GsMutationsOverTimeProps = { displayMutations?: string[]; height?: string; pageSizes?: number[]; - useNewEndpoint?: true; hideGaps?: true; initialMeanProportionInterval?: MeanProportionInterval; customColumns?: CustomColumn[]; @@ -32,7 +31,6 @@ export const GsMutationsOverTime: FC = ({ displayMutations, height, pageSizes, - useNewEndpoint, hideGaps, initialMeanProportionInterval, customColumns, @@ -51,7 +49,6 @@ export const GsMutationsOverTime: FC = ({ granularity={granularity} lapisDateField={lapisDateField} displayMutations={displayMutations ? JSON.stringify(displayMutations) : undefined} - useNewEndpoint={useNewEndpoint} hideGaps={hideGaps} pageSizes={JSON.stringify(pageSizes ?? [10, 20, 30, 40, 50])} initialMeanProportionInterval={ diff --git a/website/src/components/genspectrum/GsNumberSequencesOverTime.astro b/website/src/components/genspectrum/GsNumberSequencesOverTime.astro deleted file mode 100644 index f8847ddbd..000000000 --- a/website/src/components/genspectrum/GsNumberSequencesOverTime.astro +++ /dev/null @@ -1,27 +0,0 @@ ---- -import type { NamedLapisFilter } from '@genspectrum/dashboard-components/util'; - -import { defaultTablePageSize } from '../../views/View'; -import ComponentWrapper from '../ComponentWrapper.astro'; - -interface Props { - lapisFilters: NamedLapisFilter[]; - lapisDateField: string; - granularity: string; - pageSize?: number; - height?: string; -} - -const { lapisFilters, lapisDateField, granularity, pageSize, height } = Astro.props; ---- - - - - diff --git a/website/src/components/genspectrum/GsPrevalenceOverTime.astro b/website/src/components/genspectrum/GsPrevalenceOverTime.astro deleted file mode 100644 index 063a9001d..000000000 --- a/website/src/components/genspectrum/GsPrevalenceOverTime.astro +++ /dev/null @@ -1,44 +0,0 @@ ---- -import type { - LapisFilter, - NamedLapisFilter, - PrevalenceOverTimeView, - TemporalGranularity, -} from '@genspectrum/dashboard-components/util'; - -import { defaultTablePageSize } from '../../views/View'; -import ComponentWrapper from '../ComponentWrapper.astro'; - -interface Props { - numeratorFilters: NamedLapisFilter[]; - denominatorFilter: LapisFilter; - lapisDateField: string; - granularity: TemporalGranularity; - views?: PrevalenceOverTimeView[]; - height?: string; - pageSize?: number; -} - -const { - numeratorFilters, - denominatorFilter, - lapisDateField, - granularity, - views = ['bar', 'line', 'bubble', 'table'], - height, - pageSize, -} = Astro.props; ---- - - - - diff --git a/website/src/components/genspectrum/GsQueriesOverTime.tsx b/website/src/components/genspectrum/GsQueriesOverTime.tsx index e13f3ae7f..15063d9fe 100644 --- a/website/src/components/genspectrum/GsQueriesOverTime.tsx +++ b/website/src/components/genspectrum/GsQueriesOverTime.tsx @@ -3,8 +3,8 @@ import { type CustomColumn, type LapisFilter, type MeanProportionInterval, - type QueryDefinition, type TemporalGranularity, + type CountCoverageQuery, } from '@genspectrum/dashboard-components/util'; import { type FC } from 'react'; @@ -13,7 +13,7 @@ import { ComponentWrapper } from '../ComponentWrapper'; export type GsQueriesOverTimeProps = { collectionTitle?: string; lapisFilter: LapisFilter; - queries: QueryDefinition[]; + queries: CountCoverageQuery[]; granularity: TemporalGranularity; lapisDateField: string; height?: string; diff --git a/website/src/components/genspectrum/GsRelativeGrowthAdvantage.astro b/website/src/components/genspectrum/GsRelativeGrowthAdvantage.astro deleted file mode 100644 index 377cb2271..000000000 --- a/website/src/components/genspectrum/GsRelativeGrowthAdvantage.astro +++ /dev/null @@ -1,26 +0,0 @@ ---- -import type { LapisFilter } from '@genspectrum/dashboard-components/util'; - -import { defaultTablePageSize } from '../../views/View'; -import ComponentWrapper from '../ComponentWrapper.astro'; - -interface Props { - numeratorFilter: LapisFilter; - denominatorFilter: LapisFilter; - lapisDateField: string; - height?: string; -} - -const { numeratorFilter, denominatorFilter, lapisDateField, height } = Astro.props; ---- - - - - diff --git a/website/src/components/genspectrum/GsStatistics.astro b/website/src/components/genspectrum/GsStatistics.astro deleted file mode 100644 index e365d6298..000000000 --- a/website/src/components/genspectrum/GsStatistics.astro +++ /dev/null @@ -1,21 +0,0 @@ ---- -import type { LapisFilter } from '@genspectrum/dashboard-components/util'; - -import ComponentHeadline from '../ComponentHeadline.astro'; - -interface Props { - numeratorFilter: LapisFilter; - denominatorFilter: LapisFilter; -} - -const { numeratorFilter, denominatorFilter } = Astro.props; ---- - -
- - -
diff --git a/website/src/components/views/analyzeSingleVariant/CovidSingleVariantDataDisplay.tsx b/website/src/components/views/analyzeSingleVariant/CovidSingleVariantDataDisplay.tsx index 8ee878318..134748bb8 100644 --- a/website/src/components/views/analyzeSingleVariant/CovidSingleVariantDataDisplay.tsx +++ b/website/src/components/views/analyzeSingleVariant/CovidSingleVariantDataDisplay.tsx @@ -113,7 +113,6 @@ export const CovidSingleVariantDataDisplay: FC ); diff --git a/website/src/components/views/analyzeSingleVariant/GenericAnalyseSingleVariantDataDisplay.tsx b/website/src/components/views/analyzeSingleVariant/GenericAnalyseSingleVariantDataDisplay.tsx index 0bd266e27..9f9ab6bea 100644 --- a/website/src/components/views/analyzeSingleVariant/GenericAnalyseSingleVariantDataDisplay.tsx +++ b/website/src/components/views/analyzeSingleVariant/GenericAnalyseSingleVariantDataDisplay.tsx @@ -103,14 +103,12 @@ export const GenericAnalyseSingleVariantDataDisplay: FC ); diff --git a/website/src/components/views/compareSideBySide/GenericCompareSideBySideReactPage.tsx b/website/src/components/views/compareSideBySide/GenericCompareSideBySideReactPage.tsx index 22a009dda..f97b19ea2 100644 --- a/website/src/components/views/compareSideBySide/GenericCompareSideBySideReactPage.tsx +++ b/website/src/components/views/compareSideBySide/GenericCompareSideBySideReactPage.tsx @@ -55,14 +55,13 @@ export const GenericCompareSideBySideReactPage: FC {pageState.filters.size > 1 && ( - setPageState(view.pageStateHandler.removeFilter(pageState, id))} > Remove column - + )} - setPageState(view.pageStateHandler.addEmptyFilter(pageState))} > - Add column - + + Add column + + ); diff --git a/website/src/components/views/wasap/WasapPage.tsx b/website/src/components/views/wasap/WasapPage.tsx index 0f90733f2..f6ebea710 100644 --- a/website/src/components/views/wasap/WasapPage.tsx +++ b/website/src/components/views/wasap/WasapPage.tsx @@ -1,18 +1,13 @@ import type { MeanProportionInterval } from '@genspectrum/dashboard-components/util'; -import { useQuery } from '@tanstack/react-query'; import { useMemo } from 'react'; import { type FC } from 'react'; +import { CollectionInfo } from './components/CollectionInfo'; +import { NoDataHelperText } from './components/NoDataHelperText'; +import { VariantFetchInfo } from './components/VariantFetchInfo'; +import { WasapStats } from './components/WasapStats'; import { toMutationAnnotations } from './resistanceMutations'; -import { getLapisFilterForTimeFrame, useWasapPageData } from './useWasapPageData'; -import { - variantTimeFrameLabel, - type WasapAnalysisFilter, - type WasapPageConfig, - type WasapVariantFilter, -} from './wasapPageConfig'; -import { getDateRange } from '../../../lapis/getDateRange'; -import { getTotalCount } from '../../../lapis/getTotalCount'; +import { useWasapPageData } from './useWasapPageData'; import { defaultBreadcrumbs } from '../../../layouts/Breadcrumbs.tsx'; import { DataPageLayout } from '../../../layouts/OrganismPage/DataPageLayout.tsx'; import { dataOrigins } from '../../../types/dataOrigins.ts'; @@ -120,7 +115,6 @@ export const WasapPageInner: FC = ({ wastewaterOrganism, isStagi } displayMutations={data.displayMutations} pageSizes={[20, 50, 100, 250]} - useNewEndpoint={true} initialMeanProportionInterval={initialMeanProportionInterval} hideGaps={base.excludeEmpty ? true : undefined} customColumns={data.customColumns} @@ -135,22 +129,29 @@ export const WasapPageInner: FC = ({ wastewaterOrganism, isStagi warningThreshold={config.clinicalSequenceCountWarningThreshold} /> )} - ) : ( -
- +
+ +
+ -
+ )} + )} @@ -160,139 +161,3 @@ export const WasapPageInner: FC = ({ wastewaterOrganism, isStagi }; export const WasapPage = withQueryProvider(WasapPageInner); - -/** - * A note to the user to display when no mutations are selected due to the settings that they set in the filters. - * The information is tailored to the mode and settings the user selected. - */ -const NoDataHelperText = ({ analysisFilter }: { analysisFilter: WasapAnalysisFilter }) => { - return ( -
-

No mutations selected

- {analysisFilter.mode === 'variant' && ( -

- No mutations could be found matching your current filter settings. Try lowering filter thresholds or - looking at a different variant. -

- )} - {analysisFilter.mode === 'untracked' && - analysisFilter.excludeSet === 'custom' && - (analysisFilter.excludeVariants === undefined || analysisFilter.excludeVariants.length === 0) && ( -

- Your set of variants to exclude is empty, please provide at least one variant to exclude. -

- )} -
- ); -}; - -/** - * Info stat about the amount of sequences used during the computation of the clinical variant signature. - * Will also show a warning of the count is small. - */ -const VariantFetchInfo = ({ - analysis, - clinicalLapisBaseUrl, - clinicalLapisLineageField, - clinicalLapisDateField, - warningThreshold, -}: { - analysis: WasapVariantFilter; - clinicalLapisBaseUrl: string; - clinicalLapisLineageField: string; - clinicalLapisDateField: string; - warningThreshold: number; -}) => { - const lapisFilter = { - ...getLapisFilterForTimeFrame(analysis.timeFrame, clinicalLapisDateField), - [clinicalLapisLineageField]: analysis.variant, - }; - - const { data, isPending, isError, error } = useQuery({ - queryKey: ['variantFetchInfo'], - queryFn: () => getTotalCount(clinicalLapisBaseUrl, lapisFilter), - }); - - const isHighlighted = data !== undefined && data < warningThreshold; - - let message = `The number of clinical sequences for ${analysis.variant}`; - if (analysis.timeFrame !== 'all') { - message += ` during the past ${variantTimeFrameLabel(analysis.timeFrame)}`; - } - if (isHighlighted) { - message += '. Clinical signature calculation with this few sequences is not recommended.'; - } - - return ( -
-
-
Clinical sequences for {analysis.variant}
-
- {isPending ? ( - '…' - ) : isError ? ( - 'Error' - ) : isHighlighted ? ( - {data.toLocaleString('en-us')} - ) : ( - data.toLocaleString('en-us') - )} -
-
{isPending ? 'Loading …' : isError ? error.message : message}
-
-
- ); -}; - -const WasapStats = ({ config }: { config: WasapPageConfig }) => ( -
- - -
-); - -const TotalCount = ({ config }: { config: WasapPageConfig }) => { - const { data, isPending, isError, error } = useQuery({ - queryKey: ['aggregatedCount'], - queryFn: () => getTotalCount(config.lapisBaseUrl, {}), - }); - - return ( -
-
Amplicon sequences
-
- {isPending ? '…' : isError ? 'Error' : data.toLocaleString('en-us')} -
-
- {isPending - ? 'Loading total amplicon sequences count…' - : isError - ? error.message - : 'The total number of amplicon sequences in all samples'} -
-
- ); -}; - -const DateRange = ({ config }: { config: WasapPageConfig }) => { - const { data, isPending, isError, error } = useQuery({ - queryKey: ['dateRange'], - queryFn: () => getDateRange(config.lapisBaseUrl, config.samplingDateField), - }); - - return ( -
-
Sampling Dates
-
- {isPending ? '…' : isError ? 'Error' : `${data.start} to ${data.end}`} -
-
- {isPending - ? 'Loading date range…' - : isError - ? error.message - : 'The start and end dates of collected samples'} -
-
- ); -}; diff --git a/website/src/components/views/wasap/components/CollectionInfo.tsx b/website/src/components/views/wasap/components/CollectionInfo.tsx new file mode 100644 index 000000000..036a0fa99 --- /dev/null +++ b/website/src/components/views/wasap/components/CollectionInfo.tsx @@ -0,0 +1,54 @@ +import type { FC } from 'react'; + +export type CollectionInfoProps = { + collectionId: number; + collectionTitle: string; + invalidVariants?: { + name: string; + error: string; + }[]; +}; + +/** + * Info component that displays collection metadata and any invalid variants. + */ +export const CollectionInfo: FC = ({ collectionId, collectionTitle, invalidVariants }) => { + return ( +
+ {/* Collection Link Stat */} +
+
CoV-Spectrum collection
+ +
Collection #{collectionId}
+
+ + {/* Invalid Variants Stat (conditional) */} + {invalidVariants && invalidVariants.length > 0 && ( +
+
Invalid Variants
+
+ {invalidVariants.length} +
+
+
    + {invalidVariants.map((v) => ( +
  • + {v.name}: {v.error} +
  • + ))} +
+
+
+ )} +
+ ); +}; diff --git a/website/src/components/views/wasap/components/NoDataHelperText.tsx b/website/src/components/views/wasap/components/NoDataHelperText.tsx new file mode 100644 index 000000000..caceb04e9 --- /dev/null +++ b/website/src/components/views/wasap/components/NoDataHelperText.tsx @@ -0,0 +1,28 @@ +import type { FC } from 'react'; + +import type { WasapAnalysisFilter } from '../wasapPageConfig'; + +/** + * A note to the user to display when no mutations are selected due to the settings that they set in the filters. + * The information is tailored to the mode and settings the user selected. + */ +export const NoDataHelperText: FC<{ analysisFilter: WasapAnalysisFilter }> = ({ analysisFilter }) => { + return ( +
+

No mutations selected

+ {analysisFilter.mode === 'variant' && ( +

+ No mutations could be found matching your current filter settings. Try lowering filter thresholds or + looking at a different variant. +

+ )} + {analysisFilter.mode === 'untracked' && + analysisFilter.excludeSet === 'custom' && + (analysisFilter.excludeVariants === undefined || analysisFilter.excludeVariants.length === 0) && ( +

+ Your set of variants to exclude is empty, please provide at least one variant to exclude. +

+ )} +
+ ); +}; diff --git a/website/src/components/views/wasap/components/VariantFetchInfo.tsx b/website/src/components/views/wasap/components/VariantFetchInfo.tsx new file mode 100644 index 000000000..f6cc01c2d --- /dev/null +++ b/website/src/components/views/wasap/components/VariantFetchInfo.tsx @@ -0,0 +1,58 @@ +import { useQuery } from '@tanstack/react-query'; +import type { FC } from 'react'; + +import { getTotalCount } from '../../../../lapis/getTotalCount'; +import { getLapisFilterForTimeFrame } from '../useWasapPageData'; +import { variantTimeFrameLabel, type WasapVariantFilter } from '../wasapPageConfig'; + +/** + * Info stat about the amount of sequences used during the computation of the clinical variant signature. + * Will also show a warning if the count is small. + */ +export const VariantFetchInfo: FC<{ + analysis: WasapVariantFilter; + clinicalLapisBaseUrl: string; + clinicalLapisLineageField: string; + clinicalLapisDateField: string; + warningThreshold: number; +}> = ({ analysis, clinicalLapisBaseUrl, clinicalLapisLineageField, clinicalLapisDateField, warningThreshold }) => { + const lapisFilter = { + ...getLapisFilterForTimeFrame(analysis.timeFrame, clinicalLapisDateField), + [clinicalLapisLineageField]: analysis.variant, + }; + + const { data, isPending, isError, error } = useQuery({ + queryKey: ['variantFetchInfo', analysis.variant, analysis.timeFrame], + queryFn: () => getTotalCount(clinicalLapisBaseUrl, lapisFilter), + }); + + const isHighlighted = data !== undefined && data < warningThreshold; + + let message = `The number of clinical sequences for ${analysis.variant}`; + if (analysis.timeFrame !== 'all') { + message += ` during the past ${variantTimeFrameLabel(analysis.timeFrame)}`; + } + if (isHighlighted) { + message += '. Clinical signature calculation with this few sequences is not recommended.'; + } + + return ( +
+
+
Clinical sequences for {analysis.variant}
+
+ {isPending ? ( + '…' + ) : isError ? ( + 'Error' + ) : isHighlighted ? ( + {data.toLocaleString('en-us')} + ) : ( + data.toLocaleString('en-us') + )} +
+
{isPending ? 'Loading …' : isError ? error.message : message}
+
+
+ ); +}; diff --git a/website/src/components/views/wasap/components/WasapStats.tsx b/website/src/components/views/wasap/components/WasapStats.tsx new file mode 100644 index 000000000..1d59b1ed2 --- /dev/null +++ b/website/src/components/views/wasap/components/WasapStats.tsx @@ -0,0 +1,59 @@ +import { useQuery } from '@tanstack/react-query'; +import type { FC } from 'react'; + +import { getDateRange } from '../../../../lapis/getDateRange'; +import { getTotalCount } from '../../../../lapis/getTotalCount'; +import type { WasapPageConfig } from '../wasapPageConfig'; + +export const WasapStats: FC<{ config: WasapPageConfig }> = ({ config }) => ( +
+ + +
+); + +const TotalCount: FC<{ config: WasapPageConfig }> = ({ config }) => { + const { data, isPending, isError, error } = useQuery({ + queryKey: ['aggregatedCount'], + queryFn: () => getTotalCount(config.lapisBaseUrl, {}), + }); + + return ( +
+
Amplicon sequences
+
+ {isPending ? '…' : isError ? 'Error' : data.toLocaleString('en-us')} +
+
+ {isPending + ? 'Loading total amplicon sequences count…' + : isError + ? error.message + : 'The total number of amplicon sequences in all samples'} +
+
+ ); +}; + +const DateRange: FC<{ config: WasapPageConfig }> = ({ config }) => { + const { data, isPending, isError, error } = useQuery({ + queryKey: ['dateRange'], + queryFn: () => getDateRange(config.lapisBaseUrl, config.samplingDateField), + }); + + return ( +
+
Sampling Dates
+
+ {isPending ? '…' : isError ? 'Error' : `${data.start} to ${data.end}`} +
+
+ {isPending + ? 'Loading date range…' + : isError + ? error.message + : 'The start and end dates of collected samples'} +
+
+ ); +}; diff --git a/website/src/components/views/wasap/useWasapPageData.ts b/website/src/components/views/wasap/useWasapPageData.ts index 5f51e1eb3..2eb629e2d 100644 --- a/website/src/components/views/wasap/useWasapPageData.ts +++ b/website/src/components/views/wasap/useWasapPageData.ts @@ -13,8 +13,11 @@ import type { WasapVariantFilter, } from './wasapPageConfig'; import { getCollection } from '../../../covspectrum/getCollection'; +import { detailedMutationsToQuery } from '../../../covspectrum/variantConversionUtil'; import { getCladeLineages } from '../../../lapis/getCladeLineages'; import { getMutations, getMutationsForVariant } from '../../../lapis/getMutations'; +import { parseQuery } from '../../../lapis/parseQuery'; +import { validateGenomeOnly } from '../../../util/siloExpressionUtils'; /** * Hook that fetches and returns `WasapPageData` for the W-ASAP page, @@ -147,25 +150,91 @@ async function fetchCollectionModeData( throw Error('No collection selected'); } const collection = await getCollection(config.collectionsApiBaseUrl, analysis.collectionId); + + const variantData: { + name: string; + queryString: string; + description?: string; + }[] = []; + + const invalidVariants: { + name: string; + error: string; + }[] = []; + + for (const variant of collection.variants) { + let queryString: string; + switch (variant.query.type) { + case 'variantQuery': { + queryString = variant.query.variantQuery; + break; + } + case 'detailedMutations': { + queryString = detailedMutationsToQuery(variant.query); + break; + } + } + if (queryString === '') { + invalidVariants.push({ + name: variant.name, + error: 'Variant is empty.', + }); + continue; + } + variantData.push({ + name: variant.name, + queryString: queryString, + description: variant.description !== '' ? variant.description : undefined, + }); + } + + // Parse all variant queries through LAPIS + const parseResults = await parseQuery( + config.lapisBaseUrl, + variantData.map((vd) => vd.queryString), + ); + + // Process results and validate const queries: { displayLabel: string; + description?: string; countQuery: string; coverageQuery: string; }[] = []; - collection.variants.forEach((f) => { - if (f.query.type === 'variantQuery') { - // TODO - this way of generating a coverageQuery sort-of works, but is not production ready - // we need to to it with the LAPIS endpoint: https://github.com/GenSpectrum/dashboards/issues/1026 - const positions = (f.query.variantQuery.match(/\d+/g) ?? []).map(Number); - const coverageQuery = positions.map((p) => `!C${p}N`).join(' | '); - queries.push({ - displayLabel: f.name, - countQuery: f.query.variantQuery, - coverageQuery, + variantData.forEach(({ name, queryString, description }, index) => { + const parseResult = parseResults[index]; + + // Check if parsing failed + if (parseResult.type === 'failure') { + invalidVariants.push({ + name: name, + error: `Parse error: ${parseResult.error}`, }); + return; } + + // Validate that the parsed query only contains genome checks + const validationResult = validateGenomeOnly(parseResult.filter); + if (!validationResult.isGenomeOnly) { + invalidVariants.push({ + name: name, + error: validationResult.error, + }); + return; + } + + // Query is valid - add to queries array + // coverage query can be calculated as below, see https://github.com/GenSpectrum/LAPIS/pull/1558 + const coverageQuery = `(${queryString}) or (not maybe(${queryString}))`; + queries.push({ + displayLabel: name, + description, + countQuery: queryString, + coverageQuery, + }); }); + return { type: 'collection', collection: { @@ -173,6 +242,7 @@ async function fetchCollectionModeData( title: collection.title, queries, }, + ...(invalidVariants.length > 0 && { invalidVariants }), }; } @@ -226,6 +296,11 @@ export type WasapCollectionData = { displayLabel: string; countQuery: string; coverageQuery: string; + description?: string; }[]; }; + invalidVariants?: { + name: string; + error: string; + }[]; }; diff --git a/website/src/covspectrum/types.ts b/website/src/covspectrum/types.ts index 82e50d612..045d7a81a 100644 --- a/website/src/covspectrum/types.ts +++ b/website/src/covspectrum/types.ts @@ -36,6 +36,8 @@ export const detailedMutationsQuerySchema = z.object({ aaInsertions: z.array(z.string()).optional(), }); +export type DetailedMutationsQuery = z.infer; + export const collectionVariantSchema = z.object({ query: z.discriminatedUnion('type', [variantQuerySchema, detailedMutationsQuerySchema]), name: z.string(), diff --git a/website/src/covspectrum/variantConversionUtil.spec.ts b/website/src/covspectrum/variantConversionUtil.spec.ts new file mode 100644 index 000000000..d44128976 --- /dev/null +++ b/website/src/covspectrum/variantConversionUtil.spec.ts @@ -0,0 +1,77 @@ +import { describe, expect, test } from 'vitest'; + +import type { DetailedMutationsQuery } from './types'; +import { detailedMutationsToQuery } from './variantConversionUtil'; + +describe('detailedMutationsToQuery', () => { + test('should return empty string for empty query', () => { + const query: DetailedMutationsQuery = { + type: 'detailedMutations', + }; + + const result = detailedMutationsToQuery(query); + + expect(result).toBe(''); + }); + + test('should convert nucleotide mutations only', () => { + const query: DetailedMutationsQuery = { + type: 'detailedMutations', + nucMutations: ['A123T', 'C456G', 'G789A'], + }; + + const result = detailedMutationsToQuery(query); + + expect(result).toBe('A123T & C456G & G789A'); + }); + + test('should convert pangoLineage filter', () => { + const query: DetailedMutationsQuery = { + type: 'detailedMutations', + pangoLineage: 'BA.1', + }; + + const result = detailedMutationsToQuery(query); + + expect(result).toBe('pangoLineage=BA.1'); + }); + + test('should convert nextcladePangoLineage filter', () => { + const query: DetailedMutationsQuery = { + type: 'detailedMutations', + nextcladePangoLineage: 'C.1', + }; + + const result = detailedMutationsToQuery(query); + + expect(result).toBe('nextcladePangoLineage=C.1'); + }); + + test('should combine lineage, mutations, and insertions', () => { + const query: DetailedMutationsQuery = { + type: 'detailedMutations', + pangoLineage: 'BA.2', + nucMutations: ['A123T'], + aaMutations: ['S:N501Y'], + nucInsertions: ['ins_22204:GAGCCAGAA'], + aaInsertions: ['ins_S:214:EPE'], + }; + + const result = detailedMutationsToQuery(query); + + expect(result).toBe('pangoLineage=BA.2 & A123T & S:N501Y & ins_22204:GAGCCAGAA & ins_S:214:EPE'); + }); + + test('should handle multiple mutations and both lineage types', () => { + const query: DetailedMutationsQuery = { + type: 'detailedMutations', + pangoLineage: 'BA.1', + nextcladePangoLineage: '21K', + aaMutations: ['S:L452R', 'S:T478K'], + }; + + const result = detailedMutationsToQuery(query); + + expect(result).toBe('pangoLineage=BA.1 & nextcladePangoLineage=21K & S:L452R & S:T478K'); + }); +}); diff --git a/website/src/covspectrum/variantConversionUtil.ts b/website/src/covspectrum/variantConversionUtil.ts new file mode 100644 index 000000000..372deb32c --- /dev/null +++ b/website/src/covspectrum/variantConversionUtil.ts @@ -0,0 +1,29 @@ +import type { DetailedMutationsQuery } from './types'; + +/** + * Converts a detailedMutations query to a LAPIS query string. + * Supports lineage filters, mutations, and insertions. + * Returns an empty string if the query is empty. + */ +export function detailedMutationsToQuery(query: DetailedMutationsQuery): string { + const parts: string[] = []; + + // Add lineage filters + if (query.pangoLineage) { + parts.push(`pangoLineage=${query.pangoLineage}`); + } + if (query.nextcladePangoLineage) { + parts.push(`nextcladePangoLineage=${query.nextcladePangoLineage}`); + } + + // Add mutations and insertions + parts.push( + ...(query.nucMutations ?? []), + ...(query.aaMutations ?? []), + ...(query.nucInsertions ?? []), + ...(query.aaInsertions ?? []), + ); + + // Join with AND logic (& in LAPIS query syntax), or empty string if no parts + return parts.join(' & '); +} diff --git a/website/src/pages/index.astro b/website/src/pages/index.astro index e88ef014a..120275ef4 100644 --- a/website/src/pages/index.astro +++ b/website/src/pages/index.astro @@ -48,13 +48,13 @@ import { Page } from '../types/pages'; >.
- *) This project is supported by the National Institute Of Allergy And Infectious Diseases of the - National Institutes of Health under Award Number U24AI183840. The content is solely the responsibility of the authors and does not necessarily represent the - official views of the National Institutes of Health. + >, awarded to the SIB Swiss Institute of Bioinformatics. The content is solely the responsibility of the + authors and does not necessarily represent the official views of the National Institutes of Health.
diff --git a/website/src/util/siloExpressionUtils.spec.ts b/website/src/util/siloExpressionUtils.spec.ts new file mode 100644 index 000000000..27a0506c3 --- /dev/null +++ b/website/src/util/siloExpressionUtils.spec.ts @@ -0,0 +1,373 @@ +import { describe, expect, test } from 'vitest'; + +import { validateGenomeOnly } from './siloExpressionUtils.ts'; +import type { SiloFilterExpression } from '../lapis/siloFilterExpression.ts'; + +describe('validateGenomeOnly', () => { + test('should validate simple nucleotide equals expression', () => { + const expression: SiloFilterExpression = { + type: 'NucleotideEquals', + sequenceName: 'main', + position: 123, + symbol: 'A', + }; + + const result = validateGenomeOnly(expression); + + expect(result.isGenomeOnly).toBe(true); + }); + + test('should validate amino acid equals expression', () => { + const expression: SiloFilterExpression = { + type: 'AminoAcidEquals', + sequenceName: 'S', + position: 484, + symbol: 'K', + }; + + const result = validateGenomeOnly(expression); + + expect(result.isGenomeOnly).toBe(true); + }); + + test('should validate has mutation expression', () => { + const expression: SiloFilterExpression = { + type: 'HasNucleotideMutation', + sequenceName: 'main', + position: 501, + }; + + const result = validateGenomeOnly(expression); + + expect(result.isGenomeOnly).toBe(true); + }); + + test('should validate insertion contains expression', () => { + const expression: SiloFilterExpression = { + type: 'InsertionContains', + position: 22204, + value: 'GAGCCAGAA', + sequenceName: 'main', + }; + + const result = validateGenomeOnly(expression); + + expect(result.isGenomeOnly).toBe(true); + }); + + test('should reject non-genome expression', () => { + const expression: SiloFilterExpression = { + type: 'StringEquals', + column: 'country', + value: 'USA', + }; + + const result = validateGenomeOnly(expression); + + expect(result.isGenomeOnly).toBe(false); + if (!result.isGenomeOnly) { + expect(result.error).toContain('StringEquals'); + } + }); + + test('should validate And expression with genome checks', () => { + const expression: SiloFilterExpression = { + type: 'And', + children: [ + { + type: 'NucleotideEquals', + sequenceName: 'main', + position: 123, + symbol: 'A', + }, + { + type: 'AminoAcidEquals', + sequenceName: 'S', + position: 484, + symbol: 'K', + }, + ], + }; + + const result = validateGenomeOnly(expression); + + expect(result.isGenomeOnly).toBe(true); + }); + + test('should validate Or expression with genome checks', () => { + const expression: SiloFilterExpression = { + type: 'Or', + children: [ + { + type: 'NucleotideEquals', + sequenceName: 'main', + position: 123, + symbol: 'A', + }, + { + type: 'NucleotideEquals', + sequenceName: 'main', + position: 456, + symbol: 'T', + }, + ], + }; + + const result = validateGenomeOnly(expression); + + expect(result.isGenomeOnly).toBe(true); + }); + + test('should validate Not expression with genome check', () => { + const expression: SiloFilterExpression = { + type: 'Not', + child: { + type: 'AminoAcidEquals', + sequenceName: 'S', + position: 484, + symbol: 'K', + }, + }; + + const result = validateGenomeOnly(expression); + + expect(result.isGenomeOnly).toBe(true); + }); + + test('should validate Maybe expression with genome check', () => { + const expression: SiloFilterExpression = { + type: 'Maybe', + child: { + type: 'HasNucleotideMutation', + sequenceName: 'main', + position: 501, + }, + }; + + const result = validateGenomeOnly(expression); + + expect(result.isGenomeOnly).toBe(true); + }); + + test('should validate N-Of expression with genome checks', () => { + const expression: SiloFilterExpression = { + type: 'N-Of', + numberOfMatchers: 2, + matchExactly: false, + children: [ + { + type: 'NucleotideEquals', + sequenceName: 'main', + position: 123, + symbol: 'A', + }, + { + type: 'AminoAcidEquals', + sequenceName: 'S', + position: 484, + symbol: 'K', + }, + { + type: 'InsertionContains', + position: 22204, + value: 'GAGCCAGAA', + sequenceName: 'main', + }, + ], + }; + + const result = validateGenomeOnly(expression); + + expect(result.isGenomeOnly).toBe(true); + }); + + test('should validate True expression', () => { + const expression: SiloFilterExpression = { + type: 'True', + }; + + const result = validateGenomeOnly(expression); + + expect(result.isGenomeOnly).toBe(true); + }); + + test('should reject Or expression with non-genome check', () => { + const expression: SiloFilterExpression = { + type: 'Or', + children: [ + { + type: 'NucleotideEquals', + sequenceName: 'main', + position: 123, + symbol: 'A', + }, + { + type: 'StringEquals', + column: 'country', + value: 'USA', + }, + ], + }; + + const result = validateGenomeOnly(expression); + + expect(result.isGenomeOnly).toBe(false); + if (!result.isGenomeOnly) { + expect(result.error).toContain('StringEquals'); + } + }); + + test('should reject Not expression with non-genome check', () => { + const expression: SiloFilterExpression = { + type: 'Not', + child: { + type: 'DateBetween', + column: 'date', + from: '2021-01-01', + to: '2021-12-31', + }, + }; + + const result = validateGenomeOnly(expression); + + expect(result.isGenomeOnly).toBe(false); + if (!result.isGenomeOnly) { + expect(result.error).toContain('DateBetween'); + } + }); + + test('should validate nested complex expression with only genome checks', () => { + const expression: SiloFilterExpression = { + type: 'And', + children: [ + { + type: 'Or', + children: [ + { + type: 'NucleotideEquals', + sequenceName: 'main', + position: 123, + symbol: 'A', + }, + { + type: 'NucleotideEquals', + sequenceName: 'main', + position: 123, + symbol: 'T', + }, + ], + }, + { + type: 'Maybe', + child: { + type: 'Not', + child: { + type: 'AminoAcidEquals', + sequenceName: 'S', + position: 484, + symbol: 'K', + }, + }, + }, + { + type: 'N-Of', + numberOfMatchers: 1, + matchExactly: false, + children: [ + { + type: 'InsertionContains', + position: 22204, + value: 'GAGCCAGAA', + sequenceName: 'main', + }, + { + type: 'HasAminoAcidMutation', + sequenceName: 'S', + position: 501, + }, + ], + }, + ], + }; + + const result = validateGenomeOnly(expression); + + expect(result.isGenomeOnly).toBe(true); + }); + + test('should reject nested complex expression with non-genome checks', () => { + const expression: SiloFilterExpression = { + type: 'And', + children: [ + { + type: 'NucleotideEquals', + sequenceName: 'main', + position: 123, + symbol: 'A', + }, + { + type: 'Or', + children: [ + { + type: 'AminoAcidEquals', + sequenceName: 'S', + position: 484, + symbol: 'K', + }, + { + type: 'StringEquals', + column: 'country', + value: 'USA', + }, + ], + }, + ], + }; + + const result = validateGenomeOnly(expression); + + expect(result.isGenomeOnly).toBe(false); + if (!result.isGenomeOnly) { + expect(result.error).toContain('StringEquals'); + } + }); + + test('should list multiple non-genome types in error', () => { + const expression: SiloFilterExpression = { + type: 'And', + children: [ + { + type: 'StringEquals', + column: 'country', + value: 'USA', + }, + { + type: 'DateBetween', + column: 'date', + from: '2021-01-01', + to: '2021-12-31', + }, + { + type: 'IntEquals', + column: 'age', + value: 42, + }, + { + type: 'NucleotideEquals', + sequenceName: 'main', + position: 123, + symbol: 'A', + }, + ], + }; + + const result = validateGenomeOnly(expression); + + expect(result.isGenomeOnly).toBe(false); + if (!result.isGenomeOnly) { + expect(result.error).toContain('StringEquals'); + expect(result.error).toContain('DateBetween'); + expect(result.error).toContain('IntEquals'); + } + }); +}); diff --git a/website/src/util/siloExpressionUtils.ts b/website/src/util/siloExpressionUtils.ts new file mode 100644 index 000000000..7c0881b9d --- /dev/null +++ b/website/src/util/siloExpressionUtils.ts @@ -0,0 +1,69 @@ +import type { SiloFilterExpression } from '../lapis/siloFilterExpression.ts'; + +/** + * Result of validating a SILO filter expression + */ +export type GenomeCheckResult = + | { + isGenomeOnly: true; + } + | { + isGenomeOnly: false; + error: string; + }; + +/** + * Set of expression types that are considered genome checks + */ +const GENOME_CHECK_TYPES = new Set([ + 'NucleotideEquals', + 'HasNucleotideMutation', + 'AminoAcidEquals', + 'HasAminoAcidMutation', + 'InsertionContains', + 'AminoAcidInsertionContains', +]); + +/** + * Traverses a SILO filter expression tree and validates that only genome checks are used. + * + * @param expression The SILO filter expression to traverse + * @returns Result containing validation status + */ +export function validateGenomeOnly(expression: SiloFilterExpression): GenomeCheckResult { + const nonGenomeTypes: string[] = []; + + function traverse(expr: SiloFilterExpression): void { + const { type } = expr; + + // Recursion + if (type === 'And' || type === 'Or' || type === 'N-Of') { + expr.children.forEach(traverse); + return; + } + if (type === 'Not' || type === 'Maybe') { + traverse(expr.child); + return; + } + + if (type === 'True' || GENOME_CHECK_TYPES.has(type)) { + return; // allowed query component, do nothing + } + + // If we reach here, it's not a genome check or logical operator + nonGenomeTypes.push(type); + } + + traverse(expression); + + if (nonGenomeTypes.length > 0) { + return { + isGenomeOnly: false, + error: `Expression contains non-genome check types: ${nonGenomeTypes.join(', ')}`, + }; + } + + return { + isGenomeOnly: true, + }; +} diff --git a/website/tests/CompareSideBySidePage.ts b/website/tests/CompareSideBySidePage.ts index bb53ddb41..f65d47fea 100644 --- a/website/tests/CompareSideBySidePage.ts +++ b/website/tests/CompareSideBySidePage.ts @@ -6,8 +6,8 @@ import { type OrganismWithViewKey } from '../src/views/routing'; import { compareSideBySideViewKey } from '../src/views/viewKeys'; export class CompareSideBySidePage extends ViewPage { - public readonly removeColumnButton = this.page.getByRole('link', { name: 'Remove column' }); - public readonly addColumnButton = this.page.getByRole('link', { name: 'Add column' }); + public readonly removeColumnButton = this.page.getByRole('button', { name: 'Remove column' }); + public readonly addColumnButton = this.page.getByRole('button', { name: 'Add column' }); public readonly mutationField = this.page.getByRole('combobox', { name: 'Enter a mutation', exact: false }); public async goto(organism: OrganismWithViewKey) {