diff --git a/build.gradle b/build.gradle index b59c9016479f..1cb102989859 100644 --- a/build.gradle +++ b/build.gradle @@ -15,16 +15,16 @@ plugins { id "idea" id "jacoco" id "org.springframework.boot" version "${spring_boot_version}" - id "io.spring.dependency-management" version "1.1.2" + id "io.spring.dependency-management" version "1.1.3" id "com.google.cloud.tools.jib" version "3.3.2" id "com.github.node-gradle.node" version "${gradle_node_plugin_version}" - id "com.diffplug.spotless" version "6.20.0" + id "com.diffplug.spotless" version "6.21.0" // this allows us to find outdated dependencies via ./gradlew dependencyUpdates - id "com.github.ben-manes.versions" version "0.47.0" + id "com.github.ben-manes.versions" version "0.48.0" id "com.github.andygoossens.modernizer" version "${modernizer_plugin_version}" id "com.gorylenko.gradle-git-properties" version "2.4.1" id "info.solidsoft.pitest" version "1.9.11" - id "org.owasp.dependencycheck" version "8.3.1" + id "org.owasp.dependencycheck" version "8.4.0" id "com.adarshr.test-logger" version "3.2.0" } @@ -122,7 +122,7 @@ tasks.register("testReport", TestReport) { } jacoco { - toolVersion = "0.8.8" + toolVersion = "0.8.10" } jar { @@ -263,15 +263,15 @@ dependencies { implementation "org.springdoc:springdoc-openapi-ui:1.7.0" implementation "com.vdurmont:semver4j:3.1.0" - implementation "com.github.docker-java:docker-java-core:3.3.2" - implementation "com.github.docker-java:docker-java-transport-httpclient5:3.3.2" + implementation "com.github.docker-java:docker-java-core:3.3.3" + implementation "com.github.docker-java:docker-java-transport-httpclient5:3.3.3" // import JHipster dependencies BOM implementation platform("tech.jhipster:jhipster-dependencies:${jhipster_dependencies_version}") implementation "tech.jhipster:jhipster-framework:${jhipster_dependencies_version}" implementation "org.springframework.boot:spring-boot-starter-cache:${spring_boot_version}" - implementation "io.micrometer:micrometer-registry-prometheus:1.11.2" + implementation "io.micrometer:micrometer-registry-prometheus:1.11.4" implementation "net.logstash.logback:logstash-logback-encoder:7.4" implementation "com.fasterxml.jackson.datatype:jackson-datatype-hppc:${fasterxml_version}" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${fasterxml_version}" @@ -288,7 +288,7 @@ dependencies { implementation "org.apache.commons:commons-math3:3.6.1" implementation "javax.transaction:javax.transaction-api:1.3" implementation "org.hibernate:hibernate-entitymanager:${hibernate_version}" - implementation "org.liquibase:liquibase-core:4.23.0" + implementation "org.liquibase:liquibase-core:4.23.2" implementation "org.springframework.boot:spring-boot-starter-validation:${spring_boot_version}" implementation "org.springframework.boot:spring-boot-loader-tools:${spring_boot_version}" implementation "org.springframework.boot:spring-boot-starter-mail:${spring_boot_version}" @@ -305,16 +305,16 @@ dependencies { implementation "org.springframework.boot:spring-boot-starter-thymeleaf:${spring_boot_version}" implementation "org.springframework.ldap:spring-ldap-core:2.4.1" - implementation "org.springframework.data:spring-data-ldap:2.7.14" + implementation "org.springframework.data:spring-data-ldap:2.7.15" implementation "org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:3.1.7" implementation "org.springframework.cloud:spring-cloud-starter-config:3.1.8" implementation "org.springframework.boot:spring-boot-starter-cloud-connectors:2.2.13.RELEASE" - implementation "io.netty:netty-all:4.1.96.Final" - implementation "io.projectreactor.netty:reactor-netty:1.1.9" + implementation "io.netty:netty-all:4.1.97.Final" + implementation "io.projectreactor.netty:reactor-netty:1.1.11" implementation "org.springframework:spring-messaging:5.3.29" - implementation "org.springframework.retry:spring-retry:2.0.2" + implementation "org.springframework.retry:spring-retry:2.0.3" implementation "org.springframework.security:spring-security-config:${spring_security_version}" implementation "org.springframework.security:spring-security-data:${spring_security_version}" @@ -333,15 +333,15 @@ dependencies { implementation "io.springfox:springfox-bean-validators:3.0.0" implementation "mysql:mysql-connector-java:8.0.33" implementation "org.postgresql:postgresql:42.6.0" - implementation "com.h2database:h2:2.2.220" + implementation "com.h2database:h2:2.2.222" // zalando problem spring web can only be updated when we support Spring 6 implementation "org.zalando:problem-spring-web:0.27.0" implementation "com.ibm.icu:icu4j:73.2" implementation "com.github.seancfoley:ipaddress:5.4.0" - implementation "org.apache.maven:maven-model:3.9.3" - implementation "org.apache.pdfbox:pdfbox:2.0.29" - implementation "com.google.protobuf:protobuf-java:3.23.4" + implementation "org.apache.maven:maven-model:3.9.4" + implementation "org.apache.pdfbox:pdfbox:3.0.0" + implementation "com.google.protobuf:protobuf-java:3.24.3" implementation "org.apache.commons:commons-csv:1.10.0" implementation "org.commonmark:commonmark:0.21.0" implementation "commons-fileupload:commons-fileupload:1.5" @@ -366,14 +366,14 @@ dependencies { testImplementation "org.junit.jupiter:junit-jupiter:${junit_version}" testImplementation "org.mockito:mockito-core:${mockito_version}" testImplementation "org.mockito:mockito-junit-jupiter:${mockito_version}" - testImplementation "io.github.classgraph:classgraph:4.8.161" + testImplementation "io.github.classgraph:classgraph:4.8.162" testImplementation "org.awaitility:awaitility:4.2.0" testImplementation "org.apache.maven.shared:maven-invoker:3.2.0" - testImplementation "org.gradle:gradle-tooling-api:8.2.1" + testImplementation "org.gradle:gradle-tooling-api:8.3" testImplementation "org.apache.maven.surefire:surefire-report-parser:3.1.2" testImplementation "com.opencsv:opencsv:5.8" testImplementation "io.zonky.test:embedded-database-spring-test:2.3.0" - testImplementation "com.tngtech.archunit:archunit:1.0.1" + testImplementation "com.tngtech.archunit:archunit:1.1.0" testImplementation "org.skyscreamer:jsonassert:1.5.1" // Lightweight JSON library needed for the internals of the MockRestServiceServer @@ -417,7 +417,7 @@ tasks.withType(Test).configureEach { } wrapper { - gradleVersion = "8.2.1" + gradleVersion = "8.3" } tasks.register("stage") { diff --git a/gradle.properties b/gradle.properties index f78ac154d0fc..a3781fb28016 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,22 +7,22 @@ npm_version=9.6.0 # Dependency versions jhipster_dependencies_version=7.9.3 -spring_boot_version=2.7.14 +spring_boot_version=2.7.15 spring_security_version=5.7.10 hibernate_version=5.6.15.Final jaxb_runtime_version=4.0.3 -hazelcast_version=5.3.1 +hazelcast_version=5.3.2 junit_version=5.10.0 -mockito_version=5.4.0 +mockito_version=5.5.0 fasterxml_version=2.15.2 -jgit_version=6.6.0.202305301015-r -checkstyle_version=10.12.1 +jgit_version=6.7.0.202309050840-r +checkstyle_version=10.12.3 jplag_version=4.3.0 slf4j_version=1.7.36 -sentry_version=6.27.0 +sentry_version=6.29.0 # gradle plugin version -gradle_node_plugin_version=5.0.0 +gradle_node_plugin_version=7.0.0 apt_plugin_version=0.21 liquibase_plugin_version=2.1.1 modernizer_plugin_version=1.8.0 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9f4197d5f4b9..ac72c34e8acc 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/package-lock.json b/package-lock.json index 6ce1f04ecd2a..3ffa9dda7921 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,18 +10,18 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { - "@angular/animations": "16.2.3", - "@angular/cdk": "16.2.2", - "@angular/common": "16.2.3", - "@angular/compiler": "16.2.3", - "@angular/core": "16.2.3", - "@angular/forms": "16.2.3", - "@angular/localize": "16.2.3", - "@angular/material": "16.2.2", - "@angular/platform-browser": "16.2.3", - "@angular/platform-browser-dynamic": "16.2.3", - "@angular/router": "16.2.3", - "@angular/service-worker": "16.2.3", + "@angular/animations": "16.2.5", + "@angular/cdk": "16.2.4", + "@angular/common": "16.2.5", + "@angular/compiler": "16.2.5", + "@angular/core": "16.2.5", + "@angular/forms": "16.2.5", + "@angular/localize": "16.2.5", + "@angular/material": "16.2.4", + "@angular/platform-browser": "16.2.5", + "@angular/platform-browser-dynamic": "16.2.5", + "@angular/router": "16.2.5", + "@angular/service-worker": "16.2.5", "@ctrl/ngx-emoji-mart": "9.2.0", "@danielmoncada/angular-datetime-picker": "16.0.1", "@fingerprintjs/fingerprintjs": "4.0.1", @@ -34,16 +34,16 @@ "@ng-bootstrap/ng-bootstrap": "15.1.1", "@ngx-translate/core": "15.0.0", "@ngx-translate/http-loader": "8.0.0", - "@sentry/angular-ivy": "7.66.0", - "@sentry/tracing": "7.66.0", - "@sentry/types": "7.66.0", + "@sentry/angular-ivy": "7.69.0", + "@sentry/tracing": "7.69.0", + "@sentry/types": "7.69.0", "@swimlane/ngx-charts": "20.4.1", "@swimlane/ngx-graph": "8.2.2", - "ace-builds": "1.24.1", + "ace-builds": "1.25.1", "bootstrap": "5.3.1", "brace": "0.11.1", "compare-versions": "6.1.0", - "core-js": "3.32.1", + "core-js": "3.32.2", "crypto-js": "4.1.1", "dayjs": "1.11.9", "diff-match-patch-typescript": "1.0.8", @@ -70,37 +70,37 @@ "split.js": "1.6.5", "ts-cacheable": "1.0.9", "tslib": "2.6.2", - "uuid": "9.0.0", + "uuid": "9.0.1", "webstomp-client": "1.2.6", "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.0/xlsx-0.20.0.tgz", "zone.js": "0.13.0" }, "devDependencies": { "@angular-builders/jest": "16.0.1", - "@angular-eslint/builder": "16.1.1", - "@angular-eslint/eslint-plugin": "16.1.1", - "@angular-eslint/eslint-plugin-template": "16.1.1", - "@angular-eslint/schematics": "16.1.1", - "@angular-eslint/template-parser": "16.1.1", - "@angular/cli": "16.2.1", - "@angular/compiler-cli": "16.2.3", - "@angular/language-service": "16.2.3", - "@types/crypto-js": "4.1.1", + "@angular-eslint/builder": "16.1.2", + "@angular-eslint/eslint-plugin": "16.1.2", + "@angular-eslint/eslint-plugin-template": "16.1.2", + "@angular-eslint/schematics": "16.1.2", + "@angular-eslint/template-parser": "16.1.2", + "@angular/cli": "16.2.2", + "@angular/compiler-cli": "16.2.5", + "@angular/language-service": "16.2.5", + "@types/crypto-js": "4.1.2", "@types/d3-shape": "3.1.2", "@types/dompurify": "3.0.2", "@types/jest": "29.5.4", "@types/lodash-es": "4.17.9", - "@types/node": "20.5.7", + "@types/node": "20.6.0", "@types/papaparse": "5.3.8", "@types/showdown": "2.0.1", "@types/smoothscroll-polyfill": "0.3.1", "@types/sockjs-client": "1.5.1", "@types/uuid": "9.0.3", - "@typescript-eslint/eslint-plugin": "6.5.0", - "@typescript-eslint/parser": "6.5.0", - "eslint": "8.48.0", + "@typescript-eslint/eslint-plugin": "6.7.0", + "@typescript-eslint/parser": "6.7.0", + "eslint": "8.49.0", "eslint-config-prettier": "9.0.0", - "eslint-plugin-deprecation": "1.5.0", + "eslint-plugin-deprecation": "2.0.0", "eslint-plugin-jest": "27.2.3", "eslint-plugin-jest-extended": "2.0.0", "eslint-plugin-prettier": "5.0.0", @@ -116,7 +116,7 @@ "lint-staged": "14.0.1", "ng-mocks": "14.11.0", "prettier": "3.0.3", - "sass": "1.66.1", + "sass": "1.67.0", "ts-jest": "29.1.1", "typescript": "5.1.6", "weak-napi": "2.0.2", @@ -381,12 +381,12 @@ } }, "node_modules/@angular-devkit/schematics": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.2.1.tgz", - "integrity": "sha512-rXXO5zSI/iN6JtU3oU+vKfOB1N8n1iCH9aLudtJfO5zT9r29FIvV4YMmHO0iu78i4IhQAeJdr42cvrGPp8Y41A==", + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.2.2.tgz", + "integrity": "sha512-KeXIlibVrQEwIKbR9GViLKc3m1SXi/xuSXgIvSv+22FNu5i91ScsAhYLe65sDUL6m6MM1XQQMS46XN1Z9bRqQw==", "dev": true, "dependencies": { - "@angular-devkit/core": "16.2.1", + "@angular-devkit/core": "16.2.2", "jsonc-parser": "3.2.0", "magic-string": "0.30.1", "ora": "5.4.1", @@ -398,10 +398,37 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.2.tgz", + "integrity": "sha512-6H4FsvP3rLJaGiWpIhCFPS7ZeNoM4sSrnFtRhhecu6s7MidzE4aqzuGdzJpzLammw1KL+DuTlN0gpLtM1Bvcwg==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "2.3.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, "node_modules/@angular-eslint/builder": { - "version": "16.1.1", - "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-16.1.1.tgz", - "integrity": "sha512-NaB/A0mmlzp7laiucRUsRyoCrOE1In3UifsGP0vD6yjUpefk4g0v+0vCg8mhsIky8gYDtBE9YRfUiLA9FlF/FA==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-16.1.2.tgz", + "integrity": "sha512-Y95IBEWqzWA7SyIh5nlPuFasw/4lOILrAdY5Ji6tOpIJgNFoiR9K1UcH46i34r3384ApN8GEQJ7FlK6D6qCOJA==", "dev": true, "dependencies": { "@nx/devkit": "16.5.1", @@ -413,18 +440,18 @@ } }, "node_modules/@angular-eslint/bundled-angular-compiler": { - "version": "16.1.1", - "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-16.1.1.tgz", - "integrity": "sha512-TB01AWZBDfrZBxN1I50HfBXtC7q4NI5fwl1aS4tOfef2/kQjTtR9zmha8CsxjDkAOa9tA/4MUayAMqEBQLuHKQ==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-16.1.2.tgz", + "integrity": "sha512-wDiHPFsKTijMcQUPNcoHOJ5kezIPCCbmDK6LHH7hAdAC/eDY9NHL5e4zQ2Xkf3/r1PFuwVLGTwwreEHlmeENDw==", "dev": true }, "node_modules/@angular-eslint/eslint-plugin": { - "version": "16.1.1", - "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-16.1.1.tgz", - "integrity": "sha512-GauEwFGEcgIdsld4cVarFJYYxaRbMLzbpxyvBUDFg4LNjlcQNt7zfqXRLJoZAaFJFPtGtAoo1+6BlEKErsntuQ==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-16.1.2.tgz", + "integrity": "sha512-lYVvoKUIOg/ez15yfN4zY2A++vnIeJe1xh2ADNTmmjSh2PFV24K9YOgrTbgrY3Ul9kzGDTBkvYqslq+IvMGdIw==", "dev": true, "dependencies": { - "@angular-eslint/utils": "16.1.1", + "@angular-eslint/utils": "16.1.2", "@typescript-eslint/utils": "5.62.0" }, "peerDependencies": { @@ -433,13 +460,13 @@ } }, "node_modules/@angular-eslint/eslint-plugin-template": { - "version": "16.1.1", - "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-16.1.1.tgz", - "integrity": "sha512-hwbpiUxLIY3TnZycieh+G4fbTWGMfzKx076O5Vuh2H4ZfXfs6ZXoi3Z0TH6X9lTmdgrwzOg1v4o5kdqu7MqPBg==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-16.1.2.tgz", + "integrity": "sha512-2qsoUgPg9Qp4EVUJRwWcJ+8JMxBb0ma3pNBjFmY6LOd59igRYorJKfWep4Nln1EicYRDRsCLzeLHO976+b1yaQ==", "dev": true, "dependencies": { - "@angular-eslint/bundled-angular-compiler": "16.1.1", - "@angular-eslint/utils": "16.1.1", + "@angular-eslint/bundled-angular-compiler": "16.1.2", + "@angular-eslint/utils": "16.1.2", "@typescript-eslint/type-utils": "5.62.0", "@typescript-eslint/utils": "5.62.0", "aria-query": "5.3.0", @@ -451,13 +478,13 @@ } }, "node_modules/@angular-eslint/schematics": { - "version": "16.1.1", - "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-16.1.1.tgz", - "integrity": "sha512-KlR01gpURPjz5OcoEvmKv3zi8l6lFpXYmqkXbGMCz828QlqBz1X7iGLAPJki+WUFSFKbRsf4qqaWq6O/8vph7Q==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-16.1.2.tgz", + "integrity": "sha512-319i47NU6nfaAaQTQYN7k320proTIBCueWGt+fbT11210CMqQriFmD+B85AatCwQgMgLd8Rhs1/F7YL2OOhegA==", "dev": true, "dependencies": { - "@angular-eslint/eslint-plugin": "16.1.1", - "@angular-eslint/eslint-plugin-template": "16.1.1", + "@angular-eslint/eslint-plugin": "16.1.2", + "@angular-eslint/eslint-plugin-template": "16.1.2", "@nx/devkit": "16.5.1", "ignore": "5.2.4", "nx": "16.5.1", @@ -469,12 +496,12 @@ } }, "node_modules/@angular-eslint/template-parser": { - "version": "16.1.1", - "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-16.1.1.tgz", - "integrity": "sha512-ZJ+M4+JGYcsIP/t+XiuzL5A5pCjjCen272U3/M/WqIMDDxyIKrHubK1bVtr2kndCEudqud+WyJU0ub13UIwGgw==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-16.1.2.tgz", + "integrity": "sha512-vIkPOShVJLBEHYY3jISCVvJF3lXL//Y70J8T9lY2CBowgqp6AzzJ6cZU7JxrORN6b64rBUVvUtCGo8L36GvfuA==", "dev": true, "dependencies": { - "@angular-eslint/bundled-angular-compiler": "16.1.1", + "@angular-eslint/bundled-angular-compiler": "16.1.2", "eslint-scope": "^7.0.0" }, "peerDependencies": { @@ -483,12 +510,12 @@ } }, "node_modules/@angular-eslint/utils": { - "version": "16.1.1", - "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-16.1.1.tgz", - "integrity": "sha512-cmSTyFFY2TMLjhKdju0KQ9GB6nnXt1AbY9tZ0UtWGo3NKbrBUogc+PR9ma17VRAGhvdj/sSVkStphJH3F7rUgQ==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-16.1.2.tgz", + "integrity": "sha512-2yfEK3BPSJsUhP4JCz0EB6ktu4E4+/zc9qdtZvPWNF/eww2J/oYVPjY47C/HVg4MXpjJTI8vbdkvcnxrICIkfw==", "dev": true, "dependencies": { - "@angular-eslint/bundled-angular-compiler": "16.1.1", + "@angular-eslint/bundled-angular-compiler": "16.1.2", "@typescript-eslint/utils": "5.62.0" }, "peerDependencies": { @@ -497,9 +524,9 @@ } }, "node_modules/@angular/animations": { - "version": "16.2.3", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-16.2.3.tgz", - "integrity": "sha512-MEjCWjN7RcHNFHkDYB3ZvEQqt94EzwevVXfld6rcOZNwJxcOVyi7+nQQ1YhWLPSW81HF76bpwD3RWWhZpKdXQQ==", + "version": "16.2.5", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-16.2.5.tgz", + "integrity": "sha512-2reD50S9zWvhewRvwl320iuRICN9s0fI+3nKULlwcyJ0praLRhJ1SnaAK3NEEu7MWo3n9sb3iVTzA6S9qZRJ4g==", "dependencies": { "tslib": "^2.3.0" }, @@ -507,13 +534,13 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/core": "16.2.3" + "@angular/core": "16.2.5" } }, "node_modules/@angular/cdk": { - "version": "16.2.2", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-16.2.2.tgz", - "integrity": "sha512-luUmeIFuEX4N3EOLhg1DM2hgsR+Is1Qd0a5xflbo30hZFnufppyzjaOvljNYUFtNTD9BaQRXaZDFA2cyTgfzZw==", + "version": "16.2.4", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-16.2.4.tgz", + "integrity": "sha512-Hnh7Gs+gAkBnRYIMkDXRElEPAmBFas37isIfOtiqEmkgmSPFxsPpDOXK1soXeDk8U+yNmDWnO0fcHPp/pobHCw==", "dependencies": { "tslib": "^2.3.0" }, @@ -527,15 +554,15 @@ } }, "node_modules/@angular/cli": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-16.2.1.tgz", - "integrity": "sha512-nuCc0VOGjuUFQo1Pu9CyFQ4VTy7OuwTiwxOG9qbut4FSGz2CO9NeqoamPUuy6rpKVu5JxVe+L6Y4OFaNKv2n3Q==", + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-16.2.2.tgz", + "integrity": "sha512-PmhR/NMVVCiATXxHLkVCV781Q5aa5DaYye9+plZGX3rdKTilEunRNIfT13w7IuRfa0K/pKZj6PJU1S6yb7sqZg==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1602.1", - "@angular-devkit/core": "16.2.1", - "@angular-devkit/schematics": "16.2.1", - "@schematics/angular": "16.2.1", + "@angular-devkit/architect": "0.1602.2", + "@angular-devkit/core": "16.2.2", + "@angular-devkit/schematics": "16.2.2", + "@schematics/angular": "16.2.2", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.3", "ini": "4.1.1", @@ -560,10 +587,52 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@angular/cli/node_modules/@angular-devkit/architect": { + "version": "0.1602.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1602.2.tgz", + "integrity": "sha512-JFIeKKW7V2+/C8+pTReM6gfQkVU9l1IR1OCb9vvHWTRvuTr7E5h2L1rUInnmLiRWkEvkYfG29B+UPpYlkVl9oQ==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "16.2.2", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/cli/node_modules/@angular-devkit/core": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.2.tgz", + "integrity": "sha512-6H4FsvP3rLJaGiWpIhCFPS7ZeNoM4sSrnFtRhhecu6s7MidzE4aqzuGdzJpzLammw1KL+DuTlN0gpLtM1Bvcwg==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "2.3.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, "node_modules/@angular/common": { - "version": "16.2.3", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-16.2.3.tgz", - "integrity": "sha512-hOC2yqISBRAzltuVJQ3CEJxHRp9mWggysp0or5HydbcmvB6WIroECL7U0u36VA95zC9SXnymHA13OwiFPpmahA==", + "version": "16.2.5", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-16.2.5.tgz", + "integrity": "sha512-MCPSZfPXTEqdkswPczivwjqV117YeVjObtyxZsDAwrTZHzYBtfQreQG1XJ1IRRgDncznP6ke0mdH9LyD2LgZKQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -571,14 +640,14 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/core": "16.2.3", + "@angular/core": "16.2.5", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "16.2.3", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-16.2.3.tgz", - "integrity": "sha512-bFc7YRHNdBJZD2HiORBQun2p40emvEt8D4JwXnW1JIStAWKJOXLyEjx045wNddqH7NpUq8AE2F1i82hIDNQZ1g==", + "version": "16.2.5", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-16.2.5.tgz", + "integrity": "sha512-DpLfWWZFk4lbr81W7sLRt15+/nbyyqTvz+UmGcrSfKBTSbV0VSoUjC3XZeIdPWoIgQXiKUCpaC0YXw0BjaOl0g==", "dependencies": { "tslib": "^2.3.0" }, @@ -586,7 +655,7 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/core": "16.2.3" + "@angular/core": "16.2.5" }, "peerDependenciesMeta": { "@angular/core": { @@ -595,9 +664,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "16.2.3", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-16.2.3.tgz", - "integrity": "sha512-4p1tDeeONiq/zceC0T6unXDuqyWiAe7v2Ag7+ewwM9V8BF+YOEpEI/41lxzmbK2U1YUvG3jWfZyw3ertQlMp0Q==", + "version": "16.2.5", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-16.2.5.tgz", + "integrity": "sha512-6TtyFxro4iukVXhLlzxz7sVCMfAlNQhSYnizIJRSW31uQ0Uku8rjlUmX1tCAmhW6CacLumiz2tcy04Xn/QFWyw==", "dependencies": { "@babel/core": "7.22.5", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -617,7 +686,7 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/compiler": "16.2.3", + "@angular/compiler": "16.2.5", "typescript": ">=4.9.3 <5.2" } }, @@ -651,9 +720,9 @@ } }, "node_modules/@angular/core": { - "version": "16.2.3", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-16.2.3.tgz", - "integrity": "sha512-YCzm7Rd2l0Ti0dZ1Mw3OfoQqlLolDN6jBEPy9Ah1s/KB+jKwNK9An3g8A9H6/jQIFwHCtxRad3LYH5ftknNMBQ==", + "version": "16.2.5", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-16.2.5.tgz", + "integrity": "sha512-Po2LMUnPg23D2qI7EYaoA4x3lRswx9nxfpwROzfFPbMNJ3JVbTK0HkTD2dFPGxRua2UjfJTb1um23tEGO4OGMQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -666,9 +735,9 @@ } }, "node_modules/@angular/forms": { - "version": "16.2.3", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-16.2.3.tgz", - "integrity": "sha512-d2ELs3PU4o1Yb89w4X3trD3CFWrDUsuFKs1hyNSYPWqCmcQ+tAfr9mizYPTVPSvee/RPRBqDEa0YTzfVpOvX4Q==", + "version": "16.2.5", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-16.2.5.tgz", + "integrity": "sha512-iYJImRji1OiYIcC2mDBcXhtvPfAoEGT+HqZpivu+/ZPLuf+QegC9+ktJw90SQXR+xccmpkUb9MsJ52SN2MgkPA==", "dependencies": { "tslib": "^2.3.0" }, @@ -676,25 +745,25 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "16.2.3", - "@angular/core": "16.2.3", - "@angular/platform-browser": "16.2.3", + "@angular/common": "16.2.5", + "@angular/core": "16.2.5", + "@angular/platform-browser": "16.2.5", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/language-service": { - "version": "16.2.3", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-16.2.3.tgz", - "integrity": "sha512-AFBq643tXGSoBUFNd0c1vJzReehtrqUZCzCRV3Gv5FNgb5xTfNdh3txIK4Cz/XhdSou+f2Yq6keFDlj2RYnlmA==", + "version": "16.2.5", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-16.2.5.tgz", + "integrity": "sha512-lYNRN4+iavDuAs86lRHuiTUxtVtsarCZPeoG6K1TEvrXrvmIbTtAbvONNMMnteO9ltCTduyREF9/sefE2Qw/Rg==", "dev": true, "engines": { "node": "^16.14.0 || >=18.10.0" } }, "node_modules/@angular/localize": { - "version": "16.2.3", - "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-16.2.3.tgz", - "integrity": "sha512-8dw4Vf3lqwQK4RBzBjYVNNoXlMJAyEF3pREqQo5aWcGTbBOAwM7SQuRQfxM8yjZZaXcKQEv/XJfEym5UVzGaUw==", + "version": "16.2.5", + "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-16.2.5.tgz", + "integrity": "sha512-vDtrBlbWOqtATqaBv3gmxBT0e8TfxwW+4J47S8u5Pbi1ZAnQfDkD9MNivC6/CAifFMcxN1pH8NALwLXOUga1PA==", "dependencies": { "@babel/core": "7.22.5", "fast-glob": "3.3.0", @@ -709,8 +778,8 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/compiler": "16.2.3", - "@angular/compiler-cli": "16.2.3" + "@angular/compiler": "16.2.5", + "@angular/compiler-cli": "16.2.5" } }, "node_modules/@angular/localize/node_modules/@babel/core": { @@ -758,9 +827,9 @@ } }, "node_modules/@angular/material": { - "version": "16.2.2", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-16.2.2.tgz", - "integrity": "sha512-0SaBPZsZ1jxq5yJeey+V2k7nq1Izw63fjxkyLx7rCcdowwwoBnG/dZsY97/5Qs2cZX0J+Z0iNpMYVJZd72GsvQ==", + "version": "16.2.4", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-16.2.4.tgz", + "integrity": "sha512-TIZ/0MKObn5YU9n/VReghJJKqgkqyzrWVNEJ8UgOP6MV5o+kAbqLSmlDJEyjLIwJF0vPnJ3UP6qbEOfEi1OLaA==", "dependencies": { "@material/animation": "15.0.0-canary.bc9ae6c9c.0", "@material/auto-init": "15.0.0-canary.bc9ae6c9c.0", @@ -813,7 +882,7 @@ }, "peerDependencies": { "@angular/animations": "^16.0.0 || ^17.0.0", - "@angular/cdk": "16.2.2", + "@angular/cdk": "16.2.4", "@angular/common": "^16.0.0 || ^17.0.0", "@angular/core": "^16.0.0 || ^17.0.0", "@angular/forms": "^16.0.0 || ^17.0.0", @@ -822,9 +891,9 @@ } }, "node_modules/@angular/platform-browser": { - "version": "16.2.3", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-16.2.3.tgz", - "integrity": "sha512-adWINGgjIMxwbWJhkMwpEfb4FRFMda5X6ahxWQX2E03Nl0kzePI6cvlJqAgp+iBwTkieWeU8BThJk2/rMkS3bw==", + "version": "16.2.5", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-16.2.5.tgz", + "integrity": "sha512-p+1GH/M4Vwoyp7brKkNBcMTxscoZxA1zehetFlNr8kArXWiISgPolyqOVzvT6cycYKu5uSRLnvHOTDss6xrAuA==", "dependencies": { "tslib": "^2.3.0" }, @@ -832,9 +901,9 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/animations": "16.2.3", - "@angular/common": "16.2.3", - "@angular/core": "16.2.3" + "@angular/animations": "16.2.5", + "@angular/common": "16.2.5", + "@angular/core": "16.2.5" }, "peerDependenciesMeta": { "@angular/animations": { @@ -843,9 +912,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "16.2.3", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-16.2.3.tgz", - "integrity": "sha512-Y3cYob1VGzT1xSMbuLGVxPlyuhv4zshYEo/yy2626YD63DigqYwGzj+gT0JoU1eNuXw2UWp3R67d9F8SC015Jw==", + "version": "16.2.5", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-16.2.5.tgz", + "integrity": "sha512-kzC4z/KmLss8Du9uM1Q16r+3EqDExKKHnrb3G3tuEQ1jTvYCysdWoooVSBmtIlQUw13znpBm1B7XLoyviFvnwA==", "dependencies": { "tslib": "^2.3.0" }, @@ -853,16 +922,16 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "16.2.3", - "@angular/compiler": "16.2.3", - "@angular/core": "16.2.3", - "@angular/platform-browser": "16.2.3" + "@angular/common": "16.2.5", + "@angular/compiler": "16.2.5", + "@angular/core": "16.2.5", + "@angular/platform-browser": "16.2.5" } }, "node_modules/@angular/router": { - "version": "16.2.3", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-16.2.3.tgz", - "integrity": "sha512-xjF5v6BzXanPB0VoIxeKXg1DO95nKJ9UjTsmB5ZOufDcqQXE81NAnH7iEKOymvU7aacqrgD467vcDtGNWJdfQQ==", + "version": "16.2.5", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-16.2.5.tgz", + "integrity": "sha512-5IXhe6G7zYFUwHSfUgPw+I/q6M1AcfSyaOVcjMFQ94bVSWEMq5KrGCDc8HQtkdw7GqJ4txwbyQKSKp7khpqShQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -870,16 +939,16 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "16.2.3", - "@angular/core": "16.2.3", - "@angular/platform-browser": "16.2.3", + "@angular/common": "16.2.5", + "@angular/core": "16.2.5", + "@angular/platform-browser": "16.2.5", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/service-worker": { - "version": "16.2.3", - "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-16.2.3.tgz", - "integrity": "sha512-CKBtxA7oHbozP22hD15ZdGeh4Wl4BqNRG93O1RI74zEY2Nq0UgDc/rDkEtfe0bGWLBhU+q5q/6M+DPSy6erqzA==", + "version": "16.2.5", + "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-16.2.5.tgz", + "integrity": "sha512-rHSFkrzyOunWwAQNtTC01ry2inrutlCad8MChK+fHCAhD2maWbNHtIelXR5ylojx7EyTUY0TPL30D60z2mXbwA==", "dependencies": { "tslib": "^2.3.0" }, @@ -890,8 +959,8 @@ "node": "^16.14.0 || >=18.10.0" }, "peerDependencies": { - "@angular/common": "16.2.3", - "@angular/core": "16.2.3" + "@angular/common": "16.2.5", + "@angular/core": "16.2.5" } }, "node_modules/@assemblyscript/loader": { @@ -976,25 +1045,25 @@ } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.10.tgz", - "integrity": "sha512-Av0qubwDQxC56DoUReVDeLfMEjYYSN1nZrTUrWkXd7hpU73ymRANkbuDm3yni9npkn+RXy9nNbEJZEzXr7xrfQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.22.10" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz", - "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", "dependencies": { "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", "browserslist": "^4.21.9", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -1004,16 +1073,16 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.11.tgz", - "integrity": "sha512-y1grdYL4WzmUDBRGK0pDbIoFd7UZKoDurDzWEoNMYoj1EL+foGRQNyPWDcC+YyegN5y1DUsFFmzjGijB3nSVAQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", + "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", "dev": true, "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-function-name": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-replace-supers": "^7.22.9", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", @@ -1028,9 +1097,9 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz", - "integrity": "sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", "dev": true, "peer": true, "dependencies": { @@ -1094,39 +1163,39 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz", - "integrity": "sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.15.tgz", + "integrity": "sha512-qLNsZbgrNh0fDQBCPocSL8guki1hcPvltGDv/NxvUoABwFq7GkKSu1nRXeJkVZc+wJvne2E0RKQz+2SQrz6eAA==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", - "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.17.tgz", + "integrity": "sha512-XouDDhQESrLHTpnBtCKExJdyY4gJCdrvH2Pyv8r8kovX2U8G0dRUOT45T9XlbLtuu9CLXP15eusnkprhoPV5iQ==", "dependencies": { "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", "@babel/helper-simple-access": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.5" + "@babel/helper-validator-identifier": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -1157,15 +1226,15 @@ } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz", - "integrity": "sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.17.tgz", + "integrity": "sha512-bxH77R5gjH3Nkde6/LuncQoLaP16THYPscurp1S8z7S9ZgezCyV3G8Hc+TZiCmY8pz4fp8CvKSgtJMW0FkLAxA==", "dev": true, "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-wrap-function": "^7.22.9" + "@babel/helper-wrap-function": "^7.22.17" }, "engines": { "node": ">=6.9.0" @@ -1236,44 +1305,72 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", + "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.10.tgz", - "integrity": "sha512-OnMhjWjuGYtdoO3FmsEFWvBStBAe2QOgwOLsLNDjN+aaiMD8InJk1/O3HSD8lkqTjCgg5YI34Tz15KNNA3p+nQ==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.17.tgz", + "integrity": "sha512-nAhoheCMlrqU41tAojw9GpVEKDlTS8r3lzFmF0lP52LwblCPbuFSO7nGIZoIcoU5NIm1ABrna0cJExE4Ay6l2Q==", "dev": true, "peer": true, "dependencies": { "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.10" + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.17" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function/node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.11.tgz", - "integrity": "sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.15.tgz", + "integrity": "sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==", "dependencies": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.11", - "@babel/types": "^7.22.11" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -1293,9 +1390,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.14", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.14.tgz", - "integrity": "sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ==", + "version": "7.22.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", + "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", "bin": { "parser": "bin/babel-parser.js" }, @@ -1304,9 +1401,9 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz", - "integrity": "sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz", + "integrity": "sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==", "dev": true, "peer": true, "dependencies": { @@ -1320,15 +1417,15 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz", - "integrity": "sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz", + "integrity": "sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==", "dev": true, "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.22.5" + "@babel/plugin-transform-optional-chaining": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -1341,6 +1438,7 @@ "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead.", "dev": true, "peer": true, "dependencies": { @@ -1373,6 +1471,7 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead.", "dev": true, "peer": true, "dependencies": { @@ -1686,9 +1785,9 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.11.tgz", - "integrity": "sha512-0pAlmeRJn6wU84zzZsEOx1JV1Jf8fqO9ok7wofIJwUnplYo247dcd24P+cMJht7ts9xkzdtB0EPHmOb7F+KzXw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.15.tgz", + "integrity": "sha512-jBm1Es25Y+tVoTi5rfd5t1KLmL8ogLKpXszboWOTTtGFGz2RKnQe2yn7HbZ+kb/B8N0FVSGQo874NSlOU1T4+w==", "dev": true, "peer": true, "dependencies": { @@ -1739,9 +1838,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.10.tgz", - "integrity": "sha512-1+kVpGAOOI1Albt6Vse7c8pHzcZQdQKW+wJH+g8mCaszOdDVwRXa/slHPqIw+oJAJANTKDMuM2cBdV0Dg618Vg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.15.tgz", + "integrity": "sha512-G1czpdJBZCtngoK1sJgloLiOHUnkb/bLZwqVZD8kXmq0ZnVfTTWUcs9OWtp0mBtYJ+4LQY1fllqBkOIPhXmFmw==", "dev": true, "peer": true, "dependencies": { @@ -1790,19 +1889,19 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz", - "integrity": "sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz", + "integrity": "sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==", "dev": true, "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-function-name": "^7.22.5", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", "@babel/helper-split-export-declaration": "^7.22.6", "globals": "^11.1.0" }, @@ -1831,9 +1930,9 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.10.tgz", - "integrity": "sha512-dPJrL0VOyxqLM9sritNbMSGx/teueHF/htMKrPT7DNxccXxRDPYqlgPFFdr8u+F+qUZOkZoXue/6rL5O5GduEw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.15.tgz", + "integrity": "sha512-HzG8sFl1ZVGTme74Nw+X01XsUTqERVQ6/RLHo3XjGRzm7XD6QTtfS3NJotVgCGy8BzkDqRjRBD8dAyJn5TuvSQ==", "dev": true, "peer": true, "dependencies": { @@ -1931,9 +2030,9 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz", - "integrity": "sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz", + "integrity": "sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==", "dev": true, "peer": true, "dependencies": { @@ -2048,13 +2147,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.11.tgz", - "integrity": "sha512-o2+bg7GDS60cJMgz9jWqRUsWkMzLCxp+jFDeDUT5sjRlAxcJWZ2ylNdI7QQ2+CH5hWu7OnN+Cv3htt7AkSf96g==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.15.tgz", + "integrity": "sha512-jWL4eh90w0HQOTKP2MoXXUpVxilxsB2Vl4ji69rSjS3EcZ/v4sBmn+A3NpepuJzBhOaEBbR7udonlHHn5DWidg==", "dev": true, "peer": true, "dependencies": { - "@babel/helper-module-transforms": "^7.22.9", + "@babel/helper-module-transforms": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-simple-access": "^7.22.5" }, @@ -2169,17 +2268,17 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.11.tgz", - "integrity": "sha512-nX8cPFa6+UmbepISvlf5jhQyaC7ASs/7UxHmMkuJ/k5xSHvDPPaibMo+v3TXwU/Pjqhep/nFNpd3zn4YR59pnw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz", + "integrity": "sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==", "dev": true, "peer": true, "dependencies": { "@babel/compat-data": "^7.22.9", - "@babel/helper-compilation-targets": "^7.22.10", + "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.22.5" + "@babel/plugin-transform-parameters": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -2223,9 +2322,9 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.22.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.12.tgz", - "integrity": "sha512-7XXCVqZtyFWqjDsYDY4T45w4mlx1rf7aOgkc/Ww76xkgBiOlmjPkx36PBLHa1k1rwWvVgYMPsbuVnIamx2ZQJw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.15.tgz", + "integrity": "sha512-ngQ2tBhq5vvSJw2Q2Z9i7ealNkpDMU0rGWnHPKqRZO0tzZ5tlaoz4hDvhXioOoaE0X2vfNss1djwg0DXlfu30A==", "dev": true, "peer": true, "dependencies": { @@ -2241,9 +2340,9 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz", - "integrity": "sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz", + "integrity": "sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==", "dev": true, "peer": true, "dependencies": { @@ -2654,18 +2753,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.11.tgz", - "integrity": "sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.17.tgz", + "integrity": "sha512-xK4Uwm0JnAMvxYZxOVecss85WxTEIbTa7bnGyf/+EgCL5Zt3U7htUpEOWv9detPlamGKuRzCqw74xVglDWpPdg==", "dependencies": { - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.22.15", "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-function-name": "^7.22.5", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.11", - "@babel/types": "^7.22.11", + "@babel/parser": "^7.22.16", + "@babel/types": "^7.22.17", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2674,11 +2773,11 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/generator": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz", + "integrity": "sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==", "dependencies": { - "@babel/types": "^7.22.10", + "@babel/types": "^7.22.15", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -2688,12 +2787,12 @@ } }, "node_modules/@babel/types": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", - "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz", + "integrity": "sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==", "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.15", "to-fast-properties": "^2.0.0" }, "engines": { @@ -3229,9 +3328,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", - "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz", + "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4214,6 +4313,14 @@ "uuid": "9.0.0" } }, + "node_modules/@ls1intum/apollon/node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@material/animation": { "version": "15.0.0-canary.bc9ae6c9c.0", "resolved": "https://registry.npmjs.org/@material/animation/-/animation-15.0.0-canary.bc9ae6c9c.0.tgz", @@ -5250,6 +5357,150 @@ "node": ">= 10" } }, + "node_modules/@nx/nx-darwin-x64": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-16.5.1.tgz", + "integrity": "sha512-j9HmL1l8k7EVJ3eOM5y8COF93gqrydpxCDoz23ZEtsY+JHY77VAiRQsmqBgEx9GGA2dXi9VEdS67B0+1vKariw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-freebsd-x64": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-16.5.1.tgz", + "integrity": "sha512-CXSPT01aVS869tvCCF2tZ7LnCa8l41wJ3mTVtWBkjmRde68E5Up093hklRMyXb3kfiDYlfIKWGwrV4r0eH6x1A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm-gnueabihf": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.5.1.tgz", + "integrity": "sha512-BhrumqJSZCWFfLFUKl4CAUwR0Y0G2H5EfFVGKivVecEQbb+INAek1aa6c89evg2/OvetQYsJ+51QknskwqvLsA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm64-gnu": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.5.1.tgz", + "integrity": "sha512-x7MsSG0W+X43WVv7JhiSq2eKvH2suNKdlUHEG09Yt0vm3z0bhtym1UCMUg3IUAK7jy9hhLeDaFVFkC6zo+H/XQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm64-musl": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.5.1.tgz", + "integrity": "sha512-J+/v/mFjOm74I0PNtH5Ka+fDd+/dWbKhpcZ2R1/6b9agzZk+Ff/SrwJcSYFXXWKbPX+uQ4RcJoytT06Zs3s0ow==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-x64-gnu": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.5.1.tgz", + "integrity": "sha512-igooWJ5YxQ94Zft7IqgL+Lw0qHaY15Btw4gfK756g/YTYLZEt4tTvR1y6RnK/wdpE3sa68bFTLVBNCGTyiTiDQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-x64-musl": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.5.1.tgz", + "integrity": "sha512-zF/exnPqFYbrLAduGhTmZ7zNEyADid2bzNQiIjJkh8Y6NpDwrQIwVIyvIxqynsjMrIs51kBH+8TUjKjj2Jgf5A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-win32-arm64-msvc": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.5.1.tgz", + "integrity": "sha512-qtqiLS9Y9TYyAbbpq58kRoOroko4ZXg5oWVqIWFHoxc5bGPweQSJCROEqd1AOl2ZDC6BxfuVHfhDDop1kK05WA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-win32-x64-msvc": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.5.1.tgz", + "integrity": "sha512-kUJBLakK7iyA9WfsGGQBVennA4jwf5XIgm0lu35oMOphtZIluvzItMt0EYBmylEROpmpEIhHq0P6J9FA+WH0Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@parcel/watcher": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.0.4.tgz", @@ -5329,9 +5580,9 @@ } }, "node_modules/@polka/url": { - "version": "1.0.0-next.21", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", - "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", + "version": "1.0.0-next.23", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.23.tgz", + "integrity": "sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==", "dev": true }, "node_modules/@popperjs/core": { @@ -5396,13 +5647,13 @@ "integrity": "sha512-1dgmkh+3so0+LlBWRhGA33ua4MYr7tUOj+a9Si28vUi0IUFNbff1T3sgpeDJI/LaC75bBYnQ0A3wXjn0OrRNBA==" }, "node_modules/@schematics/angular": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-16.2.1.tgz", - "integrity": "sha512-e3ckgvSv+OA+4xUBpOqVOvNM8FqY/yXaWqs/Ob0uQ/zPL1iVa/MCAoB25KqYQPnq21hEwE4zqIIQFKasKBIqMA==", + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-16.2.2.tgz", + "integrity": "sha512-OqPhpodkQx9pzSz7H2AGeEbf3ut6WOkJFP2YlX2JIGholfG/0FQMJmfTEyRoFXCBeVIDGt3sOmlfK7An0PS8uA==", "dev": true, "dependencies": { - "@angular-devkit/core": "16.2.1", - "@angular-devkit/schematics": "16.2.1", + "@angular-devkit/core": "16.2.2", + "@angular-devkit/schematics": "16.2.2", "jsonc-parser": "3.2.0" }, "engines": { @@ -5411,14 +5662,41 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.2.tgz", + "integrity": "sha512-6H4FsvP3rLJaGiWpIhCFPS7ZeNoM4sSrnFtRhhecu6s7MidzE4aqzuGdzJpzLammw1KL+DuTlN0gpLtM1Bvcwg==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "2.3.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, "node_modules/@sentry-internal/tracing": { - "version": "7.66.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.66.0.tgz", - "integrity": "sha512-3vCgC2hC3T45pn53yTDVcRpHoJTBxelDPPZVsipAbZnoOVPkj7n6dNfDhj3I3kwWCBPahPkXmE+R4xViR8VqJg==", + "version": "7.69.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.69.0.tgz", + "integrity": "sha512-4BgeWZUj9MO6IgfO93C9ocP3+AdngqujF/+zB2rFdUe+y9S6koDyUC7jr9Knds/0Ta72N/0D6PwhgSCpHK8s0Q==", "dependencies": { - "@sentry/core": "7.66.0", - "@sentry/types": "7.66.0", - "@sentry/utils": "7.66.0", + "@sentry/core": "7.69.0", + "@sentry/types": "7.69.0", + "@sentry/utils": "7.69.0", "tslib": "^2.4.1 || ^1.9.3" }, "engines": { @@ -5426,13 +5704,13 @@ } }, "node_modules/@sentry/angular-ivy": { - "version": "7.66.0", - "resolved": "https://registry.npmjs.org/@sentry/angular-ivy/-/angular-ivy-7.66.0.tgz", - "integrity": "sha512-+/Z+c38J2PdZ7Okg8dC+tdu0tTdSz4Pngne4PPHkOsq4VP2pz4JUyMGDBqd7LaMXtcVurMLjxaweINFDC5Cb0w==", + "version": "7.69.0", + "resolved": "https://registry.npmjs.org/@sentry/angular-ivy/-/angular-ivy-7.69.0.tgz", + "integrity": "sha512-tXyTebex0O8ZUqS9RyTMNsVPM8z1Hr63W36Utg7jNd9Fi6XItQFWvOt4ME8/I89DIuCMBzhxCpwgPQqJolrhOQ==", "dependencies": { - "@sentry/browser": "7.66.0", - "@sentry/types": "7.66.0", - "@sentry/utils": "7.66.0", + "@sentry/browser": "7.69.0", + "@sentry/types": "7.69.0", + "@sentry/utils": "7.69.0", "tslib": "^2.4.1" }, "engines": { @@ -5446,15 +5724,15 @@ } }, "node_modules/@sentry/browser": { - "version": "7.66.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.66.0.tgz", - "integrity": "sha512-rW037rf8jkhyykG38+HUdwkRCKHJEMM5NkCqPIO5zuuxfLKukKdI2rbvgJ93s3/9UfsTuDFcKFL1u43mCn6sDw==", - "dependencies": { - "@sentry-internal/tracing": "7.66.0", - "@sentry/core": "7.66.0", - "@sentry/replay": "7.66.0", - "@sentry/types": "7.66.0", - "@sentry/utils": "7.66.0", + "version": "7.69.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.69.0.tgz", + "integrity": "sha512-5ls+zu2PrMhHCIIhclKQsWX5u6WH0Ez5/GgrCMZTtZ1d70ukGSRUvpZG9qGf5Cw1ezS1LY+1HCc3whf8x8lyPw==", + "dependencies": { + "@sentry-internal/tracing": "7.69.0", + "@sentry/core": "7.69.0", + "@sentry/replay": "7.69.0", + "@sentry/types": "7.69.0", + "@sentry/utils": "7.69.0", "tslib": "^2.4.1 || ^1.9.3" }, "engines": { @@ -5462,12 +5740,12 @@ } }, "node_modules/@sentry/core": { - "version": "7.66.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.66.0.tgz", - "integrity": "sha512-WMAEPN86NeCJ1IT48Lqiz4MS5gdDjBwP4M63XP4msZn9aujSf2Qb6My5uT87AJr9zBtgk8MyJsuHr35F0P3q1w==", + "version": "7.69.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.69.0.tgz", + "integrity": "sha512-V6jvK2lS8bhqZDMFUtvwe2XvNstFQf5A+2LMKCNBOV/NN6eSAAd6THwEpginabjet9dHsNRmMk7WNKvrUfQhZw==", "dependencies": { - "@sentry/types": "7.66.0", - "@sentry/utils": "7.66.0", + "@sentry/types": "7.69.0", + "@sentry/utils": "7.69.0", "tslib": "^2.4.1 || ^1.9.3" }, "engines": { @@ -5475,43 +5753,43 @@ } }, "node_modules/@sentry/replay": { - "version": "7.66.0", - "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.66.0.tgz", - "integrity": "sha512-5Y2SlVTOFTo3uIycv0mRneBakQtLgWkOnsJaC5LB0Ip0TqVKiMCbQ578vvXp+yvRj4LcS1gNd98xTTNojBoQNg==", + "version": "7.69.0", + "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.69.0.tgz", + "integrity": "sha512-oUqWyBPFUgShdVvgJtV65EQH9pVDmoYVQMOu59JI6FHVeL3ald7R5Mvz6GaNLXsirvvhp0yAkcAd2hc5Xi6hDw==", "dependencies": { - "@sentry/core": "7.66.0", - "@sentry/types": "7.66.0", - "@sentry/utils": "7.66.0" + "@sentry/core": "7.69.0", + "@sentry/types": "7.69.0", + "@sentry/utils": "7.69.0" }, "engines": { "node": ">=12" } }, "node_modules/@sentry/tracing": { - "version": "7.66.0", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.66.0.tgz", - "integrity": "sha512-9bnz2EcOwjeMZAuYJnrwcRrImu9c10p7A0iDB8b2HLcp7gpuCkJbJyGoC1xeKD7reVD0BPq3VIbeHSwCcQufoQ==", + "version": "7.69.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.69.0.tgz", + "integrity": "sha512-nhwJXyLU2KT6ci3YRUCkpFQH7RL9lpEuVDHqaJ9xLql766FJ7A7jKtRGSaefgRzJvvdKHUVboIjZnSvqIu8gWw==", "dependencies": { - "@sentry-internal/tracing": "7.66.0" + "@sentry-internal/tracing": "7.69.0" }, "engines": { "node": ">=8" } }, "node_modules/@sentry/types": { - "version": "7.66.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.66.0.tgz", - "integrity": "sha512-uUMSoSiar6JhuD8p7ON/Ddp4JYvrVd2RpwXJRPH1A4H4Bd4DVt1mKJy1OLG6HdeQv39XyhB1lPZckKJg4tATPw==", + "version": "7.69.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.69.0.tgz", + "integrity": "sha512-zPyCox0mzitzU6SIa1KIbNoJAInYDdUpdiA+PoUmMn2hFMH1llGU/cS7f4w/mAsssTlbtlBi72RMnWUCy578bw==", "engines": { "node": ">=8" } }, "node_modules/@sentry/utils": { - "version": "7.66.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.66.0.tgz", - "integrity": "sha512-9GYUVgXjK66uXXcLXVMXVzlptqMtq1eJENCuDeezQiEFrNA71KkLDg00wESp+LL+bl3wpVTBApArpbF6UEG5hQ==", + "version": "7.69.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.69.0.tgz", + "integrity": "sha512-4eBixe5Y+0EGVU95R4NxH3jkkjtkE4/CmSZD4In8SCkWGSauogePtq6hyiLsZuP1QHdpPb9Kt0+zYiBb2LouBA==", "dependencies": { - "@sentry/types": "7.66.0", + "@sentry/types": "7.69.0", "tslib": "^2.4.1 || ^1.9.3" }, "engines": { @@ -5827,9 +6105,9 @@ } }, "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "version": "3.4.36", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", + "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", "dev": true, "peer": true, "dependencies": { @@ -5837,9 +6115,9 @@ } }, "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", - "integrity": "sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.1.tgz", + "integrity": "sha512-iaQslNbARe8fctL5Lk+DsmgWOM83lM+7FzP0eQUJs1jd3kBE8NWqBTIT2S8SqQOJjxvt2eyIjpOuYeRXq2AdMw==", "dev": true, "peer": true, "dependencies": { @@ -5848,9 +6126,9 @@ } }, "node_modules/@types/crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.1.2.tgz", + "integrity": "sha512-t33RNmTu5ufG/sorROIafiCVJMx3jz95bXUMoPAZcUD14fxMXnuTzqzXZoxpR0tNx2xpw11Dlmem9vGCsrSOfA==", "dev": true }, "node_modules/@types/d3-path": { @@ -6019,9 +6297,9 @@ "dev": true }, "node_modules/@types/lodash": { - "version": "4.14.197", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.197.tgz", - "integrity": "sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g==", + "version": "4.14.198", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.198.tgz", + "integrity": "sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==", "dev": true }, "node_modules/@types/lodash-es": { @@ -6041,9 +6319,9 @@ "peer": true }, "node_modules/@types/node": { - "version": "20.5.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", - "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==", + "version": "20.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", + "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==", "dev": true }, "node_modules/@types/papaparse": { @@ -6218,16 +6496,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.5.0.tgz", - "integrity": "sha512-2pktILyjvMaScU6iK3925uvGU87E+N9rh372uGZgiMYwafaw9SXq86U04XPq3UH6tzRvNgBsub6x2DacHc33lw==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.0.tgz", + "integrity": "sha512-gUqtknHm0TDs1LhY12K2NA3Rmlmp88jK9Tx8vGZMfHeNMLE3GH2e9TRub+y+SOjuYgtOmok+wt1AyDPZqxbNag==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/type-utils": "6.5.0", - "@typescript-eslint/utils": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/type-utils": "6.7.0", + "@typescript-eslint/utils": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -6253,13 +6531,13 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.5.0.tgz", - "integrity": "sha512-f7OcZOkRivtujIBQ4yrJNIuwyCQO1OjocVqntl9dgSIZAdKqicj3xFDqDOzHDlGCZX990LqhLQXWRnQvsapq8A==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.0.tgz", + "integrity": "sha512-f/QabJgDAlpSz3qduCyQT0Fw7hHpmhOzY/Rv6zO3yO+HVIdPfIWhrQoAyG+uZVtWAIS85zAyzgAFfyEr+MgBpg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.5.0", - "@typescript-eslint/utils": "6.5.0", + "@typescript-eslint/typescript-estree": "6.7.0", + "@typescript-eslint/utils": "6.7.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -6280,17 +6558,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.5.0.tgz", - "integrity": "sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.0.tgz", + "integrity": "sha512-MfCq3cM0vh2slSikQYqK2Gq52gvOhe57vD2RM3V4gQRZYX4rDPnKLu5p6cm89+LJiGlwEXU8hkYxhqqEC/V3qA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/typescript-estree": "6.5.0", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.0", "semver": "^7.5.4" }, "engines": { @@ -6305,15 +6583,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.5.0.tgz", - "integrity": "sha512-LMAVtR5GN8nY0G0BadkG0XIe4AcNMeyEy3DyhKGAh9k4pLSMBO7rF29JvDBpZGCmp5Pgz5RLHP6eCpSYZJQDuQ==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.0.tgz", + "integrity": "sha512-jZKYwqNpNm5kzPVP5z1JXAuxjtl2uG+5NpaMocFPTNC2EdYIgbXIPImObOkhbONxtFTTdoZstLZefbaK+wXZng==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/typescript-estree": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", "debug": "^4.3.4" }, "engines": { @@ -6333,13 +6611,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", - "integrity": "sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.0.tgz", + "integrity": "sha512-lAT1Uau20lQyjoLUQ5FUMSX/dS07qux9rYd5FGzKz/Kf8W8ccuvMyldb8hadHdK/qOI7aikvQWqulnEq2nCEYA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0" + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -6434,9 +6712,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", - "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.0.tgz", + "integrity": "sha512-ihPfvOp7pOcN/ysoj0RpBPOx3HQTJTrIN8UZK+WFd3/iDeFHHqeyYxa4hQk4rMhsz9H9mXpR61IzwlBVGXtl9Q==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -6447,13 +6725,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", - "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.0.tgz", + "integrity": "sha512-dPvkXj3n6e9yd/0LfojNU8VMUGHWiLuBZvbM6V6QYD+2qxqInE7J+J/ieY2iGwR9ivf/R/haWGkIj04WVUeiSQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -6596,12 +6874,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", - "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.0.tgz", + "integrity": "sha512-/C1RVgKFDmGMcVGeD8HjKv2bd72oI1KxQDeY8uc66gw9R0OK0eMq48cA+jv9/2Ag6cdrsUGySm1yzYmfz0hxwQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/types": "6.7.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -6964,9 +7242,9 @@ } }, "node_modules/ace-builds": { - "version": "1.24.1", - "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.24.1.tgz", - "integrity": "sha512-TLcxMxiTRX5Eq9bBVSd/bTJlanCBULiv/IULLohJDDaCAfcpZKJBVSd4OWfN/j2c2jCLc+jhpNWGELiJZw3wPw==" + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.25.1.tgz", + "integrity": "sha512-pB4N8wvl+tUEwD12BovBUpd6B+IpASOShd8WlufwFnXCfBQk/4nwmpN5vZSsvd6v5G7YaP9/PPdQK4cq2ZRzng==" }, "node_modules/acorn": { "version": "8.10.0", @@ -8067,9 +8345,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001525", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001525.tgz", - "integrity": "sha512-/3z+wB4icFt3r0USMwxujAqRvaD/B7rvGTsKhbhSQErVrJvkZCLhgNLJxU8MevahQVH6hCU9FsHdNUFbiwmE7Q==", + "version": "1.0.30001529", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001529.tgz", + "integrity": "sha512-n2pUQYGAkrLG4QYj2desAh+NqsJpHbNmVZz87imptDdxLAtjxary7Df/psdfyDGmskJK/9Dt9cPnx5RZ3CU4Og==", "funding": [ { "type": "opencollective", @@ -8626,9 +8904,9 @@ } }, "node_modules/core-js": { - "version": "3.32.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.32.1.tgz", - "integrity": "sha512-lqufgNn9NLnESg5mQeYsxQP5w7wrViSj0jr/kv6ECQiByzQkrn1MKvV0L3acttpDqfQrHLwr2KCMgX5b8X+lyQ==", + "version": "3.32.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.32.2.tgz", + "integrity": "sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -8636,9 +8914,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.32.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.1.tgz", - "integrity": "sha512-GSvKDv4wE0bPnQtjklV101juQ85g6H3rm5PDP20mqlS5j0kXF3pP97YvAu5hl+uFHqMictp3b2VxOHljWMAtuA==", + "version": "3.32.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.2.tgz", + "integrity": "sha512-+GjlguTDINOijtVRUxrQOv3kfu9rl+qPNdX2LTbJ/ZyVTuxK+ksVSAGX1nHstu4hrv1En/uPTtWgq2gI5wt4AQ==", "dev": true, "peer": true, "dependencies": { @@ -8655,15 +8933,15 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "node_modules/cosmiconfig": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", - "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.4.tgz", + "integrity": "sha512-SF+2P8+o/PTV05rgsAjDzL4OFdVXAulSfC/L19VaeVT7+tpOOSscCt2QLxDZ+CLxF2WOiq6y1K5asvs8qUJT/Q==", "dev": true, "peer": true, "dependencies": { - "import-fresh": "^3.2.1", + "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", - "parse-json": "^5.0.0", + "parse-json": "^5.2.0", "path-type": "^4.0.0" }, "engines": { @@ -8671,6 +8949,14 @@ }, "funding": { "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/cosmiconfig/node_modules/argparse": { @@ -9693,9 +9979,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.506", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.506.tgz", - "integrity": "sha512-xxGct4GPAKSRlrLBtJxJFYy74W11zX6PO9GyHgl/U+2s3Dp0ZEwAklDfNHXOWcvH7zWMpsmgbR0ggEuaYAVvHA==" + "version": "1.4.513", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.513.tgz", + "integrity": "sha512-cOB0xcInjm+E5qIssHeXJ29BaUyWpMyFKT5RB3bsLENDheCja0wMkHJyiPl0NBE/VzDI7JDuNEQWhe6RitEUcw==" }, "node_modules/emittery": { "version": "0.13.1", @@ -9973,16 +10259,16 @@ } }, "node_modules/eslint": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", - "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz", + "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.48.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint/js": "8.49.0", + "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.12.4", @@ -10039,18 +10325,43 @@ } }, "node_modules/eslint-plugin-deprecation": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-deprecation/-/eslint-plugin-deprecation-1.5.0.tgz", - "integrity": "sha512-mRcssI/tLROueBQ6yf4LnnGTijbMsTCPIpbRbPj5R5wGYVCpk1zDmAS0SEkgcUDXOPc22qMNFR24Qw7vSPrlTA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-deprecation/-/eslint-plugin-deprecation-2.0.0.tgz", + "integrity": "sha512-OAm9Ohzbj11/ZFyICyR5N6LbOIvQMp7ZU2zI7Ej0jIc8kiGUERXPNMfw2QqqHD1ZHtjMub3yPZILovYEYucgoQ==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "^5.57.0", + "@typescript-eslint/utils": "^6.0.0", "tslib": "^2.3.1", "tsutils": "^3.21.0" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0", - "typescript": "^3.7.5 || ^4.0.0 || ^5.0.0" + "eslint": "^7.0.0 || ^8.0.0", + "typescript": "^4.2.4 || ^5.0.0" + } + }, + "node_modules/eslint-plugin-deprecation/node_modules/@typescript-eslint/utils": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.0.tgz", + "integrity": "sha512-MfCq3cM0vh2slSikQYqK2Gq52gvOhe57vD2RM3V4gQRZYX4rDPnKLu5p6cm89+LJiGlwEXU8hkYxhqqEC/V3qA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" } }, "node_modules/eslint-plugin-jest": { @@ -10960,9 +11271,9 @@ } }, "node_modules/fraction.js": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.4.tgz", - "integrity": "sha512-pwiTgt0Q7t+GHZA4yaLjObx4vXmmdcS0iSJ19o8d/goUGgItX9UZWKWNnLHehxviD8wU2IWRsnR8cD5+yOJP2Q==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.6.tgz", + "integrity": "sha512-n2aZ9tNfYDwaHhvFTkhFErqOMIb8uyzSQ+vGJBjZyanAKZVbGUQ1sngfk9FdkBw7G26O7AgNjLcecLffD1c7eg==", "dev": true, "peer": true, "engines": { @@ -12595,9 +12906,9 @@ "integrity": "sha512-4dG1D1x/7g8PwHS9aK6QV5V94+ZvyP4+d19qDv43EzImmrndysIl4prmJ1hWWIGCqrZHyaHBm6BSEWHOLnpoNw==" }, "node_modules/jackspeak": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.1.tgz", - "integrity": "sha512-4iSY3Bh1Htv+kLhiiZunUhQ+OYXIn0ze3ulq8JeWrFKmhPAJSySV2+kdtRh2pGcCeF0s6oR8Oc+pYZynJj4t8A==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.3.tgz", + "integrity": "sha512-R2bUw+kVZFS/h1AZqBKrSgDmdmjApzgY0AlCPumopFiAlbUxE2gf+SCuBzQ0cP5hHmUmFYF5yw55T97Th5Kstg==", "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -13523,9 +13834,9 @@ } }, "node_modules/jest-environment-jsdom/node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.1.tgz", + "integrity": "sha512-4OOseMUq8AzRBI/7SLMUwO+FEDnguetSk7KMb1sHwvF2w2Wv5Hoj0nlifx8vtGsftE/jWHojPy8sMMzYLJ2G/A==", "dev": true, "engines": { "node": ">=10.0.0" @@ -14726,9 +15037,9 @@ } }, "node_modules/jiti": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.3.tgz", - "integrity": "sha512-5eEbBDQT/jF1xg6l36P+mWGGoH9Spuy0PCdSr2dtWRDGC6ph/w9ZCL4lmESW8f8F7MwT3XKescfP0wnZWAKL9w==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.20.0.tgz", + "integrity": "sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==", "dev": true, "peer": true, "bin": { @@ -17923,9 +18234,9 @@ } }, "node_modules/pure-rand": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz", - "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.3.tgz", + "integrity": "sha512-KddyFewCsO0j3+np81IQ+SweXLDnDQTs5s67BOnrYmYe/yNmUhttQyGsYzy8yUnoljGAQ9sl38YB4vH8ur7Y+w==", "dev": true, "funding": [ { @@ -18562,9 +18873,9 @@ } }, "node_modules/rollup": { - "version": "3.28.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.1.tgz", - "integrity": "sha512-R9OMQmIHJm9znrU3m3cpE8uhN0fGdXiawME7aZIpQqvpS/85+Vt1Hq1/yVIcYfOmaQiHjvXkQAoJukvLpau6Yw==", + "version": "3.29.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.0.tgz", + "integrity": "sha512-nszM8DINnx1vSS+TpbWKMkxem0CDWk3cSit/WWCBVs9/JZ1I/XLwOsiUglYuYReaeWWSsW9kge5zE5NZtf/a4w==", "dev": true, "peer": true, "bin": { @@ -18649,9 +18960,9 @@ "integrity": "sha512-LRneZZRXNgjzwG4bDQdOTSbze3fHm1EAKN/8bePxnlEZiBmkYEDggaHbuvHI9/hoqHbGfsEA7tWS9GhYHZBBsw==" }, "node_modules/sass": { - "version": "1.66.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.66.1.tgz", - "integrity": "sha512-50c+zTsZOJVgFfTgwwEzkjA3/QACgdNsKueWPyAR0mRINIvLAStVQBbPg14iuqEQ74NPDbXzJARJ/O4SI1zftA==", + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.67.0.tgz", + "integrity": "sha512-SVrO9ZeX/QQyEGtuZYCVxoeAL5vGlYjJ9p4i4HFuekWl8y/LtJ7tJc10Z+ck1c8xOuoBm2MYzcLfTAffD0pl/A==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -19708,9 +20019,9 @@ } }, "node_modules/tar": { - "version": "6.1.15", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", - "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", "dev": true, "dependencies": { "chownr": "^2.0.0", @@ -20111,9 +20422,9 @@ } }, "node_modules/ts-api-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.2.tgz", - "integrity": "sha512-Cbu4nIqnEdd+THNEsBdkolnOXhg0I8XteoHaEKgvsxpsbWda4IsUut2c187HxywQCvveojow0Dgw/amxtSKVkQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", "dev": true, "engines": { "node": ">=16.13.0" @@ -20490,9 +20801,13 @@ } }, "node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } @@ -20954,9 +21269,9 @@ } }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.1.tgz", + "integrity": "sha512-4OOseMUq8AzRBI/7SLMUwO+FEDnguetSk7KMb1sHwvF2w2Wv5Hoj0nlifx8vtGsftE/jWHojPy8sMMzYLJ2G/A==", "dev": true, "peer": true, "engines": { diff --git a/package.json b/package.json index 33c99708233e..a21c26412c31 100644 --- a/package.json +++ b/package.json @@ -13,18 +13,18 @@ "node_modules" ], "dependencies": { - "@angular/animations": "16.2.3", - "@angular/cdk": "16.2.2", - "@angular/common": "16.2.3", - "@angular/compiler": "16.2.3", - "@angular/core": "16.2.3", - "@angular/forms": "16.2.3", - "@angular/localize": "16.2.3", - "@angular/material": "16.2.2", - "@angular/platform-browser": "16.2.3", - "@angular/platform-browser-dynamic": "16.2.3", - "@angular/router": "16.2.3", - "@angular/service-worker": "16.2.3", + "@angular/animations": "16.2.5", + "@angular/cdk": "16.2.4", + "@angular/common": "16.2.5", + "@angular/compiler": "16.2.5", + "@angular/core": "16.2.5", + "@angular/forms": "16.2.5", + "@angular/localize": "16.2.5", + "@angular/material": "16.2.4", + "@angular/platform-browser": "16.2.5", + "@angular/platform-browser-dynamic": "16.2.5", + "@angular/router": "16.2.5", + "@angular/service-worker": "16.2.5", "@ctrl/ngx-emoji-mart": "9.2.0", "@danielmoncada/angular-datetime-picker": "16.0.1", "@fingerprintjs/fingerprintjs": "4.0.1", @@ -37,16 +37,16 @@ "@ng-bootstrap/ng-bootstrap": "15.1.1", "@ngx-translate/core": "15.0.0", "@ngx-translate/http-loader": "8.0.0", - "@sentry/angular-ivy": "7.66.0", - "@sentry/tracing": "7.66.0", - "@sentry/types": "7.66.0", + "@sentry/angular-ivy": "7.69.0", + "@sentry/tracing": "7.69.0", + "@sentry/types": "7.69.0", "@swimlane/ngx-charts": "20.4.1", "@swimlane/ngx-graph": "8.2.2", - "ace-builds": "1.24.1", + "ace-builds": "1.25.1", "bootstrap": "5.3.1", "brace": "0.11.1", "compare-versions": "6.1.0", - "core-js": "3.32.1", + "core-js": "3.32.2", "crypto-js": "4.1.1", "dayjs": "1.11.9", "diff-match-patch-typescript": "1.0.8", @@ -73,7 +73,7 @@ "split.js": "1.6.5", "ts-cacheable": "1.0.9", "tslib": "2.6.2", - "uuid": "9.0.0", + "uuid": "9.0.1", "webstomp-client": "1.2.6", "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.0/xlsx-0.20.0.tgz", "zone.js": "0.13.0" @@ -95,30 +95,30 @@ }, "devDependencies": { "@angular-builders/jest": "16.0.1", - "@angular-eslint/builder": "16.1.1", - "@angular-eslint/eslint-plugin": "16.1.1", - "@angular-eslint/eslint-plugin-template": "16.1.1", - "@angular-eslint/schematics": "16.1.1", - "@angular-eslint/template-parser": "16.1.1", - "@angular/cli": "16.2.1", - "@angular/compiler-cli": "16.2.3", - "@angular/language-service": "16.2.3", - "@types/crypto-js": "4.1.1", + "@angular-eslint/builder": "16.1.2", + "@angular-eslint/eslint-plugin": "16.1.2", + "@angular-eslint/eslint-plugin-template": "16.1.2", + "@angular-eslint/schematics": "16.1.2", + "@angular-eslint/template-parser": "16.1.2", + "@angular/cli": "16.2.2", + "@angular/compiler-cli": "16.2.5", + "@angular/language-service": "16.2.5", + "@types/crypto-js": "4.1.2", "@types/d3-shape": "3.1.2", "@types/dompurify": "3.0.2", "@types/jest": "29.5.4", "@types/lodash-es": "4.17.9", - "@types/node": "20.5.7", + "@types/node": "20.6.0", "@types/papaparse": "5.3.8", "@types/showdown": "2.0.1", "@types/smoothscroll-polyfill": "0.3.1", "@types/sockjs-client": "1.5.1", "@types/uuid": "9.0.3", - "@typescript-eslint/eslint-plugin": "6.5.0", - "@typescript-eslint/parser": "6.5.0", - "eslint": "8.48.0", + "@typescript-eslint/eslint-plugin": "6.7.0", + "@typescript-eslint/parser": "6.7.0", + "eslint": "8.49.0", "eslint-config-prettier": "9.0.0", - "eslint-plugin-deprecation": "1.5.0", + "eslint-plugin-deprecation": "2.0.0", "eslint-plugin-jest": "27.2.3", "eslint-plugin-jest-extended": "2.0.0", "eslint-plugin-prettier": "5.0.0", @@ -134,7 +134,7 @@ "lint-staged": "14.0.1", "ng-mocks": "14.11.0", "prettier": "3.0.3", - "sass": "1.66.1", + "sass": "1.67.0", "ts-jest": "29.1.1", "typescript": "5.1.6", "weak-napi": "2.0.2", diff --git a/src/main/java/de/tum/in/www1/artemis/domain/enumeration/DataExportState.java b/src/main/java/de/tum/in/www1/artemis/domain/enumeration/DataExportState.java index 5f4331897e67..1789c1d2ce5d 100644 --- a/src/main/java/de/tum/in/www1/artemis/domain/enumeration/DataExportState.java +++ b/src/main/java/de/tum/in/www1/artemis/domain/enumeration/DataExportState.java @@ -8,10 +8,28 @@ public enum DataExportState { REQUESTED, IN_CREATION, EMAIL_SENT, DOWNLOADED, DOWNLOADED_DELETED, DELETED, FAILED; + /** + * Checks if the data export can be downloaded. + *
+ * The data export can be downloaded if its state is either EMAIL_SENT or DOWNLOADED. + * The state is EMAIL_SENT if the data export has been created and the user has been notified via email. + * The state is DOWNLOADED if the user has downloaded the data export at least once. + * + * @return true if the data export can be downloaded, false otherwise + */ public boolean isDownloadable() { return this == DOWNLOADED || this == EMAIL_SENT; } + /** + * Checks if the data export has been downloaded. + *
+ * The data export has been downloaded if its state is either DOWNLOADED or DOWNLOADED_DELETED.
+ * The state is DOWNLOADED if the user has downloaded the data export at least once, but it has not been deleted yet.
+ * The state is DOWNLOADED_DELETED if the user has downloaded the data export at least once, and it has been deleted.
+ *
+ * @return true if the data export has been downloaded, false otherwise
+ */
public boolean hasBeenDownloaded() {
return this == DOWNLOADED || this == DOWNLOADED_DELETED;
}
diff --git a/src/main/java/de/tum/in/www1/artemis/repository/DataExportRepository.java b/src/main/java/de/tum/in/www1/artemis/repository/DataExportRepository.java
index 9315ccd9d78a..4344193419f0 100644
--- a/src/main/java/de/tum/in/www1/artemis/repository/DataExportRepository.java
+++ b/src/main/java/de/tum/in/www1/artemis/repository/DataExportRepository.java
@@ -1,5 +1,6 @@
package de.tum.in.www1.artemis.repository;
+import java.util.List;
import java.util.Set;
import org.springframework.data.jpa.repository.JpaRepository;
@@ -55,12 +56,23 @@ default DataExport findByIdElseThrow(long dataExportId) {
""")
Set
+ * This is relevant if more than one data export exists that can be downloaded.
+ * This can happen if the user had requested a data export that was created and the admin requested another data export for the same user that has been created.
+ *
+ * @param userId the id of the user to find the data exports for
+ * @return a list of data exports for the given user ordered by their request date descending
+ */
@Query("""
SELECT dataExport
FROM DataExport dataExport
WHERE dataExport.user.id = :userId
+ ORDER BY dataExport.createdDate DESC
""")
- Set
+ * This file contains information Art. 15 GDPR requires us to provide to the user.
+ * The file is retrieved from the resources folder.
+ * The file is added to the root of the data export.
+ *
+ * @param workingDirectory the directory in which the data export is created
+ * @throws IOException if the file could not be copied
+ * @throws URISyntaxException if the resource file path is invalid
+ */
private void addReadmeFile(Path workingDirectory) throws IOException, URISyntaxException {
var readmeInDataExportPath = workingDirectory.resolve("README.md");
var readmeTemplatePath = Path.of("templates", "dataexport", "README.md");
@@ -105,6 +118,8 @@ private void addReadmeFile(Path workingDirectory) throws IOException, URISyntaxE
/**
* Creates the data export for the given user.
+ *
+ * This includes creation of the export and notifying the user about the creation.
*
* @param dataExport the data export to be created
* @return true if the export was successful, false otherwise
@@ -129,6 +144,15 @@ public boolean createDataExport(DataExport dataExport) {
return true;
}
+ /**
+ * Handles the case of a failed data export creation.
+ *
+ * This includes setting the state of the data export to failed, notifying the user about the failure and sending an email to the admin with the exception why the export
+ * failed.
+ *
+ * @param dataExport the data export that failed to be created
+ * @param exception the exception that occurred during the creation
+ */
private void handleCreationFailure(DataExport dataExport, Exception exception) {
dataExport.setDataExportState(DataExportState.FAILED);
dataExport = dataExportRepository.save(dataExport);
@@ -141,6 +165,13 @@ private void handleCreationFailure(DataExport dataExport, Exception exception) {
mailService.sendDataExportFailedEmailToAdmin(admin.get(), dataExport, exception);
}
+ /**
+ * Finishes the creation of the data export by setting the file path to the zip file, the state to EMAIL_SENT and the creation finished date.
+ *
+ * @param dataExport the data export whose creation is finished
+ * @param dataExportPath the path to the zip file containing the data export
+ * @return the updated data export from the database
+ */
private DataExport finishDataExportCreation(DataExport dataExport, Path dataExportPath) {
dataExport.setFilePath(dataExportPath.toString());
dataExport.setCreationFinishedDate(ZonedDateTime.now());
@@ -149,6 +180,15 @@ private DataExport finishDataExportCreation(DataExport dataExport, Path dataExpo
return dataExportRepository.save(dataExport);
}
+ /**
+ * Prepares the data export by creating the working directory, scheduling it for deletion and setting the state to IN_CREATION.
+ *
+ * If the path where the data exports are stored does not exist yet, it will be created.
+ *
+ * @param dataExport the data export to be prepared
+ * @return the path to the working directory
+ * @throws IOException if the working directory could not be created
+ */
private Path prepareDataExport(DataExport dataExport) throws IOException {
if (!Files.exists(dataExportsPath)) {
Files.createDirectories(dataExportsPath);
@@ -161,6 +201,14 @@ private Path prepareDataExport(DataExport dataExport) throws IOException {
return workingDirectory;
}
+ /**
+ * Adds the general user information to the data export.
+ *
+ * This includes the login, name, email, and registration number (matriculation number).
+ *
+ * @param user the user for which the information should be added
+ * @param workingDirectory the directory in which the information should be stored
+ */
private void addGeneralUserInformation(User user, Path workingDirectory) throws IOException {
String[] headers = { "login", "name", "email", "registration number" };
CSVFormat csvFormat = CSVFormat.DEFAULT.builder().setHeader(headers).build();
@@ -171,11 +219,18 @@ private void addGeneralUserInformation(User user, Path workingDirectory) throws
}
}
+ /**
+ * Creates the zip file containing the data export.
+ *
+ * @param userLogin the login of the user for which the data export was created
+ * @param workingDirectory the directory containing the data export
+ * @return the path to the zip file
+ * @throws IOException if the zip file could not be created
+ */
private Path createDataExportZipFile(String userLogin, Path workingDirectory) throws IOException {
// There should actually never exist more than one data export for a user at a time (once the feature is fully implemented), but to be sure the name is unique, we add the
// current timestamp
return zipFileService.createZipFileWithFolderContent(dataExportsPath.resolve("data-export_" + userLogin + ZonedDateTime.now().toEpochSecond() + ZIP_FILE_EXTENSION),
workingDirectory, null);
-
}
}
diff --git a/src/main/java/de/tum/in/www1/artemis/service/dataexport/DataExportExamCreationService.java b/src/main/java/de/tum/in/www1/artemis/service/dataexport/DataExportExamCreationService.java
index 126c8c204a61..af105f6ba49d 100644
--- a/src/main/java/de/tum/in/www1/artemis/service/dataexport/DataExportExamCreationService.java
+++ b/src/main/java/de/tum/in/www1/artemis/service/dataexport/DataExportExamCreationService.java
@@ -7,9 +7,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -18,14 +16,18 @@
import org.springframework.stereotype.Service;
import de.tum.in.www1.artemis.domain.Course;
+import de.tum.in.www1.artemis.domain.GradingScale;
import de.tum.in.www1.artemis.domain.ProgrammingExercise;
import de.tum.in.www1.artemis.domain.exam.StudentExam;
+import de.tum.in.www1.artemis.repository.GradingScaleRepository;
import de.tum.in.www1.artemis.repository.StudentExamRepository;
import de.tum.in.www1.artemis.service.exam.ExamService;
import de.tum.in.www1.artemis.web.rest.dto.ExamScoresDTO;
/**
* A service to create the data export for exams the user has participated in.
+ * This includes exercise participations and general information such as working time.
+ * Results are only included if the results are already published.
*/
@Service
public class DataExportExamCreationService {
@@ -38,11 +40,14 @@ public class DataExportExamCreationService {
private final ExamService examService;
- public DataExportExamCreationService(StudentExamRepository studentExamRepository, DataExportExerciseCreationService dataExportExerciseCreationService,
- ExamService examService) {
+ private final GradingScaleRepository gradingScaleRepository;
+
+ public DataExportExamCreationService(StudentExamRepository studentExamRepository, DataExportExerciseCreationService dataExportExerciseCreationService, ExamService examService,
+ GradingScaleRepository gradingScaleRepository) {
this.studentExamRepository = studentExamRepository;
this.dataExportExerciseCreationService = dataExportExerciseCreationService;
this.examService = examService;
+ this.gradingScaleRepository = gradingScaleRepository;
}
/**
@@ -61,14 +66,24 @@ public void createExportForExams(long userId, Path workingDirectory) throws IOEx
var exam = studentExam.getExam();
var examTitle = exam.getSanitizedExamTitle();
var courseDirPath = retrieveCourseDirPath(workingDirectory, exam.getCourse());
- createDirectoryIfNotExistent(courseDirPath);
+ var examsDirPath = courseDirPath.resolve("exams");
+ createDirectoryIfNotExistent(examsDirPath);
var examDirectoryName = EXAM_DIRECTORY_PREFIX + examTitle + "_" + studentExam.getId();
- var examWorkingDir = Files.createDirectories(courseDirPath.resolve(examDirectoryName));
- createStudentExamExport(studentExam, examWorkingDir);
+ var examWorkingDirPath = examsDirPath.resolve(examDirectoryName);
+ createDirectoryIfNotExistent(examWorkingDirPath);
+ createStudentExamExport(studentExam, examWorkingDirPath);
}
}
}
+ /**
+ * Creates the data export for the given student exam.
+ *
+ * This includes extracting all exercise participations, general exam information such as working time, and the results if the results are published.
+ *
+ * @param studentExam the student exam belonging to the user for which the data export should be created
+ * @param examWorkingDir the directory in which the information about the exam should be stored
+ */
private void createStudentExamExport(StudentExam studentExam, Path examWorkingDir) throws IOException {
for (var exercise : studentExam.getExercises()) {
// since the behavior is undefined if multiple student exams for the same exam and student combination exist, the exercise can be null
@@ -76,10 +91,10 @@ private void createStudentExamExport(StudentExam studentExam, Path examWorkingDi
continue;
}
if (exercise instanceof ProgrammingExercise programmingExercise) {
- dataExportExerciseCreationService.createProgrammingExerciseExport(programmingExercise, examWorkingDir, studentExam.getUser().getId());
+ dataExportExerciseCreationService.createProgrammingExerciseExport(programmingExercise, examWorkingDir, studentExam.getUser());
}
else {
- dataExportExerciseCreationService.createNonProgrammingExerciseExport(exercise, examWorkingDir, studentExam.getUser().getId());
+ dataExportExerciseCreationService.createNonProgrammingExerciseExport(exercise, examWorkingDir, studentExam.getUser());
}
}
// leave out the results if the results are not published yet to avoid leaking information through the data export
@@ -89,11 +104,18 @@ private void createStudentExamExport(StudentExam studentExam, Path examWorkingDi
addGeneralExamInformation(studentExam, examWorkingDir);
}
+ /**
+ * Adds the results of the student to the data export.
+ *
+ * @param studentExam the student exam for which the results should be added
+ * @param examWorkingDir the directory in which the results should be stored
+ */
private void addExamScores(StudentExam studentExam, Path examWorkingDir) throws IOException {
var studentExamGrade = examService.getStudentExamGradeForDataExport(studentExam);
var studentResult = studentExamGrade.studentResult();
+ var gradingScale = gradingScaleRepository.findByExamId(studentExam.getExam().getId());
List
+ * This includes information such as if the exam was started, if it is a test exam, when it was started, if it was submitted, when it was submitted, the working time, and the
+ * individual end of the working time.
+ *
+ * @param studentExam the student exam for which the information should be added
+ * @param examWorkingDir the directory in which the information should be stored
+ */
private void addGeneralExamInformation(StudentExam studentExam, Path examWorkingDir) throws IOException {
- String[] headers = { "started", "testExam", "started at", "submitted", "submitted at", "working time (in minutes)", "individual end date" };
- CSVFormat csvFormat = CSVFormat.DEFAULT.builder().setHeader(headers).build();
+ List
+ * Includes submission information, the repository from the VCS and potential plagiarism cases.
*
* @param programmingExercise the programming exercise for which the export should be created
- * @param courseDir the directory that is used for the course the exercise belongs to
- * @param userId the id of the user that requested the export
+ * @param exercisesDir the directory where all exercises of a course should be stored
+ * @param user the user for which the export should be created
* @throws IOException if an error occurs while accessing the file system
*/
-
- public void createProgrammingExerciseExport(ProgrammingExercise programmingExercise, Path courseDir, long userId) throws IOException {
- Path exerciseDir = courseDir.resolve(programmingExercise.getSanitizedExerciseTitle());
+ public void createProgrammingExerciseExport(ProgrammingExercise programmingExercise, Path exercisesDir, User user) throws IOException {
+ Path exerciseDir = exercisesDir.resolve(EXERCISE_PREFIX + programmingExercise.getSanitizedExerciseTitle());
if (!Files.exists(exerciseDir)) {
Files.createDirectory(exerciseDir);
}
- createSubmissionsResultsExport(programmingExercise, exerciseDir);
+ createSubmissionsResultsExport(programmingExercise, exerciseDir, user);
RepositoryExportOptionsDTO repositoryExportOptions = new RepositoryExportOptionsDTO();
repositoryExportOptions.setExportAllParticipants(false);
repositoryExportOptions.setAnonymizeRepository(false);
@@ -141,7 +154,7 @@ public void createProgrammingExerciseExport(ProgrammingExercise programmingExerc
programmingExerciseExportService.exportStudentRepositories(programmingExercise, listOfProgrammingExerciseParticipations, repositoryExportOptions, tempRepoWorkingDir,
exerciseDir, Collections.synchronizedList(new ArrayList<>()));
- createPlagiarismCaseInfoExport(programmingExercise, exerciseDir, userId);
+ createPlagiarismCaseInfoExport(programmingExercise, exerciseDir, user.getId());
}
@@ -150,21 +163,35 @@ public void createProgrammingExerciseExport(ProgrammingExercise programmingExerc
*
* @param exercise the exercise for which the export should be created
* @param courseDir the directory that is used for the course the exercise belongs to
- * @param userId the id of the user that requested the export
+ * @param user the user for which the export should be created
* @throws IOException if an error occurs while accessing the file system
*/
- public void createNonProgrammingExerciseExport(Exercise exercise, Path courseDir, long userId) throws IOException {
- Path exercisePath = courseDir.resolve(exercise.getSanitizedExerciseTitle());
+ public void createNonProgrammingExerciseExport(Exercise exercise, Path courseDir, User user) throws IOException {
+ Path exercisePath = courseDir.resolve(EXERCISE_PREFIX + exercise.getSanitizedExerciseTitle());
if (!Files.exists(exercisePath)) {
Files.createDirectory(exercisePath);
}
- createSubmissionsResultsExport(exercise, exercisePath);
- createPlagiarismCaseInfoExport(exercise, exercisePath, userId);
+ createSubmissionsResultsExport(exercise, exercisePath, user);
+ createPlagiarismCaseInfoExport(exercise, exercisePath, user.getId());
}
- private void createSubmissionsResultsExport(Exercise exercise, Path exerciseDir) throws IOException {
- boolean includeResults = exercise.isExamExercise() && exercise.getExamViaExerciseGroupOrCourseMember().resultsPublished()
- || exercise.isCourseExercise() && ExerciseDateService.isAfterAssessmentDueDate(exercise);
+ /**
+ * Creates the export for the submission of the user to the given exercise.
+ *
+ * Includes the submission information and the submission content and the results if the results are
+ * published.
+ * For quiz exercises it delegates the creation of the export to {@link DataExportQuizExerciseCreationService}.
+ *
+ * @param exercise the exercise for which the export should be created
+ * @param exerciseDir the directory in which the export should be created
+ * @param user the user for which the export should be created
+ */
+ private void createSubmissionsResultsExport(Exercise exercise, Path exerciseDir, User user) throws IOException {
+ // quizzes do not have an assessment due date, so we need to check if they have ended according to their due date
+ boolean isInstructor = authCheckService.isAtLeastInstructorForExercise(exercise, user);
+ boolean includeResults = (exercise.isExamExercise() && exercise.getExamViaExerciseGroupOrCourseMember().resultsPublished())
+ || (exercise.isCourseExercise() && ExerciseDateService.isAfterAssessmentDueDate(exercise) && !(exercise instanceof QuizExercise))
+ || (exercise.isCourseExercise() && exercise instanceof QuizExercise quizExercise && quizExercise.isQuizEnded()) || isInstructor;
for (var participation : exercise.getStudentParticipations()) {
for (var submission : participation.getSubmissions()) {
createSubmissionCsvFile(submission, exerciseDir);
@@ -180,13 +207,22 @@ else if (submission instanceof ModelingSubmission modelingSubmission) {
else if (submission instanceof QuizSubmission) {
dataExportQuizExerciseCreationService.createQuizAnswersExport((QuizExercise) exercise, participation, exerciseDir, includeResults);
}
- if (includeResults) {
- createResultsAndComplaintFiles(submission, exerciseDir);
+ // for a programming exercise, we want to include the results that are visible before the assessment due date
+ if (includeResults || exercise instanceof ProgrammingExercise) {
+ boolean programmingExerciseBeforeAssessmentDueDate = exercise instanceof ProgrammingExercise && !ExerciseDateService.isAfterAssessmentDueDate(exercise);
+ createResultsAndComplaintFiles(submission, exerciseDir, user, programmingExerciseBeforeAssessmentDueDate, isInstructor);
}
}
}
}
+ /**
+ * Stores the modeling submission as pdf if the apollon profile is active and the apollon conversion service works, otherwise stores it as json file.
+ *
+ * @param modelingSubmission the modeling submission for which the content should be stored
+ * @param outputDir the directory in which the content should be stored
+ * @throws IOException if the file cannot be written
+ */
private void storeModelingSubmissionContent(ModelingSubmission modelingSubmission, Path outputDir) throws IOException {
if (modelingSubmission.getModel() == null) {
log.warn("Cannot include modeling submission content in data export because content is null for submission with id: {}", modelingSubmission.getId());
@@ -202,12 +238,22 @@ private void storeModelingSubmissionContent(ModelingSubmission modelingSubmissio
try (var modelAsPdf = apollonConversionService.get().convertModel(modelingSubmission.getModel())) {
Files.write(outputDir.resolve(fileName + PDF_FILE_EXTENSION), modelAsPdf.readAllBytes());
}
- catch (IOException e) {
+ catch (Exception e) {
log.warn("Failed to include the model as pdf, going to include it as plain JSON file.");
addModelJsonWithExplanationHowToView(modelingSubmission.getModel(), outputDir, fileName);
}
}
+ /**
+ * Stores the given model as json file and adds a markdown file with an explanation how to view the model.
+ *
+ * Used if the Apollon Conversion Service is not available or an error occurs while using it.
+ *
+ * @param model the model belonging to the submission as JSON string
+ * @param outputDir the directory in which the content should be stored
+ * @param fileName the file name of the JSON file
+ * @throws IOException if the file cannot be written
+ */
private void addModelJsonWithExplanationHowToView(String model, Path outputDir, String fileName) throws IOException {
Files.writeString(outputDir.resolve(fileName + ".json"), model);
String explanation = """
@@ -216,6 +262,13 @@ private void addModelJsonWithExplanationHowToView(String model, Path outputDir,
Files.writeString(outputDir.resolve("view_model.md"), explanation);
}
+ /**
+ * Stores the text submission content as txt file.
+ *
+ * @param textSubmission the text submission for which the content should be stored
+ * @param outputDir the directory in which the content should be stored
+ * @throws IOException if the file cannot be written
+ */
private void storeTextSubmissionContent(TextSubmission textSubmission, Path outputDir) throws IOException {
// text can be null which leads to an exception
if (textSubmission.getText() != null) {
@@ -226,32 +279,56 @@ private void storeTextSubmissionContent(TextSubmission textSubmission, Path outp
}
}
- private void createResultsAndComplaintFiles(Submission submission, Path outputDir) throws IOException {
+ /**
+ * Creates a txt file containing the results with the score, the number of passed test cases if it is a programming exercise
+ * and the feedbacks (both manual and automatic).
+ *
+ * @param submission the submission for which the results should be stored
+ * @param outputDir the directory in which the results should be stored
+ * @param user the user for which the export should be created
+ * @param programmingExerciseBeforeAssessmentDueDate whether the programming exercise is before the assessment due date
+ * @param isInstructor whether the user is an instructor in the course the exercise belongs to
+ * @throws IOException if the file cannot be written
+ */
+ private void createResultsAndComplaintFiles(Submission submission, Path outputDir, User user, boolean programmingExerciseBeforeAssessmentDueDate, boolean isInstructor)
+ throws IOException {
StringBuilder resultScoreAndFeedbacks = new StringBuilder();
for (var result : submission.getResults()) {
if (result != null) {
+ // Do not include the results if the assessment due date is in the future and the assessment is not automatic and the user is not an instructor
+ // We only consider programming exercises here because for other exercises this method is not called if the assessment due date is in the future
+ if (programmingExerciseBeforeAssessmentDueDate && result.getAssessmentType() != AssessmentType.AUTOMATIC && !isInstructor) {
+ continue;
+ }
+ resultService.filterSensitiveInformationIfNecessary(submission.getParticipation(), List.of(result), Optional.of(user));
var score = result.getScore();
if (score != null) {
resultScoreAndFeedbacks.append("Score of submission: ").append(score).append("%").append(" ")
- .append(score * submission.getParticipation().getExercise().getMaxPoints() / 100).append(" Points").append("\n");
+ .append(roundToNDecimalPlaces(score * submission.getParticipation().getExercise().getMaxPoints() / 100, 2)).append(" Points").append("\n");
}
if (submission instanceof ProgrammingSubmission && result.getPassedTestCaseCount() != null && result.getTestCaseCount() != null && result.getTestCaseCount() > 0) {
resultScoreAndFeedbacks.append("Passed test cases: ").append(result.getPassedTestCaseCount()).append("/").append(result.getTestCaseCount()).append("\n");
}
+ if (submission instanceof ProgrammingSubmission programmingSubmission && programmingSubmission.isBuildFailed()) {
+ resultScoreAndFeedbacks.append("Build failed").append("\n");
+ }
for (var feedback : result.getFeedbacks()) {
- resultScoreAndFeedbacks.append("- Feedback: ");
- // null if it's manual feedback
- if (feedback.getText() != null) {
- resultScoreAndFeedbacks.append(feedback.getText()).append("\t");
+ if (feedback != null) {
+ resultScoreAndFeedbacks.append("- Feedback: ");
+
+ // null if it's manual feedback
+ if (feedback.getText() != null) {
+ resultScoreAndFeedbacks.append(feedback.getText()).append("\t");
+ }
+ // null if the test case passes
+ if (feedback.getDetailText() != null) {
+ resultScoreAndFeedbacks.append(feedback.getDetailText()).append("\t");
+ }
+ if (feedback.getCredits() != null) {
+ resultScoreAndFeedbacks.append(feedback.getCredits());
+ }
+ resultScoreAndFeedbacks.append("\n");
}
- // null if the test case passes
- if (feedback.getDetailText() != null) {
- resultScoreAndFeedbacks.append(feedback.getDetailText()).append("\t");
- }
- if (feedback.getCredits() != null) {
- resultScoreAndFeedbacks.append(feedback.getCredits());
- }
- resultScoreAndFeedbacks.append("\n");
}
Files.writeString(outputDir.resolve("submission_" + submission.getId() + "_result_" + result.getId() + TXT_FILE_EXTENSION), resultScoreAndFeedbacks);
}
@@ -263,6 +340,15 @@ private void createResultsAndComplaintFiles(Submission submission, Path outputDi
}
}
+ /**
+ * Creates a CSV file containing the complaint data.
+ *
+ * Complaint can be either a complaint or a more feedback request.
+ *
+ * @param complaint the complaint for which the data should be stored
+ * @param outputDir the directory in which the data should be stored
+ * @throws IOException if the file cannot be written
+ */
private void addComplaintData(Complaint complaint, Path outputDir) throws IOException {
List
+ * This includes the id, the submission date and the commit hash if it is a programming exercise.
+ *
+ * @param submission the submission for which the information should be stored
+ * @param outputPath the directory in which the information should be stored
+ * @throws IOException if the file cannot be written
+ */
private void createSubmissionCsvFile(Submission submission, Path outputPath) throws IOException {
List
+ * This includes the id, the submission date and the commit hash if it is a programming exercise.
+ *
+ * @param submission the submission for which the information should be stored
+ * @return a stream of the submission information that should be included in the CSV file
+ */
private Stream> getSubmissionStreamToPrint(Submission submission) {
var builder = Stream.builder();
builder.add(submission.getId()).add(submission.getSubmissionDate());
diff --git a/src/main/java/de/tum/in/www1/artemis/service/dataexport/DataExportQuizExerciseCreationService.java b/src/main/java/de/tum/in/www1/artemis/service/dataexport/DataExportQuizExerciseCreationService.java
index bcc98cd6dedb..6b51e2ecf0ff 100644
--- a/src/main/java/de/tum/in/www1/artemis/service/dataexport/DataExportQuizExerciseCreationService.java
+++ b/src/main/java/de/tum/in/www1/artemis/service/dataexport/DataExportQuizExerciseCreationService.java
@@ -16,7 +16,10 @@
import de.tum.in.www1.artemis.service.DragAndDropQuizAnswerConversionService;
/**
- * A service to create the data export for quiz exercise participations
+ * A service to create the data export for quiz exercise participations.
+ * This includes creating a pdf highlighting the submitted answers for drag and drop questions and
+ * txt files containing the submitted answers for multiple choice and short answer questions.
+ * Additionally, the results can be included in the export if the due date is over.
*/
@Service
public class DataExportQuizExerciseCreationService {
@@ -80,6 +83,13 @@ else if (submittedAnswer instanceof MultipleChoiceSubmittedAnswer multipleChoice
}
+ /**
+ * Creates a txt file containing the submitted answers for a multiple choice question and information if the answer was correct or not if includeResults is true.
+ *
+ * @param multipleChoiceSubmittedAnswer the submitted answer to a multiple choice question that should be included in the export
+ * @param includeResults true if the results should be included in the export (if the assessment due date or result publication date is over)
+ * @return the content for the txt file as a string
+ */
private String createExportForMultipleChoiceAnswerQuestion(MultipleChoiceSubmittedAnswer multipleChoiceSubmittedAnswer, boolean includeResults) {
StringBuilder stringBuilder = new StringBuilder();
MultipleChoiceQuestion question = (MultipleChoiceQuestion) multipleChoiceSubmittedAnswer.getQuizQuestion();
@@ -105,6 +115,15 @@ private String createExportForMultipleChoiceAnswerQuestion(MultipleChoiceSubmitt
return stringBuilder.toString();
}
+ /**
+ * Adds an explanation to the answer option if no result should be included in the export.
+ *
+ * The explanation contains information if the answer option was selected or not or if it is invalid.
+ *
+ * @param multipleChoiceSubmittedAnswer the submitted answer to a multiple choice question that should be included in the export
+ * @param stringBuilder the string builder user to create the txt file content
+ * @param answerOption the answer option for which the explanation should be added
+ */
private void addExplanationToAnswerOptionWithoutResult(MultipleChoiceSubmittedAnswer multipleChoiceSubmittedAnswer, StringBuilder stringBuilder, AnswerOption answerOption) {
if (answerOption.isInvalid()) {
stringBuilder.append("Invalid answer option: ");
@@ -117,6 +136,15 @@ else if (multipleChoiceSubmittedAnswer.getSelectedOptions().contains(answerOptio
}
}
+ /**
+ * Adds an explanation to the answer option if a result should be included in the export.
+ *
+ * The explanation contains information if the answer option was selected or not or it is invalid and if the answer option is correct or not.
+ *
+ * @param multipleChoiceSubmittedAnswer the submitted answer to a multiple choice question that should be included in the export
+ * @param stringBuilder the string builder user to create the txt file content
+ * @param answerOption the answer option for which the explanation should be added
+ */
private void addExplanationToAnswerOptionWithResult(MultipleChoiceSubmittedAnswer multipleChoiceSubmittedAnswer, StringBuilder stringBuilder, AnswerOption answerOption) {
if (answerOption.isInvalid()) {
stringBuilder.append("Invalid answer option: ");
@@ -135,6 +163,13 @@ else if (!answerOption.isIsCorrect() && !multipleChoiceSubmittedAnswer.getSelect
}
}
+ /**
+ * Creates a txt file containing the submitted answers for a short answer question and information if the answer was correct or not if includeResults is true.
+ *
+ * @param shortAnswerSubmittedAnswer the submitted answer to a short answer question that should be included in the export
+ * @param includeResults true if the results should be included in the export (if the assessment due date or result publication date is over)
+ * @return the content for the txt file as a string
+ */
private String createExportForShortAnswerQuestion(ShortAnswerSubmittedAnswer shortAnswerSubmittedAnswer, boolean includeResults) {
StringBuilder stringBuilder = new StringBuilder();
ShortAnswerQuestion question = (ShortAnswerQuestion) shortAnswerSubmittedAnswer.getQuizQuestion();
@@ -145,6 +180,14 @@ private String createExportForShortAnswerQuestion(ShortAnswerSubmittedAnswer sho
return replaceSpotWithSubmittedAnswer(shortAnswerSubmittedAnswer, stringBuilder, includeResults);
}
+ /**
+ * Replaces the spots (the gaps that indicate where an answer should be entered) in the text of a short answer question with the submitted answers.
+ *
+ * @param shortAnswerSubmittedAnswer the submitted answer to a short answer question that should be included in the export
+ * @param submittedAnswer the string builder user to create the txt file content
+ * @param includeResults true if the results should be included in the export (if the assessment due date or result publication date is over)
+ * @return the string containing the question text with the answers of the user
+ */
private String replaceSpotWithSubmittedAnswer(ShortAnswerSubmittedAnswer shortAnswerSubmittedAnswer, StringBuilder submittedAnswer, boolean includeResults) {
var spotToSubmittedTextMap = buildMapFromSpotsToSubmittedAnswers(shortAnswerSubmittedAnswer);
submittedAnswer.append("Your answer: ").append("\n");
@@ -160,30 +203,39 @@ private String replaceSpotWithSubmittedAnswer(ShortAnswerSubmittedAnswer shortAn
return submittedAnswer.toString();
}
+ /**
+ * Adds the submitted answer to the string builder if the answer is correct or incorrect.
+ *
+ * @param submittedAnswer the string builder user to create the txt file content
+ * @param includeResults true if the results should be included in the export (if the assessment due date or result publication date is over)
+ * @param submittedText the question text of a short answer question that should be included in the export
+ * @param pattern the pattern used to find the spot in the question text
+ * @param matcher the matcher used to find the spot in the question text
+ * @param replacement the string builder used to create the replacement (the submitted answer text) for the spot
+ * @return the matcher used to find the next spot in the question text
+ */
private Matcher addSubmittedAnswerWithResult(StringBuilder submittedAnswer, boolean includeResults, ShortAnswerSubmittedText submittedText, Pattern pattern, Matcher matcher,
StringBuilder replacement) {
int start = matcher.start();
int end = matcher.end();
- if (submittedText.isIsCorrect() != null && submittedText.isIsCorrect()) {
- replacement.append(submittedText.getText());
- if (includeResults) {
- replacement.append(" (Correct)");
- }
+ replacement.append(submittedText.getText());
+ if (submittedText.isIsCorrect() != null && submittedText.isIsCorrect() && includeResults) {
+ replacement.append(" (Correct)");
}
- else if (submittedText.isIsCorrect() != null && !submittedText.isIsCorrect()) {
- replacement.append(submittedText.getText());
- if (includeResults) {
- replacement.append(" (Incorrect)");
- }
- else {
- replacement.append(submittedText.getText());
- }
- submittedAnswer.replace(start, end, replacement.toString());
- matcher = pattern.matcher(submittedAnswer);
+ else if (submittedText.isIsCorrect() != null && !submittedText.isIsCorrect() && includeResults) {
+ replacement.append(" (Incorrect)");
}
+ submittedAnswer.replace(start, end, replacement.toString());
+ matcher = pattern.matcher(submittedAnswer);
return matcher;
}
+ /**
+ * Builds a map from the spots (the gaps that indicate where an answer should be entered) in the text of a short answer question to the submitted answers.
+ *
+ * @param shortAnswerSubmittedAnswer the submitted answer to a short answer question that should be included in the export
+ * @return a map from the spots (represented as the string in text) to the submitted answers
+ */
private Map
+ * This is the date when the last data export was requested (stored in the createdDate) + the constant DAYS_BETWEEN_DATA_EXPORTS.
+ * By default, DAYS_BETWEEN_DATA_EXPORTS is set to 14 days.
+ * This can be changed by setting the property artemis.data-export.days-between-data-exports in the application.yml file.
+ *
+ * @param dataExport the data export for which the next request date should be calculated
+ * @return the next date when the user can request a data export
+ */
@NotNull
private ZonedDateTime retrieveNextRequestDate(DataExport dataExport) {
return dataExport.getCreatedDate().atZone(ZoneId.systemDefault()).plusDays(DAYS_BETWEEN_DATA_EXPORTS);
@@ -148,4 +161,18 @@ public void deleteDataExportAndSetDataExportState(DataExport dataExport) {
dataExportRepository.save(dataExport);
}
+ /**
+ * Checks if the data export can be downloaded.
+ *
+ * The data export can be downloaded if its state is either EMAIL_SENT or DOWNLOADED.
+ *
+ * @param dataExport the data export to check
+ * @throws AccessForbiddenException if the data export is not in a downloadable state
+ */
+ public void checkDataExportCanBeDownloadedElseThrow(DataExport dataExport) {
+ if (!dataExport.getDataExportState().isDownloadable()) {
+ throw new AccessForbiddenException("Data export has either not been created or already been deleted");
+ }
+ }
+
}
diff --git a/src/main/java/de/tum/in/www1/artemis/service/dataexport/DataExportUtil.java b/src/main/java/de/tum/in/www1/artemis/service/dataexport/DataExportUtil.java
index 8c711062d08c..b275ec861b7e 100644
--- a/src/main/java/de/tum/in/www1/artemis/service/dataexport/DataExportUtil.java
+++ b/src/main/java/de/tum/in/www1/artemis/service/dataexport/DataExportUtil.java
@@ -17,12 +17,25 @@ private DataExportUtil() {
// Utility class
}
+ /**
+ * Creates the given directory if it does not exist yet.
+ *
+ * @param directory the directory to create
+ * @throws IOException if an error occurs while accessing the file system
+ */
static void createDirectoryIfNotExistent(Path directory) throws IOException {
if (!Files.exists(directory)) {
- Files.createDirectory(directory);
+ Files.createDirectories(directory);
}
}
+ /**
+ * Retrieves the path to the directory for the given course within the data export.
+ *
+ * @param workingDirectory the working directory where the data export is created
+ * @param course the course for which the directory should be retrieved
+ * @return the path to the directory for the given course
+ */
static Path retrieveCourseDirPath(Path workingDirectory, Course course) {
return workingDirectory.resolve(COURSE_DIRECTORY_PREFIX + course.getShortName());
}
diff --git a/src/main/java/de/tum/in/www1/artemis/service/exam/ExamUserService.java b/src/main/java/de/tum/in/www1/artemis/service/exam/ExamUserService.java
index f60e68c2a921..cd2aabaaad9f 100644
--- a/src/main/java/de/tum/in/www1/artemis/service/exam/ExamUserService.java
+++ b/src/main/java/de/tum/in/www1/artemis/service/exam/ExamUserService.java
@@ -6,6 +6,7 @@
import java.util.List;
import java.util.Optional;
+import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripperByArea;
import org.slf4j.Logger;
@@ -51,7 +52,7 @@ public ExamUserService(FileService fileService, UserRepository userRepository, E
*/
public List
+ * This is the case if the user has not requested a data export yet or if the last data export was created more than DAYS_BETWEEN_DATA_EXPORTS days ago.
*
* @return true if the user can request a new data export, false otherwise
*/
private boolean canRequestDataExport() {
var user = userRepository.getUser();
- var dataExports = dataExportRepository.findAllDataExportsByUserId(user.getId());
+ var dataExports = dataExportRepository.findAllDataExportsByUserIdOrderByRequestDateDesc(user.getId());
if (dataExports.isEmpty()) {
return true;
}
- var latestDataExport = dataExports.stream().max(Comparator.comparing(DataExport::getCreatedDate)).get();
+ // because we order by request date desc, the first data export is the latest one
+ var latestDataExport = dataExports.get(0);
var olderThanDaysBetweenDataExports = Duration.between(latestDataExport.getCreatedDate().atZone(ZoneId.systemDefault()), ZonedDateTime.now())
.toDays() >= DAYS_BETWEEN_DATA_EXPORTS;
@@ -82,7 +84,12 @@ private boolean canRequestDataExport() {
}
/**
- * Download the data export for the given user
+ * GET /data-exports/{dataExportId}: Download the data export for the given id.
+ *
+ * We check if the user is the owner of the data export and if the data export can be downloaded.
+ * If this is the case, we return a resource containing the data export zip file.
+ * The file name is set to the name of the zip file.
+ * The content disposition header is set to attachment so that the browser will download the file instead of displaying it.
*
* @param dataExportId the id of the data export to download
* @return A resource containing the data export zip file
@@ -92,20 +99,18 @@ private boolean canRequestDataExport() {
public ResponseEntity
+
{{ 'artemisApp.dataExport.nextRequestDate' | artemisTranslate }}
{{ dataExport?.nextRequestDate | artemisDate: 'long-date' }}
id="download-data-export-btn"
[btnSize]="ButtonSize.LARGE"
[disabled]="!canDownload"
- title="artemisApp.dataExport.download"
+ [tooltip]="'artemisApp.dataExport.download'"
+ [title]="'artemisApp.dataExport.download'"
(onClick)="downloadDataExport()"
>
@@ -33,7 +34,7 @@
{{ 'artemisApp.dataExport.lastRequestDate' | artemisTranslate }}
{{ dataExport?.createdDate | artemisDate: 'long-date' }}
' + text + '';
+ html[index] = '' + text + '';
break;
case DiffOperation.DIFF_EQUAL:
html[index] = text;
@@ -116,5 +156,5 @@ export class ExamExerciseUpdateHighlighterComponent implements OnInit {
}
});
return html.join('');
- };
+ }
}
diff --git a/src/main/webapp/app/exam/participate/exercises/exam-exercise-update-highlighter/exam-exercise-update-highlighter.module.ts b/src/main/webapp/app/exam/participate/exercises/exam-exercise-update-highlighter/exam-exercise-update-highlighter.module.ts
new file mode 100644
index 000000000000..30e5255744b1
--- /dev/null
+++ b/src/main/webapp/app/exam/participate/exercises/exam-exercise-update-highlighter/exam-exercise-update-highlighter.module.ts
@@ -0,0 +1,10 @@
+import { NgModule } from '@angular/core';
+import { ArtemisSharedCommonModule } from 'app/shared/shared-common.module';
+import { ExamExerciseUpdateHighlighterComponent } from 'app/exam/participate/exercises/exam-exercise-update-highlighter/exam-exercise-update-highlighter.component';
+
+@NgModule({
+ declarations: [ExamExerciseUpdateHighlighterComponent],
+ imports: [ArtemisSharedCommonModule],
+ exports: [ExamExerciseUpdateHighlighterComponent],
+})
+export class ExamExerciseUpdateHighlighterModule {}
diff --git a/src/main/webapp/app/exercises/file-upload/manage/file-upload-exercise-management.module.ts b/src/main/webapp/app/exercises/file-upload/manage/file-upload-exercise-management.module.ts
index 0b704a7bc039..2e0795a8afb2 100644
--- a/src/main/webapp/app/exercises/file-upload/manage/file-upload-exercise-management.module.ts
+++ b/src/main/webapp/app/exercises/file-upload/manage/file-upload-exercise-management.module.ts
@@ -20,6 +20,7 @@ import { NonProgrammingExerciseDetailCommonActionsModule } from 'app/exercises/s
import { ArtemisSharedComponentModule } from 'app/shared/components/shared-component.module';
import { ExerciseCategoriesModule } from 'app/shared/exercise-categories/exercise-categories.module';
import { ExerciseTitleChannelNameModule } from 'app/exercises/shared/exercise-title-channel-name/exercise-title-channel-name.module';
+import { ExerciseUpdateNotificationModule } from 'app/exercises/shared/exercise-update-notification/exercise-update-notification.module';
@NgModule({
imports: [
@@ -41,6 +42,7 @@ import { ExerciseTitleChannelNameModule } from 'app/exercises/shared/exercise-ti
ArtemisSharedComponentModule,
ExerciseCategoriesModule,
ExerciseTitleChannelNameModule,
+ ExerciseUpdateNotificationModule,
],
declarations: [FileUploadExerciseComponent, FileUploadExerciseDetailComponent, FileUploadExerciseUpdateComponent],
exports: [FileUploadExerciseComponent],
diff --git a/src/main/webapp/app/exercises/file-upload/manage/file-upload-exercise-update.component.html b/src/main/webapp/app/exercises/file-upload/manage/file-upload-exercise-update.component.html
index e4740153ec82..71b190057fb9 100644
--- a/src/main/webapp/app/exercises/file-upload/manage/file-upload-exercise-update.component.html
+++ b/src/main/webapp/app/exercises/file-upload/manage/file-upload-exercise-update.component.html
@@ -197,10 +197,7 @@ Assessment Instructions