From 412e2a6ffe265ae7109fd20c7758f4e6aad2f31a Mon Sep 17 00:00:00 2001 From: Maximilian Anzinger <44003963+MaximilianAnzinger@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:31:15 +0200 Subject: [PATCH 01/49] Atlas: Fix creation of competency relations (#9327) --- .../competency-relation-graph.component.html | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/webapp/app/course/competencies/competency-management/competency-relation-graph.component.html b/src/main/webapp/app/course/competencies/competency-management/competency-relation-graph.component.html index 85abe072e64a..1be5b1aa75c3 100644 --- a/src/main/webapp/app/course/competencies/competency-management/competency-relation-graph.component.html +++ b/src/main/webapp/app/course/competencies/competency-management/competency-relation-graph.component.html @@ -40,6 +40,7 @@ } From 5144408b2c9e22377fb6191c4058592e9d06734f Mon Sep 17 00:00:00 2001 From: Stephan Krusche Date: Wed, 18 Sep 2024 20:31:47 +0200 Subject: [PATCH 02/49] Development: Configure Mend Bolt for GitHub --- .whitesource | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .whitesource diff --git a/.whitesource b/.whitesource new file mode 100644 index 000000000000..9c7ae90b4ec3 --- /dev/null +++ b/.whitesource @@ -0,0 +1,14 @@ +{ + "scanSettings": { + "baseBranches": [] + }, + "checkRunSettings": { + "vulnerableCheckRunConclusionLevel": "failure", + "displayMode": "diff", + "useMendCheckNames": true + }, + "issueSettings": { + "minSeverityLevel": "LOW", + "issueType": "DEPENDENCY" + } +} \ No newline at end of file From 68158356a655aca0547628c24c124ca6b3d464a8 Mon Sep 17 00:00:00 2001 From: Stephan Krusche Date: Wed, 18 Sep 2024 20:32:29 +0200 Subject: [PATCH 03/49] Development: Bump version to 7.5.4 --- README.md | 2 +- build.gradle | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4cd94a4e4278..040487b2ae20 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,7 @@ Refer to [Using JHipster in production](http://www.jhipster.tech/production) for The following command can automate the deployment to a server. The example shows the deployment to the main Artemis test server (which runs a virtual machine): ```shell -./artemis-server-cli deploy username@artemistest.ase.in.tum.de -w build/libs/Artemis-7.5.3.war +./artemis-server-cli deploy username@artemistest.ase.in.tum.de -w build/libs/Artemis-7.5.4.war ``` ## Architecture diff --git a/build.gradle b/build.gradle index 9fb031da325f..8e18d5db388c 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ plugins { } group = "de.tum.cit.aet.artemis" -version = "7.5.3" +version = "7.5.4" description = "Interactive Learning with Individual Feedback" java { diff --git a/package-lock.json b/package-lock.json index 1418d86ae999..22be3d641330 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "artemis", - "version": "7.5.3", + "version": "7.5.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "artemis", - "version": "7.5.3", + "version": "7.5.4", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 28e9fc7a90fc..65f810fa96dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "artemis", - "version": "7.5.3", + "version": "7.5.4", "description": "Interactive Learning with Individual Feedback", "private": true, "license": "MIT", From 128fd449925b98c946919a9dbb251a56811b22ad Mon Sep 17 00:00:00 2001 From: Stephan Krusche Date: Wed, 18 Sep 2024 21:18:25 +0200 Subject: [PATCH 04/49] Development: Update client dependencies --- package-lock.json | 465 +++++++++++++++++++++++++--------------------- package.json | 45 ++--- 2 files changed, 273 insertions(+), 237 deletions(-) diff --git a/package-lock.json b/package-lock.json index 22be3d641330..bb5825b0477e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,18 +10,18 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { - "@angular/animations": "18.2.4", + "@angular/animations": "18.2.5", "@angular/cdk": "18.2.4", - "@angular/common": "18.2.4", - "@angular/compiler": "18.2.4", - "@angular/core": "18.2.4", - "@angular/forms": "18.2.4", - "@angular/localize": "18.2.4", + "@angular/common": "18.2.5", + "@angular/compiler": "18.2.5", + "@angular/core": "18.2.5", + "@angular/forms": "18.2.5", + "@angular/localize": "18.2.5", "@angular/material": "18.2.4", - "@angular/platform-browser": "18.2.4", - "@angular/platform-browser-dynamic": "18.2.4", - "@angular/router": "18.2.4", - "@angular/service-worker": "18.2.4", + "@angular/platform-browser": "18.2.5", + "@angular/platform-browser-dynamic": "18.2.5", + "@angular/router": "18.2.5", + "@angular/service-worker": "18.2.5", "@ctrl/ngx-emoji-mart": "9.2.0", "@danielmoncada/angular-datetime-picker": "18.1.0", "@fingerprintjs/fingerprintjs": "4.5.0", @@ -60,7 +60,7 @@ "ngx-webstorage": "18.0.0", "papaparse": "5.4.1", "pdfjs-dist": "4.6.82", - "posthog-js": "1.161.3", + "posthog-js": "1.161.6", "rxjs": "7.8.1", "showdown": "2.1.0", "showdown-highlight": "3.1.0", @@ -85,22 +85,22 @@ "@angular-eslint/schematics": "18.3.1", "@angular-eslint/template-parser": "18.3.1", "@angular/cli": "18.2.4", - "@angular/compiler-cli": "18.2.4", - "@angular/language-service": "18.2.4", + "@angular/compiler-cli": "18.2.5", + "@angular/language-service": "18.2.5", "@sentry/types": "8.30.0", "@types/crypto-js": "4.2.2", "@types/d3-shape": "3.1.6", "@types/dompurify": "3.0.5", "@types/jest": "29.5.13", "@types/lodash-es": "4.17.12", - "@types/node": "22.5.4", + "@types/node": "22.5.5", "@types/papaparse": "5.3.14", "@types/showdown": "2.0.6", "@types/smoothscroll-polyfill": "0.3.4", "@types/sockjs-client": "1.5.4", "@types/uuid": "10.0.0", - "@typescript-eslint/eslint-plugin": "8.5.0", - "@typescript-eslint/parser": "8.5.0", + "@typescript-eslint/eslint-plugin": "8.6.0", + "@typescript-eslint/parser": "8.6.0", "eslint": "9.10.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-deprecation": "3.0.0", @@ -120,7 +120,7 @@ "ng-mocks": "14.13.1", "prettier": "3.3.3", "rimraf": "6.0.1", - "sass": "1.78.0", + "sass": "1.79.1", "ts-jest": "29.2.5", "typescript": "5.5.4", "weak-napi": "2.0.2" @@ -548,9 +548,9 @@ } }, "node_modules/@angular/animations": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.4.tgz", - "integrity": "sha512-ajjXpLD+SyxbHnmhj2ZvYpXneviOjcBgU9L2UX4OVS0jVWxCNHLhJrcMqtqFHA6U5fPnhPNR9cmnt6tmqri0rA==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.5.tgz", + "integrity": "sha512-IlXtW/Nj48ZzjHUzH1TykZcSR64ScJx39T3IHnjV2z/bVATzZ36JGoadQHdqpJNKBodYJNgtJCGLCbgAvGWY2g==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -559,7 +559,7 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "18.2.4" + "@angular/core": "18.2.5" } }, "node_modules/@angular/build": { @@ -701,9 +701,9 @@ } }, "node_modules/@angular/common": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.4.tgz", - "integrity": "sha512-flUaKhdr8KvtjH0cLC6Rrjirt8GsiFlrmZLZplr784O3Gkei2VBBNFoopgmlEzbVGPiIG5QlFZH9yvah6JPQZw==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.5.tgz", + "integrity": "sha512-m+KJrtbFXTE36jP/po6UAMeUR/enQxRHpVGLCRcIcE7VWVH1ZcOvoW1yqh2A6k+KxWXeajlq/Z04nnMhcoxMRw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -712,14 +712,14 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "18.2.4", + "@angular/core": "18.2.5", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.4.tgz", - "integrity": "sha512-o3ngFr1Bjt7cKOu4DSZJGCUF9YPTxJee97wFon2eNFj6FFNTmnGwAvsnJjHBMmk90fmZLC2/HpPdhYz7WprMZQ==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.5.tgz", + "integrity": "sha512-vcqe9x4dGGAnMfPhEpcZyiSVgAiqJeK80LqP1vWoAmBR+HeOqAilSv6SflcLAtuTzwgzMMAvD2T+SMCgUvaqww==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -728,7 +728,7 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "18.2.4" + "@angular/core": "18.2.5" }, "peerDependenciesMeta": { "@angular/core": { @@ -737,9 +737,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.4.tgz", - "integrity": "sha512-BIp5zr+npqSs/4KWPxwKdn7+sjo008ieNOQDlXyQms9BKlxx/gDnj7W2TsxhrkDTYCIHF73fJZ7u2U8Qy4JWfw==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.5.tgz", + "integrity": "sha512-CCCtZobUTUfId/RTYtuDCw5R1oK0w65hdAUMRP1MdGmd8bb8DKJA86u1QCWwozL3rbXlIIX4ognQ6urQ43k/Gw==", "license": "MIT", "dependencies": { "@babel/core": "7.25.2", @@ -760,14 +760,14 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/compiler": "18.2.4", + "@angular/compiler": "18.2.5", "typescript": ">=5.4 <5.6" } }, "node_modules/@angular/core": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.4.tgz", - "integrity": "sha512-ulYmYpI/ZVQ5BL38rBy4DS/9wgGWmVD9Uo6tcrLqCzt1G1G2nKwseZv009536pHfk6dj2HdPSkpcerhWh57DWw==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.5.tgz", + "integrity": "sha512-5BLVc5gXxzanQkADNS9WPsor3vNF5nQcyIHBi5VScErwM5vVZ7ATH1iZwaOg1ykDEVTFVhKDwD0X1aaqGDbhmQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -781,9 +781,9 @@ } }, "node_modules/@angular/forms": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.4.tgz", - "integrity": "sha512-rlLhReauUz6jhLCEkGabLqqF6xLaTfvxafuj2ojzcqoKGSZcXDIM/UOSoWX756B8NtrpsuglpGBZjZlsrAZGsg==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.5.tgz", + "integrity": "sha512-ohKeH+EZCCIyGSiFYlraWLzssGAZc13P92cuYpXB62322PkcA5u0IT72mML9JWGKRqF2zteVsw4koWHVxXM5mA==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -792,16 +792,16 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.2.4", - "@angular/core": "18.2.4", - "@angular/platform-browser": "18.2.4", + "@angular/common": "18.2.5", + "@angular/core": "18.2.5", + "@angular/platform-browser": "18.2.5", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/language-service": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-18.2.4.tgz", - "integrity": "sha512-Keg6n8u8xHLhRDTmx4hUqh1AtVFUt8hDxPMYSUu64czjOT5Dnh8XsgKagu563NEjxbDaCzttPuO+y3DlcaDZoQ==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-18.2.5.tgz", + "integrity": "sha512-JE6ck4UWXayiG8ptJJtkrKCjy+5Ftktgsoj4QGdQzMhbpia7Wge5XDj28o+bwEFndRnP6ihRtud63IvOz9aKFQ==", "dev": true, "license": "MIT", "engines": { @@ -809,9 +809,9 @@ } }, "node_modules/@angular/localize": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-18.2.4.tgz", - "integrity": "sha512-3QgfYNwM4Dkd7sWu/JXZfOToporIrgdyi/G8T2zgTtArbvPNbZdSmihpSjKVmsDzB4ScXlOCH/sf0rLKIYkKwQ==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-18.2.5.tgz", + "integrity": "sha512-kteBBkSmmmpMrHAIlxFK/PB9HemJ8OBo/qAGOqCGbvPHLMHdR7cxaMGL+Lkya/QhwhqlhoxUcE5zFWXl7UslNg==", "license": "MIT", "dependencies": { "@babel/core": "7.25.2", @@ -828,8 +828,8 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/compiler": "18.2.4", - "@angular/compiler-cli": "18.2.4" + "@angular/compiler": "18.2.5", + "@angular/compiler-cli": "18.2.5" } }, "node_modules/@angular/material": { @@ -851,9 +851,9 @@ } }, "node_modules/@angular/platform-browser": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.4.tgz", - "integrity": "sha512-ddzq5MyPvFyTv0kUe8U9fbhE1nZtLYBCFKDqICrzHXiVRAdqLv6qtE5PtbURrdspSy1u/YEGV4LdkNJK3UgnZQ==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.5.tgz", + "integrity": "sha512-PoX9idwnOpTJBlujzZ2nFGOsmCnZzOH7uNSWIR7trdoq0b1AFXfrxlCQ36qWamk7bbhJI4H28L8YTmKew/nXDA==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -862,9 +862,9 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/animations": "18.2.4", - "@angular/common": "18.2.4", - "@angular/core": "18.2.4" + "@angular/animations": "18.2.5", + "@angular/common": "18.2.5", + "@angular/core": "18.2.5" }, "peerDependenciesMeta": { "@angular/animations": { @@ -873,9 +873,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.4.tgz", - "integrity": "sha512-0nA04zJueGzdnl37TJ7guDCrzxYS4fjqgvYKiOpFktpMHPuNrBlAQo5YA7u20HGFG3i47PQh7hEWhQaqcXXpQw==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.5.tgz", + "integrity": "sha512-5u0IuAt1r5e2u2vSKhp3phnaf6hH89B/q7GErfPse1sdDfNI6wHVppxai28PAfAj9gwooJun6MjFWhJFLzS44A==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -884,16 +884,16 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.2.4", - "@angular/compiler": "18.2.4", - "@angular/core": "18.2.4", - "@angular/platform-browser": "18.2.4" + "@angular/common": "18.2.5", + "@angular/compiler": "18.2.5", + "@angular/core": "18.2.5", + "@angular/platform-browser": "18.2.5" } }, "node_modules/@angular/router": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.4.tgz", - "integrity": "sha512-kYNHD3K1Xou2PRMqbG2tVahtMobgDlhwHdMB7G5oFHg6K13gQ2TmopF1U5A2wYtIMdsC+AkVGIJEOxQN8fmgcA==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.5.tgz", + "integrity": "sha512-OjZV1PTiSwT0ytmR0ykveLYzs4uQWf0EuIclZmWqM/bb8Q4P+gJl7/sya05nGnZsj6nHGOL0e/LhSZ3N+5p6qg==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -902,16 +902,16 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.2.4", - "@angular/core": "18.2.4", - "@angular/platform-browser": "18.2.4", + "@angular/common": "18.2.5", + "@angular/core": "18.2.5", + "@angular/platform-browser": "18.2.5", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/service-worker": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-18.2.4.tgz", - "integrity": "sha512-yvdHWtD9m70JE9kPapu819f7g0rsBKvIs1FebS7/fvt4Cj7B6+0xSCnoiQPDE5hpRl8qSk/8eikFcGVM/D8F8g==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-18.2.5.tgz", + "integrity": "sha512-MoF2n7z/X+yqK89mIRHQutVHIBTyEUo/fDEL8LcuBP4KOZmX9cRoCEt+vqH49BkArsgOM0jNFMYCM8yt0jg7pw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -923,8 +923,8 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.2.4", - "@angular/core": "18.2.4" + "@angular/common": "18.2.5", + "@angular/core": "18.2.5" } }, "node_modules/@babel/code-frame": { @@ -3288,9 +3288,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", + "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", "dev": true, "license": "MIT", "engines": { @@ -3605,19 +3605,18 @@ } }, "node_modules/@inquirer/core": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.1.0.tgz", - "integrity": "sha512-RZVfH//2ytTjmaBIzeKT1zefcQZzuruwkpTwwbe/i2jTl4o9M+iML5ChULzz6iw1Ok8iUBBsRCjY2IEbD8Ft4w==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.2.1.tgz", + "integrity": "sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/figures": "^1.0.5", - "@inquirer/type": "^1.5.3", + "@inquirer/figures": "^1.0.6", + "@inquirer/type": "^2.0.0", "@types/mute-stream": "^0.0.4", - "@types/node": "^22.5.2", + "@types/node": "^22.5.5", "@types/wrap-ansi": "^3.0.0", "ansi-escapes": "^4.3.2", - "cli-spinners": "^2.9.2", "cli-width": "^4.1.0", "mute-stream": "^1.0.0", "signal-exit": "^4.1.0", @@ -3629,6 +3628,19 @@ "node": ">=18" } }, + "node_modules/@inquirer/core/node_modules/@inquirer/type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-2.0.0.tgz", + "integrity": "sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==", + "dev": true, + "license": "MIT", + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@inquirer/editor": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-2.2.0.tgz", @@ -3660,9 +3672,9 @@ } }, "node_modules/@inquirer/figures": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.5.tgz", - "integrity": "sha512-79hP/VWdZ2UVc9bFGJnoQ/lQMpL74mGgzSYX1xUqCVk7/v73vJCMw1VuyWN1jGkZ9B3z7THAbySqGbCNefcjfA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.6.tgz", + "integrity": "sha512-yfZzps3Cso2UbM7WlxKwZQh2Hs6plrbjs1QnzQDZhK2DgyCo6D8AaHps9olkNcUFlcYERMqU3uJSp1gmy3s/qQ==", "dev": true, "license": "MIT", "engines": { @@ -3783,9 +3795,9 @@ } }, "node_modules/@inquirer/type": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.3.tgz", - "integrity": "sha512-xUQ14WQGR/HK5ei+2CvgcwoH9fQ4PgPGmVFSN0pc1+fVyDL3MREhyAY7nxEErSu6CkllBM3D7e3e+kOvtu+eIg==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", + "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", "dev": true, "license": "MIT", "dependencies": { @@ -5413,9 +5425,9 @@ } }, "node_modules/@npmcli/package-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.0.tgz", - "integrity": "sha512-qe/kiqqkW0AGtvBjL8TJKZk/eBBSpnJkUWvHdQ9jM2lKHXRYYJuyNpJPlJw3c8QjC2ow6NZYiLExhUaeJelbxQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.1.tgz", + "integrity": "sha512-f7zYC6kQautXHvNbLEWgD/uGu1+xCn9izgqBfgItWSx22U0ZDekxN08A1vM8cTxj/cRVe0Q94Ode+tdoYmIOOQ==", "dev": true, "license": "ISC", "dependencies": { @@ -6584,9 +6596,9 @@ } }, "node_modules/@types/node": { - "version": "22.5.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", - "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", + "version": "22.5.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", + "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", "dev": true, "license": "MIT", "dependencies": { @@ -6614,15 +6626,15 @@ } }, "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "version": "15.7.13", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", + "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", "license": "MIT" }, "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "version": "6.9.16", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", + "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", "dev": true, "license": "MIT" }, @@ -6634,9 +6646,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "18.3.5", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.5.tgz", - "integrity": "sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==", + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.7.tgz", + "integrity": "sha512-KUnDCJF5+AiZd8owLIeVHqmW9yM4sqmDVf2JRJiBMFkGvkoZ4/WyV2lL4zVsoinmRS/W3FeEdZLEWFRofnT2FQ==", "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -6790,17 +6802,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.5.0.tgz", - "integrity": "sha512-lHS5hvz33iUFQKuPFGheAB84LwcJ60G8vKnEhnfcK1l8kGVLro2SFYW6K0/tj8FUhRJ0VHyg1oAfg50QGbPPHw==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.6.0.tgz", + "integrity": "sha512-UOaz/wFowmoh2G6Mr9gw60B1mm0MzUtm6Ic8G2yM1Le6gyj5Loi/N+O5mocugRGY+8OeeKmkMmbxNqUCq3B4Sg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.5.0", - "@typescript-eslint/type-utils": "8.5.0", - "@typescript-eslint/utils": "8.5.0", - "@typescript-eslint/visitor-keys": "8.5.0", + "@typescript-eslint/scope-manager": "8.6.0", + "@typescript-eslint/type-utils": "8.6.0", + "@typescript-eslint/utils": "8.6.0", + "@typescript-eslint/visitor-keys": "8.6.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -6824,16 +6836,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.5.0.tgz", - "integrity": "sha512-gF77eNv0Xz2UJg/NbpWJ0kqAm35UMsvZf1GHj8D9MRFTj/V3tAciIWXfmPLsAAF/vUlpWPvUDyH1jjsr0cMVWw==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.6.0.tgz", + "integrity": "sha512-eQcbCuA2Vmw45iGfcyG4y6rS7BhWfz9MQuk409WD47qMM+bKCGQWXxvoOs1DUp+T7UBMTtRTVT+kXr7Sh4O9Ow==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "8.5.0", - "@typescript-eslint/types": "8.5.0", - "@typescript-eslint/typescript-estree": "8.5.0", - "@typescript-eslint/visitor-keys": "8.5.0", + "@typescript-eslint/scope-manager": "8.6.0", + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/typescript-estree": "8.6.0", + "@typescript-eslint/visitor-keys": "8.6.0", "debug": "^4.3.4" }, "engines": { @@ -6853,14 +6865,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.5.0.tgz", - "integrity": "sha512-06JOQ9Qgj33yvBEx6tpC8ecP9o860rsR22hWMEd12WcTRrfaFgHr2RB/CA/B+7BMhHkXT4chg2MyboGdFGawYg==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.6.0.tgz", + "integrity": "sha512-ZuoutoS5y9UOxKvpc/GkvF4cuEmpokda4wRg64JEia27wX+PysIE9q+lzDtlHHgblwUWwo5/Qn+/WyTUvDwBHw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.5.0", - "@typescript-eslint/visitor-keys": "8.5.0" + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/visitor-keys": "8.6.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6871,14 +6883,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.5.0.tgz", - "integrity": "sha512-N1K8Ix+lUM+cIDhL2uekVn/ZD7TZW+9/rwz8DclQpcQ9rk4sIL5CAlBC0CugWKREmDjBzI/kQqU4wkg46jWLYA==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.6.0.tgz", + "integrity": "sha512-dtePl4gsuenXVwC7dVNlb4mGDcKjDT/Ropsk4za/ouMBPplCLyznIaR+W65mvCvsyS97dymoBRrioEXI7k0XIg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.5.0", - "@typescript-eslint/utils": "8.5.0", + "@typescript-eslint/typescript-estree": "8.6.0", + "@typescript-eslint/utils": "8.6.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -6896,9 +6908,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.5.0.tgz", - "integrity": "sha512-qjkormnQS5wF9pjSi6q60bKUHH44j2APxfh9TQRXK8wbYVeDYYdYJGIROL87LGZZ2gz3Rbmjc736qyL8deVtdw==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.6.0.tgz", + "integrity": "sha512-rojqFZGd4MQxw33SrOy09qIDS8WEldM8JWtKQLAjf/X5mGSeEFh5ixQlxssMNyPslVIk9yzWqXCsV2eFhYrYUw==", "dev": true, "license": "MIT", "engines": { @@ -6910,14 +6922,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.5.0.tgz", - "integrity": "sha512-vEG2Sf9P8BPQ+d0pxdfndw3xIXaoSjliG0/Ejk7UggByZPKXmJmw3GW5jV2gHNQNawBUyfahoSiCFVov0Ruf7Q==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.6.0.tgz", + "integrity": "sha512-MOVAzsKJIPIlLK239l5s06YXjNqpKTVhBVDnqUumQJja5+Y94V3+4VUFRA0G60y2jNnTVwRCkhyGQpavfsbq/g==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "8.5.0", - "@typescript-eslint/visitor-keys": "8.5.0", + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/visitor-keys": "8.6.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -6939,16 +6951,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.5.0.tgz", - "integrity": "sha512-6yyGYVL0e+VzGYp60wvkBHiqDWOpT63pdMV2CVG4LVDd5uR6q1qQN/7LafBZtAtNIn/mqXjsSeS5ggv/P0iECw==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.6.0.tgz", + "integrity": "sha512-eNp9cWnYf36NaOVjkEUznf6fEgVy1TWpE0o52e4wtojjBx7D1UV2WAWGzR+8Y5lVFtpMLPwNbC67T83DWSph4A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.5.0", - "@typescript-eslint/types": "8.5.0", - "@typescript-eslint/typescript-estree": "8.5.0" + "@typescript-eslint/scope-manager": "8.6.0", + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/typescript-estree": "8.6.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6962,13 +6974,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.5.0.tgz", - "integrity": "sha512-yTPqMnbAZJNy2Xq2XU8AdtOW9tJIr+UQb64aXB9f3B1498Zx9JorVgFJcZpEc9UBuCCrdzKID2RGAMkYcDtZOw==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.6.0.tgz", + "integrity": "sha512-wapVFfZg9H0qOYh4grNVQiMklJGluQrOUiOhYRrQWhx7BY/+I1IYb8BczWNbbUpO+pqy0rDciv3lQH5E1bCLrg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.5.0", + "@typescript-eslint/types": "8.6.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -9556,12 +9568,12 @@ "license": "MIT" }, "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -9944,9 +9956,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.20", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.20.tgz", - "integrity": "sha512-74mdl6Fs1HHzK9SUX4CKFxAtAe3nUns48y79TskHNAG6fGOlLfyKA4j855x+0b5u8rWJIrlaG9tcTPstMlwjIw==", + "version": "1.5.25", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.25.tgz", + "integrity": "sha512-kMb204zvK3PsSlgvvwzI3wBIcAw15tRkYk+NQdsjdDtcQWTp2RABbMQ9rUBy8KNEOM+/E6ep+XC3AykiWZld4g==", "license": "ISC" }, "node_modules/emittery": { @@ -14894,9 +14906,9 @@ "license": "MIT" }, "node_modules/jsdom": { - "version": "24.1.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.1.tgz", - "integrity": "sha512-5O1wWV99Jhq4DV7rCLIoZ/UIhyQeDR7wHVyZAHAshbrvZsLs+Xzz7gtwnlJTJDjleiTKh54F4dXrX70vJQTyJQ==", + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.0.tgz", + "integrity": "sha512-OhoFVT59T7aEq75TVw9xxEfkXgacpqAhQaYgP9y/fDqWQCMB/b1H66RfmPm/MaeaAIU9nDwMOVTlPN51+ao6CQ==", "dev": true, "license": "MIT", "dependencies": { @@ -15924,9 +15936,9 @@ } }, "node_modules/memfs": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.11.1.tgz", - "integrity": "sha512-LZcMTBAgqUUKNXZagcZxvXXfgF1bHX7Y7nQ0QyEiNbRJgE29GhgPd8Yna1VQcLlPiHt/5RFJMWYN9Uv/VPNvjQ==", + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.11.2.tgz", + "integrity": "sha512-VcR7lEtgQgv7AxGkrNNeUAimFLT+Ov8uGu1LuOfbe/iF/dKoh/QgpoaMZlhfejvLtMxtXYyeoT7Ar1jEbWdbPA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -16357,9 +16369,9 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/msgpackr": { @@ -17731,9 +17743,9 @@ } }, "node_modules/postcss": { - "version": "8.4.41", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", - "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "dev": true, "funding": [ { @@ -17752,8 +17764,8 @@ "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -17882,9 +17894,9 @@ "license": "MIT" }, "node_modules/posthog-js": { - "version": "1.161.3", - "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.161.3.tgz", - "integrity": "sha512-TQ77jtLemkUJUyJAPrwGay6tLqcAmXEM1IJgXOx5Tr4UohiTx8JTznzrCuh/SdwPIrbcSM1r2YPwb72XwTC3wg==", + "version": "1.161.6", + "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.161.6.tgz", + "integrity": "sha512-UO0z/YTuan55Kl5Yg9Xs5x1PKUkm2zGKUNPioznb4GLRcxFnLBkWoeKQXNro2YZsYJvK+MY8jlF3cdGa8BZ8/Q==", "license": "MIT", "dependencies": { "fflate": "^0.4.8", @@ -17893,9 +17905,9 @@ } }, "node_modules/preact": { - "version": "10.23.2", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.23.2.tgz", - "integrity": "sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==", + "version": "10.24.0", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.0.tgz", + "integrity": "sha512-aK8Cf+jkfyuZ0ZZRG9FbYqwmEiGQ4y/PUO4SuTWoyWL244nZZh7bd5h2APd4rSNDYTBNghg1L+5iJN3Skxtbsw==", "license": "MIT", "funding": { "type": "opencollective", @@ -18069,13 +18081,6 @@ "license": "MIT", "optional": true }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true, - "license": "MIT" - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -18870,13 +18875,13 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.78.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.78.0.tgz", - "integrity": "sha512-AaIqGSrjo5lA2Yg7RvFZrlXDBCp3nV4XP73GrLGvdRWWwk+8H3l0SDvq/5bA4eF+0RFPLuWUk3E+P1U/YqnpsQ==", + "version": "1.79.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.79.1.tgz", + "integrity": "sha512-+mA7svoNKeL0DiJqZGeR/ZGUu8he4I8o3jyUcOFyo4eBJrwNgIMmAEwCMo/N2Y3wdjOBcRzoNxZIOtrtMX8EXg==", "dev": true, "license": "MIT", "dependencies": { - "chokidar": ">=3.0.0 <4.0.0", + "chokidar": "^4.0.0", "immutable": "^4.0.0", "source-map-js": ">=0.6.2 <2.0.0" }, @@ -18928,6 +18933,36 @@ } } }, + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.0.tgz", + "integrity": "sha512-mxIojEAQcuEvT/lyXq+jf/3cO/KoA6z4CeNDGGevTybECPOMFCnQy3OPahluUkbqgPNGw5Bi78UC7Po6Lhy+NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sass/node_modules/readdirp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.1.tgz", + "integrity": "sha512-GkMg9uOTpIWWKbSsgwb5fA4EavTR+SG/PMPoAY8hkhHfEEY0/vqljY+XHqtDf2cr2IJtoNRDbrrEpZUiZCkYRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/sax": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", @@ -19064,13 +19099,6 @@ "node": ">= 0.8" } }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -20324,6 +20352,26 @@ "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", "license": "MIT" }, + "node_modules/tldts": { + "version": "6.1.46", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.46.tgz", + "integrity": "sha512-fw81lXV2CijkNrZAZvee7wegs+EOlTyIuVl/z4q6OUzZHQ1jGL2xQzKXq9geYf/1tzo9LZQLrkcko2m8HLh+rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.46" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.46", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.46.tgz", + "integrity": "sha512-zA3ai/j4aFcmbqTvTONkSBuWs0Q4X4tJxa0gV9sp6kDbq5dAhQDSg0WUkReEm0fBAKAGNj+wPKCCsR8MYOYmwA==", + "dev": true, + "license": "MIT" + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -20376,19 +20424,16 @@ } }, "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", + "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" + "tldts": "^6.1.32" }, "engines": { - "node": ">=6" + "node": ">=16" } }, "node_modules/tr46": { @@ -20819,16 +20864,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -20988,15 +21023,15 @@ } }, "node_modules/vite": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.0.tgz", - "integrity": "sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==", + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.6.tgz", + "integrity": "sha512-IeL5f8OO5nylsgzd9tq4qD2QqI0k2CQLGrWD0rCN0EQJZpBK5vJAx0I+GDkMOXxQX/OfFHMuLIx6ddAxGX/k+Q==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.21.3", - "postcss": "^8.4.40", - "rollup": "^4.13.0" + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" diff --git a/package.json b/package.json index 65f810fa96dc..6bbcd55c3142 100644 --- a/package.json +++ b/package.json @@ -13,18 +13,18 @@ "node_modules" ], "dependencies": { - "@angular/animations": "18.2.4", + "@angular/animations": "18.2.5", "@angular/cdk": "18.2.4", - "@angular/common": "18.2.4", - "@angular/compiler": "18.2.4", - "@angular/core": "18.2.4", - "@angular/forms": "18.2.4", - "@angular/localize": "18.2.4", + "@angular/common": "18.2.5", + "@angular/compiler": "18.2.5", + "@angular/core": "18.2.5", + "@angular/forms": "18.2.5", + "@angular/localize": "18.2.5", "@angular/material": "18.2.4", - "@angular/platform-browser": "18.2.4", - "@angular/platform-browser-dynamic": "18.2.4", - "@angular/router": "18.2.4", - "@angular/service-worker": "18.2.4", + "@angular/platform-browser": "18.2.5", + "@angular/platform-browser-dynamic": "18.2.5", + "@angular/router": "18.2.5", + "@angular/service-worker": "18.2.5", "@ctrl/ngx-emoji-mart": "9.2.0", "@danielmoncada/angular-datetime-picker": "18.1.0", "@fingerprintjs/fingerprintjs": "4.5.0", @@ -63,7 +63,7 @@ "ngx-webstorage": "18.0.0", "papaparse": "5.4.1", "pdfjs-dist": "4.6.82", - "posthog-js": "1.161.3", + "posthog-js": "1.161.6", "rxjs": "7.8.1", "showdown": "2.1.0", "showdown-highlight": "3.1.0", @@ -92,22 +92,23 @@ }, "braces": "3.0.3", "critters": "0.0.24", - "debug": "4.3.6", + "debug": "4.3.7", "eslint-plugin-deprecation": { "eslint": "^9.10.0" }, "eslint-plugin-jest": { - "@typescript-eslint/eslint-plugin": "^8.5.0" + "@typescript-eslint/eslint-plugin": "^8.6.0" }, - "jsdom": "24.1.1", + "jsdom": "25.0.0", "katex": "0.16.11", - "postcss": "8.4.41", + "postcss": "8.4.47", "rimraf": "6.0.1", "semver": "7.6.3", "showdown-katex": { "showdown": "2.1.0" }, - "tough-cookie": "4.1.4", + "tough-cookie": "5.0.0", + "vite": "5.4.6", "webpack-dev-middleware": "7.4.2", "word-wrap": "1.2.5", "ws": "8.18.0", @@ -122,22 +123,22 @@ "@angular-eslint/schematics": "18.3.1", "@angular-eslint/template-parser": "18.3.1", "@angular/cli": "18.2.4", - "@angular/compiler-cli": "18.2.4", - "@angular/language-service": "18.2.4", + "@angular/compiler-cli": "18.2.5", + "@angular/language-service": "18.2.5", "@sentry/types": "8.30.0", "@types/crypto-js": "4.2.2", "@types/d3-shape": "3.1.6", "@types/dompurify": "3.0.5", "@types/jest": "29.5.13", "@types/lodash-es": "4.17.12", - "@types/node": "22.5.4", + "@types/node": "22.5.5", "@types/papaparse": "5.3.14", "@types/showdown": "2.0.6", "@types/smoothscroll-polyfill": "0.3.4", "@types/sockjs-client": "1.5.4", "@types/uuid": "10.0.0", - "@typescript-eslint/eslint-plugin": "8.5.0", - "@typescript-eslint/parser": "8.5.0", + "@typescript-eslint/eslint-plugin": "8.6.0", + "@typescript-eslint/parser": "8.6.0", "eslint": "9.10.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-deprecation": "3.0.0", @@ -157,7 +158,7 @@ "ng-mocks": "14.13.1", "prettier": "3.3.3", "rimraf": "6.0.1", - "sass": "1.78.0", + "sass": "1.79.1", "ts-jest": "29.2.5", "typescript": "5.5.4", "weak-napi": "2.0.2" From bac8af90a3fe6e2935f497717af4ff3cc735ca4d Mon Sep 17 00:00:00 2001 From: Marcel Gaupp Date: Thu, 19 Sep 2024 22:25:41 +0200 Subject: [PATCH 05/49] Programming exercises: Add JavaScript programming language template (#8859) --- .../programming-exercise-features.inc | 4 + .../domain/ProgrammingLanguage.java | 3 +- .../service/TemplateUpgradePolicyService.java | 4 +- .../ci/ContinuousIntegrationService.java | 8 +- ...abCIProgrammingLanguageFeatureService.java | 2 + ...kinsProgrammingLanguageFeatureService.java | 2 + .../build_plan/JenkinsBuildPlanService.java | 4 +- ...alCIProgrammingLanguageFeatureService.java | 2 + src/main/resources/config/application.yml | 2 + .../templates/aeolus/javascript/default.sh | 26 + .../templates/aeolus/javascript/default.yaml | 14 + .../javascript/regularRuns/.gitlab-ci.yml | 49 + .../templates/javascript/exercise/.gitignore | 1 + .../javascript/exercise/package.json | 11 + .../javascript/exercise/src/bubblesort.js | 3 + .../javascript/exercise/src/client.js | 66 + .../javascript/exercise/src/context.js | 3 + .../javascript/exercise/src/mergesort.js | 3 + .../javascript/exercise/src/policy.js | 3 + .../resources/templates/javascript/readme | 82 + .../templates/javascript/solution/.gitignore | 1 + .../javascript/solution/package.json | 11 + .../javascript/solution/src/bubblesort.js | 18 + .../javascript/solution/src/client.js | 72 + .../javascript/solution/src/context.js | 30 + .../javascript/solution/src/mergesort.js | 66 + .../javascript/solution/src/policy.js | 35 + .../templates/javascript/test/.gitignore | 4 + .../javascript/test/babel.config.json | 6 + .../javascript/test/package-lock.json | 5925 +++++++++++++++++ .../templates/javascript/test/package.json | 24 + .../javascript/test/src/behavior.test.js | 71 + .../javascript/test/src/structural.test.js | 44 + .../javascript/regularRuns/pipeline.groovy | 59 + .../programming/programming-exercise.model.ts | 1 + src/test/resources/config/application.yml | 2 + 36 files changed, 6652 insertions(+), 9 deletions(-) create mode 100644 src/main/resources/templates/aeolus/javascript/default.sh create mode 100644 src/main/resources/templates/aeolus/javascript/default.yaml create mode 100644 src/main/resources/templates/gitlabci/javascript/regularRuns/.gitlab-ci.yml create mode 100644 src/main/resources/templates/javascript/exercise/.gitignore create mode 100644 src/main/resources/templates/javascript/exercise/package.json create mode 100644 src/main/resources/templates/javascript/exercise/src/bubblesort.js create mode 100644 src/main/resources/templates/javascript/exercise/src/client.js create mode 100644 src/main/resources/templates/javascript/exercise/src/context.js create mode 100644 src/main/resources/templates/javascript/exercise/src/mergesort.js create mode 100644 src/main/resources/templates/javascript/exercise/src/policy.js create mode 100755 src/main/resources/templates/javascript/readme create mode 100644 src/main/resources/templates/javascript/solution/.gitignore create mode 100644 src/main/resources/templates/javascript/solution/package.json create mode 100644 src/main/resources/templates/javascript/solution/src/bubblesort.js create mode 100644 src/main/resources/templates/javascript/solution/src/client.js create mode 100644 src/main/resources/templates/javascript/solution/src/context.js create mode 100644 src/main/resources/templates/javascript/solution/src/mergesort.js create mode 100644 src/main/resources/templates/javascript/solution/src/policy.js create mode 100644 src/main/resources/templates/javascript/test/.gitignore create mode 100644 src/main/resources/templates/javascript/test/babel.config.json create mode 100644 src/main/resources/templates/javascript/test/package-lock.json create mode 100644 src/main/resources/templates/javascript/test/package.json create mode 100644 src/main/resources/templates/javascript/test/src/behavior.test.js create mode 100644 src/main/resources/templates/javascript/test/src/structural.test.js create mode 100644 src/main/resources/templates/jenkins/javascript/regularRuns/pipeline.groovy diff --git a/docs/user/exercises/programming-exercise-features.inc b/docs/user/exercises/programming-exercise-features.inc index 3675a9e4c2b0..6d0b257dd96e 100644 --- a/docs/user/exercises/programming-exercise-features.inc +++ b/docs/user/exercises/programming-exercise-features.inc @@ -35,6 +35,8 @@ Instructors can still use those templates to generate programming exercises and +----------------------+----------+---------+ | Rust | yes | yes | +----------------------+----------+---------+ + | JavaScript | yes | yes | + +----------------------+----------+---------+ - Not all ``templates`` support the same feature set and supported features can also change depending on the continuous integration system setup. Depending on the feature set, some options might not be available during the creation of the programming exercise. @@ -67,6 +69,8 @@ Instructors can still use those templates to generate programming exercises and +----------------------+----------------------+----------------------+---------------------+--------------+------------------------------------------+------------------------------+----------------------------+------------------------+ | Rust | no | no | no | no | n/a | no | no | L: yes, J: no | +----------------------+----------------------+----------------------+---------------------+--------------+------------------------------------------+------------------------------+----------------------------+------------------------+ + | JavaScript | no | no | no | no | n/a | no | no | L: yes, J: no | + +----------------------+----------------------+----------------------+---------------------+--------------+------------------------------------------+------------------------------+----------------------------+------------------------+ - *Sequential Test Runs*: ``Artemis`` can generate a build plan which first executes structural and then behavioral tests. This feature can help students to better concentrate on the immediate challenge at hand. - *Static Code Analysis*: ``Artemis`` can generate a build plan which additionally executes static code analysis tools. diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/domain/ProgrammingLanguage.java b/src/main/java/de/tum/cit/aet/artemis/programming/domain/ProgrammingLanguage.java index ea435ac5ea5a..4206bfe15dbc 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/domain/ProgrammingLanguage.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/domain/ProgrammingLanguage.java @@ -48,7 +48,8 @@ public enum ProgrammingLanguage { ASSEMBLER, SWIFT, OCAML, - RUST + RUST, + JAVASCRIPT ); // @formatter:on diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/TemplateUpgradePolicyService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/TemplateUpgradePolicyService.java index 5ddd9dac7e8d..16285e6a0695 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/service/TemplateUpgradePolicyService.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/TemplateUpgradePolicyService.java @@ -32,8 +32,8 @@ public TemplateUpgradePolicyService(JavaTemplateUpgradeService javaRepositoryUpg public TemplateUpgradeService getUpgradeService(ProgrammingLanguage programmingLanguage) { return switch (programmingLanguage) { case JAVA -> javaRepositoryUpgradeService; - case KOTLIN, PYTHON, C, HASKELL, VHDL, ASSEMBLER, SWIFT, OCAML, EMPTY, RUST -> defaultRepositoryUpgradeService; - case JAVASCRIPT, C_SHARP, C_PLUS_PLUS, SQL, R, TYPESCRIPT, GO, MATLAB, BASH, RUBY, POWERSHELL, ADA, DART, PHP -> + case KOTLIN, PYTHON, C, HASKELL, VHDL, ASSEMBLER, SWIFT, OCAML, EMPTY, RUST, JAVASCRIPT -> defaultRepositoryUpgradeService; + case C_SHARP, C_PLUS_PLUS, SQL, R, TYPESCRIPT, GO, MATLAB, BASH, RUBY, POWERSHELL, ADA, DART, PHP -> throw new UnsupportedOperationException("Unsupported programming language: " + programmingLanguage); }; } diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/ContinuousIntegrationService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/ContinuousIntegrationService.java index f22c65b8b6d6..b4f67794c073 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/ContinuousIntegrationService.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/ci/ContinuousIntegrationService.java @@ -219,8 +219,8 @@ enum RepositoryCheckoutPath implements CustomizableCheckoutPath { @Override public String forProgrammingLanguage(ProgrammingLanguage language) { return switch (language) { - case JAVA, PYTHON, C, HASKELL, KOTLIN, VHDL, ASSEMBLER, SWIFT, OCAML, EMPTY, RUST -> "assignment"; - case JAVASCRIPT, C_SHARP, C_PLUS_PLUS, SQL, R, TYPESCRIPT, GO, MATLAB, BASH, RUBY, POWERSHELL, ADA, DART, PHP -> + case JAVA, PYTHON, C, HASKELL, KOTLIN, VHDL, ASSEMBLER, SWIFT, OCAML, EMPTY, RUST, JAVASCRIPT -> "assignment"; + case C_SHARP, C_PLUS_PLUS, SQL, R, TYPESCRIPT, GO, MATLAB, BASH, RUBY, POWERSHELL, ADA, DART, PHP -> throw new UnsupportedOperationException("Unsupported programming language: " + language); }; } @@ -230,9 +230,9 @@ public String forProgrammingLanguage(ProgrammingLanguage language) { @Override public String forProgrammingLanguage(ProgrammingLanguage language) { return switch (language) { - case JAVA, PYTHON, HASKELL, KOTLIN, SWIFT, EMPTY, RUST -> ""; + case JAVA, PYTHON, HASKELL, KOTLIN, SWIFT, EMPTY, RUST, JAVASCRIPT -> ""; case C, VHDL, ASSEMBLER, OCAML -> "tests"; - case JAVASCRIPT, C_SHARP, C_PLUS_PLUS, SQL, R, TYPESCRIPT, GO, MATLAB, BASH, RUBY, POWERSHELL, ADA, DART, PHP -> + case C_SHARP, C_PLUS_PLUS, SQL, R, TYPESCRIPT, GO, MATLAB, BASH, RUBY, POWERSHELL, ADA, DART, PHP -> throw new UnsupportedOperationException("Unsupported programming language: " + language); }; } diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/gitlabci/GitLabCIProgrammingLanguageFeatureService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/gitlabci/GitLabCIProgrammingLanguageFeatureService.java index c898b33edb0d..7cd996e35cc4 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/service/gitlabci/GitLabCIProgrammingLanguageFeatureService.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/gitlabci/GitLabCIProgrammingLanguageFeatureService.java @@ -2,6 +2,7 @@ import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.EMPTY; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.JAVA; +import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.JAVASCRIPT; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.RUST; import static de.tum.cit.aet.artemis.programming.domain.ProjectType.MAVEN_MAVEN; import static de.tum.cit.aet.artemis.programming.domain.ProjectType.PLAIN_MAVEN; @@ -25,5 +26,6 @@ public GitLabCIProgrammingLanguageFeatureService() { programmingLanguageFeatures.put(EMPTY, new ProgrammingLanguageFeature(EMPTY, false, false, false, false, false, List.of(), false, false)); programmingLanguageFeatures.put(JAVA, new ProgrammingLanguageFeature(JAVA, false, false, false, true, false, List.of(PLAIN_MAVEN, MAVEN_MAVEN), false, false)); programmingLanguageFeatures.put(RUST, new ProgrammingLanguageFeature(RUST, false, false, false, false, false, List.of(), false, false)); + programmingLanguageFeatures.put(JAVASCRIPT, new ProgrammingLanguageFeature(JAVASCRIPT, false, false, false, false, false, List.of(), false, false)); } } diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/jenkins/JenkinsProgrammingLanguageFeatureService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/jenkins/JenkinsProgrammingLanguageFeatureService.java index 82c0a9ebf238..94e6bf8d27fc 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/service/jenkins/JenkinsProgrammingLanguageFeatureService.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/jenkins/JenkinsProgrammingLanguageFeatureService.java @@ -4,6 +4,7 @@ import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.EMPTY; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.HASKELL; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.JAVA; +import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.JAVASCRIPT; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.KOTLIN; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.PYTHON; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.RUST; @@ -41,5 +42,6 @@ public JenkinsProgrammingLanguageFeatureService() { programmingLanguageFeatures.put(C, new ProgrammingLanguageFeature(C, false, false, true, false, false, List.of(FACT, GCC), false, false)); programmingLanguageFeatures.put(HASKELL, new ProgrammingLanguageFeature(HASKELL, false, false, false, false, true, List.of(), false, false)); programmingLanguageFeatures.put(RUST, new ProgrammingLanguageFeature(RUST, false, false, false, false, false, List.of(), false, false)); + programmingLanguageFeatures.put(JAVASCRIPT, new ProgrammingLanguageFeature(JAVASCRIPT, false, false, false, false, false, List.of(), false, false)); } } diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/jenkins/build_plan/JenkinsBuildPlanService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/jenkins/build_plan/JenkinsBuildPlanService.java index 571be75f7624..6e904910ca57 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/service/jenkins/build_plan/JenkinsBuildPlanService.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/jenkins/build_plan/JenkinsBuildPlanService.java @@ -184,8 +184,8 @@ private JenkinsXmlConfigBuilder builderFor(ProgrammingLanguage programmingLangua throw new UnsupportedOperationException("Xcode templates are not available for Jenkins."); } return switch (programmingLanguage) { - case JAVA, KOTLIN, PYTHON, C, HASKELL, SWIFT, EMPTY, RUST -> jenkinsBuildPlanCreator; - case VHDL, ASSEMBLER, OCAML, JAVASCRIPT, C_SHARP, C_PLUS_PLUS, SQL, R, TYPESCRIPT, GO, MATLAB, BASH, RUBY, POWERSHELL, ADA, DART, PHP -> + case JAVA, KOTLIN, PYTHON, C, HASKELL, SWIFT, EMPTY, RUST, JAVASCRIPT -> jenkinsBuildPlanCreator; + case VHDL, ASSEMBLER, OCAML, C_SHARP, C_PLUS_PLUS, SQL, R, TYPESCRIPT, GO, MATLAB, BASH, RUBY, POWERSHELL, ADA, DART, PHP -> throw new UnsupportedOperationException(programmingLanguage + " templates are not available for Jenkins."); }; } diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIProgrammingLanguageFeatureService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIProgrammingLanguageFeatureService.java index 77ebdcabcff9..1a5e3553cc27 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIProgrammingLanguageFeatureService.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIProgrammingLanguageFeatureService.java @@ -5,6 +5,7 @@ import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.C; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.HASKELL; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.JAVA; +import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.JAVASCRIPT; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.KOTLIN; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.OCAML; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.PYTHON; @@ -48,5 +49,6 @@ public LocalCIProgrammingLanguageFeatureService() { programmingLanguageFeatures.put(OCAML, new ProgrammingLanguageFeature(OCAML, false, false, false, false, true, List.of(), false, true)); programmingLanguageFeatures.put(SWIFT, new ProgrammingLanguageFeature(SWIFT, false, false, true, true, false, List.of(PLAIN), false, true)); programmingLanguageFeatures.put(RUST, new ProgrammingLanguageFeature(RUST, false, false, false, false, false, List.of(), false, true)); + programmingLanguageFeatures.put(JAVASCRIPT, new ProgrammingLanguageFeature(JAVASCRIPT, false, false, false, false, false, List.of(), false, true)); } } diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml index 6b3f18dfaeeb..630a9c527db1 100644 --- a/src/main/resources/config/application.yml +++ b/src/main/resources/config/application.yml @@ -89,6 +89,8 @@ artemis: default: "ls1tum/artemis-ocaml-docker:v1" rust: default: "ghcr.io/ls1intum/artemis-rust-docker:v0.9.70" + javascript: + default: "ghcr.io/ls1intum/artemis-javascript-docker:v1.0.0" management: endpoints: diff --git a/src/main/resources/templates/aeolus/javascript/default.sh b/src/main/resources/templates/aeolus/javascript/default.sh new file mode 100644 index 000000000000..bc63c59f3365 --- /dev/null +++ b/src/main/resources/templates/aeolus/javascript/default.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -e +export AEOLUS_INITIAL_DIRECTORY=${PWD} +install_dependencies () { + echo '⚙️ executing install_dependencies' + npm ci --prefer-offline --no-audit +} + +test () { + echo '⚙️ executing test' + npm run test:ci +} + +main () { + if [[ "${1}" == "aeolus_sourcing" ]]; then + return 0 # just source to use the methods in the subshell, no execution + fi + local _script_name + _script_name=${BASH_SOURCE[0]:-$0} + cd "${AEOLUS_INITIAL_DIRECTORY}" + bash -c "source ${_script_name} aeolus_sourcing; install_dependencies" + cd "${AEOLUS_INITIAL_DIRECTORY}" + bash -c "source ${_script_name} aeolus_sourcing; test" +} + +main "${@}" diff --git a/src/main/resources/templates/aeolus/javascript/default.yaml b/src/main/resources/templates/aeolus/javascript/default.yaml new file mode 100644 index 000000000000..9786187ebe2f --- /dev/null +++ b/src/main/resources/templates/aeolus/javascript/default.yaml @@ -0,0 +1,14 @@ +api: v0.0.1 +metadata: + name: JavaScript + description: Run tests using Jest +actions: + - name: install_dependencies + script: 'npm ci --prefer-offline --no-audit' + - name: test + script: 'npm run test:ci' + runAlways: false + results: + - name: junit + path: 'junit.xml' + type: junit diff --git a/src/main/resources/templates/gitlabci/javascript/regularRuns/.gitlab-ci.yml b/src/main/resources/templates/gitlabci/javascript/regularRuns/.gitlab-ci.yml new file mode 100644 index 000000000000..b2b5dcdaa592 --- /dev/null +++ b/src/main/resources/templates/gitlabci/javascript/regularRuns/.gitlab-ci.yml @@ -0,0 +1,49 @@ +stages: + - test + - upload + + +test-job: + image: ${ARTEMIS_BUILD_DOCKER_IMAGE} + stage: test + only: + variables: + - $CI_COMMIT_BRANCH == $ARTEMIS_SUBMISSION_GIT_BRANCH + allow_failure: true + variables: + GIT_STRATEGY: none + script: + - git clone --branch ${ARTEMIS_TEST_GIT_BRANCH} ${CI_SERVER_PROTOCOL}://${ARTEMIS_TEST_GIT_USER}:${ARTEMIS_TEST_GIT_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}/${CI_PROJECT_NAMESPACE}/${ARTEMIS_TEST_GIT_REPOSITORY_SLUG} . + - git clone --branch ${ARTEMIS_SUBMISSION_GIT_BRANCH} ${CI_SERVER_PROTOCOL}://${ARTEMIS_TEST_GIT_USER}:${ARTEMIS_TEST_GIT_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME} assignment + - export ARTEMIS_NOTIFICATION_SECRET=[hidden] # Workaround for overwriting the secret + - export ARTEMIS_TEST_GIT_TOKEN=[hidden] + - npm ci --prefer-offline --no-audit | tee -a "${ARTEMIS_BUILD_LOGS_FILE}" + - npm run test:ci | tee -a "${ARTEMIS_BUILD_LOGS_FILE}" && echo "ARTEMIS_BUILD_STATUS=success" > .env || echo "ARTEMIS_BUILD_STATUS=failed" > .env + - test -e junit.xml && sed -i 's/]*>//g ; s/<\/testsuites>/<\/testsuite>/g' junit.xml # not supported by notification plugin + - test -e junit.xml && mkdir test-reports && cp junit.xml test-reports/junit.xml + after_script: + - echo "ARTEMIS_TEST_GIT_HASH=$(git rev-parse HEAD)" >> .env + - echo "ARTEMIS_SUBMISSION_GIT_HASH=${CI_COMMIT_SHA}" >> .env + - echo "ARTEMIS_SUBMISSION_GIT_REPOSITORY_SLUG=${CI_PROJECT_NAME}" >> .env + artifacts: + paths: + - ${ARTEMIS_BUILD_LOGS_FILE} + - test-reports/junit.xml + reports: + dotenv: .env + + +upload-job: + image: ${ARTEMIS_NOTIFICATION_PLUGIN_DOCKER_IMAGE} + stage: upload + dependencies: + - test-job + only: + variables: + - $CI_COMMIT_BRANCH == $ARTEMIS_SUBMISSION_GIT_BRANCH + variables: + GIT_STRATEGY: none + script: + - cp -r /notification-plugin/* . + - export ARTEMIS_TEST_RESULTS_DIR="test-reports" # override project variable + - gradle run diff --git a/src/main/resources/templates/javascript/exercise/.gitignore b/src/main/resources/templates/javascript/exercise/.gitignore new file mode 100644 index 000000000000..c2658d7d1b31 --- /dev/null +++ b/src/main/resources/templates/javascript/exercise/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/src/main/resources/templates/javascript/exercise/package.json b/src/main/resources/templates/javascript/exercise/package.json new file mode 100644 index 000000000000..f5dfc56c86ef --- /dev/null +++ b/src/main/resources/templates/javascript/exercise/package.json @@ -0,0 +1,11 @@ +{ + "name": "artemis-exercise", + "private": true, + "scripts": { + "start": "node ./src/client.js" + }, + "exports": { + "./*.js": "./src/*.js" + }, + "type": "module" +} diff --git a/src/main/resources/templates/javascript/exercise/src/bubblesort.js b/src/main/resources/templates/javascript/exercise/src/bubblesort.js new file mode 100644 index 000000000000..19ea2939c6f7 --- /dev/null +++ b/src/main/resources/templates/javascript/exercise/src/bubblesort.js @@ -0,0 +1,3 @@ +export default class BubbleSort { + // TODO: implement in performSort(Date[]) +} diff --git a/src/main/resources/templates/javascript/exercise/src/client.js b/src/main/resources/templates/javascript/exercise/src/client.js new file mode 100644 index 000000000000..4cd9116f80da --- /dev/null +++ b/src/main/resources/templates/javascript/exercise/src/client.js @@ -0,0 +1,66 @@ +const ITERATIONS = 10; +const DATES_LENGTH_MIN = 5; +const DATES_LENGTH_MAX = 15; + +/** + * Main function. + * Add code to demonstrate your implementation here. + */ +function main() { + // TODO: Init Context and Policy + + // Run multiple times to simulate different sorting strategies + for (let i = 0; i < ITERATIONS; i++) { + const dates = createRandomDates(); + + // TODO: Configure context + + console.log('Unsorted Array of dates:'); + console.log(dates); + + // TODO: Sort dates + + console.log('Sorted Array of dates:'); + console.log(dates); + } +} + +/** + * Generates an Array of random Date objects with random Array length between + * {@link DATES_LENGTH_MIN} and {@link DATES_LENGTH_MAX}. + * + * @return an Array of random Date objects + */ +function createRandomDates() { + const length = randomIntegerWithin(DATES_LENGTH_MIN, DATES_LENGTH_MAX); + + const lowestDate = new Date('2024-09-15'); + const highestDate = new Date('2025-01-15'); + + return Array.from(Array(length), () => randomDateWithin(lowestDate, highestDate)); +} + +/** + * Creates a random Date within the given range. + * + * @param low {Date} the lower bound + * @param high {Date} the upper bound + * @return {Date} random Date within the given range + */ +function randomDateWithin(low, high) { + const randomTimestamp = randomIntegerWithin(low.valueOf(), high.valueOf()); + return new Date(randomTimestamp); +} + +/** + * Creates a random int within the given range. + * + * @param low {number} the lower bound + * @param high {number} the upper bound + * @returns {number} random int within the given range + */ +function randomIntegerWithin(low, high) { + return Math.floor(Math.random() * (high - low + 1)) + low; +} + +main(); diff --git a/src/main/resources/templates/javascript/exercise/src/context.js b/src/main/resources/templates/javascript/exercise/src/context.js new file mode 100644 index 000000000000..a667a10bb29e --- /dev/null +++ b/src/main/resources/templates/javascript/exercise/src/context.js @@ -0,0 +1,3 @@ +export default class Context { + // TODO: Create and implement a Context class according to the UML class diagram +} diff --git a/src/main/resources/templates/javascript/exercise/src/mergesort.js b/src/main/resources/templates/javascript/exercise/src/mergesort.js new file mode 100644 index 000000000000..43c86272c2cf --- /dev/null +++ b/src/main/resources/templates/javascript/exercise/src/mergesort.js @@ -0,0 +1,3 @@ +export default class MergeSort { + // TODO: implement in performSort(Date[]) +} diff --git a/src/main/resources/templates/javascript/exercise/src/policy.js b/src/main/resources/templates/javascript/exercise/src/policy.js new file mode 100644 index 000000000000..7c8723feb1a9 --- /dev/null +++ b/src/main/resources/templates/javascript/exercise/src/policy.js @@ -0,0 +1,3 @@ +export default class Policy { + // TODO: Create and implement a Policy class as described in the problem statement +} diff --git a/src/main/resources/templates/javascript/readme b/src/main/resources/templates/javascript/readme new file mode 100755 index 000000000000..97cf7cb4339a --- /dev/null +++ b/src/main/resources/templates/javascript/readme @@ -0,0 +1,82 @@ +# Sorting with the Strategy Pattern + +In this exercise, we want to implement sorting algorithms and choose them based on runtime specific variables. + +### Part 1: Sorting + +First, we need to implement two sorting algorithms, in this case `MergeSort` and `BubbleSort`. + +**You have the following tasks:** + +1. [task][Implement Bubble Sort](structural_BubbleSort_has_method,behavior_BubbleSort_should_sort_correctly) +Implement the method `performSort(Date[])` in the class `BubbleSort`. Make sure to follow the Bubble Sort algorithm exactly. + +2. [task][Implement Merge Sort](structural_MergeSort_has_method,behavior_MergeSort_should_sort_correctly) +Implement the method `performSort(Date[])` in the class `MergeSort`. Make sure to follow the Merge Sort algorithm exactly. + +### Part 2: Strategy Pattern + +We want the application to apply different algorithms for sorting an Array of `Date` objects. +Use the strategy pattern to select the right sorting algorithm at runtime. + +**You have the following tasks:** + +1. [task][Context Class](structural_Context_has_properties,structural_Context_has_methods) +Create and implement a `Context` class following the below class diagram. +Add `get` and `set` accessors for the attribute. + +2. [task][Context Policy](structural_Policy_has_properties,structural_Policy_has_methods) +Create and implement a `Policy` class following the below class diagram. +Add `get` and `set` accessors for the attribute. +`Policy` should implement a simple configuration mechanism: + + 1. [task][Select MergeSort](behavior_Policy_uses_MergeSort_for_big_list) + Select `MergeSort` when the List has more than 10 dates. + + 2. [task][Select BubbleSort](behavior_Policy_uses_BubbleSort_for_small_list) + Select `BubbleSort` when the List has less or equal 10 dates. + +3. Complete the `main()` function which demonstrates switching between two strategies at runtime. + +@startuml + +class Policy { + +Policy(Context) <> + +configure() +} + +class Context { + -dates: Date[] + +sort() +} + +interface SortStrategy { + +performSort(Date[]) +} + +class BubbleSort { + +performSort(Date[]) +} + +class MergeSort { + +performSort(Date[]) +} + +MergeSort -up-|> SortStrategy #testsColor(structural_MergeSort_has_method) +BubbleSort -up-|> SortStrategy #testsColor(structural_BubbleSort_has_method) +Policy -right-> Context #testsColor(structural_Policy_has_properties): context +Context -right-> SortStrategy #testsColor(structural_Context_has_properties): sortAlgorithm + +hide empty fields +hide empty methods + +@enduml + + +### Part 3: Optional Challenges + +(These are not tested) + +1. Create a new class `QuickSort` that implements `SortStrategy` and implement the Quick Sort algorithm. + +2. Think about a useful decision in `Policy` when to use the new `QuickSort` algorithm. diff --git a/src/main/resources/templates/javascript/solution/.gitignore b/src/main/resources/templates/javascript/solution/.gitignore new file mode 100644 index 000000000000..c2658d7d1b31 --- /dev/null +++ b/src/main/resources/templates/javascript/solution/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/src/main/resources/templates/javascript/solution/package.json b/src/main/resources/templates/javascript/solution/package.json new file mode 100644 index 000000000000..f5dfc56c86ef --- /dev/null +++ b/src/main/resources/templates/javascript/solution/package.json @@ -0,0 +1,11 @@ +{ + "name": "artemis-exercise", + "private": true, + "scripts": { + "start": "node ./src/client.js" + }, + "exports": { + "./*.js": "./src/*.js" + }, + "type": "module" +} diff --git a/src/main/resources/templates/javascript/solution/src/bubblesort.js b/src/main/resources/templates/javascript/solution/src/bubblesort.js new file mode 100644 index 000000000000..cef35929a7f7 --- /dev/null +++ b/src/main/resources/templates/javascript/solution/src/bubblesort.js @@ -0,0 +1,18 @@ +export default class BubbleSort { + /** + * Sorts dates with BubbleSort. + * + * @param input {Date[]} the array of Dates to be sorted + */ + performSort(input) { + for (let i = input.length - 1; i >= 0; i--) { + for (let j = 0; j < i; j++) { + if (input[j].valueOf() > input[j + 1].valueOf()) { + const temp = input[j]; + input[j] = input[j + 1]; + input[j + 1] = temp; + } + } + } + } +} diff --git a/src/main/resources/templates/javascript/solution/src/client.js b/src/main/resources/templates/javascript/solution/src/client.js new file mode 100644 index 000000000000..0cbc568e6c24 --- /dev/null +++ b/src/main/resources/templates/javascript/solution/src/client.js @@ -0,0 +1,72 @@ +import Context from './context.js'; +import Policy from './policy.js'; + +const ITERATIONS = 10; +const DATES_LENGTH_MIN = 5; +const DATES_LENGTH_MAX = 15; + +/** + * Main function. + * Add code to demonstrate your implementation here. + */ +function main() { + // Init Context and Policy + const context = new Context(); + const policy = new Policy(context); + + // Run multiple times to simulate different sorting strategies + for (let i = 0; i < ITERATIONS; i++) { + const dates = createRandomDates(); + + context.dates = dates; + policy.configure(); + + console.log('Unsorted Array of dates:'); + console.log(dates); + + context.sort(); + + console.log('Sorted Array of dates:'); + console.log(dates); + } +} + +/** + * Generates an Array of random Date objects with random Array length between + * {@link DATES_LENGTH_MIN} and {@link DATES_LENGTH_MAX}. + * + * @return an Array of random Date objects + */ +function createRandomDates() { + const length = randomIntegerWithin(DATES_LENGTH_MIN, DATES_LENGTH_MAX); + + const lowestDate = new Date('2024-09-15'); + const highestDate = new Date('2025-01-15'); + + return Array.from(Array(length), () => randomDateWithin(lowestDate, highestDate)); +} + +/** + * Creates a random Date within the given range. + * + * @param low {Date} the lower bound + * @param high {Date} the upper bound + * @return {Date} random Date within the given range + */ +function randomDateWithin(low, high) { + const randomTimestamp = randomIntegerWithin(low.valueOf(), high.valueOf()); + return new Date(randomTimestamp); +} + +/** + * Creates a random int within the given range. + * + * @param low {number} the lower bound + * @param high {number} the upper bound + * @returns {number} random int within the given range + */ +function randomIntegerWithin(low, high) { + return Math.floor(Math.random() * (high - low + 1)) + low; +} + +main(); diff --git a/src/main/resources/templates/javascript/solution/src/context.js b/src/main/resources/templates/javascript/solution/src/context.js new file mode 100644 index 000000000000..9041afb1152e --- /dev/null +++ b/src/main/resources/templates/javascript/solution/src/context.js @@ -0,0 +1,30 @@ +export default class Context { + /** @type {?{ performSort: (input: Date[]) => void }} */ + #sortAlgorithm = null; + + /** @type {Date[]} */ + #dates = []; + + /** + * Runs the configured sort algorithm. + */ + sort() { + this.#sortAlgorithm?.performSort(this.#dates); + } + + get sortAlgorithm() { + return this.#sortAlgorithm; + } + + set sortAlgorithm(sortAlgorithm) { + this.#sortAlgorithm = sortAlgorithm; + } + + get dates() { + return this.#dates; + } + + set dates(dates) { + this.#dates = dates; + } +} diff --git a/src/main/resources/templates/javascript/solution/src/mergesort.js b/src/main/resources/templates/javascript/solution/src/mergesort.js new file mode 100644 index 000000000000..7b1fa1c918e5 --- /dev/null +++ b/src/main/resources/templates/javascript/solution/src/mergesort.js @@ -0,0 +1,66 @@ +export default class MergeSort { + /** + * Wrapper method for the real MergeSort algorithm. + * + * @param input {Date[]} the array of Dates to be sorted + */ + performSort(input) { + mergesort(input, 0, input.length - 1); + } +} + +/** + * Recursive merge sort function + * + * @param input {Date[]} + * @param low {number} + * @param high {number} + */ +function mergesort(input, low, high) { + if (high - low < 1) { + return; + } + const mid = Math.floor((low + high) / 2); + mergesort(input, low, mid); + mergesort(input, mid + 1, high); + merge(input, low, mid, high); +} + +/** + * Merge function + * + * @param input {Date[]} + * @param low {number} + * @param middle {number} + * @param high {number} + */ +function merge(input, low, middle, high) { + const temp = new Array(high - low + 1); + + let leftIndex = low; + let rightIndex = middle + 1; + let wholeIndex = 0; + + while (leftIndex <= middle && rightIndex <= high) { + if (input[leftIndex] <= input[rightIndex]) { + temp[wholeIndex] = input[leftIndex++]; + } else { + temp[wholeIndex] = input[rightIndex++]; + } + wholeIndex++; + } + + if (leftIndex <= middle && rightIndex > high) { + while (leftIndex <= middle) { + temp[wholeIndex++] = input[leftIndex++]; + } + } else { + while (rightIndex <= high) { + temp[wholeIndex++] = input[rightIndex++]; + } + } + + for (wholeIndex = 0; wholeIndex < temp.length; wholeIndex++) { + input[wholeIndex + low] = temp[wholeIndex]; + } +} diff --git a/src/main/resources/templates/javascript/solution/src/policy.js b/src/main/resources/templates/javascript/solution/src/policy.js new file mode 100644 index 000000000000..15b9ed4cb23b --- /dev/null +++ b/src/main/resources/templates/javascript/solution/src/policy.js @@ -0,0 +1,35 @@ +import BubbleSort from './bubblesort.js'; +import MergeSort from './mergesort.js'; + +const DATES_LENGTH_THRESHOLD = 10; + +export default class Policy { + /** @type {Context} */ + #context; + + /** + * @param context {Context} + */ + constructor(context) { + this.#context = context; + } + + /** + * Chooses a strategy depending on the number of date objects. + */ + configure() { + if (this.#context.dates.length > DATES_LENGTH_THRESHOLD) { + this.#context.sortAlgorithm = new MergeSort(); + } else { + this.#context.sortAlgorithm = new BubbleSort(); + } + } + + get context() { + return this.#context; + } + + set context(context) { + this.#context = context; + } +} diff --git a/src/main/resources/templates/javascript/test/.gitignore b/src/main/resources/templates/javascript/test/.gitignore new file mode 100644 index 000000000000..d81d793eaed4 --- /dev/null +++ b/src/main/resources/templates/javascript/test/.gitignore @@ -0,0 +1,4 @@ +node_modules/ + +/assignment +/junit.xml diff --git a/src/main/resources/templates/javascript/test/babel.config.json b/src/main/resources/templates/javascript/test/babel.config.json new file mode 100644 index 000000000000..2c69a84a9fad --- /dev/null +++ b/src/main/resources/templates/javascript/test/babel.config.json @@ -0,0 +1,6 @@ +{ + "targets": { + "node": 20 + }, + "presets": ["@babel/preset-env"] +} diff --git a/src/main/resources/templates/javascript/test/package-lock.json b/src/main/resources/templates/javascript/test/package-lock.json new file mode 100644 index 000000000000..b18c57c3b694 --- /dev/null +++ b/src/main/resources/templates/javascript/test/package-lock.json @@ -0,0 +1,5925 @@ +{ + "name": "artemis-test", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "artemis-test", + "workspaces": [ + "assignment" + ], + "devDependencies": { + "@babel/core": "^7.24.7", + "@babel/preset-env": "^7.24.7", + "@types/jest": "^29.5.12", + "babel-jest": "^29.7.0", + "jest": "^29.7.0", + "jest-junit": "^16.0.0" + } + }, + "assignment": { + "name": "artemis-exercise" + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-wrap-function": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-function-name": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.7", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.24.7", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.24.7", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoped-functions": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.24.7", + "@babel/plugin-transform-class-properties": "^7.24.7", + "@babel/plugin-transform-class-static-block": "^7.24.7", + "@babel/plugin-transform-classes": "^7.24.7", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.7", + "@babel/plugin-transform-dotall-regex": "^7.24.7", + "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-dynamic-import": "^7.24.7", + "@babel/plugin-transform-exponentiation-operator": "^7.24.7", + "@babel/plugin-transform-export-namespace-from": "^7.24.7", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.24.7", + "@babel/plugin-transform-json-strings": "^7.24.7", + "@babel/plugin-transform-literals": "^7.24.7", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-member-expression-literals": "^7.24.7", + "@babel/plugin-transform-modules-amd": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-modules-systemjs": "^7.24.7", + "@babel/plugin-transform-modules-umd": "^7.24.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-new-target": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-object-super": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-property-literals": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-reserved-words": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-template-literals": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.7", + "@babel/plugin-transform-unicode-escapes": "^7.24.7", + "@babel/plugin-transform-unicode-property-regex": "^7.24.7", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/runtime": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/console/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/console/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/core/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/core/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/reporters/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { + "version": "6.0.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/node_modules/semver": { + "version": "7.6.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/transform/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/transform/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/types/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.12", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/node": { + "version": "20.14.8", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/artemis-exercise": { + "resolved": "assignment", + "link": true + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-jest/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/babel-jest/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.1", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001636", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui": { + "version": "8.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.37.1", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/create-jest": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/create-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/create-jest/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/create-jest/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/create-jest/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/create-jest/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/create-jest/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "1.5.3", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.810", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/error-ex": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.14.0", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-circus/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-circus/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-cli/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-cli/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-config/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-config/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-diff/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-each/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-each/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-junit": { + "version": "16.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "mkdirp": "^1.0.4", + "strip-ansi": "^6.0.1", + "uuid": "^8.3.2", + "xml": "^1.0.1" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-matcher-utils/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-message-util/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-resolve/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-resolve/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runner/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-runner/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-runtime/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-snapshot/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.6.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-util/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-validate/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-watcher/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.6.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/node-int64": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.14", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pure-rand": { + "version": "6.1.0", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/react-is": { + "version": "18.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate": { + "version": "1.4.2", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "dev": true, + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.16", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/xml": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/src/main/resources/templates/javascript/test/package.json b/src/main/resources/templates/javascript/test/package.json new file mode 100644 index 000000000000..3971d2b0f3c6 --- /dev/null +++ b/src/main/resources/templates/javascript/test/package.json @@ -0,0 +1,24 @@ +{ + "name": "artemis-test", + "private": true, + "scripts": { + "test": "jest", + "test:ci": "jest --ci --reporters=default --reporters=jest-junit" + }, + "workspaces": [ + "assignment" + ], + "devDependencies": { + "@babel/core": "^7.24.7", + "@babel/preset-env": "^7.24.7", + "@types/jest": "^29.5.12", + "babel-jest": "^29.7.0", + "jest": "^29.7.0", + "jest-junit": "^16.0.0" + }, + "jest-junit": { + "classNameTemplate": "{classname}_{title}", + "titleTemplate": "{classname}_{title}", + "ancestorSeparator": "_" + } +} diff --git a/src/main/resources/templates/javascript/test/src/behavior.test.js b/src/main/resources/templates/javascript/test/src/behavior.test.js new file mode 100644 index 000000000000..1a1d1ba86ff7 --- /dev/null +++ b/src/main/resources/templates/javascript/test/src/behavior.test.js @@ -0,0 +1,71 @@ +import MergeSort from 'artemis-exercise/mergesort.js'; +import BubbleSort from 'artemis-exercise/bubblesort.js'; +import Context from 'artemis-exercise/context.js'; +import Policy from 'artemis-exercise/policy.js'; + +// prettier-ignore +const datesWithCorrectOrder = [ + new Date('2016-02-15'), + new Date('2017-04-15'), + new Date('2017-09-15'), + new Date('2018-11-08'), +]; + +describe('behavior', () => { + let dates; + beforeEach(() => { + // prettier-ignore + dates = [ + new Date('2018-11-08'), + new Date('2017-04-15'), + new Date('2016-02-15'), + new Date('2017-09-15'), + ]; + }); + + describe('BubbleSort', () => { + it('should_sort_correctly', () => { + const bubbleSort = new BubbleSort(); + bubbleSort.performSort(dates); + expect(dates).toEqual(datesWithCorrectOrder); + }); + }); + + describe('MergeSort', () => { + it('should_sort_correctly', () => { + const mergeSort = new MergeSort(); + mergeSort.performSort(dates); + expect(dates).toEqual(datesWithCorrectOrder); + }); + }); + + describe('Policy', () => { + it('uses_MergeSort_for_big_list', () => { + const bigList = []; + for (let i = 0; i < 11; i++) { + bigList.push(new Date()); + } + + const context = new Context(); + context.dates = bigList; + const policy = new Policy(context); + policy.configure(); + const chosenSortStrategy = context.sortAlgorithm; + expect(chosenSortStrategy).toBeInstanceOf(MergeSort); + }); + + it('uses_BubbleSort_for_small_list', () => { + const smallList = []; + for (let i = 0; i < 3; i++) { + smallList.push(new Date()); + } + + const context = new Context(); + context.dates = smallList; + const policy = new Policy(context); + policy.configure(); + const chosenSortStrategy = context.sortAlgorithm; + expect(chosenSortStrategy).toBeInstanceOf(BubbleSort); + }); + }); +}); diff --git a/src/main/resources/templates/javascript/test/src/structural.test.js b/src/main/resources/templates/javascript/test/src/structural.test.js new file mode 100644 index 000000000000..ed9ee705aa78 --- /dev/null +++ b/src/main/resources/templates/javascript/test/src/structural.test.js @@ -0,0 +1,44 @@ +import MergeSort from 'artemis-exercise/mergesort.js'; +import BubbleSort from 'artemis-exercise/bubblesort.js'; +import Context from 'artemis-exercise/context.js'; +import Policy from 'artemis-exercise/policy.js'; + +describe('structural', () => { + describe('Context', () => { + const context = new Context(); + + it('has_properties', () => { + expect(context).toHaveProperty('dates'); + expect(context).toHaveProperty('sortAlgorithm'); + }); + + it('has_methods', () => { + expect(context).toHaveProperty('sort', expect.any(Function)); + }); + }); + + describe('Policy', () => { + const context = new Context(); + const policy = new Policy(context); + + it('has_properties', () => { + expect(policy).toHaveProperty('context'); + }); + + it('has_methods', () => { + expect(policy).toHaveProperty('configure', expect.any(Function)); + }); + }); + + describe('BubbleSort', () => { + it('has_method', () => { + expect(BubbleSort.prototype).toHaveProperty('performSort', expect.any(Function)); + }); + }); + + describe('MergeSort', () => { + it('has_method', () => { + expect(MergeSort.prototype).toHaveProperty('performSort', expect.any(Function)); + }); + }); +}); diff --git a/src/main/resources/templates/jenkins/javascript/regularRuns/pipeline.groovy b/src/main/resources/templates/jenkins/javascript/regularRuns/pipeline.groovy new file mode 100644 index 000000000000..bc37c762097a --- /dev/null +++ b/src/main/resources/templates/jenkins/javascript/regularRuns/pipeline.groovy @@ -0,0 +1,59 @@ +/* + * This file configures the actual build steps for the automatic grading. + * + * !!! + * For regular exercises, there is no need to make changes to this file. + * Only this base configuration is actively supported by the Artemis maintainers + * and/or your Artemis instance administrators. + * !!! + */ + +dockerImage = '#dockerImage' +dockerFlags = '#dockerArgs' + +/** + * Main function called by Jenkins. + */ +void testRunner() { + docker.image(dockerImage).inside(dockerFlags) { c -> + runTestSteps() + } +} + +private void runTestSteps() { + test() +} + +/** + * Run unit tests + */ +private void test() { + stage('Build') { + sh 'npm ci --prefer-offline --no-audit' + } + stage('Test') { + sh 'npm run test:ci' + } +} + +/** + * Script of the post build tasks aggregating all JUnit files in $WORKSPACE/results. + * + * Called by Jenkins. + */ +void postBuildTasks() { + sh ''' + rm -rf results + mkdir results + if [ -e junit.xml ] + then + sed -i 's/]*>//g ; s/<\\/testsuites>/<\\/testsuite>/g' junit.xml + fi + cp junit.xml $WORKSPACE/results/ || true + sed -i 's/[^[:print:]\t]/�/g' $WORKSPACE/results/*.xml || true + ''' +} + +// very important, do not remove +// required so that Jenkins finds the methods defined in this script +return this diff --git a/src/main/webapp/app/entities/programming/programming-exercise.model.ts b/src/main/webapp/app/entities/programming/programming-exercise.model.ts index 3d47a8320bd2..ef2d95985068 100644 --- a/src/main/webapp/app/entities/programming/programming-exercise.model.ts +++ b/src/main/webapp/app/entities/programming/programming-exercise.model.ts @@ -24,6 +24,7 @@ export enum ProgrammingLanguage { OCAML = 'OCAML', EMPTY = 'EMPTY', RUST = 'RUST', + JAVASCRIPT = 'JAVASCRIPT', } export enum ProjectType { diff --git a/src/test/resources/config/application.yml b/src/test/resources/config/application.yml index f7d8bc06ea1b..742c904105e9 100644 --- a/src/test/resources/config/application.yml +++ b/src/test/resources/config/application.yml @@ -68,6 +68,8 @@ artemis: default: "~~invalid~~" rust: default: "~~invalid~~" + javascript: + default: "~~invalid~~" spring: application: From 64be5de2793c81f42848f28f8b65bd2f417cc175 Mon Sep 17 00:00:00 2001 From: Simon Entholzer <33342534+SimonEntholzer@users.noreply.github.com> Date: Thu, 19 Sep 2024 22:26:10 +0200 Subject: [PATCH 06/49] Development: Add admin metrics page tests (#9249) --- .../metrics-garbagecollector.component.html | 42 ++++++++++------- .../artemis/JhiMetricsIntegrationTest.java | 45 +++++++++++++++++++ 2 files changed, 70 insertions(+), 17 deletions(-) create mode 100644 src/test/java/de/tum/cit/aet/artemis/JhiMetricsIntegrationTest.java diff --git a/src/main/webapp/app/admin/metrics/blocks/metrics-garbagecollector/metrics-garbagecollector.component.html b/src/main/webapp/app/admin/metrics/blocks/metrics-garbagecollector/metrics-garbagecollector.component.html index 680ebefc10d8..725183033342 100644 --- a/src/main/webapp/app/admin/metrics/blocks/metrics-garbagecollector/metrics-garbagecollector.component.html +++ b/src/main/webapp/app/admin/metrics/blocks/metrics-garbagecollector/metrics-garbagecollector.component.html @@ -1,7 +1,7 @@ -

+

- @if (garbageCollectorMetrics) { + @if (garbageCollectorMetrics && garbageCollectorMetrics['jvm.gc.live.data.size']) {
GC Live Data Size/GC Max Data Size ({{ garbageCollectorMetrics['jvm.gc.live.data.size'] / 1048576 | number: '1.0-0' }}M / @@ -19,8 +19,10 @@

}
-
- @if (garbageCollectorMetrics) { +
+
+ @if (garbageCollectorMetrics && garbageCollectorMetrics['jvm.gc.memory.promoted']) { +
GC Memory Promoted/GC Memory Allocated ({{ garbageCollectorMetrics['jvm.gc.memory.promoted'] / 1048576 | number: '1.0-0' }}M / @@ -36,8 +38,10 @@

{{ (100 * garbageCollectorMetrics['jvm.gc.memory.promoted']) / garbageCollectorMetrics['jvm.gc.memory.allocated'] | number: '1.0-2' }}%
- } -
+
+ } +
+
@if (garbageCollectorMetrics) {
@@ -50,6 +54,8 @@

}
+
+
@if (!updating && garbageCollectorMetrics) {
@@ -67,17 +73,19 @@

- - - - - - - - - - - + @if (garbageCollectorMetrics['jvm.gc.pause']) { + + + + + + + + + + + + }
jvm.gc.pause{{ garbageCollectorMetrics['jvm.gc.pause'].count }}{{ garbageCollectorMetrics['jvm.gc.pause'].mean | number: '1.0-3' }}{{ garbageCollectorMetrics['jvm.gc.pause']['0.0'] | number: '1.0-3' }}{{ garbageCollectorMetrics['jvm.gc.pause']['0.5'] | number: '1.0-3' }}{{ garbageCollectorMetrics['jvm.gc.pause']['0.75'] | number: '1.0-3' }}{{ garbageCollectorMetrics['jvm.gc.pause']['0.95'] | number: '1.0-3' }}{{ garbageCollectorMetrics['jvm.gc.pause']['0.99'] | number: '1.0-3' }}{{ garbageCollectorMetrics['jvm.gc.pause'].max | number: '1.0-3' }}
jvm.gc.pause{{ garbageCollectorMetrics['jvm.gc.pause'].count }}{{ garbageCollectorMetrics['jvm.gc.pause'].mean | number: '1.0-3' }}{{ garbageCollectorMetrics['jvm.gc.pause']['0.0'] | number: '1.0-3' }}{{ garbageCollectorMetrics['jvm.gc.pause']['0.5'] | number: '1.0-3' }}{{ garbageCollectorMetrics['jvm.gc.pause']['0.75'] | number: '1.0-3' }}{{ garbageCollectorMetrics['jvm.gc.pause']['0.95'] | number: '1.0-3' }}{{ garbageCollectorMetrics['jvm.gc.pause']['0.99'] | number: '1.0-3' }}{{ garbageCollectorMetrics['jvm.gc.pause'].max | number: '1.0-3' }}
diff --git a/src/test/java/de/tum/cit/aet/artemis/JhiMetricsIntegrationTest.java b/src/test/java/de/tum/cit/aet/artemis/JhiMetricsIntegrationTest.java new file mode 100644 index 000000000000..a5ddcf176a6d --- /dev/null +++ b/src/test/java/de/tum/cit/aet/artemis/JhiMetricsIntegrationTest.java @@ -0,0 +1,45 @@ +package de.tum.cit.aet.artemis; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.security.test.context.support.WithMockUser; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +class JhiMetricsIntegrationTest extends AbstractSpringIntegrationIndependentTest { + + @Autowired + private ObjectMapper objectMapper; + + @Test + @WithMockUser(username = "admin", roles = "ADMIN") + void getMetricsTest() throws Exception { + var result = request.get("/management/jhimetrics", HttpStatus.OK, String.class); + + JsonNode rootNode = objectMapper.readTree(result); + + assertThat(rootNode.has("jvm")).isTrue(); + assertThat(rootNode.path("jvm").has("G1 Old Gen")).isTrue(); + assertThat(rootNode.path("jvm").path("G1 Old Gen").has("committed")).isTrue(); + assertThat(rootNode.path("jvm").path("G1 Old Gen").has("max")).isTrue(); + assertThat(rootNode.path("jvm").path("G1 Old Gen").has("used")).isTrue(); + + assertThat(rootNode.has("http.server.requests")).isTrue(); + assertThat(rootNode.path("http.server.requests").path("all").has("count")).isTrue(); + + assertThat(rootNode.has("cache")).isTrue(); + + assertThat(rootNode.has("garbageCollector")).isTrue(); + assertThat(rootNode.path("garbageCollector").has("jvm.gc.max.data.size")).isTrue(); + assertThat(rootNode.path("garbageCollector").path("jvm.gc.pause").has("max")).isTrue(); + + assertThat(rootNode.has("processMetrics")).isTrue(); + assertThat(rootNode.path("processMetrics").has("process.cpu.usage")).isTrue(); + + assertThat(rootNode.has("customMetrics")).isTrue(); + } +} From afa1e3f3c149a9ffe48463f9ec297a026a241e81 Mon Sep 17 00:00:00 2001 From: Michael Baumgartner Date: Thu, 19 Sep 2024 22:26:54 +0200 Subject: [PATCH 07/49] Development: Document Jenkins and LocalVC setup (#9266) --- README.md | 5 +- docker/gitlab/gitlab-local-setup.sh | 2 +- docker/jenkins.yml | 2 +- ...fig.yml => jenkins-casc-config-gitlab.yml} | 0 .../jenkins/jenkins-casc-config-localvc.yml | 33 + docker/jenkins/plugins.yml | 1 - docs/dev/setup.rst | 4 +- docs/dev/setup/jenkins-gitlab.rst | 121 +-- .../jenkins_project_config_xml.png | Bin 189043 -> 0 bytes .../jenkins-gitlab/jenkins_test_project.png | Bin 318059 -> 0 bytes docs/dev/setup/jenkins-localvc.rst | 779 ++++++++++++++++++ 11 files changed, 835 insertions(+), 112 deletions(-) rename docker/jenkins/{jenkins-casc-config.yml => jenkins-casc-config-gitlab.yml} (100%) create mode 100644 docker/jenkins/jenkins-casc-config-localvc.yml delete mode 100644 docs/dev/setup/jenkins-gitlab/jenkins_project_config_xml.png delete mode 100644 docs/dev/setup/jenkins-gitlab/jenkins_test_project.png create mode 100644 docs/dev/setup/jenkins-localvc.rst diff --git a/README.md b/README.md index 040487b2ae20..044b49dec4f5 100644 --- a/README.md +++ b/README.md @@ -139,8 +139,9 @@ You can find a guide on [how to write documentation](docs/README.md). Setting up Artemis in your development environment or a demo production environment is really easy following the instructions on https://docs.artemis.cit.tum.de/dev/setup. When you want to support programming exercises, we recommend using the [Integrated Code Lifecycle](https://docs.artemis.cit.tum.de/dev/setup/#integrated-code-lifecycle-setup). Artemis can also be set up in conjunction with external tools for version control and continuous integration: -1. [GitLab and Jenkins](https://docs.artemis.cit.tum.de/dev/setup/#jenkins-and-gitlab-setup) -2. [GitLab and GitLab CI (experimental)](https://docs.artemis.cit.tum.de/dev/setup/#gitlab-ci-and-gitlab-setup) +1. [LocalVC and Jenkins](https://docs.artemis.cit.tum.de/dev/setup/#jenkins-and-localvc-setup) +2. [GitLab and Jenkins (deprecated)](https://docs.artemis.cit.tum.de/dev/setup/#jenkins-and-gitlab-setup) +3. [GitLab and GitLab CI (experimental)](https://docs.artemis.cit.tum.de/dev/setup/#gitlab-ci-and-gitlab-setup) Artemis uses these external tools for user management and the configuration of programming exercises. diff --git a/docker/gitlab/gitlab-local-setup.sh b/docker/gitlab/gitlab-local-setup.sh index 8a29ab818082..4e979c3ab2ea 100644 --- a/docker/gitlab/gitlab-local-setup.sh +++ b/docker/gitlab/gitlab-local-setup.sh @@ -47,7 +47,7 @@ artemis: " echo -echo 'The access Jenkins token has been created and can be copied into your jenkins-casc-config.yml file:' +echo 'The access Jenkins token has been created and can be copied into your jenkins-casc-config-gitlab.yml file:' echo " credentials: system: diff --git a/docker/jenkins.yml b/docker/jenkins.yml index 86b532593197..ca4f35492475 100644 --- a/docker/jenkins.yml +++ b/docker/jenkins.yml @@ -13,7 +13,7 @@ services: - artemis-jenkins-data:/var/jenkins_home - ./jenkins/jenkins-disable-csrf.groovy:/var/jenkins_home/init.groovy # Disable CSRF token - ./jenkins/master-key-only-for-testing.key:/var/jenkins_home/master.key # Preset master key to use pre-generated secrets - - ./jenkins/jenkins-casc-config.yml:/usr/share/jenkins/ref/jenkins-casc-config.yml:ro + - ./jenkins/jenkins-casc-config-gitlab.yml:/usr/share/jenkins/ref/jenkins-casc-config.yml:ro - /var/run/docker.sock:/var/run/docker.sock ports: - "8082:8080" diff --git a/docker/jenkins/jenkins-casc-config.yml b/docker/jenkins/jenkins-casc-config-gitlab.yml similarity index 100% rename from docker/jenkins/jenkins-casc-config.yml rename to docker/jenkins/jenkins-casc-config-gitlab.yml diff --git a/docker/jenkins/jenkins-casc-config-localvc.yml b/docker/jenkins/jenkins-casc-config-localvc.yml new file mode 100644 index 000000000000..36766ce7dd01 --- /dev/null +++ b/docker/jenkins/jenkins-casc-config-localvc.yml @@ -0,0 +1,33 @@ +jenkins: + systemMessage: "Jenkins has been configured to run with Artemis\n\n" + securityRealm: + local: + allowsSignup: false + users: + - id: "artemis_admin" # Artemis admin username + password: "artemis_admin" # Artemis admin password + labelString: "docker" + authorizationStrategy: + projectMatrix: + permissions: + - "Overall/Administer:artemis_admin" # Make sure that the username matches the Artemis admin username + - "Overall/Read:authenticated" +credentials: + system: + domainCredentials: + - credentials: + - string: + id: artemis_notification_plugin_token # Value of the "artemis-authentication-token-key" defined key in application-artemis.yml + description: 'Access token for Artemis Test Notification Plugin' + scope: GLOBAL + secret: artemis_admin # Value of the "artemis-authentication-token-value" key defined in application-artemis.yml + - usernamePassword: + id: artemis_localvc_credentials + scope: GLOBAL + username: "jenkins" # artemis.version-control.build-agent-git-username + password: "artemis_admin" # artemis.version-control.build-agent-git-password + description: "LocalVC credentials for Artemis" +unclassified: + timestamper: + elapsedTimeFormat: "''yyyy-MM-dd'T'HH:mm:ssX' '" + systemTimeFormat: "''yyyy-MM-dd'T'HH:mm:ssX' '" diff --git a/docker/jenkins/plugins.yml b/docker/jenkins/plugins.yml index 028d098e34fb..859200f9f59a 100644 --- a/docker/jenkins/plugins.yml +++ b/docker/jenkins/plugins.yml @@ -2,7 +2,6 @@ plugins: - artifactId: matrix-auth - artifactId: docker-workflow - - artifactId: gitlab-plugin - artifactId: pipeline-maven - artifactId: timestamper - artifactId: configuration-as-code diff --git a/docs/dev/setup.rst b/docs/dev/setup.rst index 3ed91396dc39..01c6a0acec05 100644 --- a/docs/dev/setup.rst +++ b/docs/dev/setup.rst @@ -46,7 +46,8 @@ following dependencies/tools on your machine: There are multiple stacks available for the integration with Artemis: * :ref:`Integrated Code Lifecycle Setup ` - * :ref:`GitLab and Jenkins ` + * :ref:`LocalVC and Jenkins ` + * :ref:`GitLab and Jenkins ` (deprecated) * :ref:`GitLab and GitLab CI ` (experimental, not yet production ready) ------------------------------------------------------------------------------------------------------------------------ @@ -74,6 +75,7 @@ following dependencies/tools on your machine: setup/server setup/client setup/integrated-code-lifecycle + setup/jenkins-localvc setup/jenkins-gitlab setup/gitlabci-gitlab setup/aeolus diff --git a/docs/dev/setup/jenkins-gitlab.rst b/docs/dev/setup/jenkins-gitlab.rst index 60a226292c68..59fe3b0bde26 100644 --- a/docs/dev/setup/jenkins-gitlab.rst +++ b/docs/dev/setup/jenkins-gitlab.rst @@ -3,6 +3,12 @@ Jenkins and GitLab Setup ------------------------ +.. warning:: + + GitLab support will be removed with Artemis 8.0.0. + Please use :ref:`LocalVC and Jenkins ` instead for new installations with Jenkins as the CI system. + For existing Jenkins and GitLab Setups, you can migrate to LocalVC with this `not merged Pull Request `__. + This section describes how to set up a programming exercise environment based on Jenkins and GitLab. Optional commands are in curly brackets ``{}``. @@ -63,7 +69,6 @@ the `Gitlab Server Quickstart <#gitlab-server-quickstart>`__ guide. user: artemis_admin password: artemis_admin url: http://localhost:8082 - secret-push-token: AQAAABAAAAAg/aKNFWpF9m2Ust7VHDKJJJvLkntkaap2Ka3ZBhy5XjRd8s16vZhBz4fxzd4TH8Su # pre-generated or replaced in Automated Jenkins Server step 3 vcs-credentials: artemis_gitlab_admin_credentials artemis-authentication-token-key: artemis_notification_plugin_token artemis-authentication-token-value: artemis_admin @@ -466,8 +471,8 @@ Automated Jenkins Server Setup The following steps describe how to deploy a pre-configured version of the Jenkins server. This is ideal as a quickstart for developers. For a more detailed setup, see `Manual Jenkins Server Setup <#manual-jenkins-server-setup>`__. -In a production setup, you have to at least change the user credentials (in the file ``jenkins-casc-config.yml``) and -generate random access tokens and push tokens. +In a production setup, you have to at least change the user credentials (in the file ``jenkins-casc-config-gitlab.yml``) and +generate random access tokens. 1. Create a new access token in GitLab named ``Jenkins`` and give it **api** and **read_repository** rights. You can do either do it manually or using the following command: @@ -486,20 +491,9 @@ do either do it manually or using the following command: docker compose -f docker/.yml up -d Jenkins is then reachable under ``http://localhost:8082/`` and you can login using the credentials specified - in ``jenkins-casc-config.yml`` (defaults to ``artemis_admin`` as both username and password). - -3. You need to generate the `secret-push-token`. + in ``jenkins-casc-config-gitlab.yml`` (defaults to ``artemis_admin`` as both username and password). - .. - Workaround as long as Github Issue 5973 (Default Push Notifications GitLab → Jenkins not working) - for now just generate the secret-push-token manually - - As there is currently an `open issue with the presets for Jenkins in Development environments `__, - follow the steps described in - `Gitlab to Jenkins push notification token <#gitlab-to-jenkins-push-notification-token>`__ to generate the token. - In a production setup, you should use a random ``master.key`` in the file ``gitlab-jenkins-mysql.yml``. - -4. The `application-local.yml` must be adapted with the values configured in ``jenkins-casc-config.yml``: +3. The `application-local.yml` must be adapted with the values configured in ``jenkins-casc-config-gitlab.yml``: .. code:: yaml @@ -517,7 +511,6 @@ do either do it manually or using the following command: user: artemis_admin password: artemis_admin url: http://localhost:8082 - secret-push-token: # pre-generated or replaced in Automated Jenkins Server step 3 vcs-credentials: artemis_gitlab_admin_credentials artemis-authentication-token-key: artemis_notification_plugin_token artemis-authentication-token-value: artemis_admin @@ -711,22 +704,19 @@ The list of plugins is maintained in ``docker/jenkins/plugins.yml``. You will need to install the following plugins (apart from the recommended ones that got installed during the setup process): -1. `GitLab `__ for enabling - webhooks to and from GitLab - -2. `Timestamper `__ for adding the +1. `Timestamper `__ for adding the time to every line of the build output (Timestamper might already be installed) -3. `Pipeline `__ for defining the +2. `Pipeline `__ for defining the build description using declarative files (Pipeline might already be installed) **Note:** This is a suite of plugins that will install multiple plugins -4. `Pipeline Maven `__ to use maven within the pipelines. If you want to +3. `Pipeline Maven `__ to use maven within the pipelines. If you want to use Docker for your build agents you may also need to install `Docker Pipeline `__ . -5. `Matrix Authorization Strategy Plugin `__ for configuring permissions +4. `Matrix Authorization Strategy Plugin `__ for configuring permissions for users on a project and build plan level (Matrix Authorization Strategy might already be installed). @@ -868,87 +858,6 @@ GitLab Repository Access continuous-integration: vcs-credentials: the.id.of.the.username.and.password.credentials.from.jenkins -GitLab to Jenkins push notification token -""""""""""""""""""""""""""""""""""""""""" - -GitLab has to notify Jenkins build plans if there are any new commits to -the repository. The push notification that gets sent here is secured by -a token generated by Jenkins. In order to get this token, you have to do -the following steps: - -1. Create a new item in Jenkins (use the Freestyle project type) and - name it **TestProject** - -2. In the project configuration, go to *Build Triggers → Build when a - change is pushed to GitLab* and activate this option - -3. Click on *Advanced*. - -4. You will now have a couple of new options here, one of them being a - “**Secret token**”. - -5. Click on the “*Generate*” button right below the text box for that - token. - -6. Copy the generated value, let’s call it **$gitlab-push-token** - -7. Apply these change to the plan (i.e. click on *Apply*) - - .. figure:: jenkins-gitlab/jenkins_test_project.png - :align: center - -8. Perform a *GET* request to the following URL (e.g. with Postman) - using Basic Authentication and the username and password you chose - for the Jenkins admin account: - - :: - - GET https://your.jenkins.domain/job/TestProject/config.xml - - If you have xmllint installed, you can use this command, which will output the ``secret-push-token`` from - steps 9 and 10 (you may have to adjust the username and password): - - .. code:: bash - - curl -u artemis_admin:artemis_admin http://localhost:8082/job/TestProject/config.xml | xmllint --nowarning --xpath "//project/triggers/com.dabsquared.gitlabjenkins.GitLabPushTrigger/secretToken/text()" - | sed 's/^.\(.*\).$/\1/' - -9. You will get the whole configuration XML of the just created build - plan, there you will find the following tag: - - :: - - {$some-long-encrypted-value} - - .. figure:: jenkins-gitlab/jenkins_project_config_xml.png - :align: center - - Job configuration XML - -10. Copy the ``secret-push-token value`` in the line - ``{secret-push-token}``. This is the encrypted value of the ``gitlab-push-token`` - you generated in step 5. - -11. Now, you can delete this test project and input the following values - into your Artemis configuration *application-artemis.yml* (replace - the placeholders with the actual values you wrote down) - - .. code:: yaml - - artemis: - continuous-integration: - secret-push-token: $some-long-encrypted-value - -12. In a local setup, you have to disable CSRF otherwise some API endpoints will return HTTP Status 403 Forbidden. - This is done be executing the following command: - ``docker compose -f docker/.yml exec -T jenkins dd of=/var/jenkins_home/init.groovy < docker/jenkins/jenkins-disable-csrf.groovy`` - - The last step is to disable the ``use-crumb`` option in ``application-local.yml``: - - .. code:: yaml - - jenkins: - use-crumb: false - Upgrading Jenkins """"""""""""""""" @@ -1010,7 +919,7 @@ You should also update the Jenkins plugins regularly due to security reasons. You can update them directly in the Web User Interface in the Plugin Manager. -.. _jenkins_build_agents: +.. _jenkins_build_agents_gitlab: Build agents ^^^^^^^^^^^^ diff --git a/docs/dev/setup/jenkins-gitlab/jenkins_project_config_xml.png b/docs/dev/setup/jenkins-gitlab/jenkins_project_config_xml.png deleted file mode 100644 index 4d5cc9bda4680cb91ac0304035deb4acd0462c69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 189043 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˥)`_LJcV!g;}>j{smfvr_J>?7zG=e8k|~-k`70B$P4ECpAG-Z zs`GDq*@@6w>|MVsP{^#%VhD+ZdgVHNv+{`2&`iBgZ6! zDBy#c{SVDBv84r&bkoivz6zkb4D6C*qJ78iU?OM|j8Ws(e%no zSyn1?h;o|>6&cGslMfI$6wUuQfb`E>GLp}0-YZ3fL6meq(GSRf@n@x7^;X6-wt=ys z4S=gxQ_-&)aN}+$c>~8sIoog0j^K7Vo&p6l?B2R`$Jx#1iM6y=4l`S;SX6+4$^Nf1 z0ptN+mX12(8jHyZs{rS%!U3NE!Islv$DY8*$$VEWI%Iz|1z}169{J4mLHpw+zr~iF z?RC6t&{&}m^cVW44K+9+%Ng-2x|Z;IQx&QJ3@qbX4W*Z%AgyV}h% zcKTY-h3x-+@`+jP$haBCkkz}A9(p{k(PL;SI=?HO)P5kb5IdLmu`R}UYQS4cTFpY= zEf6kon}VIoHVlzF>OCmUzdF46Q=Jj-fZjIYTFAhXI}p^I_v2Wc<`TNn5;WFTZ$#bw z&tdvu>o+3U45bC@RnXb_rdeVxA)};JTwZ>h?CUTf;~5HPvHaQljj`(Itd)iFDoe!v z8G$t+`S<^_Ik>m2uun+iLV}Hjg$1e*xIab}hW)|9ckJIgRteO9SfYZtz(%Nl{@dU< zLC8uc_A-QV?J!m?<cI4G(*R!5#%XxuRk<{2uRy%(SJ96&kMXSM%j<8dcLQ)sna zvKG4JnOyW-)OcpdNnW4(@HgoAd(-G!48+}MhoYpRLG7GHeg(U^{x!(5|Cd}+iiH2L zE%DBW(vjo5Appe@n#nbqHD^3O6*f$oRgQ^co!+PG6bdz_z;ShrCu$%Cfe3R)z-B1< zgM3^7yn*#`R|wT@%Z<2T7FB|i=~CjMJn!Xx`omi?}$$8^vj&bH)6lo2JhR?uSQN~ zkMPn$?yJ{khq+b9Zy&=ML`#)Sy z4j$JIX$c_IZlN;c)ge%SM@Ee|s8x`#1kLkMF{sdV_Q5jYa+d5p`Pn}EI>+oxx)&tm zO+f$HKTO0^?I}Ipy~p_VI?dOP_Ttoc$zc4ZyHYZVD@qV`^~bHhhSIz0C6hmb^4{R^ zMe9|&yV1TQXhrs}rm9sXe(wChU(f>;0UstCo8Hm?5&=|#tTIq@$e;FV8<-8s>Ew@z zuInIq2PvH|#ivoH*ND|#KlOyVXSwHI=(UO1Ji}P6+N8hniZU2Z zv?QVY+En0Wi}u*-K}+Zk-!OG;0-E1lO%5w#U|M10daT|hy4MfqlpoC)2XWsr!81&X#}#(vB62UvZHKYUVCAF zOsB+n?nJ3W9A4~=VcC>}UU?V|53izxTldR&Sxjh_p}wvu&+aAK+EiF>v>@JWsC03? ztFhHWbL^Gdj>=XYT(ocO0J&04GRHwW$#M(yG^PF0rb$1$acrMP+15S;Ijhy!()gF3 zM^t*BN`(6lp*0`bRBqk5kC)lF1hK{EFl3B7R@Gfq#7rwy|FxX-Y4r{&7eCsm`&a~# z!r)ng(~qfibb7;ReFS~h*3F}Iuxaib(Si1$@mF=q19+OvZvI0Dr-t*1(! zqx1h{7kXN6RnZk`VA#uA%myuttS=L zMD^9Cm{Cve$57OXHiBSK@o2(t7JFyxUSoVH{>lcT7kV1u&&U4Wj2YMBAKfj{(D#R2 zU(F{RNe+p|bmT`|31miCauZvxxKdPJhWa~YVR+?CQM4Gc#bYPr#+~U!VQChW1x4v$ zw=dR3HqSNG7a$80ZciEkcI^qk-?ck&7DBSm6Nu%y9~G2-lcn(1IOs{+XZZ^!BtP5I zd*~t7o{kjF9^>EOMk}==+ z>3?R=p>(YxmMtP>u|U#d49yNb%k*$vOcghdas4<`mrC#M(zSylDarp6*e$zgt3ZWXGW4BV73}3sZMq<$ z)+9n3&!LR2%>3i`ovA^B(LYqX6F+TCVsHq~yW8}V8&x+!^o5nXSIzW`%_+y3N9=O? z`d5nN*hF7~Wf^1-q6VD(>m@kTECSv0a0>Ik%wZ;POf3P27{hU?xhk7p?|YT{E5|7RM5k;VMy1qdtW0BhUEaVe~@|XRl!r zUIT8G*rOq2k4v40Ijb&YaRmm*&p!zE3`N*JC9FO8ZWfN$MI=-^lyo{4)ludWl6nu@{S;)kWFUBNEH+h*DZkz*vygHy<*}@ zE``D$GGH0G$2z|gYCOZLVw>gO{x)Ifg-^37dS%Xdy^8iYi$a_JTq5DQqql3;Y+NUe zhDRJYkv-fc?WY`K8tF31$>4RTJi^8F)zKMe1jiX@i@NFa6_P|9Vp)>GYnPQRK8Z)U zL%eZc+RDu*OzWXB;8n_D`TEmn`X>(L>C1!mcak?x^)=|#_iav&*NUjriUfEdhqK*| zfzPEgP#ZFe$phV;p*?hP7M<}fDUrS;?`>C+nBfH08vUWFD^y1gM)!sF+^aHkXnn9) zzwx_tHHv6nVyrad&Yo>APSrq&<_6`6bm7m3z)eOR93m zKY9A=Iwj2cklcIQ3kKq{v>t`XhllrVZ;3_j0u)ry%F|*x5WGK~Ey0by_Wm5nb;3~4 z>+ud3Y3zx^6Klj|yJv18hRV&_;KmM$IDB{$kgzF?W%>m{ctb4)4l5#sahoOqvovY) z^{!RiXU3m7xYq6N;YU@aG#b`qqRP)U(0hik-&`OKPc*+po5$V)hR^cLnu?a@#8yR@ zxWx#9TT|m@PCPcerqj4~yC76dwfAWn>`hdMVod)~iLbwh!Mtm4hZE;F{Q}~ZnRys9 zsd-a6R+sVx!CH^Mj!j!oZNEaLP{QFU4kIi8NXhj)_j;F-g2O1?)3sh#(>HzaY6H72%LIsK=C^>b0)Z2v`dF%a-d9GbW=1{7^*SX|1sBM5>qjucB6t<`|5ZiMq{g z`m@y49~YOi-MO)@rdb4AEly&;N+1dLht+|H^God;G{_J-PZQwVVpanVN= zX5;1XCy$4<>ES_5%pv5$s+O$#1MV%eU#2W3)JCD@l2}sGvl;>edEY#BqQW64} zOJ5^9QJ}PtMA=H#muueJL1|A*)F4Q;(-}Tmr-K(|bx?9Jl;%I8{55X;?G>`z26nho z+%|!X_F@XFQU%=ud^@Xnc8?x6VWVGX|Qi*aDosgRq zMpi0EBHYD6!kSIKmXNr<1$i{MV$p0qCmoBuPDs6cv;g_)hC-zSdy%reRJ|FJtmP2< za_1*!0wDHbjbnS#GAt1*eGaAE@02b4mt_LhY}OHz{2HNaaW~D+Kf4{7mrfjZr(?QY zP$nD1WS$mG6~NZ#CxVS$@4K9q9W<&*-vq&n%X{Sw(Ka_E-lhJ50$K83CJ4-LgJM?q zdcSn;C=i9-{rfq(dDY-@_HnLSJ2Qr^O$;CI8OdmFmTey$ywM&6+!5VRIR(-fktxM} z?gU<%n`3DvcSy8Q4NTW);B?+(jo5S6#KA93RFohL_4L3w0?AzliolOAh2O?KLGR2c zjGPZ@F#7G+ujCeoCGzvmrnvTd?V)vLolk0|+u2$SEn@MWw|dc|=S@xC=subLB!0eC2DoE;#9w7@~{z=L`^!a?+O@Mv8hrmI&S{zOgYm7OkZt zo(HSH*MUrZO`;h&IheXp1c^oB-39-SKK>keea|;S>Yr18rr3X$&ciUgjI!-3s?BKE zu&umU1C;MfgWxIhvMaC$a0LQ$f{{VFcnWaRUm0k);UVg%#A@C5*7 zX1DXl_jB6^<+M_gs+2gtP2!RbnxW;><$+tp5bN{Aoc8jTCT^GgkyMMqBAEeteW#9q z(lGM?-7*20>?(;5>GHe&gi}*RK|nB*0`tS?$+mhe8S^?HWOdW|;1tKd9NQ9Z*3SS6 zW3P(OhQi^#CyQ%`Grsp(rGzlyj36T+So=k!n;;2#9MY|XWN|danUVy>l_AKo&S<=b zcJE7{Kq_SnB?R(vn-T|wiqC8DK+rc)Jl%quwYgcwwuKz_DQKhY1NVZ6SBQ@*T&)t| z$|KxUZ(cbWeW;hyIX_6EbhR`{FnGroj)?m-?ewHJ+CFseXK$W-u;uQ&(M;63c?|Cti8_vA z#3tvg$3QSDYS!@mO#X4_J%q}qrc+Kf@JF-`UP<~g9lyj`;=8end%~*^qGOg(LEvO@ z7UwypWuVT?c*itqYR5?rDSZuFZNRb{T-w`+9_G^gW_jx^nwBXFwt_?arx!q_pV;4? z(1_}HV0?ht2v1e#&*7Z|!KC4+`Uuk8<0mz3m?Z!tM0FZXAbpx3SEb?@ek@?$kZ$FO8CB#`wnKQPXR z`?qwjzw+#1Q1USbVUyA06cc{M4)k~sxx-XOWtHtn($Fp8qJ2vr^r-!wWy@$JYGM*oNZe35AyH-EQI3YF*Ll`m@bwo z_rXUO`zn{1KI8>w1(vbTckZ+{EY`Atx%-4hNv*tox9~9+JR?E;LMAzm=(hF1G(Vy2 z!E}Y!EB}qX0Pgqk?lC&r8dSNNhLy+MHe^&LAx7I%<)NocMsxdFrjs%^$T$7s=IHFL~g?<ST~_yDm=dpEHmE-fQ0pI>KwARm<7KLKpOS=)sxX0op{0q+mVlR?7ZhD6Iw# zr#6a3m3X0Q@EaCaBAL-~0(9XJ{jyMe4A1`5MpF<&Wd5!%XBwyILx|Lwy7l(|1Je19 zXh$c)^~{Q!2HT1#Fcq*^ysm_^c5rWW&FIY88ny^_EueaOzSf1w3-<{Wy71 zfOV+A_c}QQv_CJuBPTq^Q=y@22GTGDU5->{HbvJLM=dHo|wwF_k!{BZ^vir;LWgAod9txm+?;O5}~Rq&y+ z+s%6oV`8)Y&?ZgBAF*HqNwqZ8p`-wG`2c9Uyo2FBZhSD`Ioh+sKO`7g3e`#omP6S& z4K~63Qi^G>edddhNUeMJiG8Z5^Smj5GM?b@ExhT}H`x0+6whFM54V#mj8eMtR%Jmr zAwvqMFp@o+SzeGft?@=RmH2!EGDKB$=SY+t;QEo{=?Ji;DwTWQ4$8Nltvnd%uuiVHg~&+1hAosOHKwhA z-?Ni4^g}`11OeL@o|95K`hrt+3?d2WW!;znU8(~NNHKBMchC3*ENOi5*KoD^rUljsgRe^lq&{Ya>%Qvx(HHJLYX z-gMblyR&1mbnoYhCQIxLnYVkQsItvAey&@wetOw=A!#k)%mMP>@UE>4D;>|R%o6+K z4ws%(7FG5ts&@o@&-d~2VG_tvYQr5U%||Gur%)hPiIMxWl6MeEce@iifypxHee&;5D@kW zzbbf{i8OrXvK}Yr^IN>|<^0${{kfa_sLL()(8J9jQl4(tOESxlOtB2U3HnFej|d90E!He4&VUE9biM(M0`Su5 zWNnacArv1xZ)B77OcLi4g*7i%tDjaVDn`!0nPlZo(P(0}i_~{u*Q4(gyHG>K#Bx$06wYpk!g^&B3y?4?M)l%pnp?^z)xM~XWTvu2 zn**Kly9rQSrJ`)kGt)519yogC%@?pvNpbG89-4l=KGRFB{cJyD$+SGC_}Q|GR05&2 z{s*fKA6CuJzo9vJ zfwM*_zccv06v*lR@ji=E<|gKg*)=gH17a5ccdSHF=qIpn>9k75bE#A7$hRAByyp=kz$oA7qF-+nt~dO{xjWE zDu$d5de#M5X5@=OYhuk5I-zOwJ==08#5Ju>u+%N}&yMqTU2BX#vo|)k-g)EtGSU;O z06tC`uY5Kj?9`}d%e@qNM0?!C#i3|+@YN6lPm}*ls**v2y7o-r6kh>?HjJh>JnQJY zOKHcmRPlYI)s2tDQthXYOWf#maC`2WCO-%qIm6;~?uGgU-PZ;UEMHgaSsf$Op(kHU zG|6wudGa9}g+eASe{%FV?HpdC3DTPVNh~X=j2fD;DuzRSR}auVDwsXL9mb9ydAJh? z5`-Uqs4E$R#M`;d$ILw`R;TxnBhSSyPy1;>vyW-utm-s!_)kpv5sb~GPP@P#3NkWQBrVyKx_ z-(!xRzf; zVgJPZE2yt?La-@TFnL#YBrkd(X?ECSP6ZlHtyB}{uNzEmJruP1t;ak*`5R_T|f5H2}C)lT`;I;z*Bi|GuyU*#0LqUb`Fj5CUZW;2HW54H}16`_~dI&J$}~0DG;0)LiDlC zFl#G^OFpjNk6rIowss)LPAj6`%vB&clB9I(H&^IK2YL#5aY%Cb!BWcsJ8Hz zSJddbE+I9BL3$TH+`-8*f5xH@lxFAPTTJjKCn#afA9wl5?xZ_A?{ZnV_T1>9w=Ct4 z&!UtahqKSP{DjX}qz6OWyeA15+)<*sZbF
S4+u8<Gsli9dGW*j-r~Rsn+<2(JtlbvxhrPE7sb465&qG7Jjy&eeSGZI$wKr zcdMfOsPt>M?8eS|qi`S>JxpUz`l3`(9V>r`73DnJ&tQK45s=4_Hb{gu7YSF`hNA6TJDOtv6o#ckcwUtv58U6Rz>X?{_=zUtD+Pux9h(yN7gzIqUZe z>$wErVH^lc7+-yd{ht6M^{K&J>f#Lsy))Rh6!!J-F>L7s-8o~+DlmxE33NBC#KP*r z7Pig5=iEK(0g-8cYXj);EVv*0lO2~=h6#l)ZE0CqY;#?Aw6E>J`rTvvEimFV>`Ce=@|5J<<71UG2u>*f zBkpf!E#{~(OKLQ*3I`xwTpZBeaP*zC*@(k>FH8HlSQJ<^4r4$2mpZ9J(2d!wr+|!| zLTU$zk&|$K(bli=4nK(~I7-&={CrA~eA`MRlTjFIS*>m!m{4-2(guGeCB~cCF)xJ= zWvP5Eeg){7!qT@qVye6+pMU^|8;*#&)n5g#&`1Qo0d{wF+#UD9t*y@*Hle%+bFhC? zMZ_d!C}5OoP*1WB%(1EBcAF|bl6Ky8us^FTT0%C>ZhclsNKYZ4H7Y!%nDXS zLiX-=pSA-6AYX8c>(rS{|lIK^_G>xw&nRUq%Bh7zJw*VI3)aU_xZVGU? z{`To<^Q|3yW+}DAh+KOkgiC^^H(w7 zIjq-?=X{G}X0kEa!&{qtYOC{l9M<7=)x8ym&`)R1U$+DIn6bG}~SK8$^)dD~35pQr}0Y^o;~UNo^(Nxj4S4d+6Lj~C*IxuekXVnh0S@Tgq{dr<(@ zwnDfipp}95-CDda*+D?5HL0UtNu3BEsNzsV=-fypKkQFId^rkLOBY(bCEaDWCs^qn zdV9J>_=)p5R%CU0C3M;{XC|yh4|PvW7Qk%F`;37~woiR(sAZ(^9nD^pLV@6_Z{FP&z%Y$e(68jO{$ffCC4TU(jT+MoG->On!~hb}65Yd7EOtR=pt7GxKe zeR9l*d;j+D5eb6ZMwykyE;_Vjy3;IrvaKslyuL#bRtiAQV@RP&MZ_tUj?ZuabEt*0 z5mS8oCPE)SNpdvR+u7N;1{<$WCu`G=N)amEz9WHRlBh@RlB<4+1;Zfr^!lVbwJ$^B zGG{B1YTm7M3PKgxh<-AaOi=Xb8-6JsY8Hpi59M4K7la-8RdOUhuS;580$W)IKM;V7 zlA8P}LX-rC0XE%PIX+>QVK;1+G!DbC=+x|_)3iA)bi&Tj!;w{{{L4{$M7{}QU0p9;v)yV7Tw%2i0|D;U~n}N*q_h{ zv&A}Mpp|*|TZw&T(1A{EhmU8@)KN47M#W-iW61#IomOKby`s}YqG1Wc_jIFfZyBW& zSoe$X_~kuX;aj5MsfrNr=36@uMjA@7ocStnyp}L$ftc4S(?-=`n@oh+)=Ou?huIl_ ztCjV;Gkf4xp2d~z2;S9EGpsbFDR3~Q>%*ZAzxak`HG=Zkf)!o2DV-@`p~J#RmXiB( z)l;0(sdp#0sMAq-l>cnLZsYR8LX+7ek2V4cfM|x;=O9N%cXGviH3dU&r4C*C)URHV zl-+_;lLA7PBrcvO*r8}hQQl3TXw}ARSuEupOi(e|bQbtEIv0+}zZZy*Q++RGHcNbq zRQImqGjeFg-5ms}6b&C$-;$G!=soMTvF)`%qVNj)`Rzv#sW~(Pn5i~Rq>HC5$^pCr zo;i%(x-Q!-XPtGCfgHO%9D(6HEKBAwkJ6c2N`1xpkq*UryP7whmktXf`j;8v68PTA zB|)u?W~0seQcw=qNSv%0hT{716fdXRWpnG=8JtXhw_?aX$`;x`=bV=_#HUa2FYa=3 zNCeRxT`l6p(A_^A)yWmn6ct17l&cza@)g>7y=L*(hEB*BNUpVHS;Cd_v!BRTTv+VIb=g6$tc&;|v2Kz$uVVCN>+jyg{qw~uNK)?6s+=Ji=m zoHplz^5WTPa)=>*pe9-M>V=T3E(A55Dz5WrEu^t?^rjUFrU0yZ*)K5m^$uo-7>7rT zo?ld_NO4o9HTq>=QgEH8bkf61u)gCYw_eL{Ga-KW$Y*09oym>?<>j9yPHH+l{ABl! z;$hu$8n$vI7&c3MN5^R0FmDsh;E1XU^;B=0_xxeTPDPUd)cz40DGQAbd4!`WPW%} zHmu8T<-SBCpjPWky(R@DP%*bbg;>yELU!HZ#KX@wcXKjY+a38J_MC+*vmZ4|X!wTT zGb(Fd4kcEnYSftNn;PoH*dYxmoyqoVxWp0vaP$Qo-?ucIN>jb&QT|&ka1;k6Y$=$d zuU+~OWl&}gg?SxxV}vvoN)m7|Fn9Fx>R#~`B@M_)xg;Ra&@vAfrqbl$jHt24aPAjl zZ0--=OT_=q0Rh_T$fG+CC(bqXEXz6#ViFPl^Lx=~63?tPPt(VWD%asr+T`uCOasgf`_1T+dr!M< zGg9wHU$wvbkE49$(m6g`$o~(KnIXF2JhGtdu72_JcA*j1xa8g#Qkgs}%Qm0r zVYi5?c072DZvBH5F6USkZZbMM`HdK{8B?U0uaJY_zIN(;gV+4{)z;?S7~OFX#1JKA zWvyl--f{I$dr!flnOd%d#$sO$Cw#gfVy^==#miR5Joivf*IE9ueUtXbLlkECo;H6W zlfS@;yo}6Pj0taSY%FDhq*3)qH5-(`qec_+m=~}Dn>1{vo~8~7Q6-KiVJ&r^4>5Nq7;I-O0oP1M!ZTH zbDiozqeGZ;rU#Th(PXu1GjAEU4A&c6Y0&d4p%#cTxq?eL&Oie=>{IF;93FHy2U;T# zde`6J6^Y+`on1BTQ`WN$CfpL+>`;8$Q-Yo8e|s1rXG&rAfBPSB>y@zY;G1Ph+;xYQ zNq1n2YijYvLH3)&V>67lxZu4-?k!HUrnK4vx2$#FVjCm`7U3S(5_X%q1KasNO6vVy zl%@JVulBkB0thbtV6_eUf+f%X{NLE4S*ZSJJ*rPH8@l?s)>w`h`Kb0+foSak+$>PP z=d_;%4f&@%Dw2P7Ht(sxzNbrR?rJDhqYO0FrX}JpdEH({qFK8KR_um;1-2$O?!{6P zlTaRbQqQVH5tHZDJ}|XD;FpuW_Yh2FyE-y#aNwShQF1{<9=4}jf5jk+_RfkXXhE$} zAIU$xGaG0r`xmU;ak#SlpRrhQuq2CX;{JWQ>=tFbGGZ238vuSK*{5gupn+HeW|S$n zWTEi{ELC7fo*#L7;HqRTU7CV(`xJIgpo1`Ndo0_W4bvD+@t5MX0Jf~SiGyjJnxEKh zBOb69d2Su%lPXSTwjLotM^&Hd<0og!NV;E8vQ9^#c8jOkVyeG@7c^j`4G9b?(d_vy z?N-ix=1f~OwwyYu`{Xij!1c(E-j}$37lk%a^Nk67v`MX;&V#aB!ALNvDP|Lib%vlB zZzmOgIl2iZ6DM53u*iHMaCW}&ndJO`hX~E0IE+~Ks$b;YhCsxiUd`Yi4y)Sd4ubv{ z;5omZFboK3-V-6mb^645AYVm`8B7B_i*KeHk|`Nf_4$}6VjVEk-Yy2Z+AD2H-mR;J{xod>)kOF>E?>swi9;)#UU**BV zm=GEkiG=vn9$Wa;RO8-3kl99SAnY(DGsOFb6GsEonX`(N({LzHrtY(QS9x-n zwqNSz?H#Gnm_WJ1jB;CWDL(zod{Q}#_ILz~`Qr7e8507f@??rDABD7INJvRvGYMfd z5_jK9l`)T`a5au*O4_8Rjv=)>I}0Rptj2GvzFO~#NzxdkPRW&6aCWA|T$sSbWQwQp zQ6aRq3mq>%?i+KHzKiXSm77;pr(usm+Ht`=f14uom3F8SYC>^YNh(Y6F`W?6ox-!t zo_NgU!_Z;9sjm<$#$?GS=^>Toe{I1=b_)xOpKq;AP1qo9I?<$|^&rI!@b2CVi`jRv#L zSG>I}oRL45itU2~V@jT9O_-(XW1RY5uW#`Hw+ZR5H=G*Aa827$cwoOgDMVNMYauvK zS8NLE1;j>&DMA5vEU1$I9hk3}T?OSKC~i_!78JP>=+>ays(qD&@dbz`gse74Rllk1 z9?3B|b_wF>EIYfP;y806dms?h)cIX+i$KupGzhyrSmcx({r=Z^P4-m(H#R8~tT)jqLN{0JFgRjk12PnW<)xG5rj7~RrT*p!>4c!5pgr$vGc$n$GcSx1q)MN*0-9O@ zRPFTa+EcQ}+gVp|*poVa!M5Jx?xnr-S_=P%Or@Bmj9B`FL;mW36q5U89Kp*y8OI~diOE*r&C0Oq-`E&LcG7mi7P2_Tn*^!qHQ{h9T4 zh*Ne2^4XY!i-3m_+sPA3WZ!uv5KMhzZJ$M->s&XuCv1Be_LW7YxWzx&=yvo2gow9LJevbAZFvvmv9?j@`d-?oFXsSe)XcauJlK_}LfC z0BM2j28@+V(< z`D0nM&uHjk)eMm$HH=5>%7ZyQ%Iv{we{$^(gybd$D_5FZTEsHwpu3w|$^cXVAH?vP zg!uLw#sM6n?UjX^-9mS-tA71sk+b+pZV@#~98NPcYakKKup@@(G)xnRs=?W%21Z4s zQoC_!J3Roo=XZoPSutN)|4doT_V#5w99qCI|7$93?;Y(|@CIkI)Xh^jZYNKo@2r$h zM2esNaBVl5+iaS#AMsNRz8{F#EZ>*sb?+9o%=p{3F0@&5p?h|RYF=X1s1#qNFXiXY zNNnu4w4K**NjY#;t>9Lz^uT205=k?>H(((KI}75^SU78-h4Pu~jIcfUlB@QJ!NvqI z2SNJRR3wPD;2+q%(D%hAg6zLJquQ!$r>m8j)rtpB2o)J_a!UeVgred-!XI4j;{sjnMR zHRqLcq^qqIdz~SdV$Hna=(K4RCSrH4j z|K)cC*uSxJ290?6;ojE z3#W_;&3v(&md+?xc?FfDIN1s$LmqHNvQWIHyvh^%)2umer%ttvv0}X_ejSiOXoW)a z3R{(J-w@X_T(~Q0;JSEp*eGAZiebTmSKH{8!yOsW!6m`tRCy)6`u*46l|{+_FHvUm zLNO#Yb#)HFWut@)n}I#!cNo%l-u$}M$Ak3dnJj{IwO{hRkQA3;yyXYSB8PKz1mjJ~ zJFhnLkZ56TV$}?n~p^D2I70nC&7_@=~DC%q>Q=^19%&7i*9<51$&IY)@P zV=mP1u3Xtjwq|Ax{1|0Y{nQG~H{AGzbb^Ob}NrfHn9m@uG$vtp# z{LHpVpfMN8u*RTbNJ&d7g^8zJ(|o5^1GtD&;-O(;CP~SV{ZUtf2H4T*RC!Io_X7e? zeY`24My$*tZc?&Jv6I)2g)xq7?;XyyY7^4Fk825ppnNw)HiW*&S~jN3Co!So%)lY# zkxwxPUlKV1O-(;Ktdu&j*2@!3sEvu41m=r#0Zc3qmhlq)zO}rc`Y-!z# zZ2d(9VGy;6m#5xW!|)xH8r667*fRI+C3l`_=h^a*ux4;UQu|5%{=zF`O-yb(Dzh)w zeW;BEzncL|sDy?AY2$UmeBf6onOUuiDC$(YoRld}Tm`UHSL){I53^@_0Ltl{LpM`R z47kE8QfSyI7X_V0nB?~{Z6V0FeFtJCvc=IJ zqjK`>qP{SSY5w1z#6yE{4WVS_P%Wf|s6ZQ!?xPN#K@Awy<5NPEbO$|c+lN|$C4rjr zUqq1(MFJ2rWYqH>A{_Qb%PlF}WSDgS!E< zSfS!qnFnOMgx5`OtRFbX|2SWXvOJ<}2RI#hn9g-&8ybRA4+#5NEjlnPY8zgE1eG{| zDQ^wB#s4a7IbyKgo@uzbLfcbd*dqcsuK!FFw3@2}uamIS$wZ@coM-iVYO}k11eAs`0Kl5(uvF=UL%~v{1up4z$<{5m zZtGvne<$cIRRxN0@MIo?v(uixuUmWVH6=5j zNT}8QAWaCcF{QN@Ni)Yi@iWZPA0VGyI!U>Ev1`@@Rw8ioig?k(JFa&ueU=CKJP`w< zLfF$Rq28b-vt@PVrWx@WSKV-~OP0OOPEC{$#Fm5n9i1&3dDM4$enfFu=L zD((rwbHG*Yt;@}*V}?d0w`7XNxzg-k!`zMjONZ!I9W5{isuY;ve>t|+`2eAe_}bO! z_16;~6s0h-l0tN#hauu}J*pY>C{#%_RM1%keu6iBGWml=qvUF|P`i{x^rVeBcG-p- zlgxt7ZDVduQX!McW_5op@$Q8bRBgsq*aEbV){sq{YJ%KbXgC@qLjpvF`WwZ(qQiHZBF92 zIvv4eA^4ZlK*uxnKMUA@(gzb}{ChwCZS6k)xqe)p{JPXVD)Lhb|K}I2bp-sl&nv^DohNOE~<>$L&jc zzI-v~Q5{v*TXUd+@EtFpb)cnE58ct2U)d&FOosG}=Y}e{*^bs>V$MdPX7vF|H=2D1 zBH5a;Lh;YjKW}AFfyaZJBKCo`@Zmgh>M+d_hup81=~+05;qmSaS3*KQ7mB$tbLo+G z>^-+cXAKx>9r17cy?C|MH0N-*XKJ8Rul{o(GI^?{?C;Df zB!YFd|C;i~A4TmAP6fyK-NUjf1usatPT@UC=Dp!9rzTXp9wS3XO3#$GJ}_EQ-s(vE zLi~ywj)|!=J$&vsH<1U8sEXd6SgiSML}#eGxN<+1xjC)|kP*1$yedvmCd%7gtUY z%m4a0jj8q_PC$iZWms^xQ1%fF5##vQV_ThX#?rBV1~QxfwI$fohdWIz5;xeKe!}_{ zN~CA^<>xBgUSKu30=#HofMT%R9XZ^8m7gXK7X*5&0Q2P(N(BN_tqHkF^-SL>^nqda zsnzM`OCvB-jrRC7xuzb(_hTn!W^dOEdq;y`1vzinb*yrr?C>~*2U5QZ3b{@#T6}pw z5B{!#iHv3Vg;H8zAa;O?{@YU=e+JoN1|+eQgV#{aRf^Q5^o5j8F$~ZW3C`oqQUlLl z&*J4PMr-dK^l!ZfYFk(-r=JtRr!6tc+SOs1^ZpIfVGR<6 z5uOt0gBT;5ZNK^^Q=UEQ1(Kq*#=ybU@hnFe|Wavh{; z#h_Q00M_T$0967e;f~Ktaa!UAmSWcd%*nEc=cJkBN2=E^c`b1uIb7VIX5UIAm7mjV zCUi_Q+FT!WJj?5b8cjL-WohaV#@K&|74v`j4E+gAK-i|VJT};wE6HXn(QQ+sd>Gc| z+f{xfn<47~qsnPg5!wN}3Z+(z#;a3yEP|$<hXG7@;)W$^m>f6xBD0dkw~p;-2NiMy^)2i+?6c3en8Psib0!fuxz7w!Gv| zr|c7=Nn(tZq^5xI{f)665h9N0SBi9eiI6R1(`BsRR_~$ez1DGpCp^wyE%1!D;$Y zoB7lQ?3?NH_SAxdp)(zDIZ1G!eGPRH~&=a#g4?m zAkFxxZ%i|^gdKZjKKS<{3+cE==<1S+g^M!$&$Z%f2?=-5lV2y7ITUnLo-+O5-$^1f zL>x+!GD+?auSv(rOj>I(|H37=XNj6GC$DzfpJzD+f9vn6H1o+xtux%*l zZXr%ew8pB2?UE+|H{D*cnsPBltd6=q$UN2vY8JH2uD7ebTasY@e=k_Js5ENOa)-i< z%qi5AhczS^of?U&$vo}Gj!^&)@0_HDF0lRc-L-&$NpB;36y47^uad_#}?o!RF z6ZKLA7oKa0RGi6-*S?mow{$kIKO6b+8wV zetu1}#1YEatf5ZK+7qG%*3P#zl;_T-v#*GY+D?Y9KcB!{H)e>XXsdQs*M}e`d|6<3 zgyjCmYze8kC5QH$FrQ8QFgPVRMP;qFV3{P8kM86R3<$lq4+4PtRDU~vMFBm1aHTx` z<|I@Kr?sFX2X7X+CW&WLwPm3|5o#e!zHALK(foEcNENUaC-vo#5GWN60OOZwA3JUUY=lt=n@CSvIq^7g|5kpnR_?; z2-_PrxY+%HMz4Sf12PIi<9>_#SC`_9u&&BscD!`DifHDI*f~6~hd^PaOe8EM#eLXY zfP{|`ez77TR7STme}E8+oiGm~7~>G)wJx1fGZGxt5Tk;ON`eQ>ow>Lc=k;D7FLHuM zaG{#g;{o3{0hKD6!DNdtIoml8@8iv#h-?a)QkxzBjC}?$6mPs;fQ->A(_;ClW(w2^ z%LuzCqG*Yk#Y;Le%EKw5j9%RQDS1ckM&btjHXbA) zXL|*Ubr7nk>Dzx3O<&|yvS|&&nT>z+I}jG+>0|iE?L8*rVqnyLMNO*v$wl#lUI{fY zLCrjy__F2lR;Lh=I0_2Zw1HPxD15XSa4>{z3C*Kwlh88GGJyYY9>YcS}lciEQBlUkMZhy_?b469FTP1{AN`N=Z)u$ z^g%JvrH!`Yr7TxtsQ4M0Ts=pjIRLWHK4 zGkpxXS_P&JTXp2o?O29Yjwpei+DJ_YCJ8ZC`SaQ>LXCieCqrkJ3cL5SR%j9czL*pD zDq>cZ_q)_dmIY``b@xE}qsQ4|!#h-Y?5PB1->}HMf8|JMhd$dtLy~TKj8idc)WC2` z^st2bEf&>4R@YW2X*7;+C8n|gfujuLA-tCBVPE9jFV+3qmG%PK2%=x3QI%`-l$$S!b-+)ku8GIsFfag-pMk`Ek zW?nhxl?wB79lhD$=tQsOTTDGoXjS8Axkv6jL^&vxm%=Z?+v?_R7Z`#Td}-`nWLRIR zVRA&Sj0}>5ReSO(ldzL+;M^wPdj8alVZACW}lkRa}BNi&-6L zJL~hsZpRIcvKTTN1Mm*ByBs2rcsU}8x4l07vq!i4gPz1uraS3HL%Ue$5vcMMLl(q) zDU9tWcsL$U_zr&I66bHGeaWt!`tBaWv*KbuxXsThXZqaR73z{LC6JKHRE^J*yIt6_ z4)jp`hzJ9B>dQ|9K#hCglpacCMRsL_4~c8Yzh^s7`S>9gfb2xyz&slqPVSEyDH+sq zdOIyB`5%E!!*d!qJw;G4ZdE1fzGKuM$cL|$64e>e!PtXX%>FDn91zj$iz)-px&sNb z2TkGlsprO@j=aQ;erDHDZCi9!7RumiDi%8ste_hn&jr_pI4QF?FM%ESAg^&1(^c%m zk}aC4!2Z~tcc{%%pWGWi$@J28yH#L&D9p3jeZZD2g}*I8YRq`nE*Rk-hxew3%fh*n<@>!owNuc`-)v zRlT?U%YlKctATl=uwV3cFTLq!-$)mgutm&qmC2>FiE>x0PysQ)Dd}DRIMro3qDi}C z8*2u`QBea@@aL8y)D0Ec1?4mA)54l&jI*^7aS0e|3Q<$REK}lC+ddXtB(OOzrWa{xuh~A-sy;>;8Y?ILZcBb9$YNIpfC{eroITA!({o}Of^5BbcV;#cReXS z`rFSCx|KtMM1AqJn8JM;npqpit6<6RR0+Kq-{vI!qws1j~k|Ilz=Sw zaG&v7$Gg@KU!)s!9MKJXJ`wDOFA(j8ZSUV+-p@n4xVjqR3DU=$@oXx%E{ZQ|&K8Tx zjINI%Zl5eUo}M}JkhN!=4+*^juhcCJfIZXQG6|)xr#F848(yex{-VpXKh2iYSoDzu7cI)9ySsuuL+2Tp1?O7Y@TOv_58dZ;YALP_R-i1+PwKD)dRi;}OUY}%ec`PWL zOg8LFj*5-$qnN1kGRMOFVD^nVS{ntr!B=&O%rel9jB^s)0IoFnO9rXN1^ zJOjXXkiQaoR%AuyZ2Qi=M>X#7G)>*ESkLt4X13P6=pxTHRe0N7A#hp8a@*>nRML`u zFAct3jc^y~c7@%gsS#OTQkSbCwM*O$V6N|Nx5t>U5@nUuq62uq@&u}2#3yMg4Hd$oEvwyZd~`Eunk{n z#IIkfY^bi&*cFkCBsmh&HZSz}r zCA%!y32s%+M4LPr4ExUtH~`$*p608T+x70g`&mjZoP0IYOnP`u_Vr%$<~KUqvNah5 zX_1cLQx5XC6^t=1zEm6~j8&AkY7LWWEVX%$huqakng={`UHCfB%k_p&Gd9N$7hh6S z|2ddG2^dI|&xowQfgFr$uW>#%B%GdFrKYAz^2Qkx4|Bi};BR|7w%n1#QHcC13a)?zl=(ViKaKdYgQV zG^gBRcSyQ}#Y?Uq{9nJ$vPCY%PxD#J^7c?lvdKCV^3^7O$2c7eI(YIkpD|gXyNAKm zw)v9Gj&ktMYJ~8#|7Ky{37Yf58ZD87Zp^f4T!R?`iVj$Ya_za-1(%u8V|xVDKf5@< z(jWS!$?rmHaO{C)RP1l+`RBF)zeIwbfJF44hxqG{7G!ra@n7Wh-{09`LmP%|as_f* zGAW)jt(h^j+gBVp?#DA4&vBu>ANwX>@0?0$#g8S6Z4gn2d0QX9s^pT}zI(7*Z;YLv z;i@xmc!ai!vHdn4adEj==~jf;fLQaETlTlXK=r-jrkbv6((aDdJs4N^-O8G87aDJr zIy}c&p!(+-9`~EhO>TY>{VNs##%w3j)lP0oxSw<_0PQjL{yFcpJQsq@NyqU7f3)!c z(WVW;W0~(@C(w6b-m$F!ZI!Z??;RX5j)l`c{ylE_aZDNDQ!$A@w0^S4;Mq zC!*7^&{2^O37x8h)Q%`p`^u#83?%(Jw^(>4?2f~#@L`>g11HDv>Wk&|=?(Fb6FCDU zP5G-S-$-)61~ezQ$8yyMe0_5)u`z&;0Ovj{%Ekx_d4r#;Q4mG)J#KV1PtEs%l;;|J zm)1RXw4RJP3(r4i-~)oTva(QSDtpX3qSYNU9)WqQw0&Hnz9W=#;(V_rvSR@Md6BRY zCPMF@WxPRD(ZW!0GXncg@IHA1QCI$B6f5HsrJW@mcI{;YJr~TU&5<1hwDDmgA&dMg zlT0(13TPPza(5FZs-NE0EPnwcu}6JwsLmFHhx2yMcOTe>sDA`Yw;ZTmNgl^ zxy90QtS}S6S0m;BT z#dkkFL51EbED(zsoJ%2)7^)mK{dz9i%mc!S0;|H>%n-LySe@JH2 z!G$XUxd4=o@D>#~9$(et^9IRxm3S8G_143n2uvzzky}$ocw;hBW-$+9#}LlsL#PZ5Ye$)dVLu=NoLRxsxH&-E2QNP z3y;py97?;(?l_V6X}Z;^MqtFL%vkoey&hhfYs~$XIQ3Amc~tNKD2J*Xk?rfRYrQrv z-aTw_bDCo`Nxn6USD{|_iA_RUZZzZkI+P#HW|#>wk3_@4v#aD)ky53N;lcq*eDq~D z3I+37-f zsi72}xO`Gkq=ZC|?ujEub*s>lHnwOf45u8dIG?DbYfri=M`%Ldw zMWGEW$Z;0@d3V>&?%0tmGPgp#F4)-KL7XxXFMS%@8l|B!Y{*&pIR}Gqv#J_mYDG!y ze$j9ZCo}JlNYc_C;f5{Lf(O^wA8u5qPwtc1PDA$e0B%L>k4MQ{4eUq^>0e=>Y!w+D z*-yJ>g>SP#3mV}CO@Rbg+H`*(%$r=@&TNJ0(b5)S!UqQ#AiW!ap#2k3&Yhaaq9L4i z?(7?5dl7N$N(G-Z<9vh^6!qwWi>D6PiRt*juaK>+Akvecr1=LC$*KA%>Q; zWMPt05IYYNXL?)V%(|3xxC&Lwcz~hRcJD>vOhM|9b#y$+3JPaRbutVYWV$9{ZrvFF zb8eEj;ty@4Y6)F6$?Ecm=5lnmxP3r_5rU!B2nSOy?e2d>O=$x#)3e7o#*jE@9O&Am z;@8Nn z8r-NDP|Nn$-w}OvK?tqUA$F}#NYzG{=fUuxQFSb1Ok;@Vm3y_jAXys;jU3?+1KmkV zVl-I=O_h6&si>7*(dTqeX9iEN1y>-VQg^`%w(`Si+GUH7;~P$@Dcg>&tVNa;`_G6qBzdanoDN9SrcAEvtFjrDfy+d>!<3Gzucs)3^ zi>n#GD@O7Oay5Q7w_%5n(`ljI`Ee^nv-zyUZJmY zJRvkt%#E6v>U!h=t_{U*=!}>iIYLX?ZcT40+d?!M)K<;Pjtu^7v^U16&!rel4&)i% z^QpAYk9Xm-2muQ<`t4J&`2NFmG^FyP(^13r<5#oVt2&mgIL8p&Mm3@7bUww#XZlyg zBVRy%tC-=_ceym^blQQfOHiBmRO;uNLVGw)Kp`3m`@4!+--d|lp1hZO-ylhgrLYIi zaG*N@m`d}+aBtD@Hvp${LtNb}Jz53g+na&$rB*hESa@naRoAB$1|Z`+F6%x58KkfV z;HW-nI<$@4GmA^dGU5UjMsY_!1?{DibV zuzPz5F85O8`S`m6pKY@Se^)OKQmEeNQ|b*E&Mmg6=t<{-j-0mQAbSi?AT}fo*ZOO` z3n35*R<*42zt2v6F=afXxOr;GS{*81CyzQ`>W@O=%Q;tCaLnR`fh}peT!6 z9O+p{pySp)r(8IQOW*5p-v!A8`Gm8Pw_~LS7<`knP8}+)xv;P97viR<=;$&+@%2^@+w*O6{Vr6+h#5=29Pd7u-62pi*N*jY_gFwI|&Y zfYoME79i1F0L3$95+9#t%5`z?V?U}7IK#0m&KS#|3-msPLc)NWSQj3vL1}L)}ke-of{$6H=LZ1+~e_+pVq}(Wmu|e!X*|r zLYA$%O_v1e{r)4}@)b+U=xW+IoIzdEfH$A@c)HIU{7WO-kEIkPwlm6Q!gL#FlVH3{c+LWi|!du>;)-Ci}G%Mrp_O>n;*b6lL3&ndIlrs zdGG9e!lGrb6`}!_-fQj5-g(%9G6?qa?CUkBJ5)tp_U}Mm**85ryxo3iq=yY`Vzzm0 z)6WaX^raUMeJ(z`E@e!3^u9$XL1pf;J&V2lG4628X1lf8*|-DGV~L8d!q$*>6Kd`h z2Y}1)Y=_oCwO(zB=O!V|cG_~P-I10eS4<4WY{7*2`;dCXa1@H5!r9?@J*j1nI(rEb zHNJG4Sjcd*mDs`v%}#SwfNl81`Sf~%OH{DAjIwz~#_T~vhU0LvV9MJ?7wr^FiPE@^xCon5$K>dzXd5|)@5tK0r90IF~f#hiSnlf4oO02oIf21&oSsj-r(EB!d~yj@3ftj5&E8N z&`%mylpfoP&UVWP#i4T3JA5lRqZz1okUFnzbY3Kb*iHo0_!jCilib94iA0l!Vas$- zz4wl1?e=2Rn6I$ybT7aA(}6bXHN23?B0Y)J!W^DrBa;1G`^n`rbywO!hFm(uTwJ^8 zx7xj;`|&XR@jrxz4Q_#FRE+64>v4gwVDh>l(Cdjs9MIdjJ*$dP3+T&eAS04sY*>p8 z-3t9I+i?Y#{4biHjYv-`!6a%XY8jc|&S_wJJ83DmW`R(V3hkYjO z4;ioTLlO~aYpT6!Af)~K2gEE34i=3m$G6cPJVG!t=JQEpo!0M4ve-eMbknFI0E@ zi;vk2fHB2Im#Du}BFg78ywr;pmcl=P1*-8plPZrwj+BKcYBq~@Z~U@rzN5-~BgqY% zHHv_HJc4j+Z=*;+&XWfUDa<;yBkgt*=+LxtTyq!m&axihH71KwrO%$w9T{3!*a~S3 zC=>eF#EqCxK>Z~n+IRD+2S|GViGb(X0jBGW9cj1#(0t}~QrR*y$G;`Fx7zB>fxk|C zO<{Of(Ndww^e4^!kDi+VnxNY?qY`O7;a@B_ztQOblf)9MV|T*n7uxFlh9ci|D~0M~ zI*7NmZs%I1V&ivmy%njQ@l6|i|7XUsYsr54CFv*?p{!|1*E`YX6R3-GuJ%x-{i2lX zU%@%naCNrUMM+@&Z@KYkP~Lc(k$5D8#>iR;1cl2L6NKhbKV;_lVYqbP z7Eoj}f7%sC*BX(xf2j8B&4wcF<>@*ezbjm4x?$A~hj-M3Mn&sjO`UW6FP%3h!wRTe zX7hS%=@*-vtkiM09Lum$)2&vJYowu7Pqg&QJgsOpJuG1^F~Dg-W&JPn|e4t-@yb9-rC0A{PutmpJOSCos^bEj@ko5Dz+6K7`e zd3eZuU)@Giq33yU(Y3L~A>+bk;kBB0mw%T8Qvn}0=}`kdXR!?|B>($cl_frz3)W!s z2P!n$aPPBr6ZU%k5|Z=dZdKt4rdz7il7|6t_!8sLt>6FGI-n+Aa2Y%L2>Y$&Xvwo24EhX>avY zCy@n#X3j<9Ceu}>0JI~XQFOWr04GAQfOr3UE&NL^UC8Rg@Bj}8&I`Mtcb5IgM>l&X z_Ci+n%&J>Bkd8-{xBV+FHh#xQ7-B9Dy=!*dxaE8v6L)c8m6k@oc)pZQdf}aOXNtAk zFu7JT##vz-rF0pedClpK-W!wFvibZwN`%raETFANsk8RNVkYNHM<20FR*$U6!mks# z8#qP*Y%$+k=iTd2vy#rmCd8VLwb{>&fb$hh*2ll`65&h7#p>@hug?J|eu-lxIELhr zIUs_SY3I+E66MiB8D6tUe*TF8UY}@CH#h~u`4NN!+Zw}$f1X&0iI0*^AwVB6juHwt zOdG>sDiGfD{fDD&u8hE~{KJoV52un79agyE9@oeRM%Wn;;B&tE3`{Tmd6S}5)0QcNFCpJNA5LC3 zyGq$KU_n7de6CML8ZOqy&S^S#X`K^CoSEEQX3!d}HpV)V59ps;1|Q)P8h><$q9dG5 zfwTG5P&MD6Q;9cCIsAKLp{*9OoG7;SE*@cI%mgPGg-y%llbGwqaJ0lt^+-iup{d8I zf^{U(lPrwbK6l2+cWMoKH!Gc>rL^d{*K3x8&0N`TNdYS@ z!N{KXQ(V(U88^&)YRtGBxw>+$yZr~n&1tR<3=krGZK~Isg z*@~{cE^x<9+_T_Sa`Z3vn~43J=diR?0li;K-Wq+d zPnT~)9COG!=qL%u>u|;8+SlYh24?rwXg=8C#R;*~O-ml<9gw}|#MS4LPUAeVmnD9<-MLBhiJ z&PfkG3LC(jyFQLuf>^Ikq!>X%0{Ed{s8iwMCrvH8F?n5ReJV{^@!?1w2U@JW3(h3| ze9Erx|Lo}YP*+ZPAK0xMPsqTXPlTW`2s2@CatQ=flxcwPJ?Od0HYB?_z!te90n#qR z1qku~1-R9=KHrBolBP1BG2DUD7cFplq)hoXF>h6Dldar1b|`v`0Rf3BWC^D6IKkvm z;RS@m?7}_T!2BCbl5tth9a=2Yh5tp#`L~J%B4BmW+GXm)p!nzrS#ys-Aky11;*_$q zs5f$tiEd}sp-DVb6^89o!s`y($G4FsFVfL;uI&c&1ePTEcA3|H^T_9DRyE(^n9q*9 zAPVQq+b9QcXeB@T(LaJ^eQSg0%DSqn6PeedP{sc~cGOmjXOWYSde=q|zDGw+Lwzh} zegX*i<@H>$E(k@zBce^mhCTC8>Tc>-L7i{6zA@r{F!1=DFjXCbzw6PZD|yp@*TfBC zfrS6cl-jO&D3dAe@Dp!Hw<~O63CBw1?1M)QSZe2D9T6@rao5O4XvA+_BVo;`MHc5DSFi|VK>JPw|Wm@%5e+^y; zF~&RiQlut0$mQqYZ2S&;L(QGDC!*lf>}iT!$2Dbvbp|`Ena^WICsc1QDAKTRID$%7 zs*<`eb^<4CKl#FmA<$VI7JaPIPs0psR7i#(oYmyjKT2gR^&^Xa1+*nKZ2lTwjqc5FSzJg{1+Fx;{~XL^Vx^*C`((%A-SU z1fHm;(w_h11fRWsI_-|BcZEMG4#l=NmA|;1^);5__3yi{yUFqOS`Zc*vYNBs4N2CjBA?Bmb=35AM;6)El8|)HPvm6p^2B=i<>Cwz*Ht$#CpwGzYdO9ZCQcIj#puejlDI$#0bZPUs(zxTpZruwbhgfp1 zsobnuIj+WC#&gMxyKFH{XLA*XB0Y9-BmE8@IjMbl#LszV7+f?;tdglC z;Ea_Ul#h}|K?6{6u!L|gM)XRdh7SI*?4MWSONWjuU5f5h45(y=E6)gMts%YYba7lO z5@VI&Iq7Zlen0IwoLf)D+$~cX5A<6$7JoO-#I1+@Utn^7aLcBBKX&@#FDs6i95U}ZPDp2cQKJ$MH{k)8@oXaL~%S82XP8R zx0nf?)u@T4_^=4(TlEm@mV^BCzM$ZlE8n^_-`T~flm&YGt)2`|Z!ih|sE%Fz-5<_M zo$8XEMnW=Vvsr(Av-&+0oYflf4CzHTdh&kJ5HM(xV8uzX%7t%&^R#aWYms+WneyYq z#e7DSMY;XfYh8|2%9FeCsci;46BTKaXFqZ4MBP!|B8{oz0ly61;jMUam%v53ixAed zsoY#TvT!G83}o9wTC+4J6k{~h@3)IT7r!NA077zxm=libuk|$-IZ?zR1?gpoYW5dq zJ8bj$#>FzAzbH*US_spd4zHnW;hS^EUNekq@>}g$yvv)5KI|l?lz^LxxyC&U5W8=W zLL71r`$<>TLIIejNI<3c`dhmN`;fu6^*JexnW9g`$kq!(z3Qz*AIjo}x zFNn7>jMSuL!u+Ev0QN;dsUvo^g{jI#%4AFPwargy0I^ye;k`6;mktdMs_NL5rKlrnz zNV&%Zn1Oo|_HKRN4`-j03G)-E_)(Md5xTtM3Q)<4;Qi>V6MRmRfB0foV+wYPp9-P* zH7w~3hiGS;O2m0e{r`?d|19NX$$g+ ztkKZ+Mnn+@(v9zP@;=!?uH54kQs@<27T=_PBoOxZ zi&AM$bm8L9>|TS?9^WhL;b%(se`l=o_-0DXB^ZOnCOvoe6)ZA3Kpnh^Z@o9`IcJ@3 zP2S(qfr0c+Yyd1(%MnXPk|#OyJokpaA$9-~4;#-FXg!XGEL9Yro_A>Z8RoM}o&+fe zAtQ1O6So(peDwPQ8)`Bqiq|3NFh*n0e(&WgOw2 zW#@*IRn2`U!+KGEl6u?&zRl&#Rr&Is8b|LzPx^Rni`_P_=ZaSQX7A0)&9VuN{6p)Y z>rEn+^lx52voKa~v+APBU1elN!IVS!^j4w)rN7JvJ51qk@Y`aBj?xZ;|GJbx*e01s zcr7_=NwaqjUwn(Tse`@ffW^&(GlH6`Tr#HUMCmSBF%$M2Vedw>8kZD-Wr^=PY~IV8 z9}0O=+1prZVJ8>P$X`D4e*8bY$z50fla$xWC52$LJ@!1@1BL+G4*?R$zbvrCm`yj$ zOS{3`PC9dJ*Of%XA??6t&5UqC`&g{9LNU~1B+Ow$3bjhW)JbVA;ap{)@fCsA-o?w_ zkt*0>G&|(W6FKwHQX_H&MtcoR_i_AYCM}gersiY9_Loaao9FnD_1`1SX%2}_xVU8P zB@x}*I;HDG?I(wvhnAiZX>5%<(y4tx!hqNua8V`q+mbpPFA2BfZQ@C6VcV_c|6+$m z1KOckOXwCvjeC=+^}2rzeBaro4>bFnNShJul3_k%G|YIVP=}P?d@_Yfot74*14och zUWzeg!&d2Cb@gjYexI*3PMMQU8sFCF%`$sB8a|NPFy)Fl9fH+CAwM4vmk1kBQ0Fyz zRs2-&1T6y7=c5j#o*xa_PWx#qp}n$;7rBOxp1g-a> zA}mRz->wtfRX%b!+}vQG=Wq z7W9X%r#riGsZt%jtY@}o{mAloaPK<*U~aqPACb(nU-kepK0V0B;w(+uCnpZuwu@s| zXL~(l-_Cw+j#fgC=a7zT4fieq@;|5(Wxsy>D}u zg6^UHCRm7i{r%G8<5<1dE9v2{gUgY-5jDAYimJJ0dkSc2P1PEU33_X~W4D~IOnk^y zcY@26y_-I%9HYP`rU9n#SfIjpXpUAxC-h^$urZJ#kX_)bpZHR*ele59ZdqKxDy+c_ ze!kwBA(*J=C@H&j6g}SO?7oAAd}#wS3nabIX9_HJ?IR_|UzkNCpK+T%`kaCC$Z#(L ztTC7Dh5o1dy7y8v5DF@<)8RXxKEuvjw@crcBqsc%gkOgY3ekLlJ;=br*1Hbf&t4+} zGZf{MU6@MD=|&~N{t+`ngWn;RA52ZaisfP8NtC-ELlT@!HoGbiW z4ct!>*l*eIIr@UhYE6q`&#*#N~=x_nqld`=$mGOD^r{luYaq{ z3Zn8H)iPi>5nzf_4dd6*E(0cWQS@HzeawDU2&OY7$cIfG19c=t@FGYtro-=3drU=x zK?53i&Si2Gu2>Eipu8VrotH-~zFRZSfT_hCeI*^cmG$+se79d{38|(85Z}eA`T1y> zx9V|!Z)Hn}*ngAL84@$d3d8s>Nh&$evSQcA`nnhuc+H#TcR~WR{w!C-L%lCqJ1a+09)1ivv+}#< zy>pw!N?lgl#IgP3ee}J;9i21LbSx=@XcXy2j{Uzm{$o4uauxsMI=3!~4r((%a_SPd z%*Ma;gls1SK_T}+SG}P?$$Ub^~4nYBll7Ub)Bp($W*i{EN z(z1)1Fd5+WV0=PfRJ%>M*sHYSvG{#*7qAeqfIaKk*TpF^;hl)tpObSu<-Y1^i>F@$ zjLHtQ`%Yv(LL@&w!WIXX5p28JH3W>Wd)c)2h{19qg_{rpG9qWu36ag%r5YPj7)*#5 z;z8fmX2NW#im5cD6b-&olvZS{W8hJ}2OHwEASGj42qxnI{PcbDg>&;JK5G=LsvkQ0*-$phU`_WVs&E_8Q)qBw_cdt0l$N81p#0&Pw8Nxnyj zo!Z%6iv;;AZoZV=!cKj#f%U52s@ftui}kxdIslo<>>3)7?N~UP?Dph=Z6v-Xk)5c? zbK#=!vOMYRH|G!qOH`?^Ws|f})^m&ZI88w~fwycnIa`BR{d7-EOO)V^cMr44n)!*) z=c7{#m!EV2uQ|?Jb!wQpT2i0tGaRkDTSNtAhE87XvO;(ZkOF{#pbeo^N=BgYVPO+pqQ^d13gk_7pgLH&dD<8xz zIDf*2AeC&6ngW<=+*lj<&Y}roV$KCm%r(`9cXfGjR>z9RxY)0_+cOnuCK7IX@h>y1 zg*jF@*|%NJc6w#NI379$x&%_yI$>OUJefn|7k&-1SGSK3D`H+uq-u^=L^ojvnp2^&K0ed zUurBhotpDH`D^I@&Qqpx)2IUd$M9EG!&0F7FhF;c;R8-JZ)*@--c?p-!1G8thp+2) z6EP6TTnqK2L^751+fLa(sj<-9^4>ol{_bM6YApY$PtjPH>G42t-ZFQN28_!M?JlU1MY|5r-Gg7 zbXPJ!ZD0URCb3Gto5)vBsw$v(CfZd9_$_iDELrbc**y!wBRL|b@YO@90=Pj(AY>x7 zCC8C367toKs#zH6)jt2M#|cyJ7{-t))#GuK#f5H-`_}qbXOUj0SbZoRPxlXcVNEEe z+*#~cj*#8w9s@|6s;#f0I5Xa4el?~@z-O>KF1$<5-n=0t+Xi-SkjvMtPGBGl)Fgtb z{3J~}gHJ8A)EPl(dOOmI2zUx8yE-q3RsIFTH#Xf{EVJS9P2s1UB@u=)4Xclhef)MG{u&M z4GUSkL&7X~IE5kbI**aOX9a|VXcQYbB^y%*1(IGq@_a(qZhXm<&oldm8~CY#_x`K= z=;AYs9WdG?Q?NCjFysG6fci%p>Yz19``<*OPhI2)U4J*&|5*M5O0yH7ayWop9 zY_TjEDv?DAKG&|tm{S`haMJm+2K_gGu3mzh zaHu1_OJVQf1pY$4?Gs!QZxD`c8^}{#WH;TVHS*k(1+}GKLkY!6fh{j4TJAr zeD!|bdcHsT^p%XXRB+Y2*o4rSJB!t_#qx5clNUygG$b&+z)zmxi>vcYpRyF}?;#a} z>q>Imd1e-#duCxs}1gZLi+=V($)c@KwU}jAlk~qt-13*bru_7BJ|`e-%;Wl+filBhf6O zsHM+SmDM-s?w*rkEX-H%u*+VP9^-0_TMI4mxkE_FK4^7cXa(&-etYAKed}~$zR>t4 z9fj@$L;rRy-k<566y69QSzfV0&QVb54H}5@SS4DS+ipe0A}YEF{I!JHT-oYUFDJ4y zPGx7pbbpYJ^&lLe$Sg14jPDA{w{tT3A{wQGt<$ghnhPa6@hd0vUNAH-_x>i8F15NN z&~4UH<#wV6mxWDJvZ)#Ru=-VFK;sJmp*NiCxQe6xKo7eS^3cdf#Hg1h{UHLL^}2`@ zhs^ky#y3eAGsf$%7WIeKcw8ZqQKILa3a#+$V4V{TM;>S2j%Z}aPGUwMw4o8`A?j-T z*UgG1$xyt&@!&PyU;M+;{)DNgN+rCDmr)$8Y!Tz4=&$HQPy^L(=M*gkkb_z^S-btH zvzgem{6+*mOE(xvtsHO9oLanKu2QWhA%k8tkIU^s>9x5-1%gu*FY5+7T=g{mszqGMl$-G+vGr-tnG`Pb8`DnnyDcUg9e! zk8gFIPOXk@`pg5ZOJS-*mq%pJqTcmu{kpgWXO|m$^23OzbSD10RpaEU0l|7>ly8S7 zbjjqt6+tZldQ?@GN_v7l1^mzT#cmS6lvH9G573E28I7j|`o;0I$f#kLpUYMR(ya*BbGow`kbUdHFX|?ZKI2Yt0Gq^S2g{sv zdAsmAdp6EsE=#hSP^g#Hn$uk6Ofcn63Ah5=WF{@iOKA)zl1K(Rt4wmyL^V{z%q)VE zNA^z85xZ+}QX1_dYqC35C;BW53DW7jR*f_yLa$N($+2N?>_&MKR>AF9g-0P1uyMMp16X`0H+|#f!Z^6TUEbR* zIEsrcty=7{On;Ey!+M8HyKE;@>%8_XIO^JQl524$s`A2votJ7#7G0<`sT7aVs4Tvf zrK^1+;!?B@oxYoTvTLz(c0b0nohC{?6>@R!y2C>+OOEH{NpEpP6_VQM?cA-muUX@_ z3II*23TV+5X4mF_{X|+c>$r8dHb@J?m5J&i64WoWohLwQf+6>eQ-{CCNI8W+L~M5pZ_ z+}v7g@Nr07PEpbg+bPpYN1xDM{4jN}>8vlq-I6VN61nrXQHu3gj*_JR?UW|c@1?g^ zjgMEf-`kPCVWnDWVTzQ|{!ci5oTu+MTt|Ysf?k%b2iVJedks>1rBQ};R=Kn$3BM{e z8Qq5^71w5-U#iYZ&b6ePAJYuY+($MZE_7c|#Bpu<{+%K377R|4quHHmIsmso*QK4Z zIM&IK#?t;|jtQu%M)u1-(p-52JNP>D5}X)Ao4tw70Us#AuV@o25I1soyC zVO?{tz+sNj=#7_fyznb`@RQ(Y_u-_p8^R^4Y`>AF?+U|g9V))&cZZ$7Z!jvKtpQ&|j z%?!A62K$?gDB_Gy9z|2Z)*jdxlqIWWP!+mh3P|yGZh^tzXoS?f&ttlHrCND7@R>*; zx#tmuN2e9{!|uA5n%G;P^O}o_-F$(;XUR59@kdO~LeJ0+?8?RYFJ~M&7-@TT2D9*p zi?$?3*Ob(&9?a2r>}m}frGl&GkhBQ%~k=?Mf6a5GLHH#&mYhGGxm^d`J!?fEWo8?gH+9-186OQRLVV37T z=8u*6%iz~{ z?VV2@H+Pf3KhGwBD25O_YPX<_q@Yo!WjT{vF+rs3xl-P$(?9jx&f zOL>e7LW#;k$5};QB{6VpdJEvR%8^!kNtl%D+Pebg_lz{Gg}WJdT@IS47zEp4(foQn z*Hu*5BG`PGuaULiOJ7lcJe=KHM4Bb`a3>%x>&xY))cG}i255_d84m~?D7#kmljCkj zB)iU>E#ziqpwzj_Xt-A8urQAubVADBm{(_howwS5Kjm)0Dyz{bpJj1fYnw^>dqx8> zYyqhVSS)WgvJW>b-lLk3d8B(_^g6 z9Bn{6uKI=-)rB~_9{p9MA2Qcas|d<@|rmNB{0QSH>T@Mhq~iduxK zgeX|fTz)SwFDWGlllz)ldsL4)v%CdYSJ)juNrX@HS;QvEqYerJ#qElVS_}Hwn{tL5 zSfMr0EWy?8X0I7xPK53KDK=$-y&^b*?DTe9fVTyIiLJ>**BNTvyo}*7dh1lt5VvN= z@hW=}4d={dTHXcLR)TjrXPSjwLV##NW)+uKEJeJ0UO>>@I%oWsAlUJ!$tyGJc)Yb! z3rJ%yjIj%`BQ0VV74yUU4^OstfP3(Vu+<3bPk7CcB+)oVn9?^4^a+kG+u|p)r!Usy z^w&X04|b1xB0q=WYcI}taO#*5Ez^4PvS|%uOmKQCxvV}CdGM8|cEPojy_5_@ZKbff zwhQt2qj-k~KjXTk|72IkMq#z4b%bNRZ+qg9*14R=%V`?szaNDnAYnQQ1zgSGk8g5i zX+)oSrt{!?^$*?P20qI%3`s#atBuFZ^W09VHy|&;ZT77kV`ShugD+Ix09~UQ+!Ck~ zIi`L#w=Fz5N)I2uS$|9~AA@UYaUSp|#eU{5Pyt_KFQ9!I&n?7;%VuGrz6S|vLwCO!#HS0+S`jjUFGQd;$*Qkg^w+)NH&~#%5t82#Z7oR(Ae| z`Dv2&V?B~ZPOCE;%gc@!t(!mQh?5&+L2KFe&UY!T;W{$>Ln`dtU=^C2+1x{yZGf{} zV{IqgSFHiFN*%usEhrr{NPt8MF_iQ$gozZ4b_wAp>^SJd6T58WhdqBHao;;mRC}{J zr0G09Mj|Jv(!65%In%+_Y`(s$Ko+yn;1p=7E&>5J_e2d`C$8trEE_VPY@ZZfd>uU7 z6d!y{JkI51Gm8@fTGF_bMMQR$XPo!9u)SSVnJ;zPG`W?^xgq))EeWqjdpz7NuTZRX zY&kAU)s{Dsr)Af9())DSZ>Md zY1^*-plsG?6QR27_MB(kKbFAi>PzfZ=cf~pxY;vkgP=#Esn&a{Ohb(|TzI7J)Wht- zClYvv_=z|1sWSPlC{4HV4Yz;s(F>ml@Ls))6n%vc6fLT#2y19y-zF9B{W)N;!umI1 zB{G%@ps?8Ses%j1vIEImuzy{ELXjB&&UBg7K4Iz-m*8-+S-iE_+GZ_IJZD9EA?jYT z2XS1kQhtzrgtg^&cPL_K+_shzf6Mq^M@FL^1mo8c1 z!2&TeKfXAs(gpDIk(lsHIVPPZLrVi&{W$@~E&dhpLwMWC&NK~UAu`?c%p5Lv$ z6xzi0h+VFagURlE{tm!RxN;d849(tF5^e%l;L(a3pyj%sueJ_O@ZNJ=Zu<5h$$xK`#rR1vwP{rh}fNOva>m`|ypnxqe1^(<@gJwY_iihmJ zd*QFND?mjGD*H01>9?zFexNuJ}Rq>HXK);P(t@YmDEaUF7 zq#JN|0MJ!!fKl>rl<97>Q5{?#Jp=4GGuc-pfHO8!OE9{rxF20`?T1oR#=yDRM`Ul@ zu~jTt;BxPD3`SE7u{dFk6=kJ3sD(NPtadz)QY|&+S;24!{I5 zG11a3Ka$u`q}wyt9a$)Pd*OLBamViWE>sATlzs`OoYlbXIG4lM70rCmEcvJf2N9My zT(oOJuoyw`wi|O{H~lT0;e@v?^0E_5T#TPvw2yX%{vR&@X&YP%a8qmC;eNEtfc#46 z!;ngaXP8%?=m>@mxYmB^pvv188>cs9Btbr~En4=-==7fd9a|&*cd@a-v3aG%cyzly zU3K<5-Y3MczoC+&gueqC$%!1%MhTyHLveUlP}#{KOl&A#9f; zPC;NMwyi;Mu)mPF82gh&yEX)+VSp|vW3tFUUFlY0kv2R%Nk8{GF!Qf}7bG-wQ z!y<=LhfLBvvWn&uh3#DF7pvC9pKzz#Zy;vPyYv+kE5;QXMI^huwG1f$5g%y~2< zjLsEq(=M+cC-4NLGljQ}aLHkN5B6Z~v~isp%feW(K;?{fnJVcN^)cMLZ#_XUZ5tuS z3U0r_yN=FsteS@B&3UlXqgJ+geD+TS;jG76lE+Tj&zCTqTCJm6wG*{Q_DF!*$;lTv z&rI+8jJkQZ3CfLUOK_?1f>=0?^Mh_epz4znXC#N?&{3;@Xu}QJ(`g`2+gl^!xIXd4 zJ2xq~N2K@?CiyXS20kMzuM@r&*WVyY%~H3VA?6-KV6H?C3%JaL1>mZTTyAs1+ih7P zA*0g>PnUk5#K2_p#+&9BHh0~O8Z%kVDQLpVn8P!;!Q(IU`Iskaw$<@9DU&~);a?p3CZ7px`7AHWnI`2szd zHQAR+ba8#(3Q19hD~f-gkG)Jt8vTM>{tOt~K1x238oCq`cLeP_=!t~^&R$Rl?Vc!lZmFm4)NS8+@ z9nN(lFTGyN%@ig)*mCfBVsjie3U%=T7puXzokg>Rx5a-J)%UA3#m=v{te^35))On< zw+k6Xu|p%Sv9$ihH5t$CkPuq({%>}0MI^pktr7rhPyC{m;fRfvV5Shbf{Jy?7KNfR z4^z8#1b%b9*H?jQWMaa&qhDtQMcnM=%l3Xuo^S;dzQGyBNO8PmmB$YywV!-o4j%CI zhx6D{&J(U0*pIG{XwlupUX_Ix3s?#&7r(WrNXKZ&n)a!1hH662*>-if@+tm!{ozYt z_cgnkz_l1$)+3JZ74_f%J^pD#xg-(K>#UyH_mNO=zmvIbpzjA8{eF@CwHbyx=e=U> zMsKF%d$(&6{BmdY)Z76GhdIU4#3M<1ioVOFaie1?U6%oHUEg_Dd%aA(d6^E~?5>{W z7TdGU^P$h!U)!EymZK5%N*+~e@ABQ?tT-BFtdm;ZdvGT|)k@<7r$xOpwW+ir9lKuj zrtvIJ>8HJXmgUyx?+(<`98OP{3~0u!e?9uA9^?$!YR!=UEY5zBYO(eyp9(*Fm4B`V z;u+6TiE`fvbERXSsuFGia?4aen=BJh4AXPl>h&l*PDimj-VG`Dd~DA5jASZW$5R!! z-`+`Tu!U9h>VS%6)NC2tNMnZFQ^V#|N z^=gO4e>(e20owp6s`p-j2}WWSR~=-1f}Ce-jIkL)>betT0w`{AYedXXdFA7U>yxOD zz-4T_BIU0e3DbX1DHndV3kY@vEJQ5{YzrK88b|gqA#(mfp8lIy7(M@#cVPPwM%f?r z>v4L*hrps{D(gbX9)Fja5Ge$qN61cy`mids``M2%SCA@nqT~lXR_89n_9Mn%N~LQo zFpXT6#(0m7J(kevT{Fau^lv#vM`q;GKYB&fx0sHcSgz!ft^)yH`QFryTTd4GnFT$K zJTfG}d2Qcpq#bAU=5wx?me~F^9Qoy@EnTtCg=crov&wdE&2id3mA7=zxNj@MgwS7+ zrV;u7SD^n{Femek^MRY)vAhpqRmRAM*mX`p$&e;=6FP|JUkFNN*MpuD#kfA^?XH-L z;Ry--p~|d`yOS_oI|!n{>A1fihvEwf>>{jFzP(6RxY%k_ml#kZ@bbn-ul&sO;nis{ zYrHm}x#%5zLNI4G^>u8W|M}D^FOiXUMP~ezi@(t~sBdP$apIc84e$|=AZlBGXAUc+ zRv%c`>oAV;mZric1pHa1OVq2OAAt#?XKY%8%HveK)NNFkF|z&EbbGJws^->rA$06N zq-c%$1yX;qH88f!Roqf9w`FF40cx)D)62ZW#UHNZvO;??3+AVH$yL20sgI+!?kfU2`A+YzemoN zd!5gAKlp9`iU~eC7XOKi=S(RHXh5^IHht0TQ__+!IPYA?d@Vuz(!Imu`h6baKrP~% z&@|MxLgBmW60_cMjBJh!q7$!f=rsa#*tV!LLB z`y#+9+jm77zGj*66Bn;~lG-pPPfyg!7DT7&n|z^*#1 zUvJhF_=8zZ!BWAS&Aje_kvCG(Uhb~{$L~X(QK@(|o{+8*vR|!P^F4G5ikMgw?P=Uq z-M3mLwB1{FQ$|v%15N(g#y@1hrek!Z0C} zB*>z*V-z<)(neVdCMHDVf3K(wKY4eRM-By#s_o_;&*}N*2zEL__J^<4QAzibhJugjfO6=!@abyd4NFDbMr=AgJ4xcvyAHjjk=(BggXI`@8 z;fTj;Lzwna;=3W1LtrLMlQO>#Mw{X3`)#cmYVfQT+ti15Qvtia0Q*5b2=g8yso?EjD1JA7F8K z{f_hKJAG`~2sujpcE!?bMlwsoRl3-a{*IGj$LagB2nHPHP|uk@j|6z;M#iFXN-p0~ zN_}Ikf$TZN{~W;KL+0@GbvGbM3~KVU#rgE_5kH`60;qJsiV%L)`SwzJ4?57%<1KlR z;1dcFH9Zz=s5{MRat+nto`;cb(Qh@b7e6a(mwVcTy8kuPC!Q3K0*ufzfGE3KfcqA~f3NEGROUup%PC}~s} z--^(&6HLS8lNyiq1-Gzt8J2k$_GNlm&)8PS$YU^!L1$s-SoH-wE|;&N^fW$;iHzI{b@kD=3{?YGqGnccJSC>QK# z37n$Q8~(-d$g4HLM~Pc9hMm%4g_^9h5pb%SOQ#m>bgxdiUN>1rPe_8~6XX{QaR>?aOMnK zBAq>mv0F#xp1ou_1udLy)4)<=GQKwk?>>4xGXW$n^$v7?KbteX$`eK2X|_K7ruK$? z+YL1BXUa0eFKdJ(9IP1sC+K+h+kt9;*Qh%VZKDjx0A9VC2Wz%nA1$wZqBDQy9e1l5 zlICuv3w1q~f>S>q5uT^#6%9GW^4MPN*r}sN<%@A$D|d<-+SOGy_Q*Uc<2yx;FmF|Q zg~Fpx+JA>>c;B*<7NM1odTE~A{Nzg$%_#YySE`Q}qK19nQ`q!2xzdsyVG4K11lu#1 zFHjnUw*fK)%+=-dVS{PCSv5Mpu$!;`_9kMy#$3>m(WK&M-6<}$`(c$o1KvcVMP5sk>KKMGd69X}-^r!| zkP-y(0_JgW#Ha;Cn$~X=ZwspzTUqtdi$~3mvQ{wBx12}hTp?^Eowm1JjP|HZtnYw_ z_v4rXGPM$SQ?j+5;RG44kZ54=~K3onxV)N0LlPa$96TFK(D=*RVCv5RA`Jrxyq3%*xS6V|F@UKUXpU#_* zTh~}d@0Lc}RfYR1&oZ1oRVJKr>XBKSz;hZ5rrZ$uJj;RZFS=NXuJ4_>0vt}2zye>J zOO$>kv{q|~@O7Cw-4nEpZ@Aq1Vd0SEjv|ts!!KAH07P@;iwkt9Au@hj6 zeY}W4++ucWmRC^`80T#Q-@n3{CJaKNq;Wa?c2e@#qJ3)y=1XNj>|sQfyHM4*63n;D zBkqBsft;XvLBOG;28B1UDgR8hcQw5eD7NRvBa~=Cc)1C)w!)^z1CkAyc&w*1!ym~3 z^|0iy>Q{U$>G5OKC}SHzhR+W&yNvJh@Zuh!bS|GbC4Qaefy;M|k=Ggt8vK?;&P8j> zin5;b5YMh{B@6%+^|`6dNks*rnLhh4kfmglv~6B5_8VfT2-R1bXCfwnBueF5=AUvp zQx`hizap|0{aHMll+*(ursE41V)bI1uZpyD{hA6FR~V2B@NvsE4Z^b*yOo$Jn$j-kf}cFjc{sdbjm}^e=pH z1M7R%l7yuuOzwQcf;4P$ru7CqeAiE_`I?Dx{VQ;k;(*U0G)WrTx|~1$gGRsqL8EkO z|1BCd@+bd;Mu8Jcg9H-IvYyN8zgrId0 zN?i>EeYwXjTli`R2rFs86%{yQen%c>A9_3O6XddI*em-hN5+0y18G&dcO#^6#ousY zqO`L+dv5CtB3LD_b7M}msEfnJ@p%G-^45E-eclJ~P!0sUjMrPm?8^3gpZdTW$Iq;J zemCde45oF)7FqW-^$h3t|6z(CbO@mWT$^TuhryMAKwe6_3Hl9v0wVLU>>o=4<2d@@0D`N z%e%{VBCc1RJ&P@T&6LzkM`KO2Y@bzD7r=B?RMildwJhmagyXV<0*N7gHsj;;l?7Z? zv{lTUJ+t%d6cmp(#%2xgUJv69JLPt}0a!DKw4KZ+@*1W)%q9 zm=Bh$+H9}hqbmMfx!Xb-QOw#wiBvz7LJ=Bi0xCM>H&q(KSO=J`Wb9H}u2Epa`@QOV z)FJLr4#mRv8(hZWpj%tB1!(k4Wme{yWCj_q!)tNozPn6k)#RC^CIn#f7HFcKn_n;a z5z&IoBODl=*|<&(&So~yb4u7Sln08xJVY-Y+09`Z%=Ykm? zTaaGwr+~-TrO?t+6(-u7$_`8BqQ2gN68_{KS1FHOO394@SEFs5j)Y3ce`w(EB|}&? z@p0dK3N!ulOhs*GT1CpsOP`0E%al98%rFa5@zQIvY>2P7 zZ8S%JJ-beUcg2||lakaogU^@jt4+w7gijdha=$ZY##=mGKm zqgy>ONo*7$Xj$Yt85VPM5s+JsC!-LhdCRT*i8-%}4fMEDFu7dW*5nK0yXGDzmIZmA zUE8+y1F&dar3BV8ztt;$$KzeAcpldBC_&HQjdGqZRX5#utF*wB?yXfTWR1BYC54^q z46W|p?Y#q@jho3>U|tF7f3WtJ!EG(uqOKvfV`hfL%*@Qpc5KJY%*@Q}m|2dQ9WygC zW6aFVc(tZH5En1^P`Q>IuOtH>ar^?zVutI4X5==8dW~R zqI%zPShKAv9V*u*!(LbkR@=d=f0zp#CD^m8>TS51EhXPASp9rHgj7;{4Q2tlc=w*A zQdYf*N{n=~BJy{UUh@w>PV>hth*|joW*wh+oR+ntbgwXHND(XP8x*vc0p`=QkECNh zS*ykddGZ7c97Hx<*A_$AL#I0biR+& z6F_U|CIz_GfcJ65()|5WG}EtfTV+Ca#qS97=J1O1$ig*>A#!u&g%>C_s-f#AEX1`K zKpknY@;dNlp=%zM<7|t)E75sXN0dClR(~{eMDgfwA$E%F)CkpNtD`Tq=S|OE#Ic_4 zzb+q0e(Zg*Yn&r)oO{q*jRDVGw*2b-4kQ%`VYi(2z#vT9u3Bn-w?ChjN~9o&U|H&1?~`wLb@U6t5&+b3vx^2YZNe%|WjyWeWLYMycU^2 zA|WUerZM|E^_VI9r~03*u`2|AWC!kr`$fn<6BR6Khc#MLb(({iZEZvmivDVGY=5;l z+^B@)ygi^{_UUcf)RxinA4Bs5NuMb#W<C zVneX7CTs_aMlD-Lcaj$Zq1@KS6wB8d?z2@eSM?TUxp-A3b=A-} zkmAU~yx&X~TKcDxT})&AQ;>!6a2gZM;Q)p8QEP}if8BB>-8niAn>;zlYPjp$8<_{J+{p3U1#ih<@u-~VaKYz-!!kDdexr}8-bw{ z&Kh|`Ot1bpv(1Eg`~F{W?-;!U=fUy37nA8kX_zsDd1a()cN2yauN-T(VN8sLDSf1jne=D*( zOIHlWoz%I^TZ~LMvz4|59c*nY>W79PHR0?5tuN22oOtJxi;DNBu_cce6jI*`k$;qEruQjd=PPV_Z)4!rAFX~D(qL0 zyI+640eI;;+`IDc-(V(R_P=X5LF7^VU5!#trfDmU@~lYu$@36UNnbs8z~m}KbGuhq zEIB#aqiqlNkg3kD!P5;df}bK&xGdu}3oNaWVyKfGD~21I4!@eP1qujmsi5Bi4$mIF zx)SH>lBPXE+bFjbUIm%%?O`!}^F|P(9;1NV>&>n+8TdornjdrKk|GV7W;TpS7rzJi zH)w&eog-VEdR*jynta*#a1$DoimerNl+)lCiTSi4R+I-(>xntH|?Ud}Wt)m4<0f2bxqI zDXLNc!6|q38K1z{{lomT@`xZfaM|c5iL*T?3&+5kgn%g}%RSr7t+w)czT?*P@U< zrTDj&2szM7ok`&d;1dJ`BuMXxdOcMaY&^vR#E(neqvR9q)IRvWACQ>50oM$gbZaci zEba-fpb{92T5`_$>=IIvheLCb13Ip8*ULZOw(^~9xIc%(Nhb6C%LQmQ!X@E}fpM{3 zAM2pPEX^!heh*4HQ0)*?x%7Tsw{5slc+*&T9Y&xcb_9GMy-qVf{893D%c|pX=9n&I zyMd@{pyorXiBFciFC$Roay@OkaA~4~<*C5>)go7-&q~Shz4pcpBvtY_!E(xybWVez zVjN0~1ZQJj>0_28GP+6ROUuhS?*n;((e78^R@k4Bb}N?M#qFm1Js6p>+Bab%e!8ic}H_FX1ltg zH}JeuZ#$gsa})RxZ9l9;G`esV%LLVOVQWx|u>!^$`Rx*{Bz%zL?RnPexkgf>I{WsB z%_=Ey7K+G;GfIAXr~Wti-O+#0lkbbJvP5HZYTnX)y|e;N?#XJ3x+Oa9dK>;v#Tk0y z$}Xj1$4%WVeKMkZ)(d533OF%*$6At2hiw24`D;P%Yhs={(3#D!c0iwPe5;#>e|%oGe8B=| z7gQ0Q65jg^wcNWl96FNiX63pWP3<(#ya&;JpZ%$6U29VK3+L3N_T=b^n$pXmWoDh1 zRPZtMHS^C>7=^t!z+R4l=hvL1`e#l8S*pF}c}vct;qB>^Z2dFDvhN>)zR9U8ED5Wz zKD~KWOIOEHSo7Yr*ee8Z0$EmM%Z59F0}9+yC7$((En9_8SfnYJx}DrLP8Q25xJG z;O+;_t?&i2pds5l7wv0QqJ54K;%{c`eDE$;J@H7Jq9VgH_6b*f!eD2{1QSGA(8c+$dt${oJ9ub=5&G+1^Qm&AZt^sH_OjA+yxRs#K3e3T2#Evsh(T0kmP4B z5krC1kg1Yquv>)W)1e`+Q)3-*#7}U<=+6Edw{?shY(}TmzQ9;UJO`(yqKXtm?QD^kO z*zZ@?y(g`C6z%L+VDPa3jr3^=dnqh7ufa2#{QbhAr7F5ZA=d9Te=&`P$9sDA3)M%p zJ;pwbY&Gd(Y72}D!M=N8!BsWkhxE4{A3Bz%F5Sqyv6;@0fd7xAyPoAYm|S}2Gg6ik z+f~Sq`DGPtl<%&6wt2OpL{vY0BedjS7*`S_CCBZiH1MBu7LmDmF+aksyA{>Q@r?&B z3wN2_9JJwM;-@59P+db|QA|+E>ZcTRr0MB)YlMfq@e{`%&8ad;e;+!5+Q4FtoB|0t zkAFz&PSZuqi$b=Ro?M02#_Rmf*pi|#)omT|d6s@g`&wfg>Bm^EWr$0h{#82lDID2p=7GBrgoI`6d;RSAC0)EM!^wm1_?DZFBZ?bEG7WQ~K3}%hm*x1i5PF7u0;euih9ez!xr23Jx>U@z2uTAlcqcY)AX}tmE(s-U9 z7c3C?NlWGGB=rP_ww8}I0k-7-6YAgpf%*_8e?$Ge-VPf~-tKY`(I}DF(^K5=lQWks zMDNei{}bv9U;-tvw%fj%MidXH zBB<^#7O1r;mmZpbyTe9*IFPr0)q}@zBrF6|-k6{)edHiQO<_74hI%fIm=Y?(5Qv>2 z-#Iz~u)Pv%ycnmtG@KWj_~H#i&@&jOAzY{wVr%(N3L{z&JwHpy2BCO(y}f<8PpeC@ zd+u!9x*mR9Bi2@!jlAh4%7sa0GQKl3Yx0V~euSLkoYTPcX%1{yAX^z2{6Qlr65Mce z>Gp#8a_@0j{H++YT`-pGj8JF2qv--zsN1U&VaV{Q4s0#&DPM6k=v5{Yy|oxZ;b>YK zrLbtj$g|j;3VliC(68e$c(!{loe9M=2MZ9*S?WJ|T-mKL6r&$dkuuMk$=f8ReVCyC z+1nlLpv_78yzm^m0d~ACr(B2 z8&1ShJsdN)HMp&wH6L{&DZ-yKBe(6z99Q>myiqnN-Tu5S6W62n);qer;i3RAzaVjLmQe}iA*{qrvFc}sS3$nS=+3U5cOSS!yYYUx z2v_4o{lG#^dGn{#z`PFMK+LvTrhR~b@bpUQg!20z%69)c{~!G+D)IlAkmx|9gSbN7 zo-TS1`WV8qyOLK${WtlP!B8J1+`upa@O8lj>Ct1B`4@S)OkV;AoDvP=yHyQeQjOOJoaGKf^3~st;}BYJEPgO z)qjm|Ol3Lik}XSFottXXk_^>F@rS9a0}(+f7RWFR6XcDJD4KVVth{Mo2YK-Egr8Cx zD&P&)5{m3}hEU$`jM$o;cv6APflZT$>JKp9=3t>^O-w#NFp@RRF&G0zsa%=G{muDR zoI<|%9IO4}6f^YXoRwI@nF+bt+QO)r94b%{mNQEZH)g@0a0Pr*jEp`+bietIJEY|M z_37rB&Acy@MtZuAj_f$PP{R4Mgh2wwA9r$^EqBWR1QogcnDL5JRGSrc2p;2#?6xgw zhU5nypK{I!B$)J;@xs*l*D5!wHgU6qK&@S&D*Q)HE>^ZZ4EZo)#!1hcpXNGKqzC=( zej&(vUc6q-qp$JM2`u6l&)fp5avys8BwZg=6bQ2-VHJi(R`?}%>49gD)_1sDL2}Fu z1{bY`w*o*eSnGJ5vj#Ay&YCOn58idRRuS`rFp*kM#iQtH@tn}vW%WLz8kT>jL503z zQ_%59?<8oaXb%WR5(?ADy3*%sxwO6NX%sGbZ}Pj*4G_!gejwq06wP(kZYKywA ziFTqq#Ey2b0cJmYU78ky{4ja|4LO3+U3E`U*7O5MO<9%*nNZ`R{hxTU#LSAT)W#{= zA%x3=1vmJ0=<=I+vj;o%4bVIWNG3#&CUOk$*zoloF&GBE2t+P$fcNIV4?J+2^QaCT znnyA|2L5&dnXgL?pBB>v@7)M8$lA&f%ilwrFk#-BrHK*(p3^<*tfMd^MvVL&IjdbO zApY~&c|6~cHzcWEs?qgZXRX>Wyl}OGePin-0Lj}huV{}WI)#{#j~Bc`OulQbKL`@- z0Y~f(y`_m=JSIWTOk3F8(N;&>d`6gbw%h~Gw{wFSw4=0YFKGJ-qL^>@R`eV{4Hu{> z`;I~Du*PQ7(Ah6}5Vax85fib>k!2H;Hw^q@SAxXDNfb6d276icyzK@@dZOF*LYq+H z`rOLG6>*3|icC?zyEZY~LFFK2asWW0ZNan*zthUjPyBA#7l5S60H-P}(U6ufK+zCj zJ`x=WhOf4|pSCw4AMd7T@`-neI{A3`1`*9hF14+M=1YsS6UjrclUq>dHnobI8hCGlZzw|s!onySb#@nQ zMoxl^w(`{OsioEH+^dlH4uNtrhPU1O`|)*(z~yv#a+nD^|1)6_QZMT^uX4{$ArjjF z;MYaL^|!@=mDu44{*R;(?=UD8Tv-)Tyi%%W{j!(YERI4Gq=(3Uts6AQEmvCvrokYB zUg=J93t(*vP{PM6j18}u{<~}0%y((R^IZ6EGT(*AB02?bC~?XxJv|awYz}S$fArD4 zFz@iz1E-X@5-W>-#Y=y&5@O~LY|?e9j8{+#;=Sm~adl}oK;0W$|7x)eV0Zp4TbJ~x%QYBpiuWC>3k)FoKR+0@1zS0$H5Elz>_yxFa zA0EK{Xn!5Bq$Df;kl(|RsnMzjv3 zBD&ezX1Yb5{zVsWzSlwd)>KS-RdV*Tce(H4(8(x!jb#!T9eEOIvlZRpN;mtQIJYZZ z1@}fl5o$z6eEGbU?4*&33l(G*?7ZUekJCFmY*jFuO2h$mS_)S3k`@)3c1D17Lu2Y~ z!iQ0O5xVI*zar}p9_l-^EhFjh7zIB>r=Qz46Q-Ru@7RH6jRI6D;<=IfVFfE7qRlMZ z?fij+E(qa8pUUOnUPj`?K8J1arY}Mbx=(PnyV0IyeV-L-hDl)=?^4Xpr!Ksj-jv}k z1-q#XF=s`4tz9le1K zQMy6&Z2BQKxTi5UTF>iy1?K<=OzM31m2Xx=?2sMrLHDxmk9>5uFz0KCIVK$UWI`fO zLA)?t?QwM*InEikIk33kOb;y5Pfrjm&jpVSq#k5@QhmZ!z%_nxWn8KP0sbR|;H(n+ z4UQU9PUg$rDq}CFm@~$|sUnnhK3n5IP-x%yFzhc|_dQ#0I{EP1!se-6jdLPMH5xg# zTJLGX$daD360=^E0UT&eu`xrKwPW0V9g#7; z6qpykJlK_*U#?w5_#X!%Q^H<}yg5NEy3pe~4Gp{vO7vZC{KR_)-7{{)mBFH-4e4*i z_U&$DsX-F@OxU;Pf~atnh~u)kyAU`0p99BWZ| zAPyp%5$&V4?!vP)U9tgkT^>SFtWaEarQu15*PSglp9MyGz9xPmqtWU`1+}Ya$2eGb zW?9{z69WF8AfyLo?ETrnJf_`!Mf`nY;Jx_kMWIzX?EiZ5nGp^}2Kny;z@u1@(1l^4 zAxyTo%7FUS6Qj@e7yXs`D`kZ^ z#FTfmd&ve_&Ek7XjM0rQpjnJ7ZJPl4aiWt^^a=dqCM8$@%WuUN{MG}X?^c4}gCUOctWFRr|G}vbuHM&IUt8jGC+vfW%s^e$guX>px|}E1 zDrNq@VeWe9i+F~Qla4PuRQUHo7WePT0|PH^=rNMiZWbL<%NMm+3uAIC>gDV8e%pI# zyYm|recr6;(38I?ru(~j$;}T}UAT??TiUfa_WK;gm7i23)SJpWEY$zLOpVrkft2rt zVCH-`i~uc*ftw{G6JGXEqdRa1>2Dhd+0uCK{D7ORE7U62U!5(%m-f0G0z2(;pBSjP z0;_l{c4ivBY%0*oXkCAxWEkz7ZiKMeS9Kcm83MP@WD<&fuWxzaXf-CM^JUhjv_)>e z6a~7v#s%@ns1k|JM5VM<+;I-SH6qNguIBA*$czR5+&G?cF`m>JuZ}qR79X>hsO=SV zl29mciw8cPD$MYoJg-iKsNwY*&=ve6gwD_lDG8T|p9KeTy_g3evJFaW7Pd}7rciEY z0BK7dS=9PB(9p~|S7_Hy7i?1~Kg6^Ss?U|RZEISw7`<%a73Ia4TAEWsM#Y49FRu7K zVL)j?p>2`4O>y3{fs-q819C13_b;*?jctO=VKPt1VhR4!z=c2rUKtU!_Y*hkRJ@(R zC9^qR;0WT>i<>s?Z9s~WU!#^IWWm!(&(d#j}7Lly!3!6E! zFR^&lMxKpQJA=a#(W7D+w-4;6ysS{s2P3WwzB*mmrW(!c927C!*FP|V;+wAL-`cVX zOr{3G<;I)jBHB$Wwx^V?Eo&Xk3bm~(N(w77Cg?OUh=Jp;3to5eXJ5gpG5FMg+OC0C zGNky;d{Oe4=`Jq0xO7!URJ<+nYV%{e(#}p#93|&Q1kXuJl)8Ow{scwsmM*Wq(eCdd zZb}d|LF}=m1g8(+}w1UI+BefKEYwWcWBBdgA zrWA6;rkEd&q-uSLy4nLROK5fAj0Wr&b|JpGo;g7_a;c6nCKrz#8rFdEusgdpLdD%< zrdF+c;2T>C$jT>G6Z*kwvgnE=zXcHo4>Dh)Wq1Y+=T?xN51%5&m)6DKY0XrKQ<(wF8)@$nzo~@{fwFF{mG45H!!L91$~* zhOt&pv>C&3G84`*#)0SLKd8$~QWPY6ZR_f%kzzCXIrdx33Gh}AO&!Lja{bi#9)!`^ z3|u3I9#wh%%HTvPKgKwdcmr;65+y?89%}ES-5WF}($*G$^a3g60Amk9|J7v~H>&X? zNV>hHb2T#?39g%K)wtfNg7dunv&&&;msh`mApPS->@~0AT2M9x0yD+^ay_0ez}3B4tA%id zG}HDKPM>4_di9yC57nKkL?$T(8KQ)Bqk?2D&B#~!7LOiO|g!V-(d85IbDr0R2ixq zYh+?Eq-pv2_~A~Yq%pQhDJD%{>%K#j@jIfQE-<G%b53`>hh37y30^Vrwh?8^clz0nr;Ts~>cZ{7vpU3dsH`K(73o&Y zHcXf8VqA?mWy`eDrO_`ATjg0NO+boJ5bg%2&-)UEz=mAB7_b=QG3|4ba5vIeSc(#J z{<}Y>ZReYZtjx^W^KxU;>Y}w4xjvsa#Gya1$i% zeQfAMXd;t)*QfVf&hLR4)%YvDF}yFFKIcU2b>`rCVSptu^Q%j!M+tQ-8+EML<%F8A zfBvo^$Juu>(3w0L?)GY&?8P#e|_e$n`lhZppPlLN=1In^@?NY@}hECmr z6m^P=O7hCeu(}1kKU(cMP{*juz`H8$WxgMo+wN)jU3{c}4Yn*zs2sfT@T6X^#K<=g zK-JS%T45t|!9Rtf8;s^fw~>p@uq41bTeQSS=f}^p+dATE9PDTHc#j2~4-^+RrqWx% z$dhOsa<+nY`l+s3$oJ08uSe*n_H?1uMFf28vb!A*S6XX`=^NG!JSac#Apg8^GZ>DH zg6?8}81r+VV&|20`wb;2wKy*8CnM$GpOEWn^VXb#=cjAQYP#8|({SpS!){7Ar`fgY>H6Gdh^Eqg0C?LBkiBP;?G z2f1U|)H%oBN0Vq9bbD|6iuaTv=Ie+B=~Zj^;audmq+}%x=3D!>MaYc;OmtUnGj#Ax zPs4M}oC}+Bcg=5N;#e(TsuV#zSbVYw3FgDqX!DO7ahsURZ&{`nPK9uBhAB?9p#EWA zH*|1{p3^#Qqx;MatzH~gbtltQ8i%KWIj~bZ<`>F-Jl?GtB~8Co<^uUIT+tKPr4Mv$ z#}0a`oBMd#0nZN(M_3GqPTn&>n3dzorR7(pe+t3k!}~V+zloRK!(}XP9h!r=JYmYz zwykz|;!~BusbHaUD}s%}m}qa~*aH|Sq303dd2ID{<#f5F($Id!aL#s;1SZ$LSJZ%Ning}~hR)l?X^OvPv>gPlpSE67n3{++W$QVsZ z3zjw7Rj7@FVZbT!Sbx>@$OvdRuIMR+jeA88*pTnAZ|(W#9JLAio0!=AlH3vmk2B0{ z`h4#=Q!?NE7;}q$xV10)bC0pRljATGE@VSYt~G!c7xv3Uu`$7P{l$F*1rAsT`p6i? zfP0ha+<*`)Mx!c~$+{&#ym)azw`QG1iEw8Zo{pKH?n@SKc3QEuD1MA)H$V} z%^7OG;{`Y(8(^L`&a12ZfRP&!D&khffb_h#xm8H{=cfG@YcrK{TSe;`ctpK#|CW8c z^8JNz`RRbrj>mq(C&YB%ap$0UWN(Gp%c(d(U#5hR0Lz+1CCRS1bT_2pT;6p%HC=F( z9>Z~5c`SINU2@0oB>tGO?bb7w%n}}M!CKF^DupED zgYQMFpx0d~*)1t*NR8Jj8!%+fmDyrP{aJJ0Iz?|M-=kwj>x)w?JuNblz4$h)NuHZs zCEe8Z>jot)pF+Pm%Po~;)qyyUz|{HJ$<|N*YLvJ28}OoAUN@MLe@~FiR?T$(5K$3@ z4|SP?i!Wlkc2TKeV$R5-!;A^2H?lgTN40q+h}qpuNNkQdRll1{o;SG2w&;_UT(D>; zG_9fHMhBLIJTBgqxc7*;<&7>2PInY9;asd2BpkpIQobUzsSmii90hwMZ|hGaVa|I+ zdj;DLAJyt|zGDE`4htpKFaWJmWr>rYbg+N2zipT3n(s7k_jDZ|&fhN(zTlYDrj3mF zJfCh9><|=Kt|Jccv_^mLgwLFy?|AAxRPl0*37nx_hMO@#XP-9s-j;EN={4FN;cq@L zzFV-26LZcvLd#XS>a2uujzRhNDPjXWoBm3U1q@BB>Pl*1y}<^sXw^pePF@uzQxDzh za6pKELSMO+!4_OmoO5MWrp@dWiL=EK{gWhxaqnkW>=XA5G3ce%22|0``4^$zjY0BN z9cnlWi*L@s(ZIq-4Ty?6)1mhg1bpqgtk>olZ0>e#?alu?B>HS$G{gYlBS<1-k3DAi z@~6WBK5V-T|JM^BrjFB#_$QwRk^=?_2GKBa4Vt6n-|oDE++BPoI>RdyBcKo1&}2#r zz;({|S-blk!{we?c%Wu!9UkNv7-=2PlyH-^bPuxep1y!*BUMvd)0YXYYxY7UzDsB~ zA8opm_&Z%*_`j2GxY;my0bH|Z$Vn18eXmPHvo>8NU6;&Q*fPad7X>nA!-d8$?^VBn z7gF8KG4hYv{U36LZc{QE-O4vABR+tB1=E*lvNq|S*Qytv%VMV`*plTJO&r`c@GowN z{p}rDcaFkd{2bTryw1$Vu5YCXFpdri78lMPOT(J=i9EtExV5O~_8RAWH`MBF=Bq-- z&qU|W6B{ZP*iXxHRGu3~mY|l(uu~Hr3EHsd>jkW++4_pPk%69aGj^@yo+8Iz|6Ii_ z=Iw5@4@Q3$z*DL`9qW#}6;o|?hH%X@Xfr7l(nw==hOE(!;`_;)Mx_M-@scja0h;UN zze|)aev|4;ugj7eGatsQCe#|`SFT7c|L`VuX1oGcRdOJ?(2=pg|2vVsxCf_f+!8Dc z{1Ze4O@=`!r%z&DOD-Z>0~EEmqjxX$1cEOq`ySOUucl#e+Cif0N*Z~R+`5j0$WScn zQ8auLg^kI`-rV5d=S8Dpej#C%=bbJ6PRy#a$M4z@5*dLR7{t1|;V|QC2#+xAcS{qT zlV@i5L~#h#6`%I0ZhQ63u#~O|l-Cf2DNHIooUcn%{7$FT#niDtUV6_%oD^QPU&dp( z2MgZG%|8cQr114~-f-99y#@}DzxAuPUVwOm{h+Vfy!wo9^P*q*X-w4f8fs~x0l{rt zF@Y&eo>3v;j%)&9N~G$mPe<}dxib=PXx|k5FZ2}U+3gn5%4Yjk|Bf$~vLr>OHAW%W z;8aQCY_&Ew(8r+O*IW)tnY)X);mo0i3Xw}S``R%aFWH)roW`_e2b@D1cXZ^LdKz^x z&XgvJNEBM_L3g6(=iWtCV}vTMK~ml{CJCV0>Ih|v=e;SykSNJjB)rQ3g1}m;iE*_q zv@gI)GU)bg+3hHX#-z`7#1Y%M4hOB}ztuQ{*0DVdlxHM$Spp^cgJ+W`_wO_*9l#2W zbSAZg0+#&(q^zgu*lfr0%I95;9?P9n3nqH3KvHG}^%ro~d8g9^w`SF|)5L1}{p2bN z>`pw`FqT5+G(|pMxg6rDh8@0t&qRvRImp*@hSVJCLVAFyDk4X<{bt7*F|^$Dqpe0Y zOnahmzLtTCkfNN#vlVug)Jjr!^2fqNn{HMwiYWqVq5BvE_EanEa+4QzNWJ^q8raK}hr}TbtQ)f@#uX%HeQ0CN z`x@A(6QAdBsHAp1A~{la%@11WW*QC0PwbG{y6rzmfjFRlU|-ad0?Q&4uGeWstti22 zVXF?m+hr7)??0vXzQdnr2h!Q1%S^SR(tyeEj7aafuA*o6LtGS0R;c?QI8n@ob8oXL z6bw$#%q8(B$?M_;FpCn>d=tJQ-C)S>n$iR7yw%IBO;ywJj8?;#+`)}KIk!gX$Hy3I zDmEW`KYviaJyi~BrK+BHVl#OantH)MxOwmyI?5C_OGrk^1)a(ra|c)M0-dP%Ao$3- zBP6LbaHu1o0EW3ALmystsWGFT)z+`#@1{G5+_;Q6;p1KLXhOmhh>yD;uW`rwX?H&WXc)jg>YK6CxcQ!J$2Vg_?KI*M|mhvxBzoM+FexkONhuLK8=qH+}^# znNXDJn@j|!@e|BbfL|- z>u=IpD;mk-D@&;jeh?)m)%}GDPi;RDCp zYnOd*aYApde`7BvlBIJ{GmT4rrt9A)r8!Pl>(A`DHp1kd#jMurMqyewP+I27&j7Xl zOs2+H#xx_Lt?tKn=ZpcTFNN@S>!eE0r0~lH8Wtn}$6jjp$!O7zrD^N0gDPUjX)p{L z^-<(r6jj>rGae>?QsA*6DZ}o7ej4@Ww1DTz7uH%cXENv*ni))5z3Fr?xTp&0NqAl`1qEzrt>{f9a`E*=yuj!D36N)KE1h7xvuc z(`k>)%vB0V#SR@ob2J*ow>U9Mt6t>Job8JE!z(K(J>U_C97(29Bib2t3BdRztNx~2 zD5N#$4q#bO(~y|dVi?jQZJ$B0+#DJqrIGMXks5WF0el(xA$MOPYiusY)(n1Mp)4bNAq@U|Ehzi?jG1+JC zJi6-|YV1_?+IpdF)kC@ap7>ts9s$8MuKyAS~@oyQ9+# zVPVt6D)j!B;iOLtpf&9H%sHluVw=1{QDfEAFLqFDrw9RL)j6pt$?O$0piuvFS^oKV zMxE8BQI~Cn9q25c?~uGy&T)T*c71uKeW6cI|AV=_5-*edxa}Ki-=sY%+^{#g}53F|H^2L7>l1VHOHBV|EeW?xR z+n+fqXs_g*-OBPV*0W47xOv=~kZU*SK@&USr1VT=AUL3C;OQW+2{R3h)h7!4cAU34 zic^rqbuNg4j@zoCZnE^7_0tNwT`aoY?}F8~ShMh2bu6rk8*@Su3ZDeK18*m0a2P0H zk{27})_7sWVO?lFE+I&@EGB=UrQoi?TMIx$s*4+!rR8Ij-S5G3VHA-UR92p&(AoJ{ zQkNvPE~Ogl4ae6TRn5$5WKIqMhiPo73p7{iiVEIIK}+gGct|V;lAOU}3akXRAG~>% z85q3A9b)Z-{%SKRacH>busMflPDvV0ei8!gLHU$=F304K<(Ds&vdIp>O1GT2|Q^D!uY;JJgO*EN~9 zeSNDnn-`$#*V8q*NBpl|DBxU@LDbYE1k>c%k?Vt)%Hxgk#KC9z;!DT2{^q}DMYB`O z6>qAUZYy_Y=(J93Uz|Zbc+LW4i}SW^)D#ilGaW_Q+1)(Y(W=<@9k-UWwzD(j-#nY0 zisjlY2vs`Qx{`pK!~)-Xspf|P0={zIG|{#A>8lyRv?LeKWU)v-P2o{{RtNhuPH-3n zaA#07R5VQIy#l;RZV_Srw7l6P4+x2W=|nS=JlTN{NM^ZqHx_IyGfQn;35mHfA;|L0 z!Kx$o?W5`5etgMl3zf!CxnN8U2wQy`ypY0+t`&L=0+v_f?(T*+mFPvKN@)p_CORA5 z^&~XDStN@Xs)f%U%vefn_b@GfwMLjHYG+^-{y}xl<#Mw7L#5svS#p`O!B*<;bfT_y z{^&)$;ToCJ&*{Xvyqi-O{uOBWbox)ZM%!8#V+~+1p-9rx>N7bWpXtNbO9*0y&7w<*MZrIL zR%{FMm;F504-9%Q?!@C*SdI@;GnVx8^WODm7z@@PUc?%Lfgzie%AZ~5m8q$T`Tq@< zGX6zChR!jn{fWFo!VgjmVw|`KOl`ztye@}rOOXh=jnH9A%2AOKRK5uLIAhiC4>6MN z)L!78IL+sL6djPC3D^OFw*V`==yPRryZt0GX>5fgz$iPfA%v1J1(q&J&qOD~-e;Nq zSzbM2e;1PKy#}<^6m(ktWx(Z=Y}z<;vH*@W;&X^V7S)A$Ul4gh_B)ULmPefjYOP6{ z{W7&TFTrX*TILkvNfMgD9f$_p{?S+ju7}|gM3Z#Ql9$M2{Fo@5p;X*^FgXKt_Z;@n zl_=qAg|KxCRo{3k-~4n59cvJDq&H=0_L z{#>YAF8tEG8TK)8OES{s)v|CK0}lthEsd_T9*8C_8(rbn8b2XZFzMvJCl4#LyHu2T z$)<6*QhFYN0(az+S#HmfL)ku3`JxAkFGaQJ{bnYI8@ck9TcA>Kl16k4hSU^zO25R4 z)VkECImg81SKB@jh1$#R+(M9qT6V{E7jsYh&D;Sy1RN5%x76tn|)&7YcRX$199JX(QYREp!93R95x+P}k57G!Muj>GpD2|m{Vnd`dku@~}Es#Uj9 zHa%sgFpY-jLlFGMIgLs*WBY<~z^L1QS3b0!^-$BFu>0O-!T{n0d6l0%*Fkg855zOD zUK}8mebf9~pFv93=HHT^78d7F;+nt`bm)FG~-x=#keT^3@YVzj& zaXK=SGG;$3=9FwRXfC+kS=cGZ*QZw;rInA!ooVqF#S<@|a54cEe`t&TIJ%;Ac|j18E16t#+uCPnhZm@?xdOddsPWG-==;lX(smWuM#3e+H?Qn z+*VIZh(LxCT|OB;Tl?9sEi$nnr3y?q)eds))=(AzcC#Kv#Fp?!`BkH2+S6M~meuH1 zKM%t)dNT3iRVzuk1^bUG2TiK_=hp-l4JGBsdDp@MY)La{aS>hjtw}W(ZA{!vxYS#t z4z;KdJds=3FyN?7ZIwD>?=EoMy`RKfDwMkR@@q&^#@ppicxn;?@}1Z&w1P%edKT*H z(csKezac}AYQ&>R4bkCfbYhwcvOO`+ET{4!&M!x_&&ZuI*c3I44VT|>=HqJ35v-4` zcxQE2#b@m%mXq>QN0I_`vLd8u3#b(zjE zGC7DpulbSG5aB(c8e_FC^Li}PVAQOT<&uf8DEp=cVpp%=cuv83(85O1_g&bGicdt^ z_hmzgRQL29+@G>cBDK;^wjzhn79YO7_CdeuZ}8CvFQ!hDoDnJwu2!Xke^j@MIcCC~ zl=K#r)FeH~E4Aq5h8_O>ojb9YKd0>!AqK*or2opph3wq9#Ol1NnlhyCRSM&T$WcPu z6Sp^vKq%dw+1foq{L48x;5zInmjbfT0{#HG0kRle< zgm{Q5AvvS$q-Q4VML^1>&0H`j&yVMi_RlBJOa2%!h%BW3(6Eb_A|P6pRsGG4@+rQA z=b*heCqq)qJ2b0f$EY*E&dbiWIVa#deg_Kv&6UDDr9z%=uZrQCf9Ui5jmv<+n;LPi z*Wb+NuUIZbFo5!3hk%ye*KV{c0mXf5!{gfIpI?ybuukYVdUCM!zP#}izFyM`L9HD8 zFfn<(eh80QK-&K|Fn{`maaQZ8&O-UF0mZ2$|Wx<>3v*MH&88Z+5{nmfTW0W5_r9Z1B$szz9&QN#DF!C3s=}eeHN! z{+)nA1)^iChDx7WCCV@MmS(Xc#`VKMUkb7AeS_O{@^WmfDyH<|OiB*wrN^e5_md-+8A z@9m4R#z=GI47LHq#2qqyK^jQjB}dh2DtUR2d#a_>k$n__jINQ>J&uL^>Uxx^bP2gh zqhUB^$Zu4!RwirvsH<~VqIpQj#{JKqmVjv2peh#3uw2HB(pX;k;%z)C1K>Z55{;46 zaD3*~!3=Qu`t=IGp2zRICKRuQ>VPq6`!M2Z;c%tO;?v-g0kei^uOJU zTlj;rU8$^?Ax`XKsD~M=s=hT_>fd2o1?%u0Ams4eDbqQC!9>7#+Y?eJ64+ATGVT9j z>@9=a+Lmo$L(I&~9LLNcGh@sQF*7G-ikV}K8Dokmj+vR6*)lWBj8EBnpL_0m_uTrv zKdMrd){^GZ?4I4DNB0Qv2*Ne?w1<&;QZBK5%v5c`u{A-Q;Z&SWN>SA}6ptElAOBic zitUC18fxuhB{LA@7(LcbZpNj9RiMSoB_jvc_7+x{dzw+$&ag8$_f`9>$+73Kn9d2& zL8Rv*^lDdV7xd>@|LoG#Rp>$4hwrjM+1e_-GK7=^h=Pev1mB`gjg0nf!UEamv-zx- zm0!Qk(2YeKy=qRlI~)Cbqi1^KD@>sie^(&hzdva8nz4*ij_B%mG_~2i0f~$CG&0nr z5dfDaS=J{m(`mhyyI_$Ka4WN)DPm$OAR1YS`+du1KD$o;deUOGWWZqPpwLx$n6A(I z+4^kg>WmMs=oz;0OWfyipc3{4-9ue>Jp1Y(=`&@xqa}&c~_P2TtVmbWj*LcGmF2u?@z&hs%0sO7gBC;s38$R1^F@s zQt+jXFUjR*PFdm2cK^nIv-h@Sn=2y!{zK^ZRVrdyRd=F?C|ej|rj`#5vrvW2g7Y-HP+ORsGR6#Jr; zP^d4_8ID%gnVgviGLx ztSt)Ut_q6%LJ|iP1`#Vd@r7|g5Ah*?wW~2)MoMMqGsFY~v)vP(Zt+_votk0cL!6Gd zo@l>voaPjigNSHZKtnfz)koT1<2vo|$jLmzS`{xVGz~>xi#umF5vq>2Y6j--xW0Fy zx^8Q4?px|4*yXaO^1`n5XFwIn!Cvk1dA?T88F}%TnCWR3<}WdU2)|8Ger~&Y=0Fwm zJ9{I)d*>>!QIIMw^A)its-M4vo$e^3YMiZ>km3|ls+Bse9 z>6(_pKDM(^R)L@!rzA4PoPkG~gVwFZO28-LTqKAI_M=OlM3CYnWGeV-anaZ(qi0Z2 zB?>$wbXbnF?;O|9PQ{uip(xa(;B^*){8MF)W-CuAvZ0fpzOu_F7{e=GY_P@i2dKNa z2Cbh;d=4??M&m@2GrF1O|C~BT3xSLv+xy;NpRs5oI98|X2YMOYq{(Wvi0r?(0IbTE znwfd7aCnMbG{kESQ6&C=As7W}p^U+I5S$9(aiVG(3W`Ad*gI^LU9bKzol$&$2!N@H zB|58>?)l8W&W>=5|0O^^_tvWFMJHMxeJF@&5Q^}CubooY=+66@aK?02i`18+>%6qoG23A+x+>mkjAj!3A#&==p$T@fJpSoF7@ZS0y;CH_yXSHFMWQ%TCdJ z{2DuG+!;$(+7c%h*i*G1O_@DXObpoZ{N3&!4)H-XcWFD-t_=Hlvs_T5a5k=j%H1ShX{JEuR*%q_SD448>wY=;hX$M#b)iHC;h7+gt~YK}^o%KFv; zv;+US+{zcF)h4ra8Rcfg#EN(Ra#ucjV?(sL|`@NTztV-IzP0wEUz>)Wbd2JE`)) zID+n|n6a_mn*fg)wf*kp13h!deoxer>#rl+pr|uCH06JpAE_ag(5N&#TY}rW=J$M_ zN22h5^O3>fQqU$TbIga}#wY#R zZ{wsJrdNl}+VKV&X8rF`0y%p7YcdCIY}PP9eQvz-w>#7E*9uHlHou1s4z_#roVJ?S zPk={v2`H7cj{Zd*Nh38zE1@*WzUr;`s)o=}k^8rGDW@s1@$c)F=7!)u(gPyeW8z;0 z+ts_bUbu(i%l=UczDiJ4+y<}31ajf!_T9ra*;`PYO;8#iUEpNA(hm>vzkN@-b6OVZ&cbqT! z>hX9Vj=P{4)|mZeF020B^p#?F7nam0HL&Z=q40)Og(NyQZ3I7HG7TS!_|5~tBYA|Z zwKIapXyf|Kq*m58mH6e?+~l8)dcY3O{r_iKxzo76@rcjb5jwa15z}7ntEU3=G~e!K z0k|o!d``~lMFlmv6rDfrAVi)mm|?@&v%G_HO~Uh!C3u3aMa*X#h&wItuy3|6hZf^;UfpuN`otnoe;$*Sk7!Qp|`bAAxDXr zU}nFt2)q5&ap?B`jD@k!XaP~S>+6ote=L*mxhx8w|k`%V(ZcFJ8a#VAkU-wMJrNpf? z_KC(2j*|-me4hXUhcu9bnO{*76}+CGvHRO^g=llPM>CRMPodZ*M*C;&3L0A@i|UD@ zk{HZMj&ai_8Tj2sYL;FR8yVfJT@*=gAbR7ovm%7vSRZ$&M_~a;b`++kpG>s&e)Y!7 z_G=2{(maeAj55m6a7-W^L@3JA`A#8I;@~Oi31uue7MA3s?knDi;wiqg|ad`HtiSI!F17|B#I{3W$lk={R~=!%UZ3wVknIbjQHQ_)1pi6Mx738IQz`vt<&N zh{B3?K8LCArAutQOv-JnuGSOM9|?oO;P4NPe+C7B>F}a|t5lW}5Nrgxk$_8H;hvmE z+}LX_22}zaD!sjLQM?W(6!utunusEB1o#TnXFc%1hPOhXRuT&Y@Y@T?vGS6LOqy&> zZ&?eTbbqtz5{6g?3n94DokGuhrz1ppnrxc%zh~B+z;=F-Q+%0^F#Hb$ z4328(IXLK7Lo1dd**bKa*{ztgz=l@*yF`PosK6?|kEF;RIYG0c9zMW~Co$%j&maOG z2F&;G;bh}*{f{Hxa@wBaA|IQv-rj=mMp;=MLm=J4pFiRwt4XUM>E-*CJ4|^*u9<8X zHygZ^6V=4OZbEH95MgM>lMYO^1b#P4bGY^abuln$|ue15u@S>`eQ=Qd3uiUIYVtJPEG3ah*2T z#H}oM60qEHG71x#Z@r1KG2e-z2R|(V)(LfJg_QD7#SY5aid=@Pn5Y2^31znsi7{&5 z(ubYHMTViN6J-C$i@IU%G85X`X&+;QrTg3gE~lDuz~7UMG!%4Bi6U~iY72JMzprV8 zm?}_79Tz1Zh+4jZZjD=Y64<<&*WVyDlu%sOSv)Gb>-RV)SeUaO zTi5r*HzI^+75d8RyPD%|Hw>Eu8L3S!RKw%noea-Sv8;!SJb`Gu`%YN6S;00R4Y+ds z?PSQ!Ie%)q{jAac;z(!gk*RY$kEwSx9n&Q-BvQ_YvW$w-?lA3>KjIg>D=yH6AuCZL zGQ24BNE|ZKqPeA>Agf&ybJ$dGJjvj|G~A#TS}d&Ptl`+Hm*^n3iq%JmX<{>)4NAH8w^3#Gg&qQN`9; zOuL(O+!%&LULDMFhh=!%!p&(N$$XQk4Xma&Ui|K7`0R7?VPD26^PMJ_*}eRzK~m8i z2D8s5G|a!*gf1N?*;C}cNp&A7_AWQ5wO7GAjv}(p+kc9Dv99D51z1AMUO5XrSVLw9 zpq|d|d@NoIsWB!QZ?_hD;{&(71f62CS#ZQz>`l&TN6eWN7Bxjd7_;~U)`j@a_>huW zq{n5KdlDLYzB&)D+0fD*N@pP!d+$6w->-PxcKiBezi5> zkaZTCCO)5;MLu`xyVwVw-UlMv>E>f_s2 zrIxxVp{VNN3SJC9I_a!YXY6Bv6}WE97(>%wjcYlj>7lKEJP{wJk?HTLnvhms8a9vf zN=+zVyF`z~(4SWotX7&%ALU?`y(bVyxj#8|a=)|~$GKAk>F`*k$90Sk?;=?2`S~(~ zl3~j=k&?M8+)xscMA6@g-sd-mAx+Blj_P)QV0OASIf&cuHv%x=CU45}g`1*`cj z(7%EtFOi-D$=R%>m>=F!C%O*_(?1L>z8O-`MKM|tUqFTpP-B#;iFd|M8_eNoVGYWUWy8d&ntYCcw*MLruOsdr1)X0r zHJ~-)(Jux;)*cB(EJy1+1BZ%PgmpvhlO zlgE-|@Ah~jaUC-(5@fO05#RRUZuaJcR(i>8gXYhAzieOp>-$oW`HX$>N`(}+<+QCp zaLpQApbc>$?(AXIBoxNsk_0#Do?MWCNBQE{oV->y>~qOO*o#e9{sWpsS&q3zrSqa5 z6gRy_RXb^JODxzfM@tQ_+Dlk!pLfK#{7(YmLL%Z4KI|Bn*Uk3y&{XOkD&;o{`t^vV zx7PtrL^NZcMnndBk+Igy&*210PY0SzTGnCIGg8>AccGcTFCF$tH{76CnB|}Am5C(} zU6Z}?#I^ba@I|@tqO~d|de=Ue#B+SzJ#%^LH0YgEJ{nMk?EHl-9*y!eMA-~Ic`P_O zrwje)Chq?bVw)Hdy?_-;G+|C;s&krK)|8N-=D*SQLZ)J}@U0%q!xg@zufgOr9l1)5tRrkg=NZSLN=42{=kQBmVh?ck2;W*p<cif6OQdz#D+2~>Lz_Y_6H-MIN_q9 zuQh@vP=B!QPI&Jpe%4h}aYTevQB?met*+im*mLzk&u2G*_@=Vd_Du##eD*p>@^uM` z3h2*|s?$zB9(MF`w<G}~SK&<}d&srj+Y8VO z*yIfqpu?~3q(_>{6sv-3;9cj9q=E+;tM6*r2|LM{W(pb~J4#P)8WC0}MO|jrxOZ5b z7*gOXqBGx!_HNsZ3X6(WVh}I*kV^Q8<>k(lQ(JVy94EhhLHZ1bm|AZ|wI>N{#n|Py z!Ici1q>_6JU%^D!Jo57}jk}*Sj0u{c4%cV+W@7Bzc?L_DMVbUp-lO}yg%GIXb^DX9 zlMN)=MuU^}lSO7~>hDK$lgIgSd^Ta8l$HrVKa8*$AYs0D7R6iU&|4A4P}(UE7x=)_ zgnfstrumkBsLM0_V1$xw!Ae*qW^0R8QBmDXJKSs4zYK7h*=Y{R7UD<#9sOwtsTELl z&c((5ev(bs8=YElxR-dTbAU@+H)?8lgG1OK@wI(|eS>ymA#YmDF#|d$GgPQceqacb zat1sol5XbI3BtOh)&aZ*&Q?;MpZ8sBw?xP0WCVP&L0ht>s$Q65g|`{)#};0X$FquZ zRi~VIZ>~HJ9b&mpvLzlT=37F=pyn-7SE& zHr>B4m>~n>mxI`z4V`ido7m$zcW3Uk+4}!%=lC<%ByM*}$HvP9fQwV|uNlEZ(!==%eurvC_e z?sB#JK#NjOfr1CWOTD;w|u z2Sp1wKbqE=RM?_c3QQXICI?CCBaD&dRQmuPmBno3AQq8IeD*o9-mK~RcXhOdK9H<1 zBj`fgi1`bTRF?o8pdc^mdB0g$V$OYmcQ5#Uma3tUM51pEUCaFZo{CTd7~!SPeh&x| z=mqo?9*r4&J%;T* zEbCork#6~P9TG_k5Wqfntn?=r6i4WRu$}jfx|aZ|ezQDDExJ5ET*m@pBjj9tQ**Z{ zbFo!G7FI7wc~D>U2MoJEBX@6UeycuXDAJCCJ?Gr+a9+&ACXknFCP-umSrp+&o_BrT z+=flkEB($>N+{H7^>{8B)cjVz+K3%; zesyDMI9;IGba(|}ui-WVqzrw3q-%GdR7Xu+a`?L*%Ilew#70NaNJhC}Zf#O?)of5p zhH<<{IDh#KJFSd|t?8C8{jB#~pyMm>lrS&m+NDQy0{%1`yZ|op8!lX3z|V|l7-!Rr zk_`|&J)M7NNCs0%&&8=IMCe=Fq<=lpLj3+$;kznLVXyR_lrEV&J`GW=`sC@VDPP0!BXM0{vrPNPrNp7ZeODoL=t|yekxedUB2iqOvIpr z#QZ%aLyS01q=kbmR176YmE1?i;B!t+SD|DEGQpkr21%kq5EVWRBR~!C>pX9JJtc=Q z^m3Z?@!&BivP`ugUP*bs3C;-zOTan`yJn)NI+c)Z_BZ!iF_YSo#wTnzViVYrhgmv_kqm{WTSl++L`fY-nQ2dc48O@}4FFxb4gu&5x`C@~eP7vu-O z5Yt%WFi44Ca74<8aZiYQ*U0lBTG_F&nTsydKOiJ~dy#sPk7 zNF=ngejgn&(C7dB?GBZ+pwYyNT(WET%0x!KC4?m3hxez!fg-^HB&~n4q_yu9HjgCT za9Zn@Yzj3DC_g*1ORFPY)Mz}^5e1I*I?AI?{ zuv=SSb9_?AgN1sqAJ>Fcy;)O$NI5iP7||X%4U@1ia!tBNVjWg|7zI0YAH8vDEQAo$ zK9j@vD;uEI@n6(hhs()9iO3oC_P!#z2%NIM3sN$q#Ec2bjyoWT(y@x{wFVGm`e~^$ zKr#IB#ZFk;LhR;OqwQMrY-2U7D@)glP&foeV91aO>lazkk%)@ZJF%!N<_@t97r=(NwOwJ@ zL|sYa(n5fM8ojeevXsOm+2m*dbsn4c?N6$NN~ZV`HH-TEKsYMy}3LFAB0kJ zv1R)qzvyBXUy2|mVNb>~#i989rTH|EFT6bsukCS_f6%&Lusj?x{`Z&Y@;UZRKfJSH zw36!e6FFwx@uY8=9k?%P6^&AZ%AL(Y@)0biKDXl0kuetDI4^BGA_%vMH$K)kj;V`# zxi!@`oy#BR^gaFIrmtc~z1V8?6ipd!ySKY~*p{ew9jL|U1Aw9fX(U|+fJfiqxtTe$ z@>TJAp!~u^h4!0O!PcVRdnpEBzPR+D_bbjV)8$sh`UHsO`gD&&@F~Lg`JoJGIk4i% zIrm-7@opNA+vV*6#c;|$=e*;U8~B~eBiYN2Zax2cLcEH-77!q7f#qVr#>Hd%Ce0Ki zB%Uq&raNkzf*A;#EGIr&bIv~JxIf%J#tG$N=dlwr3RdHG>ihcAc{WMe@@3WD(1b9^ zw&tE?VS8eJat`-HLu_J|=>%{vnygZC*L_Omch=8HJ^K$n^mOi%t()f2NOHfj19#3} z5_;R~yysuC!+tp(7B~C?Trm-quGJU|JEa~n`i}#5n^ng3J_=f!HrwQy2ylB+l^)+3 z&)OWQ939fHNlL>+&yz+!+;uY*@=Zrjt?gITiDoB=(<9BZn;(6$ks4Nh`t%bu!^30O z{}LxTs9xF54JFlP&gGFcQPaV+a!K_2nv&&PZt;qBSkQh$7T>5iqY;g5?Dy<`sPc2- z{I+Mb6BcRkd4L|Q5}c+`lu^08wDizNjGB;=BK7(6O=H%bq#Vfb+wc1LWar3f_qb?# zxkXI>M$7{qY;~gWD-b`$@DReR1Xm z!~!xylcy$UDUAbZH^G6;_EoOi+W4EW81iiPx{J~xLQA6l zGHl_Nu$Bj~fuA3Svs>h+fQ2&5%`r>BJZdNgRYI&7**t4O9sKDzH+3JcDpwk0I?T-d zaTAg%kw{kBqh8NE1|Azq3uc<1)jPPj952uJ`K!fXcR>!{u%CUpM+M*gA|k$X5|gTV zgfJlQeoFCEDbBefYyt=HxT+}FstWA~j)hP4e-b`D@^tgsRu$;`(D(!6F;fz&Es!t` zq3mg9$?iA0kXo<$nw0;Xspt-Ise2r~c;>@nc;@MGe|^=TWst90oBa2;@ZC)4UD$tJ z0lw(Zv)3d4%J7vnpR-8tfmy1+tJ79i;dS5r;R@8T&B)RoX-N2hxC|rkaAgWQvtf43 zV2&eTX_s52zjGO3H>CA`c|Tjwq1H&YT23nQf#xL*eBmCNr`b!SijX`Y@%2Gmq2{wY zPfo)z^PD@MBU%j^*V&f{=DX zcXX@V>{>OzR*U7LSokHm%wRi9e$&*j!zos8|B{{^GllCqjs zBlJQlUW41@7Yi1-k-N%#-mpdQ*R0VoE-0{{x^eUQ{XJb6*LmW* z*v(?2*R14z#Tgkuq3O<6aCDc0`PrR3$~6D=z3_Sm)JWol+9Ic6M69CSxTzqa&giQe zN<)X@-P+G{o-(+#fl?n3Z>rHQBVR*;EJ@<)Aw>VRv0*C{cc!JEWY(PDc|+)H^o_w& zoe_ulE6y9})1hLVyWXA2oxqt0?4NY>5AeFy2&YDwPiZaiM)&Gfi1HR}?ekfOSw88G zPrb5phd9Md(s}dlEe>R_BAA&mkPxES>R*m~?qR9!VSK%4xa|m2OhFlQ|E$Hv+~9n+ zwrzSc*?d?_+EnvU{TBHfFaU1yQI>nfwJ0&{b{TbX6i5xU(JyrW^l9@}HNCI$19{=M zG{oeAGZAug>;?_sxd-54`sU5PKeaol{$E@Gmt|42M_pA=!>4Qi@56|9BnsOcjq*2Z z?hm}<0)85QZ>dc`&a8Z#H zh{F#g`uv)~ah^Yfz|Ae1QUx$GpeP8QN@!rg-qp<|X&c1aT&?<|tid;_casEdh#*)j zt$N2k90+8h)HbQ2y_i!sh~-RsA8S#<1Y|Hoo@X~znkUZT z1?Av_GEgd%-nW{}7|v&nut(uVI`p9YNoE@BtaQNhitFd_Nmn8@76Ky=8_in4aMh%} zaBrbI(xWtOa32$;`GXfN&0*KJ2*bK)Uz+iQY)wNvcm#hsH)V%@hB5c3Iy&7|PSR;69>Bt2TXswydAOZM>uz-K|Oci+M0BlBa4< z3fZpJaxw~0dYA8uJK*cKiO$iwz@f*vOI8D3eaBans`Kv3@CCc~SagV4K4H_dS@Gw(4Ng{70Dg!AshXCfnd;ZjfEP}Z7NjIq4K7z&M zVP$k%)w+Tnjzw8D)Su|BvZvr$kqDN{8_^We*v#7~Nj=a=# zcroXh;&2&?Xo(zCl{IL&=l_>&aDZ*2%WP|#dYQQvlINNy=m&yAc<`hk`KBw&|5r^V zm_MW>-ql~srdx;k%qJGrpLXcju#!w)5TT3*!xpIY z&`#OP#yF_m5W;X<+_d%XCKH8vXy9R|7{&vNzg8`=3J&{+f~uyYM17mol0f1856Fm}8KQWJV8l*I*Dn6_&z_?mUtVJf)cf+y;mjRzFv1N34u=P32yS~{+X$uggJ3h7|92!D=59AyH(f{n^qz&F77d_uDO}HVo>6;*Hh6Jw zeuV6X#(OqnzYafh&GwA4U<_gSGz)^2(xcxFEM7JDL`>JaqvwtfSDT<|Si$?Vw_q zzEJF+cJb~csP;=u@6+qA*I^bXD0HXWD@@cGpfy^}d=$v;_Zki4KeiklH;~&t6Q}>I z$*j!Ead+&RR>f&tr(05PO`^6!^CuVqhX=lQVBOq^R2})$KA3SsWGT5MMnyNp?5=2D z6d5)_LAqpw_XvliVLrhEq9)VP;F)%8IUzG#oI0`9Z*5{qxLT9Ex$fwsi4s4QP#^{5 z#7i3FXcH}dI%lmbh7ldqI~6X*+KtoNAv1(!)L#sayp2%_KcbW(%+2O7H%F=2xG9XX zP8r+^k*tY4ITJGKh55G(D5CMJzyA-2`Sm0r{yqExEfzr)9Wqb$Nd0jERYD48F;o7l zoApJV2v;TI%EptOKuFt%T0_Z(th4IT+6%_o@5%3ixK9V1>#4B>6#W@tT%fI&eRk^A z^ebE-9g;W(4i!?R-QLm*E8Mijt@-W#R3>^M0>2P4XYMX`-SK)1ORelEkiOhDJoI;~ z@30k}e$KQo0+wJlkhIt)VNIv}>NPff)AP?8f@?pbBL2zxjn9#NkYV)gvEgB$YGRkd zk;@VZX!<5ire?SxWTl&*WJQ}r_~A2jnAbf73dZG-gv{h|eIBnk*jbwqImdUD)Q z&g|6ChLQLhs_nF}ks0lQRanips%QyUA4L7pGZU3Bv9TKGiFI~xPr=JR%&Go~{9{bP z>{otYj2CE+XYS0LcQe;qn%jvn5)hDu@sV4J*zFBDrYW>03Q0c7Ty8+Ae5#1ALX$jMq30E?#?Cr^Z zqsF2wOr1*XRhm487Ka;m&cgm1n?^BGEj_eWFZim0=XhG(hMPG|ei%>YnHHwy*a?{C zd2EoBs({IvUZ@6bYOG!(zs$GBX-e}tJo|~vQ&}r2to;g0YTtf;!T(hS_J07&Aw~S6 zspZmz>QjK}S>(P;0^H`$+jrMlyM5=747zC1xFPu2e<84~9{Tt35#JzrHtwc4$Q37% ztxKWY>KdlkXXU)@-d9hti}!CJPwZ}Jrod?&-yE1@yBb}TZ?l6_gsrDB zycxRIS`M1`@jonzau*Q^h*fJoy5|O1M{%1Nng!Hjp1>Iv3~dtCkw#lIKKf}%amujU zB!6x3-^oRagX-DkRA2;8-N1kk;Ac*`2-X<&+0%oL4N^k_*BeWw2Kk{PZFk70EKAS* zXzo8iy<2_v%&*R)px2B;sIH6RH*lleq2-J<342@)*Lhx8EbPlt!YSUqdojJfET?8G zP(6hpF%aEUkMwsK?mh)TD6&exy+Q*~@w)HOYXlXYdsx30mJ;xzzC)1eQSatn*NW}%eTC4{zfG3Sq^ z77+1id2WxvFyno^QG(31G+F0X7)jak*@uTTPx4~b6hHF*E{vawNT+?4aD*#AbY5s_ zH3W<8LyBUMvv^y-fvA2BrP!i~RZ?bv7J84iLeb|l3ns0YBq(ieIFR1XXtvVnRn z00?z)t-+w@~SoAKdH?C2JL_9d?K=kMyXC6}EJpco+cSc zdd9(PKta7Zi1=*O2f_^BNe4f@-)#F$R>{5j&6)nu<`Sqqb|gdeFU#%Z@S z9r_KF8|cy^W?*TLiVC`=f<09(bX92+9oPX>`qOzzqg3`wK2ZB;Q@9Ys1J;_qWgc}c ztO(FZbhlM$rQjx1=$I+_ncXJ*SO6YDyYGyJV`qfpb|iJWTnnl5ITTFOVY%4TQZsk0 zXue@;eG0ECuKOawYM$iMktTAgla$&gXf_MYzXKy5VN?CC*eQmZB23zK`dekn#nkJ| z^QQVkOdxg+QlCItZLQwmw=z<=A+sWw;Mp10te#)a?f$(r2DgA6d%fOxa-UR;f5Lujf3gG5Q;b zdxe{}hOt1Fb%~^RGSUg6?`^Pe6U?MUi#~wFgN>mjhnKbyqwg<>aTyqO)XR^b32o6MxJUE3B3puJ+3t( zz9pwmo(XIgG3~Ur!dz_GS5N6TLR<3uzo_0MRGwN#Lj-R{sFMz@&n{{Hix9ukYrydD zc6IscobvA4tB(7~Vfo|0^N%{4Jz9^n-?18uAJRaI6w3SL&=O0a`A^_@vTug98_{gQdgF#MWQoP9`gPe*fc>>9>E-F@;W7?rqLmnQbaVu% z7Wnhwl<}=Aal${x;0eX56%o~&;R(p=++z+U2aRJ%bfC<{j^i5nwc^)9=-t<7W?QO$ zAL#e3_k>X;41zd>=4^6+fC)_?5n@T1FV1#NM^Q^5X<^~(qhr9-5oAC?fbL3}f5q5?pmC{G?5rC50Cp>2&eX#ijP5T?sWbQs^W2~lAz6s0%akhLm@~(Zow-l zi;h%uJ5F zAXl*H{I9c(gilD;M5xB<3~m}{g2zUR`3wB3@`xK9V93Iqal3@6GH~$@2DvlE`HHX8|;{4LDSk4dscr( z;D0{&P7PcY3k^xGEPO1vmEJ(>j znrWWzPuotIczfe{uF?b#j4>ao&dtx)p-@SdhqdN<^tUx7t4!wi@WR{0zqk12pCSCc z#O@b|)dhtq>M<%uKYr&&`h)h+nxCm^mSt8*!Lh=eVKhkl7nAP}Y??cBl%H|D7d-Y= z(WPk3?YGZUEK&WY+B2rtVD2CN9R3E{pn+<2S-*LVw|IawpHppZJ8o?)20OO=g+8>s zMAJH$onehcG!9YR4fz*7N59<8+()x#ul7x79`L^Q)IFCwR%qTK7L;nMCw9e>%;3Wmgp@{_fg{xp6n z5S^2;R2zA?`Y{qBYu$3qJx?<o zc;6VAU#gQJ(7C;d{J+l(&v8SuUBb@3s@mMz5A33vi^-XSD=E}z(IqMeKi5VIzfyTT zqFUM+_YW5i{{9}Ds8>o~A94k~QAoEzbm0n=1+faX#amTG7nz@LU_evJt_FDCP*T=b zTP=2fpK04@_*irNS$_=-Tde+8{4t8Wr@_||BtH=OSj9B9E;WDh-ey@rL6#?1v&rei zJN+^ABWX(;&yG%uF&#%S>DFq?fOudCH5j*c-QhTHwBky597U2?E<=do$({0Q`r;*^ zVV*Z(w)jlV{zgRG%8fLiZqe*;d!m#rt@%5qyP?fTz>(Bi{UacSosc8qpci>`kGe9M zxS;jsF@DgEBjQvOwI0>S|3fu!HNqL(wH+D52=~gOMfmt$mR2oiDfs6-_Vh{L;O|(& zCuSiAUetcLf-}kg%(ZocmYAU8dt*SB_38%P@G66aRds-a37a`%x1GM)|MiEXHuC6E z4UBz~TqoYjr~LS!$E!t*TqU6tF6vqlSwCp)W1bQkwV$P*m=KWxp<#bVUEEEAH}pfD z!@`w6!UZpei@W@@+(Bw!#3k9q5KH}*ya(}2x}u=^6Q@=t^f_Nhe}Nwf`{G5F5RSi#aOdNa zUI`Nw9>E)1LlmwjrymW|!Zf?B^`9Ul2H~;A^6FH@D9;acBCdrv;2<4#*Q@Jre~hZB zJv^V11w?8jraA3c+KyEt#995rER`)oH5`Rg&9p|9!zx(ngM}+63QaO{I-rCLqtLGC z1X%Xb@+CNpabc#~6>g!XT-tHoc%=rlP%nm`8CN*hOXSG#-!x6Lbmjj9npF#C^t5RG zmrFSd_Qq0hPI29FPnPJT1{J#D)aAjb{eVY+@(brlh-cpXP(>MlDC?^1!mz4>nP~CB z!f%iI$2`AXifLwrEeX4?d|t&pYc|BBQ+QFoBOBjZCr)v}8_DZ1nw8r-0ll`<+l_`Z zjWDY-Z}BJR^wZ-sOfn>mJP=`&6BrVX8y`WPRZ9%C`SzRbM~n5knusM&K$Md0RPJ-_ z-EQ&GhXrkU31svmkJLxi@L?E`Sm+0-P!p2n#bQ|81&;sAl96?ryG^49FKESmr;{sJm%drGZ9eKVb9M67VlqWAe-^!`K+wzO2sd`p;ytRDj zq=9Em>Oms0-GgE&BEEKE=~veKyvnBIP-{We{4_TkUQM2zaG=x-0TCp*(<`felkL<% z(6rIbe^Eh^=463*d1nMECgIhefNB!%5Kg3fHmAA?{a1FeJK3{s0tUSQoMw1)Z3so^ zohyYKr;kaXOU8R3Qq|?zkS^33* zr_gnNnLm99+t$OA3!0af)9?5HE$+_Ju%(VdKAb4cvLxlqB&M6({BtV zy4i7`**+YJ`)=4_F^M%Z<3haB4%IAH=5y*rc4{cSm zG#P|R^UFC-n2}eTPHB~pC>+r5Nj$&a05mKKEdLot@U9G`0vOF^}DJBe0WYVuBagzSol@p;GDw1qF`)p;RCc~4)TBsmq zQ`KVwka9L)4Jh(6Bcv8rU{Phn6%fR!z=Ho6acwNYcPZmj`T0p^m_Gxb-rsvphldyA6 z?kKH)HO%xIbz0c|kAfyu$+pz9*G_o)7J1e8K=@xQwvw6X|2=InXFy&eKmJ!Bi$Ls5xmo;mox)dB zhrfAGzHsaumH+m}nU}yZIuk_KS3lG!I*HsX_i5E9t=Q~3xDGzlMLzE>LHSodm^XH^ z=JfZx&SG{^&&K~^>p&a2PEI8ZU0W{Po$tBM@twek$u+smig~>{rtVtP*sqeAfc^NK!ON9PINg7~)KhZdwqcjrrA)d165 zDGPf;$v9y5ZkC?&m#2@hui?$+8G{~Q05-{Z{(4+v(nc*YrEI?XwJA$725C~DPa_*7 zCeNrz^$JCfy2{jD6TO@7@F|1?`IXwVcocML_sng6oigq|k|(JueeVH*Eb?B#@_GeK zKkqu`$MD9=&6f(HTO-^Bj#Yg zScSgKd}Btty&^$w{@s6bRU91H{mjGRD$X9P1YA?YG~4CoiCF+KFxo&q37&t`aHjs$ zOV_j`+b-@;&2jO8&2;~yGVV&LLuSpN+!X`H$Hy%mm|~8O^ngEZYO=vx5VgiQ z#kJm5pT_IGTS(Dh1=XA-iHX3^`VNg@o-NS%mb;*vAzak#a*VE}r!i>5f5NI@xEWq$ zaQd|QT0qB47e%_V$rjyzFF1{USW(m{@lN$j7|rWn4vbX&&JR*o6#a~(XM5CZORq#P zR!zgIWud7_zLirmDejf~laDXO(La`Zk&6kYQruIzwkke!bO1(0k+>Wyi55=ajmZBi zSIRN{|3Sa#_N9$sP;QT!Dru+Eih5jD+7o&cXurB@!7pC#=PLC4;kYgyc; zjlj$Cd?#f-D}frk!ajHD%K3+ZV!pcp&V-J;_vr#IeN&Qv=CDy|v5k}Wt+m$P-(Ksqw%hqG&P{G+%WPxL`5$BS=hvU!d&8_1-SgU-$$$AIZky@x zaa3a3jyeRTqf0$pW)55aDI*br?GTDV6V=0Iljoc#B>9=rDvTt5W$o|vJh2k;_o($h zJwwNLx22X|O=j8>*v^^p*jF>zt-4!QUp4#BA;yV#zL#UBtg=6x+u>(U=VpsPX@owU z?)2R&IvVhsjJ|tD^2h$sRd4}(F`wz7*<+8SaxRg1ovf z1oC6;8C!_R`C>Qlg!FmWXOgi7!Pcj>6vuG<$jhBr8A?GfBpTWJ{ebuL=d(yjX_)tE zcj}NC>PjGPHN=ayC79^Zxkrc{$dFM)DkkwXG` zk-5<5^_`T&Y{0OeLPtP2Q}WjLq&V@Iw{%J}kZqchvfs^kDO`?JiUh+go|Fs>jPHM? zC7R~;An_u{`djR2o?WqCX*ngEZU6){xA8**pmbIc(YpZfnu5fYY7E&$);jwRb~GOO zI;j@>5*EGb@y&EX*`#&c?qxIX2!{Ep}h49#iMlnIHi`?d!Vua)yb=QBA>f+wWQAIkr^ zPH-hwrs1EtdPg`|nD2i@ZD3b>Y zBSNG2y3gz6jAe9#a*(_zPnLkbm4qlEG$G?DM*uHj=`}MklUdWJ0$dA!PK9pB$C1g0 z$|0A*MsMi&&hdQB4_U5YN-IXQJ!!U?`c^{x7gSy}=Yk`%x!B}-sQop))xEi=U;)m* z7idNt;W0?dO>Ov7O6D0)ac0WU9hcn%+~xgSCLa9GisgUmtYguC=qwOkg#TXgw+Qxw znsY&oy1f~No_n&w$s&vf3QQ9}wJk+z%N`glWNH?W97nJ|6!~hCcS;Kheqvn$i|^ZZ zSXFQD=AYK8lQZU71YG|4SV^C3*`xi5K)dA5rRfLNCgV1LAfqLWr_BDCZ{lGGnGV_( zlS;2meM(D+RX?dwi?(a3O44|WZZ5xeH06Q8!J}aecEzG?|3?~?R*Bs|tMYz!Rfmg6 z4+*6a-F#{l0G7xUB43vh3~$V6R*bE(ZOyp`gkFWZnr1OcR&mM>^hvEhBOG)f_e5m# zdsH}lEq=7?3dzWKO7?K`dC)A&7os7bsP%!9Zd}b5Q-`SHx_Qv_>r`Ti_1iFjPmOr z+u5^vXTEfel?d+7%k&4;Giy?i*(*Q;4y5q2G6Yq$ph|eHN%gJ->QIQys_XT*eh6qe zEWs716bdl`UO!IPJ(QG8(jQ-J*8RTGghwC>qe2(yQy%lP%{WFoTke_xn0{LkXqm*b z$ixE}sML%(`_*N*5|Y&TWQ~h_ss^Rn9A?Xz*2TTk3}(a3q72oUMj0v-pqR}}(E`xp zzU<{E%Kh-okX)Z4_yHD#K_3Q8Iz{d?@YBm}^X=TkW*On)c|N?Wju= zKG>fWQvsNbiQ*o&#R9K(UptX$0hTW6-t@|Ag*6qac1c>%icPxFebyePW_78qj9KWR zEatIvgef3c?(g=}p&BeaBd7w8A!x7tha6e8X#~8sNzKvCBXosKnY;^;VR~&ZpKbVW zeX4|@`CaA0-l*&(@!S*QVs|9gGo?|rMr!dUb!lx zZJVuc{h_(Ew-VmSzZ>*AZaPqJGzIkPbRgrI10&w<;IuZ$;fddqtGfC?QIg^1idtX~ zB-tiyw7~Hj)#d)ke6)5(ilP`O$A*6v)!8kQloibCOe&J~@v+nq-;((Pxy7UY{kpA^ z`u7zmIHxUv53q@+SkTn>sW=k=u+qT~>b0f}VGG>Mr<(mXMl5+qvI)_Gw2EEQuo)(pG%G%LD%?t7R7OQHH$Bk51~Hid zzm5{7!@^*OpHs17d(Ib@^P2M;zMAe#=F6mGcdyfiJI`>BD=X4Iut>n?O)6ci*21P z*XqaL9in?fBy+*%wi~kjj!lbKv5m|LdvBkd$P>Ijx6Dltw*RnX+qxobeDA3=fNz>m zH;u$4rHI`Y_gx@wWYlpRXNHN21+JyZjwST~O}BaF*Vtl#BZn!sU97UKV@*)WwG}qg zP0gyx^?DKl{n~nXL2cZ@`SR;GV=iY0wvu!->zFhYkMw;mHA9E1mGX}Ozg~Vv_>{Bc z3|#qq4T}IAYd5yR>>(lNY`6@X7&kJ$^@%7YmF(QZh|QM2dmIjE$?!aVYfcFEIM?#K z%T|iNbB~|HsCPHw^md_BL0OzJ4doRx&Hq4W5)}g!x8AcS*%0ix7T_d!(O9IUcFpsO zPActcJVLexsg(jHwPKF>4?uj!;1!k~{c^Ib^BXu3-gDftm*l(-T zP&En&Gr4Mz`I&#scPx+GVBJ^&7KqbPt-OkoiM2z-fXHZ2J>Fm2Gl8eyBC0e%JJ_Q@ z5Y{osNY%R0jI-PpLWRLc+V0j*Jt3fVn)Th)hH$G?U}Qz2isiR6rak?NN*t(fTw)(f zA*K_*uPq|vvjGoTotV$1{OqAo-pr9)nu=WvO~m$j^vvfRoqP53TJ`*sWOP9d78P=u zxrpYC?-Bs`*|{iR`1KB!aaNF(B5tMhm;-w}f{qv3ZZ11#<~U@wwK<9Pu+6Lcb^_bu zy6o456N(YgY5M9?AZZJbvu3;Z=`>^y^GYOC^8Ntep3t(Ez2F;kuUgiY+IGtOammGN zUm7fzUAqmh_V`_=iFmQU8zMcXXMEazFc0c>R;g6E#(Y`Xg=|*IaVyUw--HzdoOX3? zvYu*_y5A^#-mK_KyxVhR*Vr~oT5#ZY&3MMb7VB%L2B}@^GH*$E%oCvQlG*4XKwxn{ z7$!`}+>jl+qYD&boYu!Y4I;8@b_x$K@rR0caR(ec3DQ>YucKaiR34~JqFMM$qbGOq z*4odO#?KuX=Ff05)D8|9TJ8fHo$)F3666T-dBNnY%+b|> z;Strrq*1h5l?FJp1M|IWL+~WgMag{ixY=bFdMTNzwH>ZbEvE={*O0SrY*#MzyJyqU z(_5LN{(yi1?W7=3p`T_RaefnRu_c5#3HB*+&46;69@D+?XkZn=I6=20^HJpBq?u`k z!He#)0)GXqsnZ=BQ&p6v-_f7GlBCVV^=PzhdEs9BU?g3Y3gkrC z-k{Dy>GOgPz{o^ku+i4u7_}vmzRg*#k0GAcsMsZ%lH)DY}Q__n6`5wsMwLR(}yzO?X(x2 z3NzASiL#kB*VDUOnd4D~Z|BlFr!V_=N33xvMefheTSUd_*@iwajZXh~R6d9C;?MB` zS0V~{7QH&MjbOt4qfg!$@dzr>fEC8i%|Y_JIW3qgCz4w7zn4_(|KIy=J>rt2{aNZ? zFJ5toF$#~HQX+JXk9NP%YXpoJ94S{Ki^EOSm5YrK`Lpt1+|Gc^2b~6pY$kH<}_nc@nBLq|-L7sWx< z@mFct*j8I!b?!$_i}UndDXKSM1k$DJ^RTMw)4Nt=51qVr_WM6y`Z)dmNMh`)$k|o> zt=1jN>{Om>zl&<~_=Mk_S8ROby#kMDxt1neaos5w&hll?j}6X)M3waLc8TSyFFtEN z$god_mhSi#X#t8hKfH_(&K0Kw4vNuTMNO3@_)Vs2&DLhex>$Cs zXxf_mZB#VVRH3IM{3#=wkZRc9y%6N#3d1%V0BWCllj1Sr$Sb)!OvCmF%XtD{fwM@@ zwIHNwx5L>H0$<{?1D)Eezp1yYFo@qlL}&pqM!-7rOos*wlnxeCXR3%*FYOI3%Z4bv zrko)79Bgl&qCS(Co9P_}Gi(k?Qh^M7**LvAFTU~igz1~7+B)Wpy3Gq1Rxt061tlhT zv8!4P0=)Ztt)3ULkN-R>at}?xFfufK;cpPU`vqk3Q!P^&si#{JhTn-F_4mtWmtr;U zG1EBEG41l^yM*S3;bwx=snYl!(HyMQNm=3cqcBpU*e^Ago9;bQG z5^cB0)I`$SGuiPj0#D}YGWU$RBzO5p4Eil+Z)Xq)bE)2SSlRP}dt|WcXeAq~w!~y| z(f)uYGe+j*vpiGKV}Hu79mF>ZOqMq!uM*#>DQZuNr=OskU$N4lK^vv17dEu>vcoB{ zSZ8QvTFRrl@cvKC;@FAJ;RTk#Rz=7&=*zl1R`z?0O;ud*Ia5iXQ~Flg4Qx<_JZ+qt z%h?0?MylVjnbXu##n-d0IVoXLt#^gZ;M>lt5f+nV3*I19o|IxgcW2Wb1I!I~+H6%qhIxApjh|3#HP_01Rm zP7LqNrh~tGHKwX2vnazk|MgUDtrntp&yo*A+bx_Ze8l5tW-H83(@xCLMVD0>sb~!L zn~OV8<|kEXWbhP23_bR)2)-ZKX*ZVsPia#|mWVmr5|Rka<|-Z02}fy>UiyP^pj$?keN5wuCi=(Bf* zz|;zjj)!$V1=60E0Bl(V1IVNh&WuKiFA6%E_|hxpiuLA|=PuR3@+w5tn%pMbXxxb%|uC8M8v>o2DxJ}lCc+MOTn1+Ts ztq(TiiAO3fZalU9rFbqaWnUGf2Rpe+av zt!GH~&~+_)&b_*5m7*%Oj;j%d=ADim?xqc*BD2?bB+X~Lnh8|TH48c)`-d{WwEIsB z!GFuRAOk1HAQU84#L!TGbtr?k*|&g&{laWp)|8NRkE~?!6G(2=*T&^=(InsPgz9+Izr!o#V{Q}4Eer43LMbftUqySfZh0aRBm#l}=_IRTl(LRhx?tTEw_rdPh1S(?Hvq>ab%jUZsWhEF3#F#hX+h()ScNzL#fa)uFwkfk=hszb zrU>j{a_Tw%qU9mEvl!d{q!;@lvBAMW zHi%0lano9aeR2AB(F{J#%*l8^zkyZ*kJdjVhrC)i6Q-{?l#_YVu%4OD*=F=O| zq(pNfmSB$g&;b4Vo64o@^Dy~{6gsmwEBdKxz}lmW`el1$K{+UH2w?Scs?g=UpXs@# zSkQ(MS)pTzo8DVoT!fieTi_}e_X-(y=)F?BKi06X0kBjN=~J?RbiNp+EvGjO<5~AX zVoIHQ?h!q>>P-I_p^`611N0en6EC6vBp!JOg}I<38Y~34HI)u%L9UwpR<^a=zRxadxNo~_$8gsv#lpqPT--^vO`+f7%6RD#*!axLvW3V`8jIi zM%1yzT4`>;zmvl0M`Q&hF$-Ss+7;OQ36;e=?_!;2hYfF7fdwK3*~LY6*9cM+hI|L8 zv>7Jz8h4&Oh@Uq??}1?EhR^j7LjN0!CZ}pYsUzm;J~gEW>{v;y8!z(MMfJ9QeZ=_b zQ)wvAG?`Hzv2$uMvmcqb_Dot8@8@}_>T#F-Hsa1R0*FxSWW?)kPbmi);iy<|Nl&a7 z<=9}26e;*lTy2^vFCf7-(fC3QXJF5BRa2uwI2F6ek0nUI>M{((?PN`33WZ3_bJXm zMIZz>X<3yZj;YBhx}kI@m3oA(bXbd~M8QQC3{kv@Y+Lq6BdX15s35-ZT8lp|MkC>> zXH>=1YLg3dF*YAf9#72v4?Qc@Jo}U11nqq5+d(yDbW;u)ghQUy>(vH-k9<&keUhd{ z!x{aaZe8`)-<17g65H4ck(`A5?2w>uwfHD%g?x_`fX{rqsblGQdCPF}psmaBk>F2G z51I#6ni(g_h`h@5@`Pl-pvDDZks|~EAi^JFy^(H;YnXB^XU3a8=Hz*K-u`+%urebg zv1Thv9PoM<25Xxs*(k@JK+(6izl5@zqd{90>Du~~!YYBS+*r~nrD zj7u-JHmtghopU1ctPht1(&Q zhPrQ@cDN0iVO(fhPvmXJx!k>QnpS+8JtC=N+vokC%GW7X2Xx z^oB-!AEs-ytuu05+CIOr{TNHMWI{UTj=bTwJdYM1h0S#Ho08&Et9fHnO?dq)O7=M< zaa3`*+@fg;>CU-#Aeix{z31RS@Tl@Hs5^9M^fTW;p;q56+Fe-INRUyUetW!8mBe9J zS%qREx&M;WHCfb`MeS7w`|*pgYcg6RN7HGRwI!^b;(pDFMdHuI#Jpn;SDTvoz1a)rR$@GO4S(JjxA8yKSiBO-_4JsYx^Krm%}iv#qTw<+N${ z;P(F?WN#=If1@Ye=IdCLX>t44opZyDaIYl?RTAI7HDzE6sUojQIIjsBjtWMswK(wR zkF`m486_?N3@{m$MYrPU>#bVhR=-DU*zxAlGza%WBdY#a4#SU$YPD3nH&lE(hNI<> z8(TDDm$i0PC)FnW-05NnLhc>C8aKYmq!7%u-Q#DsG}Y_Qi@4p=J=Gg6=Y*Q~!1$1* zA?qIR*G@P`f~u`q;R|M!Q}8-`qo-&q5|EiT&La->?;&$66KH?>UF$zfxiOL!HpqLt zQhTYq1>QPPY+T|k(l|J5ITAd+nEvFE(Axa*T1el0OVo8^#dd-F6xn_%FFx+-4G#Yi z>Trjzbg-~zLpQ8G%WrU&_2dh9>8F(;;ELh&Vrg9+rPMs!nr9exR5=+NX)usI-zivZ zzdg@YvO70HgViP4?^>r`sSD`Mc}slfVi-ZQ>`|+Y$j${*9I>`s9sQj2OY06^(ysp( zEI<^HiYb#VzSTOoK7s%nM4&7q%SCv#rq#jMXttpUG?w9{BpgY^63a=J%v+avPKsfl zDdc|^snEdhjo0(fP04G6p7dGf2kp@%_E6+-fT^1X*Sht3MV^eofz0cF4cLr5d1f%- zI|p?v{1^nTOK)&H5o$Zd>&3eaI#N)Bp!Aem&Nx`dBjU=i?*eIcnj82&Xr zDH;%fn5%Y4u~>IkSey=dzcAyL>rYj66rAq%8B`fj{jKnqP}I_64wFib&LNmN3T-~S zcbGMtCC<^=ZL7ioI~J~ed}Te+!~S@KkDab@C1tN? z5zjQzxLQl9v-c=k`8b>(vX;;NT1ha?lkQnV|I)j@m$Xc8`UdKObL47*!1K05tBC1* zI*fIZW$?L8LZT$mJT8NMEAXg&mW58bmFR)^kzlfEMKwIWOk6jnN{M{Us=frgfBS-x zjY3R0$Tgx-k8Kct0+RXtpI!h0omD+`gpNsHx@{mqAnjn@N(0x4Z?NJ$TLVV=>%IAK z7GmNod7rz;_BloKu_haFW?Orc;?A~}E@D2C+OgMN9c5QH-&HgQ&~-S{*$pW;J+con zHEU-_t$_><=_Y^tQ*MzboHD?aalhCOC^l$+Du>tx;5qLFcYA9bhwmB1hgT7%d}v&2 zqAA$B8-rNt86SZGqN_QzgQs!Tc|(HnHs)qplpPTT$LvD67S>AsH)mtGk)A4#n^UQA z+l8K0gf$K5%={_+E7ukQ!E)W#DH%9mak%LCrlq7Pey2Q6$~YUZz0=pNSg%b3kGYA; z7k;d5n7;8W?|lUMkr8hZ}AUrsYFVao%VOowO&=O^ z$&waFY5t$%UtBg&j0|9xR)GN1MiA(ppAk+Uz#D1A=u5*=y z5=@%9945m^jS!cXrl4zw?7z}_Et~z78KOhd%uH|*g138OPEF>J7sPL3a!WMd5+}U6 zh|Jvdrc1Fj7^;znX~j9g3#|ncjKr&^yAce}Tkc33h9G^@ za9rf)ahH*f_{g2oV`<=NH@(jVZV)@IGKUX2${Dm-+Y-k=Xh*>ZU+ zgAdWRV_(5Rqxra^cx$m#|9E9TZ*`?5jpz|TZpPCQo?lmT)zyZuUM$LxxzQg~1!PJ) zy=*qD-4=!%6>>i$f}Oq!=pNMY`y0z5Huv9>D6W}sT(24{C>%Q2_$4=W4TwgJDG|7b zDAv!8XfP6N7M0H_2-~%r{nD&UUJy<*#{Q9!wukjLiKWO%%2#QIA*Zm{m-yVl0|u@ll%AJm)!UpwnN(1kFE z;>6{wCoH0L@s?h0E$ws7nLRx!b#E+m3z6BAd;IFXUDXKMx`_|ZMxf@G|C1@?kD&H@ z(b;c$0eJ`Wc|{fP&N$EggE9;r11z`$P1a?ov2ts|=RX<9v3e+wgcaJT*NH(8T3oAA zNb@xdI5;qNi_+?dga_15rXND4c`rTQv-lt6;r{O6G4Gfz)bjLeb5iSJ#>cnD2m33v zd^KUn+|0^3xnW-yKiN0UykL1jG=hxdy6v)L`g(9#XR;l!r@!x_fPx5m`n!xk6?kyI zXxNCh&_FGOiw}@#?~hIX$#fPHJcj{yBdMV&{xe=w0)Ag#uHPVlgTn!_<7;GrlANf! zYplZVru3eBmekTbf}VzK(y77UOh@^LJ@|y!1^=ciWt5a^TKckf+2U)pl1N5iu6*e zdOVW@WevvF^r%Ac>IwUm{0WN{#UC24V&EQ68F-06^%yecz-hq5=ehOG2G0iP&BE#z zU*yjD-f3&A<$6teS2OR<=&h2{n#i*f6In3eyxV_x&PVzysqcd+*vLs!o#`+NrWmfW z!S@ViF@CHUoK_!0M5|!HB8-aW(rXYNz1p-{r|XM#P1lG&*~pMTo=q&yhYXB&O5D*U zJ|9SkfnXRc>w%?PbYC63Ot%gbC&^*3QGC!-Z`K~|glGvEecpm{K{y>eIAqK~^EJrx z@{gZ?P>R7z_hP6(1u^(`uFqO|o2SnsLrF9T!}3^dWqn?RSM`78(;c;bAh#p{Rf0`~ zrpUeaePWkLjNJc8UGhlpfi`r4%5RX+jh417yLtzHdV|FrLgUL~o83qi9ILz1mg4>#UX)q_+I1>9En*GQ|mhBVA%Z( zyI#PPW35DHdSGR|-NtBaf+-JtOoGy{)mDqLyao(;OT6G-Iu^ua( zy)FZIkeH#;YG7rZUEb)og*>X>p6$h^&Fj~tGZ9}gP~}|@VA~^Q*B3IGMe>jm%`qfl zM}EU`Bsqc*d}WY`c@~k!>*#d}PvM^yQ22ILCNo3>L&?(c&dqBhlAn1+;00eb&-H6v z&Oa`_wmWh&S8C!qi@L7$@pR#%w?~(dlW*90EDHM+`=4flNB9V>mmm@Bj8)M?6$Z5B zw589+t5c1n@QjYdUxu-IbPdk?r|NSH!|Ms!A)_B>(&v1SGTFW*AWei)ZKINM2a}T_ zk(o_pqWJYMX_O%G}T*FKrZg{2sJCq7qQAFkBbQv={spi#EJy_n`GB?RR+@oXfHvlDYyq< z&TQcvf9}e<*e)JmrVZ?zLBk3={(Uzrph1QeIOZQ$(M%-|(;6%Gd8-T9qKAU`;)%G7 z&iHW>;BmcE6D-~#xz=(US8BxlwwQyOie|vRQ3aWjN$fuu4nD8mAPX@D5frj*Ld4r) zcVYG`))#S_H(qgUxiq$Ts{lVT2*jSld;MS0cTM!wL_9C(AH1LAWJ^}W4%#XUF+&&h z(8PiM1%vK(=;IBwrYs$H;PdxOVV??DD@&8$J*A}nJJA@>=HP1mpIm558JQuhqlK^P zyH*`q1n`&WZ;7811l0>(24Vw7@GSy1u%AW3TTF!EzeN@%Rt+IVEg2q$2>f#AI1h?Am5ZVxMi&!ZxJ>pa3dAFti z@*7unAxV4Pz1qVHJ+W| zoZd_Lp(#|_O2!E*2Iv{~G&VT_!Yke<#k8(vvGJAx2b9|o0^acoOK^bYu&h*}txSHf2**!GG+iS`a>91rZfws=+LwmbUT)IZ;lZ&? z?R8bVqE^6rT7oS#ejizrMe=;=4b{oDI4}0i>K?b>ef~5!1&5^Vi6IgS zF65IEUxoiD!qzgMj2Jyys;*A|#`@1-TJW~Xt8eD`$S{>iiu&~cI^3j4w`cf=3r;uR zeV7zK7x8}?9zNH~n$TT_n}yyN9+2ICrA-739{rIxDb1yJ{ScE2=Z;lc-m`-GX3<=2 zO~7-XMeR`+8Mgr*?D5u|nu|H0(F(C%oQ3*+Mr>fiX7Lop~?Fqeg`GJaQYP4?Bl0}&s^r2l}L)Vf1X96N{iH*{hZ<6|Cn zi8a|{gPi)i6*?vYIggBLo_N%8{NzBgAmHmw$09rp)(J-e;E8dsk8%HrGl6v&#wH1X2%e7^comm&N-bWd0BY`#8SDb)*IW(vl zT2lj^~l)ff;=wwbzw$?ZyN{`xKb9u1<}2;D#NB61i-q$GNH1%JN&Sws8Kih1n3 zk?eqM{QzPpeAbxZn0?K)SWEbSVdL5PbuP-ui zf`+|k3}^p~KM~J>?vFsX5%}O+n1LLcmvgvY-Yly9{jh|tN*dL#STFaxo0^*bJh2!3 zH8oXIRAh9GW;5rkQ^Gi?HCcnN@#MaS)_#;$0W+!cHLdUB-S;(Fg4Zwx$VlKQ7%qz93OeSkC)xZp}flqu};55l(6i1Ub_=5Jdbd`sI$C#Zf`nbvviG4k_xV zjfY=$O7<0Q?9WNYa1kHgOkQ++{YmeDN<7<}XH_48k$wvUHeJ5=4e&Mu68?I`Uq_~(PC@+xLaK~Y-G{Nm022JQQ=h?F$uvb>-UNtgkErUohM3df};v9)doGdPc$}9 zObaga5f4MKh~jlVulL?-^9yffm|q0T3=5t4GZ^a7{O&^mGnT_Ax-t7y`htA~nE1-` zi0#9v3gTJ%by-F9&=0z*1zc|<8tMdPAL5J9b2;E_EsTW@_Vlx;7-((nMB(Ge|k;ShiOXHr_+aw6a8#21|b zV;-s9Zi3#B=tKyefn=}LdYiXwFoX)ylBw^44piCV*M#YNQub%gmLnJ(@A6ddwMRtF z6bL>i5RM^0)P*))abO%G4eBWM1U?bCJudDDQ3RYl9oZd!*-)Bth4ot8_$EQ1IvvI} z)S3z)AH?~R6>x${FgaQy92&E9YT(GqWHljs#->Z0V5`-Fh@db*DfD~i_DwBhbJe=g z6Gp@eZ_s$xb-++GVSes=Jc*QrjCrXQ8XM-pEY784LZo{#jycC0L@c_rSP@{{6X=mF z78k!{lRvzFh5b&Rg1{{~JXmWfj!C#DTvjfi_CQe#n?I76(FELs(eWN>LE-v}^d(8w z{z@Mx@p|;lVfHsJW;o;AbV%!CAW3hjRX0_4$?j8*H&MjU}pXRS5@uAg~#5hXFC%#Mx~O z4C0?lsY`t>LCP*?|CddMxOmo7Cz$&09h73zgUg9oM^2eceyDvZ$%O$GVZnp=#tPa| zp$~x7c0k;1(AF_J zeN((kBG%k){7e}KZ8syWpW}er()bH*vYSGRTxjCmnhKYxUPIA_A!L!T5K zRIMhk-QmQ#kl!9$LNN47V@(Y-wQDSofc`|2$18-IaVLGNf|P zyxcj#fmnh)d_vWpWUCxuNi2;98m_0r+io@7wft(|$g_5?pJW^tCk!VR5N~66D$5(_ zZvjNlFXTU`ETsmGNOas|vd4&XM|xTe;p$%-9od{j9ugX}TUV?!IUTmsL(GYTI~2wp zs7>dA+~<$s-T6M7S{UlS4>ikiz|Xj#ZQ)awOF*)|La0D2U_y7tkiKp@>a=_>Cb!_Z zK^|3{TJ7N}gKxv;605Tzb}9_FE`g9fFlW5Zt3L0(3QBE(o8R2Y9`s&o%n?e^{s~rC z-LzZI<-apUzN=Am6wn{oUkkT@tt0_bRgaM`C@>vo`N0b)hOhEe=)Wt`2x1-V%jCc+ zoS3Db_V$zfiHknPhSYJqJ(@&yivU(FD^WU5-7qzH!97)EkwE$R?mlBfzsNKWxtt-&CqO2EwX>GKPAE>6d@K9(aP6msjO@F6)xllLVA6kYj}b z4e8f~-`+0FZ!uL7o=h=fl~(De!Wz?P2`bp2@o0hMrkBFe#$A(E^Fw#m04 z@8K7FTAOM^cRC-Fc{hqTRM+dN%c;?fIe?49;WwAQ6NP`q*P*K?!u4rBEEzU!p5Y-+ zrY(mXMuoSHb|XBX_2_k<)e-NKPMV}bo3$!-(N$bLJc|GPM@S+v#yguEhH<08W|bP} zWMC`X(2XWpcJ*~i8^e~dPWJCZ=MFP_y0qU0Q}cK`iz0rSe(Ia)I z__`BuPWeRR9588w`N$ZOl-a^1a~NZ`4#YBMpyv0(0x2D!6{4vY2$J>nKk~poPjU^B zt#{~o85?|icTkY7b?Wo}0)hwYsXTUR>sS%+&4S0_uptVL7;9Yzy*}9!#Xuocj-KDN zCx(_wXtS{2Ge4tzE<${)Szl}x@yY}9^_1joBTfVNU=F8zz*358Obqb$xo=#_EkPD4 z&lmC`xZc^pF8Me5%TTJ(MfxG@$`JVVU+3eOV_5n4N(YL^Y7I-ss)W6x5q8~Tu zv(U@e;|2N&8`)&TNHq}&&ga(!&K-pTxp7RN^VnMN8R21x-I0@NNWv|TLtp_D5z`_Z(t*F`V^#o-@1b#%2I0nCw!g4A*ncN&Y1u zv5VWkxe)ZbTkfCOshs8?-bkf5tdb}`t`o#=DvUr#&oNINH8l6GOIPvzeOua*zi>~r z9%s-Z>61nH72nKhmA405Z+!bS`0$750o)bZPB2reNc_ptJzCS}@2#S59B&w&x*~9=`P$sQwd1(7OUt70L0xiO(vChS`Fl$; z_T(Q$2y*dKNIMokb!WbY3WW-N6#_#0mcPrOH1h!*C&qqX{a9xw879PE6iyTIrctRJ zwQ7?oQ6x~LfD{%OCM5DOY6|#ylwG}U?YJ72T&6!(r4yQu!2TPupc0uU`IoBKj#CU;wL+PE+1J4SxEWU5Rg;d6z@~kXF@rO7 zqPA>K^%OC70g}c1t6iZYks|Ouy}md|B;*rpzCHSFTT8AV6<*fA!DlY=t;)mkOi0`{ z2Yz#0Ws){oR4mM!e_C6wl>b^{z8$Jf&QWdT0ugpjZJp>UYpq-U335dBjI-3TC_5^d z0JTV1bIdm)nH?((9MtyMzS_;WcZlukO60j4s=Wx&D`)tU?jBCp`42W z*Dw{N9fpGNWE8HhN4E%qk0TbeFclW>iGdRoi<}wzufCjZRwS8-Q(-D5ect*yk=`y= ztAhq4-h>4ueBQF5S^YEB#0FPIU;2>xYIm_*e6U?Me(Wa4lt{4a#LX~@ndTg&7}RpQ ze}oNtuxHx(v>2;-b{8BvI)>EVpu}tk+N1o|WiD1Sc=<8>AbFdP&6W6AXHj*t?3C!5 zgVkyMwf4m5b_2b$Y2JKc*-H}b!@DBWb#KtX%Cnwq$RyB~9kz6MC!_Yomff3XAch#9 z*!=Fui|ndpC>$~-VqeUVdhrLzfQ-Oe8kdr z(s|Q)gIdIHwx9FIwK;T958IE@iY)FQ`0WUyDsU)aT8cB~gDK>%9pRO1=h?ES$(|Ea zDW+j@Gbc3OyrMp|kzC}F@8^g*MyI?eHW{_f2%gAq>D#lT9m#G1R&kbF5z0Kyy>C<^;8J*6b z^9##x(&eGXW|LR@1E5no&c5E*x+=BnFk{8I-|uXiD#OZyv!{=u?B`AMEe|cI|+3gO&-^>h(1y$^Faj(C~654kuhIi#XR*B@C#$7A$){aOcLAxM&NO)KsU^rbGPe!LdDbiH;2#X zY-o>|=sHf+_m3?Ghf*i|;^4LcP%FhzK(R>B*?6n3-bdX@OGlBZhrUX@*tZe8yyHfw7=q zU)%V!wBirja=bEDJnlDS+b6&jm-N&X1tQ6ySa4ctH$ixr?liP}W-h?^K(7M(7B7g7 zVyf8h1~xn5GWCfWB%qp&$QwN#raiQ?mGdZ{!ImcL%M$Lw)RP|l!$W_ainywu^y~*;CquY>UD{9r8fR~%w?-ndRp3T3P$&jPA+}F z`U-$VvMTcl^~{0E6u}Rp2@30|%vA(~U0RvWD!n zU?z6S$Ry@O{Z1R|;Cjz;3-@lzpyF^oWjfVQo>~&4{_JrfRqR=OywZv?tZkLM0;Y@LFqDhxy-*<08^Rr3iMrX`T zj5!VoYFsM&X%iNV82cU5_=OtOkRf6LXv0`)moZTni0pNYBI|r{)VQhxU1znmi1~`Z zf~1BB?j$R^aIgFIp%}BZT9DQ#$y*ghTGy|>vVi2$f_c+$R`^Q#U!-0W;PDk1rEAK; zlN?DhM4?v!5-x8bDHoI{_7;HiIzr$)lGdS&NCr+@qT)7&&J z-vWWB9(pd;5?&J{%lJ=27k|RYalv-MJ~?)nGYB7?XDy8^A!R?P1cnF_ABel;Z^v0P z5ETCpU+)+l>DIOXraN|boQ`cf9ot5CY}>YN+qP}Hl8$ZLI<@z+_xql6{?9pMt#$j+Txtrq$$8?L_p7B-_ano>G;eY4&o`S7 zrwP%AdhgHnx99%&3`zB#y1?ZUGUAxN!a{t^7>#?)&(5vteidDj zL~TD(yATCwsaX*tY6bmuv{HJIek8b1w2I*IqesD+uIPGrh`Z+?-|}{I2|?~wFIetO zPCZ2jpWvz&37%&i^q&v7`BT~a*UnwTk5-w(^S|&PMJ+a3Ba4lGFE^UMC1(GlxCKRo zrD6R?a;bi!NW3`fT?%>FQ$+W^zupaiQS4HR1 zq9B|j9f*W#mWkHAhw*Unq)WW&imahDDn0^GWxAbRg=iXO)>*tFDUmmuf3on`fAouk z?G_3CaRka2Oe+{UpDbzS1%ZRQJtki)n#;gwxsGKZETiH#Tm&w#2-`x~|0#l7wV#~f zu)KOKAx$V*Or-K<{yp}-{IULNS+&L7@Qb^4=?5bs`9FJk(`A-O&ZtsDTx1`1?fy0z z+EKGaTxurQ#(BHJd3N7{X>KVbzyn#_(kRdPDa7e}aTfZZ96Qwm^|AvNVO)3u}!?WDY{#0+NI*gk3YMFz97B!t0IXXwU# z*87DT!5e*p2dl~Q5x~`VQVKH~NGQzf#(JIEJ$ic9r&=Ez|5H-5+J-g^Qac;cPyp#$ z8JqzpO&E{5(zmvn%U4XtE=UTEdf$eiVbf;NIM8k-k@xZRBaX|q{BB06%mm@C*$@UQ z)WG`CvNHb!Heu&qjrvtJH)8Unlx2fsf7|;37t9rjNvK1K$>_+8K24>L4V)O{@Z&`e zB@1M{DQ)vqC$zIVcTyQpskA^YT{t#sw4~@bzUa0cRH*%ku_>H3lZtCnw0F<^FoumI z_E%%t(w_M*dN$1H&UkwtLXK#2QZl4+m7G6@Ht!u=DCdn!LZV}fLE2{dMQ`-(&K>>R zls`EE0%%h+U(|MBBtigXAaq~wwr&H^30d{)OT>RS#I;}mQ+Z%Q0JsCW%j6XCepoj^ z#fbS*7m(-cnSZT@KwwxwN=4^@%Yb<#bsKu&bN`bhfx>kl;uX46Y{3X+D3O?~gfBKc zx8$3*G-hY4phxZ}B$l`6xj4>mDwW_1)1N}YN2)hw>ia~mb z0OsIP-k!9SBoMnUI5`ox@J`+vyQ2)N(>jE!Zz`3|zADh*yk-sB=BkUbKiV5L`*sv| z=b1zzv`+h$A84MGLm*yzwIQ#b-A}mLv3$u+9a7C6+~9pNd{<8A&|ea}Xj|W-AX#Hk zFXgeo-4>&p+n#i&0Qv)CMJqZsMEz-I&HvSv^_!O^=T7{tSy^Y@-6R5w)z&~1@JrTx znezL;-&E0U#DnGPZo%;#8FOZo#Z0WVMBcau*dbJK_^ovv8yg$3tlsDQ z2L}qOs?LK`?P{0LEr3z|DY@BCM}e>15*X#_aw#TdSYCZijt?)tbm+f*s2Xg>bb|Tg#|J(Je$ph52WhYgkj4|lk3vC!g87508g5WOj5tmc#eaX%j^QImg3u$m zqwej!66(Y4>XafCC51(T0)yPKxk`(D6&|D^I!7E8YtAx(JLoc+(9ohx}q>@R2t zC*yW#R~7oi>(D_LAP>w zgm2Bfp+X$WyJyMI!W9~nHQCkC!YT14eCGZZQid0F9Kspub#w9HnK5j-yMz|ACQ<+pvqDAyb~mZU+8Rncq^ zd+z@jy4NA5h4rIy_L)fx{~O4j|8sh;8~Zm3*x196z3;6aIa#4zRlVw9L3{f;HuTlw zA!9$~pN;T4h&*TmvP^3_;Kd=Ab+|;winy>Jj_g7G6Mwf{B*DK6WL#2m zHL^d#@tNhH?MQ#sil=NWIy~xnA0ZVbz>|Vb=$J1>i}&UcS{6){SY(m&fm;zQ7z_aw zG_FMcEB0MJTXlOkX#P2%d`~x`GFCKF*cG^iob(J&s=!e}K;Wv*mtn9JK^biUUtBNKsu|6Ch^r?sE<5*?T<+#8LXdx(Ujl`zs?1EAdB#txc?GQ2 zS)EdcyD4+k)}4`a9o2=XWUj=UM)DMyUbDFe&=2E7xo)BlYOtjK~jPBXM8^ zWgAP_ez#o1`SmRqt8qN#8gMA4A|;hFl{}sR*%Y5#9JZ3gzk=9ozm9Be|1O&?$Sd+o z)I&zsqo~UGLhv*ctIoE7IrUeYp*8(0+HQ=cEnD~48rjCdi*Zvtn`J~z)KkX)B(=k+ zc&T|)Dbsb}&%~#@IiJ`MD|S)X<%K`%;%aHrpFdCCU`S8ppQde_Ja}JuPrK%NQM$xm zs57{?avqT?i*TIBu~0U2px(FRZPX=ASK2X$#pq)3Vk0l|)nhsHRl%C)K8k;uE>;-~ zMTgT7GE>G~zA*vnqwS3VfL!NZ+0~vkWw}>{J-4kr9*7bn<_eTyIX#+kHiFi7K zONy{dHH<1BZWqqUhVxY+^L+iaU3=LT3_gS zFow2wWcWtedon#U?pF+k31*$@mNvB^Xz)N{#}p36TpS9UV*pqTg6#`i`VqhE8a!5N ztrl*SF*n&^7`~ zh-Zezw`sD*rFRggHRO#Dq@kM>`!zw@Ah`k3n2a=ujPg*3_N)QdO_7CNA9fm;LOfYP zOwFb%y8Aj8z1ze1n52NOh*?c`XN@XfM?za45RgoJ@@4pO&|$faILoI3umY|J&^*!y z8o&%ZS>3QU37b9?B{F3A1T&7c#Y0qyRGsGT7o%+;iEU&*#QwV7DT!_zZmIv7Y5 z!WG$_D-yc!b7=bHN{ZSmBE0xG9HA+GyX~3Tq;C#wL%~HhY}hGmS|4QeV{!s5(zEKr zm%2Zq#PL>ROm}L2W91NU zNWrp|WSqCq%3=Hg%YFDYzhIP@v0A)$(=>m5Hk@vxBnYNBe_=7xz>lAkYX z$N@6+M#aO78>Y~YZxOm}ia7|N7HD?Eg;dWZPxb!P##{V)C;sy8qYJIbw3cxS$O{GJ zLN)BrC(j;&$KISAr4&0#rja$RT6>!>tR{e5nlG(V)fZD!khvryQKtutel zlFi|S?x$L3j^knIU~STS4T#RejFt`xVvp0+5o-4%9!Pr3_cuL{177&$Q z9S;PMm=xqFP{Ft}Tg;-i8`|-Qgiah=x59-ASI)PS6>ius$u6BgvJ$ASnRxV z);c=wK161T{wKzPZA-MIG*wQRFh?!TAD^Fh8hqiDy}?$YO&7G&fRoTBBm3wG?rwe! z?R?m5Vd{e8bsOT%i?_>uGUII`3bIBu ztEjUiWI~AD-4q@2TUS9{3I;}D@`VQ@so{@N87O=X&Z8q6eAhfkVN9_Mw(PBAZuV(@ z6N%v;JMNzX?*3T`*3*LL_Q)71y19I$skO>~^4fqqs-SyjV-0j9G_w&x^RV3^Lpdk? zRg<|g_m~Z2EW?{f89B@Bdv2P{34E&9q4aHQk5c%ChC-KR!R6&^?8_JCfyu7OmZmG_ z?2g0&Q<)is1t>=NlL(|Zz|Z41(ZLjehrpc_WgDj9di$a5tvsf9r!LIl$BXZR1&h?lhNyda*4_@6oB0~C253|r`Uqy%h^g z>1-AP_%j6Q+tAC<0+tanIzu}(B4b$=WVT0Eq#fcnP(=}xk-bdz4;2aR6{Mmfwi&k* zIDS4JM~Zl4ng%77yfJn0vKRKsSgu(5>^t+frO#_;h~#t}3TXj=N0;0Nz&o8ng!ch> zjVG~5%;N{dBXy-%-qJh z#Fk}AIkwc;Y3A+c!)%VjxO^!ZQU-Gv%Eqs9_^R$PAFYtZ!$K$6G*dUbBUPP|;+mJU z%ZZ{Vj&5#alO-aO@xBg;xemTsm02A7af-DsjUk5uWScd(A{3NxK>ax7DQqbnlA9hLH5rj{w zW@Vi|SqK<5Gf7R6<@ACn~NLDS`)as~-+$wy+H_dnha+*WOT8N`; zTw-pP;L7{C$c}7l!Sc61qnfj@I)a)~FgJhuRF)BTs37v;0?_A>EN6#&NjTuicL`3p#K#|N2Z#nfEm>2-@ZVuWMSjZlT08&1y*ZzhV zG#xb+u~TC*+b7@BX2wVDh50NVoO`28i=s6Ty4qd^GtmAG-2BYph)Wbi*m9?Y!!x4i zRYb=^+0!K(XzlS5zz8%F|oq=Iri`pDs@QBHG-QDG4`tGXtA7 z-lv5lz2$Z0-D=cak}cL?ksx-nM1Fzz*OLP3n@Ev}-=*Xk(r2ZNih#WVWGr409uT?s zdK1jXbG#Zhp0<9OK(F3@14(0!+D$m0gP_-x)Vjp5Alx{sU*WkgUNYXCXOZmJ&?7Jx zTk7@Eaic%GkU%4>oy|MZ@I zG(ASP84#n3=cD4|;ga67}qeL2c-7gzS z2FwqUsLpPGO+1gjV^XqND!j-vM2F{;x%QGWOjqeFj9rO1WThM$y*l}5B}>wf@Cz8G zG_1wg4D2wh)IT9zJt2A#WXIJUQ9nBah-rMXgyOG}?ihms1`j`W^g%44kB16w5fwpT zXv$2-XN$#J+PQrqyR2AjF)?!mZzMyyOS~kp-s93*OkH!iFjzMZ@6;b=l90c zFYLE2;NZjMQK?0%v9CW3@TM?Yz>NM&7ebX|(xf1QM=eMwwy9wy% z4;H&jgy%9gu`8hV&>IFzF`=xQ@4XGpkg~O1=bYf;1)iMZInFyreq)EE=%HO*U!?A3 zaWz1#CMy+@W*Bgox4D9inkBFQ&}X`1y)zP3WUFad;1OfSm}gE|4D`)#u~FA7sPc^G z%7k1jPKVqX((Z%~x8mk7-^7>AC&gz0DAopMoiO<6Y>uVQMM`yFB1#>{A6+(WW2P7~ zs-;DIlrdNjlA0Cs2z~@T=De~$1Rdm>=Bf8ZWYc`T z58u2XaoJPZaAf^S!?8@cmqwhxHSEa54Q9@2ztdTF#X#GJU`^sU8SZfkam4$@r3EvAaZ#pb$=UT_0Q|n@!-pj+a6x{`B)SW@x$B6PO4pdfK4tlSKYoo+wKLv!1TL zsv)*h4Vp)6O#+T+EBqRFOP7<0g#o@7(CR#@cYc?!xU0a@`d=>Y40FBC>>Df|#W3$D zY^ifM7|NoRM49i2Xn$2@ z+FCzneKER|7CGK;PLXlKtTE`KGMyt@Wu{bvy8VVWH^p~_f(8FE0}GIp`G482LFF+C z|MTKsZ@o`_)j(JfD(?PujKhNk3`w?$& zXHy2zu-Wm0ztta!3pE`KH^1uC&*#sF+tx#gV5KLKQ(mFT@!+02?8RxUE=A!t=S_nl zY|SIt?0{7@3BbnY_MM5m;=jEBHd-IxBCq95diTq;lY=)|c~4b=+hINa#Q>?*F6jo= zC~w2K*gnAPY=6cRdGbVXmY}Dpz>mBU63amd#t2t(&q;@5tD>g02=DoLr6bi#Qgt`C ztHyz%!xpdDNLlTT2}4ilj=TVKue!JkRlMT&INFNzp`CWL-Q}jJM7#*P$`0>W)W<63HcEyg! z;2P~QSczcv_jKvI9I}fb;6Y_0!lJcS566_q4hiBk`3~AU*>8&BnzsXnwYF9AU#}>? zEzL`<--T-?60VnVi{?1+nhf^BoiS6b)h+&xyATH0~PTW zG!I_ejw)BYP3fKs$KDK~rojzky3Dw*GpFr$;F-cw{~`*Yo!zcK+&@ua{z+89HJ+yu zF6uLIo&*JM_%!kmju0$wM7t(Q?4&n{S7ceYy5@XQs-PSd(7;KNN6)iu3e>*d9a(9} zPIU3k_?cX#5^t^aXkN=@=)@{Lxpbc7H2IK<0NWB;r`XE zx7?aN;%xcb4*K`_B?*flq9<#?&7=|@3o;lA;DW&V83_s5@u@9Zf4wu*Y1L)Z_KW~( zi&4M4CZ>@&`d3eQQcK?bUIH~=`Sr|ZP4vrpH2{D}Trt#8m9i0!yHm#$I_o%F3-q_b z5`0vWY7ai9Nr4T*p0S5$uZPPws;8lFxNsiZigo>!jOBW zEZJ;=4u?%6{~I$9@s_JYWKn9BYbbDb(dm zb58>zyvKcwe*sL)&9Jz+@)f_UHpCu>hlO4*AC=X9ktb4*OO9bo6>f=kM zcH17MWUlwssY$uQrSsptH=P)LKH{ep?qdzN+KBc$12Dr=l0DGETZ2dspSeftahLmK zt!DBi=X$*@_8|~|Idcyxx>v^3rVMAdgy(5+a}uXfIbDxQx|iaLCds^NM_v{zPqYmDQs zYCA?#WGZF(&Rmw`wSD#kLG7dJ208kxh$fayF}f<&Sf)nZRnc)^-6CWQgX4r zw3%}HBC+BTQ@-s?NbGbMR*++7Qc6kzD@H^^{I^TGa~N`ec%=4!vZ8=b)4LCL-n}_7 zb?O(6g5MT`zD_kR5dl0t+?SZMXK%C=Q6uA}COREyVGGd8$|mOLo#7oQRlDk<+O;XR zVi&Xhk}tLs$BrPcb=E(>u1b`fs-jdXtDY-n^n;>pS>Jt9TF4R6{QRBatje+0BspFZcaI0O*tQa+O+7iB1+XiEPon{a?@ z^+F<5{7N%yp2s=dNL=9(B{hjl-R+vO;l*uRG_vy3Y|nGp)NR)_!wIp>4}L@69sArb$8lUv}Dz>Xl2OYWFRmjATFyhl$tU|Km82;YYbB}HyV znd)Cx5ln0idqH?q=Jb>NE1T-#AT|1;=1%gu>6N~I=^62SJ8gP|`;o}syNCHaz?@O^ z+avucO)iF0|2tJzw_kcuxhWf-!D3V=Hf?p$Bz%sjwn0I&2dq;&EYLBUx{z!Q89*r!D@jL|_z+SYiy?EeN`RN}BM`GUeFOV% zT`Ie-xGX2BpW@f?){1ZOY$M{eGc}i*FSBv%?HHedkdLVO>A&V&-?sF2~(C217#kyiIdGeYV&z$JC@|tIZC`piKkhFCQKIhfh zHGOWsRVG#C9v&yr@1}O!^fR?nP>c83>QK!=C3h?7)rE&zt_D{Qf`4#Y>>CB~7I887 z|Eh#}Qz=NY3D+zYfCkG$KzMNHE5)rC5sC1(y;_*ng)R*3KKRDnCJ+Z7kqRWhwEp$vcS!A^(IUTV^ScUN}MuR!$@F=0!cbM|Ha zh>1xI;Md%lHr8fy%IVAy4v*&a{$btV-mBi6&Ak8tb6D(48xG#=6@9tMnLL`s8Fjwi zTZPDzTQ@51z}BKy7V2@rz$UDG6s8CFOv{OIS5amKS{uhXtGWhUce~XOC@p+FH8GRp+X;uF4CErme(Z3o}5{LQkYpa9~kfZf>Fv3pZfG<Ww%hl1gzoGKHoP*&(25K$l@BaqdVmKwdm>e2ym zmUhh*37KukRE&@UeJB3(9=m-ZUgE&1SI5Tae9)5_qsxzL3jN9jhVk~uXY3;qo;Tgw zBh}0U*%fa3`?G46HHU*-BPt4!R)Ip2Kuf~%656kOuhA-x?3O1?;i z!#=dc2W0sJcLXk}%0WSVPFeD}klCY|$|t%5k((f3R~60t^PxZN!T9WW-;zj_f3;dF z9xg5&?x?U%j{bxc;3Cr?xnfvJ&*x(ImoqQ0p%ROB)yx2<4-hv$lJM;cp64>~rdPFm z;#A~QBV=uyXm(*iMpYF_T+xxZZ1{}lZwDgXum88sCxZnPIpb-3fcEr9eIC{RX}|1v zt@Dzu4B4=O-iGr*?*CHSO%dAVi8P6(Y(X%w$w2PC+xbI zUkTaSHuR@xceLAUMZ7H=b{mJp>sLrG;Xx>FMo8!R_ylF2(T0#!^rvH!Iyq%!K}mzo zWH98S09KiKIILHEj;ohD6C{rA5wbOrjT;T@RouS0ov&ddt~;{~S-gAW$*z2^zKolT zfr~8ENN<`huNF&9>$0~{bjv?jw4;>Kx?)0UZt1zYgZuJlj`I5QaqS|yZOIzFSD=qV zwI2wF3MFekO?f}2IA0P;22Og8!A6KxAgxxHteMhh7`?NAK?kK)++aVQ{ztvojkBDh zqu(R1X=_WV@!#c>hOMegTD0Hj;uL|k9bv5*OYP`ljgA!~t~=QwL{un=^^k#^IZyHX z7=%pA*Ea<$mi^%6_FWtV)#ce#v^tw01e>jrns02@IHRL#e1T?W(AUr)Y6(B+-ZLk2 zA>{gy6zUgt$2t z7!cTL-1QVdUq>}!W)sN*HBcjZ`MSHL$jmu@bgd~Vp>@=ek_tQPc|3)J&b@%9XH-qV z12K~nV}-3N*7jA-L|$4wibuF_{rro?onv|E_y`nEoVLJQi&t-S%`9DMXnGP`0speL zJ+`wOw741wcPOd8k~gp{^F!KcpzOg)o7=q&@FuAmw6e`fcV=tDK!xeIl$v_ns$h)% zjzD*TMiq8OLQGtO4?GuNZhhjU@rPBWj4W6;5%PtRzP8(WonW_!h$Y<}N%n%&%KlnkqMF7$cNU-QhRJ41vq z#d(~o=xdISnJ!P58I@YB zxkX9i{!I>>2~PG*(PUYEHMVSTyF#rdO5im#?-Q|0@ie#r?kBE1ionWmCWfhsrN!Jl&VDO~zHS?Q@5%2jQ+*^V!W0b-Oy{5f*WB*Qiq?H>f`r2%TB3 zC>vqY^D>@6Z}6A=kG5yeVRMD;tTS>rRmKH&# z?KQMK#|fj-$zMC||MP}5TmB}i{>IY@{rCU*VL&n5`y(lG;^jbUCWmT zL~Ud5QCSzmY3`YhNYOu+ePL+3JEAUo-$6OK#2gLZJ__fq*!?&^o^DlLwn9ah>c)Lm zh;-{!YEBCgr(u1y&2nFU!GiwgW`$Ht3NW-Db{+PE9o{gOulyz38-0oEkuJ-kvndED zo{s6fK$MCle#>+eBa(sq(VI+tyAfXvFmnrA=IumZY0~quG4*&V73t!yeD4Oc8# zWsh46+HM(JtJZO@`6FUU>BCN?OX^T576VU1fX}pV`zjhLF3t)N>{Qa{4EQ%!M!a;2 z_H9B}G@NflI4!sxd{Bq-HDj(`91h>B?LkxBKD;-mW$CZWDx15pwZBR?g^#7#Y zOi`r_epmZ0CgmRjw}}CC(h07AgU5hzX(0OUTg?0)y1iRI_Q9D*C*yz*wvB{j=;iP~ z_Yz{tvni+Tu#Q}-74|QB_q&oN<5c|n(tl;dz&~2QBdPCI0&WW4Pq;(ND-6*}6JD{W zml~{Hi{#qMLwJz8K&}vx%_Dl#LPY7`fM<2s_E!T~Hc#+}9wECfOMR9{SO5b8VC@aE z>eXsiSi^-`q=>sAv%|Cu7SC?h)~0nISc{(T?MEUVNE&9C+Ld0Ky4|FPkN-r^-@**L z)SN^O`NzO@8|x^n`oH#&ts>^&Kd%H*Q%{k~!)IMUMB#Dt89RL@A{2d-&g`dYPOs_u z$#;p>B8+%1EQ*Q(-rz45E!5WX?bf`W$s|>G1s_+^H+7;*3(f)4L$4N=uO?h4 zJ%`DT<-+CXF6QO(n-KV;U5;UihFw&SG#q+IR=0R>nmMBH3HJ#|I}tlks%m*cs;^&i;s$ z0ngFsxx=gOfBo~${EHi`HH2-Bo$9E?fm`A~B-oFBAn{V_m}h+1mzS6r5lC`alnp;8Jy7#Vi1rSWy-^r>Q2p8-S*@|~n%4pJg4(%H=0p`2PkAI1(K z1|~a!5^G#~;Fh$n1f4taMEDv9|LR*@TI~da&s1UXQr0dmb+^@|v^7aP&}m5%*)&sc zu#B63Q-UfN>v3oWw_whpx$P4`vRBcD<=KWyf^?AvyvGeD_8kJ?+W&*9M|Yo-ZA>fz z>RBjj*R}=&eLJdgjUNQZebZ%h7MxxDkl;AMj*A2fI++0-eGoJ06>B|tx?|DoJAeX8sSSR=%DQa> zkC*`?JxkZ(loi>=#=7kgi3Ev}`Y^*Zz^sHX%Z8L*GUR#ZS~gAt_60>`PSsLJqU%ec zY~E&DFw?3t0?=Fa>)-@Sfx_6azu_I|oq7#kBitEqelXVDdO|oCbhrsm?&p=->hm5~ z8*Zmauo~zPnFI)W)Hf)?3qi z!{S;b12;0}&7pHJX?qQhW>WD0J5dV1PhQ!P{pQ&EzVri^|9s&I9A~0yE z$h+o4R<_@=E%RTR(~rSX6jhl#7tD4XaW%-Opr$4Y&Byy2I50acwCK5h(yyBh=rbrP zZ~CfxL_z<(BRnksPwI<%p=DZKaI+@8XFOo{=Y)*L8Yb*P!eR&Z$Ph`=EDAcFBD<86 z&GH_tEG-CuSKc^v6@9dZ zabAnzQrZUF^Sx>yU*XlC8k{)l7Y*h<(qC;WUO-EiDKi%GS-={PlCAN@S0+k7)nUM8 z8SEo}Job2D;k@Dk?LS2Dbuj^#t9(woE4>gVFO4J3+(XxDETiS#!W#-q#X$dI+3%R+ zhk))&FB#RJF{Y6wEU~ot8l=@NSc&_lAJ_6U3~XIu+fsQK9598D&d;~MXwW(^#I;{F z*b%7Zhf(4(-nf#Ivj@YoQos;nBwy0tiGQ=nw^qW*?nuD=u`&p|*Ht^$AM6b*4P%W- zmLE>t}YIHD3X4oBu4a!=o3oJ`+($GnpPL2SLjAcI-mwDe* zQxfjhIVf{Kc6DTm!}D99v&rLR>@*pP&-w2of~Y4TM1wxgkMT+?3rDKm{C_$$umweA zOJ-3lBTmFHi4Z^%#7z>1>ARbtySH(TDm&8)c5@NX7cv|Tju5Vof#URsi+QO@qb_As z=M8XQfoe3>*<=;}OIJg1>WU*?lE+KBXPC3)ORw233fwjs+%!2Inma}!P@4%lo0#Tv znIzKS;646BZ=2+T=S<+JQdQ1!9mgp-GjixPB&F^;u%rp%UE*Z5El3Xz&{JDYpe?J< zF(04ef9W&etm5tlOa@XDfEMEAM64u_3z!$Jv7ZI(wF3tg`4*e-X4Z`Gfn$r}$}0k| zD1inQYLOjp;ve!>g6_BB6El41^lr=8G+a2p%HrrT(d}NjcyU;im6R7|?6eC0IpI@H z5B=@)M{D$>dDH089Z&z`&HhJQzc%&zp-JVr;n*DBP50t@zw_<1{Kxg-u6Yj(IzRtO zgmA^v2aHu(RnfXfjONb=yOxf$CW6>XqRj*eRpt8_78vIG`npn%D@K*;L#pziuquhF1YlG)93{z|MlJzRbQ@nzb!sH7e6j)kAcXV}wiES)9jK7BFvl_l`HVCa2AUoCkdOA}a{RM3 z+De+>C83s9P3%MpHEM40$o9*-k=l6Wk<_67q9qkgWmHy+Sz{LU0a6_=d1HXQMq@}{S^`Vc6x z_HF3YGU$H%7ahs_H} z)zWw<@EZ6b{%4?aTh)|BBJxMJWlb$^g2odI=lpgzXxB)ifFi_@aIRosf(<-en(Yi3 z{~kAMSSi)0Rzt=U3JoJ))$F!as9UgTw&j(KClXKOm&C7E>82~4@n>=ODH3oqp4g`s zho;T0{Q08C@mE4W6hCO+K6%}p@okO$mgG3*n~F z%1cTin7tvyf0r^RN7uAivI{kL11%JFj$V_Q9Ci$+etC~HM0V>ojRrgI@V*w|Xi5%L ze>YbM{X*O7yt5|XUona3(ff%{hWuGcQ!qKsR}CsRdmIKy+*0+B3IcY_en-DBg}?4a z7aRNGezq)q?<+Ky^o|9~mIj^4&3B%)cyyFWiuUK|g4>u~ta*yQ49^NFQNZ)}ec-n}3E{uw{m4&~f3xblT23a9 zGzoZvxFZcgh-DD{MDU3;HD}AA^9(}XXVDOdcI?MhfOudd$-j(TD9F1tpZ$)^x3^|h z=G~1|LvMO7xujCrbNlKq^rqF#iG*=-U_14Z2?`p3lPIblt8wuAwF*^IaX0QB+m}H!K&ujlg@!QKgw-Ditzj)P5u| z^^a!rbI(zPTvLY)8x`&0m4YFhlNh-i>O6&tS#Qk?oo zDVl!0lo$wnykc@e6pV1hSx)yFVHSlx{86<)5pbCizC^+?U>hMLAms5bo$Og9F~LDnv@(!h?r}iHQ--#r&)Yk?{MM@8ep!oV6`w6CqH*& z#}1~b#Nza&`CDG1i)#poUHj%&(PB7QeA)ed*-x=y(AA*b)LNi4EKG?^CJ9%|Kw!*_ zNL84*i0EMOMF{d(6qMZ(-mNe8OZxrIw8!Q)2vN<@9uicrl~rkjw|Rd{>HO&|FeF0; z9T+&&O*Q=@V3LSR-sJde_ddrUCL>v}pv+*;5oc#n*L}}%t{$>Ti_*j~ReYpTSUV+N zRVQ=p^~OlV80Nc4X>?RVs5bvx#dz1c%8H4DKOe5QWg@Lmed$KZoGl zpKG^uOIktAH2xINta>y0W7?AiUC9IAzC@$zhtZ_rhiUt<49+;W{fhUkX;0$=lVcPc zo5WsjY>%F)*pGdw%*Yyu$5cFkAss|?Mszz)ZFpg$?yv?0N*m(gB+5jzVx<~@O-PE> zk}&>=b%I~tE0^lNT0p*<)|sp5-JC&mM|5BPj&+ZCvF`s_!=Wlb*%KzdHcb&>N@Qj9= z6w_t*T?AZjC!QgSw6U@gNyYdZ+ujT@Xl+|>_Z zhs&?muD^_mL`2E%BP32=aj+nL%NW}f{={ThK#(LB_+@-pqo_%k+#b?9@>4RTq{`KN zZFJsc@n);$7tgmbF*Y!xYG^hc^}p~)C}Mfjf;MU;iC6LaypRk>4%Qk;_w zcdh=`O}>LV)u$6T&~-JINyw~zSRw3Hj`%ke%=E{YQovE!iunF4j0hL4urYsjjMSsy zrjkb|*nYYO#_(3mHPzj3l=8*M&-eUf*y1p_jjyCBUcZVQ> z;O>J%f)m^!xVyW%1$TD{?(QBmNN@@6?(XnSp2+UIyWjlkYo>d;@9yf7Q>Uu#UoT$K zaGi2JYvSM|KwL*WOlXwid{sV?IXxft1_?Ugd4`v)2()JUr#thEjRdXg8vO`ze!VR| zrfagGCVixMHSQWbF#T~3e!%M*aXGJ^d^`Tu&x-(5`FYJv@uxt}o`PjdkekjZF;SHE z=1goai8;>i73_p30#03b=m!af3v-ya8DGyGH6|l%cjn%Ye|XPn?*KKQ_5x%gacdRE z`7FdO1S_sB*!#>MdJifm-H%HvX5TZrMY@%*em4)Emb)@q#&T=_)e6j`_lHFT5thN; zQ5$QJzkz{)tbzjbQ{-Ins!PUYDuO9(J2S!YnbuH$w$gr*ApU+7ufT1ERQjXdDrBb( zx>AR9gB30TK^gX`Y=voeqnE#BT`3GK;BAV`MS`IfUZ+0nw8ITd#_gcpJay=c917fCjx-f?K`BumWNP5nfwG@*7mEyz#*Phc+pJzy z-iRU*-8Jv&pXj0l)B>Jk3X~8bbqR8vyUR2pWxrZ7`AS|k`vGabzs?6k)LZ|JB@4I9 zSSncbcXNB-e%S87o=t!D2*8FED_A-hDNT92x>QM6cYgEdmtGExY}Pz_Jx5(krC|sd zja~&!aXDMyP-YNtg&hV%(-j0-@qjQa>C0VS@7~W9)sYuaMxw^s8BQAB59o#UnGGrG zs!hVV7rai42jc8r6j(^E`{5e99KU96pa9#8PbX6-5HF~TM`h+5>qQ6a!nu|v)>?D~ zaZ@blh=UGalG{AIKKY_sq9@l{unuFfpULJV+?<0^VMA%%Q@gJIfp`kpxEZQHiI z`>)phKUY^=EmKgZxhAlR{8kNxoV17!7j~)uWzHdVDw7apYYM%7t8&yJ)h@BNar_%B z8GQ&#>pS%&&Pe>qV;NE^svnk62a$8vb#%nfF?1@D)KKU@@U_A2&Q4r|7wjkUtrM1# zz73ZbG<@%`D>Jy_VmQ%6R#?>`GVNhVi7^v4wv&I}V0M98(l>m7GOAqdB4rIe72-_V zF&uB%)P1`MYLCy%W@Ts=>KlEC{jT86okssFdPiSJ)|A83J|@-ARY{{YmQT-}G)?jGV?&>zMmedA z%*LBO<3s-Hg&Tmvo(+&G0MXIxYMFtrl4i_-Z#=U#WobvlH`6vGM&I-~WJTKy%+D^! z({Ef9lL2J2PHz;MV6zYpL>p1i?QK2xuQ&+6)-xo@zF%U=niklQc?k%;)zDxn(3=Kz zF3krondRVYZp`C_%^Ch`<_WqxJcios2jGF(tEP1axjwRw ze{J!T5T`bS(*QH!_U|zq(5g!G$WP!3@((THS}<&i{ngn^AlR0XXAonI3aLY(FCYMC zDKUT3qD}{H;hww&bHuRX+QK1q%+G=R0E}`IeLESDw^dum7}hJwTtCXR!eEyD9J-E0 zt$IVM_HMwG;23rx)F#8>BRV=LmTwp1ql}i2U$I}UA*%*h-6V;Lw)R9VAgEWBNNtr% zfDlZvQ^I~2jT}^moQOT^TL`ew?Gc3FIKMA|jgCLxfNyE0DJlWw-TO_lainZ$LN=lV zj?2~ktLE{yZcb5kQ#LKhfm8XtWce|MW4hbjU@Zqjlw4Zwm%HkcSw z)`uYWoNVc_ZmZgBNng7S$^{9_L#Y>?Us{tWpoyq2@^~MkV5Pxlq!_jr2ccJWSGH+f ze0-|=BM5>@p-KodWiQ!?-uZ@PcS7MK{OrmI@iB`croGE)+7Sbfpv{ng68&gsWSeYl zRbkymQOghnL3u(Imp{j)V`zSU0Gl_G0#+WHe+n!ljqKy3)tkD^nK+dy2=45WHvhcA z_Dw;Lx&&pN7Efj+bCzW6T11HkM8h9(sVULz0kB5gC^_#DfTL6<0924=wBPueW&0nk zJHKazN{ju~>b*@k|J${@Mo?sAH2g{pXCx^UqLEiz6YNjm+RxQ%i^*?ZmQz<9I+>YB z+KO0T5x-Enjr;+c^V9=aJJi`TQiXi_a;l)tJ<^-G^;o@H3q}Ivzy*$u@9CeSi?!>_ z&7WHcHkS!LqV+1#(J~U`lmqrXYhr35=yu$R+;U0aWJ(<-gWGQh?nd#0ujn>g`T^!7 zd%JYOAYY@BjL1C_7j;ml-Sdc}LD_Ps7W8sz+z$BS9*7C8(do+iBm5r~rccywRIB;c zOwf2Y`mlTHiiwG-sJIxX)~kmpulj1#qpruD%Dnw0hyZmH&O%*zZT<%0yYh6U82R>B zW!WgtppqfEPey-@T}S-S&R~_3tzhZ5p=RQ8L#I0D?4`Js+!WJ_ z_~bZw68mdFFz{6jR`0pP%6>C9t2Iz8SNZwro{Gx+TgNUHhM&;FP|@loy{EtY^oN2< z@5FiXy_>mBZeaD8r#?aMZ}kKNz&A)8Gqh?l<@sY@1Dd{kV3Xv-Eb{~ z#%uRnr6(9+LOt)|;AlqceB&u+2jJ*sW0=9;6uE=nXr~MLeFD{O`&VUr@1RQV=MR|M zB^jWM%P(-+&Gr*mZ}Wd$L1T_BEg$Yc`V8*<&h#bT!?NzEa87w(F}zBL3#bBxfbx{- z%f(lbrj~vNaa-_|=7i7YEYz?1(9dr?<;7gj8b`!KUZ#(oH|qtPPe*= z7&5?bk@3D9Y?J7CXI8$^Xr$Roa>lwfNZ-&t1>*LobOBp>uW`3Et2K#Por$-Q5G-JU z4oWMg1J{MTwraRpC|06^JV}hY+lN~o+?)@BD!Ids;VsXL=aEg>b!iRA&N=l69()=s z&o5S~BZtY4CNI|^zxq$Y0L(VonEDt?qwj4q{Iz&w<*76}K(?oOylz{aDd7!jJ#5JX z&*9`f#DJhoRY)h#t@mZ)yULBM`p+XzTQSa2(`$4L``YCu2zzvxiq5Rs1#j{5NwB!UEiV_r3QSxB&D80ALz6uox0VD7 z{K2uhD8o0RQHU>zXrmqVbPtG)6T(9a<&wkV!dOmIH|tI%yk&%7y;~i<%J6E<;Wy=GduBYJjQ)FPc?OzG@L+`duXnhmN=BjuDeGovyr}c%xFpW0(E3vO6ez zT*o!W{ykebR|Ng8RmtsXSmaB{s*k5VPX>jbWHKvw?t=Jbrg0JP+@p@xvFoYp$r7*> zM-VG}!0i@4mWJK7WobC#TI0rekRBAm%%s>M#>*W_IGfoE{N_8`sI@ziHH7GjO;BVAmmC5!z$lhyy}F%rV;*=Kbp z7Ro(7kblS|d`S7+3z{vWd4o}00Pb}Qa4_0e~6 zyk9oBv68}zu^oL}S!>zp$vpO8Uz{c*zP@1Cv-9xn(kxC8`_QA-RwRciH=>GlWZkEo zkX0Yye276a)29D&Lp?f%ZsdP^Ls$UhkKr9 zPDJpg;rZ*Wu=rL#m5y@`2A&s^#MM_?g1f-b+$_U;qZ2vaH4*3b2pR)&5{85o#o+rx z-i<=pxH&>lA@3?@jqB zPT7&}qRVlUYk9IppLutz6Rd*ANQj79#0FOcX2Bxt-_LGN7)9HSNsMUiY;EZpJ3uQy zx!v|~Ahk~HKKm^h(wKNS5)f5fw?&Oa+-c zerOXBl__7JvP7QJRr{WP$}MoDiha|J@ykes5B;D}K-;NtQ9{pmUkD~eSjoeF6C9vx zM?S9#m#Hu#H2!62>(T>(>YkQvgcvX>Sza4{8}`=Z)P0~@XRvlc^#S}t=3c4w-Vz{Z zRl!*AJJXcY-m-~j^o>6Y*D2YsmH)wo$!$N{hfEZdoXd3F=Mfw}M9OD;6>dqw&MXBI$MjI1&MQg*hk2#D>aJM6AbXcejK$lUJSV2e95)j!7VwFK z+0CG8`!?~Ypf>OK5q9+@K|b`X@ROI{lW1$BKU2Bfd`izk032C(cG**u|1#e^o^FvGn;m5vnX(; znNh#L7qaUD4xS`DI`KAQFy$d8e*+GjYV7AZMz&74hrm6yQ=fSo(`=hL47~OzCj#(3 zzlUq%lv-Qn4)X||dktWq1!LMC(u>0XUF6nK>~Mnj|J-+9)7g+bhR&$(!;k99p5EXD zowaFE^bM%#CWbizEMKB^4E6FNrmzOshN@>jsrN2Ao=c9^=xcjWe6Evs?)S|tiJYZp z2krC?feq=}W(d*h_F{JXgv?zT3>BABjYGKVR(b8G`O0W;ZM_e9dF3LzL}iyV?Y9Q1xi8-yJ& z0AtT)=XWRy=E7OiX?Cy+l&Pn*fq0qS-F=AIu=JkIPZVSK=QV(j(DE-GVh z&UnzvUIo27`Z002n*m23XwG@Hxa_e7O0Ot4MvFNr#wVw^L;J1UrX%%1U02OJFC%bB z59!o1?zztxMq2gTP@gLH*#@06(-$3PrBa;npZNi?bC4OAQa@6RC0{Y$r(rt?tb*q|el-?W5SDAxK{jdTRes6oVM(a2LOyozGrIHR)jtqAFuQ?Nnw zsY}{#(@C=bNhUboqo8Ep_ObLQ`_5#Fl_|-9G)?c2v&{EHKmt=Ebz|6?y>gEGG^{wR|1z#=@#&h1Z8X$A}%E6Rm^NB{B$Im|SzhpI9jTxL0U!8DVX3 z8<7`c5}}xYZ}^(#&UtW_y^vJnU^TW!&I<1?P7_%|lN5iRMN7_js5M!Wn`JENfuERy zNf@A{>Z_+7#HxiX4mIe?DO4gZ%t*YcHs&7eGY|&o3&bb%f}M>Y75A`LeUrcl2mP`N@1=^FL5O;(bD`>!%jSEu}oROirqL&bjUHCxSv~TP9*L3L&oF#jEJDM**(h~OQX7DI zbVssVx&OdS;1!gjOR)01TG;S5hgCr#XvLe5OQ}$o-O)IU;&NgY#iUro zy!h1nAntU)YYZ+Ndwd^3(&Y-#C{Qzf^%^3g{hD#9mGjUeb3Up=#OR0EaVIaoeOJ(J zmlJvUs`#iNf43U9Z$l=PVhmU4O4*~uZJ`lw<@0r+#mfxR$;HFj%$%(Ky+x8NXRDWT zkIbtf)*}MHxR(<$!wYM`O6&l4)N3#W9TZGUF~=Q^({;Sm`SbSfQ|Y$I)1GnVImry4 zZ0W%L*Gj6_;cZZd37{#>Sy1q#6LZ2f)1;~woS8mr3$*X_9Wksto4JN+sW(eS{t$!} z%+X*^eow{3c1omBIPs}IZYcK+NekkaQl3*3%0;nSPxwm$HUG|hzly}QBDgxFeRx;; zT#`OLOBuPdBL%)_ov^qaU~mWlGGz0ve77N@(@;JwZM6RY^t0(@^8L6{898`$iTKgO zTnKW|9>)XrCkl5Ftb|Q2wFt{+g8Ni@(ZkGB*-tpciZ4vN1-ze+zr1k>YImq_&Lwf= z8MCMQ1<*AKgnu`}wKH%x-o;`reHBiMiQ$*}E~@0$%<~-3q>D4D;%3aVu-+c;d4op& zJG{4@YOWRrPEoMJvt7GyN~RXe`wc|(68?nd5z2pO2!7jS^%ZO&^zi#wqJTTQxc@>5 z{=f)&7^Eq7J;S;?B$dqe54#*fH?>>5RiMvZ4I|}SJTFl9GOt+8t3ypr-iD~EGHn9l zPrJeVe^D^8aQ&agzqE6B=d|1)adI^gSmbed`a++^Zf)dPU{?+v9AoyOs~LG12HB!? zrGGGM^?PB~Qno}rwld?ct=QV%e>x9W{}XLHAelv=oKM?rFbov8VRwkj0L+fJS(ImO zOxrfGAr)S@6z6zS4OwyiEP*}wT=lJLia38}%+&TZtp=NIS0Eu4&+~hozPEv}n`ldS z3LCMawTsn#8Jm0OCTW0M)g9{*3hCW~>pghIq&XW{?sMmt7?xZ8^oMcCz3P?rpsgXP zboyJrn&6S3Migs#K;2Q^)68;!@Y|k|$CP#_#JFj~4)izv=m2qQpj{P9OA5h9JnnTG z#iQSU-w^wV=Gr_n-7ue=m=LbD+t+@mdw|QA)&6qmyuA4w&n<94{M3+QOxG+k z)Y%&q)hEwGiJrw~RF40XKc*%6pC{Kp$U&-rQReztr8G(&I86^T(i4Q85|Wkd9dJw^ za42H=7fg|l;QSVROmXC$!xXPCcwgcltCwpNij4_&+KiJ0g~f}!nn~4|w{Io_Vg(l# zSkKn=pURiQT(=og%;C^7Q1XCbmvvqt#^pW@ZvjbqPq>s!Y|3G;s~w*_>HiI$KwR@G zRE5^MkU2E>$@(pNEa0?U-4>x}Ux=l%4#mdmGQY0Z=rgEDbWDn8^zeWD^zK;M>8}WO z*yv|TiX{(ks7l43n3BXY?ihCx;mBX8swIEa%S%x+#yQ1e9p^E*`z)-!5Bh|ftxF&k z;mk-zlX98KP_!a81hi+=9PZtHWPFcjAZjn6nGu|%-={X0U#Z{m_`r=OwWyekQS5BR zyr9xrer%E!enhuHg#ifw0q-AVW>j*8y-PRg7?#Ntm-merowU4jPXnT{>GTEb4pg>c zrUvu&D$P|s6)jAmk#jko0O!8~jy;J@p|Fvxz>zh2;oMAU&-(Cher%{yU;8=gq#MPA zNx(C|gAwx?B$ev>TxiQpBkhsp)c(HJbguu4sZgqWFxAI5 z)5r7Q%gEHL7{me_m^9qAvIn_!#`c{VKhb@8KtFxcP9&i0PID|(UPn<7hh3@Hgg-~~ z2jCCy23{3fvQdWU!^Pu|wzf{knOpX=^Y^X5IbWtU?8Oxe#48nH#%_u49yi`o)oX7PjAOs{43v)3GW1Bb}KE}7uS$I+N<*XJmy;h z_P-35)*#Lk6yjYch3Cg*pU+~Y+T9IikeRClN5%en{dSMU-P>d10Lm|U|ACiZ?fiMW zQS{Bi;Z6Go8cMhcEZ2|xa>UOhq*g{TPH(BhOp9ob zi!*AX6BH1SxDm2rWvieRW_ZA;4wGZ$qi*?F;!w|A0HbwZ3Ik=I(8{QwY{H-FH1XLV zEO3R>A>44)#rI&W4ebh2Zp;Y!T_xlk$D#NjtqOhThiBL4YokVe@ICE#N(Mu2mt=Fr zpv1{mGJ{uD`3ceT-XkopgXYR_C^I@HhV_H9`nTp|RMik>3IpYnz&cuu>hFs=b62)w z{|PRov~%nNhnv^y(yQZD>XeSnjLdIV<)f+on|zQh5GyV> z0+y$t+3BKg(H?e4r|+<)KCiY)B3?@p#gh#46f`tODjiAYHNQ&Usd zo!g|Jg^)MVYVbRfx@@L`{zzc3t&@L*Bx)n=n>zhhv0Bod|LvXu6PUjL4MT%CVup3Zh|I=AkW-?zVM*HnTlqGP zvwF#`)Ri>aUhFdN6RZ+Gm%MK_eYBxalQ2O5e{2I{(rZbi@vk7eVy7<9f2LM%kh53~ zV)T>=>|vIEUxK;@J- zfBa)()b{F5sDSr^)VAWS9yx_RBV@CS1?~)mc~d|pa2};->LWnfa}VrF<#a{R4p@nm zbW4gpjVFJ)C@Np_S#%TCY-K^Z)%p%w5|Y7o@fe4a+Qr#3=->b}R{;Z;>adZCjs{0l zg=B4EAcfuOmZIMwg>?BIw_rXt#FA6^y28@MeYAL_Eo+38MpRT5wlQISp*Dit*_w}Y z#KVB5Ws*34DZi*BMWW)JN6jP5m-SItADrRiu)UWp94=yzDXOQ2i0oQ05ld#xn6amr zzfan;pC~0q=Q~ZWnrHk*SY!2>+M|>h;iSCSBDOHQ7shnF!;#bbeJZHBKsCHKh!EAj z^r+~IocD)l#OH@qp4K#j6+xy~;cHb?ji{}MfT0pZ74|2;kxy^Zm)yhGFW_D#DejtB zfWpEfvt+n<17!wEmj1yncLg{ z2K-VDKK+$`Cw*-nHeLEKV^%r0lH*i{tD*SHYK}wVZGz<|g`ap=S=%LjhbAMshGE<5 z&f-&XQTW1aCJnNAT^4QFO63iSi<(h1$1qckKRc%Fmj(Eya}Sm7eAO^U?~`D`-c%zL z_IUvWo~PY(gp!g;yMTUst>7k;N~hec58xo}mXL93D?siIRuT-V%~5Uw9&H@76Vjwy z3pyPNx6HTAok`JASV>A1|G|5Dx{eq9`q|8lyGQHGofkbb;^HmuNBWb8Ag}`MOrpP8 zT49rLk%C@8p$$*Q_Nm>vT1tGtqDs97l$7_%K(V@xN+?<(8UeJL;Crd^at%(KZjm3W zXl5wZ)4|%#{#k6`0A52z0O~!fP(EdA# zRXP#(&-I?;{Di3fCsgvmCv~u91|Bx41K4BWI}bToNohlH<7XUt}1 zq(;SB=^0z&MgYt@8dyINP2rKHn>RT%%DU66mw2ZC@U-|AFtE#6==JrTq?v1y!pYZV zgb<)3V)0`#R(9dgh671KZO&^d%IWVS`fz|PI3Pn`s{C_S2+G5n+?Rzy-IIhPB@Fiu z1jy65zJ0CLq!f36`M9M-X^U!F_@yQ}aA-1ffeK!gbEa#h2ZS0H(wyR353AbvcBRIKsv6(~1K4~C=XE6|!!WT8L z1c*n#zQ8STYr#P8lZ!gL+<6i0qSh_4MZ8mO7d69`UM-q;vKj~P29e^#(@*55o z(4GpiuKvkFdkq{;Tf1=P@zx}qaHj=k2-}<2L_4fni`sn{*}sS}aQLG#g2#-HlrK>? z+~i~TE4&hFDM)|uF@YhEp2d>vlt%z|eK7i1(CB&OAFJ9+ClpJ?-Uer;y~48c*MUXJ z3Hmp7*FW5?zY6%5sdWKr@hwLq=~uj;z6(ct9(^d7x((@ayb9Qg_OVZ zp8?ndV0D42pGTq&^Xzr>t0IOb1>@^ANxwlDVU!u%vvapOo+-5S(~PI_yK{a&p4;T( zX;Ew2D`oN%Q|@h5hmAHTGVs%bER{ z`i3By@?)v~Euo5U$-Kie{1kEDyT4S2@9BGR@s|Dz#mgvf?2cEs0znH1_iXEJv_^9X z5P_D(jJZF<+>oLUOw5SyY)Kmz)lYWit(~jTjeXneoZ~0KeGD3ftLel9$0kp3Pc~aZ zahD}%6kdW=PUq%8c1w0)S6XaY3jmts_R%o+xt?iu14hFhrGl|kUoEVk4&Cxg(z%NO zAJTr*2eI_hz~sR}Y)O84{6*pG!97Pcwx<}?7N(YI$#8P;^%CV`E|+i+pV&~x8Kub` z!yFO8_thE9K@txY*9Yf5Jnrzd%5?mnzNp)8a$X_SC#(!x2_q?7Dz-g_1%r@o*V=vY zwU2}=d0S_a_FKAx)%*V=EY+&^qz+>*Beu^$&86?U-{{=Lc_bY0^-GP7T(+X%?(>hj`Q}8lpT8haWX$NU5jk*)r5;q_2pqZ76^eailB=lnVQda1x1}V z+A-`TbQ)ApiPE5$+M*9h2wMkoXwu{v=qP^mNvrS$SCEGf;k`$vUa_|wOb(TU)*-aB zVo!h$-M=a>qS4knS$IFLwfs&hbPo+soe|ebPlVQqw0PSPd*qfZEK^qr_&SjCj+c+b z-*nYIt(GU39*vdNjT^m`sPa=;AntzCkO9A~nDY1-6eYL5S z%TvOnx<&8kW!p~acrs1MJWmk7b{Qfa1N29uW5*`DY0*f&Pjd~sbQbyE@b|o9SrA8F zivmG>G%;)Qr&1kEzYQ-~8Klgk)r|!b%qTQ~1T$ph?Cr{6EAvu{A|oA1F(L08?3F<_ za?-o;#u;>MY2j(B{XU4cG2xGL|21Tzih&S zLWRc}>y%xfopDZhB&~)k#===RBwF>XE@GG#t~&q_3nfA%#7TxTdxkzkI?N=FwgP4{k>&Yp8XC+iS~ln>4bb^h z>x1p+)`EMzm(3eUv{{^OHD+Z*H}B^u##9G%hA+XSPC$X3#{G-UU}v&iD)$gkTNcz! ztp&s3CU>6ldE?{YU#S3ea9Y?ybosEdM6H3-Mzr!5Ps#9rDUanQ=Vu?c zTgExgfN#yqimzVmI=YhwNmb=)zPq>3?g!b))k_`0Huua92;w$WMN_p^ix%7pHR&9o zH}Z>aG@ovMv#NsC=dc+fJbZI_k8}niGkH%HZ2%g>Usi?DscefcQ+Unc%+f*qxjx@R z&a2QjEKP^R^ZWw}aJJn_-C$)AaTpTOU>RSBJIIOwy;fjKWd9#npm7K>0LG;aTft%v zbR$Ve3TOF8FntuRXDH%kSAQZJS9c?Ta|*%7c13==gES(of(?FW(5fyG<)z>4ii#P= zwIX3KICLh3zqDW&3v8sw^&Ua%zU7rGVINmCQ$yx({somtc#*5@+>LP;Fk{4DTDFGv zrYQr8oI!m6f&_>tToBVTi_}QkQ=i}9g~RbhpD;QEL5GWnXn&nnrGG0kjc}4E-!8Bq=<~LMUNk?eC0TB+-w8uG|h3xGRhLL^z<~Q+99>flW z{T&_Wh}V^G2QbrgwG_`cFP(axIk5}O1O>v>hz*tC8wy`jH-u%^nsY}(xN|KTG9z7 zMFwhiHJCR?P(|XGg0Bde4_mCG#@4zkg61#}o)8+>{>r9strH7&$?eym8^KzIt*1T6 zliL?Db-_!euZcW@X(Iw5vnf@g7=_1qr zc7-;`-{{xQ(<9b@sjamy({CpFH)em5Rs#0p>l7-N99*5&txfBY$7(O9YtC^`P);k1ex zx&Y@}-iU0dzkIv%zPQxCXixx3E@Qt0$zKklfJd_!)3!wKRr%^!g7*mSDdS(iPJMxc z90(}ZKD1iAtcV*?DO*V;cSfFCz8GW5ynFm6ENytw_)4H;)E6;0FA$kAoz<2p0j{2G zx9UDpeOS2(_+wIn(-xcFWV4P?8+d6@2r3!L?aFe9tn2BN<-W})eSgyg6*=b=F}P2B zqR$dFnDXcJFt)6laguTc^3ldy4zAqrNm6YVxxOQQ_YgxeC@N|k^y`Ruy<{;)jrw8l z2PQUw;?(dneM+J7$P*Eh>3OL|TuB%#Qp?EyDP$(J*wY;PUAx$qJH(OIbpKry6bWC% zT-c|9%r%GNFziD!rrFgn!y34Mc$yr_$54dik7Af*gGBxDFj-FludbCId_Ki0%9do7 zTI6mlzBNUas`g597-?>=BdPPq~=qg+^o9&1)}@K%*t2N*k|sh2iZG&eRzE(Vou5BdbB1LizO9%&@1&yp0q)9cg`edwFxX*SJ>54 zwtLPrS|NB#9KKN6!QzuT%X4$>Jc;og!08k|7idH&gge0MNC8_QZ&7r1zXo%8Io!px z-a2r%m+94T&SpFZ70&E#;J7QAnGYtrDzf!SNI zEZ`lDCEcgV9nuvCU$s~f9-!mh^;M_GYd`L2b=}QAK zQ_dicL#7CFF)hh#7`1A-UHQn%S@6O+WMUM$G=%0iYPA5D+ZIb>@4JABR%SrKj~>!z zFO&tt9BLt|gLxUh(OMKzDQ!WD&u0o)@~D=J-0o8~%IeIzH6Bh!zKr)HZ|MKQB0GO3 zR;a>fE)r`{z& za}JYkV}r4%GE#I-&Q5vhkwS%&-Ckgw%3CO!K|nxJ#f113U+(xjZqtM*w_#V^;%oQe zFUQ&(gO7P#gI5ki)5ki#?bSk4rr*IcWZZS)NB@%A_v*k===09cpFe*#tK62zj;vTb z-B3q|cBN~thM<^zglX3l#PeRSOv)2G+~)O&H8{JY;EkaDxx&~IGr?8_OJXGvmW&OR z9pZLL`VdUN8{tHwLf#;EiJyDqeM-DnBp!<4l&d&A%Af9;LFN&X0LechV)AB~GgbOW zR6m6o^8B+Q_NHn?M2#%k-DT4N3 l{Iih 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
    =U&dBpni90>*4}!S^Q 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'D*~X$}O(9G+>b{@yRpnjaR`P)$8YE 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
    OmBY6deZ#a3oO6s&?H;WnHxQ$ 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 z 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 diff --git a/docs/dev/setup/jenkins-localvc.rst b/docs/dev/setup/jenkins-localvc.rst new file mode 100644 index 000000000000..384affe8dc05 --- /dev/null +++ b/docs/dev/setup/jenkins-localvc.rst @@ -0,0 +1,779 @@ +.. _Jenkins and LocalVC Setup: + +Jenkins and LocalVC Setup +------------------------- + +This section describes how to set up a programming exercise environment +based on Jenkins and LocalVC, which is integrated in Artemis. Optional commands are in curly brackets ``{}``. + +The following assumes that all instances run on separate servers. If you +have one single server, or your own NGINX instance, just skip all NGINX +related steps and use the configurations provided under *Separate NGINX +Configurations* + +**If you want to setup everything on your local development computer, +ignore all NGINX related steps.** **Just make sure that you use +unique port mappings for your Docker containers (e.g.** ``8081`` **for +Jenkins,** ``8080`` **for Artemis)** + +**Prerequisites:** + +* `Docker `__ + + Make sure that docker has enough memory (~ 6GB). To adapt it, go to ``Preferences -> Resources`` and restart Docker. + +.. contents:: Content of this section + :local: + :depth: 3 + +Artemis +^^^^^^^ + +In order to use Artemis with Jenkins as **Continuous Integration** +Server and LocalVC as integrated **Version Control** Server, you have to configure +the file ``application-prod.yml`` (Production Server) or +``application-artemis.yml`` (Local Development) accordingly. Please note +that all values in ``<..>`` have to be configured properly. These values +will be explained below in the corresponding sections. If you want to set up a local environment, copy the values +below into your ``application-artemis.yml`` or ``application-local.yml`` file (the latter is recommended). + +.. code:: yaml + + artemis: + course-archives-path: ./exports/courses + repo-clone-path: ./repos + repo-download-clone-path: ./repos-download + bcrypt-salt-rounds: 11 # The number of salt rounds for the bcrypt password hashing. Lower numbers make it faster but more unsecure and vice versa. + # Please use the bcrypt benchmark tool to determine the best number of rounds for your system. https://github.com/ls1intum/bcrypt-Benchmark + user-management: + use-external: false + internal-admin: + username: artemis_admin + password: artemis_admin + accept-terms: false + login: + account-name: TUM + version-control: + url: http://localhost:8080 + user: root + password: dummy # has to be set, but does not matter for LocalVC + build-agent-git-username: jenkins + build-agent-git-password: artemis_admin # choose some strong password and username (gives read access to all repositories) + continuous-integration: + user: artemis_admin + password: artemis_admin + url: http://localhost:8082 + vcs-credentials: artemis_localvc_credentials + artemis-authentication-token-key: artemis_notification_plugin_token + artemis-authentication-token-value: artemis_admin + build-timeout: 30 + git: + name: Artemis + email: artemis@xcit.tum.de + jenkins: + # only required if Artemis and Jenkins cannot communicate on their public URLs + # e.g., Jenkins is only available in a local container network + internal-urls: + ci-url: http://jenkins:8080 + vcs-url: http://172.17.0.1:8080 # `http://host.docker.internal:8080` for Windows + use-crumb: false + server: + port: 8080 + url: http://172.17.0.1:8080 # `http://host.docker.internal:8080` for Windows + +In addition, you have to start Artemis with the profiles ``localvc`` and +``jenkins`` so that the correct adapters will be used, e.g.: + +:: + + --spring.profiles.active=dev,jenkins,localvc,artemis,scheduling + +Please read :ref:`Server Setup` for more details. + +For a local setup on Windows you can use `http://host.docker.internal` appended +by the chosen ports as the continuous-integration url and the internal vcs url. + +Make sure to change the ``server.url`` and ``artemis.version-control.url`` value in ``application-dev.yml`` +or ``application-prod.yml`` accordingly. The ``server.url`` value will be used for the +communication hooks from Jenkins to Artemis. +In case you use a different port than 80 (http) or 443 (https) for the +communication, you have to append it to the both urls value, +e.g. \ ``127.0.0.1:8080``. + +When you start Artemis for the first time, it will automatically create +an admin user. + +**Note:** Sometimes Artemis does not generate the admin user which may lead to a startup +error. You will have to create the user manually in the MySQL database. Make sure +both are set up correctly and follow these steps: + +1. Use the tool mentioned above to generate a password hash. +2. Connect to the database via a client like `MySQL Workbench `__ + and execute the following query to create the user. Replace `artemis_admin` and `HASHED_PASSWORD` with your + chosen username and password: + + .. code:: sql + + INSERT INTO `artemis`.`jhi_user` (`id`,`login`,`password_hash`,`first_name`,`last_name`,`email`, + `activated`,`lang_key`,`activation_key`,`reset_key`,`created_by`,`created_date`,`reset_date`, + `last_modified_by`,`last_modified_date`,`image_url`,`last_notification_read`,`registration_number`) + VALUES (1,"artemis_admin","HASHED_PASSWORD","artemis","administrator","artemis_admin@localhost", + 1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +3. Give the user admin and user roles: + + .. code:: sql + + INSERT INTO `artemis`.`jhi_user_authority` (`user_id`, `authority_name`) VALUES (1,"ROLE_ADMIN"); + INSERT INTO `artemis`.`jhi_user_authority` (`user_id`, `authority_name`) VALUES (1,"ROLE_USER"); + +Starting the Artemis server should now succeed. + +Jenkins +^^^^^^^ + +Automated Jenkins Server Setup +"""""""""""""""""""""""""""""" + +The following steps describe how to deploy a pre-configured version of the Jenkins server. +This is ideal as a quickstart for developers. For a more detailed setup, see +`Manual Jenkins Server Setup <#manual-jenkins-server-setup>`__. +In a production setup, you have to at least change the user credentials (in the file ``jenkins-casc-config-localvc.yml``). + +#. You can now first build and deploy Jenkins, then you can also start the other services which weren't started yet: + + .. code:: bash + + JAVA_OPTS=-Djenkins.install.runSetupWizard=false docker compose -f docker/.yml up --build -d jenkins + docker compose -f docker/.yml up -d + + Jenkins is then reachable under ``http://localhost:8082/`` and you can login using the credentials specified + in ``jenkins-casc-config-localvc.yml`` (defaults to ``artemis_admin`` as both username and password). + +#. The `application-local.yml` must be adapted with the values configured in ``jenkins-casc-config-localvc.yml``: + + .. code:: yaml + + artemis: + user-management: + use-external: false + internal-admin: + username: artemis_admin + password: artemis_admin + version-control: + url: http://localhost:8080 + user: root + password: dummy # have to be set, but does not matter for LocalVC + build-agent-git-username: jenkins + build-agent-git-password: artemis_admin # choose some strong password and username (gives read access to all repositories) + continuous-integration: + user: artemis_admin + password: artemis_admin + url: http://localhost:8082 + vcs-credentials: artemis_localvc_credentials + artemis-authentication-token-key: artemis_notification_plugin_token + artemis-authentication-token-value: artemis_admin + +#. Open the ``src/main/resources/config/application-jenkins.yml`` and change the following: + Again, if you are using a development setup, the template in the beginning of this page already contains the + correct values. + + .. code:: yaml + + jenkins: + internal-urls: + ci-url: http://jenkins:8080 + vcs-url: http://172.17.0.1:8080 # `http://host.docker.internal:8080` for Windows + +#. You're done. You can now run Artemis with the LocalVC/Jenkins environment. + +Manual Jenkins Server Setup +""""""""""""""""""""""""""" + +1. Pull the latest Jenkins LTS Docker image + + Run the following command to get the latest jenkins LTS docker image. + + .. code:: bash + + docker pull jenkins/jenkins:lts + +Nginx proxy setup +################# + +If you run your own NGINX or if you install Jenkins on a local development computer, you can skip this section. + +2. Create a file increasing the maximum file size for the Nginx proxy. + The nginx-proxy uses a default file limit that is too small for the + plugin that will be uploaded later. **Skip this step if you have your + own NGINX instance.** + + .. code:: bash + + echo "client_max_body_size 16m;" > client_max_body_size.conf + +3. The NGINX default timeout is pretty low. For plagiarism check and unlocking student repos for the exam a higher + timeout is advisable. Therefore we write our own nginx.conf and load it in the container. + + + .. code:: nginx + + user nginx; + worker_processes auto; + + error_log /var/log/nginx/error.log warn; + pid /var/run/nginx.pid; + + + events { + worker_connections 1024; + } + + + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + fastcgi_read_timeout 300; + proxy_read_timeout 300; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + include /etc/nginx/conf.d/*.conf; + } + daemon off + +4. Run the NGINX proxy docker container, this will automatically setup + all reverse proxies and force https on all connections. (This image + would also setup proxies for all other running containers that have + the VIRTUAL_HOST and VIRTUAL_PORT environment variables). **Skip this + step if you have your own NGINX instance.** + + .. code:: bash + + docker run -itd --name nginx_proxy \ + -p 80:80 -p 443:443 \ + --restart always \ + -v /var/run/docker.sock:/tmp/docker.sock:ro \ + -v /etc/nginx/certs \ + -v /etc/nginx/vhost.d \ + -v /usr/share/nginx/html \ + -v $(pwd)/client_max_body_size.conf:/etc/nginx/conf.d/client_max_body_size.conf:ro \ + -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \ + jwilder/nginx-proxy + +5. The nginx proxy needs another docker-container to generate + letsencrypt certificates. Run the following command to start it (make + sure to change the email-address). **Skip this step if you have your + own NGINX instance.** + + .. code:: bash + + docker run --detach \ + --name nginx_proxy-letsencrypt \ + --volumes-from nginx_proxy \ + --volume /var/run/docker.sock:/var/run/docker.sock:ro \ + --env "DEFAULT_EMAIL=mail@yourdomain.tld" \ + jrcs/letsencrypt-nginx-proxy-companion + +Start Jenkins +############# + +6. Run Jenkins by executing the following command (change the hostname + and choose which port alternative you need) + + .. code:: bash + + docker run -itd --name jenkins \ + --restart always \ + -v jenkins_data:/var/jenkins_home \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /usr/bin/docker:/usr/bin/docker:ro \ + -e VIRTUAL_HOST=your.jenkins.domain -e VIRTUAL_PORT=8080 \ # Alternative 1: If you are NOT using a separate NGINX instance + -e LETSENCRYPT_HOST=your.jenkins.domain \ # Only needed if Alternative 1 is used + -p 8082:8080 \ # Alternative 2: If you ARE using a separate NGINX instance OR you ARE installing Jenkins on a local development computer + -u root \ + jenkins/jenkins:lts + + Note that you can omit the ``-u root``, ``-v /var/run/docker.sock:/var/run/docker.sock`` and + ``-v /usr/bin/docker:/usr/bin/docker:ro`` parameters, if you do not want to run Docker builds on the Jenkins controller + (but e.g. use remote agents). + +7. Open Jenkins in your browser (e.g. ``localhost:8082``) and setup the + admin user account (install all suggested plugins). You can get the + initial admin password using the following command. + + .. code:: bash + + # Jenkins highlights the password in the logs, you can't miss it + docker logs -f jenkins + or alternatively + docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword + +8. Set the chosen credentials in the Artemis configuration + *application-artemis.yml* + + .. code:: yaml + + artemis: + continuous-integration: + user: your.chosen.username + password: your.chosen.password + +Required Jenkins Plugins +"""""""""""""""""""""""" + +**Note:** The custom Jenkins Dockerfile takes advantage of the +`Plugin Installation Manager Tool for Jenkins `__ +to automatically install the plugins listed below. If you used the Dockerfile, you can skip these steps and +`Server Notification Plugin <#server-notification-plugin>`__. +The list of plugins is maintained in ``docker/jenkins/plugins.yml``. + + +You will need to install the following plugins (apart from the +recommended ones that got installed during the setup process): + +1. `Timestamper `__ for adding the + time to every line of the build output (Timestamper might already be installed) + +2. `Pipeline `__ for defining the + build description using declarative files (Pipeline might already be installed) + + **Note:** This is a suite of plugins that will install multiple plugins + +3. `Pipeline Maven `__ to use maven within the pipelines. If you want to + use Docker for your build agents you may also need to install + `Docker Pipeline `__ . + +4. `Matrix Authorization Strategy Plugin `__ for configuring permissions + for users on a project and build plan level (Matrix Authorization Strategy might already be installed). + + +The plugins above (and the pipeline-setup associated with it) got introduced in Artemis 4.7.3. +If you are using exercises that were created before 4.7.3, you also have to install these plugins: + +Please note that this setup is **deprecated** and will be removed in the future. +Please migrate to the new pipeline-setup if possible. + +1. `Multiple SCMs `__ for combining the + exercise test and assignment repositories in one build + +2. `Post Build Task `__ for preparing build + results to be exported to Artemis + +3. `Xvfb `__ for exercises based on GUI + libraries, for which tests have to have some virtual display + +Choose “Download now and install after restart” and checking the +“Restart Jenkins when installation is complete and no jobs are running” box + +Timestamper Configuration +""""""""""""""""""""""""" + +Go to *Manage Jenkins → System Configuration → Configure*. There you will find the +Timestamper configuration, use the following value for both formats: + +:: + + ''yyyy-MM-dd'T'HH:mm:ssX' ' + +.. figure:: jenkins-gitlab/timestamper_config.png + :align: center + +Server Notification Plugin +"""""""""""""""""""""""""" + +Artemis needs to receive a notification after every build, which +contains the test results and additional commit information. For that +purpose, we developed a Jenkins plugin, that can aggregate and *POST* +JUnit formatted results to any URL. + +You can download the current release of the plugin +`here `__ +(Download the **.hpi** file). Go to the Jenkins plugin page (*Manage +Jenkins → System Configuration → Plugins*) and install the downloaded file under the +*Advanced settings* tab under *Deploy Plugin* + +.. figure:: jenkins-gitlab/jenkins_custom_plugin.png + :align: center + +Jenkins Credentials +""""""""""""""""""" + +Go to *Manage Jenkins → Security → Credentials → Jenkins → Global credentials* and create the +following credentials + +Server Notification Token +######################### + +1. Create a new Jenkins credential containing the token, which gets send + by the server notification plugin to Artemis with every build result: + + 1. **Kind**: Secret text + 2. **Scope**: Global + 3. **Secret**: *your.secret_token_value* (choose any value you want, + copy it for the nex step) + 4. Leave the ID field blank + 5. The description is up to you + +2. Copy the generated ID of the new credentials and put it into the + Artemis configuration *application-artemis.yml* + + .. code:: yaml + + artemis: + continuous-integration: + artemis-authentication-token-key: the.id.of.the.notification.token.credential + +3. Copy the actual value you chose for the token and put it into the + Artemis configuration *application-artemis.yml* + + .. code:: yaml + + artemis: + continuous-integration: + artemis-authentication-token-value: the.actual.value.of.the.notification.token + +LocalVC Repository Access +######################### + +1. Create a new Jenkins credentials containing the username and password + of the build-agent-git-user: + + 1. **Kind**: Username with password + 2. **Scope**: Global + 3. **Username**: *the_username_you_chose_at_build-agent-git-username* + 4. **Password**: *the_password_you_chose_at_build-agent-git-password* + 5. Leave the ID field blank + 6. The description is up to you + +2. Copy the generated ID (e.g. ``ea0e3c08-4110-4g2f-9c83-fb2cdf6345fa``) + of the new credentials and put it into the Artemis configuration file + *application-artemis.yml* + + .. code:: yaml + + artemis: + continuous-integration: + vcs-credentials: the.id.of.the.username.and.password.credentials.from.jenkins + +Upgrading Jenkins +""""""""""""""""" + +In order to upgrade Jenkins to a newer version, you need to rebuild the Docker image targeting the new version. +The stable LTS versions can be viewed through the `changelog `__ +and the corresponding Docker image can be found on +`dockerhub `__. + +1. Open the Jenkins Dockerfile and replace the value of ``FROM`` with ``jenkins/jenkins:lts``. + After running the command ``docker pull jenkins/jenkins:lts``, this will use the latest LTS version + in the following steps. + You can also use a specific LTS version. + For example, if you want to upgrade Jenkins to version ``2.289.2``, you will need to use the + ``jenkins/jenkins:2.289.2-lts`` image. + +2. If you're using ``docker compose``, you can simply use the following command and skip the next steps. + + .. code:: bash + + docker compose -f docker/.yml up --build -d + +3. Build the new Docker image: + + .. code:: bash + + docker build --no-cache -t jenkins-artemis . + + The name of the image is called ``jenkins-artemis``. + +4. Stop the current Jenkins container (change jenkins to the name of your container): + + .. code:: bash + + docker stop jenkins + +5. Rename the container to ``jenkins_old`` so that it can be used as a backup: + + .. code:: bash + + docker rename jenkins jenkins_old + +6. Run the new Jenkins instance: + + .. code:: bash + + docker run -itd --name jenkins --restart always \ + -v jenkins_data:/var/jenkins_home \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -p 9080:8080 jenkins-artemis \ + +7. You can remove the backup container if it's no longer needed: + + .. code:: bash + + docker rm jenkins_old + + +You should also update the Jenkins plugins regularly due to security +reasons. You can update them directly in the Web User Interface in the +Plugin Manager. + +.. _jenkins_build_agents: + +Build agents +^^^^^^^^^^^^ + +You can either run the builds locally (that means on the machine that hosts Jenkins) or on remote build agents. + +Configuring local build agents +"""""""""""""""""""""""""""""" + +Go to `Manage Jenkins` → `Nodes` → `Built-In Node` → `Configure` + +Configure your master node like this (adjust the number of executors, if needed). Make sure to add the docker label. + + .. figure:: jenkins-gitlab/jenkins_local_node.png + :align: center + + Jenkins local node + +Alternative local build agents setup using docker +""""""""""""""""""""""""""""""""""""""""""""""""" + +An alternative way of adding a build agent that will use docker (similar to the remote agents below) but running +locally, can be done using the jenkins/ssh-agent docker image `docker image `__. + +Prerequisites: + +1. Make sure to have Docker `installed `__ + +Agent setup: + +1. Create a new SSH key using ``ssh-keygen`` (if a passphrase is added, store it for later) + +2. Copy the public key content (e.g. in ~/.ssh/id_rsa.pub) + +3. Run: + + .. code:: bash + + docker run -d --name jenkins_agent -v /var/run/docker.sock:/var/run/docker.sock \ + jenkins/ssh-agent:latest "" + +4. Get the GID of the 'docker' group with ``cat /etc/groups`` and remember it for later + +5. Enter the agent's container with ``docker exec -it jenkins_agent bash`` + +6. Install Docker with ``apt update && apt install docker.io`` + +7. Check if group 'docker' already exists with ``cat /etc/groups``. If yes, remove it with ``groupdel docker`` + +8. Add a new 'docker' group with the same GID as seen in point 2 with ``groupadd -g docker`` + +9. Add 'jenkins' user to the group with ``usermod -aG docker jenkins`` + +10. Activate changes with ``newgrp docker`` + +11. Now check if 'jenkins' has the needed permissions to run docker commands + + 1. Log in as 'jenkins' with ``su jenkins`` + + 2. Try if ``docker inspect `` works or if a permission error occurs + + 3. If an permission error occurs, try to restart the docker container + +12. Now you can exit the container executing ``exit`` twice (the first will exit the jenkins user and + the second the container) + +Add agent in Jenkins: + +1. Open Jenkins in your browser (e.g. localhost:8082) + +2. Go to Manage Jenkins → Credentials → System → Global credentials (unrestricted) → Add Credentials + + - Kind: SSH Username with private key + + - Scope: Global (Jenkins, nodes, items, all child items, etc) + + - ID: leave blank + + - Description: Up to you + + - Username: jenkins + + - Private Key: (e.g /root/.ssh/id_rsa) + + - Passphrase: (you can leave it blank if none has been specified) + + .. figure:: jenkins-gitlab/alternative_jenkins_node_credentials.png + :align: center + +3. Go to Manage Jenkins → Nodes → New Node + + - Node name: Up to you (e.g. Docker agent node) + + - Check 'Permanent Agent' + + .. figure:: jenkins-gitlab/alternative_jenkins_node_setup.png + :align: center + +4. Node settings: + + - # of executors: Up to you (e.g. 4) + + - Remote root directory: /home/jenkins/agent + + - Labels: docker + + - Usage: Only build jobs with label expressions matching this node + + - Launch method: Launch agents via SSH + + - Host: output of command ``docker inspect --format '{{ .Config.Hostname }}' jenkins_agent`` + + - Credentials: + + - Host Key Verification Strategy: Non verifying Verification Strategy + + - Availability: Keep this agent online as much as possible + + .. figure:: jenkins-gitlab/alternative_jenkins_node.png + :align: center + +5. Save the new node + +6. Node should now be up and running + +Installing remote build agents +"""""""""""""""""""""""""""""" +You might want to run the builds on additional Jenkins agents, especially if a large amount of students should use +the system at the same time. +Jenkins supports remote build agents: The actual compilation of the students submissions happens on these +other machines but the whole process is transparent to Artemis. + +This guide explains setting up a remote agent on an Ubuntu virtual machine that supports docker builds. + +Prerequisites: +1. Install Docker on the remote machine: https://docs.docker.com/engine/install/ubuntu/ + +2. Add a new user to the remote machine that Jenkins will use: ``sudo adduser --disabled-password --gecos "" jenkins`` + +3. Add the jenkins user to the docker group (This allows the jenkins user to interact with docker): + ``sudo usermod -a -G docker jenkins`` + +4. Generate a new SSH key locally (e.g. using ``ssh-keygen``) and add the public key to the ``.ssh/authorized_keys`` + file of the jenkins user on the agent VM. + +5. Validate that you can connect to the build agent machine using SSH and the generated private key and validate that + you can use docker (`docker ps` should not show an error) + +6. Log in with your normal account on the build agent machine and install Java: ``sudo apt install default-jre`` + +7. Add a new secret in Jenkins, enter private key you just generated and add the passphrase, if set: + + .. figure:: jenkins-gitlab/jenkins_ssh_credentials.png + :align: center + + Jenkins SSH Credentials + +8. Add a new node (select a name and select `Permanent Agent`): + Set the number of executors so that it matches your machine's specs: This is the number of concurrent builds + this agent can handle. It is recommended to match the number of cores of the machine, + but you might want to adjust this later if needed. + + Set the remote root directory to ``/home/jenkins/remote_agent``. + + Set the usage to `Only build jobs with label expressions matching this node`. + This ensures that only docker-jobs will be built on this agent, and not other jobs. + + Add a label ``docker`` to the agent. + + Set the launch method to `Launch via SSH` and add the host of the machine. + Select the credentials you just created and select `Manually trusted key Verification Strategy` + as Host key verification Strategy. + Save it. + + + .. figure:: jenkins-gitlab/jenkins_node.png + :align: center + + Add a Jenkins node + +9. Wait for some moments while jenkins installs it's remote agent on the agent's machine. + You can track the progress using the `Log` page when selecting the agent. System information should also be available. + +10. Change the settings of the master node to be used only for specific jobs. + This ensures that the docker tasks are not executed on the master agent but on the remote agent. + + + .. figure:: jenkins-gitlab/jenkins_master_node.png + :align: center + + Adjust Jenkins master node settings + +11. You are finished, the new agent should now also process builds. + + +Jenkins User Management +^^^^^^^^^^^^^^^^^^^^^^^ + +Artemis supports user management in Jenkins as of version 4.11.0. Creating an account in Artemis will also create an +account on Jenkins using the same password. This enables users to login and access Jenkins. Updating and/or deleting +users from Artemis will also lead to updating and/or deleting from Jenkins. + +Unfortunately, Jenkins does not provide a Rest API for user management which present the following **caveats**: + + - The username of a user is treated as a unique identifier in Jenkins. + - It's not possible to update an existing user with a single request. + We update by deleting the user from Jenkins and recreating it with the updated data. + - In Jenkins, users are created in an on-demand basis. + For example, when a build is performed, its change log is computed and as a result commits from users + who Jenkins has never seen may be discovered and created. + - Since Jenkins users may be re-created automatically, issues may occur such as 1) creating a user, deleting it, + and then re-creating it and 2) changing the username of the user and reverting back to the previous one. + - Updating a user will re-create it in Jenkins and therefore remove any additionally saved Jenkins-specific + user data such as API access tokens. + + +Jenkins Build Plan Access Control Configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Artemis takes advantage of the Project-based Matrix Authorization Strategy plugin to support build plan +access control in Jenkins. +This enables specific Artemis users to access build plans and execute actions such as triggering a build. +This section explains the changes required in Jenkins in order to set up build plan access control: + +1. Navigate to Manage Jenkins → Plugins → Installed plugins and make sure that you have the + `Matrix Authorization Strategy `__ plugin installed + +2. Navigate to Manage Jenkins → Security and navigate to the "Authorization" section + +3. Select the "Project-based Matrix Authorization Strategy" option + +4. In the table make sure that the "Read" permission under the "Overall" section is assigned to + the "Authenticated Users" user group. + +5. In the table make sure that all "Administer" permission is assigned to all administrators. + +6. You are finished. If you want to fine-tune permissions assigned to teaching assistants and/or instructors, + you can change them within the ``JenkinsJobPermission.java`` file. + +.. figure:: jenkins-gitlab/jenkins_authorization_permissions.png + :align: center + + +Caching +^^^^^^^ + +You can configure caching for e.g. Maven repositories. +See :ref:`this section in the administration documentation ` for more details. From b2ccddb4fce8fdc8892346bf2593b6615b415f4d Mon Sep 17 00:00:00 2001 From: Stephan Krusche Date: Thu, 19 Sep 2024 22:28:23 +0200 Subject: [PATCH 08/49] Development: Mark Gitlab CI as deprecated in the README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 044b49dec4f5..556d5b40ac88 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ Setting up Artemis in your development environment or a demo production environm Artemis can also be set up in conjunction with external tools for version control and continuous integration: 1. [LocalVC and Jenkins](https://docs.artemis.cit.tum.de/dev/setup/#jenkins-and-localvc-setup) 2. [GitLab and Jenkins (deprecated)](https://docs.artemis.cit.tum.de/dev/setup/#jenkins-and-gitlab-setup) -3. [GitLab and GitLab CI (experimental)](https://docs.artemis.cit.tum.de/dev/setup/#gitlab-ci-and-gitlab-setup) +3. [GitLab and GitLab CI (experimental and deprecated)](https://docs.artemis.cit.tum.de/dev/setup/#gitlab-ci-and-gitlab-setup) Artemis uses these external tools for user management and the configuration of programming exercises. From c35ba633f9bf9573947af63c6994c7b020c9d2a8 Mon Sep 17 00:00:00 2001 From: Mohamed Bilel Besrour <58034472+BBesrour@users.noreply.github.com> Date: Thu, 19 Sep 2024 23:29:46 +0300 Subject: [PATCH 09/49] Integrated code lifecycle: Structure buildlogs folder (#9304) --- .../assessment/service/ResultService.java | 7 +- .../assessment/web/ResultResource.java | 2 +- .../repository/BuildJobRepository.java | 6 + .../ProgrammingExerciseRepository.java | 10 ++ .../service/BuildLogEntryService.java | 163 +++++++++++++++--- .../LocalCIResultProcessingService.java | 19 +- .../web/localci/BuildLogResource.java | 1 + .../localvcci/LocalCIIntegrationTest.java | 2 +- .../LocalCIResourceIntegrationTest.java | 15 +- .../service/ParticipationServiceTest.java | 2 +- 10 files changed, 183 insertions(+), 44 deletions(-) diff --git a/src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java b/src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java index 66a042ffea0e..fd0cb47e843b 100644 --- a/src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java +++ b/src/main/java/de/tum/cit/aet/artemis/assessment/service/ResultService.java @@ -450,10 +450,11 @@ public Result getResultForParticipationAndCheckAccess(Long participationId, Long /** * Get a map of result ids to the respective build job ids if build log files for this build job exist. * - * @param results the results for which to check the availability of build logs + * @param results the results for which to check the availability of build logs + * @param participation the participation the results belong to * @return a map of result ids to respective build job ids if the build log files exist, null otherwise */ - public Map getLogsAvailabilityForResults(List results) { + public Map getLogsAvailabilityForResults(List results, Participation participation) { Map logsAvailability = new HashMap<>(); @@ -466,7 +467,7 @@ public Map getLogsAvailabilityForResults(List results) { String buildJobId = resultBuildJobSet.get(resultId); if (buildJobId != null) { - if (buildLogEntryService.buildJobHasLogFile(buildJobId)) { + if (buildLogEntryService.buildJobHasLogFile(buildJobId, ((ProgrammingExerciseParticipation) participation).getProgrammingExercise())) { logsAvailability.put(resultId, buildJobId); } else { diff --git a/src/main/java/de/tum/cit/aet/artemis/assessment/web/ResultResource.java b/src/main/java/de/tum/cit/aet/artemis/assessment/web/ResultResource.java index ea8f2fcaa290..1692beaa7d69 100644 --- a/src/main/java/de/tum/cit/aet/artemis/assessment/web/ResultResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/assessment/web/ResultResource.java @@ -187,7 +187,7 @@ public ResponseEntity> getBuildJobIdsForResultsOfParticipation Participation participation = participationRepository.findByIdElseThrow(participationId); List results = resultRepository.findAllByParticipationIdOrderByCompletionDateDesc(participationId); - Map resultBuildJobMap = resultService.getLogsAvailabilityForResults(results); + Map resultBuildJobMap = resultService.getLogsAvailabilityForResults(results, participation); participationAuthCheckService.checkCanAccessParticipationElseThrow(participation); diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/repository/BuildJobRepository.java b/src/main/java/de/tum/cit/aet/artemis/programming/repository/BuildJobRepository.java index d97b7f03abd7..dfce5b56ef52 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/repository/BuildJobRepository.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/repository/BuildJobRepository.java @@ -114,4 +114,10 @@ default Page findAllWithDataByCourseId(long courseId, Pageable pageabl """) List getBuildJobsResultsStatistics(@Param("fromDateTime") ZonedDateTime fromDateTime, @Param("courseId") Long courseId); + Optional findByBuildJobId(String buildJobId); + + default BuildJob findByBuildJobIdElseThrow(String buildJobId) { + return getValueElseThrow(findByBuildJobId(buildJobId)); + } + } diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java b/src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java index f943d7824b84..32739a6eed1e 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java @@ -992,4 +992,14 @@ public String getFetchPath() { return fetchPath; } } + + /** + * Find a programming exercise by its id and throw an Exception if it cannot be found + * + * @param programmingExerciseId of the programming exercise. + * @return The programming exercise related to the given id + */ + default ProgrammingExercise findByIdElseThrow(long programmingExerciseId) { + return getValueElseThrow(findById(programmingExerciseId)); + } } diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/BuildLogEntryService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/BuildLogEntryService.java index 1c235dcce3b7..f6143a43561c 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/service/BuildLogEntryService.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/BuildLogEntryService.java @@ -24,10 +24,14 @@ import org.springframework.stereotype.Service; import de.tum.cit.aet.artemis.core.service.ProfileService; +import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise; import de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage; import de.tum.cit.aet.artemis.programming.domain.ProgrammingSubmission; +import de.tum.cit.aet.artemis.programming.domain.build.BuildJob; import de.tum.cit.aet.artemis.programming.domain.build.BuildLogEntry; +import de.tum.cit.aet.artemis.programming.repository.BuildJobRepository; import de.tum.cit.aet.artemis.programming.repository.BuildLogEntryRepository; +import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseRepository; import de.tum.cit.aet.artemis.programming.repository.ProgrammingSubmissionRepository; import de.tum.cit.aet.artemis.programming.service.ci.ContinuousIntegrationService; @@ -43,16 +47,23 @@ public class BuildLogEntryService { private final ProfileService profileService; + private final BuildJobRepository buildJobRepository; + + private final ProgrammingExerciseRepository programmingExerciseRepository; + @Value("${artemis.continuous-integration.build-log.file-expiry-days:30}") private int expiryDays; @Value("${artemis.build-logs-path:./build-logs}") private Path buildLogsPath; - public BuildLogEntryService(BuildLogEntryRepository buildLogEntryRepository, ProgrammingSubmissionRepository programmingSubmissionRepository, ProfileService profileService) { + public BuildLogEntryService(BuildLogEntryRepository buildLogEntryRepository, ProgrammingSubmissionRepository programmingSubmissionRepository, ProfileService profileService, + BuildJobRepository buildJobRepository, ProgrammingExerciseRepository programmingExerciseRepository) { this.buildLogEntryRepository = buildLogEntryRepository; this.programmingSubmissionRepository = programmingSubmissionRepository; this.profileService = profileService; + this.buildJobRepository = buildJobRepository; + this.programmingExerciseRepository = programmingExerciseRepository; } /** @@ -282,23 +293,34 @@ public void deleteBuildLogEntriesForProgrammingSubmission(ProgrammingSubmission } /** - * Save the build logs for a given submission to a file + * Saves a list of build log entries to a file for a specific build job. + * + *

    + * The log file path is constructed based on the course's short name, the exercise's short name, + * and the build job ID. If the directory structure for the logs does not already exist, it is created. + * Each log entry is written to the log file in the format of "time\tlog message". * - * @param buildLogEntries the build logs to save - * @param buildJobId the id of the build job for which to save the build logs + * @param buildLogEntries A list of {@link BuildLogEntry} objects containing the build log information to be saved. + * @param buildJobId The unique identifier of the build job whose logs are being saved. + * @param programmingExercise The programming exercise associated with the build job, used to + * retrieve the course and exercise short names. + * @throws IllegalStateException If the directory for storing the logs could not be created. + * @throws RuntimeException If an I/O error occurs while writing the log file. */ - public void saveBuildLogsToFile(List buildLogEntries, String buildJobId) { - - if (!Files.exists(buildLogsPath)) { + public void saveBuildLogsToFile(List buildLogEntries, String buildJobId, ProgrammingExercise programmingExercise) { + String courseShortName = programmingExercise.getCourseViaExerciseGroupOrCourseMember().getShortName(); + String exerciseShortName = programmingExercise.getShortName(); + Path exerciseLogsPath = buildLogsPath.resolve(courseShortName).resolve(exerciseShortName); + if (!Files.exists(exerciseLogsPath)) { try { - Files.createDirectories(buildLogsPath); + Files.createDirectories(exerciseLogsPath); } catch (Exception e) { throw new IllegalStateException("Could not create directory for build logs", e); } } - Path logPath = buildLogsPath.resolve(buildJobId + ".log"); + Path logPath = exerciseLogsPath.resolve(buildJobId + ".log"); StringBuilder logsStringBuilder = new StringBuilder(); for (BuildLogEntry buildLogEntry : buildLogEntries) { @@ -315,23 +337,49 @@ public void saveBuildLogsToFile(List buildLogEntries, String buil } /** - * Retrieves the build logs for a given submission from a file. + * Retrieves the build logs for a specific build job from the file system as a {@link FileSystemResource}. + * + *

    + * The method first attempts to locate the log file in the directory corresponding to the course + * and exercise short names. If the file is not found, it will attempt to retrieve the log from a + * parent directory for backward compatibility. * - * @param buildJobId the id of the build job for which to retrieve the build logs - * @return the build logs as a string or null if the file could not be found (e.g. if the build logs have been deleted) + * @param buildJobId The unique identifier of the build job whose logs are being retrieved. + * @return A {@link FileSystemResource} representing the log file if it exists, or {@code null} if the log file cannot be found. */ public FileSystemResource retrieveBuildLogsFromFileForBuildJob(String buildJobId) { - Path logPath = buildLogsPath.resolve(buildJobId + ".log"); + if (buildJobId.contains("/") || buildJobId.contains("\\") || buildJobId.contains("..")) { + log.warn("Invalid build job ID: {}", buildJobId); + throw new IllegalArgumentException("Invalid build job ID"); + } + + ProgrammingExercise programmingExercise = retrieveProgrammingExerciseByBuildJobId(buildJobId); + String courseShortName = programmingExercise.getCourseViaExerciseGroupOrCourseMember().getShortName(); + String exerciseShortName = programmingExercise.getShortName(); + Path logPath = buildLogsPath.resolve(courseShortName).resolve(exerciseShortName).resolve(buildJobId + ".log"); FileSystemResource fileSystemResource = new FileSystemResource(logPath); if (fileSystemResource.exists()) { log.debug("Retrieved build logs for build job {} from file {}", buildJobId, logPath); return fileSystemResource; } - else { - log.warn("Could not find build logs for build job {} in file {}", buildJobId, logPath); - return null; + + // If the file is not found in the exercise directory, try to find it in the parent directory (for backwards compatibility) + log.warn("Build log file for build job {} not found at path {}. Searching in Parent directory...", buildJobId, logPath); + logPath = buildLogsPath.resolve(buildJobId + ".log"); + fileSystemResource = new FileSystemResource(logPath); + if (fileSystemResource.exists()) { + log.debug("Retrieved build logs for build job {} from file {}", buildJobId, logPath); + return fileSystemResource; } + + log.warn("Could not find build logs for build job {} in file {}", buildJobId, logPath); + return null; + } + + private ProgrammingExercise retrieveProgrammingExerciseByBuildJobId(String buildJobId) { + BuildJob buildJob = buildJobRepository.findByBuildJobIdElseThrow(buildJobId); + return programmingExerciseRepository.findByIdElseThrow(buildJob.getExerciseId()); } /** @@ -359,25 +407,86 @@ public void deleteOldBuildLogsFiles() { if (!profileService.isSchedulingActive()) { return; } + log.info("Deleting old build log files"); - ZonedDateTime now = ZonedDateTime.now(); - try (DirectoryStream stream = Files.newDirectoryStream(buildLogsPath)) { - for (Path file : stream) { - ZonedDateTime lastModified = ZonedDateTime.ofInstant(Files.getLastModifiedTime(file).toInstant(), now.getZone()); - if (lastModified.isBefore(now.minusDays(expiryDays))) { - Files.deleteIfExists(file); - log.info("Deleted old build log file {}", file); - } - } + try { + deleteExpiredBuildLogFilesRecursively(buildLogsPath); } catch (IOException e) { log.error("Error occurred while trying to delete old build log files", e); } } - public boolean buildJobHasLogFile(String buildJobId) { - Path logPath = buildLogsPath.resolve(buildJobId + ".log"); + private void deleteExpiredBuildLogFilesRecursively(Path path) throws IOException { + if (!Files.isDirectory(path)) { + deleteFileIfExpired(path); + return; + } + + try (DirectoryStream stream = Files.newDirectoryStream(path)) { + for (Path subPath : stream) { + deleteExpiredBuildLogFilesRecursively(subPath); + } + } + catch (IOException e) { + log.error("Error occurred while processing directory: {}", path, e); + } + + if (!path.equals(buildLogsPath)) { + deleteDirectoryIfEmpty(path); + } + } + + private void deleteFileIfExpired(Path file) throws IOException { + ZonedDateTime now = ZonedDateTime.now(); + + ZonedDateTime lastModified = ZonedDateTime.ofInstant(Files.getLastModifiedTime(file).toInstant(), now.getZone()); + if (Files.isRegularFile(file) && lastModified.isBefore(now.minusDays(expiryDays))) { + Files.deleteIfExists(file); + log.info("Deleted old build log file {}", file); + } + + } + + private void deleteDirectoryIfEmpty(Path directory) { + if (Files.isDirectory(directory)) { + try (DirectoryStream stream = Files.newDirectoryStream(directory)) { + if (!stream.iterator().hasNext()) { + Files.deleteIfExists(directory); + log.info("Deleted empty directory {}", directory); + } + } + catch (IOException e) { + log.error("Error occurred while trying to delete empty directory {}", directory, e); + } + } + } + + /** + * Checks if the log file for a specific build job exists in the file system. + * + *

    + * The log file path is constructed based on the course's short name, the exercise's short name, + * and the build job ID. The file is expected to be located at: + * {@code buildLogsPath///.log}. + * + * @param buildJobId The unique identifier of the build job whose log file is being checked. + * @param programmingExercise The programming exercise associated with the build job, used to + * retrieve the course and exercise short names. + * @return {@code true} if the log file exists, otherwise {@code false}. + */ + public boolean buildJobHasLogFile(String buildJobId, ProgrammingExercise programmingExercise) { + String courseShortName = programmingExercise.getCourseViaExerciseGroupOrCourseMember().getShortName(); + String exerciseShortName = programmingExercise.getShortName(); + Path logPath = buildLogsPath.resolve(courseShortName).resolve(exerciseShortName).resolve(buildJobId + ".log"); + boolean existsInExerciseFolder = Files.exists(logPath); + if (existsInExerciseFolder) { + return true; + } + + // Check parent folder for backwards compatibility + logPath = buildLogsPath.resolve(buildJobId + ".log"); return Files.exists(logPath); } diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIResultProcessingService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIResultProcessingService.java index 5c033aab1aaa..39bfac28ca0b 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIResultProcessingService.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIResultProcessingService.java @@ -159,6 +159,9 @@ public void processResult() { if (participationOptional.isPresent()) { ProgrammingExerciseParticipation participation = (ProgrammingExerciseParticipation) participationOptional.get(); + if (participation.getExercise() == null) { + participation.setExercise(programmingExerciseRepository.getProgrammingExerciseFromParticipation(participation)); + } if (result != null) { programmingMessagingService.notifyUserAboutNewResult(result, participation); @@ -168,15 +171,15 @@ public void processResult() { programmingMessagingService.notifyUserAboutSubmissionError((Participation) participation, new BuildTriggerWebsocketError("Result could not be processed", participation.getId())); } - } - } - if (!buildLogs.isEmpty()) { - if (savedBuildJob != null) { - buildLogEntryService.saveBuildLogsToFile(buildLogs, savedBuildJob.getBuildJobId()); - } - else { - log.warn("Couldn't save build logs as build job {} was not saved", buildJob.id()); + if (!buildLogs.isEmpty()) { + if (savedBuildJob != null) { + buildLogEntryService.saveBuildLogsToFile(buildLogs, savedBuildJob.getBuildJobId(), participation.getProgrammingExercise()); + } + else { + log.warn("Couldn't save build logs as build job {} was not saved", buildJob.id()); + } + } } } diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/web/localci/BuildLogResource.java b/src/main/java/de/tum/cit/aet/artemis/programming/web/localci/BuildLogResource.java index 9ab8cfba30db..c8fd18e69fca 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/web/localci/BuildLogResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/web/localci/BuildLogResource.java @@ -43,6 +43,7 @@ public BuildLogResource(BuildLogEntryService buildLogEntryService) { public ResponseEntity getBuildLogForBuildJob(@PathVariable String buildJobId) { log.debug("REST request to get the build log for build job {}", buildJobId); HttpHeaders responseHeaders = new HttpHeaders(); + FileSystemResource buildLog = buildLogEntryService.retrieveBuildLogsFromFileForBuildJob(buildJobId); if (buildLog == null) { return new ResponseEntity<>(HttpStatus.NOT_FOUND); diff --git a/src/test/java/de/tum/cit/aet/artemis/localvcci/LocalCIIntegrationTest.java b/src/test/java/de/tum/cit/aet/artemis/localvcci/LocalCIIntegrationTest.java index 10fea95376be..684439d104d9 100644 --- a/src/test/java/de/tum/cit/aet/artemis/localvcci/LocalCIIntegrationTest.java +++ b/src/test/java/de/tum/cit/aet/artemis/localvcci/LocalCIIntegrationTest.java @@ -444,7 +444,7 @@ void testBuildLogs() throws IOException { assertThat(resultBuildJobSet.iterator().next().buildJobId()).isEqualTo(buildJob.getBuildJobId()); // Assert that the corresponding build job are stored in the file system - assertThat(buildLogEntryService.buildJobHasLogFile(buildJob.getBuildJobId())).isTrue(); + assertThat(buildLogEntryService.buildJobHasLogFile(buildJob.getBuildJobId(), studentParticipation.getProgrammingExercise())).isTrue(); // Retrieve the build logs from the file system buildLogs = buildLogEntryService.retrieveBuildLogsFromFileForBuildJob(buildJob.getBuildJobId()); diff --git a/src/test/java/de/tum/cit/aet/artemis/localvcci/LocalCIResourceIntegrationTest.java b/src/test/java/de/tum/cit/aet/artemis/localvcci/LocalCIResourceIntegrationTest.java index 0a553702716a..9c048bb7696a 100644 --- a/src/test/java/de/tum/cit/aet/artemis/localvcci/LocalCIResourceIntegrationTest.java +++ b/src/test/java/de/tum/cit/aet/artemis/localvcci/LocalCIResourceIntegrationTest.java @@ -54,6 +54,8 @@ class LocalCIResourceIntegrationTest extends AbstractLocalCILocalVCIntegrationTe protected BuildJob finishedJob3; + protected BuildJob finishedJobForLogs; + @Autowired @Qualifier("hazelcastInstance") private HazelcastInstance hazelcastInstance; @@ -95,17 +97,22 @@ void createJobs() { buildConfig, null); BuildJobQueueItem finishedJobQueueItem3 = new BuildJobQueueItem("5", "job5", "address1", 5, course.getId() + 2, 1, 1, 1, BuildStatus.FAILED, repositoryInfo, jobTimingInfo3, buildConfig, null); + BuildJobQueueItem finishedJobQueueItemForLogs = new BuildJobQueueItem("6", "job5", "address1", 5, course.getId(), programmingExercise.getId(), 1, 1, BuildStatus.FAILED, + repositoryInfo, jobTimingInfo3, buildConfig, null); var result1 = new Result().successful(true).rated(true).score(100D).assessmentType(AssessmentType.AUTOMATIC).completionDate(ZonedDateTime.now()); var result2 = new Result().successful(false).rated(true).score(0D).assessmentType(AssessmentType.AUTOMATIC).completionDate(ZonedDateTime.now()); var result3 = new Result().successful(false).rated(true).score(0D).assessmentType(AssessmentType.AUTOMATIC).completionDate(ZonedDateTime.now()); + var resultForLogs = new Result().successful(false).rated(true).score(0D).assessmentType(AssessmentType.AUTOMATIC).completionDate(ZonedDateTime.now()); resultRepository.save(result1); resultRepository.save(result2); resultRepository.save(result3); + resultRepository.save(resultForLogs); finishedJob1 = new BuildJob(finishedJobQueueItem1, BuildStatus.SUCCESSFUL, result1); finishedJob2 = new BuildJob(finishedJobQueueItem2, BuildStatus.FAILED, result2); finishedJob3 = new BuildJob(finishedJobQueueItem3, BuildStatus.FAILED, result3); + finishedJobForLogs = new BuildJob(finishedJobQueueItemForLogs, BuildStatus.FAILED, resultForLogs); queuedJobs = hazelcastInstance.getQueue("buildJobQueue"); processingJobs = hazelcastInstance.getMap("processingJobs"); @@ -321,13 +328,15 @@ void testGetBuildAgents_instructorAccessForbidden() throws Exception { @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR") void testGetBuildLogsForResult() throws Exception { try { + buildJobRepository.save(finishedJobForLogs); BuildLogEntry buildLogEntry = new BuildLogEntry(ZonedDateTime.now(), "Dummy log"); - buildLogEntryService.saveBuildLogsToFile(List.of(buildLogEntry), "0"); - var response = request.get("/api/build-log/0", HttpStatus.OK, String.class); + buildLogEntryService.saveBuildLogsToFile(List.of(buildLogEntry), "6", programmingExercise); + var response = request.get("/api/build-log/6", HttpStatus.OK, String.class); assertThat(response).contains("Dummy log"); } finally { - Path buildLogFile = Path.of("build-logs", "0.log"); + Path buildLogFile = Path.of("build-logs").resolve(programmingExercise.getCourseViaExerciseGroupOrCourseMember().getShortName()) + .resolve(programmingExercise.getShortName()).resolve("6.log"); Files.deleteIfExists(buildLogFile); } } diff --git a/src/test/java/de/tum/cit/aet/artemis/service/ParticipationServiceTest.java b/src/test/java/de/tum/cit/aet/artemis/service/ParticipationServiceTest.java index 7ba508ff7fef..89965b5a87e1 100644 --- a/src/test/java/de/tum/cit/aet/artemis/service/ParticipationServiceTest.java +++ b/src/test/java/de/tum/cit/aet/artemis/service/ParticipationServiceTest.java @@ -142,7 +142,7 @@ void testGetBuildJobsForResultsOfParticipation() throws Exception { List results = resultRepository.findAllByParticipationIdOrderByCompletionDateDesc(participation.getId()); - Map resultBuildJobMap = resultService.getLogsAvailabilityForResults(results); + Map resultBuildJobMap = resultService.getLogsAvailabilityForResults(results, participation); assertThat(resultBuildJobMap).hasSize(0); assertThat(participation).isNotNull(); assertThat(participation.getSubmissions()).hasSize(1); From 2d3848865e4882d6bd9ccf22ab925303ee69d90c Mon Sep 17 00:00:00 2001 From: Simon Entholzer <33342534+SimonEntholzer@users.noreply.github.com> Date: Thu, 19 Sep 2024 22:35:21 +0200 Subject: [PATCH 10/49] Development: Add access log for LocalVC repositories (#9184) --- .../domain/AuthenticationMechanism.java | 24 ++++ .../programming/domain/VcsAccessLog.java | 107 ++++++++++++++++++ .../programming/dto/VcsAccessLogDTO.java | 29 +++++ .../repository/VcsAccessLogRepository.java | 74 ++++++++++++ .../service/RepositoryService.java | 12 +- .../AutomaticVcsAccessLogCleanupService.java | 38 +++++++ .../localvc/LocalVCServletService.java | 60 +++++++++- .../SshGitLocationResolverService.java | 4 +- .../service/localvc/VcsAccessLogService.java | 86 ++++++++++++++ ...grammingExerciseParticipationResource.java | 63 ++++++++++- .../web/repository/RepositoryResource.java | 2 +- .../resources/config/application-prod.yml | 3 +- .../changelog/20240804144500_changelog.xml | 46 ++++++++ .../resources/config/liquibase/master.xml | 2 + .../entities/vcs-access-log-entry.model.ts | 13 +++ ...ming-exercise-management-routing.module.ts | 25 ++++ ...gramming-exercise-participation.service.ts | 28 +++++ .../repository-view.component.html | 7 ++ .../repository-view.component.ts | 15 ++- ...-repository-access-log-view.component.html | 34 ++++++ ...cs-repository-access-log-view.component.ts | 65 +++++++++++ src/main/webapp/i18n/de/repository.json | 11 ++ src/main/webapp/i18n/en/repository.json | 11 ++ ...VCLocalCIParticipationIntegrationTest.java | 45 ++++++++ .../localvc/repository-view.component.spec.ts | 14 ++- ...pository-access-log-view.component.spec.ts | 87 ++++++++++++++ ...gramming-exercise-participation.service.ts | 3 + ...ing-exercise-participation.service.spec.ts | 17 +++ 28 files changed, 909 insertions(+), 16 deletions(-) create mode 100644 src/main/java/de/tum/cit/aet/artemis/programming/domain/AuthenticationMechanism.java create mode 100644 src/main/java/de/tum/cit/aet/artemis/programming/domain/VcsAccessLog.java create mode 100644 src/main/java/de/tum/cit/aet/artemis/programming/dto/VcsAccessLogDTO.java create mode 100644 src/main/java/de/tum/cit/aet/artemis/programming/repository/VcsAccessLogRepository.java create mode 100644 src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/AutomaticVcsAccessLogCleanupService.java create mode 100644 src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/VcsAccessLogService.java create mode 100644 src/main/resources/config/liquibase/changelog/20240804144500_changelog.xml create mode 100644 src/main/webapp/app/entities/vcs-access-log-entry.model.ts create mode 100644 src/main/webapp/app/localvc/vcs-repository-access-log-view/vcs-repository-access-log-view.component.html create mode 100644 src/main/webapp/app/localvc/vcs-repository-access-log-view/vcs-repository-access-log-view.component.ts create mode 100644 src/test/javascript/spec/component/localvc/vcs-repository-access-log-view.component.spec.ts diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/domain/AuthenticationMechanism.java b/src/main/java/de/tum/cit/aet/artemis/programming/domain/AuthenticationMechanism.java new file mode 100644 index 000000000000..3caec801ed53 --- /dev/null +++ b/src/main/java/de/tum/cit/aet/artemis/programming/domain/AuthenticationMechanism.java @@ -0,0 +1,24 @@ +package de.tum.cit.aet.artemis.programming.domain; + +public enum AuthenticationMechanism { + /** + * The user used password to authenticate to the LocalVC + */ + PASSWORD, + /** + * The user used the participation+user token to authenticate to the LocalVC + */ + PARTICIPATION_VCS_ACCESS_TOKEN, + /** + * The user used the user token to authenticate to the LocalVC + */ + USER_VCS_ACCESS_TOKEN, + /** + * The user used SSH user token to authenticate to the LocalVC + */ + SSH, + /** + * The user used the artemis client code editor to authenticate to the LocalVC + */ + CODE_EDITOR +} diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/domain/VcsAccessLog.java b/src/main/java/de/tum/cit/aet/artemis/programming/domain/VcsAccessLog.java new file mode 100644 index 000000000000..560ca52a31c1 --- /dev/null +++ b/src/main/java/de/tum/cit/aet/artemis/programming/domain/VcsAccessLog.java @@ -0,0 +1,107 @@ +package de.tum.cit.aet.artemis.programming.domain; + +import java.time.ZonedDateTime; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; + +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import de.tum.cit.aet.artemis.core.domain.DomainObject; +import de.tum.cit.aet.artemis.core.domain.User; +import de.tum.cit.aet.artemis.exercise.domain.participation.Participation; +import de.tum.cit.aet.artemis.programming.web.repository.RepositoryActionType; + +/** + * A Vcs access log entry. + */ +@Entity +@Table(name = "vcs_access_log") +@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class VcsAccessLog extends DomainObject { + + @ManyToOne + private User user; + + @ManyToOne + private Participation participation; + + @Column(name = "name") + private String name; + + @Column(name = "email") + private String email; + + @Column(name = "repository_action_type", nullable = false) + @Enumerated(EnumType.ORDINAL) + private RepositoryActionType repositoryActionType; + + @Column(name = "authentication_mechanism", nullable = false) + @Enumerated(EnumType.ORDINAL) + private AuthenticationMechanism authenticationMechanism; + + @Column(name = "commit_hash") + private String commitHash; + + @Column(name = "ip_address") + private String ipAddress; + + @Column(name = "timestamp") + private ZonedDateTime timestamp; + + public VcsAccessLog(User user, Participation participation, String name, String email, RepositoryActionType repositoryActionType, + AuthenticationMechanism authenticationMechanism, String commitHash, String ipAddress) { + this.user = user; + this.participation = participation; + this.name = name; + this.email = email; + this.repositoryActionType = repositoryActionType; + this.authenticationMechanism = authenticationMechanism; + this.commitHash = commitHash; + this.ipAddress = ipAddress; + this.timestamp = ZonedDateTime.now(); + } + + public VcsAccessLog() { + } + + public void setCommitHash(String commitHash) { + this.commitHash = commitHash; + } + + public User getUser() { + return user; + } + + public String getName() { + return name; + } + + public String getEmail() { + return email; + } + + public String getCommitHash() { + return commitHash; + } + + public ZonedDateTime getTimestamp() { + return timestamp; + } + + public AuthenticationMechanism getAuthenticationMechanism() { + return authenticationMechanism; + } + + public RepositoryActionType getRepositoryActionType() { + return repositoryActionType; + } +} diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/dto/VcsAccessLogDTO.java b/src/main/java/de/tum/cit/aet/artemis/programming/dto/VcsAccessLogDTO.java new file mode 100644 index 000000000000..b9896cf6efbe --- /dev/null +++ b/src/main/java/de/tum/cit/aet/artemis/programming/dto/VcsAccessLogDTO.java @@ -0,0 +1,29 @@ +package de.tum.cit.aet.artemis.programming.dto; + +import java.time.ZonedDateTime; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import de.tum.cit.aet.artemis.programming.domain.VcsAccessLog; + +/** + * DTO representing a VCS access log entry. + * + * @param id The id of the access log entry. + * @param userId The user's id associated with the access log event. + * @param name The name associated with the user. + * @param email The email associated with the user. + * @param repositoryActionType The type of action performed in the repository (read or write). + * @param authenticationMechanism The method the user used for authenticating to the repository. + * @param commitHash The latest commit hash at the access event. + * @param timestamp The date and time when the access event occurred. + */ +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public record VcsAccessLogDTO(Long id, Long userId, String name, String email, String repositoryActionType, String authenticationMechanism, String commitHash, + ZonedDateTime timestamp) { + + public static VcsAccessLogDTO of(VcsAccessLog vcsAccessLog) { + return new VcsAccessLogDTO(vcsAccessLog.getId(), vcsAccessLog.getUser().getId(), vcsAccessLog.getName(), vcsAccessLog.getEmail(), + vcsAccessLog.getRepositoryActionType().name(), vcsAccessLog.getAuthenticationMechanism().name(), vcsAccessLog.getCommitHash(), vcsAccessLog.getTimestamp()); + } +} diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/repository/VcsAccessLogRepository.java b/src/main/java/de/tum/cit/aet/artemis/programming/repository/VcsAccessLogRepository.java new file mode 100644 index 000000000000..af342179e111 --- /dev/null +++ b/src/main/java/de/tum/cit/aet/artemis/programming/repository/VcsAccessLogRepository.java @@ -0,0 +1,74 @@ +package de.tum.cit.aet.artemis.programming.repository; + +import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_LOCALVC; + +import java.time.ZonedDateTime; +import java.util.List; +import java.util.Optional; + +import org.springframework.context.annotation.Profile; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository; +import de.tum.cit.aet.artemis.programming.domain.VcsAccessLog; + +/** + * Spring Data JPA repository for the User entity.
    + *
    + *

    + * Note: Please keep in mind that the User entities are soft-deleted when adding new queries to this repository. + * If you don't need deleted user entities, add `WHERE user.isDeleted = FALSE` to your query. + *

    + */ +@Profile(PROFILE_LOCALVC) +@Repository +public interface VcsAccessLogRepository extends ArtemisJpaRepository { + + /** + * Find the access log entry which does not have any commit hash yet + * + * @param participationId The id of the participation the repository belongs to + * @return a log entry belonging to the participationId, which has no commit hash + */ + @Query(""" + SELECT vcsAccessLog + FROM VcsAccessLog vcsAccessLog + WHERE vcsAccessLog.participation.id = :participationId + AND vcsAccessLog.commitHash IS NULL + ORDER BY vcsAccessLog.timestamp DESC + LIMIT 1 + """) + Optional findNewestByParticipationIdWhereCommitHashIsNull(@Param("participationId") long participationId); + + /** + * Retrieves a list of {@link VcsAccessLog} entities associated with the specified participation ID. + * The results are ordered by the log ID in ascending order. + * + * @param participationId the ID of the participation to filter the access logs by. + * @return a list of {@link VcsAccessLog} entities for the given participation ID, sorted by log ID in ascending order. + */ + @Query(""" + SELECT vcsAccessLog + FROM VcsAccessLog vcsAccessLog + WHERE vcsAccessLog.participation.id = :participationId + ORDER BY vcsAccessLog.id ASC + """) + List findAllByParticipationId(@Param("participationId") long participationId); + + /** + * Retrieves a list of {@link VcsAccessLog} entities associated with the specified participation ID. + * The results are ordered by the log ID in ascending order. + * + * @param date The date before which all log ids should be fetched + * + * @return a list of ids of the access logs, which have a timestamp before the date + */ + @Query(""" + SELECT vcsAccessLog.id + FROM VcsAccessLog vcsAccessLog + WHERE vcsAccessLog.timestamp < :date + """) + List findAllIdsBeforeDate(@Param("date") ZonedDateTime date); +} diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/RepositoryService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/RepositoryService.java index c181815e2143..ed5dd6cbae45 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/service/RepositoryService.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/RepositoryService.java @@ -47,6 +47,7 @@ import de.tum.cit.aet.artemis.programming.domain.RepositoryType; import de.tum.cit.aet.artemis.programming.domain.VcsRepositoryUri; import de.tum.cit.aet.artemis.programming.dto.FileMove; +import de.tum.cit.aet.artemis.programming.service.localvc.VcsAccessLogService; /** * Service that provides utilities for managing files in a git repository. @@ -59,11 +60,14 @@ public class RepositoryService { private final ProfileService profileService; + private final Optional vcsAccessLogService; + private static final Logger log = LoggerFactory.getLogger(RepositoryService.class); - public RepositoryService(GitService gitService, ProfileService profileService) { + public RepositoryService(GitService gitService, ProfileService profileService, Optional vcsAccessLogService) { this.gitService = gitService; this.profileService = profileService; + this.vcsAccessLogService = vcsAccessLogService; } /** @@ -468,11 +472,15 @@ public void pullChanges(Repository repository) { * * @param repository for which to execute the commit. * @param user the user who has committed the changes in the online editor + * @param domainId the id of the domain Object (participation) owning the repository * @throws GitAPIException if the staging/committing process fails. */ - public void commitChanges(Repository repository, User user) throws GitAPIException { + public void commitChanges(Repository repository, User user, Long domainId) throws GitAPIException { gitService.stageAllChanges(repository); gitService.commitAndPush(repository, "Changes by Online Editor", true, user); + if (vcsAccessLogService.isPresent()) { + vcsAccessLogService.get().storeCodeEditorAccessLog(repository, user, domainId); + } } /** diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/AutomaticVcsAccessLogCleanupService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/AutomaticVcsAccessLogCleanupService.java new file mode 100644 index 000000000000..f438a093edf6 --- /dev/null +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/AutomaticVcsAccessLogCleanupService.java @@ -0,0 +1,38 @@ +package de.tum.cit.aet.artemis.programming.service.localvc; + +import java.time.ZonedDateTime; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Profile; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import de.tum.cit.aet.artemis.programming.repository.VcsAccessLogRepository; + +@Service +@Profile("scheduling & localvc") +public class AutomaticVcsAccessLogCleanupService { + + private static final Logger log = LoggerFactory.getLogger(AutomaticVcsAccessLogCleanupService.class); + + private final VcsAccessLogRepository vcsAccessLogRepository; + + @Value("${artemis.audit-events.retention-period:120}") + private int vcsAccessLogRetentionPeriod; + + public AutomaticVcsAccessLogCleanupService(VcsAccessLogRepository vcsAccessLogRepository) { + this.vcsAccessLogRepository = vcsAccessLogRepository; + } + + /** + * Deletes all vcs access log entries from the database which have a timestamp older than vcsAccessLogRetentionPeriod days (120 by default) + */ + @Scheduled(cron = "0 30 2 * * *") // execute this every night at 2:30:00 am + public void cleanup() { + var outDatedAccessLogs = vcsAccessLogRepository.findAllIdsBeforeDate(ZonedDateTime.now().minusDays(vcsAccessLogRetentionPeriod)); + log.info("Scheduled deletion of expired access log entries: deleting {} vcs access log entries", outDatedAccessLogs.size()); + vcsAccessLogRepository.deleteAllById(outDatedAccessLogs); + } +} diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/LocalVCServletService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/LocalVCServletService.java index f331ead9ad44..90186a8c2c31 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/LocalVCServletService.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/LocalVCServletService.java @@ -49,6 +49,7 @@ import de.tum.cit.aet.artemis.core.security.SecurityUtils; import de.tum.cit.aet.artemis.core.service.AuthorizationCheckService; import de.tum.cit.aet.artemis.core.util.TimeLogUtil; +import de.tum.cit.aet.artemis.programming.domain.AuthenticationMechanism; import de.tum.cit.aet.artemis.programming.domain.Commit; import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise; import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseParticipation; @@ -100,6 +101,9 @@ public class LocalVCServletService { private final ProgrammingTriggerService programmingTriggerService; + // TODO As soon as only LocalVC is supported, this Optional can be removed + private final Optional vcsAccessLogService; + private static URL localVCBaseUrl; private final ParticipationVCSAccessTokenRepository participationVCSAccessTokenRepository; @@ -132,7 +136,7 @@ public LocalVCServletService(AuthenticationManager authenticationManager, UserRe ProgrammingExerciseParticipationService programmingExerciseParticipationService, AuxiliaryRepositoryService auxiliaryRepositoryService, ContinuousIntegrationTriggerService ciTriggerService, ProgrammingSubmissionService programmingSubmissionService, ProgrammingMessagingService programmingMessagingService, ProgrammingTriggerService programmingTriggerService, - ParticipationVCSAccessTokenRepository participationVCSAccessTokenRepository) { + ParticipationVCSAccessTokenRepository participationVCSAccessTokenRepository, Optional vcsAccessLogService) { this.authenticationManager = authenticationManager; this.userRepository = userRepository; this.programmingExerciseRepository = programmingExerciseRepository; @@ -145,6 +149,7 @@ public LocalVCServletService(AuthenticationManager authenticationManager, UserRe this.programmingMessagingService = programmingMessagingService; this.programmingTriggerService = programmingTriggerService; this.participationVCSAccessTokenRepository = participationVCSAccessTokenRepository; + this.vcsAccessLogService = vcsAccessLogService; } /** @@ -238,13 +243,36 @@ public void authenticateAndAuthorizeGitRequest(HttpServletRequest request, Repos throw new LocalVCForbiddenException(); } - authorizeUser(repositoryTypeOrUserName, user, exercise, repositoryAction, localVCRepositoryUri.isPracticeRepository()); + var authenticationMechanism = resolveAuthenticationMechanism(authorizationHeader, user); + var ipAddress = request.getRemoteAddr(); + authorizeUser(repositoryTypeOrUserName, user, exercise, repositoryAction, authenticationMechanism, ipAddress, localVCRepositoryUri); request.setAttribute("user", user); log.debug("Authorizing user {} for repository {} took {}", user.getLogin(), localVCRepositoryUri, TimeLogUtil.formatDurationFrom(timeNanoStart)); } + /** + * Resolves the user's authentication mechanism for the repository + * + * @param authorizationHeader the request's authorizationHeader, containing the token or password + * @param user the user + * @return the authentication type + * @throws LocalVCAuthException if extracting the token or password from the authorizationHeader fails + */ + private AuthenticationMechanism resolveAuthenticationMechanism(String authorizationHeader, User user) throws LocalVCAuthException { + UsernameAndPassword usernameAndPassword = extractUsernameAndPassword(authorizationHeader); + + String password = usernameAndPassword.password(); + if (!password.startsWith(TOKEN_PREFIX)) { + return AuthenticationMechanism.PASSWORD; + } + if (password.equals(user.getVcsAccessToken())) { + return AuthenticationMechanism.USER_VCS_ACCESS_TOKEN; + } + return AuthenticationMechanism.PARTICIPATION_VCS_ACCESS_TOKEN; + } + private User authenticateUser(String authorizationHeader, ProgrammingExercise exercise, LocalVCRepositoryUri localVCRepositoryUri) throws LocalVCAuthException { UsernameAndPassword usernameAndPassword = extractUsernameAndPassword(authorizationHeader); @@ -377,11 +405,14 @@ private UsernameAndPassword extractUsernameAndPassword(String authorizationHeade * @param user The user that wants to access the repository. * @param exercise The exercise the repository belongs to. * @param repositoryActionType The type of the action the user wants to perform. - * @param isPracticeRepository Whether the repository is a practice repository. + * @param authenticationMechanism The authentication mechanism used by the user to authenticate to the repository + * @param ipAddress The ip address of the user + * @param localVCRepositoryUri The URI of the local repository. + * * @throws LocalVCForbiddenException If the user is not allowed to access the repository. */ - public void authorizeUser(String repositoryTypeOrUserName, User user, ProgrammingExercise exercise, RepositoryActionType repositoryActionType, boolean isPracticeRepository) - throws LocalVCForbiddenException { + public void authorizeUser(String repositoryTypeOrUserName, User user, ProgrammingExercise exercise, RepositoryActionType repositoryActionType, + AuthenticationMechanism authenticationMechanism, String ipAddress, LocalVCRepositoryUri localVCRepositoryUri) throws LocalVCForbiddenException { if (repositoryTypeOrUserName.equals(RepositoryType.TESTS.toString()) || auxiliaryRepositoryService.isAuxiliaryRepositoryOfExercise(repositoryTypeOrUserName, exercise)) { // Test and auxiliary repositories are only accessible by instructors and higher. @@ -396,7 +427,8 @@ public void authorizeUser(String repositoryTypeOrUserName, User user, Programmin ProgrammingExerciseParticipation participation; try { - participation = programmingExerciseParticipationService.getParticipationForRepository(exercise, repositoryTypeOrUserName, isPracticeRepository, false); + participation = programmingExerciseParticipationService.getParticipationForRepository(exercise, repositoryTypeOrUserName, localVCRepositoryUri.isPracticeRepository(), + false); } catch (EntityNotFoundException e) { throw new LocalVCInternalException( @@ -409,6 +441,18 @@ public void authorizeUser(String repositoryTypeOrUserName, User user, Programmin catch (AccessForbiddenException e) { throw new LocalVCForbiddenException(e); } + String commitHash = null; + try { + if (repositoryActionType == RepositoryActionType.READ) { + commitHash = getLatestCommitHash(repositories.get(localVCRepositoryUri.getRelativeRepositoryPath().toString())); + } + } + catch (GitAPIException e) { + log.warn("Failed to obtain commit hash for repository {}. Error: {}", localVCRepositoryUri.getRelativeRepositoryPath().toString(), e.getMessage()); + } + // Write a access log entry to the database + String finalCommitHash = commitHash; + vcsAccessLogService.ifPresent(service -> service.storeAccessLog(user, participation, repositoryActionType, authenticationMechanism, finalCommitHash, ipAddress)); } /** @@ -475,6 +519,10 @@ public void processNewPush(String commitHash, Repository repository) { // Process push to any repository other than the test repository. processNewPushToRepository(participation, commit); + + // For push the correct commitHash is only available here, therefore the preliminary null value is overwritten + String finalCommitHash = commitHash; + vcsAccessLogService.ifPresent(service -> service.updateCommitHash(participation, finalCommitHash)); } catch (GitAPIException | IOException e) { // This catch clause does not catch exceptions that happen during runBuildJob() as that method is called asynchronously. diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/SshGitLocationResolverService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/SshGitLocationResolverService.java index 99b90e06425d..a61712685ef7 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/SshGitLocationResolverService.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/SshGitLocationResolverService.java @@ -21,6 +21,7 @@ import de.tum.cit.aet.artemis.core.exception.EntityNotFoundException; import de.tum.cit.aet.artemis.core.exception.localvc.LocalVCForbiddenException; import de.tum.cit.aet.artemis.core.exception.localvc.LocalVCInternalException; +import de.tum.cit.aet.artemis.programming.domain.AuthenticationMechanism; import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise; import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseRepository; import de.tum.cit.aet.artemis.programming.service.localvc.ssh.SshConstants; @@ -76,7 +77,8 @@ public Path resolveRootDirectory(String command, String[] args, ServerSession se else { final var user = session.getAttribute(SshConstants.USER_KEY); try { - localVCServletService.authorizeUser(repositoryTypeOrUserName, user, exercise, repositoryAction, localVCRepositoryUri.isPracticeRepository()); + localVCServletService.authorizeUser(repositoryTypeOrUserName, user, exercise, repositoryAction, AuthenticationMechanism.SSH, session.getClientAddress().toString(), + localVCRepositoryUri); } catch (LocalVCForbiddenException e) { log.error("User {} does not have access to the repository {}", user.getLogin(), repositoryPath); diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/VcsAccessLogService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/VcsAccessLogService.java new file mode 100644 index 000000000000..d77b37c02a7f --- /dev/null +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/VcsAccessLogService.java @@ -0,0 +1,86 @@ +package de.tum.cit.aet.artemis.programming.service.localvc; + +import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_LOCALVC; + +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import de.tum.cit.aet.artemis.core.domain.User; +import de.tum.cit.aet.artemis.exercise.domain.participation.Participation; +import de.tum.cit.aet.artemis.exercise.repository.ParticipationRepository; +import de.tum.cit.aet.artemis.programming.domain.AuthenticationMechanism; +import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseParticipation; +import de.tum.cit.aet.artemis.programming.domain.Repository; +import de.tum.cit.aet.artemis.programming.domain.VcsAccessLog; +import de.tum.cit.aet.artemis.programming.repository.VcsAccessLogRepository; +import de.tum.cit.aet.artemis.programming.web.repository.RepositoryActionType; + +@Profile(PROFILE_LOCALVC) +@Service +public class VcsAccessLogService { + + private static final Logger log = LoggerFactory.getLogger(VcsAccessLogService.class); + + private final VcsAccessLogRepository vcsAccessLogRepository; + + private final ParticipationRepository participationRepository; + + VcsAccessLogService(VcsAccessLogRepository vcsAccessLogRepository, ParticipationRepository participationRepository) { + this.vcsAccessLogRepository = vcsAccessLogRepository; + this.participationRepository = participationRepository; + } + + /** + * Creates a vcs access log entry and stores it to the database + * + * @param user The user accessing the repository + * @param participation The participation which owns the repository + * @param actionType The action type: READ or WRITE + * @param authenticationMechanism The used authentication mechanism: password, vcs token (user/participation), SSH or code editor + * @param commitHash The latest commit hash + * @param ipAddress The ip address of the user accessing the repository + */ + public void storeAccessLog(User user, ProgrammingExerciseParticipation participation, RepositoryActionType actionType, AuthenticationMechanism authenticationMechanism, + String commitHash, String ipAddress) { + log.debug("Storing access operation for user {}", user); + + VcsAccessLog accessLogEntry = new VcsAccessLog(user, (Participation) participation, user.getName(), user.getEmail(), actionType, authenticationMechanism, commitHash, + ipAddress); + vcsAccessLogRepository.save(accessLogEntry); + } + + /** + * Updates the commit hash after a successful push + * + * @param participation The participation to which the repository belongs to + * @param commitHash The newest commit hash which should get set for the access log entry + */ + public void updateCommitHash(ProgrammingExerciseParticipation participation, String commitHash) { + vcsAccessLogRepository.findNewestByParticipationIdWhereCommitHashIsNull(participation.getId()).ifPresent(entry -> { + entry.setCommitHash(commitHash); + vcsAccessLogRepository.save(entry); + }); + } + + /** + * Stores the log for a push from the code editor. + * + * @param repo The repository to which the push is executed + * @param user The user submitting the change + * @param participationId The id of the participation belonging to the repository + * @throws GitAPIException if an error occurs while retrieving the git log + */ + public void storeCodeEditorAccessLog(Repository repo, User user, Long participationId) throws GitAPIException { + try (Git git = new Git(repo)) { + String lastCommitHash = git.log().setMaxCount(1).call().iterator().next().getName(); + var participation = participationRepository.findById(participationId); + if (participation.isPresent() && participation.get() instanceof ProgrammingExerciseParticipation programmingParticipation) { + storeAccessLog(user, programmingParticipation, RepositoryActionType.WRITE, AuthenticationMechanism.CODE_EDITOR, lastCommitHash, null); + } + } + } +} diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/web/ProgrammingExerciseParticipationResource.java b/src/main/java/de/tum/cit/aet/artemis/programming/web/ProgrammingExerciseParticipationResource.java index a1e104e6fde4..d06fdf5fb975 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/web/ProgrammingExerciseParticipationResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/web/ProgrammingExerciseParticipationResource.java @@ -11,6 +11,8 @@ import java.util.stream.Collectors; import org.eclipse.jgit.api.errors.GitAPIException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Profile; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -31,6 +33,7 @@ import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastInstructor; import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastStudent; import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastTutor; +import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInExercise.EnforceAtLeastInstructorInExercise; import de.tum.cit.aet.artemis.core.service.AuthorizationCheckService; import de.tum.cit.aet.artemis.exam.repository.StudentExamRepository; import de.tum.cit.aet.artemis.exam.service.ExamService; @@ -42,10 +45,13 @@ import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseStudentParticipation; import de.tum.cit.aet.artemis.programming.domain.ProgrammingSubmission; import de.tum.cit.aet.artemis.programming.domain.RepositoryType; +import de.tum.cit.aet.artemis.programming.domain.VcsAccessLog; import de.tum.cit.aet.artemis.programming.domain.VcsRepositoryUri; import de.tum.cit.aet.artemis.programming.dto.CommitInfoDTO; +import de.tum.cit.aet.artemis.programming.dto.VcsAccessLogDTO; import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseRepository; import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseStudentParticipationRepository; +import de.tum.cit.aet.artemis.programming.repository.VcsAccessLogRepository; import de.tum.cit.aet.artemis.programming.service.ProgrammingExerciseParticipationService; import de.tum.cit.aet.artemis.programming.service.ProgrammingSubmissionService; import de.tum.cit.aet.artemis.programming.service.RepositoryService; @@ -55,6 +61,8 @@ @RequestMapping("api/") public class ProgrammingExerciseParticipationResource { + private static final Logger log = LoggerFactory.getLogger(ProgrammingExerciseParticipationResource.class); + private static final String ENTITY_NAME = "programmingExerciseParticipation"; private final ParticipationRepository participationRepository; @@ -79,11 +87,13 @@ public class ProgrammingExerciseParticipationResource { private final StudentExamRepository studentExamRepository; + private final Optional vcsAccessLogRepository; + public ProgrammingExerciseParticipationResource(ProgrammingExerciseParticipationService programmingExerciseParticipationService, ResultRepository resultRepository, ParticipationRepository participationRepository, ProgrammingExerciseStudentParticipationRepository programmingExerciseStudentParticipationRepository, ProgrammingSubmissionService submissionService, ProgrammingExerciseRepository programmingExerciseRepository, AuthorizationCheckService authCheckService, ResultService resultService, ParticipationAuthorizationCheckService participationAuthCheckService, RepositoryService repositoryService, - StudentExamRepository studentExamRepository) { + StudentExamRepository studentExamRepository, Optional vcsAccessLogRepository) { this.programmingExerciseParticipationService = programmingExerciseParticipationService; this.participationRepository = participationRepository; this.programmingExerciseStudentParticipationRepository = programmingExerciseStudentParticipationRepository; @@ -95,6 +105,7 @@ public ProgrammingExerciseParticipationResource(ProgrammingExerciseParticipation this.participationAuthCheckService = participationAuthCheckService; this.repositoryService = repositoryService; this.studentExamRepository = studentExamRepository; + this.vcsAccessLogRepository = vcsAccessLogRepository; } /** @@ -305,6 +316,27 @@ public ResponseEntity> getCommitHistoryForParticipationRepo( return ResponseEntity.ok(commitInfo); } + /** + * GET /programming-exercise-participations/{participationId}/vcs-access-log : + * Here we check if the user is least an instructor for the exercise. If true the user can have access to the vcs access log of any participation of the exercise. + * + * @param participationId the id of the participation for which to retrieve the vcs access log + * @return the ResponseEntity with status 200 (OK) and with body containing a list of vcsAccessLogDTOs of the participation, or 400 (Bad request) if localVC is not enabled. + */ + @GetMapping("programming-exercise-participations/{participationId}/vcs-access-log") + @EnforceAtLeastInstructor + public ResponseEntity> getVcsAccessLogForParticipationRepo(@PathVariable long participationId) { + if (vcsAccessLogRepository.isEmpty()) { + return ResponseEntity.badRequest().build(); + } + ProgrammingExerciseStudentParticipation participation = programmingExerciseStudentParticipationRepository.findByIdElseThrow(participationId); + participationAuthCheckService.checkCanAccessParticipationElseThrow(participation); + log.info("Fetching VCS access logs for participation ID: {}", participationId); + List vcsAccessLogs = vcsAccessLogRepository.get().findAllByParticipationId(participationId); + var vcsAccessLogDTOs = vcsAccessLogs.stream().map(VcsAccessLogDTO::of).toList(); + return ResponseEntity.ok(vcsAccessLogDTOs); + } + /** * GET /programming-exercise/{exerciseID}/commit-history/{repositoryType} : Get the commit history of a programming exercise repository. The repository type can be TEMPLATE or * SOLUTION or TESTS. @@ -392,6 +424,34 @@ else if (repositoryType != null) { } } + /** + * Retrieves the VCS access logs for the specified programming exercise's template or solution participation + * + * @param exerciseId the ID of the programming exercise + * @param repositoryType the type of repository (either TEMPLATE or SOLUTION) for which to retrieve the logs. + * @return the ResponseEntity with status 200 (OK) and with body containing a list of vcsAccessLogDTOs of the participation, or 400 (Bad request) if localVC is not enabled. + * @throws BadRequestAlertException if the repository type is invalid + */ + @GetMapping("programming-exercise/{exerciseId}/vcs-access-log/{repositoryType}") + @EnforceAtLeastInstructorInExercise + public ResponseEntity> getVcsAccessLogForExerciseRepository(@PathVariable long exerciseId, @PathVariable RepositoryType repositoryType) { + if (vcsAccessLogRepository.isEmpty()) { + return ResponseEntity.badRequest().build(); + } + if (repositoryType != RepositoryType.TEMPLATE && repositoryType != RepositoryType.SOLUTION) { + throw new BadRequestAlertException("Can only get vcs access log from template and assignment repositories", ENTITY_NAME, "incorrect repositoryType"); + } + ProgrammingExercise programmingExercise = programmingExerciseRepository.findByIdWithTemplateAndSolutionParticipationAndAuxiliaryRepositoriesElseThrow(exerciseId); + authCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.INSTRUCTOR, programmingExercise, null); + log.info("Fetching VCS access logs for exercise ID: {} and repository type: {}", exerciseId, repositoryType); + + var participation = repositoryType == RepositoryType.TEMPLATE ? programmingExercise.getTemplateParticipation() : programmingExercise.getSolutionParticipation(); + + List vcsAccessLogs = vcsAccessLogRepository.get().findAllByParticipationId(participation.getId()); + var vcsAccessLogDTOs = vcsAccessLogs.stream().map(VcsAccessLogDTO::of).toList(); + return ResponseEntity.ok(vcsAccessLogDTOs); + } + /** * Checks if the user has access to the participation. * If the exercise has not started yet and the user is a student, access is denied. @@ -426,5 +486,4 @@ private boolean shouldHideExamExerciseResults(ProgrammingExerciseStudentParticip } return false; } - } diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/web/repository/RepositoryResource.java b/src/main/java/de/tum/cit/aet/artemis/programming/web/repository/RepositoryResource.java index bd50617ee04d..f9ca7350afd1 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/web/repository/RepositoryResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/web/repository/RepositoryResource.java @@ -281,7 +281,7 @@ public ResponseEntity commitChanges(Long domainId) { return executeAndCheckForExceptions(() -> { Repository repository = getRepository(domainId, RepositoryActionType.WRITE, true); - repositoryService.commitChanges(repository, user); + repositoryService.commitChanges(repository, user, domainId); // Trigger a build, and process the result. Only implemented for local CI. // For GitLab + Jenkins, webhooks were added when creating the repository, // that notify the CI system when the commit happens and thus trigger the build. diff --git a/src/main/resources/config/application-prod.yml b/src/main/resources/config/application-prod.yml index 7d86700066e4..576e5ca01cde 100644 --- a/src/main/resources/config/application-prod.yml +++ b/src/main/resources/config/application-prod.yml @@ -109,8 +109,7 @@ jhipster: port: 5000 ring-buffer-size: 512 audit-events: - retention-period: 120 # Number of days before audit events are deleted. - + retention-period: 120 # Number of days before audit events and VCS access logs are deleted. # Properties to be exposed on the /info management endpoint info: guided-tour: diff --git a/src/main/resources/config/liquibase/changelog/20240804144500_changelog.xml b/src/main/resources/config/liquibase/changelog/20240804144500_changelog.xml new file mode 100644 index 000000000000..72b4d0498221 --- /dev/null +++ b/src/main/resources/config/liquibase/changelog/20240804144500_changelog.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/config/liquibase/master.xml b/src/main/resources/config/liquibase/master.xml index f8be6b6255a0..2c204094c0ff 100644 --- a/src/main/resources/config/liquibase/master.xml +++ b/src/main/resources/config/liquibase/master.xml @@ -22,6 +22,8 @@ + + diff --git a/src/main/webapp/app/entities/vcs-access-log-entry.model.ts b/src/main/webapp/app/entities/vcs-access-log-entry.model.ts new file mode 100644 index 000000000000..c2571e9ddd0d --- /dev/null +++ b/src/main/webapp/app/entities/vcs-access-log-entry.model.ts @@ -0,0 +1,13 @@ +import { BaseEntity } from 'app/shared/model/base-entity'; +import dayjs from 'dayjs/esm'; + +export class VcsAccessLogDTO implements BaseEntity { + public id?: number; + public userId?: number; + public name?: string; + public email?: string; + public repositoryActionType: string; + public authenticationMechanism: string; + public commitHash?: string; + public timestamp: dayjs.Dayjs; +} diff --git a/src/main/webapp/app/exercises/programming/manage/programming-exercise-management-routing.module.ts b/src/main/webapp/app/exercises/programming/manage/programming-exercise-management-routing.module.ts index 54c277c9bd7d..cf949670dcf9 100644 --- a/src/main/webapp/app/exercises/programming/manage/programming-exercise-management-routing.module.ts +++ b/src/main/webapp/app/exercises/programming/manage/programming-exercise-management-routing.module.ts @@ -18,6 +18,7 @@ import { RepositoryViewComponent } from 'app/localvc/repository-view/repository- import { CommitHistoryComponent } from 'app/localvc/commit-history/commit-history.component'; import { CommitDetailsViewComponent } from 'app/localvc/commit-details-view/commit-details-view.component'; import { LocalVCGuard } from 'app/localvc/localvc-guard.service'; +import { VcsRepositoryAccessLogViewComponent } from 'app/localvc/vcs-repository-access-log-view/vcs-repository-access-log-view.component'; @Injectable({ providedIn: 'root' }) export class ProgrammingExerciseResolve implements Resolve { @@ -183,6 +184,18 @@ export const routes: Routes = [ }, canActivate: [LocalVCGuard], }, + { + path: ':courseId/programming-exercises/:exerciseId/repository/:repositoryType/vcs-access-log', + component: VcsRepositoryAccessLogViewComponent, + data: { + authorities: [Authority.ADMIN, Authority.INSTRUCTOR], + pageTitle: 'artemisApp.repository.title', + flushRepositoryCacheAfter: 900000, // 15 min + participationCache: {}, + repositoryCache: {}, + }, + canActivate: [LocalVCGuard], + }, { path: ':courseId/programming-exercises/:exerciseId/repository/:repositoryType/commit-history/:commitHash', component: CommitDetailsViewComponent, @@ -219,6 +232,18 @@ export const routes: Routes = [ }, canActivate: [UserRouteAccessService, LocalVCGuard], }, + { + path: ':courseId/programming-exercises/:exerciseId/participations/:participationId/repository/vcs-access-log', + component: VcsRepositoryAccessLogViewComponent, + data: { + authorities: [Authority.ADMIN, Authority.INSTRUCTOR], + pageTitle: 'artemisApp.repository.title', + flushRepositoryCacheAfter: 900000, // 15 min + participationCache: {}, + repositoryCache: {}, + }, + canActivate: [UserRouteAccessService, LocalVCGuard], + }, { path: ':courseId/programming-exercises/:exerciseId/participations/:participationId/repository/commit-history/:commitHash', component: CommitDetailsViewComponent, diff --git a/src/main/webapp/app/exercises/programming/manage/services/programming-exercise-participation.service.ts b/src/main/webapp/app/exercises/programming/manage/services/programming-exercise-participation.service.ts index e5ece788a0fb..e83414219bb6 100644 --- a/src/main/webapp/app/exercises/programming/manage/services/programming-exercise-participation.service.ts +++ b/src/main/webapp/app/exercises/programming/manage/services/programming-exercise-participation.service.ts @@ -8,6 +8,7 @@ import { Result } from 'app/entities/result.model'; import { EntityTitleService, EntityType } from 'app/shared/layouts/navbar/entity-title.service'; import { createRequestOption } from 'app/shared/util/request.util'; import { Observable, map, tap } from 'rxjs'; +import { VcsAccessLogDTO } from 'app/entities/vcs-access-log-entry.model'; export interface IProgrammingExerciseParticipationService { getLatestResultWithFeedback: (participationId: number, withSubmission: boolean) => Observable; @@ -145,6 +146,33 @@ export class ProgrammingExerciseParticipationService implements IProgrammingExer return this.http.get(`${this.resourceUrlParticipations}${participationId}/commits-info`); } + /** + * Get the vcs access log for a given participation id. + * The current user needs to be at least an instructor in the course of the participation. + * @param participationId of the participation to get the vcs Access log + */ + getVcsAccessLogForParticipation(participationId: number): Observable { + return this.http + .get(`${this.resourceUrlParticipations}${participationId}/vcs-access-log`, { observe: 'response' }) + .pipe(map((res: HttpResponse) => res.body ?? undefined)); + } + + /** + * Get the vcs access log for a given exercise id and the repository type. + * The current user needs to be at least a instructor in the course of the participation. + * @param exerciseId of the exercise to get the vcs Access log + * @param repositoryType of the repository of the exercise, to get the vcs Access log + */ + getVcsAccessLogForRepository(exerciseId: number, repositoryType: string): Observable { + const params: { [key: string]: number | string } = {}; + if (repositoryType) { + params['repositoryType'] = repositoryType; + } + return this.http + .get(`${this.resourceUrl}${exerciseId}/vcs-access-log/${repositoryType}`, { observe: 'response' }) + .pipe(map((res: HttpResponse) => res.body ?? undefined)); + } + /** * Get the repository files with content for a given participation id at a specific commit hash. * The current user needs to be at least a student in the course of the participation. diff --git a/src/main/webapp/app/localvc/repository-view/repository-view.component.html b/src/main/webapp/app/localvc/repository-view/repository-view.component.html index b3e821dbf431..6a41335a4f51 100644 --- a/src/main/webapp/app/localvc/repository-view/repository-view.component.html +++ b/src/main/webapp/app/localvc/repository-view/repository-view.component.html @@ -34,6 +34,13 @@

    } + @if (vcsAccessLogRoute && enableVcsAccessLog && allowVcsAccessLog && localVcEnabled) { + + + + + } + @if (exercise?.allowOfflineIde) { { + this.localVcEnabled = profileInfo.activeProfiles.includes(PROFILE_LOCALVC); + }); } /** @@ -122,6 +133,7 @@ export class RepositoryViewComponent implements OnInit, OnDestroy { this.participationCouldNotBeFetched = true; this.loadingParticipation = false; } + this.allowVcsAccessLog = this.accountService.isAtLeastInstructorInCourse(this.getCourseFromExercise(this.exercise)); }), ) .subscribe({ @@ -146,6 +158,7 @@ export class RepositoryViewComponent implements OnInit, OnDestroy { this.domainService.setDomain([DomainType.PARTICIPATION, participationWithResults]); this.participation = participationWithResults; this.exercise = this.participation.exercise as ProgrammingExercise; + this.allowVcsAccessLog = this.accountService.isAtLeastInstructorInCourse(this.getCourseFromExercise(this.exercise)); this.repositoryUri = this.participation.repositoryUri!; }), ) diff --git a/src/main/webapp/app/localvc/vcs-repository-access-log-view/vcs-repository-access-log-view.component.html b/src/main/webapp/app/localvc/vcs-repository-access-log-view/vcs-repository-access-log-view.component.html new file mode 100644 index 000000000000..32f6eaaf0da6 --- /dev/null +++ b/src/main/webapp/app/localvc/vcs-repository-access-log-view/vcs-repository-access-log-view.component.html @@ -0,0 +1,34 @@ + +
    +

    +
    + +
    + + + + + + + + + + + + + + @for (entry of vcsAccessLogEntries(); track entry; let i = $index) { + + + + + + + + + + } + +
    #
    {{ i }}{{ entry.userId }}{{ entry.name + ', ' + entry.email }}{{ entry.repositoryActionType }}{{ entry.authenticationMechanism }}{{ entry.commitHash }}{{ entry.timestamp }}
    +
    +
    diff --git a/src/main/webapp/app/localvc/vcs-repository-access-log-view/vcs-repository-access-log-view.component.ts b/src/main/webapp/app/localvc/vcs-repository-access-log-view/vcs-repository-access-log-view.component.ts new file mode 100644 index 000000000000..0f72191f8405 --- /dev/null +++ b/src/main/webapp/app/localvc/vcs-repository-access-log-view/vcs-repository-access-log-view.component.ts @@ -0,0 +1,65 @@ +import { Component, computed, effect, inject, signal } from '@angular/core'; +import { Observable, lastValueFrom } from 'rxjs'; +import { ActivatedRoute } from '@angular/router'; +import { ProgrammingExerciseParticipationService } from 'app/exercises/programming/manage/services/programming-exercise-participation.service'; +import { VcsAccessLogDTO } from 'app/entities/vcs-access-log-entry.model'; +import { AlertService } from 'app/core/util/alert.service'; +import { toSignal } from '@angular/core/rxjs-interop'; +import { TranslateDirective } from 'app/shared/language/translate.directive'; + +@Component({ + selector: 'jhi-vcs-repository-access-log-view', + templateUrl: './vcs-repository-access-log-view.component.html', + standalone: true, + imports: [TranslateDirective], +}) +export class VcsRepositoryAccessLogViewComponent { + private readonly route = inject(ActivatedRoute); + private readonly programmingExerciseParticipationService = inject(ProgrammingExerciseParticipationService); + private readonly alertService = inject(AlertService); + + protected readonly vcsAccessLogEntries = signal([]); + + private readonly params = toSignal(this.route.params, { requireSync: true }); + private readonly participationId = computed(() => { + const participationId = this.params().participationId; + if (participationId) { + return Number(participationId); + } + return undefined; + }); + private readonly exerciseId = computed(() => Number(this.params().exerciseId)); + private readonly repositoryType = computed(() => String(this.params().repositoryType)); + + constructor() { + effect( + async () => { + if (this.participationId()) { + await this.loadVcsAccessLogForParticipation(this.participationId()!); + } else { + await this.loadVcsAccessLog(this.exerciseId(), this.repositoryType()); + } + }, + { allowSignalWrites: true }, + ); + } + + public async loadVcsAccessLogForParticipation(participationId: number) { + await this.extractEntries(() => this.programmingExerciseParticipationService.getVcsAccessLogForParticipation(participationId)); + } + + public async loadVcsAccessLog(exerciseId: number, repositoryType: string) { + await this.extractEntries(() => this.programmingExerciseParticipationService.getVcsAccessLogForRepository(exerciseId, repositoryType)); + } + + private async extractEntries(fetchVcsAccessLogs: () => Observable) { + try { + const accessLogEntries = await lastValueFrom(fetchVcsAccessLogs()); + if (accessLogEntries) { + this.vcsAccessLogEntries.set(accessLogEntries); + } + } catch (error) { + this.alertService.error('artemisApp.repository.vcsAccessLog.error'); + } + } +} diff --git a/src/main/webapp/i18n/de/repository.json b/src/main/webapp/i18n/de/repository.json index 241f5d8bc21d..6bd6d6d28842 100644 --- a/src/main/webapp/i18n/de/repository.json +++ b/src/main/webapp/i18n/de/repository.json @@ -20,6 +20,17 @@ "empty": "Keine Änderungen", "fileUnchanged": "Keine Änderungen am Dateiinhalt" } + }, + "vcsAccessLog": { + "title": "VCS-Zugriffsprotokoll", + "openVcsAccessLog": "Zugriffsprotokoll öffnen", + "userId": "Benutzer Id", + "author": "Autor", + "actionType": "Aktionstyp", + "authMechanism": "Zugriffsart", + "commitHash": "Commit Hash", + "timeStamp": "Zeitstempel", + "error": "VCS-Zugriffsprotokoll konnte nicht abgerufen werden" } } } diff --git a/src/main/webapp/i18n/en/repository.json b/src/main/webapp/i18n/en/repository.json index 59b50fcb0481..8ed72d96e6ee 100644 --- a/src/main/webapp/i18n/en/repository.json +++ b/src/main/webapp/i18n/en/repository.json @@ -20,6 +20,17 @@ "empty": "No changes", "fileUnchanged": "No changes in the file content" } + }, + "vcsAccessLog": { + "title": "VCS Access Log", + "openVcsAccessLog": "Open Access Log", + "userId": "User Id", + "author": "Author", + "actionType": "Action Type", + "authMechanism": "Access Type", + "commitHash": "Commit Hash", + "timeStamp": "Timestamp", + "error": "VCS Access log could not be retrieved" } } } diff --git a/src/test/java/de/tum/cit/aet/artemis/localvcci/LocalVCLocalCIParticipationIntegrationTest.java b/src/test/java/de/tum/cit/aet/artemis/localvcci/LocalVCLocalCIParticipationIntegrationTest.java index 4ccddacc3fbf..1ac8510ab262 100644 --- a/src/test/java/de/tum/cit/aet/artemis/localvcci/LocalVCLocalCIParticipationIntegrationTest.java +++ b/src/test/java/de/tum/cit/aet/artemis/localvcci/LocalVCLocalCIParticipationIntegrationTest.java @@ -4,6 +4,7 @@ import java.time.ZonedDateTime; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -14,9 +15,15 @@ import de.tum.cit.aet.artemis.core.domain.User; import de.tum.cit.aet.artemis.exercise.domain.participation.StudentParticipation; import de.tum.cit.aet.artemis.exercise.programming.ProgrammingExerciseUtilService; +import de.tum.cit.aet.artemis.participation.ParticipationUtilService; +import de.tum.cit.aet.artemis.programming.domain.AuthenticationMechanism; import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise; import de.tum.cit.aet.artemis.programming.domain.TemplateProgrammingExerciseParticipation; +import de.tum.cit.aet.artemis.programming.domain.VcsAccessLog; +import de.tum.cit.aet.artemis.programming.dto.VcsAccessLogDTO; +import de.tum.cit.aet.artemis.programming.repository.VcsAccessLogRepository; import de.tum.cit.aet.artemis.programming.service.localvc.LocalVCRepositoryUri; +import de.tum.cit.aet.artemis.programming.web.repository.RepositoryActionType; import de.tum.cit.aet.artemis.util.LocalRepository; class LocalVCLocalCIParticipationIntegrationTest extends AbstractSpringIntegrationLocalCILocalVCTest { @@ -26,6 +33,21 @@ class LocalVCLocalCIParticipationIntegrationTest extends AbstractSpringIntegrati @Autowired private ProgrammingExerciseUtilService programmingExerciseUtilService; + @Autowired + private VcsAccessLogRepository vcsAccessLogRepository; + + @Autowired + private ParticipationUtilService participationUtilService; + + private ProgrammingExercise programmingExercise; + + @BeforeEach + void initTestCase() { + userUtilService.addUsers(TEST_PREFIX, 4, 2, 0, 2); + Course course = programmingExerciseUtilService.addCourseWithOneProgrammingExerciseAndTestCases(); + programmingExercise = exerciseUtilService.getFirstExerciseWithType(course, ProgrammingExercise.class); + } + @Test @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER") void testStartParticipation() throws Exception { @@ -63,4 +85,27 @@ void testStartParticipation() throws Exception { templateRepository.resetLocalRepo(); } + + @Test + @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR") + void testGetVcsAccessLog() throws Exception { + var participation = participationUtilService.addStudentParticipationForProgrammingExercise(programmingExercise, TEST_PREFIX + "instructor1"); + var user = userRepository.getUser(); + vcsAccessLogRepository.save(new VcsAccessLog(user, participation, "instructor", "instructorMail@mail.de", RepositoryActionType.READ, AuthenticationMechanism.SSH, "", "")); + var li = request.getList("/api/programming-exercise-participations/" + participation.getId() + "/vcs-access-log", HttpStatus.OK, VcsAccessLogDTO.class); + assertThat(li.size()).isEqualTo(1); + assertThat(li.getFirst().userId()).isEqualTo(user.getId()); + } + + @Test + @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR") + void testGetVcsAccessLogOfTemplateParticipation() throws Exception { + var user = userRepository.getUser(); + vcsAccessLogRepository.save(new VcsAccessLog(user, programmingExercise.getTemplateParticipation(), "instructor", "instructorMail@mail.de", RepositoryActionType.READ, + AuthenticationMechanism.SSH, "", "")); + var li = request.getList("/api/programming-exercise/" + programmingExercise.getId() + "/vcs-access-log/TEMPLATE", HttpStatus.OK, VcsAccessLogDTO.class); + assertThat(li.size()).isEqualTo(1); + assertThat(li.getFirst().userId()).isEqualTo(user.getId()); + } + } diff --git a/src/test/javascript/spec/component/localvc/repository-view.component.spec.ts b/src/test/javascript/spec/component/localvc/repository-view.component.spec.ts index 5f4fae4014a9..ff004d03c91b 100644 --- a/src/test/javascript/spec/component/localvc/repository-view.component.spec.ts +++ b/src/test/javascript/spec/component/localvc/repository-view.component.spec.ts @@ -16,6 +16,8 @@ import { HttpResponse } from '@angular/common/http'; import { ProgrammingExercise } from 'app/entities/programming/programming-exercise.model'; import { DueDateStat } from 'app/course/dashboards/due-date-stat.model'; import { ProgrammingExerciseStudentParticipation } from 'app/entities/participation/programming-exercise-student-participation.model'; +import { ProfileService } from 'app/shared/layouts/profiles/profile.service'; +import { MockProfileService } from '../../helpers/mocks/service/mock-profile.service'; describe('RepositoryViewComponent', () => { let component: RepositoryViewComponent; @@ -39,6 +41,7 @@ describe('RepositoryViewComponent', () => { { provide: ProgrammingExerciseParticipationService, useClass: MockProgrammingExerciseParticipationService }, { provide: ProgrammingExerciseService, useClass: MockProgrammingExerciseService }, { provide: Router, useClass: MockRouter }, + { provide: ProfileService, useClass: MockProfileService }, ], }) .compileComponents() @@ -206,7 +209,16 @@ describe('RepositoryViewComponent', () => { const mockParticipation: ProgrammingExerciseStudentParticipation = { id: 2, repositoryUri: 'student-repo-uri', - exercise: { id: 1, numberOfAssessmentsOfCorrectionRounds: [new DueDateStat()], studentAssignedTeamIdComputed: true, secondCorrectionEnabled: true }, + exercise: { + id: 1, + numberOfAssessmentsOfCorrectionRounds: [new DueDateStat()], + studentAssignedTeamIdComputed: true, + secondCorrectionEnabled: true, + course: { + instructorGroupName: 'instructorGroup', + isAtLeastInstructor: true, + }, + }, results: [ { id: 3, successful: true, score: 100, rated: true, hasComplaint: false, exampleResult: false, testCaseCount: 10, passedTestCaseCount: 10, codeIssueCount: 0 }, { id: 4, successful: true, score: 100, rated: true, hasComplaint: false, exampleResult: false, testCaseCount: 10, passedTestCaseCount: 10, codeIssueCount: 0 }, diff --git a/src/test/javascript/spec/component/localvc/vcs-repository-access-log-view.component.spec.ts b/src/test/javascript/spec/component/localvc/vcs-repository-access-log-view.component.spec.ts new file mode 100644 index 000000000000..44d03a38d661 --- /dev/null +++ b/src/test/javascript/spec/component/localvc/vcs-repository-access-log-view.component.spec.ts @@ -0,0 +1,87 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ProgrammingExerciseParticipationService } from 'app/exercises/programming/manage/services/programming-exercise-participation.service'; +import { ActivatedRoute } from '@angular/router'; +import { MockProgrammingExerciseParticipationService } from '../../helpers/mocks/service/mock-programming-exercise-participation.service'; +import dayjs from 'dayjs/esm'; +import { of } from 'rxjs'; +import { TranslateService } from '@ngx-translate/core'; +import { ProgrammingExerciseService } from 'app/exercises/programming/manage/services/programming-exercise.service'; +import { MockProgrammingExerciseService } from '../../helpers/mocks/service/mock-programming-exercise.service'; +import { VcsRepositoryAccessLogViewComponent } from 'app/localvc/vcs-repository-access-log-view/vcs-repository-access-log-view.component'; +import { VcsAccessLogDTO } from 'app/entities/vcs-access-log-entry.model'; +import { MockTranslateService } from '../../helpers/mocks/service/mock-translate.service'; +import { AlertService } from 'app/core/util/alert.service'; +import { MockAlertService } from '../../helpers/mocks/service/mock-alert.service'; +import { MockProfileService } from '../../helpers/mocks/service/mock-profile.service'; +import { ProfileService } from 'app/shared/layouts/profiles/profile.service'; + +describe('VcsRepositoryAccessLogViewComponent', () => { + let fixture: ComponentFixture; + let programmingExerciseParticipationService: ProgrammingExerciseParticipationService; + const userId = 4; + let participationVcsAccessLogSpy: jest.SpyInstance; + let repositoryVcsAccessLogSpy: jest.SpyInstance; + + const mockVcsAccessLog: VcsAccessLogDTO[] = [ + { + id: 1, + userId: userId, + name: 'authorName', + email: 'authorEmail', + commitHash: 'abcde', + authenticationMechanism: 'SSH', + repositoryActionType: 'WRITE', + timestamp: dayjs('2021-01-02'), + }, + { + id: 2, + userId: userId, + name: 'authorName', + email: 'authorEmail', + commitHash: 'fffee', + authenticationMechanism: 'SSH', + repositoryActionType: 'READ', + timestamp: dayjs('2021-01-03'), + }, + ]; + + const route = { params: of({ participationId: '5' }) } as any as ActivatedRoute; + + function setupTestBed() { + fixture = TestBed.createComponent(VcsRepositoryAccessLogViewComponent); + programmingExerciseParticipationService = fixture.debugElement.injector.get(ProgrammingExerciseParticipationService); + repositoryVcsAccessLogSpy = jest.spyOn(programmingExerciseParticipationService, 'getVcsAccessLogForRepository').mockReturnValue(of(mockVcsAccessLog)); + participationVcsAccessLogSpy = jest.spyOn(programmingExerciseParticipationService, 'getVcsAccessLogForParticipation').mockReturnValue(of(mockVcsAccessLog)); + } + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [VcsRepositoryAccessLogViewComponent], + providers: [ + { provide: ActivatedRoute, useValue: route }, + { provide: ProgrammingExerciseParticipationService, useClass: MockProgrammingExerciseParticipationService }, + { provide: ProgrammingExerciseService, useClass: MockProgrammingExerciseService }, + { provide: TranslateService, useClass: MockTranslateService }, + { provide: AlertService, useClass: MockAlertService }, + { provide: ProfileService, useClass: MockProfileService }, + ], + }).compileComponents(); + }); + + it('should load participation vcs access log', () => { + setupTestBed(); + fixture.detectChanges(); + + expect(participationVcsAccessLogSpy).toHaveBeenCalledOnce(); + }); + + it('should load template repository vcs access log', () => { + route.params = of({ exerciseId: '10', repositoryType: 'TEMPLATE' }); + TestBed.overrideProvider(ActivatedRoute, { useValue: route }); + + setupTestBed(); + fixture.detectChanges(); + + expect(repositoryVcsAccessLogSpy).toHaveBeenCalledOnce(); + }); +}); diff --git a/src/test/javascript/spec/helpers/mocks/service/mock-programming-exercise-participation.service.ts b/src/test/javascript/spec/helpers/mocks/service/mock-programming-exercise-participation.service.ts index 8525ad43dc80..472de3e839b5 100644 --- a/src/test/javascript/spec/helpers/mocks/service/mock-programming-exercise-participation.service.ts +++ b/src/test/javascript/spec/helpers/mocks/service/mock-programming-exercise-participation.service.ts @@ -3,6 +3,7 @@ import { IProgrammingExerciseParticipationService } from 'app/exercises/programm import { ProgrammingExerciseStudentParticipation } from 'app/entities/participation/programming-exercise-student-participation.model'; import { Result } from 'app/entities/result.model'; import { CommitInfo } from 'app/entities/programming/programming-submission.model'; +import { VcsAccessLogDTO } from 'app/entities/vcs-access-log-entry.model'; export class MockProgrammingExerciseParticipationService implements IProgrammingExerciseParticipationService { getLatestResultWithFeedback = (participationId: number, withSubmission: boolean) => of({} as Result); @@ -13,4 +14,6 @@ export class MockProgrammingExerciseParticipationService implements IProgramming getParticipationRepositoryFilesWithContentAtCommitForCommitDetailsView = (exerciseId: number, participationId: number, commitId: string, repositoryType: string) => of(new Map()); checkIfParticipationHasResult = (participationId: number) => of(true); + getVcsAccessLogForRepository = (exerciseId: number, repositoryType: string) => of([] as VcsAccessLogDTO[]); + getVcsAccessLogForParticipation = (participationId: number) => of([] as VcsAccessLogDTO[]); } diff --git a/src/test/javascript/spec/service/programming-exercise-participation.service.spec.ts b/src/test/javascript/spec/service/programming-exercise-participation.service.spec.ts index 92bff0034faa..1ef9b69501d1 100644 --- a/src/test/javascript/spec/service/programming-exercise-participation.service.spec.ts +++ b/src/test/javascript/spec/service/programming-exercise-participation.service.spec.ts @@ -177,4 +177,21 @@ describe('ProgrammingExerciseParticipation Service', () => { req.flush(files); tick(); })); + + it('should make GET request to retrieve vcs access log for participation', fakeAsync(() => { + const participationId = 42; + service.getVcsAccessLogForParticipation(participationId).subscribe(); + const expectedURL = `${resourceUrlParticipations}${participationId}/vcs-access-log`; + httpMock.expectOne({ method: 'GET', url: expectedURL }); + tick(); + })); + + it('should make GET request to retrieve vcs access log for the template repository', fakeAsync(() => { + const exerciseId = 42; + const repositoryType = 'TEMPLATE'; + service.getVcsAccessLogForRepository(exerciseId, repositoryType).subscribe(); + const expectedURL = `${resourceUrl}${exerciseId}/vcs-access-log/${repositoryType}`; + httpMock.expectOne({ method: 'GET', url: expectedURL }); + tick(); + })); }); From a6278877135b790d99e40cd75184c1c3f453af52 Mon Sep 17 00:00:00 2001 From: Lucas Welscher Date: Thu, 19 Sep 2024 22:36:23 +0200 Subject: [PATCH 11/49] Development: Exclude xmlunit dependency due to transitive vulnerability (#9339) --- build.gradle | 1 + .../course-scripts/quick-course-setup/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8e18d5db388c..ea398221e36b 100644 --- a/build.gradle +++ b/build.gradle @@ -506,6 +506,7 @@ dependencies { testImplementation("org.springframework.boot:spring-boot-starter-test:${spring_boot_version}") { exclude group: "org.junit.vintage", module: "junit-vintage-engine" exclude group: "com.vaadin.external.google", module: "android-json" + exclude group: "org.xmlunit", module: "xmlunit-core" } testImplementation "org.springframework.security:spring-security-test:${spring_security_version}" testImplementation "org.springframework.boot:spring-boot-test:${spring_boot_version}" diff --git a/supporting_scripts/course-scripts/quick-course-setup/requirements.txt b/supporting_scripts/course-scripts/quick-course-setup/requirements.txt index 55c9f479fae2..98b3cc9c6008 100644 --- a/supporting_scripts/course-scripts/quick-course-setup/requirements.txt +++ b/supporting_scripts/course-scripts/quick-course-setup/requirements.txt @@ -1,2 +1,2 @@ requests==2.32.3 -urllib3==2.2.2 +urllib3==2.2.3 From 77bb18299af51c2376965479405dfd57fa5d850d Mon Sep 17 00:00:00 2001 From: Ole Vester <73833780+ole-ve@users.noreply.github.com> Date: Thu, 19 Sep 2024 23:26:33 +0200 Subject: [PATCH 12/49] Development: Fix the path of exercise- and lecture-type domain objects in the client (#9313) --- .../course-dashboard/course-dashboard.service.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/webapp/app/overview/course-dashboard/course-dashboard.service.ts b/src/main/webapp/app/overview/course-dashboard/course-dashboard.service.ts index aab8b86f6153..a6a1e09c0750 100644 --- a/src/main/webapp/app/overview/course-dashboard/course-dashboard.service.ts +++ b/src/main/webapp/app/overview/course-dashboard/course-dashboard.service.ts @@ -112,7 +112,7 @@ export class CourseDashboardService { return ExerciseType.QUIZ; case 'de.tum.cit.aet.artemis.text.domain.TextExercise': return ExerciseType.TEXT; - case 'de.tum.cit.aet.artemis.file.domain.FileUploadExercise': + case 'de.tum.cit.aet.artemis.fileupload.domain.FileUploadExercise': return ExerciseType.FILE_UPLOAD; default: throw new Error(`Unknown exercise type: ${type}`); @@ -121,15 +121,15 @@ export class CourseDashboardService { private mapToLectureUnitType(type: string): LectureUnitType { switch (type) { - case 'de.tum.cit.aet.artemis.domain.lecture.AttachmentUnit': + case 'de.tum.cit.aet.artemis.lecture.domain.AttachmentUnit': return LectureUnitType.ATTACHMENT; - case 'de.tum.cit.aet.artemis.domain.lecture.ExerciseUnit': + case 'de.tum.cit.aet.artemis.lecture.domain.ExerciseUnit': return LectureUnitType.EXERCISE; - case 'de.tum.cit.aet.artemis.domain.lecture.TextUnit': + case 'de.tum.cit.aet.artemis.lecture.domain.TextUnit': return LectureUnitType.TEXT; - case 'de.tum.cit.aet.artemis.domain.lecture.VideoUnit': + case 'de.tum.cit.aet.artemis.lecture.domain.VideoUnit': return LectureUnitType.VIDEO; - case 'de.tum.cit.aet.artemis.domain.lecture.OnlineUnit': + case 'de.tum.cit.aet.artemis.lecture.domain.OnlineUnit': return LectureUnitType.ONLINE; default: throw new Error(`Unknown lecture unit type: ${type}`); From 17adae185fde520a9c31ef9010c2de45ab3968a5 Mon Sep 17 00:00:00 2001 From: Stephan Krusche Date: Thu, 19 Sep 2024 23:57:05 +0200 Subject: [PATCH 13/49] Development: Update server dependencies and remove unused dependencies --- build.gradle | 45 +++++++++++++------ docs/requirements.txt | 7 ++- gradle.properties | 5 ++- .../web/ConversationMessageResource.java | 3 +- .../web/NotificationResource.java | 3 +- .../web/SystemNotificationResource.java | 3 +- .../aet/artemis/core/web/AuditResource.java | 6 +-- .../core/web/admin/AdminUserResource.java | 3 +- .../aet/artemis/exam/web/ExamResource.java | 3 +- .../cit/aet/artemis/lti/web/LtiResource.java | 3 +- .../web/ModelingAssessmentResource.java | 13 ------ .../web/ModelingSubmissionResource.java | 10 +---- .../text/web/TextAssessmentResource.java | 4 -- 13 files changed, 49 insertions(+), 59 deletions(-) diff --git a/build.gradle b/build.gradle index ea398221e36b..973eb0147347 100644 --- a/build.gradle +++ b/build.gradle @@ -231,8 +231,8 @@ dependencies { // implementation "com.offbytwo.jenkins:jenkins-client:0.3.8" implementation files("libs/jenkins-client-0.4.1.jar") // The following 4 dependencies are explicitly integrated as transitive dependencies of jenkins-client-0.4.0.jar - implementation "org.apache.httpcomponents.client5:httpclient5:5.3.1" - implementation "org.apache.httpcomponents.core5:httpcore5:5.2.5" + implementation "org.apache.httpcomponents.client5:httpclient5:5.4" + implementation "org.apache.httpcomponents.core5:httpcore5:5.3" implementation "org.apache.httpcomponents:httpmime:4.5.14" implementation("org.dom4j:dom4j:2.1.4") { // Note: avoid org.xml.sax.SAXNotRecognizedException: unrecognized feature http://xml.org/sax/features/external-general-entities @@ -256,6 +256,13 @@ dependencies { implementation "de.jplag:python-3:${jplag_version}" implementation "de.jplag:text:${jplag_version}" + // those are transitive dependencies of JPlag Text --> Stanford NLP + // Note: ideally we would exclude them, but for some reason this does not work + implementation "org.apache.lucene:lucene-queryparser:${lucene_version}" + implementation "org.apache.lucene:lucene-core:${lucene_version}" + implementation "org.apache.lucene:lucene-analyzers-common:${lucene_version}" + + // we have to override those values to use the latest version implementation "org.slf4j:jcl-over-slf4j:${slf4j_version}" implementation "org.slf4j:jul-to-slf4j:${slf4j_version}" @@ -316,7 +323,13 @@ dependencies { implementation "org.jsoup:jsoup:1.18.1" implementation "commons-codec:commons-codec:1.17.1" // needed for spring security saml2 - implementation "org.springdoc:springdoc-openapi-ui:1.8.0" + // TODO: decide if we want to use OpenAPI and Swagger v3 +// implementation 'io.swagger.core.v3:swagger-annotations:2.2.23' +// implementation "org.springdoc:springdoc-openapi-ui:1.8.0" + + // use the latest version to avoid security vulnerabilities + implementation "org.springframework:spring-webmvc:6.1.13" + implementation "com.vdurmont:semver4j:3.1.0" implementation "com.github.docker-java:docker-java-core:${docker_java_version}" @@ -346,6 +359,9 @@ dependencies { implementation "com.fasterxml.jackson.datatype:jackson-datatype-hibernate6:${fasterxml_version}" // Support XML serialization and deserialization implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${fasterxml_version}" + // Support YML serialization and deserialization + implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${fasterxml_version}" + implementation "com.hazelcast:hazelcast:${hazelcast_version}" implementation "com.hazelcast:hazelcast-spring:${hazelcast_version}" @@ -381,7 +397,7 @@ dependencies { implementation "org.springframework.boot:spring-boot-starter-oauth2-client:${spring_boot_version}" implementation "org.springframework.ldap:spring-ldap-core:3.2.6" - implementation "org.springframework.data:spring-data-ldap:3.3.3" + implementation "org.springframework.data:spring-data-ldap:3.3.4" implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:4.1.3") { // NOTE: these modules contain security vulnerabilities and are not needed @@ -393,8 +409,8 @@ dependencies { implementation "io.netty:netty-all:4.1.113.Final" implementation "io.projectreactor.netty:reactor-netty:1.1.22" - implementation "org.springframework:spring-messaging:6.1.12" - implementation "org.springframework.retry:spring-retry:2.0.8" + implementation "org.springframework:spring-messaging:6.1.13" + implementation "org.springframework.retry:spring-retry:2.0.9" implementation "org.springframework.security:spring-security-config:${spring_security_version}" implementation "org.springframework.security:spring-security-data:${spring_security_version}" @@ -402,7 +418,7 @@ dependencies { implementation "org.springframework.security:spring-security-oauth2-core:${spring_security_version}" implementation "org.springframework.security:spring-security-oauth2-client:${spring_security_version}" // use newest version of nimbus-jose-jwt to avoid security issues through outdated dependencies - implementation "com.nimbusds:nimbus-jose-jwt:9.40" + implementation "com.nimbusds:nimbus-jose-jwt:9.41.1" implementation "org.springframework.security:spring-security-oauth2-jose:${spring_security_version}" implementation "org.springframework.security:spring-security-crypto:${spring_security_version}" @@ -423,10 +439,6 @@ dependencies { implementation "org.bouncycastle:bcpkix-jdk18on:1.78.1" implementation "org.bouncycastle:bcprov-jdk18on:1.78.1" - implementation("io.springfox:springfox-swagger2:3.0.0") { - exclude module: "mapstruct" - } - implementation "io.springfox:springfox-bean-validators:3.0.0" implementation "com.mysql:mysql-connector-j:9.0.0" implementation "org.postgresql:postgresql:42.7.4" @@ -438,10 +450,14 @@ dependencies { // NOTE: 3.0.2 is broken for splitting lecture specific PDFs implementation "org.apache.pdfbox:pdfbox:3.0.1" implementation "org.apache.commons:commons-csv:1.11.0" - implementation "org.commonmark:commonmark:0.22.0" + implementation "org.commonmark:commonmark:0.23.0" implementation "commons-fileupload:commons-fileupload:1.5" implementation "net.lingala.zip4j:zip4j:2.11.5" + implementation "org.jgrapht:jgrapht-core:1.5.2" + // use the latest version explicitly to avoid security vulnerabilities (currently Artemis and JPlag rely on jgrapht 1.5.2 which relies on apfloat) + implementation "org.apfloat:apfloat:1.14.0" + // use newest version of guava to avoid security issues through outdated dependencies implementation "com.google.guava:guava:33.3.0-jre" implementation "com.sun.activation:jakarta.activation:2.0.1" @@ -450,7 +466,7 @@ dependencies { implementation "com.google.code.gson:gson:2.11.0" - implementation "com.google.errorprone:error_prone_annotations:2.31.0" + implementation "com.google.errorprone:error_prone_annotations:2.32.0" // NOTE: we want to keep the same unique version for all configurations, implementation and annotationProcessor implementation("net.bytebuddy:byte-buddy") { @@ -513,7 +529,8 @@ dependencies { testImplementation "org.assertj:assertj-core:3.26.3" testImplementation "org.mockito:mockito-core:${mockito_version}" testImplementation "org.mockito:mockito-junit-jupiter:${mockito_version}" - testImplementation "io.github.classgraph:classgraph:4.8.175" + + testImplementation "io.github.classgraph:classgraph:4.8.176" testImplementation "org.awaitility:awaitility:4.2.2" testImplementation "org.apache.maven.shared:maven-invoker:3.3.0" testImplementation "org.gradle:gradle-tooling-api:8.10.1" diff --git a/docs/requirements.txt b/docs/requirements.txt index e009c5eb21e1..f62d541fe0b4 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,7 @@ Sphinx==7.4.7 sphinx-rtd-theme==2.0.0 -sphinx-autobuild==2024.4.16 -sphinxcontrib-bibtex==2.6.2 +sphinx-autobuild==2024.9.19 +sphinxcontrib-bibtex==2.6.3 +requests==2.32.3 +zipp==3.20.2 +docutils==0.20.1 diff --git a/gradle.properties b/gradle.properties index 5cac2d2e4f08..0ddd8b8f3fdc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ npm_version=10.8.0 # Dependency versions jhipster_dependencies_version=8.7.0 -spring_boot_version=3.3.3 +spring_boot_version=3.3.4 spring_security_version=6.3.3 # TODO: upgrading to 6.6.0 currently leads to issues due to internal changes in Hibernate and potentially wrong use in Artemis server code hibernate_version=6.4.10.Final @@ -21,6 +21,9 @@ jgit_version=7.0.0.202409031743-r sshd_version=2.13.2 checkstyle_version=10.18.1 jplag_version=5.1.0 +# not really used in Artemis, nor Jplag, nor the used version of Stanford CoreNLP, but we use the latest to avoid security vulnerabilities +# NOTE: we do not need to use the latest version 9.x here as long as Stanford CoreNLP does not reference it +lucene_version=8.11.3 slf4j_version=2.0.16 sentry_version=7.14.0 liquibase_version=4.29.2 diff --git a/src/main/java/de/tum/cit/aet/artemis/communication/web/ConversationMessageResource.java b/src/main/java/de/tum/cit/aet/artemis/communication/web/ConversationMessageResource.java index 77cedf02539a..5031332a8862 100644 --- a/src/main/java/de/tum/cit/aet/artemis/communication/web/ConversationMessageResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/communication/web/ConversationMessageResource.java @@ -40,7 +40,6 @@ import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastStudent; import de.tum.cit.aet.artemis.core.service.AuthorizationCheckService; import de.tum.cit.aet.artemis.core.util.TimeLogUtil; -import io.swagger.annotations.ApiParam; import tech.jhipster.web.util.PaginationUtil; /** @@ -110,7 +109,7 @@ public ResponseEntity createMessage(@PathVariable Long courseId, @Valid @R */ @GetMapping("courses/{courseId}/messages") @EnforceAtLeastStudent - public ResponseEntity> getMessages(@ApiParam Pageable pageable, PostContextFilterDTO postContextFilter, Principal principal) { + public ResponseEntity> getMessages(Pageable pageable, PostContextFilterDTO postContextFilter, Principal principal) { long timeNanoStart = System.nanoTime(); Page coursePosts; diff --git a/src/main/java/de/tum/cit/aet/artemis/communication/web/NotificationResource.java b/src/main/java/de/tum/cit/aet/artemis/communication/web/NotificationResource.java index 3a714eb5cd33..911ea5cbfbff 100644 --- a/src/main/java/de/tum/cit/aet/artemis/communication/web/NotificationResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/communication/web/NotificationResource.java @@ -31,7 +31,6 @@ import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastStudent; import de.tum.cit.aet.artemis.core.util.TimeLogUtil; import de.tum.cit.aet.artemis.tutorialgroup.service.TutorialGroupService; -import io.swagger.annotations.ApiParam; import tech.jhipster.web.util.PaginationUtil; /** @@ -73,7 +72,7 @@ public NotificationResource(NotificationRepository notificationRepository, UserR */ @GetMapping("notifications") @EnforceAtLeastStudent - public ResponseEntity> getAllNotificationsForCurrentUserFilteredBySettings(@ApiParam Pageable pageable) { + public ResponseEntity> getAllNotificationsForCurrentUserFilteredBySettings(Pageable pageable) { long start = System.nanoTime(); User currentUser = userRepository.getUserWithGroupsAndAuthorities(); log.info("REST request to get notifications page {} with size {} for current user {} filtered by settings", pageable.getPageNumber(), pageable.getPageSize(), diff --git a/src/main/java/de/tum/cit/aet/artemis/communication/web/SystemNotificationResource.java b/src/main/java/de/tum/cit/aet/artemis/communication/web/SystemNotificationResource.java index 2fd24822e321..2d797d153f8a 100644 --- a/src/main/java/de/tum/cit/aet/artemis/communication/web/SystemNotificationResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/communication/web/SystemNotificationResource.java @@ -23,7 +23,6 @@ import de.tum.cit.aet.artemis.communication.repository.SystemNotificationRepository; import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastEditor; import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastTutor; -import io.swagger.annotations.ApiParam; import tech.jhipster.web.util.PaginationUtil; import tech.jhipster.web.util.ResponseUtil; @@ -51,7 +50,7 @@ public SystemNotificationResource(SystemNotificationRepository systemNotificatio */ @GetMapping("system-notifications") @EnforceAtLeastTutor - public ResponseEntity> getAllSystemNotifications(@ApiParam Pageable pageable) { + public ResponseEntity> getAllSystemNotifications(Pageable pageable) { log.debug("REST request to get all Courses the user has access to"); final Page page = systemNotificationRepository.findAll(pageable); HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); diff --git a/src/main/java/de/tum/cit/aet/artemis/core/web/AuditResource.java b/src/main/java/de/tum/cit/aet/artemis/core/web/AuditResource.java index 03be23e493f2..03acab9f2da7 100644 --- a/src/main/java/de/tum/cit/aet/artemis/core/web/AuditResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/core/web/AuditResource.java @@ -24,7 +24,6 @@ import de.tum.cit.aet.artemis.core.security.annotations.EnforceAdmin; import de.tum.cit.aet.artemis.core.service.AuditEventService; -import io.swagger.annotations.ApiParam; import tech.jhipster.web.util.ResponseUtil; /** @@ -49,7 +48,7 @@ public AuditResource(AuditEventService auditEventService) { */ @GetMapping("audits") @EnforceAdmin - public ResponseEntity> getAll(@ApiParam Pageable pageable) { + public ResponseEntity> getAll(Pageable pageable) { Page page = auditEventService.findAll(pageable); HttpHeaders headers = generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK); @@ -65,8 +64,7 @@ public ResponseEntity> getAll(@ApiParam Pageable pageable) { */ @GetMapping(value = "audits", params = { "fromDate", "toDate" }) @EnforceAdmin - public ResponseEntity> getByDates(@RequestParam(value = "fromDate") LocalDate fromDate, @RequestParam(value = "toDate") LocalDate toDate, - @ApiParam Pageable pageable) { + public ResponseEntity> getByDates(@RequestParam(value = "fromDate") LocalDate fromDate, @RequestParam(value = "toDate") LocalDate toDate, Pageable pageable) { Instant from = fromDate.atStartOfDay(ZoneId.systemDefault()).toInstant(); Instant to = toDate.atStartOfDay(ZoneId.systemDefault()).plusDays(1).toInstant(); diff --git a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminUserResource.java b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminUserResource.java index 6b403e5602e0..289d296c5624 100644 --- a/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminUserResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/core/web/admin/AdminUserResource.java @@ -45,7 +45,6 @@ import de.tum.cit.aet.artemis.core.service.user.UserCreationService; import de.tum.cit.aet.artemis.core.service.user.UserService; import de.tum.cit.aet.artemis.core.util.HeaderUtil; -import io.swagger.annotations.ApiParam; import tech.jhipster.web.util.PaginationUtil; import tech.jhipster.web.util.ResponseUtil; @@ -237,7 +236,7 @@ public ResponseEntity syncUserViaLdap(@PathVariable Long userId) { */ @GetMapping("users") @EnforceAdmin - public ResponseEntity> getAllUsers(@ApiParam UserPageableSearchDTO userSearch) { + public ResponseEntity> getAllUsers(UserPageableSearchDTO userSearch) { final Page page = userRepository.getAllManagedUsers(userSearch); HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK); diff --git a/src/main/java/de/tum/cit/aet/artemis/exam/web/ExamResource.java b/src/main/java/de/tum/cit/aet/artemis/exam/web/ExamResource.java index 6f035a7695bb..40be2685e58e 100644 --- a/src/main/java/de/tum/cit/aet/artemis/exam/web/ExamResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/exam/web/ExamResource.java @@ -112,7 +112,6 @@ import de.tum.cit.aet.artemis.exercise.repository.ExerciseRepository; import de.tum.cit.aet.artemis.exercise.service.SubmissionService; import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise; -import io.swagger.annotations.ApiParam; import tech.jhipster.web.util.PaginationUtil; /** @@ -513,7 +512,7 @@ private void checkExamAttendanceCheckSettings(Exam exam) { */ @GetMapping("exams/active") @EnforceAtLeastInstructor - public ResponseEntity> getAllActiveExams(@ApiParam Pageable pageable) { + public ResponseEntity> getAllActiveExams(Pageable pageable) { final var user = userRepository.getUserWithGroupsAndAuthorities(); Page page = examService.getAllActiveExams(pageable, user); HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); diff --git a/src/main/java/de/tum/cit/aet/artemis/lti/web/LtiResource.java b/src/main/java/de/tum/cit/aet/artemis/lti/web/LtiResource.java index f1bb6ed318c1..1dbfede94a83 100644 --- a/src/main/java/de/tum/cit/aet/artemis/lti/web/LtiResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/lti/web/LtiResource.java @@ -36,7 +36,6 @@ import de.tum.cit.aet.artemis.lti.domain.LtiPlatformConfiguration; import de.tum.cit.aet.artemis.lti.repository.LtiPlatformConfigurationRepository; import de.tum.cit.aet.artemis.lti.service.LtiDeepLinkingService; -import io.swagger.annotations.ApiParam; import tech.jhipster.web.util.PaginationUtil; /** @@ -113,7 +112,7 @@ public ResponseEntity lti13DeepLinking(@PathVariable Long courseId, @Req */ @GetMapping("lti-platforms") @EnforceAtLeastInstructor - public ResponseEntity> getAllConfiguredLtiPlatforms(@ApiParam Pageable pageable) { + public ResponseEntity> getAllConfiguredLtiPlatforms(Pageable pageable) { log.info("REST request to get all configured LTI platforms"); Page platformsPage = ltiPlatformConfigurationRepository.findAll(pageable); HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), platformsPage); diff --git a/src/main/java/de/tum/cit/aet/artemis/modeling/web/ModelingAssessmentResource.java b/src/main/java/de/tum/cit/aet/artemis/modeling/web/ModelingAssessmentResource.java index 721dc7c91d7c..5b781c0b657b 100644 --- a/src/main/java/de/tum/cit/aet/artemis/modeling/web/ModelingAssessmentResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/modeling/web/ModelingAssessmentResource.java @@ -28,7 +28,6 @@ import de.tum.cit.aet.artemis.assessment.service.AssessmentService; import de.tum.cit.aet.artemis.assessment.web.AssessmentResource; import de.tum.cit.aet.artemis.core.domain.User; -import de.tum.cit.aet.artemis.core.exception.ErrorConstants; import de.tum.cit.aet.artemis.core.repository.UserRepository; import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastInstructor; import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastStudent; @@ -43,8 +42,6 @@ import de.tum.cit.aet.artemis.modeling.dto.ModelingAssessmentDTO; import de.tum.cit.aet.artemis.modeling.repository.ModelingExerciseRepository; import de.tum.cit.aet.artemis.modeling.repository.ModelingSubmissionRepository; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; /** * REST controller for managing ModelingAssessment. @@ -58,10 +55,6 @@ public class ModelingAssessmentResource extends AssessmentResource { private static final String ENTITY_NAME = "modelingAssessment"; - private static final String PUT_SUBMIT_ASSESSMENT_200_REASON = "Given assessment has been saved and used for automatic assessment by Compass"; - - private static final String POST_ASSESSMENT_AFTER_COMPLAINT_200_REASON = "Assessment has been updated after complaint"; - private final ModelingExerciseRepository modelingExerciseRepository; private final AuthorizationCheckService authCheckService; @@ -114,8 +107,6 @@ public ResponseEntity getModelingExampleAssessment(@PathVariable long ex * @return result after saving/submitting modeling assessment */ @ResponseStatus(HttpStatus.OK) - @ApiResponses({ @ApiResponse(code = 200, message = PUT_SUBMIT_ASSESSMENT_200_REASON, response = Result.class), - @ApiResponse(code = 403, message = ErrorConstants.REQ_403_REASON), @ApiResponse(code = 404, message = ErrorConstants.REQ_404_REASON) }) @PutMapping("modeling-submissions/{submissionId}/result/{resultId}/assessment") @EnforceAtLeastTutor public ResponseEntity saveModelingAssessment(@PathVariable long submissionId, @PathVariable long resultId, @@ -132,8 +123,6 @@ public ResponseEntity saveModelingAssessment(@PathVariable long submissi * @return result after saving example modeling assessment */ @ResponseStatus(HttpStatus.OK) - @ApiResponses({ @ApiResponse(code = 200, message = PUT_SUBMIT_ASSESSMENT_200_REASON, response = Result.class), - @ApiResponse(code = 403, message = ErrorConstants.REQ_403_REASON), @ApiResponse(code = 404, message = ErrorConstants.REQ_404_REASON) }) @PutMapping("modeling-submissions/{exampleSubmissionId}/example-assessment") @EnforceAtLeastTutor public ResponseEntity saveModelingExampleAssessment(@PathVariable long exampleSubmissionId, @RequestBody List feedbacks) { @@ -151,8 +140,6 @@ public ResponseEntity saveModelingExampleAssessment(@PathVariable long e * @return the updated result */ @ResponseStatus(HttpStatus.OK) - @ApiResponses({ @ApiResponse(code = 200, message = POST_ASSESSMENT_AFTER_COMPLAINT_200_REASON, response = Result.class), - @ApiResponse(code = 403, message = ErrorConstants.REQ_403_REASON), @ApiResponse(code = 404, message = ErrorConstants.REQ_404_REASON) }) @PutMapping("modeling-submissions/{submissionId}/assessment-after-complaint") @EnforceAtLeastTutor public ResponseEntity updateModelingAssessmentAfterComplaint(@PathVariable Long submissionId, @RequestBody AssessmentUpdateDTO assessmentUpdate) { diff --git a/src/main/java/de/tum/cit/aet/artemis/modeling/web/ModelingSubmissionResource.java b/src/main/java/de/tum/cit/aet/artemis/modeling/web/ModelingSubmissionResource.java index 75ee0c51c4bb..95a41a0f695a 100644 --- a/src/main/java/de/tum/cit/aet/artemis/modeling/web/ModelingSubmissionResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/modeling/web/ModelingSubmissionResource.java @@ -29,11 +29,9 @@ import de.tum.cit.aet.artemis.assessment.domain.GradingCriterion; import de.tum.cit.aet.artemis.assessment.domain.Result; import de.tum.cit.aet.artemis.assessment.repository.GradingCriterionRepository; -import de.tum.cit.aet.artemis.assessment.service.ResultService; import de.tum.cit.aet.artemis.core.domain.User; import de.tum.cit.aet.artemis.core.exception.AccessForbiddenException; import de.tum.cit.aet.artemis.core.exception.BadRequestAlertException; -import de.tum.cit.aet.artemis.core.exception.ErrorConstants; import de.tum.cit.aet.artemis.core.repository.UserRepository; import de.tum.cit.aet.artemis.core.security.Role; import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastStudent; @@ -53,8 +51,6 @@ import de.tum.cit.aet.artemis.modeling.repository.ModelingSubmissionRepository; import de.tum.cit.aet.artemis.modeling.service.ModelingSubmissionService; import de.tum.cit.aet.artemis.plagiarism.service.PlagiarismService; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; /** * REST controller for managing ModelingSubmission. @@ -71,8 +67,6 @@ public class ModelingSubmissionResource extends AbstractSubmissionResource { @Value("${jhipster.clientApp.name}") private String applicationName; - private static final String GET_200_SUBMISSIONS_REASON = ""; - private final ModelingSubmissionService modelingSubmissionService; private final ModelingSubmissionRepository modelingSubmissionRepository; @@ -85,7 +79,7 @@ public class ModelingSubmissionResource extends AbstractSubmissionResource { private final PlagiarismService plagiarismService; - public ModelingSubmissionResource(SubmissionRepository submissionRepository, ResultService resultService, ModelingSubmissionService modelingSubmissionService, + public ModelingSubmissionResource(SubmissionRepository submissionRepository, ModelingSubmissionService modelingSubmissionService, ModelingExerciseRepository modelingExerciseRepository, AuthorizationCheckService authCheckService, UserRepository userRepository, ExerciseRepository exerciseRepository, GradingCriterionRepository gradingCriterionRepository, ExamSubmissionService examSubmissionService, StudentParticipationRepository studentParticipationRepository, ModelingSubmissionRepository modelingSubmissionRepository, PlagiarismService plagiarismService) { @@ -170,8 +164,6 @@ private ResponseEntity handleModelingSubmission(Long exercis * @return a list of modeling submissions */ @ResponseStatus(HttpStatus.OK) - @ApiResponses({ @ApiResponse(code = 200, message = GET_200_SUBMISSIONS_REASON, response = ModelingSubmission.class, responseContainer = "List"), - @ApiResponse(code = 403, message = ErrorConstants.REQ_403_REASON), @ApiResponse(code = 404, message = ErrorConstants.REQ_404_REASON), }) @GetMapping("exercises/{exerciseId}/modeling-submissions") @EnforceAtLeastTutor public ResponseEntity> getAllModelingSubmissions(@PathVariable Long exerciseId, @RequestParam(defaultValue = "false") boolean submittedOnly, diff --git a/src/main/java/de/tum/cit/aet/artemis/text/web/TextAssessmentResource.java b/src/main/java/de/tum/cit/aet/artemis/text/web/TextAssessmentResource.java index 8ec980049277..900347ecc54e 100644 --- a/src/main/java/de/tum/cit/aet/artemis/text/web/TextAssessmentResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/text/web/TextAssessmentResource.java @@ -43,7 +43,6 @@ import de.tum.cit.aet.artemis.athena.service.AthenaFeedbackSendingService; import de.tum.cit.aet.artemis.core.domain.User; import de.tum.cit.aet.artemis.core.exception.BadRequestAlertException; -import de.tum.cit.aet.artemis.core.exception.ErrorConstants; import de.tum.cit.aet.artemis.core.repository.UserRepository; import de.tum.cit.aet.artemis.core.security.Role; import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastInstructor; @@ -66,8 +65,6 @@ import de.tum.cit.aet.artemis.text.service.TextAssessmentService; import de.tum.cit.aet.artemis.text.service.TextBlockService; import de.tum.cit.aet.artemis.text.service.TextSubmissionService; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; /** * REST controller for managing TextAssessment. @@ -166,7 +163,6 @@ public ResponseEntity saveTextAssessment(@PathVariable Long participatio * @return result after saving example text assessment */ @ResponseStatus(HttpStatus.OK) - @ApiResponses({ @ApiResponse(code = 403, message = ErrorConstants.REQ_403_REASON), @ApiResponse(code = 404, message = ErrorConstants.REQ_404_REASON) }) @PutMapping("exercises/{exerciseId}/example-submissions/{exampleSubmissionId}/example-text-assessment") @EnforceAtLeastTutor public ResponseEntity saveTextExampleAssessment(@PathVariable long exerciseId, @PathVariable long exampleSubmissionId, @RequestBody TextAssessmentDTO textAssessment) { From 49a75cd92cb79d48d6b969ed55415dd6d39a6136 Mon Sep 17 00:00:00 2001 From: Stephan Krusche Date: Fri, 20 Sep 2024 00:11:14 +0200 Subject: [PATCH 14/49] Development: Update docs requirements --- docs/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/requirements.txt b/docs/requirements.txt index f62d541fe0b4..fdf26e7ee025 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -5,3 +5,4 @@ sphinxcontrib-bibtex==2.6.3 requests==2.32.3 zipp==3.20.2 docutils==0.20.1 +urllib3==2.2.3 From 203342383f71d4e5274b31e1103ee3fa779c983f Mon Sep 17 00:00:00 2001 From: Stephan Krusche Date: Fri, 20 Sep 2024 09:36:07 +0200 Subject: [PATCH 15/49] Development: Revert httpclient5 update due to issues with Docker Java --- build.gradle | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 973eb0147347..3415b1b37a88 100644 --- a/build.gradle +++ b/build.gradle @@ -231,8 +231,9 @@ dependencies { // implementation "com.offbytwo.jenkins:jenkins-client:0.3.8" implementation files("libs/jenkins-client-0.4.1.jar") // The following 4 dependencies are explicitly integrated as transitive dependencies of jenkins-client-0.4.0.jar - implementation "org.apache.httpcomponents.client5:httpclient5:5.4" - implementation "org.apache.httpcomponents.core5:httpcore5:5.3" + // NOTE: we cannot upgrade to the latest version for org.apache.httpcomponents because of exceptions in Docker Java + implementation "org.apache.httpcomponents.client5:httpclient5:5.3.1" // also used by Docker Java + implementation "org.apache.httpcomponents.core5:httpcore5:5.2.5" implementation "org.apache.httpcomponents:httpmime:4.5.14" implementation("org.dom4j:dom4j:2.1.4") { // Note: avoid org.xml.sax.SAXNotRecognizedException: unrecognized feature http://xml.org/sax/features/external-general-entities From 79e25b584c37f2a8fbffdbdc010d173d54f6f142 Mon Sep 17 00:00:00 2001 From: Stephan Krusche Date: Fri, 20 Sep 2024 11:12:53 +0200 Subject: [PATCH 16/49] Development: Fix issues with server test coverage verification --- build.gradle | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 3415b1b37a88..5377a61b745b 100644 --- a/build.gradle +++ b/build.gradle @@ -152,11 +152,8 @@ private excludedClassFilesForReport(classDirectories) { classDirectories.setFrom(files(classDirectories.files.collect { fileTree(dir: it, exclude: [ - "**/de/tum/in/www1/artemis/domain/**/*_*", - "**/de/tum/in/www1/artemis/config/migration/entries/**", - "**/de/tum/in/www1/artemis/service/connectors/pyris/dto/**", - "**/de/tum/in/www1/artemis/web/rest/iris/dto/**", - "**/org/eclipse/jgit/**", + "**/de/tum/cit/aet/artemis/**/domain/**/*_*", + "**/de/tum/cit/aet/artemis/core/config/migration/entries/**", "**/gradle-wrapper.jar/**" ] ) @@ -180,13 +177,13 @@ jacocoTestCoverageVerification { counter = "INSTRUCTION" value = "COVEREDRATIO" // TODO: in the future the following value should become higher than 0.92 - minimum = 0.895 + minimum = 0.894 } limit { counter = "CLASS" value = "MISSEDCOUNT" // TODO: in the future the following value should become less than 10 - maximum = 40 + maximum = 60 } } } From 0354197ab5c51b10b6db04331f4a5e0f8ba3328f Mon Sep 17 00:00:00 2001 From: Marcel Gaupp Date: Fri, 20 Sep 2024 17:49:04 +0200 Subject: [PATCH 17/49] Programming exercises: Enable empty template for LocalCI (#9280) --- ...alCIProgrammingLanguageFeatureService.java | 3 +- src/main/resources/config/application.yml | 2 +- .../templates/aeolus/empty/default.sh | 37 +++++++++++++++++++ .../templates/aeolus/empty/default.yaml | 23 ++++++++++++ .../gitlabci/empty/regularRuns/.gitlab-ci.yml | 5 ++- .../jenkins/empty/regularRuns/pipeline.groovy | 12 ++++-- .../programming-exercise-update.component.ts | 1 + ...ogramming-exercise-language.component.html | 22 +++++++++++ ...programming-exercise-language.component.ts | 10 ++++- .../webapp/i18n/de/programmingExercise.json | 13 +++++++ .../webapp/i18n/en/programmingExercise.json | 13 +++++++ 11 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 src/main/resources/templates/aeolus/empty/default.sh create mode 100644 src/main/resources/templates/aeolus/empty/default.yaml diff --git a/src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIProgrammingLanguageFeatureService.java b/src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIProgrammingLanguageFeatureService.java index 1a5e3553cc27..967e05604f30 100644 --- a/src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIProgrammingLanguageFeatureService.java +++ b/src/main/java/de/tum/cit/aet/artemis/programming/service/localci/LocalCIProgrammingLanguageFeatureService.java @@ -3,6 +3,7 @@ import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_LOCALCI; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.ASSEMBLER; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.C; +import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.EMPTY; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.HASKELL; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.JAVA; import static de.tum.cit.aet.artemis.programming.domain.ProgrammingLanguage.JAVASCRIPT; @@ -37,7 +38,7 @@ public class LocalCIProgrammingLanguageFeatureService extends ProgrammingLanguag public LocalCIProgrammingLanguageFeatureService() { // Must be extended once a new programming language is added - // TODO LOCALVC_CI: Local CI is not supporting EMPTY at the moment. + programmingLanguageFeatures.put(EMPTY, new ProgrammingLanguageFeature(EMPTY, false, false, false, false, false, List.of(), false, true)); programmingLanguageFeatures.put(JAVA, new ProgrammingLanguageFeature(JAVA, true, true, true, true, false, List.of(PLAIN_GRADLE, GRADLE_GRADLE, PLAIN_MAVEN, MAVEN_MAVEN), false, true)); programmingLanguageFeatures.put(PYTHON, new ProgrammingLanguageFeature(PYTHON, false, false, true, false, false, List.of(), false, true)); diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml index 630a9c527db1..924d087ec8f2 100644 --- a/src/main/resources/config/application.yml +++ b/src/main/resources/config/application.yml @@ -69,7 +69,7 @@ artemis: # possible overrides: maven, gradle default: "ls1tum/artemis-maven-template:java17-21" empty: - default: "ls1tum/artemis-maven-template:java17-21" + default: "ubuntu:24.04" python: default: "ls1tum/artemis-python-docker:latest" c: diff --git a/src/main/resources/templates/aeolus/empty/default.sh b/src/main/resources/templates/aeolus/empty/default.sh new file mode 100644 index 000000000000..578e9bc900c5 --- /dev/null +++ b/src/main/resources/templates/aeolus/empty/default.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +set -e +export AEOLUS_INITIAL_DIRECTORY=${PWD} +install_dependencies () { + echo '⚙️ executing install_dependencies' + # TODO: Install dependencies not provided by the Docker image + echo 'Install dependencies' +} + +run_tests () { + echo '⚙️ executing run_tests' + # TODO: Run the tests and generate JUnit XMLs + echo 'Hello World' +} + +process_results () { + echo '⚙️ executing process_results' + rm -rf results + mkdir results + # TODO: Move JUnit XMLs into the results directory +} + +main () { + if [[ "${1}" == "aeolus_sourcing" ]]; then + return 0 # just source to use the methods in the subshell, no execution + fi + local _script_name + _script_name=${BASH_SOURCE[0]:-$0} + cd "${AEOLUS_INITIAL_DIRECTORY}" + bash -c "source ${_script_name} aeolus_sourcing; install_dependencies" + cd "${AEOLUS_INITIAL_DIRECTORY}" + bash -c "source ${_script_name} aeolus_sourcing; run_tests" + cd "${AEOLUS_INITIAL_DIRECTORY}" + bash -c "source ${_script_name} aeolus_sourcing; process_results" +} + +main "${@}" diff --git a/src/main/resources/templates/aeolus/empty/default.yaml b/src/main/resources/templates/aeolus/empty/default.yaml new file mode 100644 index 000000000000..3b1b9deaedd2 --- /dev/null +++ b/src/main/resources/templates/aeolus/empty/default.yaml @@ -0,0 +1,23 @@ +api: v0.0.1 +metadata: + name: Empty + id: empty + description: Provides a starting point +actions: + - name: install_dependencies + script: |- + # TODO: Install dependencies not provided by the Docker image + echo 'Install dependencies' + - name: run_tests + script: |- + # TODO: Run the tests and generate JUnit XMLs + echo 'Hello World' + - name: process_results + script: |- + rm -rf results + mkdir results + # TODO: Move JUnit XMLs into the results directory + results: + - name: junit + path: results/*.xml + type: junit diff --git a/src/main/resources/templates/gitlabci/empty/regularRuns/.gitlab-ci.yml b/src/main/resources/templates/gitlabci/empty/regularRuns/.gitlab-ci.yml index 3fcb20956dc8..3a16b66b7143 100644 --- a/src/main/resources/templates/gitlabci/empty/regularRuns/.gitlab-ci.yml +++ b/src/main/resources/templates/gitlabci/empty/regularRuns/.gitlab-ci.yml @@ -17,7 +17,10 @@ test-job: - git clone --branch ${ARTEMIS_SUBMISSION_GIT_BRANCH} ${CI_SERVER_PROTOCOL}://${ARTEMIS_TEST_GIT_USER}:${ARTEMIS_TEST_GIT_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME} assignment - export ARTEMIS_NOTIFICATION_SECRET=[hidden] # Workaround for overwriting the secret - export ARTEMIS_TEST_GIT_TOKEN=[hidden] - - mvn --version && echo "ARTEMIS_BUILD_STATUS=success" > .env || echo "ARTEMIS_BUILD_STATUS=failed" > .env + # TODO: Install dependencies not provided by the Docker image + # TODO: Run the tests and generate JUnit XMLs + - echo "Hello World" && echo "ARTEMIS_BUILD_STATUS=success" > .env || echo "ARTEMIS_BUILD_STATUS=failed" > .env + # TODO: Move JUnit XMLs into the ${ARTEMIS_TEST_RESULTS_DIR} directory after_script: - echo "ARTEMIS_TEST_GIT_HASH=$(git rev-parse HEAD)" >> .env - echo "ARTEMIS_SUBMISSION_GIT_HASH=${CI_COMMIT_SHA}" >> .env diff --git a/src/main/resources/templates/jenkins/empty/regularRuns/pipeline.groovy b/src/main/resources/templates/jenkins/empty/regularRuns/pipeline.groovy index b4c800a23cf1..7d52cd089c67 100644 --- a/src/main/resources/templates/jenkins/empty/regularRuns/pipeline.groovy +++ b/src/main/resources/templates/jenkins/empty/regularRuns/pipeline.groovy @@ -28,10 +28,13 @@ private void runTestSteps() { * Run unit tests */ private void test() { - stage('Build') { - sh ''' - mvn --version - ''' + stage('Install dependencies') { + // TODO: Install dependencies not provided by the Docker image + sh 'echo "Install dependencies"' + } + stage('Run tests') { + // TODO: Run the tests and generate JUnit XMLs + sh 'echo "Hello World"' } } @@ -45,6 +48,7 @@ void postBuildTasks() { rm -rf results mkdir results ''' + // TODO: Move JUnit XMLs into the results directory } // very important, do not remove diff --git a/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts b/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts index e1257c9c467f..aff229febc88 100644 --- a/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts +++ b/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts @@ -270,6 +270,7 @@ export class ProgrammingExerciseUpdateComponent implements AfterViewInit, OnDest } else { this.programmingExercise.buildConfig = new ProgrammingExerciseBuildConfig(); } + this.programmingExercise.customizeBuildPlanWithAeolus = language === ProgrammingLanguage.EMPTY; } // If we switch to another language which does not support static code analysis we need to reset options related to static code analysis diff --git a/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.html b/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.html index 2f4b0b556c7f..bdabddb25dc8 100644 --- a/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.html +++ b/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.html @@ -56,6 +56,28 @@ }
} + @if (programmingExercise.programmingLanguage === ProgrammingLanguage.EMPTY) { +
+

+ + +

+
    +
  1. +
  2. +

    +
      +
    1. +
    2. +
    3. +
    +
  3. +
  4. +
  5. +
  6. +
+
+ } @if (programmingExercise.programmingLanguage && programmingExerciseCreationConfig.packageNameRequired && programmingExercise.projectType !== ProjectType.XCODE) {
diff --git a/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.ts b/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.ts index 696d75ce185f..26951968a7b2 100644 --- a/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.ts +++ b/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.ts @@ -1,6 +1,6 @@ import { AfterViewChecked, AfterViewInit, Component, EventEmitter, Input, OnDestroy, ViewChild } from '@angular/core'; import { ProgrammingExercise, ProgrammingLanguage, ProjectType } from 'app/entities/programming/programming-exercise.model'; -import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons'; +import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons'; import { ProgrammingExerciseCreationConfig } from 'app/exercises/programming/manage/update/programming-exercise-creation-config'; import { PROFILE_AEOLUS, PROFILE_LOCALCI } from 'app/app.constants'; import { NgModel } from '@angular/forms'; @@ -32,10 +32,16 @@ export class ProgrammingExerciseLanguageComponent implements AfterViewChecked, A fieldSubscriptions: (Subscription | undefined)[] = []; - faQuestionCircle = faQuestionCircle; + faExclamationTriangle = faExclamationTriangle; protected readonly PROFILE_LOCALCI = PROFILE_LOCALCI; protected readonly PROFILE_AEOLUS = PROFILE_AEOLUS; + readonly DOCKER_REGISTRY_LINKS = { + ghcrLink: 'https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry', + dockerhubLink: 'https://hub.docker.com/', + }; + readonly DOCUMENTATION_LINK = 'https://docs.artemis.cit.tum.de/user/exercises/programming.html'; + ngAfterViewInit() { this.fieldSubscriptions.push(this.selectLanguageField.valueChanges?.subscribe(() => setTimeout(() => this.calculateFormValid()))); } diff --git a/src/main/webapp/i18n/de/programmingExercise.json b/src/main/webapp/i18n/de/programmingExercise.json index 4e493f7d4daf..9d67c6853e90 100644 --- a/src/main/webapp/i18n/de/programmingExercise.json +++ b/src/main/webapp/i18n/de/programmingExercise.json @@ -657,6 +657,19 @@ "template": "Vorlage", "history": "Commit-Historie", "result": "Ergebnis" + }, + "otherLanguageHints": { + "title": "Führe folgende Schritte aus, um eine andere Sprache zu benutzen. Siehe die Dokumentation für Details.", + "setImage": "Lege ein angepasstes Docker Image mit benötigten Abhängigkeiten fest (erstelle möglicherweise ein eigenes und lade es in die GitHub Container Registry oder auf den Docker Hub hoch).", + "buildScript": { + "title": "Passe das Build Skript an:", + "dependencies": "Optional: Installiere aufgabenspezifische Abhängigkeiten.", + "runTests": "Führe alle Tests aus. Sie sollten JUnit XML Dateien generieren.", + "moveResults": "Bewege die XML Dateien in das {{resultsDirectory}} Verzeichnis." + }, + "pushExercise": "Lade den Aufgaben-Code in das entsprechende Repository. Es wird in {{checkoutDirectory}} ausgecheckt.", + "pushSolution": "Lade den Lösungs-Code in das entsprechende Repository. Es wird nicht ausgecheckt.", + "pushTest": "Lade den Test-Code in das entsprechende Repository. Es wird in {{checkoutDirectory}} ausgecheckt." } }, "error": { diff --git a/src/main/webapp/i18n/en/programmingExercise.json b/src/main/webapp/i18n/en/programmingExercise.json index 1883d8294abc..30712348289a 100644 --- a/src/main/webapp/i18n/en/programmingExercise.json +++ b/src/main/webapp/i18n/en/programmingExercise.json @@ -658,6 +658,19 @@ "template": "Template", "history": "Commit History", "result": "Result" + }, + "otherLanguageHints": { + "title": "To use another language, complete the following tasks. See the documentation for details.", + "setImage": "Specify a custom Docker image with the required dependencies (potentially create a custom one and upload it to the GitHub Container Registry or Docker Hub).", + "buildScript": { + "title": "Customize the build script to:", + "dependencies": "Optional: Install exercise specific dependencies.", + "runTests": "Run all tests. They should generate JUnit XML files.", + "moveResults": "Move the XML files into the {{resultsDirectory}} directory." + }, + "pushExercise": "Push the exercise code to its repository. It will be checked out at {{checkoutDirectory}}.", + "pushSolution": "Push the solution code to its repository. It will not be checked out.", + "pushTest": "Push the test code to its repository. It will be checked out in {{checkoutDirectory}}." } }, "error": { From e3f5cdde0aa8fca056e2baa82ea71f1f64ef4e06 Mon Sep 17 00:00:00 2001 From: Marcel Gaupp Date: Sun, 22 Sep 2024 20:28:27 +0200 Subject: [PATCH 18/49] Plagiarism checks: Fix files not being shown in plagiarism viewer (#9347) --- .../text-submission-viewer.component.html | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/webapp/app/exercises/shared/plagiarism/plagiarism-split-view/text-submission-viewer/text-submission-viewer.component.html b/src/main/webapp/app/exercises/shared/plagiarism/plagiarism-split-view/text-submission-viewer/text-submission-viewer.component.html index 96315f6b7d57..e1becc774b87 100644 --- a/src/main/webapp/app/exercises/shared/plagiarism/plagiarism-split-view/text-submission-viewer/text-submission-viewer.component.html +++ b/src/main/webapp/app/exercises/shared/plagiarism/plagiarism-split-view/text-submission-viewer/text-submission-viewer.component.html @@ -8,12 +8,9 @@
} @if (!loading && !binaryFile!! && !cannotLoadFiles) { -
+
+ +
} @if (loading && !cannotLoadFiles) {
From 3ab435c638121897f7a3296e0f87b873665933bd Mon Sep 17 00:00:00 2001 From: Stephan Krusche Date: Sun, 22 Sep 2024 20:29:52 +0200 Subject: [PATCH 19/49] Development: Update client dependencies --- package-lock.json | 164 +++++++++++++++++++++++----------------------- package.json | 20 +++--- 2 files changed, 92 insertions(+), 92 deletions(-) diff --git a/package-lock.json b/package-lock.json index bb5825b0477e..1ace05464f69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,13 +11,13 @@ "license": "MIT", "dependencies": { "@angular/animations": "18.2.5", - "@angular/cdk": "18.2.4", + "@angular/cdk": "18.2.5", "@angular/common": "18.2.5", "@angular/compiler": "18.2.5", "@angular/core": "18.2.5", "@angular/forms": "18.2.5", "@angular/localize": "18.2.5", - "@angular/material": "18.2.4", + "@angular/material": "18.2.5", "@angular/platform-browser": "18.2.5", "@angular/platform-browser-dynamic": "18.2.5", "@angular/router": "18.2.5", @@ -55,12 +55,12 @@ "jszip": "3.10.1", "lodash-es": "4.17.21", "mobile-drag-drop": "3.0.0-rc.0", - "monaco-editor": "0.51.0", + "monaco-editor": "0.52.0", "ngx-infinite-scroll": "18.0.0", "ngx-webstorage": "18.0.0", "papaparse": "5.4.1", "pdfjs-dist": "4.6.82", - "posthog-js": "1.161.6", + "posthog-js": "1.163.0", "rxjs": "7.8.1", "showdown": "2.1.0", "showdown-highlight": "3.1.0", @@ -78,13 +78,13 @@ }, "devDependencies": { "@angular-builders/jest": "18.0.0", - "@angular-devkit/build-angular": "18.2.4", + "@angular-devkit/build-angular": "18.2.5", "@angular-eslint/builder": "18.3.1", "@angular-eslint/eslint-plugin": "18.3.1", "@angular-eslint/eslint-plugin-template": "18.3.1", "@angular-eslint/schematics": "18.3.1", "@angular-eslint/template-parser": "18.3.1", - "@angular/cli": "18.2.4", + "@angular/cli": "18.2.5", "@angular/compiler-cli": "18.2.5", "@angular/language-service": "18.2.5", "@sentry/types": "8.30.0", @@ -101,7 +101,7 @@ "@types/uuid": "10.0.0", "@typescript-eslint/eslint-plugin": "8.6.0", "@typescript-eslint/parser": "8.6.0", - "eslint": "9.10.0", + "eslint": "9.11.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-deprecation": "3.0.0", "eslint-plugin-jest": "28.8.3", @@ -120,7 +120,7 @@ "ng-mocks": "14.13.1", "prettier": "3.3.3", "rimraf": "6.0.1", - "sass": "1.79.1", + "sass": "1.79.3", "ts-jest": "29.2.5", "typescript": "5.5.4", "weak-napi": "2.0.2" @@ -211,13 +211,13 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1802.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.4.tgz", - "integrity": "sha512-VH7AwGng1zuWPTJoH1IgHYeNhqZIgzlwDx39JPmArZAW/WZHDILWB7ipbTNw0R4U4VncrXJqDmMVex7NdHP6sg==", + "version": "0.1802.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.5.tgz", + "integrity": "sha512-c7sVoW85Yqj7IYvNKxtNSGS5I7gWpORorg/xxLZX3OkHWXDrwYbb5LN/2p5/Aytxyb0aXl4o5fFOu6CUwcaLUw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "18.2.4", + "@angular-devkit/core": "18.2.5", "rxjs": "7.8.1" }, "engines": { @@ -227,17 +227,17 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.4.tgz", - "integrity": "sha512-zLDstS95Yb7iBA1ZCYe3LsOLpIhr0ZC3sZ03PhVvAGbVRGSbQNnhQRZLKMk+LDhYJiG+eNFQGLfU3RfZrGds7A==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.5.tgz", + "integrity": "sha512-dIvb0AHoRIMM6tLuG4t6lDDslSAYP77wqytodsN317UzFOuuCPernXbO8NJs+QHxj09nPsem1T5vnvpO2E/PVQ==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1802.4", - "@angular-devkit/build-webpack": "0.1802.4", - "@angular-devkit/core": "18.2.4", - "@angular/build": "18.2.4", + "@angular-devkit/architect": "0.1802.5", + "@angular-devkit/build-webpack": "0.1802.5", + "@angular-devkit/core": "18.2.5", + "@angular/build": "18.2.5", "@babel/core": "7.25.2", "@babel/generator": "7.25.0", "@babel/helper-annotate-as-pure": "7.24.7", @@ -248,7 +248,7 @@ "@babel/preset-env": "7.25.3", "@babel/runtime": "7.25.0", "@discoveryjs/json-ext": "0.6.1", - "@ngtools/webpack": "18.2.4", + "@ngtools/webpack": "18.2.5", "@vitejs/plugin-basic-ssl": "1.1.0", "ansi-colors": "4.1.3", "autoprefixer": "10.4.20", @@ -288,7 +288,7 @@ "terser": "5.31.6", "tree-kill": "1.2.2", "tslib": "2.6.3", - "vite": "5.4.0", + "vite": "5.4.6", "watchpack": "2.4.1", "webpack": "5.94.0", "webpack-dev-middleware": "7.4.2", @@ -381,13 +381,13 @@ "license": "0BSD" }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1802.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.4.tgz", - "integrity": "sha512-juaDoguYccObm2xnzRDRlOtiL7ZyZcSAyiyls6QuO8hoo/h6phdHALJkUhI9+SIhCRQ6eUQtolC7hN3J+FZKnA==", + "version": "0.1802.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.5.tgz", + "integrity": "sha512-6qkcrWBdkxojCVHGWcdJaz4G+7QTjFvmc+3g8xvLc9sYvJq1I059gfXhDnC0FxiA0MT4cY/26ECYWUHTD5CJLQ==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.1802.4", + "@angular-devkit/architect": "0.1802.5", "rxjs": "7.8.1" }, "engines": { @@ -401,9 +401,9 @@ } }, "node_modules/@angular-devkit/core": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.4.tgz", - "integrity": "sha512-svlgZ0vbLrfNJAQE5WePAutcYIyA7C0OfzKSTMsfV2X1I+1blYDaZIu/ocnHqofMHu6ZqdSaaU/p/rieqU8fcA==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.5.tgz", + "integrity": "sha512-r9TumPlJ8PvA2+yz4sp+bUHgtznaVKzhvXTN5qL1k4YP8LJ7iZWMR2FOP+HjukHZOTsenzmV9pszbogabqwoZQ==", "dev": true, "license": "MIT", "dependencies": { @@ -429,13 +429,13 @@ } }, "node_modules/@angular-devkit/schematics": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.4.tgz", - "integrity": "sha512-s2WdUhyLlKj5kOjb6vrvJg9/31KvgyRJGjy7PnzS43tpwF9MLuM3AYhuJsXHPhx+i0nyWn/Jnd8ZLjMzXljSxg==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.5.tgz", + "integrity": "sha512-NUmz2UQ1Xl4cf4j1AgkwIfsCjBzAPgfeC3IBrD29hSOBE1Y3j6auqjBkvw50v6mbSPxESND995Xy13HpK1Xflw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "18.2.4", + "@angular-devkit/core": "18.2.5", "jsonc-parser": "3.3.1", "magic-string": "0.30.11", "ora": "5.4.1", @@ -563,14 +563,14 @@ } }, "node_modules/@angular/build": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.4.tgz", - "integrity": "sha512-GVs7O7wxNMJCkqh6Vv2u9GEArWg9jyEt8Fofd6CJGzxKBYQ4hR5gjzL/lU6kNFiMcioS1wm1f6qtJtgilUO+9A==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.5.tgz", + "integrity": "sha512-XWkmjzgeUga0SJ0lYSYcTuYOWTyqcln2mNfBp7Ae/GZ+/7+APbedsIZEiZGZwveOIyOpTM5wguNSoe9khDl5Ig==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1802.4", + "@angular-devkit/architect": "0.1802.5", "@babel/core": "7.25.2", "@babel/helper-annotate-as-pure": "7.24.7", "@babel/helper-split-export-declaration": "7.24.7", @@ -592,7 +592,7 @@ "rollup": "4.20.0", "sass": "1.77.6", "semver": "7.6.3", - "vite": "5.4.0", + "vite": "5.4.6", "watchpack": "2.4.1" }, "engines": { @@ -650,9 +650,9 @@ } }, "node_modules/@angular/cdk": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.4.tgz", - "integrity": "sha512-o+TuxZDqStfkviEkCR05pVyP6R2RIruEs/45Cms76hlsIheMoxRaxir/yrHdh4tZESJJhcO/EVE+aymNIRWAfg==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.5.tgz", + "integrity": "sha512-HLg5cfrIrgNIJJ+0v3kLieHeLPJLFNOBO359holXOrKUPRG+XQ3CT8EzSvREFm1XkaSEsDC0+dnG0ouNhOPFpQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -667,18 +667,18 @@ } }, "node_modules/@angular/cli": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.4.tgz", - "integrity": "sha512-n+Y2xlgcpTZ+MZmycf2b3ceVvANDJFkDEodobVtyG63WvGOhkZ3aGhT7sHguKpAQwJLicSf8zF2z+v1Yi0DvRw==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.5.tgz", + "integrity": "sha512-97uNs0HsOdnMaTlNJKFjIBUXw0wz43uYvSSKmIpBt7eq1LaPLju1G/qpDIHx2YwhMClPrXXrW2H/xdvqZiIw+w==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.1802.4", - "@angular-devkit/core": "18.2.4", - "@angular-devkit/schematics": "18.2.4", + "@angular-devkit/architect": "0.1802.5", + "@angular-devkit/core": "18.2.5", + "@angular-devkit/schematics": "18.2.5", "@inquirer/prompts": "5.3.8", "@listr2/prompt-adapter-inquirer": "2.0.15", - "@schematics/angular": "18.2.4", + "@schematics/angular": "18.2.5", "@yarnpkg/lockfile": "1.1.0", "ini": "4.1.3", "jsonc-parser": "3.3.1", @@ -833,16 +833,16 @@ } }, "node_modules/@angular/material": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-18.2.4.tgz", - "integrity": "sha512-F09145mI/EAHY9ngdnQTo3pFRmUoU/50i6cmddtL4cse0WidatoodQr0gZCksxhmpJgRy5mTcjh/LU2hShOgcA==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-18.2.5.tgz", + "integrity": "sha512-+Yz8ayKz1ALz2UvPrM33FHSUmrE0GKHn+Gg79l6NdC4eSrzAAYBVdLfQvCBWCgtdvs7IiegbCnnAJiqXVC1DDg==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { "@angular/animations": "^18.0.0 || ^19.0.0", - "@angular/cdk": "18.2.4", + "@angular/cdk": "18.2.5", "@angular/common": "^18.0.0 || ^19.0.0", "@angular/core": "^18.0.0 || ^19.0.0", "@angular/forms": "^18.0.0 || ^19.0.0", @@ -3422,9 +3422,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.10.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz", - "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==", + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.0.tgz", + "integrity": "sha512-LPkkenkDqyzTFauZLLAPhIb48fj6drrfMvRGSL9tS3AcZBSVTllemLSNyCvHNNL2t797S/6DJNSIwRwXgMO/eQ==", "dev": true, "license": "MIT", "engines": { @@ -3442,9 +3442,9 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.1.0.tgz", - "integrity": "sha512-autAXT203ixhqei9xt+qkYOvY8l6LAFIdT2UXc/RPNeUVfqRF1BV94GTJyVPFKT8nFM6MyVJhjLj9E8JWvf5zQ==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", + "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -5226,9 +5226,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.4.tgz", - "integrity": "sha512-JVDRexu3q7lg2oqJG36RtX7cqTheoZRwg2HhMV8hYXUDL0fyOrv2galwTCgXrx7vAjlx45L2uR2kuWbgW0VVcQ==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.5.tgz", + "integrity": "sha512-L0n4eHObeqEOYRfSP+e4SeF/dmwxOIFy9xYvYCOUwOLrW4b3+a1+kkT30pqyfL72LFtpf0cmUwaWEFIcWl5PCg==", "dev": true, "license": "MIT", "engines": { @@ -5873,14 +5873,14 @@ ] }, "node_modules/@schematics/angular": { - "version": "18.2.4", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.4.tgz", - "integrity": "sha512-GxrPv4eOPrjMKoAVhch9eprW8H/DFhBy5Zgp7CgGui9NprYkkubxw/yyo11WfR5CFZ/q5AfsjV76dPCkhLwLmA==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.5.tgz", + "integrity": "sha512-tBXhk9OGT4U6VsBNbuCNl2ITDOF3NYdGrEieIHU+lHSkpJNGZUIGxCgXCETXkmXDq1pe4wFZSKelWjeqYDfX0g==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "18.2.4", - "@angular-devkit/schematics": "18.2.4", + "@angular-devkit/core": "18.2.5", + "@angular-devkit/schematics": "18.2.5", "jsonc-parser": "3.3.1" }, "engines": { @@ -10216,9 +10216,9 @@ } }, "node_modules/eslint": { - "version": "9.10.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.10.0.tgz", - "integrity": "sha512-Y4D0IgtBZfOcOUAIQTSXBKoNGfY0REGqHJG6+Q81vNippW5YlKjHFj4soMxamKK1NXHUWuBZTLdU3Km+L/pcHw==", + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.11.0.tgz", + "integrity": "sha512-yVS6XODx+tMFMDFcG4+Hlh+qG7RM6cCJXtQhCKLSsr3XkLvWggHjCqjfh0XsPPnt1c56oaT6PMgW9XWQQjdHXA==", "dev": true, "license": "MIT", "dependencies": { @@ -10226,8 +10226,8 @@ "@eslint-community/regexpp": "^4.11.0", "@eslint/config-array": "^0.18.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.10.0", - "@eslint/plugin-kit": "^0.1.0", + "@eslint/js": "9.11.0", + "@eslint/plugin-kit": "^0.2.0", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.3.0", "@nodelib/fs.walk": "^1.2.8", @@ -15936,9 +15936,9 @@ } }, "node_modules/memfs": { - "version": "4.11.2", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.11.2.tgz", - "integrity": "sha512-VcR7lEtgQgv7AxGkrNNeUAimFLT+Ov8uGu1LuOfbe/iF/dKoh/QgpoaMZlhfejvLtMxtXYyeoT7Ar1jEbWdbPA==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.12.0.tgz", + "integrity": "sha512-74wDsex5tQDSClVkeK1vtxqYCAgCoXxx+K4NSHzgU/muYVYByFqa+0RnrPO9NM6naWm1+G9JmZ0p6QHhXmeYfA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -16336,9 +16336,9 @@ "license": "MIT" }, "node_modules/monaco-editor": { - "version": "0.51.0", - "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.51.0.tgz", - "integrity": "sha512-xaGwVV1fq343cM7aOYB6lVE4Ugf0UyimdD/x5PWcWBMKENwectaEu77FAN7c5sFiyumqeJdX1RPTh1ocioyDjw==", + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.0.tgz", + "integrity": "sha512-OeWhNpABLCeTqubfqLMXGsqf6OmPU6pHM85kF3dhy6kq5hnhuVS1p3VrEW/XhWHc71P2tHyS5JFySD8mgs1crw==", "license": "MIT" }, "node_modules/moo-color": { @@ -17894,9 +17894,9 @@ "license": "MIT" }, "node_modules/posthog-js": { - "version": "1.161.6", - "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.161.6.tgz", - "integrity": "sha512-UO0z/YTuan55Kl5Yg9Xs5x1PKUkm2zGKUNPioznb4GLRcxFnLBkWoeKQXNro2YZsYJvK+MY8jlF3cdGa8BZ8/Q==", + "version": "1.163.0", + "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.163.0.tgz", + "integrity": "sha512-gpLbxZkOm06oOWg0uvCxBIVIHrhX3A5hxf9eAi/Z+aFP9DvWxwHQdGUkIWjnYUyxXilIbLxBPvWmiM98dYsAHA==", "license": "MIT", "dependencies": { "fflate": "^0.4.8", @@ -18875,9 +18875,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.79.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.79.1.tgz", - "integrity": "sha512-+mA7svoNKeL0DiJqZGeR/ZGUu8he4I8o3jyUcOFyo4eBJrwNgIMmAEwCMo/N2Y3wdjOBcRzoNxZIOtrtMX8EXg==", + "version": "1.79.3", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.79.3.tgz", + "integrity": "sha512-m7dZxh0W9EZ3cw50Me5GOuYm/tVAJAn91SUnohLRo9cXBixGUOdvmryN+dXpwR831bhoY3Zv7rEFt85PUwTmzA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 6bbcd55c3142..056c7b962033 100644 --- a/package.json +++ b/package.json @@ -14,13 +14,13 @@ ], "dependencies": { "@angular/animations": "18.2.5", - "@angular/cdk": "18.2.4", + "@angular/cdk": "18.2.5", "@angular/common": "18.2.5", "@angular/compiler": "18.2.5", "@angular/core": "18.2.5", "@angular/forms": "18.2.5", "@angular/localize": "18.2.5", - "@angular/material": "18.2.4", + "@angular/material": "18.2.5", "@angular/platform-browser": "18.2.5", "@angular/platform-browser-dynamic": "18.2.5", "@angular/router": "18.2.5", @@ -58,12 +58,12 @@ "jszip": "3.10.1", "lodash-es": "4.17.21", "mobile-drag-drop": "3.0.0-rc.0", - "monaco-editor": "0.51.0", + "monaco-editor": "0.52.0", "ngx-infinite-scroll": "18.0.0", "ngx-webstorage": "18.0.0", "papaparse": "5.4.1", "pdfjs-dist": "4.6.82", - "posthog-js": "1.161.6", + "posthog-js": "1.163.0", "rxjs": "7.8.1", "showdown": "2.1.0", "showdown-highlight": "3.1.0", @@ -88,13 +88,13 @@ "d3-transition": "^3.0.1" }, "@typescript-eslint/utils": { - "eslint": "^9.10.0" + "eslint": "^9.11.0" }, "braces": "3.0.3", "critters": "0.0.24", "debug": "4.3.7", "eslint-plugin-deprecation": { - "eslint": "^9.10.0" + "eslint": "^9.11.0" }, "eslint-plugin-jest": { "@typescript-eslint/eslint-plugin": "^8.6.0" @@ -116,13 +116,13 @@ }, "devDependencies": { "@angular-builders/jest": "18.0.0", - "@angular-devkit/build-angular": "18.2.4", + "@angular-devkit/build-angular": "18.2.5", "@angular-eslint/builder": "18.3.1", "@angular-eslint/eslint-plugin": "18.3.1", "@angular-eslint/eslint-plugin-template": "18.3.1", "@angular-eslint/schematics": "18.3.1", "@angular-eslint/template-parser": "18.3.1", - "@angular/cli": "18.2.4", + "@angular/cli": "18.2.5", "@angular/compiler-cli": "18.2.5", "@angular/language-service": "18.2.5", "@sentry/types": "8.30.0", @@ -139,7 +139,7 @@ "@types/uuid": "10.0.0", "@typescript-eslint/eslint-plugin": "8.6.0", "@typescript-eslint/parser": "8.6.0", - "eslint": "9.10.0", + "eslint": "9.11.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-deprecation": "3.0.0", "eslint-plugin-jest": "28.8.3", @@ -158,7 +158,7 @@ "ng-mocks": "14.13.1", "prettier": "3.3.3", "rimraf": "6.0.1", - "sass": "1.79.1", + "sass": "1.79.3", "ts-jest": "29.2.5", "typescript": "5.5.4", "weak-napi": "2.0.2" From 00f38c0ce034fadf6d93d66967073edfcf57856f Mon Sep 17 00:00:00 2001 From: Stephan Krusche Date: Sun, 22 Sep 2024 20:30:48 +0200 Subject: [PATCH 20/49] Development: Update server dependency protobuf-java --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5377a61b745b..dff55628b0fc 100644 --- a/build.gradle +++ b/build.gradle @@ -259,7 +259,7 @@ dependencies { implementation "org.apache.lucene:lucene-queryparser:${lucene_version}" implementation "org.apache.lucene:lucene-core:${lucene_version}" implementation "org.apache.lucene:lucene-analyzers-common:${lucene_version}" - + implementation "com.google.protobuf:protobuf-java:4.28.2" // we have to override those values to use the latest version implementation "org.slf4j:jcl-over-slf4j:${slf4j_version}" From 37a20f198bcfea3044fcf8b76ceada4a8225ceaa Mon Sep 17 00:00:00 2001 From: Leon Laurin Wehrhahn <58460654+LeonWehrhahn@users.noreply.github.com> Date: Fri, 27 Sep 2024 08:32:27 +0200 Subject: [PATCH 21/49] Modeling exercises: Add preliminary AI feedback requests for students (#9278) --- .../aet/artemis/exercise/domain/Exercise.java | 2 +- .../artemis/exercise/domain/Submission.java | 4 +- .../service/ParticipationService.java | 12 +- .../exercise/service/SubmissionService.java | 1 + .../web/AbstractSubmissionResource.java | 2 +- .../exercise/web/ParticipationResource.java | 15 +- .../ModelingExerciseFeedbackService.java | 196 ++++++++++++++++++ .../service/ModelingSubmissionService.java | 11 +- .../web/ModelingSubmissionResource.java | 18 +- .../service/TextExerciseFeedbackService.java | 4 +- .../modeling-assessment-editor.component.ts | 4 +- ...feedback-suggestion-options.component.html | 2 +- .../exercises/shared/result/result.utils.ts | 3 +- ...ise-details-student-actions.component.html | 2 +- ...rcise-details-student-actions.component.ts | 29 ++- .../result-history.component.ts | 2 +- .../modeling/ModelingExerciseUtilService.java | 10 + .../ModelingSubmissionIntegrationTest.java | 3 + .../ParticipationIntegrationTest.java | 69 ++++++ .../component/exercises/shared/result.spec.ts | 20 ++ ...deling-assessment-editor.component.spec.ts | 58 +++++- 21 files changed, 431 insertions(+), 36 deletions(-) create mode 100644 src/main/java/de/tum/cit/aet/artemis/modeling/service/ModelingExerciseFeedbackService.java diff --git a/src/main/java/de/tum/cit/aet/artemis/exercise/domain/Exercise.java b/src/main/java/de/tum/cit/aet/artemis/exercise/domain/Exercise.java index 2c7ae1b53009..7503427a81fc 100644 --- a/src/main/java/de/tum/cit/aet/artemis/exercise/domain/Exercise.java +++ b/src/main/java/de/tum/cit/aet/artemis/exercise/domain/Exercise.java @@ -613,7 +613,7 @@ public Set findResultsFilteredForStudents(Participation participation) { boolean isAssessmentOver = getAssessmentDueDate() == null || getAssessmentDueDate().isBefore(ZonedDateTime.now()); if (!isAssessmentOver) { // This allows the showing of preliminary feedback in case the assessment due date is set before its over. - if (this instanceof TextExercise) { + if (this instanceof TextExercise || this instanceof ModelingExercise) { return participation.getResults().stream().filter(result -> result.getAssessmentType() == AssessmentType.AUTOMATIC_ATHENA).collect(Collectors.toSet()); } return Set.of(); diff --git a/src/main/java/de/tum/cit/aet/artemis/exercise/domain/Submission.java b/src/main/java/de/tum/cit/aet/artemis/exercise/domain/Submission.java index 8c7d55930eaa..326507d47dd4 100644 --- a/src/main/java/de/tum/cit/aet/artemis/exercise/domain/Submission.java +++ b/src/main/java/de/tum/cit/aet/artemis/exercise/domain/Submission.java @@ -220,11 +220,11 @@ public List getManualResults() { /** * This method is necessary to ignore Athena results in the assessment view * - * @return non athena automatic results including null results + * @return non athena automatic results excluding null results */ @JsonIgnore public List getNonAthenaResults() { - return results.stream().filter(result -> result == null || !result.isAthenaAutomatic()).collect(Collectors.toCollection(ArrayList::new)); + return results.stream().filter(result -> result != null && !result.isAthenaAutomatic()).collect(Collectors.toCollection(ArrayList::new)); } /** diff --git a/src/main/java/de/tum/cit/aet/artemis/exercise/service/ParticipationService.java b/src/main/java/de/tum/cit/aet/artemis/exercise/service/ParticipationService.java index 5590e5c810f4..9074ad8ec1f8 100644 --- a/src/main/java/de/tum/cit/aet/artemis/exercise/service/ParticipationService.java +++ b/src/main/java/de/tum/cit/aet/artemis/exercise/service/ParticipationService.java @@ -715,16 +715,16 @@ public List findByExerciseAndStudentIdWithEagerSubmissions } /** - * Get the text exercise participation with the Latest Submissions and its results + * Retrieves a StudentParticipation with its latest Submission and associated Result. * - * @param participationId the id of the participation - * @return the participation with latest submission and result - * @throws EntityNotFoundException + * @param participationId The unique identifier of the participation to retrieve. + * @return A StudentParticipation object containing the latest submission and result. + * @throws EntityNotFoundException If no StudentParticipation is found with the given ID. */ - public StudentParticipation findTextExerciseParticipationWithLatestSubmissionAndResultElseThrow(Long participationId) throws EntityNotFoundException { + public StudentParticipation findExerciseParticipationWithLatestSubmissionAndResultElseThrow(Long participationId) throws EntityNotFoundException { Optional participation = participationRepository.findByIdWithLatestSubmissionAndResult(participationId); if (participation.isEmpty() || !(participation.get() instanceof StudentParticipation studentParticipation)) { - throw new EntityNotFoundException("No text exercise participation found with id " + participationId); + throw new EntityNotFoundException("No exercise participation found with id " + participationId); } return studentParticipation; } diff --git a/src/main/java/de/tum/cit/aet/artemis/exercise/service/SubmissionService.java b/src/main/java/de/tum/cit/aet/artemis/exercise/service/SubmissionService.java index fc72035f5f70..2669e856337f 100644 --- a/src/main/java/de/tum/cit/aet/artemis/exercise/service/SubmissionService.java +++ b/src/main/java/de/tum/cit/aet/artemis/exercise/service/SubmissionService.java @@ -787,6 +787,7 @@ private List getSubmissionsWithComplaintsFromComplai // add each submission with its complaint to the DTO submissions.stream().filter(submission -> submission.getResultWithComplaint() != null).forEach(submission -> { // get the complaint which belongs to the submission + submission.setResults(submission.getNonAthenaResults()); Complaint complaintOfSubmission = complaintMap.get(submission.getResultWithComplaint().getId()); prepareComplaintAndSubmission(complaintOfSubmission, submission); submissionWithComplaintDTOs.add(new SubmissionWithComplaintDTO(submission, complaintOfSubmission)); diff --git a/src/main/java/de/tum/cit/aet/artemis/exercise/web/AbstractSubmissionResource.java b/src/main/java/de/tum/cit/aet/artemis/exercise/web/AbstractSubmissionResource.java index 337f58213e7b..3dc507d37b64 100644 --- a/src/main/java/de/tum/cit/aet/artemis/exercise/web/AbstractSubmissionResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/exercise/web/AbstractSubmissionResource.java @@ -82,7 +82,7 @@ protected ResponseEntity> getAllSubmissions(Long exerciseId, bo submission.getParticipation().setExercise(null); } // Important for exercises with Athena results - if (assessedByTutor) { + if (assessedByTutor && !examMode) { submission.setResults(submission.getNonAthenaResults()); } }); diff --git a/src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java b/src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java index a9f3d94ae2d2..6559c28b9d93 100644 --- a/src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java @@ -81,7 +81,9 @@ import de.tum.cit.aet.artemis.exercise.service.ExerciseDateService; import de.tum.cit.aet.artemis.exercise.service.ParticipationAuthorizationCheckService; import de.tum.cit.aet.artemis.exercise.service.ParticipationService; +import de.tum.cit.aet.artemis.fileupload.domain.FileUploadExercise; import de.tum.cit.aet.artemis.modeling.domain.ModelingExercise; +import de.tum.cit.aet.artemis.modeling.service.ModelingExerciseFeedbackService; import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise; import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseParticipation; import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseStudentParticipation; @@ -167,6 +169,8 @@ public class ParticipationResource { private final TextExerciseFeedbackService textExerciseFeedbackService; + private final ModelingExerciseFeedbackService modelingExerciseFeedbackService; + public ParticipationResource(ParticipationService participationService, ProgrammingExerciseParticipationService programmingExerciseParticipationService, CourseRepository courseRepository, QuizExerciseRepository quizExerciseRepository, ExerciseRepository exerciseRepository, ProgrammingExerciseRepository programmingExerciseRepository, AuthorizationCheckService authCheckService, @@ -176,7 +180,8 @@ public ParticipationResource(ParticipationService participationService, Programm ProgrammingExerciseStudentParticipationRepository programmingExerciseStudentParticipationRepository, SubmissionRepository submissionRepository, ResultRepository resultRepository, ExerciseDateService exerciseDateService, InstanceMessageSendService instanceMessageSendService, QuizBatchService quizBatchService, SubmittedAnswerRepository submittedAnswerRepository, QuizSubmissionService quizSubmissionService, GradingScaleService gradingScaleService, - ProgrammingExerciseCodeReviewFeedbackService programmingExerciseCodeReviewFeedbackService, TextExerciseFeedbackService textExerciseFeedbackService) { + ProgrammingExerciseCodeReviewFeedbackService programmingExerciseCodeReviewFeedbackService, TextExerciseFeedbackService textExerciseFeedbackService, + ModelingExerciseFeedbackService modelingExerciseFeedbackService) { this.participationService = participationService; this.programmingExerciseParticipationService = programmingExerciseParticipationService; this.quizExerciseRepository = quizExerciseRepository; @@ -203,6 +208,7 @@ public ParticipationResource(ParticipationService participationService, Programm this.gradingScaleService = gradingScaleService; this.programmingExerciseCodeReviewFeedbackService = programmingExerciseCodeReviewFeedbackService; this.textExerciseFeedbackService = textExerciseFeedbackService; + this.modelingExerciseFeedbackService = modelingExerciseFeedbackService; } /** @@ -363,7 +369,7 @@ public ResponseEntity requestFeedback(@PathVariable Long e Exercise exercise = exerciseRepository.findByIdElseThrow(exerciseId); - if (!(exercise instanceof TextExercise) && !(exercise instanceof ProgrammingExercise)) { + if (exercise instanceof QuizExercise || exercise instanceof FileUploadExercise) { throw new BadRequestAlertException("Unsupported exercise type", "participation", "unsupported type"); } @@ -393,7 +399,7 @@ private ResponseEntity handleExerciseFeedbackRequest(Exerc participation = studentParticipationRepository.findByIdWithResultsElseThrow(participation.getId()); // Check submission requirements - if (exercise instanceof TextExercise) { + if (exercise instanceof TextExercise || exercise instanceof ModelingExercise) { if (submissionRepository.findAllByParticipationId(participation.getId()).isEmpty()) { throw new BadRequestAlertException("You need to submit at least once", "participation", "preconditions not met"); } @@ -416,6 +422,9 @@ else if (exercise instanceof ProgrammingExercise) { if (exercise instanceof TextExercise) { updatedParticipation = textExerciseFeedbackService.handleNonGradedFeedbackRequest(exercise.getId(), participation, (TextExercise) exercise); } + else if (exercise instanceof ModelingExercise) { + updatedParticipation = modelingExerciseFeedbackService.handleNonGradedFeedbackRequest(participation, (ModelingExercise) exercise); + } else { updatedParticipation = programmingExerciseCodeReviewFeedbackService.handleNonGradedFeedbackRequest(exercise.getId(), (ProgrammingExerciseStudentParticipation) participation, (ProgrammingExercise) exercise); diff --git a/src/main/java/de/tum/cit/aet/artemis/modeling/service/ModelingExerciseFeedbackService.java b/src/main/java/de/tum/cit/aet/artemis/modeling/service/ModelingExerciseFeedbackService.java new file mode 100644 index 000000000000..e6e229e79f6a --- /dev/null +++ b/src/main/java/de/tum/cit/aet/artemis/modeling/service/ModelingExerciseFeedbackService.java @@ -0,0 +1,196 @@ +package de.tum.cit.aet.artemis.modeling.service; + +import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE; + +import java.time.ZonedDateTime; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import de.tum.cit.aet.artemis.assessment.domain.AssessmentType; +import de.tum.cit.aet.artemis.assessment.domain.Feedback; +import de.tum.cit.aet.artemis.assessment.domain.FeedbackType; +import de.tum.cit.aet.artemis.assessment.domain.Result; +import de.tum.cit.aet.artemis.assessment.repository.ResultRepository; +import de.tum.cit.aet.artemis.assessment.service.ResultService; +import de.tum.cit.aet.artemis.assessment.web.ResultWebsocketService; +import de.tum.cit.aet.artemis.athena.dto.ModelingFeedbackDTO; +import de.tum.cit.aet.artemis.athena.service.AthenaFeedbackSuggestionsService; +import de.tum.cit.aet.artemis.core.exception.BadRequestAlertException; +import de.tum.cit.aet.artemis.core.exception.InternalServerErrorException; +import de.tum.cit.aet.artemis.core.exception.NetworkingException; +import de.tum.cit.aet.artemis.exercise.domain.Submission; +import de.tum.cit.aet.artemis.exercise.domain.participation.StudentParticipation; +import de.tum.cit.aet.artemis.exercise.service.ParticipationService; +import de.tum.cit.aet.artemis.exercise.service.SubmissionService; +import de.tum.cit.aet.artemis.modeling.domain.ModelingExercise; +import de.tum.cit.aet.artemis.modeling.domain.ModelingSubmission; + +@Profile(PROFILE_CORE) +@Service +public class ModelingExerciseFeedbackService { + + private static final Logger log = LoggerFactory.getLogger(ModelingExerciseFeedbackService.class); + + private final Optional athenaFeedbackSuggestionsService; + + private final ResultWebsocketService resultWebsocketService; + + private final SubmissionService submissionService; + + private final ParticipationService participationService; + + private final ResultService resultService; + + private final ResultRepository resultRepository; + + public ModelingExerciseFeedbackService(Optional athenaFeedbackSuggestionsService, SubmissionService submissionService, + ResultService resultService, ResultRepository resultRepository, ResultWebsocketService resultWebsocketService, ParticipationService participationService) { + this.athenaFeedbackSuggestionsService = athenaFeedbackSuggestionsService; + this.submissionService = submissionService; + this.resultService = resultService; + this.resultRepository = resultRepository; + this.resultWebsocketService = resultWebsocketService; + this.participationService = participationService; + } + + private void checkRateLimitOrThrow(StudentParticipation participation) { + + List athenaResults = participation.getResults().stream().filter(result -> result.getAssessmentType() == AssessmentType.AUTOMATIC_ATHENA).toList(); + + if (athenaResults.size() >= 10) { + throw new BadRequestAlertException("Maximum number of AI feedback requests reached.", "participation", "preconditions not met"); + } + } + + /** + * Handles the request for generating feedback for a modeling exercise. + * Unlike programming exercises a tutor is not notified if Athena is not available. + * + * @param participation the student participation associated with the exercise. + * @param modelingExercise the modeling exercise object. + * @return StudentParticipation updated modeling exercise for an AI assessment + */ + public StudentParticipation handleNonGradedFeedbackRequest(StudentParticipation participation, ModelingExercise modelingExercise) { + if (this.athenaFeedbackSuggestionsService.isPresent()) { + this.checkRateLimitOrThrow(participation); + CompletableFuture.runAsync(() -> this.generateAutomaticNonGradedFeedback(participation, modelingExercise)); + } + return participation; + } + + /** + * Generates automatic non-graded feedback for a modeling exercise submission. + * This method leverages the Athena service to generate feedback based on the latest submission. + * + * @param participation the student participation associated with the exercise. + * @param modelingExercise the modeling exercise object. + */ + public void generateAutomaticNonGradedFeedback(StudentParticipation participation, ModelingExercise modelingExercise) { + log.debug("Using athena to generate (modeling exercise) feedback request: {}", modelingExercise.getId()); + + Optional submissionOptional = participationService.findExerciseParticipationWithLatestSubmissionAndResultElseThrow(participation.getId()) + .findLatestSubmission(); + + if (submissionOptional.isEmpty()) { + throw new BadRequestAlertException("No legal submissions found", "submission", "noSubmission"); + } + + Submission submission = submissionOptional.get(); + + Result automaticResult = createInitialResult(participation, submission); + + try { + this.resultWebsocketService.broadcastNewResult(participation, automaticResult); + + log.debug("Submission id: {}", submission.getId()); + + List feedbacks = getAthenaFeedback(modelingExercise, (ModelingSubmission) submission); + + double totalFeedbackScore = calculateTotalFeedbackScore(feedbacks, modelingExercise); + + automaticResult.setCompletionDate(ZonedDateTime.now()); + automaticResult.setScore(Math.max(0, Math.min(totalFeedbackScore, 100))); + automaticResult.setSuccessful(true); + + automaticResult = this.resultRepository.save(automaticResult); + resultService.storeFeedbackInResult(automaticResult, feedbacks, true); + submissionService.saveNewResult(submission, automaticResult); + this.resultWebsocketService.broadcastNewResult(participation, automaticResult); + } + catch (Exception e) { + log.error("Could not generate feedback for exercise ID: {} and participation ID: {}", modelingExercise.getId(), participation.getId(), e); + throw new InternalServerErrorException("Something went wrong... AI Feedback could not be generated"); + } + } + + /** + * Creates an initial Result object for the automatic feedback. + * + * @param participation the student participation + * @param submission the submission to which the result is associated + * @return the initial Result object + */ + private Result createInitialResult(StudentParticipation participation, Submission submission) { + Result result = new Result(); + result.setAssessmentType(AssessmentType.AUTOMATIC_ATHENA); + result.setRated(true); + result.setScore(0.0); + result.setSuccessful(null); + result.setSubmission(submission); + result.setParticipation(participation); + return result; + } + + /** + * Retrieves feedback from the Athena service. + * + * @param modelingExercise the modeling exercise + * @param submission the modeling submission + * @return a list of Feedback objects + * @throws NetworkingException if there's a problem communicating with Athena + */ + private List getAthenaFeedback(ModelingExercise modelingExercise, ModelingSubmission submission) throws NetworkingException { + return this.athenaFeedbackSuggestionsService.orElseThrow().getModelingFeedbackSuggestions(modelingExercise, submission, false).stream() + .filter(feedbackItem -> feedbackItem.description() != null).map(this::convertToFeedback).toList(); + } + + /** + * Converts an Athena feedback suggestion to a Feedback object. + * + * @param feedbackItem the Athena feedback suggestion + * @return the Feedback object + */ + private Feedback convertToFeedback(ModelingFeedbackDTO feedbackItem) { + Feedback feedback = new Feedback(); + feedback.setText(feedbackItem.title()); + feedback.setDetailText(feedbackItem.description()); + feedback.setHasLongFeedbackText(false); + feedback.setType(FeedbackType.AUTOMATIC); + feedback.setCredits(feedbackItem.credits()); + return feedback; + } + + /** + * Calculates the total feedback score based on the list of feedbacks and the exercise's max points. + * + * @param feedbacks the list of feedbacks + * @param modelingExercise the modeling exercise + * @return the total feedback score + */ + private double calculateTotalFeedbackScore(List feedbacks, ModelingExercise modelingExercise) { + double totalCredits = feedbacks.stream().mapToDouble(Feedback::getCredits).sum(); + Double maxPoints = modelingExercise.getMaxPoints(); + + if (maxPoints == null || maxPoints == 0) { + throw new IllegalArgumentException("Maximum points must be greater than zero."); + } + + return (totalCredits / maxPoints) * 100; + } +} diff --git a/src/main/java/de/tum/cit/aet/artemis/modeling/service/ModelingSubmissionService.java b/src/main/java/de/tum/cit/aet/artemis/modeling/service/ModelingSubmissionService.java index cfba2463185b..320d041325e9 100644 --- a/src/main/java/de/tum/cit/aet/artemis/modeling/service/ModelingSubmissionService.java +++ b/src/main/java/de/tum/cit/aet/artemis/modeling/service/ModelingSubmissionService.java @@ -124,14 +124,19 @@ public ModelingSubmission handleModelingSubmission(ModelingSubmission modelingSu throw new AccessForbiddenException(); } - // remove result from submission (in the unlikely case it is passed here), so that students cannot inject a result - modelingSubmission.setResults(new ArrayList<>()); - // update submission properties // NOTE: from now on we always set submitted to true to prevent problems here! Except for late submissions of course exercises to prevent issues in auto-save if (exercise.isExamExercise() || exerciseDateService.isBeforeDueDate(participation)) { modelingSubmission.setSubmitted(true); } + + // if athena results are present, then create a new submission on submit + if (modelingSubmission.getParticipation() != null && modelingSubmission.getParticipation().getResults() != null + && !modelingSubmission.getParticipation().getResults().isEmpty()) { + log.debug("Creating a new submission due to Athena results for user: {}", user.getLogin()); + modelingSubmission.setId(null); + } + modelingSubmission = save(modelingSubmission, exercise, user, participation); return modelingSubmission; } diff --git a/src/main/java/de/tum/cit/aet/artemis/modeling/web/ModelingSubmissionResource.java b/src/main/java/de/tum/cit/aet/artemis/modeling/web/ModelingSubmissionResource.java index 95a41a0f695a..e48f94b8e955 100644 --- a/src/main/java/de/tum/cit/aet/artemis/modeling/web/ModelingSubmissionResource.java +++ b/src/main/java/de/tum/cit/aet/artemis/modeling/web/ModelingSubmissionResource.java @@ -3,6 +3,7 @@ import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; @@ -26,6 +27,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import de.tum.cit.aet.artemis.assessment.domain.AssessmentType; import de.tum.cit.aet.artemis.assessment.domain.GradingCriterion; import de.tum.cit.aet.artemis.assessment.domain.Result; import de.tum.cit.aet.artemis.assessment.repository.GradingCriterionRepository; @@ -44,6 +46,7 @@ import de.tum.cit.aet.artemis.exercise.repository.ExerciseRepository; import de.tum.cit.aet.artemis.exercise.repository.StudentParticipationRepository; import de.tum.cit.aet.artemis.exercise.repository.SubmissionRepository; +import de.tum.cit.aet.artemis.exercise.service.ExerciseDateService; import de.tum.cit.aet.artemis.exercise.web.AbstractSubmissionResource; import de.tum.cit.aet.artemis.modeling.domain.ModelingExercise; import de.tum.cit.aet.artemis.modeling.domain.ModelingSubmission; @@ -332,7 +335,9 @@ public ResponseEntity getLatestSubmissionForModelingEditor(@ // make sure only the latest submission and latest result is sent to the client participation.setSubmissions(null); - participation.setResults(null); + if (ExerciseDateService.isAfterAssessmentDueDate(modelingExercise)) { + participation.setResults(null); + } // do not send the result to the client if the assessment is not finished if (modelingSubmission.getLatestResult() != null @@ -340,6 +345,17 @@ public ResponseEntity getLatestSubmissionForModelingEditor(@ modelingSubmission.setResults(new ArrayList<>()); } + if (!ExerciseDateService.isAfterAssessmentDueDate(modelingExercise)) { + // We want to have the preliminary feedback before the assessment due date too + Set participationResults = participation.getResults(); + if (participationResults != null) { + List athenaResults = participationResults.stream().filter(result -> result.getAssessmentType() == AssessmentType.AUTOMATIC_ATHENA).toList(); + modelingSubmission.setResults(athenaResults); + Set athenaResultsSet = new HashSet<>(athenaResults); + participation.setResults(athenaResultsSet); + } + } + if (modelingSubmission.getLatestResult() != null && !authCheckService.isAtLeastTeachingAssistantForExercise(modelingExercise)) { modelingSubmission.getLatestResult().filterSensitiveInformation(); } diff --git a/src/main/java/de/tum/cit/aet/artemis/text/service/TextExerciseFeedbackService.java b/src/main/java/de/tum/cit/aet/artemis/text/service/TextExerciseFeedbackService.java index 69f345c535cd..14a2558f6c9d 100644 --- a/src/main/java/de/tum/cit/aet/artemis/text/service/TextExerciseFeedbackService.java +++ b/src/main/java/de/tum/cit/aet/artemis/text/service/TextExerciseFeedbackService.java @@ -35,8 +35,6 @@ public class TextExerciseFeedbackService { private static final Logger log = LoggerFactory.getLogger(TextExerciseFeedbackService.class); - public static final String NON_GRADED_FEEDBACK_SUGGESTION = "NonGradedFeedbackSuggestion:"; - private final Optional athenaFeedbackSuggestionsService; private final ResultWebsocketService resultWebsocketService; @@ -98,7 +96,7 @@ public void generateAutomaticNonGradedFeedback(StudentParticipation participatio log.debug("Using athena to generate (text exercise) feedback request: {}", textExercise.getId()); // athena takes over the control here - var submissionOptional = participationService.findTextExerciseParticipationWithLatestSubmissionAndResultElseThrow(participation.getId()).findLatestSubmission(); + var submissionOptional = participationService.findExerciseParticipationWithLatestSubmissionAndResultElseThrow(participation.getId()).findLatestSubmission(); if (submissionOptional.isEmpty()) { throw new BadRequestAlertException("No legal submissions found", "submission", "noSubmission"); diff --git a/src/main/webapp/app/exercises/modeling/assess/modeling-assessment-editor/modeling-assessment-editor.component.ts b/src/main/webapp/app/exercises/modeling/assess/modeling-assessment-editor/modeling-assessment-editor.component.ts index e6610b4edaf0..fe7a6017459f 100644 --- a/src/main/webapp/app/exercises/modeling/assess/modeling-assessment-editor/modeling-assessment-editor.component.ts +++ b/src/main/webapp/app/exercises/modeling/assess/modeling-assessment-editor/modeling-assessment-editor.component.ts @@ -237,8 +237,8 @@ export class ModelingAssessmentEditorComponent implements OnInit { if (this.result?.feedbacks) { this.result = this.modelingAssessmentService.convertResult(this.result); - } else { - this.result!.feedbacks = []; + } else if (this.result) { + this.result.feedbacks = []; } // Only load suggestions for new assessments, they don't make sense later. diff --git a/src/main/webapp/app/exercises/shared/feedback-suggestion/exercise-feedback-suggestion-options.component.html b/src/main/webapp/app/exercises/shared/feedback-suggestion/exercise-feedback-suggestion-options.component.html index 55d7f5ce03a4..95d72394f220 100644 --- a/src/main/webapp/app/exercises/shared/feedback-suggestion/exercise-feedback-suggestion-options.component.html +++ b/src/main/webapp/app/exercises/shared/feedback-suggestion/exercise-feedback-suggestion-options.component.html @@ -18,7 +18,7 @@ >
- @if (this.exercise.type === ExerciseType.TEXT) { + @if (this.exercise.type === ExerciseType.TEXT || this.exercise.type === ExerciseType.MODELING) {
{ - if (result.participation && result.participation.exercise && result.participation.exercise.type === ExerciseType.TEXT) { + const exerciseType = result.participation?.exercise?.type; + if (exerciseType === ExerciseType.TEXT || exerciseType === ExerciseType.MODELING) { return result.assessmentType === AssessmentType.AUTOMATIC_ATHENA; } else return ( diff --git a/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html b/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html index 148fdfdef932..53a99d1f440a 100644 --- a/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html +++ b/src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html @@ -251,7 +251,7 @@ [hideLabelMobile]="false" [routerLink]="['/courses', courseId, 'exercises', exercise.type + '-exercises', exercise.id, 'participate', gradedParticipation!.id]" > - @if (exercise.allowFeedbackRequests && athenaEnabled && exercise.type === ExerciseType.TEXT) { + @if (exercise.allowFeedbackRequests && athenaEnabled && (exercise.type === ExerciseType.TEXT || exercise.type === ExerciseType.MODELING)) {