diff --git a/admin/api/exercice.go b/admin/api/exercice.go index cfdb450d..1df894bd 100644 --- a/admin/api/exercice.go +++ b/admin/api/exercice.go @@ -62,6 +62,8 @@ func declareExercicesRoutes(router *gin.RouterGroup) { apiFlagsRoutes.POST("/try", tryExerciceFlag) apiFlagsRoutes.DELETE("/", deleteExerciceFlag) apiFlagsRoutes.GET("/dependancies", showExerciceFlagDeps) + apiFlagsRoutes.GET("/statistics", showExerciceFlagStats) + apiFlagsRoutes.DELETE("/tries", deleteExerciceFlagTries) apiFlagsRoutes.GET("/choices/", listFlagChoices) apiFlagsChoicesRoutes := apiExercicesRoutes.Group("/choices/:cid") apiFlagsChoicesRoutes.Use(FlagChoiceHandler) @@ -77,6 +79,8 @@ func declareExercicesRoutes(router *gin.RouterGroup) { apiQuizRoutes.PUT("", updateExerciceQuiz) apiQuizRoutes.DELETE("", deleteExerciceQuiz) apiQuizRoutes.GET("/dependancies", showExerciceQuizDeps) + apiQuizRoutes.GET("/statistics", showExerciceQuizStats) + apiQuizRoutes.DELETE("/tries", deleteExerciceQuizTries) apiExercicesRoutes.GET("/tags", listExerciceTags) apiExercicesRoutes.POST("/tags", addExerciceTag) @@ -852,6 +856,60 @@ func showExerciceFlagDeps(c *gin.Context) { c.JSON(http.StatusOK, deps) } +func showExerciceFlagStats(c *gin.Context) { + exercice := c.MustGet("exercice").(*fic.Exercice) + flag := c.MustGet("flag-key").(*fic.FlagKey) + + history, err := exercice.GetHistory() + if err != nil { + log.Println("Unable to getExerciceHistory:", err.Error()) + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when retrieving exercice history"}) + return + } + + var completed int64 + + for _, hline := range history { + if hline["kind"].(string) == "flag_found" { + if *hline["secondary"].(*int) == flag.Id { + completed += 1 + } + } + } + + tries, err := flag.NbTries() + if err != nil { + log.Println("Unable to nbTries:", err.Error()) + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when retrieving flag tries"}) + return + } + + teams, err := flag.TeamsOnIt() + if err != nil { + log.Println("Unable to teamsOnIt:", err.Error()) + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when retrieving flag related teams"}) + return + } + + c.JSON(http.StatusOK, gin.H{ + "completed": completed, + "tries": tries, + "teams": teams, + }) +} + +func deleteExerciceFlagTries(c *gin.Context) { + flag := c.MustGet("flag-key").(*fic.FlagKey) + + err := flag.DeleteTries() + if err != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()}) + return + } + + c.AbortWithStatusJSON(http.StatusOK, true) +} + func tryExerciceFlag(c *gin.Context) { flag := c.MustGet("flag-key").(*fic.FlagKey) @@ -1022,6 +1080,60 @@ func showExerciceQuizDeps(c *gin.Context) { c.JSON(http.StatusOK, deps) } +func showExerciceQuizStats(c *gin.Context) { + exercice := c.MustGet("exercice").(*fic.Exercice) + quiz := c.MustGet("flag-quiz").(*fic.MCQ) + + history, err := exercice.GetHistory() + if err != nil { + log.Println("Unable to getExerciceHistory:", err.Error()) + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when retrieving exercice history"}) + return + } + + var completed int64 + + for _, hline := range history { + if hline["kind"].(string) == "mcq_found" { + if *hline["secondary"].(*int) == quiz.Id { + completed += 1 + } + } + } + + tries, err := quiz.NbTries() + if err != nil { + log.Println("Unable to nbTries:", err.Error()) + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when retrieving flag tries"}) + return + } + + teams, err := quiz.TeamsOnIt() + if err != nil { + log.Println("Unable to teamsOnIt:", err.Error()) + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when retrieving flag related teams"}) + return + } + + c.JSON(http.StatusOK, gin.H{ + "completed": completed, + "tries": tries, + "teams": teams, + }) +} + +func deleteExerciceQuizTries(c *gin.Context) { + quiz := c.MustGet("flag-quiz").(*fic.MCQ) + + err := quiz.DeleteTries() + if err != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()}) + return + } + + c.AbortWithStatusJSON(http.StatusOK, true) +} + func updateExerciceQuiz(c *gin.Context) { quiz := c.MustGet("flag-quiz").(*fic.MCQ) diff --git a/admin/static/js/app.js b/admin/static/js/app.js index 0753bbb0..24e7b36b 100644 --- a/admin/static/js/app.js +++ b/admin/static/js/app.js @@ -348,6 +348,9 @@ angular.module("FICApp") .factory("ExerciceFlagDeps", function ($resource) { return $resource("api/exercices/:exerciceId/flags/:flagId/dependancies", { exerciceId: '@idExercice', flagId: '@id' }) }) + .factory("ExerciceFlagStats", function ($resource) { + return $resource("api/exercices/:exerciceId/flags/:flagId/statistics", { exerciceId: '@idExercice', flagId: '@id' }) + }) .factory("ExerciceMCQFlag", function ($resource) { return $resource("api/exercices/:exerciceId/quiz/:mcqId", { exerciceId: '@idExercice', mcqId: '@id' }, { update: { method: 'PUT' } @@ -355,6 +358,9 @@ angular.module("FICApp") }) .factory("ExerciceMCQDeps", function ($resource) { return $resource("api/exercices/:exerciceId/quiz/:mcqId/dependancies", { exerciceId: '@idExercice', mcqId: '@id' }) + }) + .factory("ExerciceMCQStats", function ($resource) { + return $resource("api/exercices/:exerciceId/quiz/:mcqId/statistics", { exerciceId: '@idExercice', mcqId: '@id' }) }); angular.module("FICApp") @@ -611,9 +617,18 @@ angular.module("FICApp") response.enableExerciceDepend = response.unlockedChallengeDepth >= 0; response.disabledsubmitbutton = response.disablesubmitbutton && response.disablesubmitbutton.length > 0; + if (response.end) { + $scope.duration = (response.end - response.start)/60000; + } }) $scope.challenge = SettingsChallenge.get(); $scope.duration = 360; + $scope.durationChange = function(endChanged) { + if (endChanged) + $scope.duration = (new Date($scope.config.end).getTime() - new Date($scope.config.start).getTime())/60000; + else + $scope.config.end = new Date(new Date($scope.config.start).getTime() + $scope.duration * 60000); + } $scope.activateTime = ""; $scope.challenge.$promise.then(function (c) { if (c.duration) @@ -648,7 +663,7 @@ angular.module("FICApp") $scope.saveChallengeInfo = function () { this.challenge.duration = $scope.duration; this.challenge.$update(function (response) { - $scope.addToast('success', 'Infos du challenge mises à jour avec succès !'); + $scope.addToast('success', 'Infos du challenge mises à jour avec succès !'); }, function (response) { $scope.addToast('danger', 'An error occurs when saving challenge info:', response.data.errmsg); }); @@ -722,9 +737,9 @@ angular.module("FICApp") "teams": "En validant, vous supprimerez l'ensemble des équipes enregistreées.", "game": "En validant, vous supprimerez toutes les tentatives, les validations, ... faites par les équipes.", } - $scope.addToast('warning', txts[type], 'Êtes-vous sûr de vouloir continuer ?', + $scope.addToast('warning', txts[type], 'Êtes-vous sûr de vouloir continuer ?', function () { - if (confirm("Êtes-vous vraiment sûr ?\n" + txts[type])) { + if (confirm("Êtes-vous vraiment sûr ?\n" + txts[type])) { $http.post("api/reset", { "type": type }).then(function (time) { $scope.addToast('success', type + 'reseted'); $location.url("/"); @@ -736,7 +751,7 @@ angular.module("FICApp") }); }; $scope.switchToProd = function () { - $scope.addToast('warning', "Activer le mode challenge ?", "L'activation du mode challenge est temporaire (vous devriez plutôt relancer le daemon avec l'option `-4real`). Ce mode permet d'éviter les mauvaises manipulations et désactive le hook git de synchronisation automatique. Êtes-vous sûr de vouloir continuer ?", + $scope.addToast('warning', "Activer le mode challenge ?", "L'activation du mode challenge est temporaire (vous devriez plutôt relancer le daemon avec l'option `-4real`). Ce mode permet d'éviter les mauvaises manipulations et désactive le hook git de synchronisation automatique. Êtes-vous sûr de vouloir continuer ?", function () { $http.put("api/prod", true).then(function (time) { $rootScope.refreshSettings() @@ -759,6 +774,20 @@ angular.module("FICApp") }); }; }) + .component('teamLink', { + bindings: { + idTeam: '=', + }, + controller: function (Team) { + var ctrl = this; + ctrl.team = {}; + + ctrl.$onInit = function () { + ctrl.team = Team.get({teamId: ctrl.idTeam}); + }; + }, + template: `{{ $ctrl.team.name }} ` + }) .component('repositoryUptodate', { bindings: { repository: '<', @@ -820,10 +849,10 @@ angular.module("FICApp") $scope.deepSync = function (theme) { if (theme) { - question = 'Faire une synchronisation intégrale du thème ' + theme.name + ' ?' + question = 'Faire une synchronisation intégrale du thème ' + theme.name + ' ?' url = "api/sync/deep/" + theme.id } else { - question = 'Faire une synchronisation intégrale ?' + question = 'Faire une synchronisation intégrale ?' url = "api/sync/deep" } $scope.addToast('warning', question, '', @@ -839,7 +868,7 @@ angular.module("FICApp") }); }; $scope.speedyDeepSync = function () { - $scope.addToast('warning', 'Faire une synchronisation profonde rapide, sans s\'occuper des fichiers ?', '', + $scope.addToast('warning', 'Faire une synchronisation profonde rapide, sans s\'occuper des fichiers ?', '', function () { $scope.deepSyncInProgress = true; $http.post("api/sync/speed").then(function () { @@ -852,7 +881,7 @@ angular.module("FICApp") }); }; $scope.baseSync = function () { - $scope.addToast('warning', 'Tirer les mises à jour du dépôt ?', '', + $scope.addToast('warning', 'Tirer les mises à jour du dépôt ?', '', function () { $scope.deepSyncInProgress = true; $http.post("api/sync/base").then(function () { @@ -865,7 +894,7 @@ angular.module("FICApp") }); }; $scope.syncVideos = function () { - $scope.addToast('warning', 'Synchroniser les vidéos de résolution ?', 'ATTENTION il ne faut pas lancer cette synchronisation durant le challenge. Seulement une fois le challenge terminé, cela permet de rendre les vidéos accessibles dans l\'interface joueurs.', + $scope.addToast('warning', 'Synchroniser les vidéos de résolution ?', 'ATTENTION il ne faut pas lancer cette synchronisation durant le challenge. Seulement une fois le challenge terminé, cela permet de rendre les vidéos accessibles dans l\'interface joueurs.', function () { $scope.deepSyncInProgress = true; $http.post("api/sync/videos").then(function () { @@ -1110,7 +1139,7 @@ angular.module("FICApp") }, { type: "countdown", - params: { color: "success", end: null, lead: "Go, go, go !", title: "Le challenge forensic va bientôt commencer !" }, + params: { color: "success", end: null, lead: "Go, go, go !", title: "Le challenge forensic va bientôt commencer !" }, }, ]; $scope.display.side = [ @@ -1229,8 +1258,8 @@ angular.module("FICApp") show: true, shadow: "#E8CF5C", end: new Date($rootScope.getSrvTime().getTime() + 1802000).toISOString(), - before: "Heure joyeuse : chaque résolution compte double !", - after: "Heure joyeuse terminée !", + before: "Heure joyeuse : chaque résolution compte double !", + after: "Heure joyeuse terminée !", } } else if (scene == "freehintquarter") { @@ -1238,8 +1267,8 @@ angular.module("FICApp") show: true, shadow: "#3DD28F", end: new Date($rootScope.getSrvTime().getTime() + 902000).toISOString(), - before: "Quart d'heure facile : indices dévoilés !", - after: "Quart d'heure facile terminée !", + before: "Quart d'heure facile : indices dévoilés !", + after: "Quart d'heure facile terminée !", } } }; @@ -1368,7 +1397,7 @@ angular.module("FICApp") }); }; $scope.clearFilesDir = function () { - $scope.addToast('warning', 'Êtes-vous sûr de vouloir continuer ?', "Ceci va supprimer tout le contenu du dossier FILES. Il s'agit des fichiers ci-dessous, il faudra refaire une synchronisation ensuite.", + $scope.addToast('warning', 'Êtes-vous sûr de vouloir continuer ?', "Ceci va supprimer tout le contenu du dossier FILES. Il s'agit des fichiers ci-dessous, il faudra refaire une synchronisation ensuite.", function () { $scope.clearFilesWIP = true; $http({ @@ -2276,7 +2305,7 @@ angular.module("FICApp") method: "POST" }).then(function (response) { flag.test_str = ""; - $scope.addToast('success', "Flag Ok !"); + $scope.addToast('success', "Flag Ok !"); }, function (response) { flag.test_str = ""; $scope.addToast('danger', 'An error occurs: ', response.data.errmsg); @@ -2345,6 +2374,18 @@ angular.module("FICApp") } }) + .controller("ExerciceFlagStatsController", function ($scope, $routeParams, ExerciceFlagStats, $http) { + $scope.init = function (flag) { + $scope.flag_id = flag.id; + $scope.stats = ExerciceFlagStats.get({ exerciceId: $routeParams.exerciceId, flagId: flag.id }); + } + $scope.deleteTries = function () { + $http.delete(`/api/exercices/${$routeParams.exerciceId}/flags/${$scope.flag_id}/tries`).then(function () { + $scope.stats = ExerciceFlagStats.get({ exerciceId: $routeParams.exerciceId, flagId: $scope.flag_id }); + }); + } + }) + .controller("ExerciceMCQFlagsController", function ($scope, ExerciceMCQFlag, $routeParams, $rootScope) { $scope.quiz = ExerciceMCQFlag.query({ exerciceId: $routeParams.exerciceId }); @@ -2382,6 +2423,18 @@ angular.module("FICApp") } }) + .controller("ExerciceMCQStatsController", function ($scope, $routeParams, ExerciceMCQStats, $http) { + $scope.init = function (mcq) { + $scope.mcq_id = mcq.id; + $scope.stats = ExerciceMCQStats.get({ exerciceId: $routeParams.exerciceId, mcqId: mcq.id }); + } + $scope.deleteTries = function () { + $http.delete(`/api/exercices/${$routeParams.exerciceId}/quiz/${$scope.mcq_id}/tries`).then(function () { + $scope.stats = ExerciceMCQStats.get({ exerciceId: $routeParams.exerciceId, mcqId: $scope.mcq_id }); + }); + } + }) + .controller("TeamsListController", function ($scope, $rootScope, Team, $location, $http) { $scope.teams = Team.query(); $scope.fields = ["id", "name"]; diff --git a/admin/static/views/exercice-flags.html b/admin/static/views/exercice-flags.html index 3caf3add..f765d9a9 100644 --- a/admin/static/views/exercice-flags.html +++ b/admin/static/views/exercice-flags.html @@ -73,12 +73,28 @@
- Dépendances : + Dépendances : sans
+
+
+ Statistiques + +
diff --git a/admin/static/views/file-list.html b/admin/static/views/file-list.html index cd0d36a7..83a3242c 100644 --- a/admin/static/views/file-list.html +++ b/admin/static/views/file-list.html @@ -30,13 +30,13 @@
- + {{ file[field] }} - - {{ file.checksum | bto16 }} -
{{ file.checksum_shown | bto16 }}
+ +
{{ file.checksum | bto16 }}
+
{{ file.checksum_shown | bto16 }}
diff --git a/admin/static/views/settings.html b/admin/static/views/settings.html index 58035170..61843360 100644 --- a/admin/static/views/settings.html +++ b/admin/static/views/settings.html @@ -35,7 +35,7 @@
- +
@@ -46,14 +46,14 @@
- +
- +
min
diff --git a/admin/sync/exercice_keys.go b/admin/sync/exercice_keys.go index 8404df86..d4a88f3c 100644 --- a/admin/sync/exercice_keys.go +++ b/admin/sync/exercice_keys.go @@ -279,6 +279,7 @@ func buildKeyFlag(exercice *fic.Exercice, flag ExerciceFlag, flagline int, defau } type importFlag struct { + origin ExerciceFlag Line int Flag fic.Flag JustifyOf *fic.MCQ_entry @@ -392,8 +393,9 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl errs = multierr.Append(errs, berrs) if addedFlag != nil { ret = append(ret, importFlag{ - Line: nline + 1, - Flag: addedFlag, + origin: flag, + Line: nline + 1, + Flag: addedFlag, }) } } else if flag.Type == "key" || strings.HasPrefix(flag.Type, "number") || flag.Type == "text" || flag.Type == "ucq" || flag.Type == "radio" || flag.Type == "vector" { @@ -401,6 +403,7 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl errs = multierr.Append(errs, berrs) if addedFlag != nil { ret = append(ret, importFlag{ + origin: flag, Line: nline + 1, Flag: *addedFlag, Choices: choices, @@ -462,6 +465,7 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl errs = multierr.Append(errs, berrs) if addedFlag != nil { ret = append(ret, importFlag{ + origin: flag, Line: nline + 1, Flag: *addedFlag, JustifyOf: entry, @@ -479,8 +483,9 @@ func buildExerciceFlag(i Importer, exercice *fic.Exercice, flag ExerciceFlag, nl } ret = append([]importFlag{importFlag{ - Line: nline + 1, - Flag: &addedFlag, + origin: flag, + Line: nline + 1, + Flag: &addedFlag, }}, ret...) } return @@ -570,6 +575,10 @@ func CheckExerciceFlags(i Importer, exercice *fic.Exercice, files []string, exce if int64(fk.ChoicesCost) >= exercice.Gain { errs = multierr.Append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("flag's choice_cost is higher than exercice gain"))) } + + if raw, ok := flag.origin.Raw.(string); ok && raw == fk.Placeholder { + errs = multierr.Append(errs, NewFlagError(exercice, nil, flag.Line, fmt.Errorf("flag's placeholder and raw are identical"))) + } } // Check dependency loop diff --git a/configs/gen_metadata.sh b/configs/gen_metadata.sh index ccb2f4fe..f51984eb 100755 --- a/configs/gen_metadata.sh +++ b/configs/gen_metadata.sh @@ -20,6 +20,8 @@ escape_newline () { sed 's/$/\\n/g' | tr -d '\n' } +which mkisofs > /dev/null 2> /dev/null || { echo "Please install genisoimage (Debian/Ubuntu) or cdrkit (Alpine)" >&2; exit 1; } + if [ $# -gt 0 ] then which jq > /dev/null 2> /dev/null || { echo "Please install jq" >&2; exit 1; } diff --git a/configs/update_imgs.sh b/configs/update_imgs.sh index 13866c22..fa507cee 100644 --- a/configs/update_imgs.sh +++ b/configs/update_imgs.sh @@ -21,6 +21,8 @@ OLD_KEY=$(cat /run/config/dm-crypt/key) [ "${NEW_KEY}" != "${OLD_KEY}" ] && { read -p "DM-CRYPT key changed in metadata, are you sure you want to erase it? (y/N) " V [ "$V" != "y" ] && [ "$V" != "Y" ] && while true; do + mv /boot/imgs/fickit-metadata.iso /boot/imgs/fickit-metadata.iso.skipped + cp /boot/imgs/fickit-metadata.iso.bak /boot/imgs/fickit-metadata.iso echo echo "Metadata drive not erased" echo diff --git a/fickit-backend.yml b/fickit-backend.yml index be0ecef7..def65aaa 100644 --- a/fickit-backend.yml +++ b/fickit-backend.yml @@ -153,6 +153,15 @@ onboot: mkdir: - /var/lib/fic/secrets + - name: create-ssh-keys + image: nemunaire/rsync:a3d76b2dd0a9ad73be44dc77ad765b20d96a3285 + command: ["/bin/sh", "-c", "touch /etc/ssh/sshd_config && ssh-keygen -A"] + binds: + - /var/lib/fic/ssh:/etc/ssh + runtime: + mkdir: + - /var/lib/fic/ssh + services: # - name: getty # image: linuxkit/getty:bae9e3d4861173bacf78f14a4fe44997a430d13b @@ -228,7 +237,7 @@ services: - /var/lib/fic/generator:/srv/GENERATOR:ro - /var/lib/fic/pki:/srv/PKI - /var/lib/fic/settings:/srv/SETTINGS - - /var/lib/fic/submissions:/srv/submissions:ro + - /var/lib/fic/submissions:/srv/submissions - /var/lib/fic/sync:/srv/SYNC - /var/lib/fic/teams:/srv/TEAMS net: /run/netns/fic-admin @@ -269,7 +278,10 @@ services: binds: - /etc/hosts:/etc/hosts:ro - /var/lib/fic/generator:/srv/GENERATOR:ro + # Uncomment this to disallow registrations - /var/lib/fic/teams:/srv/TEAMS:ro + # Uncomment this to allow registrations + #- /var/lib/fic/teams:/srv/TEAMS - /var/lib/fic/secrets/mysql_password:/run/secrets/mysql_password:ro - /var/lib/fic/settingsdist:/srv/SETTINGSDIST:ro - /var/lib/fic/submissions:/srv/submissions @@ -361,7 +373,6 @@ services: - /var/lib/fic/files - /var/lib/fic/pki/shared - /var/lib/fic/settingsdist - - /var/lib/fic/ssh - /var/lib/fic/submissions - /var/lib/fic/teams - /var/log/frontend diff --git a/fickit-frontend.yml b/fickit-frontend.yml index d2c558a2..c50b9141 100644 --- a/fickit-frontend.yml +++ b/fickit-frontend.yml @@ -136,6 +136,15 @@ onboot: - /etc/iptables/rules.v6:/etc/iptables/rules.v6:ro net: /run/netns/sshd + - name: create-ssh-keys + image: nemunaire/rsync:a3d76b2dd0a9ad73be44dc77ad765b20d96a3285 + command: ["/bin/sh", "-c", "touch /etc/ssh/sshd_config && ssh-keygen -A"] + binds: + - /var/lib/fic/ssh:/etc/ssh + runtime: + mkdir: + - /var/lib/fic/ssh + services: # - name: getty # image: linuxkit/getty:bae9e3d4861173bacf78f14a4fe44997a430d13b @@ -257,7 +266,6 @@ services: - /var/lib/fic/files - /var/lib/fic/pki - /var/lib/fic/settingsdist - - /var/lib/fic/ssh - /var/lib/fic/submissions - /var/lib/fic/teams diff --git a/fickit-prepare.yml b/fickit-prepare.yml index 64f7b3ba..b8472acb 100644 --- a/fickit-prepare.yml +++ b/fickit-prepare.yml @@ -7,9 +7,9 @@ kernel: init: - nemunaire/mdadm:04814350d71ba9417e1f861be1685de26adf7a67 - nemunaire/syslinux:086f221f281d577d300949aa1094fb20c5cd90dc - - linuxkit/format:3c858f0cf42a2b14441bfb5c266b78f14d2b75a4 - - linuxkit/dm-crypt:19fa6affe9da03afc91694e36d72a4924c65a0e0 - - linuxkit/metadata:f35b5aafc7d19bb6a44a900840727902dad78e44 + - linuxkit/format:8f487d728959192289e0783784fc2b185eadbc82 + - linuxkit/dm-crypt:ad2a05dcffa28ef809a61aa27ba230c82f02f603 + - linuxkit/metadata:83cda7b43112b201613084ea8b7fab585b6e5549 - alpine:latest files: diff --git a/frontend/fic/package-lock.json b/frontend/fic/package-lock.json index b964016c..6c93a17a 100644 --- a/frontend/fic/package-lock.json +++ b/frontend/fic/package-lock.json @@ -533,9 +533,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz", - "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==", + "version": "9.19.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz", + "integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==", "dev": true, "license": "MIT", "engines": { @@ -681,9 +681,9 @@ } }, "node_modules/@parcel/watcher": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.0.tgz", - "integrity": "sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -702,25 +702,25 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.0", - "@parcel/watcher-darwin-arm64": "2.5.0", - "@parcel/watcher-darwin-x64": "2.5.0", - "@parcel/watcher-freebsd-x64": "2.5.0", - "@parcel/watcher-linux-arm-glibc": "2.5.0", - "@parcel/watcher-linux-arm-musl": "2.5.0", - "@parcel/watcher-linux-arm64-glibc": "2.5.0", - "@parcel/watcher-linux-arm64-musl": "2.5.0", - "@parcel/watcher-linux-x64-glibc": "2.5.0", - "@parcel/watcher-linux-x64-musl": "2.5.0", - "@parcel/watcher-win32-arm64": "2.5.0", - "@parcel/watcher-win32-ia32": "2.5.0", - "@parcel/watcher-win32-x64": "2.5.0" + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" } }, "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.0.tgz", - "integrity": "sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", "cpu": [ "arm64" ], @@ -739,9 +739,9 @@ } }, "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.0.tgz", - "integrity": "sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", "cpu": [ "arm64" ], @@ -760,9 +760,9 @@ } }, "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.0.tgz", - "integrity": "sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", "cpu": [ "x64" ], @@ -781,9 +781,9 @@ } }, "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.0.tgz", - "integrity": "sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", "cpu": [ "x64" ], @@ -802,9 +802,9 @@ } }, "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.0.tgz", - "integrity": "sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", "cpu": [ "arm" ], @@ -823,9 +823,9 @@ } }, "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.0.tgz", - "integrity": "sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", "cpu": [ "arm" ], @@ -844,9 +844,9 @@ } }, "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.0.tgz", - "integrity": "sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", "cpu": [ "arm64" ], @@ -865,9 +865,9 @@ } }, "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.0.tgz", - "integrity": "sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", "cpu": [ "arm64" ], @@ -886,9 +886,9 @@ } }, "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.0.tgz", - "integrity": "sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", "cpu": [ "x64" ], @@ -907,9 +907,9 @@ } }, "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.0.tgz", - "integrity": "sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", "cpu": [ "x64" ], @@ -928,9 +928,9 @@ } }, "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.0.tgz", - "integrity": "sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", "cpu": [ "arm64" ], @@ -949,9 +949,9 @@ } }, "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.0.tgz", - "integrity": "sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", "cpu": [ "ia32" ], @@ -970,9 +970,9 @@ } }, "node_modules/@parcel/watcher-win32-x64": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.0.tgz", - "integrity": "sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", "cpu": [ "x64" ], @@ -1008,9 +1008,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz", - "integrity": "sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.32.0.tgz", + "integrity": "sha512-G2fUQQANtBPsNwiVFg4zKiPQyjVKZCUdQUol53R8E71J7AsheRMV/Yv/nB8giOcOVqP7//eB5xPqieBYZe9bGg==", "cpu": [ "arm" ], @@ -1022,9 +1022,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.1.tgz", - "integrity": "sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.32.0.tgz", + "integrity": "sha512-qhFwQ+ljoymC+j5lXRv8DlaJYY/+8vyvYmVx074zrLsu5ZGWYsJNLjPPVJJjhZQpyAKUGPydOq9hRLLNvh1s3A==", "cpu": [ "arm64" ], @@ -1036,9 +1036,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.1.tgz", - "integrity": "sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.32.0.tgz", + "integrity": "sha512-44n/X3lAlWsEY6vF8CzgCx+LQaoqWGN7TzUfbJDiTIOjJm4+L2Yq+r5a8ytQRGyPqgJDs3Rgyo8eVL7n9iW6AQ==", "cpu": [ "arm64" ], @@ -1050,9 +1050,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.1.tgz", - "integrity": "sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.32.0.tgz", + "integrity": "sha512-F9ct0+ZX5Np6+ZDztxiGCIvlCaW87HBdHcozUfsHnj1WCUTBUubAoanhHUfnUHZABlElyRikI0mgcw/qdEm2VQ==", "cpu": [ "x64" ], @@ -1064,9 +1064,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.30.1.tgz", - "integrity": "sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.32.0.tgz", + "integrity": "sha512-JpsGxLBB2EFXBsTLHfkZDsXSpSmKD3VxXCgBQtlPcuAqB8TlqtLcbeMhxXQkCDv1avgwNjF8uEIbq5p+Cee0PA==", "cpu": [ "arm64" ], @@ -1078,9 +1078,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.1.tgz", - "integrity": "sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.32.0.tgz", + "integrity": "sha512-wegiyBT6rawdpvnD9lmbOpx5Sph+yVZKHbhnSP9MqUEDX08G4UzMU+D87jrazGE7lRSyTRs6NEYHtzfkJ3FjjQ==", "cpu": [ "x64" ], @@ -1092,9 +1092,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.1.tgz", - "integrity": "sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.32.0.tgz", + "integrity": "sha512-3pA7xecItbgOs1A5H58dDvOUEboG5UfpTq3WzAdF54acBbUM+olDJAPkgj1GRJ4ZqE12DZ9/hNS2QZk166v92A==", "cpu": [ "arm" ], @@ -1106,9 +1106,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.1.tgz", - "integrity": "sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.32.0.tgz", + "integrity": "sha512-Y7XUZEVISGyge51QbYyYAEHwpGgmRrAxQXO3siyYo2kmaj72USSG8LtlQQgAtlGfxYiOwu+2BdbPjzEpcOpRmQ==", "cpu": [ "arm" ], @@ -1120,9 +1120,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.1.tgz", - "integrity": "sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.32.0.tgz", + "integrity": "sha512-r7/OTF5MqeBrZo5omPXcTnjvv1GsrdH8a8RerARvDFiDwFpDVDnJyByYM/nX+mvks8XXsgPUxkwe/ltaX2VH7w==", "cpu": [ "arm64" ], @@ -1134,9 +1134,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.1.tgz", - "integrity": "sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.32.0.tgz", + "integrity": "sha512-HJbifC9vex9NqnlodV2BHVFNuzKL5OnsV2dvTw6e1dpZKkNjPG6WUq+nhEYV6Hv2Bv++BXkwcyoGlXnPrjAKXw==", "cpu": [ "arm64" ], @@ -1148,9 +1148,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.1.tgz", - "integrity": "sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.32.0.tgz", + "integrity": "sha512-VAEzZTD63YglFlWwRj3taofmkV1V3xhebDXffon7msNz4b14xKsz7utO6F8F4cqt8K/ktTl9rm88yryvDpsfOw==", "cpu": [ "loong64" ], @@ -1162,9 +1162,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.1.tgz", - "integrity": "sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.32.0.tgz", + "integrity": "sha512-Sts5DST1jXAc9YH/iik1C9QRsLcCoOScf3dfbY5i4kH9RJpKxiTBXqm7qU5O6zTXBTEZry69bGszr3SMgYmMcQ==", "cpu": [ "ppc64" ], @@ -1176,9 +1176,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.1.tgz", - "integrity": "sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.32.0.tgz", + "integrity": "sha512-qhlXeV9AqxIyY9/R1h1hBD6eMvQCO34ZmdYvry/K+/MBs6d1nRFLm6BOiITLVI+nFAAB9kUB6sdJRKyVHXnqZw==", "cpu": [ "riscv64" ], @@ -1190,9 +1190,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.1.tgz", - "integrity": "sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.32.0.tgz", + "integrity": "sha512-8ZGN7ExnV0qjXa155Rsfi6H8M4iBBwNLBM9lcVS+4NcSzOFaNqmt7djlox8pN1lWrRPMRRQ8NeDlozIGx3Omsw==", "cpu": [ "s390x" ], @@ -1204,9 +1204,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.1.tgz", - "integrity": "sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.32.0.tgz", + "integrity": "sha512-VDzNHtLLI5s7xd/VubyS10mq6TxvZBp+4NRWoW+Hi3tgV05RtVm4qK99+dClwTN1McA6PHwob6DEJ6PlXbY83A==", "cpu": [ "x64" ], @@ -1218,9 +1218,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.1.tgz", - "integrity": "sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.32.0.tgz", + "integrity": "sha512-qcb9qYDlkxz9DxJo7SDhWxTWV1gFuwznjbTiov289pASxlfGbaOD54mgbs9+z94VwrXtKTu+2RqwlSTbiOqxGg==", "cpu": [ "x64" ], @@ -1232,9 +1232,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.1.tgz", - "integrity": "sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.32.0.tgz", + "integrity": "sha512-pFDdotFDMXW2AXVbfdUEfidPAk/OtwE/Hd4eYMTNVVaCQ6Yl8et0meDaKNL63L44Haxv4UExpv9ydSf3aSayDg==", "cpu": [ "arm64" ], @@ -1246,9 +1246,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.1.tgz", - "integrity": "sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.32.0.tgz", + "integrity": "sha512-/TG7WfrCAjeRNDvI4+0AAMoHxea/USWhAzf9PVDFHbcqrQ7hMMKp4jZIy4VEjk72AAfN5k4TiSMRXRKf/0akSw==", "cpu": [ "ia32" ], @@ -1260,9 +1260,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.1.tgz", - "integrity": "sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.32.0.tgz", + "integrity": "sha512-5hqO5S3PTEO2E5VjCePxv40gIgyS2KvO7E7/vvC/NbIW4SIRamkMr1hqj+5Y67fbBWv/bQLB6KelBQmXlyCjWA==", "cpu": [ "x64" ], @@ -1784,9 +1784,9 @@ } }, "node_modules/eslint": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz", - "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==", + "version": "9.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.19.0.tgz", + "integrity": "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==", "dev": true, "license": "MIT", "dependencies": { @@ -1795,7 +1795,7 @@ "@eslint/config-array": "^0.19.0", "@eslint/core": "^0.10.0", "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.18.0", + "@eslint/js": "9.19.0", "@eslint/plugin-kit": "^0.2.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -2606,9 +2606,9 @@ } }, "node_modules/postcss": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.0.tgz", - "integrity": "sha512-27VKOqrYfPncKA2NrFOVhP5MGAfHKLYn/Q0mz9cNQyRAKYi3VNHwYU2qKKqPCqgBmeeJ0uAFB56NumXZ5ZReXg==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", + "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", "dev": true, "funding": [ { @@ -2794,9 +2794,9 @@ } }, "node_modules/rollup": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.30.1.tgz", - "integrity": "sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.32.0.tgz", + "integrity": "sha512-JmrhfQR31Q4AuNBjjAX4s+a/Pu/Q8Q9iwjWBsjRH1q52SPFE2NqRMK6fUZKKnvKO6id+h7JIRf0oYsph53eATg==", "dev": true, "license": "MIT", "dependencies": { @@ -2810,25 +2810,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.30.1", - "@rollup/rollup-android-arm64": "4.30.1", - "@rollup/rollup-darwin-arm64": "4.30.1", - "@rollup/rollup-darwin-x64": "4.30.1", - "@rollup/rollup-freebsd-arm64": "4.30.1", - "@rollup/rollup-freebsd-x64": "4.30.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.30.1", - "@rollup/rollup-linux-arm-musleabihf": "4.30.1", - "@rollup/rollup-linux-arm64-gnu": "4.30.1", - "@rollup/rollup-linux-arm64-musl": "4.30.1", - "@rollup/rollup-linux-loongarch64-gnu": "4.30.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.30.1", - "@rollup/rollup-linux-riscv64-gnu": "4.30.1", - "@rollup/rollup-linux-s390x-gnu": "4.30.1", - "@rollup/rollup-linux-x64-gnu": "4.30.1", - "@rollup/rollup-linux-x64-musl": "4.30.1", - "@rollup/rollup-win32-arm64-msvc": "4.30.1", - "@rollup/rollup-win32-ia32-msvc": "4.30.1", - "@rollup/rollup-win32-x64-msvc": "4.30.1", + "@rollup/rollup-android-arm-eabi": "4.32.0", + "@rollup/rollup-android-arm64": "4.32.0", + "@rollup/rollup-darwin-arm64": "4.32.0", + "@rollup/rollup-darwin-x64": "4.32.0", + "@rollup/rollup-freebsd-arm64": "4.32.0", + "@rollup/rollup-freebsd-x64": "4.32.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.32.0", + "@rollup/rollup-linux-arm-musleabihf": "4.32.0", + "@rollup/rollup-linux-arm64-gnu": "4.32.0", + "@rollup/rollup-linux-arm64-musl": "4.32.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.32.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.32.0", + "@rollup/rollup-linux-riscv64-gnu": "4.32.0", + "@rollup/rollup-linux-s390x-gnu": "4.32.0", + "@rollup/rollup-linux-x64-gnu": "4.32.0", + "@rollup/rollup-linux-x64-musl": "4.32.0", + "@rollup/rollup-win32-arm64-msvc": "4.32.0", + "@rollup/rollup-win32-ia32-msvc": "4.32.0", + "@rollup/rollup-win32-x64-msvc": "4.32.0", "fsevents": "~2.3.2" } }, @@ -3184,9 +3184,9 @@ "license": "MIT" }, "node_modules/vite": { - "version": "5.4.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", - "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", + "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/frontend/fic/src/lib/components/ExerciceDownloads.svelte b/frontend/fic/src/lib/components/ExerciceDownloads.svelte index c05a45a0..14ae7e7e 100644 --- a/frontend/fic/src/lib/components/ExerciceDownloads.svelte +++ b/frontend/fic/src/lib/components/ExerciceDownloads.svelte @@ -33,9 +33,9 @@

{file.name}

- {#if file.disclamer} -
- {file.disclamer} + {#if file.disclaimer} +
+ {file.disclaimer}
{/if} @@ -61,10 +61,10 @@ {/if} diff --git a/go.mod b/go.mod index 6ea2d7d9..cccf270b 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/cenkalti/dominantcolor v1.0.3 github.com/gin-contrib/sessions v1.0.2 github.com/gin-gonic/gin v1.10.0 - github.com/go-git/go-git/v5 v5.13.1 + github.com/go-git/go-git/v5 v5.13.2 github.com/go-sql-driver/mysql v1.8.1 github.com/google/gopacket v1.1.19 github.com/studio-b12/gowebdav v0.10.0 @@ -19,7 +19,7 @@ require ( gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b go.uber.org/multierr v1.11.0 golang.org/x/crypto v0.32.0 - golang.org/x/image v0.23.0 + golang.org/x/image v0.24.0 golang.org/x/oauth2 v0.25.0 gopkg.in/fsnotify.v1 v1.4.7 ) @@ -28,7 +28,7 @@ require ( dario.cat/mergo v1.0.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/ProtonMail/go-crypto v1.1.3 // indirect + github.com/ProtonMail/go-crypto v1.1.5 // indirect github.com/acomagu/bufpipe v1.0.4 // indirect github.com/asticode/go-astikit v0.20.0 // indirect github.com/asticode/go-astits v1.8.0 // indirect @@ -47,7 +47,7 @@ require ( github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.6.1 // indirect + github.com/go-git/go-billy/v5 v5.6.2 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.20.0 // indirect @@ -69,7 +69,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/pjbgf/sha1cd v0.3.2 // indirect github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/skeema/knownhosts v1.3.0 // indirect @@ -79,10 +79,10 @@ require ( github.com/xanzy/ssh-agent v0.3.3 // indirect golang.org/x/arch v0.8.0 // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.33.0 // indirect - golang.org/x/sync v0.10.0 // indirect + golang.org/x/net v0.34.0 // indirect + golang.org/x/sync v0.11.0 // indirect golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/text v0.22.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.34.1 // indirect diff --git a/go.sum b/go.sum index 2b49b734..0aad252c 100644 --- a/go.sum +++ b/go.sum @@ -33,6 +33,8 @@ github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0k github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk= github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4= +github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= @@ -168,6 +170,8 @@ github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+ github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= github.com/go-git/go-billy/v5 v5.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA= github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE= +github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= +github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8= github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= @@ -199,6 +203,8 @@ github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZt github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M= github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc= +github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0= +github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -352,6 +358,8 @@ github.com/pjbgf/sha1cd v0.2.3 h1:uKQP/7QOzNtKYH7UTohZLcjF5/55EnTw0jO/Ru4jZwI= github.com/pjbgf/sha1cd v0.2.3/go.mod h1:HOK9QrgzdHpbc2Kzip0Q1yi3M2MFGPADtR6HjG65m5M= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= +github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -591,6 +599,8 @@ golang.org/x/image v0.22.0 h1:UtK5yLUzilVrkjMAZAZ34DXGpASN8i8pj8g+O+yd10g= golang.org/x/image v0.22.0/go.mod h1:9hPFhljd4zZ1GNSIZJ49sqbp45GKK9t6w+iXvGqZUz4= golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68= golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY= +golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ= +golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -659,6 +669,8 @@ golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= golang.org/x/oauth2 v0.2.0 h1:GtQkldQ9m7yvzCL1V+LrYow3Khe0eJH0w7RbX/VbaIU= @@ -720,6 +732,8 @@ golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -851,6 +865,8 @@ golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/libfic/db.go b/libfic/db.go index ae6826ae..0a96120e 100644 --- a/libfic/db.go +++ b/libfic/db.go @@ -414,6 +414,7 @@ CREATE TABLE IF NOT EXISTS exercice_solved( } if _, err := db.Exec(` CREATE TABLE IF NOT EXISTS exercice_tries( + id_try INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, id_exercice INTEGER NOT NULL, id_team INTEGER NOT NULL, time TIMESTAMP NOT NULL, @@ -423,6 +424,26 @@ CREATE TABLE IF NOT EXISTS exercice_tries( FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice), FOREIGN KEY(id_team) REFERENCES teams(id_team) ) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; +`); err != nil { + return err + } + if _, err := db.Exec(` +CREATE TABLE IF NOT EXISTS exercice_tries_flags( + id_try INTEGER NOT NULL, + id_flag INTEGER NOT NULL, + FOREIGN KEY(id_try) REFERENCES exercice_tries(id_try) ON DELETE CASCADE, + FOREIGN KEY(id_flag) REFERENCES exercice_flags(id_flag) ON DELETE CASCADE +) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; +`); err != nil { + return err + } + if _, err := db.Exec(` +CREATE TABLE IF NOT EXISTS exercice_tries_mcq( + id_try INTEGER NOT NULL, + id_mcq INTEGER NOT NULL, + FOREIGN KEY(id_try) REFERENCES exercice_tries(id_try) ON DELETE CASCADE, + FOREIGN KEY(id_mcq) REFERENCES exercice_mcq(id_mcq) ON DELETE CASCADE +) DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; `); err != nil { return err } diff --git a/libfic/exercice.go b/libfic/exercice.go index c9979fcb..d6b38121 100644 --- a/libfic/exercice.go +++ b/libfic/exercice.go @@ -3,6 +3,7 @@ package fic import ( "errors" "fmt" + "log" "math" "time" ) @@ -444,11 +445,25 @@ func (e *Exercice) GetOrdinal() (int, error) { } // NewTry registers a solving attempt for the given Team. -func (e *Exercice) NewTry(t *Team, cksum []byte) error { - if _, err := DBExec("INSERT INTO exercice_tries (id_exercice, id_team, time, cksum) VALUES (?, ?, ?, ?)", e.Id, t.Id, time.Now(), cksum); err != nil { - return err +func (e *Exercice) NewTry(t *Team, cksum []byte, flags ...Flag) (int64, error) { + if res, err := DBExec("INSERT INTO exercice_tries (id_exercice, id_team, time, cksum) VALUES (?, ?, ?, ?)", e.Id, t.Id, time.Now(), cksum); err != nil { + return 0, err } else { - return nil + return res.LastInsertId() + } +} + +func (e *Exercice) NewTryFlag(tryid int64, flags ...Flag) { + for _, flag := range flags { + if fk, ok := flag.(*FlagKey); ok { + if _, err := DBExec("INSERT INTO exercice_tries_flags (id_try, id_flag) VALUES (?, ?)", tryid, fk.Id); err != nil { + log.Println("Unable to add detailed try: ", err.Error()) + } + } else if fm, ok := flag.(*MCQ); ok { + if _, err := DBExec("INSERT INTO exercice_tries_mcq (id_try, id_mcq) VALUES (?, ?)", tryid, fm.Id); err != nil { + log.Println("Unable to add detailed try: ", err.Error()) + } + } } } @@ -550,7 +565,7 @@ func (e *Exercice) MCQSolved() (res []int64) { // CheckResponse, given both flags and MCQ responses, figures out if thoses are correct (or if they are previously solved). // In the meanwhile, CheckResponse registers good answers given (but it does not mark the challenge as solved at the end). func (e *Exercice) CheckResponse(cksum []byte, respflags map[int]string, respmcq map[int]bool, t *Team) (bool, error) { - if err := e.NewTry(t, cksum); err != nil { + if tryId, err := e.NewTry(t, cksum); err != nil { return false, err } else if flags, err := e.GetFlagKeys(); err != nil { return false, err @@ -565,6 +580,10 @@ func (e *Exercice) CheckResponse(cksum []byte, respflags map[int]string, respmcq // Check MCQs for _, mcq := range mcqs { + if mcq.HasOneEntry(respmcq) { + e.NewTryFlag(tryId, mcq) + } + if d := mcq.Check(respmcq); d > 0 { if !PartialValidation || t.HasPartiallySolved(mcq) == nil { valid = false @@ -589,15 +608,21 @@ func (e *Exercice) CheckResponse(cksum []byte, respflags map[int]string, respmcq for _, flag := range flags { if res, ok := respflags[flag.Id]; !ok && (!PartialValidation || t.HasPartiallySolved(flag) == nil) { valid = valid && flag.IsOptionnal() - } else if flag.Check([]byte(res)) != 0 { - if !PartialValidation || t.HasPartiallySolved(flag) == nil { - valid = valid && flag.IsOptionnal() + } else if ok { + if len(res) > 0 { + e.NewTryFlag(tryId, flag) } - } else { - err := flag.FoundBy(t) - if err == nil { - // err is unicity issue, probably flag already found - goodResponses += 1 + + if flag.Check([]byte(res)) != 0 { + if !PartialValidation || t.HasPartiallySolved(flag) == nil { + valid = valid && flag.IsOptionnal() + } + } else { + err := flag.FoundBy(t) + if err == nil { + // err is unicity issue, probably flag already found + goodResponses += 1 + } } } } diff --git a/libfic/exercice_history.go b/libfic/exercice_history.go index 63dab2dd..763c48d7 100644 --- a/libfic/exercice_history.go +++ b/libfic/exercice_history.go @@ -68,7 +68,8 @@ func (e *Exercice) AppendHistoryItem(tId int64, kind string, secondary *int64) e if kind == "tries" { bid := make([]byte, 5) binary.LittleEndian.PutUint32(bid, rand.Uint32()) - return (&Exercice{Id: e.Id}).NewTry(team, bid) + _, err = (&Exercice{Id: e.Id}).NewTry(team, bid) + return err } else if kind == "hint" && secondary != nil { return team.OpenHint(&EHint{Id: *secondary}) } else if kind == "wchoices" && secondary != nil { diff --git a/libfic/file.go b/libfic/file.go index 4e5bf37f..d39bb6b0 100644 --- a/libfic/file.go +++ b/libfic/file.go @@ -392,7 +392,12 @@ func (f *EFile) GetDepends() ([]Flag, error) { // CheckFileOnDisk recalculates the hash of the file on disk. func (f *EFile) CheckFileOnDisk() error { - if _, size, err := checkFileHash(path.Join(FilesDir, f.Path), f.Checksum); err != nil { + firstChecksum := f.Checksum + if len(f.ChecksumShown) > 0 { + firstChecksum = f.ChecksumShown + } + + if _, size, err := checkFileHash(path.Join(FilesDir, f.Path), firstChecksum); size > 0 && err != nil { return err } else if size == 0 { if _, _, err := checkFileHash(path.Join(FilesDir, f.Path+".gz"), f.Checksum); err != nil { @@ -400,9 +405,17 @@ func (f *EFile) CheckFileOnDisk() error { } else { return nil } - } else { - return nil + } else if err != nil { + return err } + + if _, err := os.Stat(path.Join(FilesDir, f.Path+".gz")); !os.IsNotExist(err) { + if _, _, err = checkFileHash(path.Join(FilesDir, f.Path+".gz"), f.Checksum); err != nil { + return err + } + } + + return nil } // GunzipFileOnDisk gunzip a compressed file. diff --git a/libfic/flag.go b/libfic/flag.go index 06373495..2e419bf1 100644 --- a/libfic/flag.go +++ b/libfic/flag.go @@ -14,6 +14,9 @@ type Flag interface { Check(val interface{}) int IsOptionnal() bool FoundBy(t *Team) error + NbTries() (int64, error) + TeamsOnIt() ([]int64, error) + DeleteTries() error } // GetFlag returns a list of flags comming with the challenge. diff --git a/libfic/flag_key.go b/libfic/flag_key.go index 905d1942..40da9348 100644 --- a/libfic/flag_key.go +++ b/libfic/flag_key.go @@ -230,6 +230,54 @@ func (k *FlagKey) RecoverId() (Flag, error) { } } +// NbTries returns the flag resolution statistics. +func (k *FlagKey) NbTries() (tries int64, err error) { + err = DBQueryRow("SELECT COUNT(*) AS tries FROM exercice_tries_flags WHERE id_flag = ?", k.Id).Scan(&tries) + return +} + +func (k *FlagKey) TeamsOnIt() ([]int64, error) { + if rows, err := DBQuery("SELECT DISTINCT M.id_team FROM exercice_tries_flags F INNER JOIN exercice_tries T ON T.id_try = F.id_try INNER JOIN teams M ON M.id_team = T.id_team WHERE id_flag = ?", k.Id); err != nil { + return nil, err + } else { + defer rows.Close() + + teams := []int64{} + for rows.Next() { + var idteam int64 + if err := rows.Scan(&idteam); err != nil { + return nil, err + } + teams = append(teams, idteam) + } + + return teams, nil + } +} + +func (k *FlagKey) DeleteTries() error { + if rows, err := DBQuery("SELECT id_try FROM exercice_tries_flags WHERE id_flag = ?", k.Id); err != nil { + return err + } else { + defer rows.Close() + + for rows.Next() { + var idtry int64 + err = rows.Scan(&idtry) + if err != nil { + return err + } + + _, err = DBExec("DELETE FROM exercice_tries WHERE id_try = ?", idtry) + if err != nil { + return err + } + } + + return nil + } +} + // AddFlagKey creates and fills a new struct Flag, from a hashed flag, and registers it into the database. func (k *FlagKey) Create(e *Exercice) (Flag, error) { // Check the regexp compile diff --git a/libfic/flag_label.go b/libfic/flag_label.go index 6d103f7f..eec13522 100644 --- a/libfic/flag_label.go +++ b/libfic/flag_label.go @@ -71,6 +71,18 @@ func (k *FlagLabel) RecoverId() (Flag, error) { } } +func (k *FlagLabel) NbTries() (int64, error) { + return 0, nil +} + +func (k *FlagLabel) TeamsOnIt() ([]int64, error) { + return nil, nil +} + +func (k *FlagLabel) DeleteTries() error { + return nil +} + // AddFlagLabel creates and fills a new struct Flag and registers it into the database. func (k *FlagLabel) Create(e *Exercice) (Flag, error) { if res, err := DBExec("INSERT INTO exercice_flag_labels (id_exercice, ordre, label, variant) VALUES (?, ?, ?, ?)", e.Id, k.Order, k.Label, k.Variant); err != nil { diff --git a/libfic/mcq.go b/libfic/mcq.go index 82315479..3129ec80 100644 --- a/libfic/mcq.go +++ b/libfic/mcq.go @@ -136,6 +136,54 @@ func (m *MCQ) RecoverId() (Flag, error) { } } +// NbTries returns the MCQ resolution statistics. +func (m *MCQ) NbTries() (tries int64, err error) { + err = DBQueryRow("SELECT COUNT(*) AS tries FROM exercice_tries_mcq WHERE id_mcq = ?", m.Id).Scan(&tries) + return +} + +func (m *MCQ) TeamsOnIt() ([]int64, error) { + if rows, err := DBQuery("SELECT DISTINCT M.id_team FROM exercice_tries_mcq F INNER JOIN exercice_tries T ON T.id_try = F.id_try INNER JOIN teams M ON M.id_team = T.id_team WHERE id_mcq = ?", m.Id); err != nil { + return nil, err + } else { + defer rows.Close() + + teams := []int64{} + for rows.Next() { + var idteam int64 + if err := rows.Scan(&idteam); err != nil { + return nil, err + } + teams = append(teams, idteam) + } + + return teams, nil + } +} + +func (m *MCQ) DeleteTries() error { + if rows, err := DBQuery("SELECT id_try FROM exercice_tries_mcq WHERE id_mcq = ?", m.Id); err != nil { + return err + } else { + defer rows.Close() + + for rows.Next() { + var idtry int64 + err = rows.Scan(&idtry) + if err != nil { + return err + } + + _, err = DBExec("DELETE FROM exercice_tries WHERE id_try = ?", idtry) + if err != nil { + return err + } + } + + return nil + } +} + // Create registers a MCQ into the database and recursively add its entries. func (m *MCQ) Create(e *Exercice) (Flag, error) { if res, err := DBExec("INSERT INTO exercice_mcq (id_exercice, ordre, title) VALUES (?, ?, ?)", e.Id, m.Order, m.Title); err != nil { @@ -207,7 +255,7 @@ func (m *MCQ) AddEntry(e *MCQ_entry) (*MCQ_entry, error) { // Update applies modifications back to the database. func (n *MCQ_entry) Update() (int64, error) { - if res, err := DBExec("UPDATE mcq_entries SET label = ?, response = ? WHERE id_mcq = ?", n.Label, n.Response, n.Id); err != nil { + if res, err := DBExec("UPDATE mcq_entries SET label = ?, response = ? WHERE id_mcq_entry = ?", n.Label, n.Response, n.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err @@ -319,6 +367,24 @@ func (m *MCQ) IsOptionnal() bool { return false } +// Check if the given vals contains at least a response for the given MCQ. +func (m *MCQ) HasOneEntry(v interface{}) bool { + var vals map[int]bool + if va, ok := v.(map[int]bool); !ok { + return false + } else { + vals = va + } + + for _, n := range m.Entries { + if _, ok := vals[n.Id]; ok { + return true + } + } + + return false +} + // Check if the given vals are the expected ones to validate this flag. func (m *MCQ) Check(v interface{}) int { var vals map[int]bool diff --git a/qa/ui/package-lock.json b/qa/ui/package-lock.json index 5989b9cb..0f31cd29 100644 --- a/qa/ui/package-lock.json +++ b/qa/ui/package-lock.json @@ -524,9 +524,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz", - "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==", + "version": "9.19.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz", + "integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==", "dev": true, "license": "MIT", "engines": { @@ -689,9 +689,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz", - "integrity": "sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.32.0.tgz", + "integrity": "sha512-G2fUQQANtBPsNwiVFg4zKiPQyjVKZCUdQUol53R8E71J7AsheRMV/Yv/nB8giOcOVqP7//eB5xPqieBYZe9bGg==", "cpu": [ "arm" ], @@ -703,9 +703,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.1.tgz", - "integrity": "sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.32.0.tgz", + "integrity": "sha512-qhFwQ+ljoymC+j5lXRv8DlaJYY/+8vyvYmVx074zrLsu5ZGWYsJNLjPPVJJjhZQpyAKUGPydOq9hRLLNvh1s3A==", "cpu": [ "arm64" ], @@ -717,9 +717,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.1.tgz", - "integrity": "sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.32.0.tgz", + "integrity": "sha512-44n/X3lAlWsEY6vF8CzgCx+LQaoqWGN7TzUfbJDiTIOjJm4+L2Yq+r5a8ytQRGyPqgJDs3Rgyo8eVL7n9iW6AQ==", "cpu": [ "arm64" ], @@ -731,9 +731,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.1.tgz", - "integrity": "sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.32.0.tgz", + "integrity": "sha512-F9ct0+ZX5Np6+ZDztxiGCIvlCaW87HBdHcozUfsHnj1WCUTBUubAoanhHUfnUHZABlElyRikI0mgcw/qdEm2VQ==", "cpu": [ "x64" ], @@ -745,9 +745,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.30.1.tgz", - "integrity": "sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.32.0.tgz", + "integrity": "sha512-JpsGxLBB2EFXBsTLHfkZDsXSpSmKD3VxXCgBQtlPcuAqB8TlqtLcbeMhxXQkCDv1avgwNjF8uEIbq5p+Cee0PA==", "cpu": [ "arm64" ], @@ -759,9 +759,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.1.tgz", - "integrity": "sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.32.0.tgz", + "integrity": "sha512-wegiyBT6rawdpvnD9lmbOpx5Sph+yVZKHbhnSP9MqUEDX08G4UzMU+D87jrazGE7lRSyTRs6NEYHtzfkJ3FjjQ==", "cpu": [ "x64" ], @@ -773,9 +773,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.1.tgz", - "integrity": "sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.32.0.tgz", + "integrity": "sha512-3pA7xecItbgOs1A5H58dDvOUEboG5UfpTq3WzAdF54acBbUM+olDJAPkgj1GRJ4ZqE12DZ9/hNS2QZk166v92A==", "cpu": [ "arm" ], @@ -787,9 +787,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.1.tgz", - "integrity": "sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.32.0.tgz", + "integrity": "sha512-Y7XUZEVISGyge51QbYyYAEHwpGgmRrAxQXO3siyYo2kmaj72USSG8LtlQQgAtlGfxYiOwu+2BdbPjzEpcOpRmQ==", "cpu": [ "arm" ], @@ -801,9 +801,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.1.tgz", - "integrity": "sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.32.0.tgz", + "integrity": "sha512-r7/OTF5MqeBrZo5omPXcTnjvv1GsrdH8a8RerARvDFiDwFpDVDnJyByYM/nX+mvks8XXsgPUxkwe/ltaX2VH7w==", "cpu": [ "arm64" ], @@ -815,9 +815,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.1.tgz", - "integrity": "sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.32.0.tgz", + "integrity": "sha512-HJbifC9vex9NqnlodV2BHVFNuzKL5OnsV2dvTw6e1dpZKkNjPG6WUq+nhEYV6Hv2Bv++BXkwcyoGlXnPrjAKXw==", "cpu": [ "arm64" ], @@ -829,9 +829,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.1.tgz", - "integrity": "sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.32.0.tgz", + "integrity": "sha512-VAEzZTD63YglFlWwRj3taofmkV1V3xhebDXffon7msNz4b14xKsz7utO6F8F4cqt8K/ktTl9rm88yryvDpsfOw==", "cpu": [ "loong64" ], @@ -843,9 +843,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.1.tgz", - "integrity": "sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.32.0.tgz", + "integrity": "sha512-Sts5DST1jXAc9YH/iik1C9QRsLcCoOScf3dfbY5i4kH9RJpKxiTBXqm7qU5O6zTXBTEZry69bGszr3SMgYmMcQ==", "cpu": [ "ppc64" ], @@ -857,9 +857,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.1.tgz", - "integrity": "sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.32.0.tgz", + "integrity": "sha512-qhlXeV9AqxIyY9/R1h1hBD6eMvQCO34ZmdYvry/K+/MBs6d1nRFLm6BOiITLVI+nFAAB9kUB6sdJRKyVHXnqZw==", "cpu": [ "riscv64" ], @@ -871,9 +871,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.1.tgz", - "integrity": "sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.32.0.tgz", + "integrity": "sha512-8ZGN7ExnV0qjXa155Rsfi6H8M4iBBwNLBM9lcVS+4NcSzOFaNqmt7djlox8pN1lWrRPMRRQ8NeDlozIGx3Omsw==", "cpu": [ "s390x" ], @@ -885,9 +885,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.1.tgz", - "integrity": "sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.32.0.tgz", + "integrity": "sha512-VDzNHtLLI5s7xd/VubyS10mq6TxvZBp+4NRWoW+Hi3tgV05RtVm4qK99+dClwTN1McA6PHwob6DEJ6PlXbY83A==", "cpu": [ "x64" ], @@ -899,9 +899,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.1.tgz", - "integrity": "sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.32.0.tgz", + "integrity": "sha512-qcb9qYDlkxz9DxJo7SDhWxTWV1gFuwznjbTiov289pASxlfGbaOD54mgbs9+z94VwrXtKTu+2RqwlSTbiOqxGg==", "cpu": [ "x64" ], @@ -913,9 +913,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.1.tgz", - "integrity": "sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.32.0.tgz", + "integrity": "sha512-pFDdotFDMXW2AXVbfdUEfidPAk/OtwE/Hd4eYMTNVVaCQ6Yl8et0meDaKNL63L44Haxv4UExpv9ydSf3aSayDg==", "cpu": [ "arm64" ], @@ -927,9 +927,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.1.tgz", - "integrity": "sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.32.0.tgz", + "integrity": "sha512-/TG7WfrCAjeRNDvI4+0AAMoHxea/USWhAzf9PVDFHbcqrQ7hMMKp4jZIy4VEjk72AAfN5k4TiSMRXRKf/0akSw==", "cpu": [ "ia32" ], @@ -941,9 +941,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.1.tgz", - "integrity": "sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.32.0.tgz", + "integrity": "sha512-5hqO5S3PTEO2E5VjCePxv40gIgyS2KvO7E7/vvC/NbIW4SIRamkMr1hqj+5Y67fbBWv/bQLB6KelBQmXlyCjWA==", "cpu": [ "x64" ], @@ -1414,9 +1414,9 @@ } }, "node_modules/eslint": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz", - "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==", + "version": "9.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.19.0.tgz", + "integrity": "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==", "dev": true, "license": "MIT", "dependencies": { @@ -1425,7 +1425,7 @@ "@eslint/config-array": "^0.19.0", "@eslint/core": "^0.10.0", "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.18.0", + "@eslint/js": "9.19.0", "@eslint/plugin-kit": "^0.2.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -2154,9 +2154,9 @@ "license": "ISC" }, "node_modules/postcss": { - "version": "8.4.49", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", - "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", + "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", "dev": true, "funding": [ { @@ -2174,7 +2174,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", + "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -2328,9 +2328,9 @@ } }, "node_modules/rollup": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.30.1.tgz", - "integrity": "sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.32.0.tgz", + "integrity": "sha512-JmrhfQR31Q4AuNBjjAX4s+a/Pu/Q8Q9iwjWBsjRH1q52SPFE2NqRMK6fUZKKnvKO6id+h7JIRf0oYsph53eATg==", "dev": true, "license": "MIT", "dependencies": { @@ -2344,25 +2344,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.30.1", - "@rollup/rollup-android-arm64": "4.30.1", - "@rollup/rollup-darwin-arm64": "4.30.1", - "@rollup/rollup-darwin-x64": "4.30.1", - "@rollup/rollup-freebsd-arm64": "4.30.1", - "@rollup/rollup-freebsd-x64": "4.30.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.30.1", - "@rollup/rollup-linux-arm-musleabihf": "4.30.1", - "@rollup/rollup-linux-arm64-gnu": "4.30.1", - "@rollup/rollup-linux-arm64-musl": "4.30.1", - "@rollup/rollup-linux-loongarch64-gnu": "4.30.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.30.1", - "@rollup/rollup-linux-riscv64-gnu": "4.30.1", - "@rollup/rollup-linux-s390x-gnu": "4.30.1", - "@rollup/rollup-linux-x64-gnu": "4.30.1", - "@rollup/rollup-linux-x64-musl": "4.30.1", - "@rollup/rollup-win32-arm64-msvc": "4.30.1", - "@rollup/rollup-win32-ia32-msvc": "4.30.1", - "@rollup/rollup-win32-x64-msvc": "4.30.1", + "@rollup/rollup-android-arm-eabi": "4.32.0", + "@rollup/rollup-android-arm64": "4.32.0", + "@rollup/rollup-darwin-arm64": "4.32.0", + "@rollup/rollup-darwin-x64": "4.32.0", + "@rollup/rollup-freebsd-arm64": "4.32.0", + "@rollup/rollup-freebsd-x64": "4.32.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.32.0", + "@rollup/rollup-linux-arm-musleabihf": "4.32.0", + "@rollup/rollup-linux-arm64-gnu": "4.32.0", + "@rollup/rollup-linux-arm64-musl": "4.32.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.32.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.32.0", + "@rollup/rollup-linux-riscv64-gnu": "4.32.0", + "@rollup/rollup-linux-s390x-gnu": "4.32.0", + "@rollup/rollup-linux-x64-gnu": "4.32.0", + "@rollup/rollup-linux-x64-musl": "4.32.0", + "@rollup/rollup-win32-arm64-msvc": "4.32.0", + "@rollup/rollup-win32-ia32-msvc": "4.32.0", + "@rollup/rollup-win32-x64-msvc": "4.32.0", "fsevents": "~2.3.2" } }, @@ -2627,9 +2627,9 @@ "license": "MIT" }, "node_modules/vite": { - "version": "5.4.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", - "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", + "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", "dev": true, "license": "MIT", "dependencies": {