From 650775af455a71c1dbeaf743f242b4aec7113246 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 27 Jan 2026 16:45:16 +0100 Subject: [PATCH 01/57] style: change font and polish UI --- public/fonts/Geist-Variable.woff2 | Bin 0 -> 58512 bytes public/fonts/GeistMono-Variable.woff2 | Bin 0 -> 58092 bytes src/components/ui/badge.tsx | 2 +- src/index.css | 36 +++++++++++++++++++------- src/pages/HomePage.tsx | 4 +-- 5 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 public/fonts/Geist-Variable.woff2 create mode 100644 public/fonts/GeistMono-Variable.woff2 diff --git a/public/fonts/Geist-Variable.woff2 b/public/fonts/Geist-Variable.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..d1a0cbc66e39c773778eaa989ddad838b1b94901 GIT binary patch literal 58512 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 YZ%~iJpAoXSUKi_Bm+!vwK&}V?02RZfm;e9( literal 0 HcmV?d00001 diff --git a/public/fonts/GeistMono-Variable.woff2 b/public/fonts/GeistMono-Variable.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..4692e48c56b5ae50af74da21084004b171dbb172 GIT binary patch literal 58092 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 literal 0 HcmV?d00001 diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx index 246d1d5..bfb0a7f 100644 --- a/src/components/ui/badge.tsx +++ b/src/components/ui/badge.tsx @@ -21,7 +21,7 @@ export const Badge = ({ return (
-

+

Personalized learning needs a{' '} transparent competency benchmark @@ -173,7 +173,7 @@ export function HomePage() { function LiquidGlassGradient() { return (
-
+
From 79e45a2a6b33e13772baf9ffc5a726aa7b19a971 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 27 Jan 2026 16:47:48 +0100 Subject: [PATCH 02/57] style: update font weight --- src/pages/HomePage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index 2eb2307..cda03ae 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -38,7 +38,7 @@ export function HomePage() {
-

+

Personalized learning needs a{' '} transparent competency benchmark From 430e1c2ab167fef8d28ae0cf89e74ed7f1468981 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 3 Feb 2026 02:54:38 +0100 Subject: [PATCH 03/57] style: conform to Prettier formatting --- src/index.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.css b/src/index.css index f260895..a4522fb 100644 --- a/src/index.css +++ b/src/index.css @@ -125,4 +125,4 @@ .scrollbar-thin::-webkit-scrollbar-thumb:hover { background-color: rgb(148 163 184); } -} \ No newline at end of file +} From 73a402bce758d83f942f606087cf59805949c41e Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 3 Feb 2026 10:07:33 +0100 Subject: [PATCH 04/57] Implement optimized Scheduling Service and Pipeline Logic --- .../CompetencyRelationshipController.java | 27 +- .../memo/controller/SchedulingController.java | 43 +++ .../memo/dto/RelationshipTaskResponse.java | 40 +++ .../java/de/tum/cit/memo/dto/VoteRequest.java | 22 ++ .../de/tum/cit/memo/dto/VoteResponse.java | 28 ++ .../de/tum/cit/memo/entity/Competency.java | 3 + .../memo/entity/CompetencyRelationship.java | 79 ++++- .../entity/CompetencyRelationshipVote.java | 63 ++++ .../CompetencyRelationshipRepository.java | 76 ++++- .../CompetencyRelationshipVoteRepository.java | 20 ++ .../memo/repository/CompetencyRepository.java | 6 + .../CompetencyRelationshipService.java | 65 +++- .../cit/memo/service/SchedulingService.java | 299 ++++++++++++++++++ .../db/migration/V2__seed_sample_data.sql | 6 - .../migration/V5__drop_old_relationships.sql | 10 + .../V6__create_scheduling_tables.sql | 62 ++++ .../migration/V7__add_competency_degree.sql | 19 ++ 17 files changed, 821 insertions(+), 47 deletions(-) create mode 100644 server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java create mode 100644 server/src/main/java/de/tum/cit/memo/dto/RelationshipTaskResponse.java create mode 100644 server/src/main/java/de/tum/cit/memo/dto/VoteRequest.java create mode 100644 server/src/main/java/de/tum/cit/memo/dto/VoteResponse.java create mode 100644 server/src/main/java/de/tum/cit/memo/entity/CompetencyRelationshipVote.java create mode 100644 server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipVoteRepository.java create mode 100644 server/src/main/java/de/tum/cit/memo/service/SchedulingService.java create mode 100644 server/src/main/resources/db/migration/V5__drop_old_relationships.sql create mode 100644 server/src/main/resources/db/migration/V6__create_scheduling_tables.sql create mode 100644 server/src/main/resources/db/migration/V7__add_competency_degree.sql diff --git a/server/src/main/java/de/tum/cit/memo/controller/CompetencyRelationshipController.java b/server/src/main/java/de/tum/cit/memo/controller/CompetencyRelationshipController.java index d0efa69..ba2fbde 100644 --- a/server/src/main/java/de/tum/cit/memo/controller/CompetencyRelationshipController.java +++ b/server/src/main/java/de/tum/cit/memo/controller/CompetencyRelationshipController.java @@ -1,8 +1,10 @@ package de.tum.cit.memo.controller; import de.tum.cit.memo.dto.CreateCompetencyRelationshipRequest; +import de.tum.cit.memo.dto.VoteRequest; import de.tum.cit.memo.entity.CompetencyRelationship; import de.tum.cit.memo.service.CompetencyRelationshipService; +import de.tum.cit.memo.service.SchedulingService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; @@ -19,6 +21,10 @@ import java.util.List; +/** + * Controller for competency relationship management. + * The POST endpoint creates a relationship and records a vote. + */ @RestController @RequestMapping("/api/competency-relationships") @RequiredArgsConstructor @@ -26,11 +32,26 @@ public class CompetencyRelationshipController { private final CompetencyRelationshipService relationshipService; + private final SchedulingService schedulingService; @PostMapping - @Operation(summary = "Create a new competency relationship") - public ResponseEntity createRelationship(@Valid @RequestBody CreateCompetencyRelationshipRequest request) { - CompetencyRelationship relationship = relationshipService.createRelationship(request); + @Operation(summary = "Create a competency relationship and record a vote") + public ResponseEntity createRelationship( + @Valid @RequestBody CreateCompetencyRelationshipRequest request) { + // Create the relationship if it doesn't exist + CompetencyRelationship relationship = relationshipService.findOrCreateRelationship( + request.getOriginId(), request.getDestinationId()); + + // Record the vote via scheduling service + VoteRequest voteRequest = VoteRequest.builder() + .relationshipId(relationship.getId()) + .relationshipType(request.getRelationshipType()) + .build(); + schedulingService.submitVote(request.getUserId(), voteRequest); + + // Refresh to get updated counters + relationship = relationshipService.getRelationshipById(relationship.getId()); + return ResponseEntity.status(HttpStatus.CREATED).body(relationship); } diff --git a/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java b/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java new file mode 100644 index 0000000..681c82b --- /dev/null +++ b/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java @@ -0,0 +1,43 @@ +package de.tum.cit.memo.controller; + +import de.tum.cit.memo.dto.RelationshipTaskResponse; +import de.tum.cit.memo.dto.VoteRequest; +import de.tum.cit.memo.dto.VoteResponse; +import de.tum.cit.memo.service.SchedulingService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/scheduling") +@RequiredArgsConstructor +@Tag(name = "Scheduling", description = "Endpoints for competency mapping scheduling") +public class SchedulingController { + + private final SchedulingService schedulingService; + + @GetMapping("/next-relationship") + @Operation(summary = "Get next relationship to vote on", description = "Returns a competency pair for the user to map. Uses coverage (70%) and consensus (30%) pipelines.") + public ResponseEntity getNextRelationship( + @RequestHeader(value = "X-User-Id", required = false, defaultValue = "anonymous") String userId) { + RelationshipTaskResponse task = schedulingService.getNextTask(userId); + return ResponseEntity.ok(task); + } + + @PostMapping("/vote") + @Operation(summary = "Submit a vote on a relationship", description = "Records the user's vote on a competency relationship. MATCHES votes are bidirectional.") + public ResponseEntity submitVote( + @RequestHeader(value = "X-User-Id", required = false, defaultValue = "anonymous") String userId, + @Valid @RequestBody VoteRequest request) { + VoteResponse response = schedulingService.submitVote(userId, request); + return ResponseEntity.ok(response); + } +} diff --git a/server/src/main/java/de/tum/cit/memo/dto/RelationshipTaskResponse.java b/server/src/main/java/de/tum/cit/memo/dto/RelationshipTaskResponse.java new file mode 100644 index 0000000..098294b --- /dev/null +++ b/server/src/main/java/de/tum/cit/memo/dto/RelationshipTaskResponse.java @@ -0,0 +1,40 @@ +package de.tum.cit.memo.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class RelationshipTaskResponse { + + private String relationshipId; + private CompetencyInfo origin; + private CompetencyInfo destination; + private String pipeline; // "COVERAGE" or "CONSENSUS" + private VoteCounts currentVotes; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class CompetencyInfo { + private String id; + private String title; + private String description; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class VoteCounts { + private int assumes; + private int extendsRelation; // 'extends' is a Java reserved keyword + private int matches; + private int unrelated; + } +} diff --git a/server/src/main/java/de/tum/cit/memo/dto/VoteRequest.java b/server/src/main/java/de/tum/cit/memo/dto/VoteRequest.java new file mode 100644 index 0000000..e1f0da3 --- /dev/null +++ b/server/src/main/java/de/tum/cit/memo/dto/VoteRequest.java @@ -0,0 +1,22 @@ +package de.tum.cit.memo.dto; + +import de.tum.cit.memo.enums.RelationshipType; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class VoteRequest { + + @NotBlank(message = "Relationship ID is required") + private String relationshipId; + + @NotNull(message = "Relationship type is required") + private RelationshipType relationshipType; +} diff --git a/server/src/main/java/de/tum/cit/memo/dto/VoteResponse.java b/server/src/main/java/de/tum/cit/memo/dto/VoteResponse.java new file mode 100644 index 0000000..0764899 --- /dev/null +++ b/server/src/main/java/de/tum/cit/memo/dto/VoteResponse.java @@ -0,0 +1,28 @@ +package de.tum.cit.memo.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class VoteResponse { + + private boolean success; + private VoteCounts updatedVotes; + private double newEntropy; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class VoteCounts { + private int assumes; + private int extendsRelation; // 'extends' is a Java reserved keyword + private int matches; + private int unrelated; + } +} diff --git a/server/src/main/java/de/tum/cit/memo/entity/Competency.java b/server/src/main/java/de/tum/cit/memo/entity/Competency.java index d869f10..087febb 100644 --- a/server/src/main/java/de/tum/cit/memo/entity/Competency.java +++ b/server/src/main/java/de/tum/cit/memo/entity/Competency.java @@ -35,4 +35,7 @@ public class Competency { @CreationTimestamp @Column(nullable = false, updatable = false) private Instant createdAt; + + @Column(nullable = false) + private int degree; } diff --git a/server/src/main/java/de/tum/cit/memo/entity/CompetencyRelationship.java b/server/src/main/java/de/tum/cit/memo/entity/CompetencyRelationship.java index 27b9982..d12de7e 100644 --- a/server/src/main/java/de/tum/cit/memo/entity/CompetencyRelationship.java +++ b/server/src/main/java/de/tum/cit/memo/entity/CompetencyRelationship.java @@ -1,17 +1,14 @@ package de.tum.cit.memo.entity; -import de.tum.cit.memo.enums.RelationshipType; +import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.persistence.Column; import jakarta.persistence.Entity; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -19,6 +16,7 @@ import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDeleteAction; +import org.hibernate.annotations.UpdateTimestamp; import java.time.Instant; @@ -34,11 +32,6 @@ public class CompetencyRelationship { @Column(length = 30) private String id; - @Enumerated(EnumType.STRING) - @Column(name = "relationship_type", nullable = false) - @NotNull - private RelationshipType relationshipType; - @NotBlank @Column(name = "origin_id", nullable = false, length = 30) private String originId; @@ -47,25 +40,79 @@ public class CompetencyRelationship { @Column(name = "destination_id", nullable = false, length = 30) private String destinationId; - @NotBlank - @Column(name = "user_id", nullable = false, length = 30) - private String userId; + // Aggregated vote counters + @Column(name = "vote_assumes", nullable = false) + @Builder.Default + private Integer voteAssumes = 0; + + @Column(name = "vote_extends", nullable = false) + @Builder.Default + private Integer voteExtends = 0; + + @Column(name = "vote_matches", nullable = false) + @Builder.Default + private Integer voteMatches = 0; + + @Column(name = "vote_unrelated", nullable = false) + @Builder.Default + private Integer voteUnrelated = 0; + + // Precomputed entropy for consensus scheduling + @Column(name = "entropy", nullable = false) + @Builder.Default + private Double entropy = 0.0; + + // Total votes (denormalized for convenience) + @Column(name = "total_votes", nullable = false) + @Builder.Default + private Integer totalVotes = 0; + // Relationships (ignored in JSON to avoid proxy serialization issues) + @JsonIgnore @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "origin_id", insertable = false, updatable = false) @OnDelete(action = OnDeleteAction.CASCADE) private Competency origin; + @JsonIgnore @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "destination_id", insertable = false, updatable = false) @OnDelete(action = OnDeleteAction.CASCADE) private Competency destination; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "user_id", insertable = false, updatable = false) - private User user; - @CreationTimestamp @Column(nullable = false, updatable = false) private Instant createdAt; + + @UpdateTimestamp + @Column(nullable = false) + private Instant updatedAt; + + /** + * Recalculates entropy based on current vote distribution. + * Entropy ranges from 0 (unanimous) to ~2.0 (max disagreement with 4 types). + */ + public void recalculateEntropy() { + int total = voteAssumes + voteExtends + voteMatches + voteUnrelated; + this.totalVotes = total; + + if (total == 0) { + this.entropy = 0.0; + return; + } + + double ent = 0.0; + int[] counts = new int[4]; + counts[0] = voteAssumes; + counts[1] = voteExtends; + counts[2] = voteMatches; + counts[3] = voteUnrelated; + for (int count : counts) { + if (count > 0) { + double p = (double) count / total; + ent -= p * (Math.log(p) / Math.log(2)); + } + } + this.entropy = ent; + } } diff --git a/server/src/main/java/de/tum/cit/memo/entity/CompetencyRelationshipVote.java b/server/src/main/java/de/tum/cit/memo/entity/CompetencyRelationshipVote.java new file mode 100644 index 0000000..91af636 --- /dev/null +++ b/server/src/main/java/de/tum/cit/memo/entity/CompetencyRelationshipVote.java @@ -0,0 +1,63 @@ +package de.tum.cit.memo.entity; + +import de.tum.cit.memo.enums.RelationshipType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.CreationTimestamp; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; + +import java.time.Instant; + +@Entity +@Table(name = "competency_relationships_votes") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class CompetencyRelationshipVote { + + @Id + @Column(length = 30) + private String id; + + @NotBlank + @Column(name = "relationship_id", nullable = false, length = 30) + private String relationshipId; + + @NotBlank + @Column(name = "user_id", nullable = false, length = 30) + private String userId; + + @Enumerated(EnumType.STRING) + @Column(name = "relationship_type", nullable = false) + @NotNull + private RelationshipType relationshipType; + + // Relationships + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "relationship_id", insertable = false, updatable = false) + @OnDelete(action = OnDeleteAction.CASCADE) + private CompetencyRelationship relationship; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", insertable = false, updatable = false) + private User user; + + @CreationTimestamp + @Column(nullable = false, updatable = false) + private Instant createdAt; +} diff --git a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java index 520a0ce..9c411ba 100644 --- a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java +++ b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java @@ -1,24 +1,76 @@ package de.tum.cit.memo.repository; import de.tum.cit.memo.entity.CompetencyRelationship; -import de.tum.cit.memo.enums.RelationshipType; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.Optional; @Repository public interface CompetencyRelationshipRepository extends JpaRepository { - Optional findByOriginIdAndDestinationIdAndRelationshipType( - String originId, - String destinationId, - RelationshipType relationshipType - ); - - boolean existsByOriginIdAndDestinationIdAndRelationshipType( - String originId, - String destinationId, - RelationshipType relationshipType - ); + Optional findByOriginIdAndDestinationId(String originId, String destinationId); + + boolean existsByOriginIdAndDestinationId(String originId, String destinationId); + + /** + * Find high-entropy relationships that the user has not yet voted on. + */ + @Query(""" + SELECT r FROM CompetencyRelationship r + WHERE r.totalVotes BETWEEN :minVotes AND :maxVotes + AND r.entropy > :minEntropy + AND NOT EXISTS ( + SELECT 1 FROM CompetencyRelationshipVote v + WHERE v.relationshipId = r.id AND v.userId = :userId + ) + ORDER BY r.entropy DESC + """) + List findHighEntropyRelationshipsExcludingUser( + @Param("userId") String userId, + @Param("minVotes") int minVotes, + @Param("maxVotes") int maxVotes, + @Param("minEntropy") double minEntropy); + + /** + * Get competency degrees (number of relationships each competency appears in). + * Returns pairs of [competencyId, degree]. + */ + @Query(value = """ + SELECT cid, SUM(cnt) as degree FROM ( + SELECT origin_id AS cid, COUNT(*) AS cnt FROM competency_relationships GROUP BY origin_id + UNION ALL + SELECT destination_id AS cid, COUNT(*) AS cnt FROM competency_relationships GROUP BY destination_id + ) sub + GROUP BY cid + ORDER BY degree ASC + LIMIT :limit + """, nativeQuery = true) + List findLowDegreeCompetencyIds(@Param("limit") int limit); + + /** + * Find all relationships where user has NOT voted, for filtering. + */ + /** + * Find all relationships involving any of the given competency IDs. + * Used for batch processing in Coverage Pipeline to avoid N+1 queries. + */ + @Query("SELECT r FROM CompetencyRelationship r WHERE r.origin.id IN :ids OR r.destination.id IN :ids") + List findAllByCompetencyIds(@Param("ids") List ids); + + /** + * Find all relationships where user has NOT voted, for filtering. + * Optimized with NOT EXISTS + */ + @Query(""" + SELECT r.id FROM CompetencyRelationship r + WHERE NOT EXISTS ( + SELECT 1 FROM CompetencyRelationshipVote v + WHERE v.relationshipId = r.id AND v.userId = :userId + ) + """) + List findRelationshipIdsExcludingUser(@Param("userId") String userId); } diff --git a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipVoteRepository.java b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipVoteRepository.java new file mode 100644 index 0000000..d95fd3c --- /dev/null +++ b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipVoteRepository.java @@ -0,0 +1,20 @@ +package de.tum.cit.memo.repository; + +import de.tum.cit.memo.entity.CompetencyRelationshipVote; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface CompetencyRelationshipVoteRepository extends JpaRepository { + + Optional findByRelationshipIdAndUserId(String relationshipId, String userId); + + boolean existsByRelationshipIdAndUserId(String relationshipId, String userId); + + List findByRelationshipId(String relationshipId); + + List findByUserId(String userId); +} diff --git a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java index 50e70da..4ee5d3e 100644 --- a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java +++ b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java @@ -13,4 +13,10 @@ public interface CompetencyRepository extends JpaRepository @Query(value = "SELECT * FROM competencies ORDER BY RANDOM() LIMIT :count", nativeQuery = true) List findRandomCompetencies(@Param("count") int count); + + List findTop30ByOrderByDegreeAsc(); + + @org.springframework.data.jpa.repository.Modifying(flushAutomatically = true, clearAutomatically = true) + @Query("UPDATE Competency c SET c.degree = c.degree + 1 WHERE c.id IN :ids") + void incrementDegree(@Param("ids") List ids); } diff --git a/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java b/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java index 055465d..fc83e39 100644 --- a/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java +++ b/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java @@ -1,10 +1,11 @@ package de.tum.cit.memo.service; -import de.tum.cit.memo.dto.CreateCompetencyRelationshipRequest; +import de.tum.cit.memo.entity.Competency; import de.tum.cit.memo.entity.CompetencyRelationship; import de.tum.cit.memo.exception.InvalidOperationException; import de.tum.cit.memo.exception.ResourceNotFoundException; import de.tum.cit.memo.repository.CompetencyRelationshipRepository; +import de.tum.cit.memo.repository.CompetencyRepository; import de.tum.cit.memo.util.IdGenerator; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -12,34 +13,78 @@ import java.util.List; +/** + * Service for basic CRUD operations on competency relationships. + * For voting and scheduling, use {@link SchedulingService} instead. + */ @Service @RequiredArgsConstructor @SuppressWarnings("null") public class CompetencyRelationshipService { private final CompetencyRelationshipRepository relationshipRepository; + private final CompetencyRepository competencyRepository; + /** + * Create a new empty relationship (used for administrative purposes). + * Also updates the degree counter for both competencies. + * For normal user voting flow, use SchedulingService. + */ @Transactional - public CompetencyRelationship createRelationship(CreateCompetencyRelationshipRequest request) { - if (request.getOriginId().equals(request.getDestinationId())) { + public CompetencyRelationship createRelationship(String originId, String destinationId) { + if (originId.equals(destinationId)) { throw new InvalidOperationException("Cannot create relationship to itself"); } + if (relationshipRepository.existsByOriginIdAndDestinationId(originId, destinationId)) { + throw new InvalidOperationException("Relationship already exists"); + } + CompetencyRelationship relationship = CompetencyRelationship.builder() - .id(IdGenerator.generateCuid()) - .relationshipType(request.getRelationshipType()) - .originId(request.getOriginId()) - .destinationId(request.getDestinationId()) - .userId(request.getUserId()) - .build(); + .id(IdGenerator.generateCuid()) + .originId(originId) + .destinationId(destinationId) + .build(); + + // Update the denormalized degree counter for both competencies + List competencies = competencyRepository.findAllById(List.of(originId, destinationId)); + competencies.forEach(c -> c.setDegree(c.getDegree() + 1)); + competencyRepository.saveAll(competencies); return relationshipRepository.save(relationship); } + /** + * Find existing relationship or create a new one. + * When creating a new relationship, also updates the degree counter for both competencies. + */ + @Transactional + public CompetencyRelationship findOrCreateRelationship(String originId, String destinationId) { + if (originId.equals(destinationId)) { + throw new InvalidOperationException("Cannot create relationship to itself"); + } + + return relationshipRepository.findByOriginIdAndDestinationId(originId, destinationId) + .orElseGet(() -> { + CompetencyRelationship relationship = CompetencyRelationship.builder() + .id(IdGenerator.generateCuid()) + .originId(originId) + .destinationId(destinationId) + .build(); + + // Update the denormalized degree counter for both competencies + List competencies = competencyRepository.findAllById(List.of(originId, destinationId)); + competencies.forEach(c -> c.setDegree(c.getDegree() + 1)); + competencyRepository.saveAll(competencies); + + return relationshipRepository.save(relationship); + }); + } + @Transactional(readOnly = true) public CompetencyRelationship getRelationshipById(String id) { return relationshipRepository.findById(id) - .orElseThrow(() -> new ResourceNotFoundException("Relationship not found")); + .orElseThrow(() -> new ResourceNotFoundException("Relationship not found")); } @Transactional(readOnly = true) diff --git a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java new file mode 100644 index 0000000..ae52588 --- /dev/null +++ b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java @@ -0,0 +1,299 @@ +package de.tum.cit.memo.service; + +import de.tum.cit.memo.dto.RelationshipTaskResponse; +import de.tum.cit.memo.dto.VoteRequest; +import de.tum.cit.memo.dto.VoteResponse; +import de.tum.cit.memo.entity.Competency; +import de.tum.cit.memo.entity.CompetencyRelationship; +import de.tum.cit.memo.entity.CompetencyRelationshipVote; +import de.tum.cit.memo.enums.RelationshipType; +import de.tum.cit.memo.exception.InvalidOperationException; +import de.tum.cit.memo.exception.ResourceNotFoundException; +import de.tum.cit.memo.repository.CompetencyRelationshipRepository; +import de.tum.cit.memo.repository.CompetencyRelationshipVoteRepository; +import de.tum.cit.memo.repository.CompetencyRepository; +import de.tum.cit.memo.util.IdGenerator; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Random; +import java.util.Set; + +/** + * Service for intelligent scheduling of competency mapping tasks. + * Uses a dual-pipeline approach: coverage (70%) and consensus (30%). + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class SchedulingService { + + private static final double COVERAGE_WEIGHT = 0.7; + private static final int LOW_DEGREE_POOL_SIZE = 30; + private static final int CONSENSUS_MIN_VOTES = 5; + private static final int CONSENSUS_MAX_VOTES = 20; + private static final double CONSENSUS_MIN_ENTROPY = 0.5; + + private final CompetencyRelationshipRepository relationshipRepository; + private final CompetencyRelationshipVoteRepository voteRepository; + private final CompetencyRepository competencyRepository; + private final Random random = new Random(); + + /** + * Get the next relationship task for a user. + * Uses 70% coverage pipeline (new pairs) and 30% consensus pipeline + * (high-entropy). + */ + @Transactional + public RelationshipTaskResponse getNextTask(String userId) { + if (random.nextDouble() < COVERAGE_WEIGHT) { + log.debug("Coverage pipeline for user {}", userId); + return coveragePipeline(userId); + } + + log.debug("Consensus pipeline for user {}", userId); + RelationshipTaskResponse task = consensusPipeline(userId); + if (task == null) { + log.debug("Falling back to coverage"); + return coveragePipeline(userId); + } + return task; + } + + @Transactional + public VoteResponse submitVote(String userId, VoteRequest request) { + CompetencyRelationship rel = relationshipRepository.findById(request.getRelationshipId()) + .orElseThrow(() -> new ResourceNotFoundException( + "Relationship not found: " + request.getRelationshipId())); + + // Idempotent: if user already voted, return current state + if (voteRepository.existsByRelationshipIdAndUserId(request.getRelationshipId(), userId)) { + log.debug("User {} already voted on relationship {}", userId, request.getRelationshipId()); + return buildVoteResponse(rel); + } + + // Record the vote + voteRepository.save(CompetencyRelationshipVote.builder() + .id(IdGenerator.generateCuid()) + .relationshipId(request.getRelationshipId()) + .userId(userId) + .relationshipType(request.getRelationshipType()) + .build()); + + // Update counters and entropy + incrementVoteCounter(rel, request.getRelationshipType()); + rel.recalculateEntropy(); + relationshipRepository.save(rel); + + // Handle MATCHES bidirectionality + if (request.getRelationshipType() == RelationshipType.MATCHES) { + handleBidirectionalMatches(rel, userId); + } + + return buildVoteResponse(rel); + } + + private RelationshipTaskResponse coveragePipeline(String userId) { + List poolIds = getLowDegreeCompetencyIds(); + + if (poolIds.size() < 2) { + throw new InvalidOperationException("Not enough competencies to form pairs"); + } + + Set userVotedRelIds = getUserVotedRelationshipIds(userId); + + // Optimization: Batch fetch existing relationships to avoid N+1 queries in the + // loop + // We fetch ALL relationships involving ANY of these 50 nodes in one go. + List existingRels = relationshipRepository.findAllByCompetencyIds(poolIds); + + // Build a fast lookup set "A:B" and "B:A" + Set existingPairs = existingRels.stream() + .flatMap(r -> java.util.stream.Stream.of( + r.getOriginId() + ":" + r.getDestinationId(), + r.getDestinationId() + ":" + r.getOriginId())) + .collect(java.util.stream.Collectors.toSet()); + + // Try to find a new pair that doesn't exist yet (in-memory check) + List shuffledPool = new ArrayList<>(poolIds); + Collections.shuffle(shuffledPool, random); + + for (int i = 0; i < shuffledPool.size(); i++) { + for (int j = i + 1; j < shuffledPool.size(); j++) { + String originId = shuffledPool.get(i); + String destId = shuffledPool.get(j); + + // O(1) in-memory check instead of O(N) DB call + if (!existingPairs.contains(originId + ":" + destId)) { + CompetencyRelationship rel = createRelationship(originId, destId); + return buildTaskResponse(rel, "COVERAGE"); + } + } + } + + // All pairs exist, find one user hasn't voted on + log.debug("All candidate pairs exist, finding unvoted relationship"); + return findUnvotedRelationship(userVotedRelIds); + } + + private RelationshipTaskResponse consensusPipeline(String userId) { + List candidates = relationshipRepository + .findHighEntropyRelationshipsExcludingUser( + userId, CONSENSUS_MIN_VOTES, CONSENSUS_MAX_VOTES, CONSENSUS_MIN_ENTROPY); + + if (candidates.isEmpty()) { + return null; + } + + // Weighted random selection by entropy (higher entropy = more weight) + CompetencyRelationship selected = selectByEntropyWeight(candidates); + return buildTaskResponse(selected, "CONSENSUS"); + } + + // Helper Methods + + private List getLowDegreeCompetencyIds() { + // Optimized: Uses denormalized degree index (single simple query) O(1) + List nodes = competencyRepository.findTop30ByOrderByDegreeAsc(); + + if (nodes.isEmpty()) { + return competencyRepository.findRandomCompetencies(LOW_DEGREE_POOL_SIZE) + .stream().map(Competency::getId).toList(); + } + return nodes.stream().map(Competency::getId).toList(); + } + + private Set getUserVotedRelationshipIds(String userId) { + return new HashSet<>(voteRepository.findByUserId(userId).stream() + .map(CompetencyRelationshipVote::getRelationshipId).toList()); + } + + private CompetencyRelationship createRelationship(String originId, String destId) { + CompetencyRelationship rel = CompetencyRelationship.builder() + .id(IdGenerator.generateCuid()) + .originId(originId) + .destinationId(destId) + .build(); + + // Critical: Maintain the denormalized degree count + // Critical: Maintain the denormalized degree count (Java-side update for + // reliability) + List competencies = competencyRepository.findAllById(List.of(originId, destId)); + competencies.forEach(c -> c.setDegree(c.getDegree() + 1)); + competencyRepository.saveAll(competencies); + + return relationshipRepository.save(rel); + } + + private RelationshipTaskResponse findUnvotedRelationship(Set userVotedRelIds) { + for (CompetencyRelationship rel : relationshipRepository.findAll()) { + if (!userVotedRelIds.contains(rel.getId())) { + return buildTaskResponse(rel, "COVERAGE"); + } + } + throw new InvalidOperationException("No available relationships for voting"); + } + + private CompetencyRelationship selectByEntropyWeight(List candidates) { + double totalWeight = candidates.stream() + .mapToDouble(r -> r.getEntropy() / (r.getTotalVotes() + 1.0)) + .sum(); + double roll = random.nextDouble() * totalWeight; + double cumulative = 0; + + for (CompetencyRelationship rel : candidates) { + cumulative += rel.getEntropy() / (rel.getTotalVotes() + 1.0); + if (roll <= cumulative) { + return rel; + } + } + return candidates.get(0); + } + + private void handleBidirectionalMatches(CompetencyRelationship originalRel, String userId) { + Optional reverseOpt = relationshipRepository + .findByOriginIdAndDestinationId(originalRel.getDestinationId(), originalRel.getOriginId()); + + CompetencyRelationship reverse = reverseOpt.orElseGet(() -> createRelationship( + originalRel.getDestinationId(), originalRel.getOriginId())); + + if (!voteRepository.existsByRelationshipIdAndUserId(reverse.getId(), userId)) { + reverse.setVoteMatches(reverse.getVoteMatches() + 1); + reverse.recalculateEntropy(); + relationshipRepository.save(reverse); + + voteRepository.save(CompetencyRelationshipVote.builder() + .id(IdGenerator.generateCuid()) + .relationshipId(reverse.getId()) + .userId(userId) + .relationshipType(RelationshipType.MATCHES) + .build()); + } + } + + private void incrementVoteCounter(CompetencyRelationship rel, RelationshipType type) { + switch (type) { + case ASSUMES -> rel.setVoteAssumes(rel.getVoteAssumes() + 1); + case EXTENDS -> rel.setVoteExtends(rel.getVoteExtends() + 1); + case MATCHES -> rel.setVoteMatches(rel.getVoteMatches() + 1); + case UNRELATED -> rel.setVoteUnrelated(rel.getVoteUnrelated() + 1); + } + } + + // Response Builders + private VoteResponse buildVoteResponse(CompetencyRelationship rel) { + return VoteResponse.builder() + .success(true) + .updatedVotes(buildVoteResponseCounts(rel)) + .newEntropy(rel.getEntropy()) + .build(); + } + + private VoteResponse.VoteCounts buildVoteResponseCounts(CompetencyRelationship rel) { + return VoteResponse.VoteCounts.builder() + .assumes(rel.getVoteAssumes()) + .extendsRelation(rel.getVoteExtends()) + .matches(rel.getVoteMatches()) + .unrelated(rel.getVoteUnrelated()) + .build(); + } + + private RelationshipTaskResponse buildTaskResponse(CompetencyRelationship rel, String pipeline) { + Competency origin = competencyRepository.findById(rel.getOriginId()) + .orElseThrow(() -> new ResourceNotFoundException("Origin competency not found")); + Competency destination = competencyRepository.findById(rel.getDestinationId()) + .orElseThrow(() -> new ResourceNotFoundException("Destination competency not found")); + + return RelationshipTaskResponse.builder() + .relationshipId(rel.getId()) + .origin(buildCompetencyInfo(origin)) + .destination(buildCompetencyInfo(destination)) + .pipeline(pipeline) + .currentVotes(buildTaskResponseCounts(rel)) + .build(); + } + + private RelationshipTaskResponse.CompetencyInfo buildCompetencyInfo(Competency c) { + return RelationshipTaskResponse.CompetencyInfo.builder() + .id(c.getId()) + .title(c.getTitle()) + .description(c.getDescription()) + .build(); + } + + private RelationshipTaskResponse.VoteCounts buildTaskResponseCounts(CompetencyRelationship rel) { + return RelationshipTaskResponse.VoteCounts.builder() + .assumes(rel.getVoteAssumes()) + .extendsRelation(rel.getVoteExtends()) + .matches(rel.getVoteMatches()) + .unrelated(rel.getVoteUnrelated()) + .build(); + } +} diff --git a/server/src/main/resources/db/migration/V2__seed_sample_data.sql b/server/src/main/resources/db/migration/V2__seed_sample_data.sql index 2a68f84..96ce707 100644 --- a/server/src/main/resources/db/migration/V2__seed_sample_data.sql +++ b/server/src/main/resources/db/migration/V2__seed_sample_data.sql @@ -31,12 +31,6 @@ INSERT INTO learning_resources (id, title, url, created_at) VALUES ('res_types_001', 'On Understanding Types, Data Abstraction, and Polymorphism', 'https://dl.acm.org/doi/10.1145/6041.6042', CURRENT_TIMESTAMP) ON CONFLICT DO NOTHING; --- Seed competency relationships (examples) -INSERT INTO competency_relationships (id, relationship_type, origin_id, destination_id, user_id, created_at) VALUES -('rel_ds_fp_001', 'ASSUMES', 'comp_fp_001', 'comp_ds_001', 'user_demo_001', CURRENT_TIMESTAMP), -('rel_hof_fp_001', 'EXTENDS', 'comp_hof_001', 'comp_fp_001', 'user_demo_001', CURRENT_TIMESTAMP), -('rel_mod_poly_001', 'ASSUMES', 'comp_mod_001', 'comp_poly_001', 'user_demo_001', CURRENT_TIMESTAMP) -ON CONFLICT (origin_id, destination_id, relationship_type) DO NOTHING; -- Seed competency-resource links (examples) INSERT INTO competency_resource_links (id, competency_id, resource_id, user_id, created_at) VALUES diff --git a/server/src/main/resources/db/migration/V5__drop_old_relationships.sql b/server/src/main/resources/db/migration/V5__drop_old_relationships.sql new file mode 100644 index 0000000..3e8123f --- /dev/null +++ b/server/src/main/resources/db/migration/V5__drop_old_relationships.sql @@ -0,0 +1,10 @@ +-- Drop old competency_relationships table and related constraints +-- Platform is in development; existing votes can be discarded + +-- First drop the foreign key constraints +ALTER TABLE IF EXISTS "competency_relationships" DROP CONSTRAINT IF EXISTS "competency_relationships_originId_fkey"; +ALTER TABLE IF EXISTS "competency_relationships" DROP CONSTRAINT IF EXISTS "competency_relationships_destinationId_fkey"; +ALTER TABLE IF EXISTS "competency_relationships" DROP CONSTRAINT IF EXISTS "competency_relationships_userId_fkey"; + +-- Drop the table +DROP TABLE IF EXISTS "competency_relationships"; diff --git a/server/src/main/resources/db/migration/V6__create_scheduling_tables.sql b/server/src/main/resources/db/migration/V6__create_scheduling_tables.sql new file mode 100644 index 0000000..45f657b --- /dev/null +++ b/server/src/main/resources/db/migration/V6__create_scheduling_tables.sql @@ -0,0 +1,62 @@ +-- Create scheduling tables for competency mapping + +-- competency_relationships: One row per unique (origin, destination) pair +-- Stores aggregated vote counters and precomputed entropy for scheduling +CREATE TABLE "competency_relationships" ( + "id" VARCHAR(30) NOT NULL, + "origin_id" VARCHAR(30) NOT NULL, + "destination_id" VARCHAR(30) NOT NULL, + + -- Aggregated vote counters (denormalized for fast reads) + "vote_assumes" INT NOT NULL DEFAULT 0, + "vote_extends" INT NOT NULL DEFAULT 0, + "vote_matches" INT NOT NULL DEFAULT 0, + "vote_unrelated" INT NOT NULL DEFAULT 0, + + -- Precomputed entropy for consensus priority (0.0 = unanimous, ~2.0 = max disagreement) + "entropy" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + + -- Total votes = vote_assumes + vote_extends + vote_matches + vote_unrelated + "total_votes" INT NOT NULL DEFAULT 0, + + "created_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "competency_relationships_pkey" PRIMARY KEY ("id"), + CONSTRAINT "uk_relationship_pair" UNIQUE ("origin_id", "destination_id"), + CONSTRAINT "chk_origin_ne_dest" CHECK ("origin_id" <> "destination_id") +); + +-- competency_relationships_votes: Raw vote log (one vote per user per relationship) +CREATE TABLE "competency_relationships_votes" ( + "id" VARCHAR(30) NOT NULL, + "relationship_id" VARCHAR(30) NOT NULL, + "user_id" VARCHAR(30) NOT NULL, + "relationship_type" VARCHAR(20) NOT NULL, + "created_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "competency_relationships_votes_pkey" PRIMARY KEY ("id"), + CONSTRAINT "uk_relationship_user" UNIQUE ("relationship_id", "user_id") +); + +-- Indexes for efficient scheduling queries +CREATE INDEX "idx_rel_entropy" ON "competency_relationships"("entropy" DESC) WHERE "total_votes" > 0; +CREATE INDEX "idx_rel_total_votes" ON "competency_relationships"("total_votes"); +CREATE INDEX "idx_rel_origin" ON "competency_relationships"("origin_id"); +CREATE INDEX "idx_rel_dest" ON "competency_relationships"("destination_id"); + +CREATE INDEX "idx_votes_rel" ON "competency_relationships_votes"("relationship_id"); +CREATE INDEX "idx_votes_user" ON "competency_relationships_votes"("user_id"); + +-- Foreign keys +ALTER TABLE "competency_relationships" ADD CONSTRAINT "fk_rel_origin" + FOREIGN KEY ("origin_id") REFERENCES "competencies"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +ALTER TABLE "competency_relationships" ADD CONSTRAINT "fk_rel_dest" + FOREIGN KEY ("destination_id") REFERENCES "competencies"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +ALTER TABLE "competency_relationships_votes" ADD CONSTRAINT "fk_vote_relationship" + FOREIGN KEY ("relationship_id") REFERENCES "competency_relationships"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +ALTER TABLE "competency_relationships_votes" ADD CONSTRAINT "fk_vote_user" + FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/server/src/main/resources/db/migration/V7__add_competency_degree.sql b/server/src/main/resources/db/migration/V7__add_competency_degree.sql new file mode 100644 index 0000000..30d981b --- /dev/null +++ b/server/src/main/resources/db/migration/V7__add_competency_degree.sql @@ -0,0 +1,19 @@ +-- Add degree column +ALTER TABLE competencies ADD COLUMN degree INTEGER DEFAULT 0 NOT NULL; + +-- Create index for fast retrieval of low-degree nodes +CREATE INDEX idx_competencies_degree ON competencies(degree); + +-- Backfill existing degrees +WITH calculated_degrees AS ( + SELECT cid, SUM(cnt) as total_degree FROM ( + SELECT origin_id AS cid, COUNT(*) AS cnt FROM competency_relationships GROUP BY origin_id + UNION ALL + SELECT destination_id AS cid, COUNT(*) AS cnt FROM competency_relationships GROUP BY destination_id + ) sub + GROUP BY cid +) +UPDATE competencies c +SET degree = cd.total_degree +FROM calculated_degrees cd +WHERE c.id = cd.cid; From 8850cf6bfdc56ed77b515d4086fa16e542177db4 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 3 Feb 2026 10:12:45 +0100 Subject: [PATCH 05/57] style: update comments --- .../main/java/de/tum/cit/memo/service/SchedulingService.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java index ae52588..550cf0e 100644 --- a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java +++ b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java @@ -182,9 +182,6 @@ private CompetencyRelationship createRelationship(String originId, String destId .destinationId(destId) .build(); - // Critical: Maintain the denormalized degree count - // Critical: Maintain the denormalized degree count (Java-side update for - // reliability) List competencies = competencyRepository.findAllById(List.of(originId, destId)); competencies.forEach(c -> c.setDegree(c.getDegree() + 1)); competencyRepository.saveAll(competencies); From fe676c3964227e802706a105929b30d927f07ae8 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 10 Feb 2026 00:34:15 +0100 Subject: [PATCH 06/57] Implement AI suggestions --- .../memo/controller/SchedulingController.java | 4 ++-- .../CompetencyRelationshipRepository.java | 11 ++++++----- .../tum/cit/memo/service/SchedulingService.java | 17 ++++++++--------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java b/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java index 681c82b..caecf4f 100644 --- a/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java +++ b/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java @@ -27,7 +27,7 @@ public class SchedulingController { @GetMapping("/next-relationship") @Operation(summary = "Get next relationship to vote on", description = "Returns a competency pair for the user to map. Uses coverage (70%) and consensus (30%) pipelines.") public ResponseEntity getNextRelationship( - @RequestHeader(value = "X-User-Id", required = false, defaultValue = "anonymous") String userId) { + @RequestHeader("X-User-Id") String userId) { RelationshipTaskResponse task = schedulingService.getNextTask(userId); return ResponseEntity.ok(task); } @@ -35,7 +35,7 @@ public ResponseEntity getNextRelationship( @PostMapping("/vote") @Operation(summary = "Submit a vote on a relationship", description = "Records the user's vote on a competency relationship. MATCHES votes are bidirectional.") public ResponseEntity submitVote( - @RequestHeader(value = "X-User-Id", required = false, defaultValue = "anonymous") String userId, + @RequestHeader("X-User-Id") String userId, @Valid @RequestBody VoteRequest request) { VoteResponse response = schedulingService.submitVote(userId, request); return ResponseEntity.ok(response); diff --git a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java index 9c411ba..86b12f8 100644 --- a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java +++ b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java @@ -58,19 +58,20 @@ SELECT destination_id AS cid, COUNT(*) AS cnt FROM competency_relationships GROU * Find all relationships involving any of the given competency IDs. * Used for batch processing in Coverage Pipeline to avoid N+1 queries. */ - @Query("SELECT r FROM CompetencyRelationship r WHERE r.origin.id IN :ids OR r.destination.id IN :ids") + @Query("SELECT r FROM CompetencyRelationship r WHERE r.originId IN :ids OR r.destinationId IN :ids") List findAllByCompetencyIds(@Param("ids") List ids); /** - * Find all relationships where user has NOT voted, for filtering. - * Optimized with NOT EXISTS + * Find a single relationship the user has NOT voted on. + * Uses LIMIT 1 to avoid loading the entire table. */ @Query(""" - SELECT r.id FROM CompetencyRelationship r + SELECT r FROM CompetencyRelationship r WHERE NOT EXISTS ( SELECT 1 FROM CompetencyRelationshipVote v WHERE v.relationshipId = r.id AND v.userId = :userId ) """) - List findRelationshipIdsExcludingUser(@Param("userId") String userId); + Optional findFirstUnvotedByUser(@Param("userId") String userId, + org.springframework.data.domain.Pageable pageable); } diff --git a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java index 550cf0e..17847cd 100644 --- a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java +++ b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java @@ -111,7 +111,8 @@ private RelationshipTaskResponse coveragePipeline(String userId) { // Optimization: Batch fetch existing relationships to avoid N+1 queries in the // loop - // We fetch ALL relationships involving ANY of these 50 nodes in one go. + // We fetch ALL relationships involving ANY of the nodes in the low-degree pool + // in one go. List existingRels = relationshipRepository.findAllByCompetencyIds(poolIds); // Build a fast lookup set "A:B" and "B:A" @@ -140,7 +141,7 @@ private RelationshipTaskResponse coveragePipeline(String userId) { // All pairs exist, find one user hasn't voted on log.debug("All candidate pairs exist, finding unvoted relationship"); - return findUnvotedRelationship(userVotedRelIds); + return findUnvotedRelationship(userId); } private RelationshipTaskResponse consensusPipeline(String userId) { @@ -189,13 +190,11 @@ private CompetencyRelationship createRelationship(String originId, String destId return relationshipRepository.save(rel); } - private RelationshipTaskResponse findUnvotedRelationship(Set userVotedRelIds) { - for (CompetencyRelationship rel : relationshipRepository.findAll()) { - if (!userVotedRelIds.contains(rel.getId())) { - return buildTaskResponse(rel, "COVERAGE"); - } - } - throw new InvalidOperationException("No available relationships for voting"); + private RelationshipTaskResponse findUnvotedRelationship(String userId) { + return relationshipRepository + .findFirstUnvotedByUser(userId, org.springframework.data.domain.PageRequest.of(0, 1)) + .map(rel -> buildTaskResponse(rel, "COVERAGE")) + .orElseThrow(() -> new InvalidOperationException("No available relationships for voting")); } private CompetencyRelationship selectByEntropyWeight(List candidates) { From b199432d7d43a39608c90ebb7a83fc0f7f54b84c Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 10 Feb 2026 00:44:36 +0100 Subject: [PATCH 07/57] Update Axios, Optimise scheduling pipeline --- package-lock.json | 10 +++++----- .../cit/memo/repository/CompetencyRepository.java | 2 +- .../service/CompetencyRelationshipService.java | 15 +++++++++++---- .../tum/cit/memo/service/SchedulingService.java | 13 +++---------- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index e324a36..b66b3d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2611,13 +2611,13 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", - "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", + "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, diff --git a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java index 4ee5d3e..e7cf7be 100644 --- a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java +++ b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java @@ -14,7 +14,7 @@ public interface CompetencyRepository extends JpaRepository @Query(value = "SELECT * FROM competencies ORDER BY RANDOM() LIMIT :count", nativeQuery = true) List findRandomCompetencies(@Param("count") int count); - List findTop30ByOrderByDegreeAsc(); + List findTop20ByOrderByDegreeAsc(); @org.springframework.data.jpa.repository.Modifying(flushAutomatically = true, clearAutomatically = true) @Query("UPDATE Competency c SET c.degree = c.degree + 1 WHERE c.id IN :ids") diff --git a/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java b/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java index fc83e39..9ea7a39 100644 --- a/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java +++ b/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java @@ -56,7 +56,8 @@ public CompetencyRelationship createRelationship(String originId, String destina /** * Find existing relationship or create a new one. - * When creating a new relationship, also updates the degree counter for both competencies. + * When creating a new relationship, also updates the degree counter for both + * competencies. */ @Transactional public CompetencyRelationship findOrCreateRelationship(String originId, String destinationId) { @@ -94,9 +95,15 @@ public List getAllRelationships() { @Transactional public void deleteRelationship(String id) { - if (!relationshipRepository.existsById(id)) { - throw new ResourceNotFoundException("Relationship not found"); - } + CompetencyRelationship relationship = relationshipRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("Relationship not found")); + + // Decrement the denormalized degree counter for both competencies + List competencies = competencyRepository + .findAllById(List.of(relationship.getOriginId(), relationship.getDestinationId())); + competencies.forEach(c -> c.setDegree(Math.max(0, c.getDegree() - 1))); + competencyRepository.saveAll(competencies); + relationshipRepository.deleteById(id); } } diff --git a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java index 17847cd..8145fc5 100644 --- a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java +++ b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java @@ -20,7 +20,7 @@ import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; + import java.util.List; import java.util.Optional; import java.util.Random; @@ -36,7 +36,7 @@ public class SchedulingService { private static final double COVERAGE_WEIGHT = 0.7; - private static final int LOW_DEGREE_POOL_SIZE = 30; + private static final int LOW_DEGREE_POOL_SIZE = 20; private static final int CONSENSUS_MIN_VOTES = 5; private static final int CONSENSUS_MAX_VOTES = 20; private static final double CONSENSUS_MIN_ENTROPY = 0.5; @@ -107,8 +107,6 @@ private RelationshipTaskResponse coveragePipeline(String userId) { throw new InvalidOperationException("Not enough competencies to form pairs"); } - Set userVotedRelIds = getUserVotedRelationshipIds(userId); - // Optimization: Batch fetch existing relationships to avoid N+1 queries in the // loop // We fetch ALL relationships involving ANY of the nodes in the low-degree pool @@ -162,7 +160,7 @@ private RelationshipTaskResponse consensusPipeline(String userId) { private List getLowDegreeCompetencyIds() { // Optimized: Uses denormalized degree index (single simple query) O(1) - List nodes = competencyRepository.findTop30ByOrderByDegreeAsc(); + List nodes = competencyRepository.findTop20ByOrderByDegreeAsc(); if (nodes.isEmpty()) { return competencyRepository.findRandomCompetencies(LOW_DEGREE_POOL_SIZE) @@ -171,11 +169,6 @@ private List getLowDegreeCompetencyIds() { return nodes.stream().map(Competency::getId).toList(); } - private Set getUserVotedRelationshipIds(String userId) { - return new HashSet<>(voteRepository.findByUserId(userId).stream() - .map(CompetencyRelationshipVote::getRelationshipId).toList()); - } - private CompetencyRelationship createRelationship(String originId, String destId) { CompetencyRelationship rel = CompetencyRelationship.builder() .id(IdGenerator.generateCuid()) From 67d6e58d70c1520130650c15b5e0a4505611e0a8 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 10 Feb 2026 01:00:19 +0100 Subject: [PATCH 08/57] Optimise pipeline logic and clean up code --- .../CompetencyRelationshipRepository.java | 36 +-- .../memo/repository/CompetencyRepository.java | 7 +- .../CompetencyRelationshipService.java | 33 +-- .../cit/memo/service/SchedulingService.java | 259 +++++++++--------- 4 files changed, 156 insertions(+), 179 deletions(-) diff --git a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java index 86b12f8..0aa41b9 100644 --- a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java +++ b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java @@ -17,7 +17,8 @@ public interface CompetencyRelationshipRepository extends JpaRepository findHighEntropyRelationshipsExcludingUser( @Param("userId") String userId, @Param("minVotes") int minVotes, @Param("maxVotes") int maxVotes, - @Param("minEntropy") double minEntropy); - - /** - * Get competency degrees (number of relationships each competency appears in). - * Returns pairs of [competencyId, degree]. - */ - @Query(value = """ - SELECT cid, SUM(cnt) as degree FROM ( - SELECT origin_id AS cid, COUNT(*) AS cnt FROM competency_relationships GROUP BY origin_id - UNION ALL - SELECT destination_id AS cid, COUNT(*) AS cnt FROM competency_relationships GROUP BY destination_id - ) sub - GROUP BY cid - ORDER BY degree ASC - LIMIT :limit - """, nativeQuery = true) - List findLowDegreeCompetencyIds(@Param("limit") int limit); + @Param("minEntropy") double minEntropy, + org.springframework.data.domain.Pageable pageable); /** - * Find all relationships where user has NOT voted, for filtering. - */ - /** - * Find all relationships involving any of the given competency IDs. - * Used for batch processing in Coverage Pipeline to avoid N+1 queries. + * Relationships where both origin AND destination are in the given pool of IDs. */ - @Query("SELECT r FROM CompetencyRelationship r WHERE r.originId IN :ids OR r.destinationId IN :ids") - List findAllByCompetencyIds(@Param("ids") List ids); + @Query("SELECT r FROM CompetencyRelationship r WHERE r.originId IN :ids AND r.destinationId IN :ids") + List findIntraPoolRelationships(@Param("ids") List ids); /** - * Find a single relationship the user has NOT voted on. - * Uses LIMIT 1 to avoid loading the entire table. + * A single relationship the user hasn't voted on (use with PageRequest.of(0, + * 1)). */ @Query(""" SELECT r FROM CompetencyRelationship r diff --git a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java index e7cf7be..7ed456d 100644 --- a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java +++ b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java @@ -14,9 +14,14 @@ public interface CompetencyRepository extends JpaRepository @Query(value = "SELECT * FROM competencies ORDER BY RANDOM() LIMIT :count", nativeQuery = true) List findRandomCompetencies(@Param("count") int count); - List findTop20ByOrderByDegreeAsc(); + @Query("SELECT c.id FROM Competency c ORDER BY c.degree ASC") + List findTop20IdsByDegreeAsc(org.springframework.data.domain.Pageable pageable); @org.springframework.data.jpa.repository.Modifying(flushAutomatically = true, clearAutomatically = true) @Query("UPDATE Competency c SET c.degree = c.degree + 1 WHERE c.id IN :ids") void incrementDegree(@Param("ids") List ids); + + @org.springframework.data.jpa.repository.Modifying(flushAutomatically = true, clearAutomatically = true) + @Query(value = "UPDATE competencies SET degree = GREATEST(degree - 1, 0) WHERE id IN :ids", nativeQuery = true) + void decrementDegree(@Param("ids") List ids); } diff --git a/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java b/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java index 9ea7a39..4d0c029 100644 --- a/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java +++ b/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java @@ -1,6 +1,5 @@ package de.tum.cit.memo.service; -import de.tum.cit.memo.entity.Competency; import de.tum.cit.memo.entity.CompetencyRelationship; import de.tum.cit.memo.exception.InvalidOperationException; import de.tum.cit.memo.exception.ResourceNotFoundException; @@ -14,8 +13,8 @@ import java.util.List; /** - * Service for basic CRUD operations on competency relationships. - * For voting and scheduling, use {@link SchedulingService} instead. + * CRUD operations on competency relationships. + * For voting and scheduling, see {@link SchedulingService}. */ @Service @RequiredArgsConstructor @@ -26,9 +25,8 @@ public class CompetencyRelationshipService { private final CompetencyRepository competencyRepository; /** - * Create a new empty relationship (used for administrative purposes). - * Also updates the degree counter for both competencies. - * For normal user voting flow, use SchedulingService. + * Creates a new empty relationship (admin use). + * For the normal user voting flow, use SchedulingService. */ @Transactional public CompetencyRelationship createRelationship(String originId, String destinationId) { @@ -46,18 +44,12 @@ public CompetencyRelationship createRelationship(String originId, String destina .destinationId(destinationId) .build(); - // Update the denormalized degree counter for both competencies - List competencies = competencyRepository.findAllById(List.of(originId, destinationId)); - competencies.forEach(c -> c.setDegree(c.getDegree() + 1)); - competencyRepository.saveAll(competencies); - + competencyRepository.incrementDegree(List.of(originId, destinationId)); return relationshipRepository.save(relationship); } /** - * Find existing relationship or create a new one. - * When creating a new relationship, also updates the degree counter for both - * competencies. + * Finds an existing relationship or creates a new one. */ @Transactional public CompetencyRelationship findOrCreateRelationship(String originId, String destinationId) { @@ -73,11 +65,7 @@ public CompetencyRelationship findOrCreateRelationship(String originId, String d .destinationId(destinationId) .build(); - // Update the denormalized degree counter for both competencies - List competencies = competencyRepository.findAllById(List.of(originId, destinationId)); - competencies.forEach(c -> c.setDegree(c.getDegree() + 1)); - competencyRepository.saveAll(competencies); - + competencyRepository.incrementDegree(List.of(originId, destinationId)); return relationshipRepository.save(relationship); }); } @@ -98,12 +86,7 @@ public void deleteRelationship(String id) { CompetencyRelationship relationship = relationshipRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("Relationship not found")); - // Decrement the denormalized degree counter for both competencies - List competencies = competencyRepository - .findAllById(List.of(relationship.getOriginId(), relationship.getDestinationId())); - competencies.forEach(c -> c.setDegree(Math.max(0, c.getDegree() - 1))); - competencyRepository.saveAll(competencies); - + competencyRepository.decrementDegree(List.of(relationship.getOriginId(), relationship.getDestinationId())); relationshipRepository.deleteById(id); } } diff --git a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java index 8145fc5..22f5311 100644 --- a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java +++ b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java @@ -15,20 +15,25 @@ import de.tum.cit.memo.util.IdGenerator; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.Collections; - import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Random; import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** - * Service for intelligent scheduling of competency mapping tasks. - * Uses a dual-pipeline approach: coverage (70%) and consensus (30%). + * Dual-pipeline scheduling for competency mapping tasks. + * Coverage (70%): connects low-degree nodes to grow the graph evenly. + * Consensus (30%): resurfaces ambiguous relationships for more votes. */ @Slf4j @Service @@ -37,6 +42,7 @@ public class SchedulingService { private static final double COVERAGE_WEIGHT = 0.7; private static final int LOW_DEGREE_POOL_SIZE = 20; + private static final int CONSENSUS_CANDIDATE_LIMIT = 20; private static final int CONSENSUS_MIN_VOTES = 5; private static final int CONSENSUS_MAX_VOTES = 20; private static final double CONSENSUS_MIN_ENTROPY = 0.5; @@ -60,113 +66,91 @@ public RelationshipTaskResponse getNextTask(String userId) { log.debug("Consensus pipeline for user {}", userId); RelationshipTaskResponse task = consensusPipeline(userId); - if (task == null) { - log.debug("Falling back to coverage"); - return coveragePipeline(userId); + if (task != null) { + return task; } - return task; + + log.debug("No consensus candidates, falling back to coverage"); + return coveragePipeline(userId); } @Transactional public VoteResponse submitVote(String userId, VoteRequest request) { - CompetencyRelationship rel = relationshipRepository.findById(request.getRelationshipId()) - .orElseThrow(() -> new ResourceNotFoundException( - "Relationship not found: " + request.getRelationshipId())); - - // Idempotent: if user already voted, return current state - if (voteRepository.existsByRelationshipIdAndUserId(request.getRelationshipId(), userId)) { - log.debug("User {} already voted on relationship {}", userId, request.getRelationshipId()); - return buildVoteResponse(rel); - } + CompetencyRelationship rel = findRelationshipOrThrow(request.getRelationshipId()); - // Record the vote - voteRepository.save(CompetencyRelationshipVote.builder() - .id(IdGenerator.generateCuid()) - .relationshipId(request.getRelationshipId()) - .userId(userId) - .relationshipType(request.getRelationshipType()) - .build()); + // Already voted? Return current state (idempotent) + if (voteRepository.existsByRelationshipIdAndUserId(rel.getId(), userId)) { + log.debug("User {} already voted on {}", userId, rel.getId()); + return toVoteResponse(rel); + } - // Update counters and entropy - incrementVoteCounter(rel, request.getRelationshipType()); - rel.recalculateEntropy(); - relationshipRepository.save(rel); + saveVote(rel.getId(), userId, request.getRelationshipType()); + applyVote(rel, request.getRelationshipType()); - // Handle MATCHES bidirectionality if (request.getRelationshipType() == RelationshipType.MATCHES) { - handleBidirectionalMatches(rel, userId); + mirrorMatchesVote(rel, userId); } - return buildVoteResponse(rel); + return toVoteResponse(rel); } + // --- Pipelines --- + private RelationshipTaskResponse coveragePipeline(String userId) { List poolIds = getLowDegreeCompetencyIds(); - if (poolIds.size() < 2) { throw new InvalidOperationException("Not enough competencies to form pairs"); } - // Optimization: Batch fetch existing relationships to avoid N+1 queries in the - // loop - // We fetch ALL relationships involving ANY of the nodes in the low-degree pool - // in one go. - List existingRels = relationshipRepository.findAllByCompetencyIds(poolIds); - - // Build a fast lookup set "A:B" and "B:A" - Set existingPairs = existingRels.stream() - .flatMap(r -> java.util.stream.Stream.of( - r.getOriginId() + ":" + r.getDestinationId(), - r.getDestinationId() + ":" + r.getOriginId())) - .collect(java.util.stream.Collectors.toSet()); - - // Try to find a new pair that doesn't exist yet (in-memory check) - List shuffledPool = new ArrayList<>(poolIds); - Collections.shuffle(shuffledPool, random); - - for (int i = 0; i < shuffledPool.size(); i++) { - for (int j = i + 1; j < shuffledPool.size(); j++) { - String originId = shuffledPool.get(i); - String destId = shuffledPool.get(j); - - // O(1) in-memory check instead of O(N) DB call - if (!existingPairs.contains(originId + ":" + destId)) { - CompetencyRelationship rel = createRelationship(originId, destId); - return buildTaskResponse(rel, "COVERAGE"); + // Fetch only intra-pool relationships (both nodes in pool) + Set existingPairs = relationshipRepository.findIntraPoolRelationships(poolIds).stream() + .flatMap(r -> Stream.of(pairKey(r.getOriginId(), r.getDestinationId()), + pairKey(r.getDestinationId(), r.getOriginId()))) + .collect(Collectors.toSet()); + + // Shuffle and find the first pair that doesn't exist yet + List pool = new ArrayList<>(poolIds); + Collections.shuffle(pool, random); + + for (int i = 0; i < pool.size(); i++) { + for (int j = i + 1; j < pool.size(); j++) { + if (!existingPairs.contains(pairKey(pool.get(i), pool.get(j)))) { + return toTaskResponse(createRelationship(pool.get(i), pool.get(j)), "COVERAGE"); } } } - // All pairs exist, find one user hasn't voted on - log.debug("All candidate pairs exist, finding unvoted relationship"); - return findUnvotedRelationship(userId); + // All pool pairs already exist — fall back to any unvoted relationship + log.debug("Pool fully connected, finding any unvoted relationship"); + return relationshipRepository + .findFirstUnvotedByUser(userId, PageRequest.of(0, 1)) + .map(rel -> toTaskResponse(rel, "COVERAGE")) + .orElseThrow(() -> new InvalidOperationException("No available relationships for voting")); } private RelationshipTaskResponse consensusPipeline(String userId) { List candidates = relationshipRepository .findHighEntropyRelationshipsExcludingUser( - userId, CONSENSUS_MIN_VOTES, CONSENSUS_MAX_VOTES, CONSENSUS_MIN_ENTROPY); + userId, CONSENSUS_MIN_VOTES, CONSENSUS_MAX_VOTES, CONSENSUS_MIN_ENTROPY, + PageRequest.of(0, CONSENSUS_CANDIDATE_LIMIT)); if (candidates.isEmpty()) { return null; } - // Weighted random selection by entropy (higher entropy = more weight) - CompetencyRelationship selected = selectByEntropyWeight(candidates); - return buildTaskResponse(selected, "CONSENSUS"); + return toTaskResponse(pickWeightedByEntropy(candidates), "CONSENSUS"); } - // Helper Methods + // --- Core helpers --- private List getLowDegreeCompetencyIds() { - // Optimized: Uses denormalized degree index (single simple query) O(1) - List nodes = competencyRepository.findTop20ByOrderByDegreeAsc(); - - if (nodes.isEmpty()) { + List ids = competencyRepository.findTop20IdsByDegreeAsc(PageRequest.of(0, LOW_DEGREE_POOL_SIZE)); + if (ids.isEmpty()) { + // No degree data yet — pick random competencies return competencyRepository.findRandomCompetencies(LOW_DEGREE_POOL_SIZE) .stream().map(Competency::getId).toList(); } - return nodes.stream().map(Competency::getId).toList(); + return ids; } private CompetencyRelationship createRelationship(String originId, String destId) { @@ -176,29 +160,23 @@ private CompetencyRelationship createRelationship(String originId, String destId .destinationId(destId) .build(); - List competencies = competencyRepository.findAllById(List.of(originId, destId)); - competencies.forEach(c -> c.setDegree(c.getDegree() + 1)); - competencyRepository.saveAll(competencies); - + competencyRepository.incrementDegree(List.of(originId, destId)); return relationshipRepository.save(rel); } - private RelationshipTaskResponse findUnvotedRelationship(String userId) { - return relationshipRepository - .findFirstUnvotedByUser(userId, org.springframework.data.domain.PageRequest.of(0, 1)) - .map(rel -> buildTaskResponse(rel, "COVERAGE")) - .orElseThrow(() -> new InvalidOperationException("No available relationships for voting")); - } - - private CompetencyRelationship selectByEntropyWeight(List candidates) { + /** + * Entropy-weighted roulette selection, biased toward low-vote high-entropy + * items. + */ + private CompetencyRelationship pickWeightedByEntropy(List candidates) { double totalWeight = candidates.stream() - .mapToDouble(r -> r.getEntropy() / (r.getTotalVotes() + 1.0)) + .mapToDouble(this::entropyWeight) .sum(); double roll = random.nextDouble() * totalWeight; double cumulative = 0; for (CompetencyRelationship rel : candidates) { - cumulative += rel.getEntropy() / (rel.getTotalVotes() + 1.0); + cumulative += entropyWeight(rel); if (roll <= cumulative) { return rel; } @@ -206,70 +184,86 @@ private CompetencyRelationship selectByEntropyWeight(List reverseOpt = relationshipRepository - .findByOriginIdAndDestinationId(originalRel.getDestinationId(), originalRel.getOriginId()); + private double entropyWeight(CompetencyRelationship rel) { + return rel.getEntropy() / (rel.getTotalVotes() + 1.0); + } - CompetencyRelationship reverse = reverseOpt.orElseGet(() -> createRelationship( - originalRel.getDestinationId(), originalRel.getOriginId())); + // --- Vote logic --- - if (!voteRepository.existsByRelationshipIdAndUserId(reverse.getId(), userId)) { - reverse.setVoteMatches(reverse.getVoteMatches() + 1); - reverse.recalculateEntropy(); - relationshipRepository.save(reverse); - - voteRepository.save(CompetencyRelationshipVote.builder() - .id(IdGenerator.generateCuid()) - .relationshipId(reverse.getId()) - .userId(userId) - .relationshipType(RelationshipType.MATCHES) - .build()); - } + private void saveVote(String relationshipId, String userId, RelationshipType type) { + voteRepository.save(CompetencyRelationshipVote.builder() + .id(IdGenerator.generateCuid()) + .relationshipId(relationshipId) + .userId(userId) + .relationshipType(type) + .build()); } - private void incrementVoteCounter(CompetencyRelationship rel, RelationshipType type) { + private void applyVote(CompetencyRelationship rel, RelationshipType type) { switch (type) { case ASSUMES -> rel.setVoteAssumes(rel.getVoteAssumes() + 1); case EXTENDS -> rel.setVoteExtends(rel.getVoteExtends() + 1); case MATCHES -> rel.setVoteMatches(rel.getVoteMatches() + 1); case UNRELATED -> rel.setVoteUnrelated(rel.getVoteUnrelated() + 1); } + rel.recalculateEntropy(); + relationshipRepository.save(rel); } - // Response Builders - private VoteResponse buildVoteResponse(CompetencyRelationship rel) { - return VoteResponse.builder() - .success(true) - .updatedVotes(buildVoteResponseCounts(rel)) - .newEntropy(rel.getEntropy()) - .build(); + /** MATCHES is symmetric: if A matches B, then B matches A. */ + private void mirrorMatchesVote(CompetencyRelationship originalRel, String userId) { + Optional reverseOpt = relationshipRepository + .findByOriginIdAndDestinationId(originalRel.getDestinationId(), originalRel.getOriginId()); + + CompetencyRelationship reverse = reverseOpt.orElseGet( + () -> createRelationship(originalRel.getDestinationId(), originalRel.getOriginId())); + + if (!voteRepository.existsByRelationshipIdAndUserId(reverse.getId(), userId)) { + applyVote(reverse, RelationshipType.MATCHES); + saveVote(reverse.getId(), userId, RelationshipType.MATCHES); + } } - private VoteResponse.VoteCounts buildVoteResponseCounts(CompetencyRelationship rel) { - return VoteResponse.VoteCounts.builder() - .assumes(rel.getVoteAssumes()) - .extendsRelation(rel.getVoteExtends()) - .matches(rel.getVoteMatches()) - .unrelated(rel.getVoteUnrelated()) - .build(); + // --- Lookups & response builders --- + + private CompetencyRelationship findRelationshipOrThrow(String id) { + return relationshipRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("Relationship not found: " + id)); } - private RelationshipTaskResponse buildTaskResponse(CompetencyRelationship rel, String pipeline) { - Competency origin = competencyRepository.findById(rel.getOriginId()) - .orElseThrow(() -> new ResourceNotFoundException("Origin competency not found")); - Competency destination = competencyRepository.findById(rel.getDestinationId()) - .orElseThrow(() -> new ResourceNotFoundException("Destination competency not found")); + /** + * Fetches both competencies in one query instead of two separate findById + * calls. + */ + private RelationshipTaskResponse toTaskResponse(CompetencyRelationship rel, String pipeline) { + Map byId = competencyRepository + .findAllById(List.of(rel.getOriginId(), rel.getDestinationId())) + .stream().collect(Collectors.toMap(Competency::getId, Function.identity())); + + Competency origin = byId.get(rel.getOriginId()); + Competency destination = byId.get(rel.getDestinationId()); + if (origin == null || destination == null) { + throw new ResourceNotFoundException("Competency not found for relationship " + rel.getId()); + } return RelationshipTaskResponse.builder() .relationshipId(rel.getId()) - .origin(buildCompetencyInfo(origin)) - .destination(buildCompetencyInfo(destination)) + .origin(toCompetencyInfo(origin)) + .destination(toCompetencyInfo(destination)) .pipeline(pipeline) - .currentVotes(buildTaskResponseCounts(rel)) + .currentVotes(toTaskVoteCounts(rel)) .build(); } - private RelationshipTaskResponse.CompetencyInfo buildCompetencyInfo(Competency c) { + private VoteResponse toVoteResponse(CompetencyRelationship rel) { + return VoteResponse.builder() + .success(true) + .updatedVotes(toResponseVoteCounts(rel)) + .newEntropy(rel.getEntropy()) + .build(); + } + + private static RelationshipTaskResponse.CompetencyInfo toCompetencyInfo(Competency c) { return RelationshipTaskResponse.CompetencyInfo.builder() .id(c.getId()) .title(c.getTitle()) @@ -277,7 +271,7 @@ private RelationshipTaskResponse.CompetencyInfo buildCompetencyInfo(Competency c .build(); } - private RelationshipTaskResponse.VoteCounts buildTaskResponseCounts(CompetencyRelationship rel) { + private static RelationshipTaskResponse.VoteCounts toTaskVoteCounts(CompetencyRelationship rel) { return RelationshipTaskResponse.VoteCounts.builder() .assumes(rel.getVoteAssumes()) .extendsRelation(rel.getVoteExtends()) @@ -285,4 +279,17 @@ private RelationshipTaskResponse.VoteCounts buildTaskResponseCounts(CompetencyRe .unrelated(rel.getVoteUnrelated()) .build(); } + + private static VoteResponse.VoteCounts toResponseVoteCounts(CompetencyRelationship rel) { + return VoteResponse.VoteCounts.builder() + .assumes(rel.getVoteAssumes()) + .extendsRelation(rel.getVoteExtends()) + .matches(rel.getVoteMatches()) + .unrelated(rel.getVoteUnrelated()) + .build(); + } + + private static String pairKey(String a, String b) { + return a + ':' + b; + } } From 60d7f66017652f9dd962968d52eaf1f4fd09f76f Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 10 Feb 2026 01:19:45 +0100 Subject: [PATCH 09/57] Optimise pipeline --- .../memo/dto/RelationshipTaskResponse.java | 13 +---- .../java/de/tum/cit/memo/dto/VoteCounts.java | 18 +++++++ .../de/tum/cit/memo/dto/VoteResponse.java | 11 ---- .../memo/entity/CompetencyRelationship.java | 27 +++------- .../CompetencyRelationshipVoteRepository.java | 9 ---- .../memo/repository/CompetencyRepository.java | 3 ++ .../CompetencyRelationshipService.java | 52 ++++++++----------- .../cit/memo/service/SchedulingService.java | 36 +++---------- 8 files changed, 57 insertions(+), 112 deletions(-) create mode 100644 server/src/main/java/de/tum/cit/memo/dto/VoteCounts.java diff --git a/server/src/main/java/de/tum/cit/memo/dto/RelationshipTaskResponse.java b/server/src/main/java/de/tum/cit/memo/dto/RelationshipTaskResponse.java index 098294b..ba78b5a 100644 --- a/server/src/main/java/de/tum/cit/memo/dto/RelationshipTaskResponse.java +++ b/server/src/main/java/de/tum/cit/memo/dto/RelationshipTaskResponse.java @@ -14,7 +14,7 @@ public class RelationshipTaskResponse { private String relationshipId; private CompetencyInfo origin; private CompetencyInfo destination; - private String pipeline; // "COVERAGE" or "CONSENSUS" + private String pipeline; private VoteCounts currentVotes; @Data @@ -26,15 +26,4 @@ public static class CompetencyInfo { private String title; private String description; } - - @Data - @Builder - @NoArgsConstructor - @AllArgsConstructor - public static class VoteCounts { - private int assumes; - private int extendsRelation; // 'extends' is a Java reserved keyword - private int matches; - private int unrelated; - } } diff --git a/server/src/main/java/de/tum/cit/memo/dto/VoteCounts.java b/server/src/main/java/de/tum/cit/memo/dto/VoteCounts.java new file mode 100644 index 0000000..a2fd05b --- /dev/null +++ b/server/src/main/java/de/tum/cit/memo/dto/VoteCounts.java @@ -0,0 +1,18 @@ +package de.tum.cit.memo.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class VoteCounts { + + private int assumes; + private int extendsRelation; + private int matches; + private int unrelated; +} diff --git a/server/src/main/java/de/tum/cit/memo/dto/VoteResponse.java b/server/src/main/java/de/tum/cit/memo/dto/VoteResponse.java index 0764899..6ce9b9d 100644 --- a/server/src/main/java/de/tum/cit/memo/dto/VoteResponse.java +++ b/server/src/main/java/de/tum/cit/memo/dto/VoteResponse.java @@ -14,15 +14,4 @@ public class VoteResponse { private boolean success; private VoteCounts updatedVotes; private double newEntropy; - - @Data - @Builder - @NoArgsConstructor - @AllArgsConstructor - public static class VoteCounts { - private int assumes; - private int extendsRelation; // 'extends' is a Java reserved keyword - private int matches; - private int unrelated; - } } diff --git a/server/src/main/java/de/tum/cit/memo/entity/CompetencyRelationship.java b/server/src/main/java/de/tum/cit/memo/entity/CompetencyRelationship.java index d12de7e..40c179f 100644 --- a/server/src/main/java/de/tum/cit/memo/entity/CompetencyRelationship.java +++ b/server/src/main/java/de/tum/cit/memo/entity/CompetencyRelationship.java @@ -42,32 +42,23 @@ public class CompetencyRelationship { // Aggregated vote counters @Column(name = "vote_assumes", nullable = false) - @Builder.Default - private Integer voteAssumes = 0; + private int voteAssumes; @Column(name = "vote_extends", nullable = false) - @Builder.Default - private Integer voteExtends = 0; + private int voteExtends; @Column(name = "vote_matches", nullable = false) - @Builder.Default - private Integer voteMatches = 0; + private int voteMatches; @Column(name = "vote_unrelated", nullable = false) - @Builder.Default - private Integer voteUnrelated = 0; + private int voteUnrelated; - // Precomputed entropy for consensus scheduling @Column(name = "entropy", nullable = false) - @Builder.Default - private Double entropy = 0.0; + private double entropy; - // Total votes (denormalized for convenience) @Column(name = "total_votes", nullable = false) - @Builder.Default - private Integer totalVotes = 0; + private int totalVotes; - // Relationships (ignored in JSON to avoid proxy serialization issues) @JsonIgnore @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "origin_id", insertable = false, updatable = false) @@ -102,11 +93,7 @@ public void recalculateEntropy() { } double ent = 0.0; - int[] counts = new int[4]; - counts[0] = voteAssumes; - counts[1] = voteExtends; - counts[2] = voteMatches; - counts[3] = voteUnrelated; + int[] counts = { voteAssumes, voteExtends, voteMatches, voteUnrelated }; for (int count : counts) { if (count > 0) { double p = (double) count / total; diff --git a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipVoteRepository.java b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipVoteRepository.java index d95fd3c..014bd02 100644 --- a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipVoteRepository.java +++ b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipVoteRepository.java @@ -4,17 +4,8 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import java.util.List; -import java.util.Optional; - @Repository public interface CompetencyRelationshipVoteRepository extends JpaRepository { - Optional findByRelationshipIdAndUserId(String relationshipId, String userId); - boolean existsByRelationshipIdAndUserId(String relationshipId, String userId); - - List findByRelationshipId(String relationshipId); - - List findByUserId(String userId); } diff --git a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java index 7ed456d..67bcc9d 100644 --- a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java +++ b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java @@ -14,6 +14,9 @@ public interface CompetencyRepository extends JpaRepository @Query(value = "SELECT * FROM competencies ORDER BY RANDOM() LIMIT :count", nativeQuery = true) List findRandomCompetencies(@Param("count") int count); + @Query(value = "SELECT id FROM competencies ORDER BY RANDOM() LIMIT :count", nativeQuery = true) + List findRandomCompetencyIds(@Param("count") int count); + @Query("SELECT c.id FROM Competency c ORDER BY c.degree ASC") List findTop20IdsByDegreeAsc(org.springframework.data.domain.Pageable pageable); diff --git a/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java b/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java index 4d0c029..1f0fe95 100644 --- a/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java +++ b/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java @@ -24,50 +24,23 @@ public class CompetencyRelationshipService { private final CompetencyRelationshipRepository relationshipRepository; private final CompetencyRepository competencyRepository; - /** - * Creates a new empty relationship (admin use). - * For the normal user voting flow, use SchedulingService. - */ @Transactional public CompetencyRelationship createRelationship(String originId, String destinationId) { - if (originId.equals(destinationId)) { - throw new InvalidOperationException("Cannot create relationship to itself"); - } + validateDistinctIds(originId, destinationId); if (relationshipRepository.existsByOriginIdAndDestinationId(originId, destinationId)) { throw new InvalidOperationException("Relationship already exists"); } - CompetencyRelationship relationship = CompetencyRelationship.builder() - .id(IdGenerator.generateCuid()) - .originId(originId) - .destinationId(destinationId) - .build(); - - competencyRepository.incrementDegree(List.of(originId, destinationId)); - return relationshipRepository.save(relationship); + return buildAndSave(originId, destinationId); } - /** - * Finds an existing relationship or creates a new one. - */ @Transactional public CompetencyRelationship findOrCreateRelationship(String originId, String destinationId) { - if (originId.equals(destinationId)) { - throw new InvalidOperationException("Cannot create relationship to itself"); - } + validateDistinctIds(originId, destinationId); return relationshipRepository.findByOriginIdAndDestinationId(originId, destinationId) - .orElseGet(() -> { - CompetencyRelationship relationship = CompetencyRelationship.builder() - .id(IdGenerator.generateCuid()) - .originId(originId) - .destinationId(destinationId) - .build(); - - competencyRepository.incrementDegree(List.of(originId, destinationId)); - return relationshipRepository.save(relationship); - }); + .orElseGet(() -> buildAndSave(originId, destinationId)); } @Transactional(readOnly = true) @@ -89,4 +62,21 @@ public void deleteRelationship(String id) { competencyRepository.decrementDegree(List.of(relationship.getOriginId(), relationship.getDestinationId())); relationshipRepository.deleteById(id); } + + private CompetencyRelationship buildAndSave(String originId, String destinationId) { + CompetencyRelationship relationship = CompetencyRelationship.builder() + .id(IdGenerator.generateCuid()) + .originId(originId) + .destinationId(destinationId) + .build(); + + competencyRepository.incrementDegree(List.of(originId, destinationId)); + return relationshipRepository.save(relationship); + } + + private static void validateDistinctIds(String originId, String destinationId) { + if (originId.equals(destinationId)) { + throw new InvalidOperationException("Cannot create relationship to itself"); + } + } } diff --git a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java index 22f5311..4923e99 100644 --- a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java +++ b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java @@ -1,6 +1,7 @@ package de.tum.cit.memo.service; import de.tum.cit.memo.dto.RelationshipTaskResponse; +import de.tum.cit.memo.dto.VoteCounts; import de.tum.cit.memo.dto.VoteRequest; import de.tum.cit.memo.dto.VoteResponse; import de.tum.cit.memo.entity.Competency; @@ -78,7 +79,6 @@ public RelationshipTaskResponse getNextTask(String userId) { public VoteResponse submitVote(String userId, VoteRequest request) { CompetencyRelationship rel = findRelationshipOrThrow(request.getRelationshipId()); - // Already voted? Return current state (idempotent) if (voteRepository.existsByRelationshipIdAndUserId(rel.getId(), userId)) { log.debug("User {} already voted on {}", userId, rel.getId()); return toVoteResponse(rel); @@ -102,13 +102,11 @@ private RelationshipTaskResponse coveragePipeline(String userId) { throw new InvalidOperationException("Not enough competencies to form pairs"); } - // Fetch only intra-pool relationships (both nodes in pool) Set existingPairs = relationshipRepository.findIntraPoolRelationships(poolIds).stream() .flatMap(r -> Stream.of(pairKey(r.getOriginId(), r.getDestinationId()), pairKey(r.getDestinationId(), r.getOriginId()))) .collect(Collectors.toSet()); - // Shuffle and find the first pair that doesn't exist yet List pool = new ArrayList<>(poolIds); Collections.shuffle(pool, random); @@ -120,7 +118,6 @@ private RelationshipTaskResponse coveragePipeline(String userId) { } } - // All pool pairs already exist — fall back to any unvoted relationship log.debug("Pool fully connected, finding any unvoted relationship"); return relationshipRepository .findFirstUnvotedByUser(userId, PageRequest.of(0, 1)) @@ -146,9 +143,7 @@ private RelationshipTaskResponse consensusPipeline(String userId) { private List getLowDegreeCompetencyIds() { List ids = competencyRepository.findTop20IdsByDegreeAsc(PageRequest.of(0, LOW_DEGREE_POOL_SIZE)); if (ids.isEmpty()) { - // No degree data yet — pick random competencies - return competencyRepository.findRandomCompetencies(LOW_DEGREE_POOL_SIZE) - .stream().map(Competency::getId).toList(); + return competencyRepository.findRandomCompetencyIds(LOW_DEGREE_POOL_SIZE); } return ids; } @@ -164,10 +159,6 @@ private CompetencyRelationship createRelationship(String originId, String destId return relationshipRepository.save(rel); } - /** - * Entropy-weighted roulette selection, biased toward low-vote high-entropy - * items. - */ private CompetencyRelationship pickWeightedByEntropy(List candidates) { double totalWeight = candidates.stream() .mapToDouble(this::entropyWeight) @@ -224,17 +215,13 @@ private void mirrorMatchesVote(CompetencyRelationship originalRel, String userId } } - // --- Lookups & response builders --- + // --- Response builders --- private CompetencyRelationship findRelationshipOrThrow(String id) { return relationshipRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("Relationship not found: " + id)); } - /** - * Fetches both competencies in one query instead of two separate findById - * calls. - */ private RelationshipTaskResponse toTaskResponse(CompetencyRelationship rel, String pipeline) { Map byId = competencyRepository .findAllById(List.of(rel.getOriginId(), rel.getDestinationId())) @@ -251,14 +238,14 @@ private RelationshipTaskResponse toTaskResponse(CompetencyRelationship rel, Stri .origin(toCompetencyInfo(origin)) .destination(toCompetencyInfo(destination)) .pipeline(pipeline) - .currentVotes(toTaskVoteCounts(rel)) + .currentVotes(toVoteCounts(rel)) .build(); } private VoteResponse toVoteResponse(CompetencyRelationship rel) { return VoteResponse.builder() .success(true) - .updatedVotes(toResponseVoteCounts(rel)) + .updatedVotes(toVoteCounts(rel)) .newEntropy(rel.getEntropy()) .build(); } @@ -271,17 +258,8 @@ private static RelationshipTaskResponse.CompetencyInfo toCompetencyInfo(Competen .build(); } - private static RelationshipTaskResponse.VoteCounts toTaskVoteCounts(CompetencyRelationship rel) { - return RelationshipTaskResponse.VoteCounts.builder() - .assumes(rel.getVoteAssumes()) - .extendsRelation(rel.getVoteExtends()) - .matches(rel.getVoteMatches()) - .unrelated(rel.getVoteUnrelated()) - .build(); - } - - private static VoteResponse.VoteCounts toResponseVoteCounts(CompetencyRelationship rel) { - return VoteResponse.VoteCounts.builder() + private static VoteCounts toVoteCounts(CompetencyRelationship rel) { + return VoteCounts.builder() .assumes(rel.getVoteAssumes()) .extendsRelation(rel.getVoteExtends()) .matches(rel.getVoteMatches()) From 6251a3aa7575ae322a42f0471f3164c1ec07113b Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 10 Feb 2026 01:35:55 +0100 Subject: [PATCH 10/57] Update logic for bidirectional relationship types --- .../de/tum/cit/memo/service/SchedulingService.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java index 4923e99..93ee456 100644 --- a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java +++ b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java @@ -87,8 +87,10 @@ public VoteResponse submitVote(String userId, VoteRequest request) { saveVote(rel.getId(), userId, request.getRelationshipType()); applyVote(rel, request.getRelationshipType()); - if (request.getRelationshipType() == RelationshipType.MATCHES) { - mirrorMatchesVote(rel, userId); + // MATCHES and UNRELATED are symmetric: A→B implies B→A + RelationshipType type = request.getRelationshipType(); + if (type == RelationshipType.MATCHES || type == RelationshipType.UNRELATED) { + mirrorSymmetricVote(rel, userId, type); } return toVoteResponse(rel); @@ -201,8 +203,8 @@ private void applyVote(CompetencyRelationship rel, RelationshipType type) { relationshipRepository.save(rel); } - /** MATCHES is symmetric: if A matches B, then B matches A. */ - private void mirrorMatchesVote(CompetencyRelationship originalRel, String userId) { + /** Symmetric types: if A→B is MATCHES/UNRELATED, mirror the vote to B→A. */ + private void mirrorSymmetricVote(CompetencyRelationship originalRel, String userId, RelationshipType type) { Optional reverseOpt = relationshipRepository .findByOriginIdAndDestinationId(originalRel.getDestinationId(), originalRel.getOriginId()); @@ -210,8 +212,8 @@ private void mirrorMatchesVote(CompetencyRelationship originalRel, String userId () -> createRelationship(originalRel.getDestinationId(), originalRel.getOriginId())); if (!voteRepository.existsByRelationshipIdAndUserId(reverse.getId(), userId)) { - applyVote(reverse, RelationshipType.MATCHES); - saveVote(reverse.getId(), userId, RelationshipType.MATCHES); + applyVote(reverse, type); + saveVote(reverse.getId(), userId, type); } } From e683410b33124a03d391b9c2bee6727d4c5bdad0 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 10 Feb 2026 02:26:52 +0100 Subject: [PATCH 11/57] Streamline implementation --- .../CompetencyRelationshipController.java | 33 +----- .../memo/controller/SchedulingController.java | 7 +- .../CreateCompetencyRelationshipRequest.java | 28 ----- .../CompetencyRelationshipRepository.java | 88 +++++++------- .../CompetencyRelationshipService.java | 8 -- .../cit/memo/service/SchedulingService.java | 18 +-- src/lib/api/competency-relationships.ts | 15 +-- src/lib/api/scheduling.ts | 63 ++++++++++ src/lib/api/session-helpers.ts | 73 ++++++++---- src/pages/SessionPage.tsx | 108 +++++++++++------- 10 files changed, 241 insertions(+), 200 deletions(-) delete mode 100644 server/src/main/java/de/tum/cit/memo/dto/CreateCompetencyRelationshipRequest.java create mode 100644 src/lib/api/scheduling.ts diff --git a/server/src/main/java/de/tum/cit/memo/controller/CompetencyRelationshipController.java b/server/src/main/java/de/tum/cit/memo/controller/CompetencyRelationshipController.java index ba2fbde..02dfcc3 100644 --- a/server/src/main/java/de/tum/cit/memo/controller/CompetencyRelationshipController.java +++ b/server/src/main/java/de/tum/cit/memo/controller/CompetencyRelationshipController.java @@ -1,29 +1,22 @@ package de.tum.cit.memo.controller; -import de.tum.cit.memo.dto.CreateCompetencyRelationshipRequest; -import de.tum.cit.memo.dto.VoteRequest; import de.tum.cit.memo.entity.CompetencyRelationship; import de.tum.cit.memo.service.CompetencyRelationshipService; -import de.tum.cit.memo.service.SchedulingService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; /** - * Controller for competency relationship management. - * The POST endpoint creates a relationship and records a vote. + * Controller for competency relationship CRUD. + * For creating relationships and voting, use {@link SchedulingController}. */ @RestController @RequestMapping("/api/competency-relationships") @@ -32,28 +25,6 @@ public class CompetencyRelationshipController { private final CompetencyRelationshipService relationshipService; - private final SchedulingService schedulingService; - - @PostMapping - @Operation(summary = "Create a competency relationship and record a vote") - public ResponseEntity createRelationship( - @Valid @RequestBody CreateCompetencyRelationshipRequest request) { - // Create the relationship if it doesn't exist - CompetencyRelationship relationship = relationshipService.findOrCreateRelationship( - request.getOriginId(), request.getDestinationId()); - - // Record the vote via scheduling service - VoteRequest voteRequest = VoteRequest.builder() - .relationshipId(relationship.getId()) - .relationshipType(request.getRelationshipType()) - .build(); - schedulingService.submitVote(request.getUserId(), voteRequest); - - // Refresh to get updated counters - relationship = relationshipService.getRelationshipById(relationship.getId()); - - return ResponseEntity.status(HttpStatus.CREATED).body(relationship); - } @GetMapping("/{id}") @Operation(summary = "Get competency relationship by ID") diff --git a/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java b/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java index caecf4f..28f672a 100644 --- a/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java +++ b/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java @@ -25,11 +25,12 @@ public class SchedulingController { private final SchedulingService schedulingService; @GetMapping("/next-relationship") - @Operation(summary = "Get next relationship to vote on", description = "Returns a competency pair for the user to map. Uses coverage (70%) and consensus (30%) pipelines.") + @Operation(summary = "Get next relationship to vote on", description = "Returns a competency pair for the user to map. Uses coverage (70%) and consensus (30%) pipelines. Returns 204 if no tasks remain.") public ResponseEntity getNextRelationship( @RequestHeader("X-User-Id") String userId) { - RelationshipTaskResponse task = schedulingService.getNextTask(userId); - return ResponseEntity.ok(task); + return schedulingService.getNextTask(userId) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.noContent().build()); } @PostMapping("/vote") diff --git a/server/src/main/java/de/tum/cit/memo/dto/CreateCompetencyRelationshipRequest.java b/server/src/main/java/de/tum/cit/memo/dto/CreateCompetencyRelationshipRequest.java deleted file mode 100644 index 8f2a5a2..0000000 --- a/server/src/main/java/de/tum/cit/memo/dto/CreateCompetencyRelationshipRequest.java +++ /dev/null @@ -1,28 +0,0 @@ -package de.tum.cit.memo.dto; - -import de.tum.cit.memo.enums.RelationshipType; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class CreateCompetencyRelationshipRequest { - - @NotNull(message = "Relationship type is required") - private RelationshipType relationshipType; - - @NotBlank(message = "Origin ID is required") - private String originId; - - @NotBlank(message = "Destination ID is required") - private String destinationId; - - @NotBlank(message = "User ID is required") - private String userId; -} diff --git a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java index 0aa41b9..4daa299 100644 --- a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java +++ b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java @@ -12,48 +12,48 @@ @Repository public interface CompetencyRelationshipRepository extends JpaRepository { - Optional findByOriginIdAndDestinationId(String originId, String destinationId); - - boolean existsByOriginIdAndDestinationId(String originId, String destinationId); - - /** - * High-entropy relationships the user hasn't voted on yet (for consensus - * pipeline). - */ - @Query(""" - SELECT r FROM CompetencyRelationship r - WHERE r.totalVotes BETWEEN :minVotes AND :maxVotes - AND r.entropy > :minEntropy - AND NOT EXISTS ( - SELECT 1 FROM CompetencyRelationshipVote v - WHERE v.relationshipId = r.id AND v.userId = :userId - ) - ORDER BY r.entropy DESC - """) - List findHighEntropyRelationshipsExcludingUser( - @Param("userId") String userId, - @Param("minVotes") int minVotes, - @Param("maxVotes") int maxVotes, - @Param("minEntropy") double minEntropy, - org.springframework.data.domain.Pageable pageable); - - /** - * Relationships where both origin AND destination are in the given pool of IDs. - */ - @Query("SELECT r FROM CompetencyRelationship r WHERE r.originId IN :ids AND r.destinationId IN :ids") - List findIntraPoolRelationships(@Param("ids") List ids); - - /** - * A single relationship the user hasn't voted on (use with PageRequest.of(0, - * 1)). - */ - @Query(""" - SELECT r FROM CompetencyRelationship r - WHERE NOT EXISTS ( - SELECT 1 FROM CompetencyRelationshipVote v - WHERE v.relationshipId = r.id AND v.userId = :userId - ) - """) - Optional findFirstUnvotedByUser(@Param("userId") String userId, - org.springframework.data.domain.Pageable pageable); + Optional findByOriginIdAndDestinationId(String originId, String destinationId); + + boolean existsByOriginIdAndDestinationId(String originId, String destinationId); + + /** + * High-entropy relationships the user hasn't voted on yet (for consensus + * pipeline). + */ + @Query(""" + SELECT r FROM CompetencyRelationship r + WHERE r.totalVotes BETWEEN :minVotes AND :maxVotes + AND r.entropy > :minEntropy + AND NOT EXISTS ( + SELECT 1 FROM CompetencyRelationshipVote v + WHERE v.relationshipId = r.id AND v.userId = :userId + ) + ORDER BY r.entropy DESC + """) + List findHighEntropyRelationshipsExcludingUser( + @Param("userId") String userId, + @Param("minVotes") int minVotes, + @Param("maxVotes") int maxVotes, + @Param("minEntropy") double minEntropy, + org.springframework.data.domain.Pageable pageable); + + /** + * Relationships where both origin AND destination are in the given pool of IDs. + */ + @Query("SELECT r FROM CompetencyRelationship r WHERE r.originId IN :ids AND r.destinationId IN :ids") + List findIntraPoolRelationships(@Param("ids") List ids); + + /** + * Relationships the user hasn't voted on (use with PageRequest.of(0, 1) for a + * single result). + */ + @Query(""" + SELECT r FROM CompetencyRelationship r + WHERE NOT EXISTS ( + SELECT 1 FROM CompetencyRelationshipVote v + WHERE v.relationshipId = r.id AND v.userId = :userId + ) + """) + List findUnvotedByUser(@Param("userId") String userId, + org.springframework.data.domain.Pageable pageable); } diff --git a/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java b/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java index 1f0fe95..40da523 100644 --- a/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java +++ b/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java @@ -35,14 +35,6 @@ public CompetencyRelationship createRelationship(String originId, String destina return buildAndSave(originId, destinationId); } - @Transactional - public CompetencyRelationship findOrCreateRelationship(String originId, String destinationId) { - validateDistinctIds(originId, destinationId); - - return relationshipRepository.findByOriginIdAndDestinationId(originId, destinationId) - .orElseGet(() -> buildAndSave(originId, destinationId)); - } - @Transactional(readOnly = true) public CompetencyRelationship getRelationshipById(String id) { return relationshipRepository.findById(id) diff --git a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java index 93ee456..278ed1e 100644 --- a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java +++ b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java @@ -57,9 +57,10 @@ public class SchedulingService { * Get the next relationship task for a user. * Uses 70% coverage pipeline (new pairs) and 30% consensus pipeline * (high-entropy). + * Returns empty if the user has voted on every available relationship. */ @Transactional - public RelationshipTaskResponse getNextTask(String userId) { + public Optional getNextTask(String userId) { if (random.nextDouble() < COVERAGE_WEIGHT) { log.debug("Coverage pipeline for user {}", userId); return coveragePipeline(userId); @@ -68,7 +69,7 @@ public RelationshipTaskResponse getNextTask(String userId) { log.debug("Consensus pipeline for user {}", userId); RelationshipTaskResponse task = consensusPipeline(userId); if (task != null) { - return task; + return Optional.of(task); } log.debug("No consensus candidates, falling back to coverage"); @@ -98,10 +99,11 @@ public VoteResponse submitVote(String userId, VoteRequest request) { // --- Pipelines --- - private RelationshipTaskResponse coveragePipeline(String userId) { + private Optional coveragePipeline(String userId) { List poolIds = getLowDegreeCompetencyIds(); if (poolIds.size() < 2) { - throw new InvalidOperationException("Not enough competencies to form pairs"); + log.debug("Not enough competencies to form pairs"); + return Optional.empty(); } Set existingPairs = relationshipRepository.findIntraPoolRelationships(poolIds).stream() @@ -115,16 +117,16 @@ private RelationshipTaskResponse coveragePipeline(String userId) { for (int i = 0; i < pool.size(); i++) { for (int j = i + 1; j < pool.size(); j++) { if (!existingPairs.contains(pairKey(pool.get(i), pool.get(j)))) { - return toTaskResponse(createRelationship(pool.get(i), pool.get(j)), "COVERAGE"); + return Optional.of(toTaskResponse(createRelationship(pool.get(i), pool.get(j)), "COVERAGE")); } } } log.debug("Pool fully connected, finding any unvoted relationship"); return relationshipRepository - .findFirstUnvotedByUser(userId, PageRequest.of(0, 1)) - .map(rel -> toTaskResponse(rel, "COVERAGE")) - .orElseThrow(() -> new InvalidOperationException("No available relationships for voting")); + .findUnvotedByUser(userId, PageRequest.of(0, 1)) + .stream().findFirst() + .map(rel -> toTaskResponse(rel, "COVERAGE")); } private RelationshipTaskResponse consensusPipeline(String userId) { diff --git a/src/lib/api/competency-relationships.ts b/src/lib/api/competency-relationships.ts index 8891fcd..14a5e7c 100644 --- a/src/lib/api/competency-relationships.ts +++ b/src/lib/api/competency-relationships.ts @@ -1,20 +1,7 @@ import { apiClient } from './client'; -import type { - CompetencyRelationship, - CreateCompetencyRelationshipRequest, -} from './types'; +import type { CompetencyRelationship } from './types'; export const competencyRelationshipsApi = { - create: async ( - data: CreateCompetencyRelationshipRequest - ): Promise => { - const response = await apiClient.post( - '/api/competency-relationships', - data - ); - return response.data; - }, - getById: async (id: string): Promise => { const response = await apiClient.get( `/api/competency-relationships/${id}` diff --git a/src/lib/api/scheduling.ts b/src/lib/api/scheduling.ts new file mode 100644 index 0000000..0ca9aa4 --- /dev/null +++ b/src/lib/api/scheduling.ts @@ -0,0 +1,63 @@ +import { apiClient } from './client'; + +export interface CompetencyInfo { + id: string; + title: string; + description: string; +} + +export interface VoteCounts { + assumes: number; + extendsRelation: number; + matches: number; + unrelated: number; +} + +export interface RelationshipTask { + relationshipId: string; + origin: CompetencyInfo; + destination: CompetencyInfo; + pipeline: string; + currentVotes: VoteCounts; +} + +export interface VoteResponse { + success: boolean; + updatedVotes: VoteCounts; + newEntropy: number; +} + +export const schedulingApi = { + /** + * Get the next relationship task for a user. + * Returns null when there are no more tasks (HTTP 204). + */ + getNextRelationship: async ( + userId: string + ): Promise => { + const response = await apiClient.get( + '/api/scheduling/next-relationship', + { headers: { 'X-User-Id': userId } } + ); + if (response.status === 204) { + return null; + } + return response.data; + }, + + /** + * Submit a vote on a relationship. + */ + submitVote: async ( + userId: string, + relationshipId: string, + relationshipType: string + ): Promise => { + const response = await apiClient.post( + '/api/scheduling/vote', + { relationshipId, relationshipType }, + { headers: { 'X-User-Id': userId } } + ); + return response.data; + }, +}; diff --git a/src/lib/api/session-helpers.ts b/src/lib/api/session-helpers.ts index 8b4bdf6..ef12537 100644 --- a/src/lib/api/session-helpers.ts +++ b/src/lib/api/session-helpers.ts @@ -6,6 +6,8 @@ import { competenciesApi } from './competencies'; import { competencyRelationshipsApi } from './competency-relationships'; import { competencyResourceLinksApi } from './competency-resource-links'; import { learningResourcesApi } from './learning-resources'; +import { schedulingApi } from './scheduling'; +import type { RelationshipTask, VoteResponse as SchedulingVoteResponse } from './scheduling'; import type { Competency, LearningResource, @@ -49,58 +51,87 @@ export async function getRandomCompetenciesAction(count: number): Promise<{ } } -export async function getRandomLearningResourceAction(): Promise<{ +/** + * Get the next relationship task from the scheduling pipeline. + * Returns allDone: true when there are no more pairs to vote on. + */ +export async function getNextRelationshipTaskAction(userId: string): Promise<{ success: boolean; - resource?: LearningResource; + task?: RelationshipTask; + allDone?: boolean; error?: string; }> { try { - const resources = await learningResourcesApi.getRandom(1); - if (resources.length > 0) { - return { success: true, resource: resources[0] }; + const task = await schedulingApi.getNextRelationship(userId); + if (task === null) { + return { success: true, allDone: true }; } - return { success: false, error: 'No learning resources available' }; + return { success: true, task }; } catch (error) { return { success: false, error: error instanceof Error ? error.message - : 'Failed to fetch learning resource', + : 'Failed to fetch next relationship task', }; } } -export async function createCompetencyRelationshipAction( - formData: FormData +/** + * Submit a vote on a competency relationship via the scheduling pipeline. + */ +export async function submitCompetencyVoteAction( + userId: string, + relationshipId: string, + relationshipType: string ): Promise<{ success: boolean; - relationship?: CompetencyRelationship; + voteResponse?: SchedulingVoteResponse; error?: string; }> { try { - const relationshipType = formData.get('relationshipType') as string; - const originId = formData.get('originId') as string; - const destinationId = formData.get('destinationId') as string; + const voteResponse = await schedulingApi.submitVote( + userId, + relationshipId, + relationshipType + ); + return { success: true, voteResponse }; + } catch (error) { + return { + success: false, + error: + error instanceof Error + ? error.message + : 'Failed to submit vote', + }; + } +} - const relationship = await competencyRelationshipsApi.create({ - relationshipType: relationshipType as 'ASSUMES' | 'EXTENDS' | 'MATCHES', - originId, - destinationId, - userId: GUEST_USER_ID, - }); - return { success: true, relationship }; + +export async function getRandomLearningResourceAction(): Promise<{ + success: boolean; + resource?: LearningResource; + error?: string; +}> { + try { + const resources = await learningResourcesApi.getRandom(1); + if (resources.length > 0) { + return { success: true, resource: resources[0] }; + } + return { success: false, error: 'No learning resources available' }; } catch (error) { return { success: false, error: error instanceof Error ? error.message - : 'Failed to create relationship', + : 'Failed to fetch learning resource', }; } } + export async function deleteCompetencyRelationshipAction( id: string ): Promise<{ success: boolean; error?: string }> { diff --git a/src/pages/SessionPage.tsx b/src/pages/SessionPage.tsx index 9f1be1b..a653c79 100644 --- a/src/pages/SessionPage.tsx +++ b/src/pages/SessionPage.tsx @@ -2,7 +2,8 @@ import { useEffect, useState, useCallback, useRef } from 'react'; import { useSearchParams } from 'react-router-dom'; import { getRandomCompetenciesAction, - createCompetencyRelationshipAction, + getNextRelationshipTaskAction, + submitCompetencyVoteAction, deleteCompetencyRelationshipAction, createCompetencyResourceLinkAction, deleteCompetencyResourceLinkAction, @@ -128,6 +129,8 @@ export function SessionPage() { const [isCreating, setIsCreating] = useState(false); const [isTransitioning, setIsTransitioning] = useState(false); const [swapRotation, setSwapRotation] = useState(0); + const [allDone, setAllDone] = useState(false); + const [currentRelationshipId, setCurrentRelationshipId] = useState(null); const { hoveredValue: hoveredRelation, @@ -157,7 +160,7 @@ export function SessionPage() { } else { setError( result.error ?? - 'Failed to load user information. Please try again later.' + 'Failed to load user information. Please try again later.' ); } } catch (err) { @@ -187,33 +190,43 @@ export function SessionPage() { setResourceMatchType(null); if (mappingMode === 'competency') { - const result = await getRandomCompetenciesAction(count); + if (!userId) { + setIsTransitioning(false); + return; + } + + const result = await getNextRelationshipTaskAction(userId); if (!result.success) { setError( result.error ?? - 'An unexpected error occurred while fetching competencies.' + 'An unexpected error occurred while fetching the next task.' ); if (isInitialLoad) setCompetencies([]); setIsTransitioning(false); return; } - if (!result.competencies || result.competencies.length === 0) { - if (isInitialLoad) setCompetencies([]); + if (result.allDone) { + setAllDone(true); + setCompetencies([]); + setCurrentRelationshipId(null); setIsTransitioning(false); return; } - if ( - result.competencies.length >= 2 && - result.competencies[0]!.id === result.competencies[1]!.id - ) { - await loadMappingPair(isInitialLoad); + if (!result.task) { + if (isInitialLoad) setCompetencies([]); + setIsTransitioning(false); return; } - setCompetencies(result.competencies); + setAllDone(false); + setCurrentRelationshipId(result.task.relationshipId); + setCompetencies([ + { id: result.task.origin.id, title: result.task.origin.title, description: result.task.origin.description }, + { id: result.task.destination.id, title: result.task.destination.title, description: result.task.destination.description }, + ] as Competency[]); setLearningResource(null); } else { const [compResult, resourceResult] = await Promise.all([ @@ -224,7 +237,7 @@ export function SessionPage() { if (!compResult.success || !compResult.competencies?.length) { setError( compResult.error ?? - 'Failed to fetch competency for resource mapping.' + 'Failed to fetch competency for resource mapping.' ); if (isInitialLoad) setCompetencies([]); setIsTransitioning(false); @@ -234,7 +247,7 @@ export function SessionPage() { if (!resourceResult.success || !resourceResult.resource) { setError( resourceResult.error ?? - 'Failed to fetch learning resource. Make sure resources are seeded.' + 'Failed to fetch learning resource. Make sure resources are seeded.' ); setCompetencies(compResult.competencies); setLearningResource(null); @@ -248,7 +261,7 @@ export function SessionPage() { setIsTransitioning(false); }, - [count, mappingMode] + [count, mappingMode, userId] ); const prevModeRef = useRef(null); @@ -264,12 +277,11 @@ export function SessionPage() { if (type === 'completed') { if (mappingMode === 'competency') { if ( - !competencies || - competencies.length < 2 || + !currentRelationshipId || !relation || !userId ) { - setError('Missing required data to create relationship'); + setError('Missing required data to submit vote'); return; } @@ -277,14 +289,12 @@ export function SessionPage() { setError(null); try { - const formData = new FormData(); - formData.set('relationshipType', relation); - formData.set('originId', competencies[0]!.id); - formData.set('destinationId', competencies[1]!.id); - formData.set('userId', userId); - const startTime = Date.now(); - const result = await createCompetencyRelationshipAction(formData); + const result = await submitCompetencyVoteAction( + userId, + currentRelationshipId, + relation + ); const elapsed = Date.now() - startTime; if (elapsed < 300) { @@ -292,7 +302,7 @@ export function SessionPage() { } if (!result.success) { - setError(result.error ?? 'Failed to create relationship'); + setError(result.error ?? 'Failed to submit vote'); setIsCreating(false); return; } @@ -303,7 +313,7 @@ export function SessionPage() { { type: 'completed', mode: 'competency', - relationshipId: result.relationship?.id, + relationshipId: currentRelationshipId, competencies: competencies ? [...competencies] : undefined, }, ]); @@ -409,6 +419,7 @@ export function SessionPage() { userId, mappingMode, loadMappingPair, + currentRelationshipId, ] ); @@ -654,10 +665,9 @@ export function SessionPage() { }} className={` px-3 py-1.5 text-xs font-semibold rounded-md transition-all duration-200 - ${ - mappingMode === 'competency' - ? 'bg-white text-slate-900 shadow-sm' - : 'text-slate-500 hover:text-slate-700' + ${mappingMode === 'competency' + ? 'bg-white text-slate-900 shadow-sm' + : 'text-slate-500 hover:text-slate-700' } `} > @@ -672,10 +682,9 @@ export function SessionPage() { }} className={` px-3 py-1.5 text-xs font-semibold rounded-md transition-all duration-200 - ${ - mappingMode === 'resource' - ? 'bg-white text-slate-900 shadow-sm' - : 'text-slate-500 hover:text-slate-700' + ${mappingMode === 'resource' + ? 'bg-white text-slate-900 shadow-sm' + : 'text-slate-500 hover:text-slate-700' } `} > @@ -697,7 +706,21 @@ export function SessionPage() { )} - {noCompetencies && !error && ( + {allDone && !error && ( + + + + 🎉 All done! + + + You've voted on every available competency pair. Great work! + Check back later when more competencies have been added. + + + + )} + + {noCompetencies && !allDone && !error && ( @@ -726,7 +749,7 @@ export function SessionPage() { )} - {!error && !noCompetencies && !notEnough && ( + {!error && !allDone && !noCompetencies && !notEnough && ( <>
{isLoading || !competencies?.length ? ( @@ -936,8 +959,8 @@ export function SessionPage() { {relation === 'UNRELATED' ? 'is unrelated to' : RELATIONSHIP_TYPES.find( - rt => rt.value === relation - )?.label.toLowerCase() || ''} + rt => rt.value === relation + )?.label.toLowerCase() || ''} {' '} {competencies[1]!.title} @@ -1113,10 +1136,9 @@ export function SessionPage() { className={` relative flex items-center justify-center gap-2 px-6 py-3 rounded-xl text-sm font-bold text-white min-w-[180px] - ${ - mappingMode === 'resource' - ? 'bg-gradient-to-r from-pink-600 to-pink-500 shadow-lg shadow-pink-500/20 hover:shadow-xl hover:shadow-pink-500/30' - : 'bg-gradient-to-r from-[#0a4da2] to-[#5538d1] shadow-lg shadow-blue-500/20 hover:shadow-xl hover:shadow-blue-500/30' + ${mappingMode === 'resource' + ? 'bg-gradient-to-r from-pink-600 to-pink-500 shadow-lg shadow-pink-500/20 hover:shadow-xl hover:shadow-pink-500/30' + : 'bg-gradient-to-r from-[#0a4da2] to-[#5538d1] shadow-lg shadow-blue-500/20 hover:shadow-xl hover:shadow-blue-500/30' } transition-all duration-200 ease-out hover:scale-[1.02] From 141bebdac2963c2438e6256b66910553f5b730a5 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 10 Feb 2026 02:32:27 +0100 Subject: [PATCH 12/57] Conform to Prettier formatting --- src/lib/api/scheduling.ts | 92 +++++++++++++++++----------------- src/lib/api/session-helpers.ts | 13 ++--- src/pages/SessionPage.tsx | 69 ++++++++++++------------- 3 files changed, 86 insertions(+), 88 deletions(-) diff --git a/src/lib/api/scheduling.ts b/src/lib/api/scheduling.ts index 0ca9aa4..faba6c2 100644 --- a/src/lib/api/scheduling.ts +++ b/src/lib/api/scheduling.ts @@ -1,63 +1,63 @@ import { apiClient } from './client'; export interface CompetencyInfo { - id: string; - title: string; - description: string; + id: string; + title: string; + description: string; } export interface VoteCounts { - assumes: number; - extendsRelation: number; - matches: number; - unrelated: number; + assumes: number; + extendsRelation: number; + matches: number; + unrelated: number; } export interface RelationshipTask { - relationshipId: string; - origin: CompetencyInfo; - destination: CompetencyInfo; - pipeline: string; - currentVotes: VoteCounts; + relationshipId: string; + origin: CompetencyInfo; + destination: CompetencyInfo; + pipeline: string; + currentVotes: VoteCounts; } export interface VoteResponse { - success: boolean; - updatedVotes: VoteCounts; - newEntropy: number; + success: boolean; + updatedVotes: VoteCounts; + newEntropy: number; } export const schedulingApi = { - /** - * Get the next relationship task for a user. - * Returns null when there are no more tasks (HTTP 204). - */ - getNextRelationship: async ( - userId: string - ): Promise => { - const response = await apiClient.get( - '/api/scheduling/next-relationship', - { headers: { 'X-User-Id': userId } } - ); - if (response.status === 204) { - return null; - } - return response.data; - }, + /** + * Get the next relationship task for a user. + * Returns null when there are no more tasks (HTTP 204). + */ + getNextRelationship: async ( + userId: string + ): Promise => { + const response = await apiClient.get( + '/api/scheduling/next-relationship', + { headers: { 'X-User-Id': userId } } + ); + if (response.status === 204) { + return null; + } + return response.data; + }, - /** - * Submit a vote on a relationship. - */ - submitVote: async ( - userId: string, - relationshipId: string, - relationshipType: string - ): Promise => { - const response = await apiClient.post( - '/api/scheduling/vote', - { relationshipId, relationshipType }, - { headers: { 'X-User-Id': userId } } - ); - return response.data; - }, + /** + * Submit a vote on a relationship. + */ + submitVote: async ( + userId: string, + relationshipId: string, + relationshipType: string + ): Promise => { + const response = await apiClient.post( + '/api/scheduling/vote', + { relationshipId, relationshipType }, + { headers: { 'X-User-Id': userId } } + ); + return response.data; + }, }; diff --git a/src/lib/api/session-helpers.ts b/src/lib/api/session-helpers.ts index ef12537..06c9076 100644 --- a/src/lib/api/session-helpers.ts +++ b/src/lib/api/session-helpers.ts @@ -7,11 +7,13 @@ import { competencyRelationshipsApi } from './competency-relationships'; import { competencyResourceLinksApi } from './competency-resource-links'; import { learningResourcesApi } from './learning-resources'; import { schedulingApi } from './scheduling'; -import type { RelationshipTask, VoteResponse as SchedulingVoteResponse } from './scheduling'; +import type { + RelationshipTask, + VoteResponse as SchedulingVoteResponse, +} from './scheduling'; import type { Competency, LearningResource, - CompetencyRelationship, CompetencyResourceLink, } from './types'; @@ -100,15 +102,11 @@ export async function submitCompetencyVoteAction( } catch (error) { return { success: false, - error: - error instanceof Error - ? error.message - : 'Failed to submit vote', + error: error instanceof Error ? error.message : 'Failed to submit vote', }; } } - export async function getRandomLearningResourceAction(): Promise<{ success: boolean; resource?: LearningResource; @@ -131,7 +129,6 @@ export async function getRandomLearningResourceAction(): Promise<{ } } - export async function deleteCompetencyRelationshipAction( id: string ): Promise<{ success: boolean; error?: string }> { diff --git a/src/pages/SessionPage.tsx b/src/pages/SessionPage.tsx index a653c79..565febe 100644 --- a/src/pages/SessionPage.tsx +++ b/src/pages/SessionPage.tsx @@ -1,5 +1,5 @@ import { useEffect, useState, useCallback, useRef } from 'react'; -import { useSearchParams } from 'react-router-dom'; + import { getRandomCompetenciesAction, getNextRelationshipTaskAction, @@ -97,12 +97,6 @@ const getRelationshipDescription = ( }; export function SessionPage() { - const [searchParams] = useSearchParams(); - const countParam = searchParams.get('count'); - const parsedCount = countParam ? Number(countParam) : NaN; - const count = - Number.isFinite(parsedCount) && parsedCount > 0 ? parsedCount : 2; - const [relation, setRelation] = useState(null); const [resourceMatchType, setResourceMatchType] = useState(null); @@ -130,7 +124,9 @@ export function SessionPage() { const [isTransitioning, setIsTransitioning] = useState(false); const [swapRotation, setSwapRotation] = useState(0); const [allDone, setAllDone] = useState(false); - const [currentRelationshipId, setCurrentRelationshipId] = useState(null); + const [currentRelationshipId, setCurrentRelationshipId] = useState< + string | null + >(null); const { hoveredValue: hoveredRelation, @@ -160,7 +156,7 @@ export function SessionPage() { } else { setError( result.error ?? - 'Failed to load user information. Please try again later.' + 'Failed to load user information. Please try again later.' ); } } catch (err) { @@ -200,7 +196,7 @@ export function SessionPage() { if (!result.success) { setError( result.error ?? - 'An unexpected error occurred while fetching the next task.' + 'An unexpected error occurred while fetching the next task.' ); if (isInitialLoad) setCompetencies([]); setIsTransitioning(false); @@ -224,8 +220,16 @@ export function SessionPage() { setAllDone(false); setCurrentRelationshipId(result.task.relationshipId); setCompetencies([ - { id: result.task.origin.id, title: result.task.origin.title, description: result.task.origin.description }, - { id: result.task.destination.id, title: result.task.destination.title, description: result.task.destination.description }, + { + id: result.task.origin.id, + title: result.task.origin.title, + description: result.task.origin.description, + }, + { + id: result.task.destination.id, + title: result.task.destination.title, + description: result.task.destination.description, + }, ] as Competency[]); setLearningResource(null); } else { @@ -237,7 +241,7 @@ export function SessionPage() { if (!compResult.success || !compResult.competencies?.length) { setError( compResult.error ?? - 'Failed to fetch competency for resource mapping.' + 'Failed to fetch competency for resource mapping.' ); if (isInitialLoad) setCompetencies([]); setIsTransitioning(false); @@ -247,7 +251,7 @@ export function SessionPage() { if (!resourceResult.success || !resourceResult.resource) { setError( resourceResult.error ?? - 'Failed to fetch learning resource. Make sure resources are seeded.' + 'Failed to fetch learning resource. Make sure resources are seeded.' ); setCompetencies(compResult.competencies); setLearningResource(null); @@ -261,7 +265,7 @@ export function SessionPage() { setIsTransitioning(false); }, - [count, mappingMode, userId] + [mappingMode, userId] ); const prevModeRef = useRef(null); @@ -276,11 +280,7 @@ export function SessionPage() { async (type: 'completed' | 'skipped') => { if (type === 'completed') { if (mappingMode === 'competency') { - if ( - !currentRelationshipId || - !relation || - !userId - ) { + if (!currentRelationshipId || !relation || !userId) { setError('Missing required data to submit vote'); return; } @@ -665,9 +665,10 @@ export function SessionPage() { }} className={` px-3 py-1.5 text-xs font-semibold rounded-md transition-all duration-200 - ${mappingMode === 'competency' - ? 'bg-white text-slate-900 shadow-sm' - : 'text-slate-500 hover:text-slate-700' + ${ + mappingMode === 'competency' + ? 'bg-white text-slate-900 shadow-sm' + : 'text-slate-500 hover:text-slate-700' } `} > @@ -682,9 +683,10 @@ export function SessionPage() { }} className={` px-3 py-1.5 text-xs font-semibold rounded-md transition-all duration-200 - ${mappingMode === 'resource' - ? 'bg-white text-slate-900 shadow-sm' - : 'text-slate-500 hover:text-slate-700' + ${ + mappingMode === 'resource' + ? 'bg-white text-slate-900 shadow-sm' + : 'text-slate-500 hover:text-slate-700' } `} > @@ -709,9 +711,7 @@ export function SessionPage() { {allDone && !error && ( - - 🎉 All done! - + 🎉 All done! You've voted on every available competency pair. Great work! Check back later when more competencies have been added. @@ -959,8 +959,8 @@ export function SessionPage() { {relation === 'UNRELATED' ? 'is unrelated to' : RELATIONSHIP_TYPES.find( - rt => rt.value === relation - )?.label.toLowerCase() || ''} + rt => rt.value === relation + )?.label.toLowerCase() || ''} {' '} {competencies[1]!.title} @@ -1136,9 +1136,10 @@ export function SessionPage() { className={` relative flex items-center justify-center gap-2 px-6 py-3 rounded-xl text-sm font-bold text-white min-w-[180px] - ${mappingMode === 'resource' - ? 'bg-gradient-to-r from-pink-600 to-pink-500 shadow-lg shadow-pink-500/20 hover:shadow-xl hover:shadow-pink-500/30' - : 'bg-gradient-to-r from-[#0a4da2] to-[#5538d1] shadow-lg shadow-blue-500/20 hover:shadow-xl hover:shadow-blue-500/30' + ${ + mappingMode === 'resource' + ? 'bg-gradient-to-r from-pink-600 to-pink-500 shadow-lg shadow-pink-500/20 hover:shadow-xl hover:shadow-pink-500/30' + : 'bg-gradient-to-r from-[#0a4da2] to-[#5538d1] shadow-lg shadow-blue-500/20 hover:shadow-xl hover:shadow-blue-500/30' } transition-all duration-200 ease-out hover:scale-[1.02] From 64c4f207c8f7a1a380b328bb62c31f7ba017cb1e Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 17 Feb 2026 02:42:51 +0100 Subject: [PATCH 13/57] Implement AI suggestions --- .../memo/controller/SchedulingController.java | 2 +- .../java/de/tum/cit/memo/dto/VoteRequest.java | 18 ++++++++++++++++-- .../memo/entity/CompetencyRelationship.java | 2 +- .../memo/repository/CompetencyRepository.java | 2 +- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java b/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java index 28f672a..1f68346 100644 --- a/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java +++ b/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java @@ -34,7 +34,7 @@ public ResponseEntity getNextRelationship( } @PostMapping("/vote") - @Operation(summary = "Submit a vote on a relationship", description = "Records the user's vote on a competency relationship. MATCHES votes are bidirectional.") + @Operation(summary = "Submit a vote on a relationship", description = "Records the user's vote on a competency relationship. Accepts either a relationshipId or originId+destinationId pair (for swapped direction). MATCHES and UNRELATED votes are bidirectional.") public ResponseEntity submitVote( @RequestHeader("X-User-Id") String userId, @Valid @RequestBody VoteRequest request) { diff --git a/server/src/main/java/de/tum/cit/memo/dto/VoteRequest.java b/server/src/main/java/de/tum/cit/memo/dto/VoteRequest.java index e1f0da3..265a359 100644 --- a/server/src/main/java/de/tum/cit/memo/dto/VoteRequest.java +++ b/server/src/main/java/de/tum/cit/memo/dto/VoteRequest.java @@ -1,7 +1,6 @@ package de.tum.cit.memo.dto; import de.tum.cit.memo.enums.RelationshipType; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; @@ -14,9 +13,24 @@ @AllArgsConstructor public class VoteRequest { - @NotBlank(message = "Relationship ID is required") + /** + * Relationship ID (used directly when direction is not swapped). + * Optional if originId + destinationId are provided instead. + */ private String relationshipId; + /** + * Origin competency ID (used when direction is swapped). + * Must be provided together with destinationId. + */ + private String originId; + + /** + * Destination competency ID (used when direction is swapped). + * Must be provided together with originId. + */ + private String destinationId; + @NotNull(message = "Relationship type is required") private RelationshipType relationshipType; } diff --git a/server/src/main/java/de/tum/cit/memo/entity/CompetencyRelationship.java b/server/src/main/java/de/tum/cit/memo/entity/CompetencyRelationship.java index 40c179f..9b30190 100644 --- a/server/src/main/java/de/tum/cit/memo/entity/CompetencyRelationship.java +++ b/server/src/main/java/de/tum/cit/memo/entity/CompetencyRelationship.java @@ -93,7 +93,7 @@ public void recalculateEntropy() { } double ent = 0.0; - int[] counts = { voteAssumes, voteExtends, voteMatches, voteUnrelated }; + int[] counts = {voteAssumes, voteExtends, voteMatches, voteUnrelated}; for (int count : counts) { if (count > 0) { double p = (double) count / total; diff --git a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java index 67bcc9d..fc80203 100644 --- a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java +++ b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java @@ -18,7 +18,7 @@ public interface CompetencyRepository extends JpaRepository List findRandomCompetencyIds(@Param("count") int count); @Query("SELECT c.id FROM Competency c ORDER BY c.degree ASC") - List findTop20IdsByDegreeAsc(org.springframework.data.domain.Pageable pageable); + List findIdsByDegreeAsc(org.springframework.data.domain.Pageable pageable); @org.springframework.data.jpa.repository.Modifying(flushAutomatically = true, clearAutomatically = true) @Query("UPDATE Competency c SET c.degree = c.degree + 1 WHERE c.id IN :ids") From d863e7778a05e0c00f4a3d6accd753ede0662744 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 17 Feb 2026 02:43:07 +0100 Subject: [PATCH 14/57] Further AI suggestions --- .../cit/memo/service/SchedulingService.java | 13 +++++++++--- src/lib/api/scheduling.ts | 8 ++++--- src/lib/api/session-helpers.ts | 10 +++++---- src/pages/SessionPage.tsx | 21 ++++++++++++++----- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java index 278ed1e..a347df0 100644 --- a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java +++ b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java @@ -8,7 +8,6 @@ import de.tum.cit.memo.entity.CompetencyRelationship; import de.tum.cit.memo.entity.CompetencyRelationshipVote; import de.tum.cit.memo.enums.RelationshipType; -import de.tum.cit.memo.exception.InvalidOperationException; import de.tum.cit.memo.exception.ResourceNotFoundException; import de.tum.cit.memo.repository.CompetencyRelationshipRepository; import de.tum.cit.memo.repository.CompetencyRelationshipVoteRepository; @@ -78,7 +77,15 @@ public Optional getNextTask(String userId) { @Transactional public VoteResponse submitVote(String userId, VoteRequest request) { - CompetencyRelationship rel = findRelationshipOrThrow(request.getRelationshipId()); + // Resolve relationship: by ID directly, or find/create by competency pair + CompetencyRelationship rel; + if (request.getOriginId() != null && request.getDestinationId() != null) { + rel = relationshipRepository + .findByOriginIdAndDestinationId(request.getOriginId(), request.getDestinationId()) + .orElseGet(() -> createRelationship(request.getOriginId(), request.getDestinationId())); + } else { + rel = findRelationshipOrThrow(request.getRelationshipId()); + } if (voteRepository.existsByRelationshipIdAndUserId(rel.getId(), userId)) { log.debug("User {} already voted on {}", userId, rel.getId()); @@ -145,7 +152,7 @@ private RelationshipTaskResponse consensusPipeline(String userId) { // --- Core helpers --- private List getLowDegreeCompetencyIds() { - List ids = competencyRepository.findTop20IdsByDegreeAsc(PageRequest.of(0, LOW_DEGREE_POOL_SIZE)); + List ids = competencyRepository.findIdsByDegreeAsc(PageRequest.of(0, LOW_DEGREE_POOL_SIZE)); if (ids.isEmpty()) { return competencyRepository.findRandomCompetencyIds(LOW_DEGREE_POOL_SIZE); } diff --git a/src/lib/api/scheduling.ts b/src/lib/api/scheduling.ts index faba6c2..1a25eb5 100644 --- a/src/lib/api/scheduling.ts +++ b/src/lib/api/scheduling.ts @@ -1,4 +1,5 @@ import { apiClient } from './client'; +import type { RelationshipType } from '@/components/session/session-constants'; export interface CompetencyInfo { id: string; @@ -47,15 +48,16 @@ export const schedulingApi = { /** * Submit a vote on a relationship. + * Pass relationshipId for normal votes, or originId+destinationId when swapped. */ submitVote: async ( userId: string, - relationshipId: string, - relationshipType: string + relationshipType: RelationshipType, + opts: { relationshipId?: string; originId?: string; destinationId?: string } ): Promise => { const response = await apiClient.post( '/api/scheduling/vote', - { relationshipId, relationshipType }, + { ...opts, relationshipType }, { headers: { 'X-User-Id': userId } } ); return response.data; diff --git a/src/lib/api/session-helpers.ts b/src/lib/api/session-helpers.ts index 06c9076..3de9ab1 100644 --- a/src/lib/api/session-helpers.ts +++ b/src/lib/api/session-helpers.ts @@ -16,6 +16,7 @@ import type { LearningResource, CompetencyResourceLink, } from './types'; +import type { RelationshipType } from '@/components/session/session-constants'; const GUEST_USER_ID = 'guest'; @@ -82,11 +83,12 @@ export async function getNextRelationshipTaskAction(userId: string): Promise<{ /** * Submit a vote on a competency relationship via the scheduling pipeline. + * Pass opts.relationshipId for normal votes, or opts.originId+opts.destinationId when swapped. */ export async function submitCompetencyVoteAction( userId: string, - relationshipId: string, - relationshipType: string + relationshipType: RelationshipType, + opts: { relationshipId?: string; originId?: string; destinationId?: string } ): Promise<{ success: boolean; voteResponse?: SchedulingVoteResponse; @@ -95,8 +97,8 @@ export async function submitCompetencyVoteAction( try { const voteResponse = await schedulingApi.submitVote( userId, - relationshipId, - relationshipType + relationshipType, + opts ); return { success: true, voteResponse }; } catch (error) { diff --git a/src/pages/SessionPage.tsx b/src/pages/SessionPage.tsx index 565febe..8b23519 100644 --- a/src/pages/SessionPage.tsx +++ b/src/pages/SessionPage.tsx @@ -124,6 +124,7 @@ export function SessionPage() { const [isTransitioning, setIsTransitioning] = useState(false); const [swapRotation, setSwapRotation] = useState(0); const [allDone, setAllDone] = useState(false); + const [isSwapped, setIsSwapped] = useState(false); const [currentRelationshipId, setCurrentRelationshipId] = useState< string | null >(null); @@ -184,6 +185,7 @@ export function SessionPage() { setRelation(null); setResourceMatchType(null); + setIsSwapped(false); if (mappingMode === 'competency') { if (!userId) { @@ -280,7 +282,7 @@ export function SessionPage() { async (type: 'completed' | 'skipped') => { if (type === 'completed') { if (mappingMode === 'competency') { - if (!currentRelationshipId || !relation || !userId) { + if ((!currentRelationshipId && !isSwapped) || !relation || !userId) { setError('Missing required data to submit vote'); return; } @@ -290,10 +292,17 @@ export function SessionPage() { try { const startTime = Date.now(); + const voteOpts = + isSwapped && competencies && competencies.length >= 2 + ? { + originId: competencies[0]!.id, + destinationId: competencies[1]!.id, + } + : { relationshipId: currentRelationshipId! }; const result = await submitCompetencyVoteAction( userId, - currentRelationshipId, - relation + relation, + voteOpts ); const elapsed = Date.now() - startTime; @@ -313,7 +322,7 @@ export function SessionPage() { { type: 'completed', mode: 'competency', - relationshipId: currentRelationshipId, + relationshipId: currentRelationshipId ?? undefined, competencies: competencies ? [...competencies] : undefined, }, ]); @@ -420,6 +429,7 @@ export function SessionPage() { mappingMode, loadMappingPair, currentRelationshipId, + isSwapped, ] ); @@ -629,7 +639,7 @@ export function SessionPage() { ); return ( -
+
@@ -875,6 +885,7 @@ export function SessionPage() { size="sm" onClick={() => { setSwapRotation(prev => prev + 180); + setIsSwapped(prev => !prev); setIsTransitioning(true); setTimeout(() => { if (competencies && competencies.length >= 2) { From 791690105726132f65ff7135b369be57b01eed61 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 17 Feb 2026 10:43:26 +0100 Subject: [PATCH 15/57] feat: add dashboard with contribution heatmap, badges, and session summary --- .../ContributorStatsController.java | 29 ++ .../memo/dto/ContributorStatsResponse.java | 31 ++ .../CompetencyRelationshipVoteRepository.java | 14 + .../memo/service/ContributorStatsService.java | 140 ++++++++ .../V8__seed_additional_competencies.sql | 113 +++++++ src/App.tsx | 2 + .../dashboard/ContributionHeatmap.tsx | 105 ++++++ src/components/navbar.tsx | 29 +- src/components/session/SessionSummary.tsx | 70 ++++ src/lib/api/contributor-stats.ts | 23 ++ src/pages/DashboardPage.tsx | 320 ++++++++++++++++++ src/pages/SessionPage.tsx | 112 +++--- 12 files changed, 932 insertions(+), 56 deletions(-) create mode 100644 server/src/main/java/de/tum/cit/memo/controller/ContributorStatsController.java create mode 100644 server/src/main/java/de/tum/cit/memo/dto/ContributorStatsResponse.java create mode 100644 server/src/main/java/de/tum/cit/memo/service/ContributorStatsService.java create mode 100644 server/src/main/resources/db/migration/V8__seed_additional_competencies.sql create mode 100644 src/components/dashboard/ContributionHeatmap.tsx create mode 100644 src/components/session/SessionSummary.tsx create mode 100644 src/lib/api/contributor-stats.ts create mode 100644 src/pages/DashboardPage.tsx diff --git a/server/src/main/java/de/tum/cit/memo/controller/ContributorStatsController.java b/server/src/main/java/de/tum/cit/memo/controller/ContributorStatsController.java new file mode 100644 index 0000000..09c1ee2 --- /dev/null +++ b/server/src/main/java/de/tum/cit/memo/controller/ContributorStatsController.java @@ -0,0 +1,29 @@ +package de.tum.cit.memo.controller; + +import de.tum.cit.memo.dto.ContributorStatsResponse; +import de.tum.cit.memo.service.ContributorStatsService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/users") +@RequiredArgsConstructor +@Tag(name = "Contributor Stats", description = "Endpoints for contributor statistics and gamification") +public class ContributorStatsController { + + private final ContributorStatsService contributorStatsService; + + @GetMapping("/{userId}/stats") + @Operation(summary = "Get contributor statistics", description = "Returns contribution stats including total votes, streaks, daily counts for heatmap, " + + "and earned badge IDs.") + public ResponseEntity getContributorStats(@PathVariable String userId) { + ContributorStatsResponse stats = contributorStatsService.getStats(userId); + return ResponseEntity.ok(stats); + } +} diff --git a/server/src/main/java/de/tum/cit/memo/dto/ContributorStatsResponse.java b/server/src/main/java/de/tum/cit/memo/dto/ContributorStatsResponse.java new file mode 100644 index 0000000..66bd180 --- /dev/null +++ b/server/src/main/java/de/tum/cit/memo/dto/ContributorStatsResponse.java @@ -0,0 +1,31 @@ +package de.tum.cit.memo.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ContributorStatsResponse { + + private int totalVotes; + private int currentStreak; + private int longestStreak; + private List dailyCounts; + private List earnedBadges; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class DailyCount { + private LocalDate date; + private int count; + } +} diff --git a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipVoteRepository.java b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipVoteRepository.java index 014bd02..fa0c92b 100644 --- a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipVoteRepository.java +++ b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipVoteRepository.java @@ -2,10 +2,24 @@ import de.tum.cit.memo.entity.CompetencyRelationshipVote; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.time.Instant; +import java.util.List; + @Repository public interface CompetencyRelationshipVoteRepository extends JpaRepository { boolean existsByRelationshipIdAndUserId(String relationshipId, String userId); + + long countByUserId(String userId); + + @Query(value = "SELECT CAST(v.created_at AS DATE) AS vote_date, COUNT(*) AS vote_count " + + "FROM competency_relationships_votes v " + + "WHERE v.user_id = :userId AND v.created_at >= :since " + + "GROUP BY CAST(v.created_at AS DATE) " + + "ORDER BY vote_date", nativeQuery = true) + List findDailyVoteCountsByUserId(@Param("userId") String userId, @Param("since") Instant since); } diff --git a/server/src/main/java/de/tum/cit/memo/service/ContributorStatsService.java b/server/src/main/java/de/tum/cit/memo/service/ContributorStatsService.java new file mode 100644 index 0000000..89dd030 --- /dev/null +++ b/server/src/main/java/de/tum/cit/memo/service/ContributorStatsService.java @@ -0,0 +1,140 @@ +package de.tum.cit.memo.service; + +import de.tum.cit.memo.dto.ContributorStatsResponse; +import de.tum.cit.memo.dto.ContributorStatsResponse.DailyCount; +import de.tum.cit.memo.repository.CompetencyRelationshipVoteRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * Computes contributor statistics on-the-fly from vote timestamps. + * All date calculations use UTC. + */ +@Service +@RequiredArgsConstructor +public class ContributorStatsService { + + private final CompetencyRelationshipVoteRepository voteRepository; + + @Transactional(readOnly = true) + public ContributorStatsResponse getStats(String userId) { + LocalDate today = LocalDate.now(ZoneOffset.UTC); + LocalDate since = today.minusDays(365); + Instant sinceInstant = since.atStartOfDay(ZoneOffset.UTC).toInstant(); + + // Fetch raw daily counts from votes + List rawCounts = voteRepository.findDailyVoteCountsByUserId(userId, sinceInstant); + + // Build ordered map of date -> count + Map countMap = new LinkedHashMap<>(); + int totalVotes = 0; + for (Object[] row : rawCounts) { + LocalDate date = ((java.sql.Date) row[0]).toLocalDate(); + int count = ((Number) row[1]).intValue(); + countMap.put(date, count); + totalVotes += count; + } + + // Also count votes before the 365-day window + long olderVotes = voteRepository.countByUserId(userId) - totalVotes; + totalVotes += (int) Math.max(olderVotes, 0); + + // Build daily counts list for heatmap + List dailyCounts = new ArrayList<>(); + for (Map.Entry entry : countMap.entrySet()) { + dailyCounts.add(DailyCount.builder() + .date(entry.getKey()) + .count(entry.getValue()) + .build()); + } + + // Calculate streaks + int currentStreak = calculateCurrentStreak(countMap, today); + int longestStreak = calculateLongestStreak(countMap, since, today); + + // Evaluate badges + List earnedBadges = evaluateBadges(totalVotes, currentStreak, longestStreak); + + return ContributorStatsResponse.builder() + .totalVotes(totalVotes) + .currentStreak(currentStreak) + .longestStreak(longestStreak) + .dailyCounts(dailyCounts) + .earnedBadges(earnedBadges) + .build(); + } + + /** + * Current streak: count consecutive days ending at today (or yesterday). + */ + private int calculateCurrentStreak(Map countMap, LocalDate today) { + // Check if the user contributed today; if not, start from yesterday + LocalDate checkDate = countMap.containsKey(today) ? today : today.minusDays(1); + int streak = 0; + while (countMap.containsKey(checkDate) && countMap.get(checkDate) > 0) { + streak++; + checkDate = checkDate.minusDays(1); + } + return streak; + } + + /** + * Longest streak within the daily counts window. + */ + private int calculateLongestStreak(Map countMap, LocalDate since, LocalDate today) { + int longest = 0; + int current = 0; + LocalDate d = since; + while (!d.isAfter(today)) { + if (countMap.containsKey(d) && countMap.get(d) > 0) { + current++; + longest = Math.max(longest, current); + } else { + current = 0; + } + d = d.plusDays(1); + } + return longest; + } + + /** + * Evaluate which badges the user has earned. + */ + private List evaluateBadges(int totalVotes, int currentStreak, int longestStreak) { + List badges = new ArrayList<>(); + int maxStreak = Math.max(currentStreak, longestStreak); + + if (totalVotes >= 1) { + badges.add("first-steps"); + } + if (totalVotes >= 10) { + badges.add("getting-started"); + } + if (totalVotes >= 50) { + badges.add("half-century"); + } + if (totalVotes >= 100) { + badges.add("century"); + } + if (maxStreak >= 3) { + badges.add("streak-3"); + } + if (maxStreak >= 7) { + badges.add("streak-7"); + } + if (maxStreak >= 30) { + badges.add("streak-30"); + } + + return badges; + } +} diff --git a/server/src/main/resources/db/migration/V8__seed_additional_competencies.sql b/server/src/main/resources/db/migration/V8__seed_additional_competencies.sql new file mode 100644 index 0000000..8e3971a --- /dev/null +++ b/server/src/main/resources/db/migration/V8__seed_additional_competencies.sql @@ -0,0 +1,113 @@ +-- Additional competencies and seed data for testing +-- Adds 15 new competencies, 38 relationship pairs, and 38 backdated votes +-- for the guest user spread across the last ~8 weeks (includes a 6-day streak) + +-- ───────────────────────── Competencies ───────────────────────── + +INSERT INTO competencies (id, title, description, created_at) VALUES +('comp_alg_001', 'Algorithm Design', 'Analyze problems, design efficient algorithms using divide-and-conquer, greedy, and dynamic programming strategies, and argue correctness via invariants and induction.', CURRENT_TIMESTAMP), +('comp_tc_001', 'Type Checking and Inference', 'Implement type-checking algorithms, understand Hindley–Milner inference, and reason about type soundness in statically typed languages.', CURRENT_TIMESTAMP), +('comp_conc_001', 'Concurrency and Parallelism', 'Write concurrent programs using threads, locks, and message passing; reason about race conditions, deadlocks, and memory models.', CURRENT_TIMESTAMP), +('comp_io_001', 'I/O and Side Effects', 'Manage side effects in functional programs using monadic abstractions, distinguish pure from impure code, and sequence effectful computations.', CURRENT_TIMESTAMP), +('comp_test_001', 'Testing and Verification', 'Write unit and property-based tests, apply test-driven development, and use formal verification techniques such as pre/post-conditions.', CURRENT_TIMESTAMP), +('comp_pars_001', 'Parsing and Grammars', 'Define context-free grammars, implement recursive-descent and parser-combinator parsers, and construct abstract syntax trees from source text.', CURRENT_TIMESTAMP), +('comp_eval_001', 'Evaluation Strategies', 'Compare call-by-value, call-by-name, and lazy evaluation; implement interpreters that support different reduction strategies.', CURRENT_TIMESTAMP), +('comp_err_001', 'Error Handling', 'Model errors with option/result types instead of exceptions, propagate errors functionally, and design robust recovery strategies.', CURRENT_TIMESTAMP), +('comp_oop_001', 'Object-Oriented Design', 'Apply encapsulation, inheritance, and composition; use SOLID principles and design patterns such as Observer, Strategy, and Factory.', CURRENT_TIMESTAMP), +('comp_db_001', 'Database Fundamentals', 'Design normalized relational schemas, write SQL queries with joins and aggregations, and understand transaction isolation levels.', CURRENT_TIMESTAMP), +('comp_net_001', 'Networking Basics', 'Understand TCP/IP, HTTP, and DNS; implement client-server communication using sockets and REST APIs.', CURRENT_TIMESTAMP), +('comp_os_001', 'Operating Systems Concepts', 'Explain process scheduling, virtual memory, and file systems; write programs that interact with OS services via system calls.', CURRENT_TIMESTAMP), +('comp_sec_001', 'Software Security', 'Identify common vulnerabilities (XSS, SQL injection, buffer overflow), apply secure coding practices, and understand authentication and encryption fundamentals.', CURRENT_TIMESTAMP), +('comp_git_001', 'Version Control with Git', 'Use branching, merging, and rebasing workflows; resolve merge conflicts and collaborate effectively using pull requests.', CURRENT_TIMESTAMP), +('comp_cpl_001', 'Complexity Theory', 'Classify problems by time and space complexity using Big-O notation; understand P, NP, and NP-completeness with reduction proofs.', CURRENT_TIMESTAMP) +ON CONFLICT DO NOTHING; + +-- ───────────────────────── Relationships ───────────────────────── + +INSERT INTO competency_relationships (id, origin_id, destination_id, total_votes, vote_assumes, vote_extends, vote_matches, vote_unrelated, entropy, created_at, updated_at) VALUES +('rel_seed_01', 'comp_alg_001', 'comp_tc_001', 1, 1, 0, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '55 days', CURRENT_TIMESTAMP - INTERVAL '55 days'), +('rel_seed_02', 'comp_alg_001', 'comp_conc_001', 1, 0, 1, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '52 days', CURRENT_TIMESTAMP - INTERVAL '52 days'), +('rel_seed_03', 'comp_tc_001', 'comp_conc_001', 1, 0, 0, 0, 1, 0.0, CURRENT_TIMESTAMP - INTERVAL '50 days', CURRENT_TIMESTAMP - INTERVAL '50 days'), +('rel_seed_04', 'comp_io_001', 'comp_test_001', 1, 0, 0, 1, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '48 days', CURRENT_TIMESTAMP - INTERVAL '48 days'), +('rel_seed_05', 'comp_pars_001', 'comp_eval_001', 1, 1, 0, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '45 days', CURRENT_TIMESTAMP - INTERVAL '45 days'), +('rel_seed_06', 'comp_err_001', 'comp_oop_001', 1, 0, 1, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '43 days', CURRENT_TIMESTAMP - INTERVAL '43 days'), +('rel_seed_07', 'comp_db_001', 'comp_net_001', 1, 0, 0, 0, 1, 0.0, CURRENT_TIMESTAMP - INTERVAL '40 days', CURRENT_TIMESTAMP - INTERVAL '40 days'), +('rel_seed_08', 'comp_os_001', 'comp_sec_001', 1, 1, 0, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '38 days', CURRENT_TIMESTAMP - INTERVAL '38 days'), +('rel_seed_09', 'comp_git_001', 'comp_cpl_001', 1, 0, 0, 1, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '35 days', CURRENT_TIMESTAMP - INTERVAL '35 days'), +('rel_seed_10', 'comp_alg_001', 'comp_io_001', 1, 0, 1, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '33 days', CURRENT_TIMESTAMP - INTERVAL '33 days'), +('rel_seed_11', 'comp_tc_001', 'comp_pars_001', 1, 1, 0, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '30 days', CURRENT_TIMESTAMP - INTERVAL '30 days'), +('rel_seed_12', 'comp_conc_001', 'comp_err_001', 1, 0, 0, 0, 1, 0.0, CURRENT_TIMESTAMP - INTERVAL '28 days', CURRENT_TIMESTAMP - INTERVAL '28 days'), +('rel_seed_13', 'comp_eval_001', 'comp_db_001', 1, 0, 0, 1, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '26 days', CURRENT_TIMESTAMP - INTERVAL '26 days'), +('rel_seed_14', 'comp_net_001', 'comp_os_001', 1, 1, 0, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '24 days', CURRENT_TIMESTAMP - INTERVAL '24 days'), +('rel_seed_15', 'comp_sec_001', 'comp_git_001', 1, 0, 1, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '21 days', CURRENT_TIMESTAMP - INTERVAL '21 days'), +('rel_seed_16', 'comp_cpl_001', 'comp_test_001', 1, 0, 0, 1, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '19 days', CURRENT_TIMESTAMP - INTERVAL '19 days'), +-- 6-day streak: days 14–19 ago +('rel_seed_17', 'comp_oop_001', 'comp_db_001', 1, 1, 0, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '17 days', CURRENT_TIMESTAMP - INTERVAL '17 days'), +('rel_seed_18', 'comp_io_001', 'comp_pars_001', 1, 0, 0, 0, 1, 0.0, CURRENT_TIMESTAMP - INTERVAL '14 days', CURRENT_TIMESTAMP - INTERVAL '14 days'), +('rel_seed_19', 'comp_eval_001', 'comp_err_001', 1, 0, 1, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '12 days', CURRENT_TIMESTAMP - INTERVAL '12 days'), +('rel_seed_20', 'comp_net_001', 'comp_git_001', 1, 0, 0, 1, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '10 days', CURRENT_TIMESTAMP - INTERVAL '10 days'), +('rel_seed_21', 'comp_alg_001', 'comp_err_001', 1, 1, 0, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '7 days', CURRENT_TIMESTAMP - INTERVAL '7 days'), +('rel_seed_22', 'comp_tc_001', 'comp_db_001', 1, 0, 0, 0, 1, 0.0, CURRENT_TIMESTAMP - INTERVAL '5 days', CURRENT_TIMESTAMP - INTERVAL '5 days'), +('rel_seed_23', 'comp_conc_001', 'comp_os_001', 1, 0, 1, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '3 days', CURRENT_TIMESTAMP - INTERVAL '3 days'), +('rel_seed_24', 'comp_cpl_001', 'comp_oop_001', 1, 0, 0, 1, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '1 day', CURRENT_TIMESTAMP - INTERVAL '1 day'), +-- Extra votes on some days for varied daily counts +('rel_seed_25', 'comp_alg_001', 'comp_cpl_001', 1, 1, 0, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '28 days', CURRENT_TIMESTAMP - INTERVAL '28 days'), +('rel_seed_26', 'comp_io_001', 'comp_err_001', 1, 0, 0, 1, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '21 days', CURRENT_TIMESTAMP - INTERVAL '21 days'), +('rel_seed_27', 'comp_test_001', 'comp_eval_001', 1, 0, 1, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '14 days', CURRENT_TIMESTAMP - INTERVAL '14 days'), +('rel_seed_28', 'comp_oop_001', 'comp_sec_001', 1, 1, 0, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '7 days', CURRENT_TIMESTAMP - INTERVAL '7 days'), +('rel_seed_29', 'comp_pars_001', 'comp_cpl_001', 1, 0, 0, 1, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '5 days', CURRENT_TIMESTAMP - INTERVAL '5 days'), +('rel_seed_30', 'comp_sec_001', 'comp_db_001', 1, 0, 0, 0, 1, 0.0, CURRENT_TIMESTAMP - INTERVAL '3 days', CURRENT_TIMESTAMP - INTERVAL '3 days'), +('rel_seed_31', 'comp_git_001', 'comp_net_001', 1, 1, 0, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '1 day', CURRENT_TIMESTAMP - INTERVAL '1 day'), +('rel_seed_32', 'comp_conc_001', 'comp_test_001', 1, 0, 1, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '10 days', CURRENT_TIMESTAMP - INTERVAL '10 days'), +('rel_seed_33', 'comp_alg_001', 'comp_eval_001', 1, 0, 0, 0, 1, 0.0, CURRENT_TIMESTAMP - INTERVAL '17 days', CURRENT_TIMESTAMP - INTERVAL '17 days'), +('rel_seed_34', 'comp_test_001', 'comp_net_001', 1, 0, 0, 1, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '24 days', CURRENT_TIMESTAMP - INTERVAL '24 days'), +('rel_seed_35', 'comp_git_001', 'comp_oop_001', 1, 0, 1, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '33 days', CURRENT_TIMESTAMP - INTERVAL '33 days'), +-- Streak gap-fillers (days 15, 16, 18) +('rel_seed_36', 'comp_alg_001', 'comp_pars_001', 1, 0, 1, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '15 days', CURRENT_TIMESTAMP - INTERVAL '15 days'), +('rel_seed_37', 'comp_tc_001', 'comp_eval_001', 1, 1, 0, 0, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '16 days', CURRENT_TIMESTAMP - INTERVAL '16 days'), +('rel_seed_38', 'comp_conc_001', 'comp_git_001', 1, 0, 0, 1, 0, 0.0, CURRENT_TIMESTAMP - INTERVAL '18 days', CURRENT_TIMESTAMP - INTERVAL '18 days') +ON CONFLICT DO NOTHING; + +-- ───────────────────────── Votes ───────────────────────── + +INSERT INTO competency_relationships_votes (id, relationship_id, user_id, relationship_type, created_at) VALUES +('vote_seed_01', 'rel_seed_01', 'guest', 'ASSUMES', CURRENT_TIMESTAMP - INTERVAL '55 days'), +('vote_seed_02', 'rel_seed_02', 'guest', 'EXTENDS', CURRENT_TIMESTAMP - INTERVAL '52 days'), +('vote_seed_03', 'rel_seed_03', 'guest', 'UNRELATED', CURRENT_TIMESTAMP - INTERVAL '50 days'), +('vote_seed_04', 'rel_seed_04', 'guest', 'MATCHES', CURRENT_TIMESTAMP - INTERVAL '48 days'), +('vote_seed_05', 'rel_seed_05', 'guest', 'ASSUMES', CURRENT_TIMESTAMP - INTERVAL '45 days'), +('vote_seed_06', 'rel_seed_06', 'guest', 'EXTENDS', CURRENT_TIMESTAMP - INTERVAL '43 days'), +('vote_seed_07', 'rel_seed_07', 'guest', 'UNRELATED', CURRENT_TIMESTAMP - INTERVAL '40 days'), +('vote_seed_08', 'rel_seed_08', 'guest', 'ASSUMES', CURRENT_TIMESTAMP - INTERVAL '38 days'), +('vote_seed_09', 'rel_seed_09', 'guest', 'MATCHES', CURRENT_TIMESTAMP - INTERVAL '35 days'), +('vote_seed_10', 'rel_seed_10', 'guest', 'EXTENDS', CURRENT_TIMESTAMP - INTERVAL '33 days'), +('vote_seed_11', 'rel_seed_11', 'guest', 'ASSUMES', CURRENT_TIMESTAMP - INTERVAL '30 days'), +('vote_seed_12', 'rel_seed_12', 'guest', 'UNRELATED', CURRENT_TIMESTAMP - INTERVAL '28 days'), +('vote_seed_13', 'rel_seed_13', 'guest', 'MATCHES', CURRENT_TIMESTAMP - INTERVAL '26 days'), +('vote_seed_14', 'rel_seed_14', 'guest', 'ASSUMES', CURRENT_TIMESTAMP - INTERVAL '24 days'), +('vote_seed_15', 'rel_seed_15', 'guest', 'EXTENDS', CURRENT_TIMESTAMP - INTERVAL '21 days'), +('vote_seed_16', 'rel_seed_16', 'guest', 'MATCHES', CURRENT_TIMESTAMP - INTERVAL '19 days'), +('vote_seed_17', 'rel_seed_17', 'guest', 'ASSUMES', CURRENT_TIMESTAMP - INTERVAL '17 days'), +('vote_seed_18', 'rel_seed_18', 'guest', 'UNRELATED', CURRENT_TIMESTAMP - INTERVAL '14 days'), +('vote_seed_19', 'rel_seed_19', 'guest', 'EXTENDS', CURRENT_TIMESTAMP - INTERVAL '12 days'), +('vote_seed_20', 'rel_seed_20', 'guest', 'MATCHES', CURRENT_TIMESTAMP - INTERVAL '10 days'), +('vote_seed_21', 'rel_seed_21', 'guest', 'ASSUMES', CURRENT_TIMESTAMP - INTERVAL '7 days'), +('vote_seed_22', 'rel_seed_22', 'guest', 'UNRELATED', CURRENT_TIMESTAMP - INTERVAL '5 days'), +('vote_seed_23', 'rel_seed_23', 'guest', 'EXTENDS', CURRENT_TIMESTAMP - INTERVAL '3 days'), +('vote_seed_24', 'rel_seed_24', 'guest', 'MATCHES', CURRENT_TIMESTAMP - INTERVAL '1 day'), +('vote_seed_25', 'rel_seed_25', 'guest', 'ASSUMES', CURRENT_TIMESTAMP - INTERVAL '28 days'), +('vote_seed_26', 'rel_seed_26', 'guest', 'MATCHES', CURRENT_TIMESTAMP - INTERVAL '21 days'), +('vote_seed_27', 'rel_seed_27', 'guest', 'EXTENDS', CURRENT_TIMESTAMP - INTERVAL '14 days'), +('vote_seed_28', 'rel_seed_28', 'guest', 'ASSUMES', CURRENT_TIMESTAMP - INTERVAL '7 days'), +('vote_seed_29', 'rel_seed_29', 'guest', 'MATCHES', CURRENT_TIMESTAMP - INTERVAL '5 days'), +('vote_seed_30', 'rel_seed_30', 'guest', 'UNRELATED', CURRENT_TIMESTAMP - INTERVAL '3 days'), +('vote_seed_31', 'rel_seed_31', 'guest', 'ASSUMES', CURRENT_TIMESTAMP - INTERVAL '1 day'), +('vote_seed_32', 'rel_seed_32', 'guest', 'EXTENDS', CURRENT_TIMESTAMP - INTERVAL '10 days'), +('vote_seed_33', 'rel_seed_33', 'guest', 'UNRELATED', CURRENT_TIMESTAMP - INTERVAL '17 days'), +('vote_seed_34', 'rel_seed_34', 'guest', 'MATCHES', CURRENT_TIMESTAMP - INTERVAL '24 days'), +('vote_seed_35', 'rel_seed_35', 'guest', 'EXTENDS', CURRENT_TIMESTAMP - INTERVAL '33 days'), +-- Streak gap-fillers +('vote_seed_36', 'rel_seed_36', 'guest', 'EXTENDS', CURRENT_TIMESTAMP - INTERVAL '15 days'), +('vote_seed_37', 'rel_seed_37', 'guest', 'ASSUMES', CURRENT_TIMESTAMP - INTERVAL '16 days'), +('vote_seed_38', 'rel_seed_38', 'guest', 'MATCHES', CURRENT_TIMESTAMP - INTERVAL '18 days') +ON CONFLICT DO NOTHING; diff --git a/src/App.tsx b/src/App.tsx index 1c7a3ac..3df2686 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,6 +7,7 @@ import { HomePage } from './pages/HomePage'; import { AboutPage } from './pages/AboutPage'; import { SessionPage } from './pages/SessionPage'; import { OnboardingPage } from './pages/OnboardingPage'; +import { DashboardPage } from './pages/DashboardPage'; export function App() { const [queryClient] = useState( @@ -27,6 +28,7 @@ export function App() { }> } /> + } /> } /> } /> } /> diff --git a/src/components/dashboard/ContributionHeatmap.tsx b/src/components/dashboard/ContributionHeatmap.tsx new file mode 100644 index 0000000..5c8c687 --- /dev/null +++ b/src/components/dashboard/ContributionHeatmap.tsx @@ -0,0 +1,105 @@ +import { useMemo, useRef, useEffect } from 'react'; +import type { DailyCount } from '@/lib/api/contributor-stats'; + +/* ───────────────────────── Helpers ───────────────────────── */ + +export function heatmapColor(count: number): string { + if (count === 0) return 'bg-slate-200'; + if (count <= 2) return 'bg-blue-400'; + if (count <= 5) return 'bg-blue-500'; + if (count <= 10) return 'bg-indigo-600'; + return 'bg-indigo-800'; +} + +const MONTHS = [ + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', +]; + +const DAY_LABELS = ['Mon', '', '', 'Thu', '', '', 'Sun']; + +function buildGrid(dailyCounts: DailyCount[]) { + const map = new Map(); + for (const dc of dailyCounts) map.set(dc.date, dc.count); + + const today = new Date(); + const todayIdx = (today.getDay() + 6) % 7; + const totalDays = 52 * 7 + todayIdx + 1; + const start = new Date(today); + start.setDate(start.getDate() - totalDays + 1); + + const weeks: { date: Date; count: number }[][] = []; + let week: { date: Date; count: number }[] = []; + + for (let i = 0; i < totalDays; i++) { + const d = new Date(start); + d.setDate(d.getDate() + i); + week.push({ date: d, count: map.get(d.toISOString().split('T')[0]!) ?? 0 }); + if (week.length === 7) { weeks.push(week); week = []; } + } + if (week.length) weeks.push(week); + return weeks; +} + +/* ───────────────────────── Component ───────────────────────── */ + +export function ContributionHeatmap({ dailyCounts }: { dailyCounts: DailyCount[] }) { + const weeks = useMemo(() => buildGrid(dailyCounts), [dailyCounts]); + const scrollRef = useRef(null); + + useEffect(() => { + const el = scrollRef.current; + if (el) el.scrollLeft = el.scrollWidth; + }, [weeks]); + + return ( +
+
+ {DAY_LABELS.map((label, i) => ( +
+ + {label} + +
+ ))} +
+ +
+
+
+ {weeks.map((week, i) => { + const m = week[0].date.getMonth(); + const prev = i > 0 ? weeks[i - 1][0].date.getMonth() : -1; + return ( +
+ {m !== prev && ( + + {MONTHS[m]} + + )} +
+ ); + })} +
+ + {/* Grid */} +
+ {weeks.map((week, wi) => ( +
+ {week.map((day, di) => ( +
+ ))} +
+ ))} +
+
+ +
+
+ ); +} diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx index 6126062..2617246 100644 --- a/src/components/navbar.tsx +++ b/src/components/navbar.tsx @@ -2,6 +2,7 @@ import { Link, useLocation } from 'react-router-dom'; import { useTheme } from './use-theme'; import { useEffect, useState } from 'react'; import { cn } from '@/lib/utils'; +import { CircleUser } from 'lucide-react'; const navItems = [ { href: '/', label: 'Home' }, @@ -96,12 +97,13 @@ export function Navbar() {
- {/* Right side - Dark mode toggle & Login */}
- {/* Dark mode toggle */} - {/* Login button */} - Start Contributing + + Dashboard
diff --git a/src/components/session/SessionSummary.tsx b/src/components/session/SessionSummary.tsx new file mode 100644 index 0000000..8a7577e --- /dev/null +++ b/src/components/session/SessionSummary.tsx @@ -0,0 +1,70 @@ +import { Link } from 'react-router-dom'; +import { Button } from '@/components/ui/button'; + +interface SessionStats { + completed: number; + skipped: number; +} + +interface SessionSummaryProps { + stats: SessionStats; + onContinue: () => void; +} + +export function SessionSummary({ stats, onContinue }: SessionSummaryProps) { + return ( +
+
+
+
+ +
+
+
🧠
+

+ Session Complete +

+

+ Great work! Here's what you accomplished. +

+
+ +
+
+

+ {stats.completed} +

+

+ Mappings +

+
+
+

+ {stats.skipped} +

+

+ Skipped +

+
+
+ +
+ + +
+
+
+
+ ); +} diff --git a/src/lib/api/contributor-stats.ts b/src/lib/api/contributor-stats.ts new file mode 100644 index 0000000..bdde37e --- /dev/null +++ b/src/lib/api/contributor-stats.ts @@ -0,0 +1,23 @@ +import { apiClient } from './client'; + +export interface DailyCount { + date: string; + count: number; +} + +export interface ContributorStats { + totalVotes: number; + currentStreak: number; + longestStreak: number; + dailyCounts: DailyCount[]; + earnedBadges: string[]; +} + +export const contributorStatsApi = { + getStats: async (userId: string): Promise => { + const response = await apiClient.get( + `/api/users/${userId}/stats` + ); + return response.data; + }, +}; diff --git a/src/pages/DashboardPage.tsx b/src/pages/DashboardPage.tsx new file mode 100644 index 0000000..327596e --- /dev/null +++ b/src/pages/DashboardPage.tsx @@ -0,0 +1,320 @@ +import { useEffect, useState, useMemo } from 'react'; +import { Link } from 'react-router-dom'; +import { Button } from '@/components/ui/button'; +import { + contributorStatsApi, + type ContributorStats, +} from '@/lib/api/contributor-stats'; +import { + Flame, + Trophy, + Zap, + Mountain, + Target, + Award, + Star, +} from 'lucide-react'; +import { ContributionHeatmap, heatmapColor } from '@/components/dashboard/ContributionHeatmap'; + +const GUEST_USER_ID = 'guest'; + +interface BadgeDef { + id: string; + name: string; + description: string; + icon: React.ElementType; + gradient: string; + glowColor: string; +} + +const BADGE_DEFS: BadgeDef[] = [ + { + id: 'first-steps', + name: 'The First Node', + description: '1+ mapping', + icon: Star, + gradient: 'from-emerald-400 to-teal-500', + glowColor: 'rgba(16,185,129,0.35)', + }, + { + id: 'getting-started', + name: 'Getting Started', + description: '10+ mappings', + icon: Target, + gradient: 'from-blue-400 to-indigo-500', + glowColor: 'rgba(99,102,241,0.35)', + }, + { + id: 'half-century', + name: 'Half Century', + description: '50+ mappings', + icon: Award, + gradient: 'from-violet-400 to-purple-600', + glowColor: 'rgba(139,92,246,0.35)', + }, + { + id: 'century', + name: 'Century', + description: '100+ mappings', + icon: Trophy, + gradient: 'from-amber-400 to-orange-500', + glowColor: 'rgba(245,158,11,0.35)', + }, + { + id: 'streak-3', + name: 'On Fire', + description: '3-day streak', + icon: Flame, + gradient: 'from-orange-400 to-red-500', + glowColor: 'rgba(239,68,68,0.35)', + }, + { + id: 'streak-7', + name: 'Dedicated', + description: '7-day streak', + icon: Zap, + gradient: 'from-yellow-400 to-amber-500', + glowColor: 'rgba(245,158,11,0.35)', + }, + { + id: 'streak-30', + name: 'Monthly Mapper', + description: '30-day streak', + icon: Mountain, + gradient: 'from-cyan-400 to-blue-600', + glowColor: 'rgba(6,182,212,0.35)', + }, +]; + +function BadgeCard({ badge, earned }: { badge: BadgeDef; earned: boolean }) { + const Icon = badge.icon; + return ( +
+ {earned && ( +
+ )} +
+
+ +
+
+
+

{badge.name}

+
+

{badge.description}

+
+
+ {earned && ( +
+
+ + + +
+
+ )} +
+ ); +} + +function StatCard({ + label, + value, + icon, + accentColor, +}: { + label: string; + value: string | number; + icon: React.ReactNode; + accentColor: string; +}) { + return ( +
+
+
+
+ {icon} + + {label} + +
+

{value}

+
+
+ ); +} + +export function DashboardPage() { + const [stats, setStats] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + async function loadStats() { + try { + setLoading(true); + const data = await contributorStatsApi.getStats(GUEST_USER_ID); + setStats(data); + } catch (err) { + setError( + err instanceof Error + ? err.message + : 'Failed to load stats. Is the server running?' + ); + } finally { + setLoading(false); + } + } + void loadStats(); + }, []); + + const earnedSet = useMemo( + () => new Set(stats?.earnedBadges ?? []), + [stats?.earnedBadges] + ); + + return ( +
+
+
+
+
+
+ +
+
+
+

+ Your Dashboard +

+

+ Track your contributions and unlock milestones. +

+
+ +
+ + {error && ( +
+

Failed to load statistics

+

{error}

+
+ )} + + {loading && !error && ( +
+ {[1, 2, 3].map(i => ( +
+ ))} +
+ )} + + {stats && !loading && ( + <> +
+
+ + + + } + accentColor="rgba(99,102,241,0.3)" + /> + 0 ? `${stats.currentStreak} day${stats.currentStreak !== 1 ? 's' : ''}` : '—'} / ${stats.longestStreak > 0 ? `${stats.longestStreak} day${stats.longestStreak !== 1 ? 's' : ''}` : '—'}` + } + icon={} + accentColor="rgba(239,68,68,0.25)" + /> +
+ +
+
+

+ Contribution Activity +

+
+ Less + {[0, 2, 5, 10, 15].map(level => ( +
+ ))} + More +
+
+
+ +
+
+
+ +
+
+

+ Milestone Badges +

+ + {earnedSet.size} / {BADGE_DEFS.length} earned + +
+
+ {BADGE_DEFS.map(badge => ( + + ))} +
+
+ + )} +
+
+ ); +} diff --git a/src/pages/SessionPage.tsx b/src/pages/SessionPage.tsx index 8b23519..c5d9d2e 100644 --- a/src/pages/SessionPage.tsx +++ b/src/pages/SessionPage.tsx @@ -1,4 +1,5 @@ import { useEffect, useState, useCallback, useRef } from 'react'; +import { Link } from 'react-router-dom'; import { getRandomCompetenciesAction, @@ -18,7 +19,7 @@ import { import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Kbd } from '@/components/ui/kbd'; -import { ArrowRight, ArrowLeftRight, Check, Link2 } from 'lucide-react'; +import { ArrowRight, ArrowLeftRight, Check, Link2, LogOut } from 'lucide-react'; import { Card, CardDescription, @@ -45,6 +46,7 @@ import { RESOURCE_ICONS, RESOURCE_MATCH_TYPE_TEXT_COLORS, } from '@/components/session/session-constants'; +import { SessionSummary } from '@/components/session/SessionSummary'; type SessionStats = { completed: number; @@ -128,6 +130,7 @@ export function SessionPage() { const [currentRelationshipId, setCurrentRelationshipId] = useState< string | null >(null); + const [showSessionSummary, setShowSessionSummary] = useState(false); const { hoveredValue: hoveredRelation, @@ -157,7 +160,7 @@ export function SessionPage() { } else { setError( result.error ?? - 'Failed to load user information. Please try again later.' + 'Failed to load user information. Please try again later.' ); } } catch (err) { @@ -198,7 +201,7 @@ export function SessionPage() { if (!result.success) { setError( result.error ?? - 'An unexpected error occurred while fetching the next task.' + 'An unexpected error occurred while fetching the next task.' ); if (isInitialLoad) setCompetencies([]); setIsTransitioning(false); @@ -243,7 +246,7 @@ export function SessionPage() { if (!compResult.success || !compResult.competencies?.length) { setError( compResult.error ?? - 'Failed to fetch competency for resource mapping.' + 'Failed to fetch competency for resource mapping.' ); if (isInitialLoad) setCompetencies([]); setIsTransitioning(false); @@ -253,7 +256,7 @@ export function SessionPage() { if (!resourceResult.success || !resourceResult.resource) { setError( resourceResult.error ?? - 'Failed to fetch learning resource. Make sure resources are seeded.' + 'Failed to fetch learning resource. Make sure resources are seeded.' ); setCompetencies(compResult.competencies); setLearningResource(null); @@ -278,6 +281,13 @@ export function SessionPage() { void loadMappingPair(isInitialLoad); }, [mappingMode, loadMappingPair]); + const handleContinueSession = useCallback(() => { + setShowSessionSummary(false); + setStats({ completed: 0, skipped: 0 }); + setHistory([]); + void loadMappingPair(true); + }, [loadMappingPair]); + const handleAction = useCallback( async (type: 'completed' | 'skipped') => { if (type === 'completed') { @@ -295,9 +305,9 @@ export function SessionPage() { const voteOpts = isSwapped && competencies && competencies.length >= 2 ? { - originId: competencies[0]!.id, - destinationId: competencies[1]!.id, - } + originId: competencies[0]!.id, + destinationId: competencies[1]!.id, + } : { relationshipId: currentRelationshipId! }; const result = await submitCompetencyVoteAction( userId, @@ -665,42 +675,50 @@ export function SessionPage() {
-
- - + +
+
@@ -970,8 +988,8 @@ export function SessionPage() { {relation === 'UNRELATED' ? 'is unrelated to' : RELATIONSHIP_TYPES.find( - rt => rt.value === relation - )?.label.toLowerCase() || ''} + rt => rt.value === relation + )?.label.toLowerCase() || ''} {' '} {competencies[1]!.title} @@ -1147,10 +1165,9 @@ export function SessionPage() { className={` relative flex items-center justify-center gap-2 px-6 py-3 rounded-xl text-sm font-bold text-white min-w-[180px] - ${ - mappingMode === 'resource' - ? 'bg-gradient-to-r from-pink-600 to-pink-500 shadow-lg shadow-pink-500/20 hover:shadow-xl hover:shadow-pink-500/30' - : 'bg-gradient-to-r from-[#0a4da2] to-[#5538d1] shadow-lg shadow-blue-500/20 hover:shadow-xl hover:shadow-blue-500/30' + ${mappingMode === 'resource' + ? 'bg-gradient-to-r from-pink-600 to-pink-500 shadow-lg shadow-pink-500/20 hover:shadow-xl hover:shadow-pink-500/30' + : 'bg-gradient-to-r from-[#0a4da2] to-[#5538d1] shadow-lg shadow-blue-500/20 hover:shadow-xl hover:shadow-blue-500/30' } transition-all duration-200 ease-out hover:scale-[1.02] @@ -1182,6 +1199,11 @@ export function SessionPage() { )}

+ + {/* ─── Session Summary Overlay ─── */} + {showSessionSummary && ( + + )}
); } From 4b032446c77f548756b856306319fc82efbd31ca Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 17 Feb 2026 10:47:58 +0100 Subject: [PATCH 16/57] style: fix Prettier formatting --- .../dashboard/ContributionHeatmap.tsx | 179 ++++++++++-------- src/components/session/SessionSummary.tsx | 110 +++++------ src/lib/heatmap-helpers.ts | 7 + src/pages/DashboardPage.tsx | 16 +- src/pages/SessionPage.tsx | 40 ++-- 5 files changed, 191 insertions(+), 161 deletions(-) create mode 100644 src/lib/heatmap-helpers.ts diff --git a/src/components/dashboard/ContributionHeatmap.tsx b/src/components/dashboard/ContributionHeatmap.tsx index 5c8c687..6a0897c 100644 --- a/src/components/dashboard/ContributionHeatmap.tsx +++ b/src/components/dashboard/ContributionHeatmap.tsx @@ -1,105 +1,126 @@ import { useMemo, useRef, useEffect } from 'react'; import type { DailyCount } from '@/lib/api/contributor-stats'; +import { heatmapColor } from '@/lib/heatmap-helpers'; /* ───────────────────────── Helpers ───────────────────────── */ -export function heatmapColor(count: number): string { - if (count === 0) return 'bg-slate-200'; - if (count <= 2) return 'bg-blue-400'; - if (count <= 5) return 'bg-blue-500'; - if (count <= 10) return 'bg-indigo-600'; - return 'bg-indigo-800'; -} - const MONTHS = [ - 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec', ]; const DAY_LABELS = ['Mon', '', '', 'Thu', '', '', 'Sun']; function buildGrid(dailyCounts: DailyCount[]) { - const map = new Map(); - for (const dc of dailyCounts) map.set(dc.date, dc.count); + const map = new Map(); + for (const dc of dailyCounts) map.set(dc.date, dc.count); - const today = new Date(); - const todayIdx = (today.getDay() + 6) % 7; - const totalDays = 52 * 7 + todayIdx + 1; - const start = new Date(today); - start.setDate(start.getDate() - totalDays + 1); + const today = new Date(); + const todayIdx = (today.getDay() + 6) % 7; + const totalDays = 52 * 7 + todayIdx + 1; + const start = new Date(today); + start.setDate(start.getDate() - totalDays + 1); - const weeks: { date: Date; count: number }[][] = []; - let week: { date: Date; count: number }[] = []; + const weeks: { date: Date; count: number }[][] = []; + let week: { date: Date; count: number }[] = []; - for (let i = 0; i < totalDays; i++) { - const d = new Date(start); - d.setDate(d.getDate() + i); - week.push({ date: d, count: map.get(d.toISOString().split('T')[0]!) ?? 0 }); - if (week.length === 7) { weeks.push(week); week = []; } + for (let i = 0; i < totalDays; i++) { + const d = new Date(start); + d.setDate(d.getDate() + i); + week.push({ date: d, count: map.get(d.toISOString().split('T')[0]!) ?? 0 }); + if (week.length === 7) { + weeks.push(week); + week = []; } - if (week.length) weeks.push(week); - return weeks; + } + if (week.length) weeks.push(week); + return weeks; } /* ───────────────────────── Component ───────────────────────── */ -export function ContributionHeatmap({ dailyCounts }: { dailyCounts: DailyCount[] }) { - const weeks = useMemo(() => buildGrid(dailyCounts), [dailyCounts]); - const scrollRef = useRef(null); +export function ContributionHeatmap({ + dailyCounts, +}: { + dailyCounts: DailyCount[]; +}) { + const weeks = useMemo(() => buildGrid(dailyCounts), [dailyCounts]); + const scrollRef = useRef(null); - useEffect(() => { - const el = scrollRef.current; - if (el) el.scrollLeft = el.scrollWidth; - }, [weeks]); + useEffect(() => { + const el = scrollRef.current; + if (el) el.scrollLeft = el.scrollWidth; + }, [weeks]); - return ( -
-
- {DAY_LABELS.map((label, i) => ( -
- - {label} - -
- ))} -
+ return ( +
+
+ {DAY_LABELS.map((label, i) => ( +
+ + {label} + +
+ ))} +
-
-
-
- {weeks.map((week, i) => { - const m = week[0].date.getMonth(); - const prev = i > 0 ? weeks[i - 1][0].date.getMonth() : -1; - return ( -
- {m !== prev && ( - - {MONTHS[m]} - - )} -
- ); - })} -
- - {/* Grid */} -
- {weeks.map((week, wi) => ( -
- {week.map((day, di) => ( -
- ))} -
- ))} -
+
+
+
+ {weeks.map((week, i) => { + const m = week[0].date.getMonth(); + const prev = i > 0 ? weeks[i - 1][0].date.getMonth() : -1; + return ( +
+ {m !== prev && ( + + {MONTHS[m]} + + )}
+ ); + })} +
-
+ {/* Grid */} +
+ {weeks.map((week, wi) => ( +
+ {week.map((day, di) => ( +
+ ))} +
+ ))} +
- ); +
+
+ ); } diff --git a/src/components/session/SessionSummary.tsx b/src/components/session/SessionSummary.tsx index 8a7577e..1a3adfb 100644 --- a/src/components/session/SessionSummary.tsx +++ b/src/components/session/SessionSummary.tsx @@ -2,69 +2,69 @@ import { Link } from 'react-router-dom'; import { Button } from '@/components/ui/button'; interface SessionStats { - completed: number; - skipped: number; + completed: number; + skipped: number; } interface SessionSummaryProps { - stats: SessionStats; - onContinue: () => void; + stats: SessionStats; + onContinue: () => void; } export function SessionSummary({ stats, onContinue }: SessionSummaryProps) { - return ( -
-
-
-
+ return ( +
+
+
+
-
-
-
🧠
-

- Session Complete -

-

- Great work! Here's what you accomplished. -

-
+
+
+
🧠
+

+ Session Complete +

+

+ Great work! Here's what you accomplished. +

+
-
-
-

- {stats.completed} -

-

- Mappings -

-
-
-

- {stats.skipped} -

-

- Skipped -

-
-
- -
- - -
-
+
+
+

+ {stats.completed} +

+

+ Mappings +

+
+
+

+ {stats.skipped} +

+

+ Skipped +

+
+ +
+ + +
- ); +
+
+ ); } diff --git a/src/lib/heatmap-helpers.ts b/src/lib/heatmap-helpers.ts new file mode 100644 index 0000000..271988e --- /dev/null +++ b/src/lib/heatmap-helpers.ts @@ -0,0 +1,7 @@ +export function heatmapColor(count: number): string { + if (count === 0) return 'bg-slate-200'; + if (count <= 2) return 'bg-blue-400'; + if (count <= 5) return 'bg-blue-500'; + if (count <= 10) return 'bg-indigo-600'; + return 'bg-indigo-800'; +} diff --git a/src/pages/DashboardPage.tsx b/src/pages/DashboardPage.tsx index 327596e..485c0c9 100644 --- a/src/pages/DashboardPage.tsx +++ b/src/pages/DashboardPage.tsx @@ -14,7 +14,8 @@ import { Award, Star, } from 'lucide-react'; -import { ContributionHeatmap, heatmapColor } from '@/components/dashboard/ContributionHeatmap'; +import { ContributionHeatmap } from '@/components/dashboard/ContributionHeatmap'; +import { heatmapColor } from '@/lib/heatmap-helpers'; const GUEST_USER_ID = 'guest'; @@ -90,10 +91,11 @@ function BadgeCard({ badge, earned }: { badge: BadgeDef; earned: boolean }) { const Icon = badge.icon; return (
{earned && (
0 ? `${stats.currentStreak} day${stats.currentStreak !== 1 ? 's' : ''}` : '—'} / ${stats.longestStreak > 0 ? `${stats.longestStreak} day${stats.longestStreak !== 1 ? 's' : ''}` : '—'}` - } + value={`🔥 ${stats.currentStreak > 0 ? `${stats.currentStreak} day${stats.currentStreak !== 1 ? 's' : ''}` : '—'} / ${stats.longestStreak > 0 ? `${stats.longestStreak} day${stats.longestStreak !== 1 ? 's' : ''}` : '—'}`} icon={} accentColor="rgba(239,68,68,0.25)" /> diff --git a/src/pages/SessionPage.tsx b/src/pages/SessionPage.tsx index c5d9d2e..1a0a294 100644 --- a/src/pages/SessionPage.tsx +++ b/src/pages/SessionPage.tsx @@ -1,5 +1,4 @@ import { useEffect, useState, useCallback, useRef } from 'react'; -import { Link } from 'react-router-dom'; import { getRandomCompetenciesAction, @@ -160,7 +159,7 @@ export function SessionPage() { } else { setError( result.error ?? - 'Failed to load user information. Please try again later.' + 'Failed to load user information. Please try again later.' ); } } catch (err) { @@ -201,7 +200,7 @@ export function SessionPage() { if (!result.success) { setError( result.error ?? - 'An unexpected error occurred while fetching the next task.' + 'An unexpected error occurred while fetching the next task.' ); if (isInitialLoad) setCompetencies([]); setIsTransitioning(false); @@ -246,7 +245,7 @@ export function SessionPage() { if (!compResult.success || !compResult.competencies?.length) { setError( compResult.error ?? - 'Failed to fetch competency for resource mapping.' + 'Failed to fetch competency for resource mapping.' ); if (isInitialLoad) setCompetencies([]); setIsTransitioning(false); @@ -256,7 +255,7 @@ export function SessionPage() { if (!resourceResult.success || !resourceResult.resource) { setError( resourceResult.error ?? - 'Failed to fetch learning resource. Make sure resources are seeded.' + 'Failed to fetch learning resource. Make sure resources are seeded.' ); setCompetencies(compResult.competencies); setLearningResource(null); @@ -305,9 +304,9 @@ export function SessionPage() { const voteOpts = isSwapped && competencies && competencies.length >= 2 ? { - originId: competencies[0]!.id, - destinationId: competencies[1]!.id, - } + originId: competencies[0]!.id, + destinationId: competencies[1]!.id, + } : { relationshipId: currentRelationshipId! }; const result = await submitCompetencyVoteAction( userId, @@ -686,9 +685,10 @@ export function SessionPage() { }} className={` h-full px-3 text-xs font-semibold rounded-md transition-all duration-200 flex items-center justify-center - ${mappingMode === 'competency' - ? 'bg-white text-slate-900 shadow-sm' - : 'text-slate-500 hover:text-slate-700' + ${ + mappingMode === 'competency' + ? 'bg-white text-slate-900 shadow-sm' + : 'text-slate-500 hover:text-slate-700' } `} > @@ -703,9 +703,10 @@ export function SessionPage() { }} className={` h-full px-3 text-xs font-semibold rounded-md transition-all duration-200 flex items-center justify-center - ${mappingMode === 'resource' - ? 'bg-white text-slate-900 shadow-sm' - : 'text-slate-500 hover:text-slate-700' + ${ + mappingMode === 'resource' + ? 'bg-white text-slate-900 shadow-sm' + : 'text-slate-500 hover:text-slate-700' } `} > @@ -988,8 +989,8 @@ export function SessionPage() { {relation === 'UNRELATED' ? 'is unrelated to' : RELATIONSHIP_TYPES.find( - rt => rt.value === relation - )?.label.toLowerCase() || ''} + rt => rt.value === relation + )?.label.toLowerCase() || ''} {' '} {competencies[1]!.title} @@ -1165,9 +1166,10 @@ export function SessionPage() { className={` relative flex items-center justify-center gap-2 px-6 py-3 rounded-xl text-sm font-bold text-white min-w-[180px] - ${mappingMode === 'resource' - ? 'bg-gradient-to-r from-pink-600 to-pink-500 shadow-lg shadow-pink-500/20 hover:shadow-xl hover:shadow-pink-500/30' - : 'bg-gradient-to-r from-[#0a4da2] to-[#5538d1] shadow-lg shadow-blue-500/20 hover:shadow-xl hover:shadow-blue-500/30' + ${ + mappingMode === 'resource' + ? 'bg-gradient-to-r from-pink-600 to-pink-500 shadow-lg shadow-pink-500/20 hover:shadow-xl hover:shadow-pink-500/30' + : 'bg-gradient-to-r from-[#0a4da2] to-[#5538d1] shadow-lg shadow-blue-500/20 hover:shadow-xl hover:shadow-blue-500/30' } transition-all duration-200 ease-out hover:scale-[1.02] From 2190551cef64d714833468bfb0fc62ac8df0ed64 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 24 Feb 2026 22:45:53 +0100 Subject: [PATCH 17/57] Update heatmap --- .../dashboard/ContributionHeatmap.tsx | 219 +++++++++++------- 1 file changed, 129 insertions(+), 90 deletions(-) diff --git a/src/components/dashboard/ContributionHeatmap.tsx b/src/components/dashboard/ContributionHeatmap.tsx index 6a0897c..9c1e717 100644 --- a/src/components/dashboard/ContributionHeatmap.tsx +++ b/src/components/dashboard/ContributionHeatmap.tsx @@ -2,97 +2,125 @@ import { useMemo, useRef, useEffect } from 'react'; import type { DailyCount } from '@/lib/api/contributor-stats'; import { heatmapColor } from '@/lib/heatmap-helpers'; -/* ───────────────────────── Helpers ───────────────────────── */ - -const MONTHS = [ - 'Jan', - 'Feb', - 'Mar', - 'Apr', - 'May', - 'Jun', - 'Jul', - 'Aug', - 'Sep', - 'Oct', - 'Nov', - 'Dec', -]; - -const DAY_LABELS = ['Mon', '', '', 'Thu', '', '', 'Sun']; +const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; +const WEEKS_PER_COLUMN = 4; +const SQUARE_SIZE = 26; +// calculate the grid data for the heatmap function buildGrid(dailyCounts: DailyCount[]) { - const map = new Map(); - for (const dc of dailyCounts) map.set(dc.date, dc.count); + const countByDate = new Map(); + for (const dc of dailyCounts) { + countByDate.set(dc.date, dc.count); + } const today = new Date(); - const todayIdx = (today.getDay() + 6) % 7; - const totalDays = 52 * 7 + todayIdx + 1; - const start = new Date(today); - start.setDate(start.getDate() - totalDays + 1); - - const weeks: { date: Date; count: number }[][] = []; - let week: { date: Date; count: number }[] = []; - - for (let i = 0; i < totalDays; i++) { - const d = new Date(start); - d.setDate(d.getDate() + i); - week.push({ date: d, count: map.get(d.toISOString().split('T')[0]!) ?? 0 }); - if (week.length === 7) { - weeks.push(week); - week = []; + + // end at sunday of this week + const daysSinceMondayEnd = (today.getDay() + 6) % 7; + const endDate = new Date(today); + endDate.setDate(today.getDate() + (6 - daysSinceMondayEnd)); + + // start around april 1st 2024 + const april1st2024 = new Date(2024, 3, 1); + const daysSinceMondayStart = (april1st2024.getDay() + 6) % 7; + const startDate = new Date(april1st2024); + startDate.setDate(april1st2024.getDate() - daysSinceMondayStart); + + const columns: { date: Date; count: number }[][] = []; + let currentColumn: { date: Date; count: number }[] = []; + + let currentWeekStart = new Date(startDate); + + while (currentWeekStart <= endDate) { + let weeklyCount = 0; + + // add up all the days in the week + for (let d = 0; d < 7; d++) { + const day = new Date(currentWeekStart); + day.setDate(currentWeekStart.getDate() + d); + const dateString = day.toISOString().split('T')[0]; + + if (dateString && countByDate.has(dateString)) { + weeklyCount += countByDate.get(dateString)!; + } } + + currentColumn.push({ date: new Date(currentWeekStart), count: weeklyCount }); + + // group by 4 weeks into columns + if (currentColumn.length === WEEKS_PER_COLUMN) { + columns.push(currentColumn); + currentColumn = []; + } + + currentWeekStart.setDate(currentWeekStart.getDate() + 7); + } + + // add whatever is left + if (currentColumn.length > 0) { + columns.push(currentColumn); } - if (week.length) weeks.push(week); - return weeks; + + return columns; } -/* ───────────────────────── Component ───────────────────────── */ +// helper to figure out if we need to show a month label +function getColumnLabel(column: { date: Date }[], prevColumn: { date: Date }[] | undefined, colIndex: number) { + const currentMonth = column[0].date.getMonth(); + const currentYear = column[0].date.getFullYear(); + + const prevMonth = prevColumn ? prevColumn[0].date.getMonth() : -1; + const isMonthChange = currentMonth !== prevMonth; + + // only show label every 3 months or on the very first column + const isQuarterlyMonth = currentMonth % 3 === 0; + const shouldShowLabel = isMonthChange && (isQuarterlyMonth || colIndex === 0); -export function ContributionHeatmap({ - dailyCounts, -}: { - dailyCounts: DailyCount[]; -}) { - const weeks = useMemo(() => buildGrid(dailyCounts), [dailyCounts]); + if (!shouldShowLabel) return null; + + // add year if its jan or the first column + const includeYear = currentMonth === 0 || colIndex === 0; + return includeYear ? `${MONTHS[currentMonth]} ${currentYear}` : MONTHS[currentMonth]; +} + +export function ContributionHeatmap({ dailyCounts }: { dailyCounts: DailyCount[] }) { + const columns = useMemo(() => buildGrid(dailyCounts), [dailyCounts]); const scrollRef = useRef(null); + // auto scroll to the end useEffect(() => { - const el = scrollRef.current; - if (el) el.scrollLeft = el.scrollWidth; - }, [weeks]); + if (scrollRef.current) { + scrollRef.current.scrollLeft = scrollRef.current.scrollWidth; + } + }, [columns]); return ( -
-
- {DAY_LABELS.map((label, i) => ( -
- - {label} - -
- ))} -
+
+
+
+ + {/* header row for labels */} +
+ {columns.map((col, i) => { + const label = getColumnLabel(col, i > 0 ? columns[i - 1] : undefined, i); + + const currentYear = col[0].date.getFullYear(); + const prevYear = i > 0 ? columns[i - 1][0].date.getFullYear() : currentYear; + const isYearChange = currentYear !== prevYear; -
-
-
- {weeks.map((week, i) => { - const m = week[0].date.getMonth(); - const prev = i > 0 ? weeks[i - 1][0].date.getMonth() : -1; return (
- {m !== prev && ( - - {MONTHS[m]} + {label && ( + + {label} )}
@@ -100,25 +128,36 @@ export function ContributionHeatmap({ })}
- {/* Grid */} -
- {weeks.map((week, wi) => ( -
- {week.map((day, di) => ( -
- ))} -
- ))} + {/* grid body */} +
+ {columns.map((col, colIndex) => { + const currentYear = col[0].date.getFullYear(); + const prevYear = colIndex > 0 ? columns[colIndex - 1][0].date.getFullYear() : currentYear; + const isYearChange = currentYear !== prevYear; + + // adding margin and a dashed border when the year changes + return ( +
+ {col.map((week, weekIndex) => ( +
+ ))} +
+ ); + })}
+
From 785d9fa1992828e227588cbab4db876195dc8f48 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 24 Feb 2026 22:59:12 +0100 Subject: [PATCH 18/57] Conform to Prettier formatting --- .../dashboard/ContributionHeatmap.tsx | 63 ++++++++++++++----- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/src/components/dashboard/ContributionHeatmap.tsx b/src/components/dashboard/ContributionHeatmap.tsx index 9c1e717..65d8614 100644 --- a/src/components/dashboard/ContributionHeatmap.tsx +++ b/src/components/dashboard/ContributionHeatmap.tsx @@ -2,7 +2,20 @@ import { useMemo, useRef, useEffect } from 'react'; import type { DailyCount } from '@/lib/api/contributor-stats'; import { heatmapColor } from '@/lib/heatmap-helpers'; -const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; +const MONTHS = [ + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec', +]; const WEEKS_PER_COLUMN = 4; const SQUARE_SIZE = 26; @@ -29,7 +42,7 @@ function buildGrid(dailyCounts: DailyCount[]) { const columns: { date: Date; count: number }[][] = []; let currentColumn: { date: Date; count: number }[] = []; - let currentWeekStart = new Date(startDate); + const currentWeekStart = new Date(startDate); while (currentWeekStart <= endDate) { let weeklyCount = 0; @@ -45,7 +58,10 @@ function buildGrid(dailyCounts: DailyCount[]) { } } - currentColumn.push({ date: new Date(currentWeekStart), count: weeklyCount }); + currentColumn.push({ + date: new Date(currentWeekStart), + count: weeklyCount, + }); // group by 4 weeks into columns if (currentColumn.length === WEEKS_PER_COLUMN) { @@ -65,7 +81,11 @@ function buildGrid(dailyCounts: DailyCount[]) { } // helper to figure out if we need to show a month label -function getColumnLabel(column: { date: Date }[], prevColumn: { date: Date }[] | undefined, colIndex: number) { +function getColumnLabel( + column: { date: Date }[], + prevColumn: { date: Date }[] | undefined, + colIndex: number +) { const currentMonth = column[0].date.getMonth(); const currentYear = column[0].date.getFullYear(); @@ -80,10 +100,16 @@ function getColumnLabel(column: { date: Date }[], prevColumn: { date: Date }[] | // add year if its jan or the first column const includeYear = currentMonth === 0 || colIndex === 0; - return includeYear ? `${MONTHS[currentMonth]} ${currentYear}` : MONTHS[currentMonth]; + return includeYear + ? `${MONTHS[currentMonth]} ${currentYear}` + : MONTHS[currentMonth]; } -export function ContributionHeatmap({ dailyCounts }: { dailyCounts: DailyCount[] }) { +export function ContributionHeatmap({ + dailyCounts, +}: { + dailyCounts: DailyCount[]; +}) { const columns = useMemo(() => buildGrid(dailyCounts), [dailyCounts]); const scrollRef = useRef(null); @@ -102,14 +128,18 @@ export function ContributionHeatmap({ dailyCounts }: { dailyCounts: DailyCount[] style={{ scrollbarWidth: 'thin', WebkitOverflowScrolling: 'touch' }} >
- {/* header row for labels */}
{columns.map((col, i) => { - const label = getColumnLabel(col, i > 0 ? columns[i - 1] : undefined, i); + const label = getColumnLabel( + col, + i > 0 ? columns[i - 1] : undefined, + i + ); const currentYear = col[0].date.getFullYear(); - const prevYear = i > 0 ? columns[i - 1][0].date.getFullYear() : currentYear; + const prevYear = + i > 0 ? columns[i - 1][0].date.getFullYear() : currentYear; const isYearChange = currentYear !== prevYear; return ( @@ -132,17 +162,21 @@ export function ContributionHeatmap({ dailyCounts }: { dailyCounts: DailyCount[]
{columns.map((col, colIndex) => { const currentYear = col[0].date.getFullYear(); - const prevYear = colIndex > 0 ? columns[colIndex - 1][0].date.getFullYear() : currentYear; + const prevYear = + colIndex > 0 + ? columns[colIndex - 1][0].date.getFullYear() + : currentYear; const isYearChange = currentYear !== prevYear; // adding margin and a dashed border when the year changes return (
{col.map((week, weekIndex) => ( @@ -157,7 +191,6 @@ export function ContributionHeatmap({ dailyCounts }: { dailyCounts: DailyCount[] ); })}
-
From 2704820ec76e3ba3fdd2dbdb7c67e696dca288b2 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Wed, 25 Feb 2026 00:26:15 +0100 Subject: [PATCH 19/57] Fix security audit --- package-lock.json | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index b66b3d3..fe2b931 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2439,24 +2439,37 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.6.tgz", + "integrity": "sha512-kQAVowdR33euIqeA0+VZTDqU+qo1IeVY+hrKYtZMio3Pg0P0vuh/kwRylLUddJhB6pf3q/botcOvRtx4IN1wqQ==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -2565,9 +2578,9 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -4051,9 +4064,9 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.3.tgz", + "integrity": "sha512-M2GCs7Vk83NxkUyQV1bkABc4yxgz9kILhHImZiBPAZ9ybuvCb0/H7lEl5XvIg3g+9d4eNotkZA5IWwYl0tibaA==", "dev": true, "license": "ISC", "dependencies": { From 32ccd39c1bd934f30ecea5401b9d5dd534b1d9d0 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Wed, 25 Feb 2026 10:27:12 +0100 Subject: [PATCH 20/57] feat: Add initial version of onboarding --- src/components/Layout.tsx | 2 +- .../onboarding/OnboardingPractice.tsx | 407 ++++++++++ src/components/onboarding/OnboardingStep.tsx | 49 ++ src/pages/DashboardPage.tsx | 34 +- src/pages/HomePage.tsx | 13 +- src/pages/OnboardingPage.tsx | 753 +++++++++++++++--- 6 files changed, 1153 insertions(+), 105 deletions(-) create mode 100644 src/components/onboarding/OnboardingPractice.tsx create mode 100644 src/components/onboarding/OnboardingStep.tsx diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index 022f9ed..730a081 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -4,7 +4,7 @@ import { Footer } from './footer'; export function Layout() { return ( -
+
diff --git a/src/components/onboarding/OnboardingPractice.tsx b/src/components/onboarding/OnboardingPractice.tsx new file mode 100644 index 0000000..671d073 --- /dev/null +++ b/src/components/onboarding/OnboardingPractice.tsx @@ -0,0 +1,407 @@ +import { useState, useEffect, forwardRef, useImperativeHandle } from 'react'; +import { motion, AnimatePresence } from 'motion/react'; +import { ArrowRight, Check, ChevronDown } from 'lucide-react'; +import { MappingCard } from '@/components/session/MappingCard'; +import { TypeSelectionButton } from '@/components/session/TypeSelectionButton'; +import { + THEME_COLORS, + RELATIONSHIP_TYPES, + RELATIONSHIP_SELECTED_COLORS, + RELATIONSHIP_UNSELECTED_COLORS, + RELATIONSHIP_ICON_BG_COLORS, + RELATIONSHIP_ICONS, + type RelationshipType, +} from '@/components/session/session-constants'; + +type GuidanceLevel = 'strict' | 'soft' | 'free'; + +interface TutorialRound { + competencies: [ + { id: string; title: string; description: string; createdAt: string }, + { id: string; title: string; description: string; createdAt: string }, + ]; + correctAnswer: RelationshipType; + guidanceLevel: GuidanceLevel; + guidanceLabel: string; + introText: string; + feedbackCorrect: string; + feedbackWrong: string; +} + +const TUTORIAL_ROUNDS: TutorialRound[] = [ + { + competencies: [ + { + id: 'r1-b', + title: 'Divide and Conquer', + description: + 'Breaking problems into smaller, independent subproblems, solving them recursively, and combining results (e.g. merge sort, binary search).', + createdAt: '', + }, + { + id: 'r1-a', + title: 'Recursion', + description: + 'Understanding and applying recursive problem-solving strategies, including base cases, recursive calls, and stack behavior.', + createdAt: '', + }, + ], + correctAnswer: 'ASSUMES', + guidanceLevel: 'strict', + guidanceLabel: 'Guided', + introText: + 'Divide and Conquer requires understanding recursion first. Click the highlighted button below!', + feedbackCorrect: + 'Correct! Recursion is a prerequisite for Divide and Conquer.', + feedbackWrong: '', + }, + { + competencies: [ + { + id: 'r2-a', + title: 'Merge Sort', + description: + 'A divide-and-conquer sorting algorithm that recursively splits, sorts, and merges sub-arrays in O(n log n) time.', + createdAt: '', + }, + { + id: 'r2-b', + title: 'Sorting', + description: + 'Ordering elements of a collection according to a comparison criterion, including understanding of time complexity and stability.', + createdAt: '', + }, + ], + correctAnswer: 'EXTENDS', + guidanceLevel: 'soft', + guidanceLabel: 'Hints', + introText: + 'Merge Sort is a specific sorting algorithm. How does it relate to the general concept of Sorting?', + feedbackCorrect: + 'Exactly! Merge Sort extends the concept of Sorting, a specialized technique that builds on the general idea.', + feedbackWrong: + 'Not quite — think about whether one is a specialization of the other. Try again!', + }, + { + competencies: [ + { + id: 'r3-a', + title: 'Methods', + description: + 'Functions that are defined inside a class or an object, and typically operate on instances of that class.', + createdAt: '', + }, + { + id: 'r3-b', + title: 'Functions', + description: + 'Self-contained blocks of code that take inputs, perform specific actions, and return an output.', + createdAt: '', + }, + ], + correctAnswer: 'MATCHES', + guidanceLevel: 'free', + guidanceLabel: 'On Your Own', + introText: 'Now try this one on your own. No hints this time!', + feedbackCorrect: + 'Perfect! Methods and Functions are essentially equivalent — they describe the same concept.', + feedbackWrong: + 'These two are actually very similar concepts. Methods and Functions are essentially the same thing.', + }, +]; + +interface OnboardingPracticeProps { + onComplete: () => void; + onCorrectStateChange?: (isCorrect: boolean) => void; +} + +export interface OnboardingPracticeRef { + nextRound: () => void; + isLastRound: boolean; +} + +export const OnboardingPractice = forwardRef< + OnboardingPracticeRef, + OnboardingPracticeProps +>(function OnboardingPractice({ onComplete, onCorrectStateChange }, ref) { + const [round, setRound] = useState(0); + const [selectedRelation, setSelectedRelation] = + useState(null); + const [wrongAttempt, setWrongAttempt] = useState(false); + + const current = TUTORIAL_ROUNDS[round]!; + const isCorrect = selectedRelation === current.correctAnswer; + const isLastRound = round === TUTORIAL_ROUNDS.length - 1; + + function handleSelect(value: RelationshipType | null) { + if (!value || isCorrect) return; + + // Strict mode: only allow the correct answer + if (current.guidanceLevel === 'strict' && value !== current.correctAnswer) { + return; + } + + // Soft mode: wrong answer, show feedback, let them try again + if (current.guidanceLevel === 'soft' && value !== current.correctAnswer) { + setWrongAttempt(true); + setSelectedRelation(value); + // Reset after a moment to let them try again + setTimeout(() => { + setSelectedRelation(null); + setWrongAttempt(false); + }, 1500); + return; + } + + setSelectedRelation(value); + setWrongAttempt(false); + } + + // Effect to notify parent when selection clears/changes + useEffect(() => { + if (onCorrectStateChange) { + onCorrectStateChange(isCorrect); + } + }, [isCorrect, onCorrectStateChange]); + + function handleNext() { + if (isLastRound) { + onComplete(); + return; + } + setRound(r => r + 1); + setSelectedRelation(null); + setWrongAttempt(false); + } + + useImperativeHandle(ref, () => ({ + nextRound: handleNext, + isLastRound, + })); + + return ( +
+
+ {TUTORIAL_ROUNDS.map((_, i) => ( +
+
+ {i < round ? : i + 1} +
+ {i < TUTORIAL_ROUNDS.length - 1 && ( +
+ )} +
+ ))} +
+ + {/* ── Question ── */} + + +
+

+ How does{' '} + + {current.competencies[0].title} + {' '} + relate to{' '} + + {current.competencies[1].title} + + ? +

+
+ + {/* ── Cards ── */} +
+ + +
+
+
+
+
+
+
+
+ + +
+ + + + + + {wrongAttempt ? ( + + {current.feedbackWrong} + + ) : selectedRelation && !wrongAttempt ? ( +

+ {isCorrect ? current.feedbackCorrect : current.feedbackWrong} +

+ ) : ( +

+ {current.introText} +

+ )} +
+
+ +
+
+ {RELATIONSHIP_TYPES.map(({ value, label }, index) => { + const isSelected = selectedRelation === value; + const IconComponent = RELATIONSHIP_ICONS[value]; + const iconBgColors = RELATIONSHIP_ICON_BG_COLORS[value]; + const isCorrectBtn = value === current.correctAnswer; + + // Strict mode: dim non-correct buttons + const isStrictDisabled = + current.guidanceLevel === 'strict' && !isCorrectBtn && !isCorrect; + + return ( +
+ {current.guidanceLevel === 'soft' && + isCorrectBtn && + !selectedRelation && + !isCorrect && ( + + + + )} + +
+ {/* Pulsing ring for strict guidance */} + {current.guidanceLevel === 'strict' && + isCorrectBtn && + !selectedRelation && + !isCorrect && ( + + )} + + } + selectedClass={RELATIONSHIP_SELECTED_COLORS[value]} + unselectedClass={RELATIONSHIP_UNSELECTED_COLORS[value]} + iconBgClass={ + isSelected + ? iconBgColors.selected + : iconBgColors.unselected + } + focusRingColor="focus-visible:ring-blue-500" + onSelect={v => handleSelect(v as RelationshipType)} + onHoverEnter={() => {}} + onHoverLeave={() => {}} + /> +
+
+ ); + })} +
+
+
+ ); +}); diff --git a/src/components/onboarding/OnboardingStep.tsx b/src/components/onboarding/OnboardingStep.tsx new file mode 100644 index 0000000..27aad1f --- /dev/null +++ b/src/components/onboarding/OnboardingStep.tsx @@ -0,0 +1,49 @@ +import { motion, AnimatePresence } from 'motion/react'; +import type { ReactNode } from 'react'; + +interface OnboardingStepProps { + children: ReactNode; + stepKey: string; + direction: number; +} + +const variants = { + enter: (direction: number) => ({ + x: direction > 0 ? 80 : -80, + opacity: 0, + scale: 0.97, + }), + center: { + x: 0, + opacity: 1, + scale: 1, + }, + exit: (direction: number) => ({ + x: direction > 0 ? -80 : 80, + opacity: 0, + scale: 0.97, + }), +}; + +export function OnboardingStep({ + children, + stepKey, + direction, +}: OnboardingStepProps) { + return ( + + + {children} + + + ); +} diff --git a/src/pages/DashboardPage.tsx b/src/pages/DashboardPage.tsx index 485c0c9..85bce55 100644 --- a/src/pages/DashboardPage.tsx +++ b/src/pages/DashboardPage.tsx @@ -1,5 +1,5 @@ import { useEffect, useState, useMemo } from 'react'; -import { Link } from 'react-router-dom'; +import { Link, useNavigate } from 'react-router-dom'; import { Button } from '@/components/ui/button'; import { contributorStatsApi, @@ -13,11 +13,13 @@ import { Target, Award, Star, + BookOpen, } from 'lucide-react'; import { ContributionHeatmap } from '@/components/dashboard/ContributionHeatmap'; import { heatmapColor } from '@/lib/heatmap-helpers'; const GUEST_USER_ID = 'guest'; +const ONBOARDED_KEY = 'memo-onboarded'; interface BadgeDef { id: string; @@ -166,6 +168,7 @@ function StatCard({ } export function DashboardPage() { + const navigate = useNavigate(); const [stats, setStats] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); @@ -212,12 +215,29 @@ export function DashboardPage() { Track your contributions and unlock milestones.

- +
+ + +
{error && ( diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index cda03ae..062d759 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -1,6 +1,17 @@ +import { Link } from 'react-router-dom'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; +const ONBOARDED_KEY = 'memo-onboarded'; + +function getStartHref(): string { + try { + return localStorage.getItem(ONBOARDED_KEY) ? '/session' : '/onboarding'; + } catch { + return '/onboarding'; + } +} + type ProblemStatement = { headline: string; insight: string; @@ -56,7 +67,7 @@ export function HomePage() { className="h-12 rounded-full bg-[#0a4da2] px-7 text-base font-semibold text-white shadow-[0_18px_45px_-26px_rgba(7,30,84,0.75)] transition hover:bg-[#0d56b5]" asChild > - Start Contributing + Start Contributing
diff --git a/src/pages/OnboardingPage.tsx b/src/pages/OnboardingPage.tsx index e799a24..96aa125 100644 --- a/src/pages/OnboardingPage.tsx +++ b/src/pages/OnboardingPage.tsx @@ -1,10 +1,92 @@ -import { Link } from 'react-router-dom'; +import { useCallback, useEffect, useState, useRef, forwardRef } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { motion } from 'motion/react'; +import { + ArrowLeft, + ArrowRight, + BookOpen, + Brain, + CheckCircle2, + Layers, + LogIn, + MousePointerClick, + Rocket, + Users, + Waypoints, +} from 'lucide-react'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; +import { OnboardingStep } from '@/components/onboarding/OnboardingStep'; +import { + OnboardingPractice, + OnboardingPracticeRef, +} from '@/components/onboarding/OnboardingPractice'; -const experienceOptions = ['Beginner', 'Intermediate', 'Expert']; +const TOTAL_STEPS = 4; +const ONBOARDED_KEY = 'memo-onboarded'; export function OnboardingPage() { + const [step, setStep] = useState(0); + const [direction, setDirection] = useState(1); + const [consentChecked, setConsentChecked] = useState(false); + const [practiceCompleted, setPracticeCompleted] = useState(false); + const [currentPracticeCorrect, setCurrentPracticeCorrect] = useState(false); + const practiceRef = useRef(null); + const navigate = useNavigate(); + + const goNext = useCallback(() => { + if (step === 2 && currentPracticeCorrect && !practiceCompleted) { + practiceRef.current?.nextRound(); + return; + } + if (step < TOTAL_STEPS - 1) { + setDirection(1); + setStep(s => s + 1); + } + }, [step, currentPracticeCorrect, practiceCompleted]); + + const goBack = useCallback(() => { + if (step > 0) { + setDirection(-1); + setStep(s => s - 1); + } + }, [step]); + + // Arrow key navigation + useEffect(() => { + function handleKeyDown(e: KeyboardEvent) { + const target = e.target as HTMLElement; + if ( + target.tagName === 'INPUT' || + target.tagName === 'TEXTAREA' || + target.isContentEditable + ) { + return; + } + + if (e.key === 'ArrowRight' && step < TOTAL_STEPS - 1) { + // Don't advance past practice unless completed + if (step === 2 && !practiceCompleted && !currentPracticeCorrect) return; + e.preventDefault(); + goNext(); + } + if (e.key === 'ArrowLeft' && step > 0) { + e.preventDefault(); + goBack(); + } + } + + window.addEventListener('keydown', handleKeyDown); + return () => window.removeEventListener('keydown', handleKeyDown); + }, [step, practiceCompleted, currentPracticeCorrect, goNext, goBack]); + + const canAdvance = + step === 2 + ? practiceCompleted || currentPracticeCorrect + : step === 3 + ? consentChecked + : true; + return (
@@ -13,107 +95,586 @@ export function OnboardingPage() {
-
-
- - Competency Benchmark Mapping Platform - +
+
+
+ + Step {step + 1} of {TOTAL_STEPS} + + + {['Welcome', 'Our Mission', 'Practice', 'Guidelines'][step]} + +
+
+ +
-
- - + + Back + + + {step < TOTAL_STEPS - 1 ? ( + + ) : ( + + )}
-
+ +
+ ); +} + +function StepWelcome() { + return ( +
+
+ + + + + Welcome to{' '} + + Memo + + + + A competency network maps + how skills relate to each other — which ones are prerequisites, which + extend others, and which are equivalent. These networks power + personalized learning recommendations. + +
+ + + + +
+ ); +} + +const NETWORK_NODES = [ + { id: 'methods', label: 'Methods', x: 80, y: 50, color: '#0a4da2' }, + { id: 'functions', label: 'Functions', x: 80, y: 150, color: '#0a4da2' }, + { id: 'recursion', label: 'Recursion', x: 280, y: 100, color: '#5538d1' }, + { id: 'mergesort', label: 'Merge Sort', x: 480, y: 50, color: '#7c3aed' }, + { id: 'sorting', label: 'Sorting', x: 600, y: 50, color: '#7c3aed' }, + { id: 'trees', label: 'Tree Traversal', x: 480, y: 155, color: '#9b5dfa' }, +]; + +const NETWORK_EDGES = [ + { from: 'methods', to: 'functions', label: 'matches' }, + { from: 'recursion', to: 'methods', label: 'assumes' }, + { from: 'mergesort', to: 'recursion', label: 'assumes' }, + { from: 'trees', to: 'recursion', label: 'assumes' }, + { from: 'mergesort', to: 'sorting', label: 'extends' }, +]; + +const EDGE_COLORS: Record = { + assumes: '#0a4da2', + extends: '#7c3aed', + matches: '#10b981', +}; + +function CompetencyNetworkViz() { + const nodeMap = Object.fromEntries(NETWORK_NODES.map(n => [n.id, n])); + + return ( +
+
+ + + Competency Network Preview + +
+ + + + + + + + + + + + + + {/* Edges */} + {NETWORK_EDGES.map((edge, i) => { + const from = nodeMap[edge.from]!; + const to = nodeMap[edge.to]!; + const mx = (from.x + to.x) / 2; + const my = (from.y + to.y) / 2; + const isDirectional = + edge.label === 'assumes' || edge.label === 'extends'; + const markerId = + edge.label === 'extends' + ? 'url(#arrow-extends)' + : 'url(#arrow-assumes)'; + + // Shorten line so arrowhead sits on circle edge, not behind it + const dx = to.x - from.x; + const dy = to.y - from.y; + const len = Math.sqrt(dx * dx + dy * dy); + const r = 34; // node radius + small margin + const x1 = from.x + (dx / len) * r; + const y1 = from.y + (dy / len) * r; + const x2 = to.x - (dx / len) * r; + const y2 = to.y - (dy / len) * r; + + return ( + + + + {edge.label} + + + ); + })} + + {/* Nodes */} + {NETWORK_NODES.map((node, i) => ( + + + + {node.label.includes(' ') ? ( + <> + + {node.label.split(' ')[0]} + + + {node.label.split(' ').slice(1).join(' ')} + + + ) : ( + node.label + )} + + + ))} + +
+ + + Assumes → + + + + Extends → + + + + Matches + +
+
+ ); +} + +const HOW_IT_WORKS_TILES = [ + { + icon: Layers, + color: 'from-[#0a4da2] to-[#4263eb]', + iconBg: 'bg-blue-100 text-blue-600', + title: 'See two competencies', + desc: 'We show you a pair of skills from a knowledge domain — like "Recursion" and "Divide and Conquer".', + }, + { + icon: MousePointerClick, + color: 'from-[#7c3aed] to-[#9775fa]', + iconBg: 'bg-purple-100 text-purple-600', + title: 'Pick a relationship', + desc: 'Decide how they relate: prerequisite, extension, equivalent, or unrelated. Use buttons or keyboard shortcuts.', + }, + { + icon: CheckCircle2, + color: 'from-emerald-500 to-emerald-600', + iconBg: 'bg-emerald-100 text-emerald-600', + title: 'Build the benchmark', + desc: 'Your label joins a crowd-sourced dataset for fair, reproducible evaluation of recommender systems.', + }, +]; + +function StepHowItWorks({ onSignIn }: { onSignIn: () => void }) { + return ( +
+
+ + Our Mission + +

+ Building a Better Benchmark +

+

+ Memo crowd-sources how competencies relate to each other to create an{' '} + open benchmark dataset. + Researchers can use it to fairly evaluate and compare competency-aware + learning recommender systems. +

+
+ +
+ {HOW_IT_WORKS_TILES.map((tile, i) => ( +
+
+
+
+ +
+ + + {i + 1} + + +
+

{tile.title}

+

+ {tile.desc} +

+
+
+ ))} +
-
-
- - Onboarding +

+ Your contribution is simple. Just map relationships between pairs of + skills. +

+ +
+ +
+ +
+ + Community-driven + + + Open-source research + +
+
+ ); +} + +const StepPractice = forwardRef< + OnboardingPracticeRef, + { + onComplete: () => void; + onCorrectStateChange: (isCorrect: boolean) => void; + completed: boolean; + } +>(function StepPractice({ onComplete, onCorrectStateChange, completed }, ref) { + return ( +
+
+ + Practice Round + +

+ Try It Yourself +

+
+ + {completed ? ( + + +

+ Practice complete!

-
- -
-
- - - - - -
- -
-

- Quick primer -

-
    -
  • - Competency ↔ Competency: prerequisite, similarity, part-of - relations. -
  • -
  • - Competency ↔ Resource: align exercises, quizzes, and papers to - the best competency fit. -
  • -
  • - Short sessions: we queue focused tasks; you decide add, skip, or - undo. -
  • -
-

- No account needed. Data is mock-only for now. -

+

+ Hit Continue to proceed to the guidelines. +

+ + ) : ( + + )} +
+ ); +}); + +const GUIDELINES = [ + { + emoji: '🎯', + title: 'Accuracy over speed', + desc: 'Take your time. One thoughtful label is better than many rushed ones.', + }, + { + emoji: '⏭️', + title: 'Skip when unsure', + desc: 'No penalty for skipping. If a pair is ambiguous, move on.', + }, + { + emoji: '🤝', + title: 'No competition', + desc: 'This is a collaboration, not a race. Every contribution matters.', + }, + { + emoji: '↩️', + title: 'Undo is available', + desc: 'Made a mistake? Use the undo button or Shift+Z to fix it.', + }, +]; + +function StepConsent({ + checked, + onToggle, +}: { + checked: boolean; + onToggle: () => void; +}) { + return ( +
+
+ + Guidelines + +

+ Quality Over Quantity +

+

+ Great benchmark data comes from careful, honest mappings. +
+ Here are a few principles to keep in mind. +

+
+ +
+ {GUIDELINES.map(g => ( +
+
+ {g.emoji} +

{g.title}

+
+

{g.desc}

-
+ ))} +
-
- -
- -
+
+ +
+ ); } From 99f89e11b61374e089900f2dfd3a4c82060541f3 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Wed, 25 Feb 2026 10:47:00 +0100 Subject: [PATCH 21/57] fix onboarding flow --- src/components/onboarding/OnboardingPractice.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/onboarding/OnboardingPractice.tsx b/src/components/onboarding/OnboardingPractice.tsx index 671d073..6c65aaf 100644 --- a/src/components/onboarding/OnboardingPractice.tsx +++ b/src/components/onboarding/OnboardingPractice.tsx @@ -174,10 +174,14 @@ export const OnboardingPractice = forwardRef< setWrongAttempt(false); } - useImperativeHandle(ref, () => ({ - nextRound: handleNext, - isLastRound, - })); + useImperativeHandle( + ref, + () => ({ + nextRound: handleNext, + isLastRound, + }), + [round, isLastRound, onComplete], + ); return (
From 4a8eebac787983c073f4604a78c187d59244906f Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Wed, 25 Feb 2026 12:22:05 +0100 Subject: [PATCH 22/57] conform to Prettier formatting --- src/components/onboarding/OnboardingPractice.tsx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/components/onboarding/OnboardingPractice.tsx b/src/components/onboarding/OnboardingPractice.tsx index 6c65aaf..671d073 100644 --- a/src/components/onboarding/OnboardingPractice.tsx +++ b/src/components/onboarding/OnboardingPractice.tsx @@ -174,14 +174,10 @@ export const OnboardingPractice = forwardRef< setWrongAttempt(false); } - useImperativeHandle( - ref, - () => ({ - nextRound: handleNext, - isLastRound, - }), - [round, isLastRound, onComplete], - ); + useImperativeHandle(ref, () => ({ + nextRound: handleNext, + isLastRound, + })); return (
From 49e98c232bdb6bf09ab840c77cfeb7ef0ec352fb Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Fri, 27 Feb 2026 13:40:36 +0100 Subject: [PATCH 23/57] Update profile setup --- package-lock.json | 3153 ++++++++++++++++- package.json | 2 + .../onboarding/OnboardingPractice.tsx | 65 +- src/components/ui/command.tsx | 182 + src/components/ui/dialog.tsx | 156 + src/components/ui/popover.tsx | 87 + src/components/ui/select.tsx | 188 + src/pages/OnboardingPage.tsx | 369 +- 8 files changed, 4031 insertions(+), 171 deletions(-) create mode 100644 src/components/ui/command.tsx create mode 100644 src/components/ui/dialog.tsx create mode 100644 src/components/ui/popover.tsx create mode 100644 src/components/ui/select.tsx diff --git a/package-lock.json b/package-lock.json index fe2b931..32d17ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,9 +15,11 @@ "axios": "^1.13.2", "class-variance-authority": "0.7.1", "clsx": "2.1.1", + "cmdk": "^1.1.1", "keycloak-js": "^26.2.2", "lucide-react": "0.525.0", "motion": "12.23.24", + "radix-ui": "^1.4.3", "react": "19.0.0", "react-dom": "19.0.0", "react-router-dom": "^7.1.1", @@ -937,6 +939,44 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.4.tgz", + "integrity": "sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.5.tgz", + "integrity": "sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.4", + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.7.tgz", + "integrity": "sha512-0tLRojf/1Go2JgEVm+3Frg9A3IW8bJgKgdO0BN5RkF//ufuz2joZM63Npau2ff3J6lUVYgDSNzNkR+aH3IVfjg==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.7.5" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "license": "MIT" + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -1039,22 +1079,56 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@radix-ui/number": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", + "license": "MIT" + }, "node_modules/@radix-ui/primitive": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", "license": "MIT" }, - "node_modules/@radix-ui/react-collection": { + "node_modules/@radix-ui/react-accessible-icon": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", - "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accessible-icon/-/react-accessible-icon-1.1.7.tgz", + "integrity": "sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", + "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", "license": "MIT", "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collapsible": "1.1.12", + "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3" + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -1071,7 +1145,7 @@ } } }, - "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-primitive": { + "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-primitive": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", @@ -1094,7 +1168,7 @@ } } }, - "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": { + "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", @@ -1112,41 +1186,65 @@ } } }, - "node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", - "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "node_modules/@radix-ui/react-alert-dialog": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz", + "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==", "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dialog": "1.1.15", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-context": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", - "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-direction": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", - "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -1157,31 +1255,36 @@ } } }, - "node_modules/@radix-ui/react-id": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", - "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-label": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.8.tgz", - "integrity": "sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==", + "node_modules/@radix-ui/react-arrow/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.4" + "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -1198,14 +1301,31 @@ } } }, - "node_modules/@radix-ui/react-presence": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", - "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "node_modules/@radix-ui/react-arrow/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-aspect-ratio": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.7.tgz", + "integrity": "sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -1222,13 +1342,13 @@ } } }, - "node_modules/@radix-ui/react-primitive": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", - "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", + "node_modules/@radix-ui/react-aspect-ratio/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.2.4" + "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -1245,22 +1365,35 @@ } } }, - "node_modules/@radix-ui/react-radio-group": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.8.tgz", - "integrity": "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==", + "node_modules/@radix-ui/react-aspect-ratio/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-avatar": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz", + "integrity": "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.11", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-use-size": "1.1.1" + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-is-hydrated": "0.1.0", + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1277,7 +1410,7 @@ } } }, - "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-primitive": { + "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-primitive": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", @@ -1300,7 +1433,7 @@ } } }, - "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-slot": { + "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", @@ -1318,21 +1451,20 @@ } } }, - "node_modules/@radix-ui/react-roving-focus": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", - "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", + "node_modules/@radix-ui/react-checkbox": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", + "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1349,7 +1481,7 @@ } } }, - "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-primitive": { + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-primitive": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", @@ -1372,7 +1504,7 @@ } } }, - "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-slot": { + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", @@ -1390,10 +1522,63 @@ } } }, - "node_modules/@radix-ui/react-slot": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", - "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", + "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" @@ -1408,10 +1593,2454 @@ } } }, - "node_modules/@radix-ui/react-use-callback-ref": { + "node_modules/@radix-ui/react-collection": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context-menu": { + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.2.16.tgz", + "integrity": "sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context-menu/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context-menu/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", + "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", + "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz", + "integrity": "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", + "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-form": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-form/-/react-form-0.1.8.tgz", + "integrity": "sha512-QM70k4Zwjttifr5a4sZFts9fn8FzHYvQ5PiB19O2HsYibaHSVt9fH9rzB0XZo/YcM+b7t/p7lYCT/F5eOeF5yQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-label": "2.1.7", + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-form/node_modules/@radix-ui/react-label": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", + "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-form/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-form/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.15.tgz", + "integrity": "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-label": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.8.tgz", + "integrity": "sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz", + "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menubar": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.1.16.tgz", + "integrity": "sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menubar/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menubar/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-navigation-menu": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.14.tgz", + "integrity": "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-navigation-menu/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-navigation-menu/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-one-time-password-field": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-one-time-password-field/-/react-one-time-password-field-0.1.8.tgz", + "integrity": "sha512-ycS4rbwURavDPVjCb5iS3aG4lURFDILi6sKI/WITUMZ13gMmn/xGjpLoqBAalhJaDk8I3UbCM5GzKHrnzwHbvg==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-is-hydrated": "0.1.0", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-one-time-password-field/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-one-time-password-field/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-password-toggle-field": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-password-toggle-field/-/react-password-toggle-field-0.1.3.tgz", + "integrity": "sha512-/UuCrDBWravcaMix4TdT+qlNdVwOM1Nck9kWx/vafXsdfj1ChfhOdfi3cy9SGBpWgTXwYCuboT/oYpJy3clqfw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-is-hydrated": "0.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-password-toggle-field/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-password-toggle-field/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz", + "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", + "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", + "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-progress": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.7.tgz", + "integrity": "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-progress/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-progress/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-radio-group": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.8.tgz", + "integrity": "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", + "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz", + "integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz", + "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-separator": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", + "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slider": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.6.tgz", + "integrity": "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", + "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz", + "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", + "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toast": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.15.tgz", + "integrity": "sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.10.tgz", + "integrity": "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle-group": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.11.tgz", + "integrity": "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-toggle": "1.1.10", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toolbar": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toolbar/-/react-toolbar-1.1.11.tgz", + "integrity": "sha512-4ol06/1bLoFu1nwUqzdD4Y5RZ9oDdKeiHIsntug54Hcr1pgaHiPqHFEaXI1IFP/EsOfROQZ8Mig9VTIRza6Tjg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-separator": "1.1.7", + "@radix-ui/react-toggle-group": "1.1.11" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toolbar/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toolbar/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", + "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-is-hydrated": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz", + "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.5.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", - "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1423,14 +4052,13 @@ } } }, - "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", - "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", + "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-effect-event": "0.0.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1442,10 +4070,10 @@ } } }, - "node_modules/@radix-ui/react-use-effect-event": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", - "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", + "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", "license": "MIT", "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" @@ -1460,43 +4088,59 @@ } } }, - "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", - "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", + "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-use-previous": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", - "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "node_modules/@radix-ui/react-visually-hidden/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-use-size": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", - "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "node_modules/@radix-ui/react-visually-hidden/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -1508,6 +4152,12 @@ } } }, + "node_modules/@radix-ui/rect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", + "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", + "license": "MIT" + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.27", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", @@ -2617,6 +5267,18 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -2778,6 +5440,22 @@ "node": ">=6" } }, + "node_modules/cmdk": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.1.1.tgz", + "integrity": "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "^1.1.1", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-id": "^1.1.0", + "@radix-ui/react-primitive": "^2.0.2" + }, + "peerDependencies": { + "react": "^18 || ^19 || ^19.0.0-rc", + "react-dom": "^18 || ^19 || ^19.0.0-rc" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2903,6 +5581,12 @@ "node": ">=8" } }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -3436,6 +6120,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", @@ -4331,6 +7024,147 @@ "node": ">=6" } }, + "node_modules/radix-ui": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/radix-ui/-/radix-ui-1.4.3.tgz", + "integrity": "sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-accessible-icon": "1.1.7", + "@radix-ui/react-accordion": "1.2.12", + "@radix-ui/react-alert-dialog": "1.1.15", + "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/react-aspect-ratio": "1.1.7", + "@radix-ui/react-avatar": "1.1.10", + "@radix-ui/react-checkbox": "1.3.3", + "@radix-ui/react-collapsible": "1.1.12", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-context-menu": "2.2.16", + "@radix-ui/react-dialog": "1.1.15", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-dropdown-menu": "2.1.16", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-form": "0.1.8", + "@radix-ui/react-hover-card": "1.1.15", + "@radix-ui/react-label": "2.1.7", + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-menubar": "1.1.16", + "@radix-ui/react-navigation-menu": "1.2.14", + "@radix-ui/react-one-time-password-field": "0.1.8", + "@radix-ui/react-password-toggle-field": "0.1.3", + "@radix-ui/react-popover": "1.1.15", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-progress": "1.1.7", + "@radix-ui/react-radio-group": "1.3.8", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-scroll-area": "1.2.10", + "@radix-ui/react-select": "2.2.6", + "@radix-ui/react-separator": "1.1.7", + "@radix-ui/react-slider": "1.3.6", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-switch": "1.2.6", + "@radix-ui/react-tabs": "1.1.13", + "@radix-ui/react-toast": "1.2.15", + "@radix-ui/react-toggle": "1.1.10", + "@radix-ui/react-toggle-group": "1.1.11", + "@radix-ui/react-toolbar": "1.1.11", + "@radix-ui/react-tooltip": "1.2.8", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-escape-keydown": "1.1.1", + "@radix-ui/react-use-is-hydrated": "0.1.0", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/radix-ui/node_modules/@radix-ui/react-label": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", + "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/radix-ui/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/radix-ui/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react": { "version": "19.0.0", "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", @@ -4362,6 +7196,53 @@ "node": ">=0.10.0" } }, + "node_modules/react-remove-scroll": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz", + "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-router": { "version": "7.12.0", "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.12.0.tgz", @@ -4400,6 +7281,28 @@ "react-dom": ">=18" } }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -4730,6 +7633,58 @@ "punycode": "^2.1.0" } }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/vite": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", diff --git a/package.json b/package.json index 145902f..f5ad412 100644 --- a/package.json +++ b/package.json @@ -23,9 +23,11 @@ "axios": "^1.13.2", "class-variance-authority": "0.7.1", "clsx": "2.1.1", + "cmdk": "^1.1.1", "keycloak-js": "^26.2.2", "lucide-react": "0.525.0", "motion": "12.23.24", + "radix-ui": "^1.4.3", "react": "19.0.0", "react-dom": "19.0.0", "react-router-dom": "^7.1.1", diff --git a/src/components/onboarding/OnboardingPractice.tsx b/src/components/onboarding/OnboardingPractice.tsx index 671d073..7c84731 100644 --- a/src/components/onboarding/OnboardingPractice.tsx +++ b/src/components/onboarding/OnboardingPractice.tsx @@ -50,7 +50,7 @@ const TUTORIAL_ROUNDS: TutorialRound[] = [ guidanceLevel: 'strict', guidanceLabel: 'Guided', introText: - 'Divide and Conquer requires understanding recursion first. Click the highlighted button below!', + 'Divide and Conquer assumes understanding recursion first. Click the highlighted button below!', feedbackCorrect: 'Correct! Recursion is a prerequisite for Divide and Conquer.', feedbackWrong: '', @@ -80,7 +80,7 @@ const TUTORIAL_ROUNDS: TutorialRound[] = [ feedbackCorrect: 'Exactly! Merge Sort extends the concept of Sorting, a specialized technique that builds on the general idea.', feedbackWrong: - 'Not quite — think about whether one is a specialization of the other. Try again!', + 'Not quite. Think about whether one is a specialization of the other. Try again!', }, { competencies: [ @@ -134,7 +134,16 @@ export const OnboardingPractice = forwardRef< const isLastRound = round === TUTORIAL_ROUNDS.length - 1; function handleSelect(value: RelationshipType | null) { - if (!value || isCorrect) return; + if (!value) { + if (current.guidanceLevel === 'free') { + setSelectedRelation(null); + setWrongAttempt(false); + } + return; + } + + // Once a correct answer is selected in strict/soft mode, it cannot be changed + if (isCorrect && current.guidanceLevel !== 'free') return; // Strict mode: only allow the correct answer if (current.guidanceLevel === 'strict' && value !== current.correctAnswer) { @@ -164,6 +173,47 @@ export const OnboardingPractice = forwardRef< } }, [isCorrect, onCorrectStateChange]); + // Effect to handle keyboard shortcuts (1-9) + useEffect(() => { + if (isLastRound && isCorrect) return; // Prevent interaction after finishing + + const handleKeyDown = (e: KeyboardEvent) => { + const target = e.target as HTMLElement; + if ( + target.tagName === 'INPUT' || + target.tagName === 'TEXTAREA' || + target.isContentEditable + ) { + return; + } + + const key = parseInt(e.key); + if (key >= 1 && key <= 4) { + const index = key - 1; + if (index < RELATIONSHIP_TYPES.length) { + const relationType = RELATIONSHIP_TYPES[index].value; + + const isCorrectBtn = relationType === current.correctAnswer; + const isStrictDisabled = + current.guidanceLevel === 'strict' && !isCorrectBtn && !isCorrect; + + if (!isStrictDisabled && !wrongAttempt) { + // Toggle off if already selected, otherwise select + if (selectedRelation === relationType) { + handleSelect(null); + } else { + handleSelect(relationType); + } + } + } + } + }; + + window.addEventListener('keydown', handleKeyDown); + return () => window.removeEventListener('keydown', handleKeyDown); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [current, isCorrect, isLastRound, wrongAttempt]); + function handleNext() { if (isLastRound) { onComplete(); @@ -341,7 +391,7 @@ export const OnboardingPractice = forwardRef< !isCorrect && ( - + )} diff --git a/src/components/ui/command.tsx b/src/components/ui/command.tsx new file mode 100644 index 0000000..8878461 --- /dev/null +++ b/src/components/ui/command.tsx @@ -0,0 +1,182 @@ +import * as React from 'react'; +import { Command as CommandPrimitive } from 'cmdk'; +import { SearchIcon } from 'lucide-react'; + +import { cn } from '@/lib/utils'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog'; + +function Command({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function CommandDialog({ + title = 'Command Palette', + description = 'Search for a command to run...', + children, + className, + showCloseButton = true, + ...props +}: React.ComponentProps & { + title?: string; + description?: string; + className?: string; + showCloseButton?: boolean; +}) { + return ( + + + {title} + {description} + + + + {children} + + + + ); +} + +function CommandInput({ + className, + ...props +}: React.ComponentProps) { + return ( +
+ + +
+ ); +} + +function CommandList({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function CommandEmpty({ + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function CommandGroup({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function CommandSeparator({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function CommandItem({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function CommandShortcut({ + className, + ...props +}: React.ComponentProps<'span'>) { + return ( + + ); +} + +export { + Command, + CommandDialog, + CommandInput, + CommandList, + CommandEmpty, + CommandGroup, + CommandItem, + CommandShortcut, + CommandSeparator, +}; diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx new file mode 100644 index 0000000..1219a7f --- /dev/null +++ b/src/components/ui/dialog.tsx @@ -0,0 +1,156 @@ +import * as React from 'react'; +import { XIcon } from 'lucide-react'; +import { Dialog as DialogPrimitive } from 'radix-ui'; + +import { cn } from '@/lib/utils'; +import { Button } from '@/components/ui/button'; + +function Dialog({ + ...props +}: React.ComponentProps) { + return ; +} + +function DialogTrigger({ + ...props +}: React.ComponentProps) { + return ; +} + +function DialogPortal({ + ...props +}: React.ComponentProps) { + return ; +} + +function DialogClose({ + ...props +}: React.ComponentProps) { + return ; +} + +function DialogOverlay({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function DialogContent({ + className, + children, + showCloseButton = true, + ...props +}: React.ComponentProps & { + showCloseButton?: boolean; +}) { + return ( + + + + {children} + {showCloseButton && ( + + + Close + + )} + + + ); +} + +function DialogHeader({ className, ...props }: React.ComponentProps<'div'>) { + return ( +
+ ); +} + +function DialogFooter({ + className, + showCloseButton = false, + children, + ...props +}: React.ComponentProps<'div'> & { + showCloseButton?: boolean; +}) { + return ( +
+ {children} + {showCloseButton && ( + + + + )} +
+ ); +} + +function DialogTitle({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function DialogDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +export { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogOverlay, + DialogPortal, + DialogTitle, + DialogTrigger, +}; diff --git a/src/components/ui/popover.tsx b/src/components/ui/popover.tsx new file mode 100644 index 0000000..b97c967 --- /dev/null +++ b/src/components/ui/popover.tsx @@ -0,0 +1,87 @@ +import * as React from 'react'; +import { Popover as PopoverPrimitive } from 'radix-ui'; + +import { cn } from '@/lib/utils'; + +function Popover({ + ...props +}: React.ComponentProps) { + return ; +} + +function PopoverTrigger({ + ...props +}: React.ComponentProps) { + return ; +} + +function PopoverContent({ + className, + align = 'center', + sideOffset = 4, + ...props +}: React.ComponentProps) { + return ( + + + + ); +} + +function PopoverAnchor({ + ...props +}: React.ComponentProps) { + return ; +} + +function PopoverHeader({ className, ...props }: React.ComponentProps<'div'>) { + return ( +
+ ); +} + +function PopoverTitle({ className, ...props }: React.ComponentProps<'h2'>) { + return ( +
+ ); +} + +function PopoverDescription({ + className, + ...props +}: React.ComponentProps<'p'>) { + return ( +

+ ); +} + +export { + Popover, + PopoverTrigger, + PopoverContent, + PopoverAnchor, + PopoverHeader, + PopoverTitle, + PopoverDescription, +}; diff --git a/src/components/ui/select.tsx b/src/components/ui/select.tsx new file mode 100644 index 0000000..7d3305c --- /dev/null +++ b/src/components/ui/select.tsx @@ -0,0 +1,188 @@ +import * as React from 'react'; +import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-react'; +import { Select as SelectPrimitive } from 'radix-ui'; + +import { cn } from '@/lib/utils'; + +function Select({ + ...props +}: React.ComponentProps) { + return ; +} + +function SelectGroup({ + ...props +}: React.ComponentProps) { + return ; +} + +function SelectValue({ + ...props +}: React.ComponentProps) { + return ; +} + +function SelectTrigger({ + className, + size = 'default', + children, + ...props +}: React.ComponentProps & { + size?: 'sm' | 'default'; +}) { + return ( + + {children} + + + + + ); +} + +function SelectContent({ + className, + children, + position = 'item-aligned', + align = 'center', + ...props +}: React.ComponentProps) { + return ( + + + + + {children} + + + + + ); +} + +function SelectLabel({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function SelectItem({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + + + + + + {children} + + ); +} + +function SelectSeparator({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function SelectScrollUpButton({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + ); +} + +function SelectScrollDownButton({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + ); +} + +export { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectScrollDownButton, + SelectScrollUpButton, + SelectSeparator, + SelectTrigger, + SelectValue, +}; diff --git a/src/pages/OnboardingPage.tsx b/src/pages/OnboardingPage.tsx index 96aa125..d5e5fad 100644 --- a/src/pages/OnboardingPage.tsx +++ b/src/pages/OnboardingPage.tsx @@ -7,22 +7,43 @@ import { BookOpen, Brain, CheckCircle2, + GraduationCap, Layers, LogIn, MousePointerClick, - Rocket, Users, - Waypoints, + Check, + ChevronsUpDown, } from 'lucide-react'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from '@/components/ui/popover'; +import { + Command, + CommandInput, + CommandList, + CommandEmpty, + CommandGroup, + CommandItem, +} from '@/components/ui/command'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select'; import { OnboardingStep } from '@/components/onboarding/OnboardingStep'; import { OnboardingPractice, OnboardingPracticeRef, } from '@/components/onboarding/OnboardingPractice'; -const TOTAL_STEPS = 4; +const TOTAL_STEPS = 5; const ONBOARDED_KEY = 'memo-onboarded'; export function OnboardingPage() { @@ -31,11 +52,13 @@ export function OnboardingPage() { const [consentChecked, setConsentChecked] = useState(false); const [practiceCompleted, setPracticeCompleted] = useState(false); const [currentPracticeCorrect, setCurrentPracticeCorrect] = useState(false); + const [selectedDegree, setSelectedDegree] = useState(null); + const [fieldOfStudy, setFieldOfStudy] = useState(''); const practiceRef = useRef(null); const navigate = useNavigate(); const goNext = useCallback(() => { - if (step === 2 && currentPracticeCorrect && !practiceCompleted) { + if (step === 3 && currentPracticeCorrect && !practiceCompleted) { practiceRef.current?.nextRound(); return; } @@ -66,7 +89,7 @@ export function OnboardingPage() { if (e.key === 'ArrowRight' && step < TOTAL_STEPS - 1) { // Don't advance past practice unless completed - if (step === 2 && !practiceCompleted && !currentPracticeCorrect) return; + if (step === 3 && !practiceCompleted && !currentPracticeCorrect) return; e.preventDefault(); goNext(); } @@ -82,10 +105,12 @@ export function OnboardingPage() { const canAdvance = step === 2 - ? practiceCompleted || currentPracticeCorrect + ? selectedDegree !== null && fieldOfStudy.trim().length > 0 : step === 3 - ? consentChecked - : true; + ? practiceCompleted || currentPracticeCorrect + : step === 4 + ? consentChecked + : true; return (

@@ -102,7 +127,11 @@ export function OnboardingPage() { Step {step + 1} of {TOTAL_STEPS} - {['Welcome', 'Our Mission', 'Practice', 'Guidelines'][step]} + { + ['Welcome', 'Our Mission', 'Profile', 'Practice', 'Guidelines'][ + step + ] + }
@@ -117,8 +146,17 @@ export function OnboardingPage() { {step === 0 && } - {step === 1 && } + {step === 1 && } {step === 2 && ( + + )} + {step === 3 && ( { @@ -130,7 +168,7 @@ export function OnboardingPage() { completed={practiceCompleted} /> )} - {step === 3 && ( + {step === 4 && ( setConsentChecked(c => !c)} @@ -139,35 +177,34 @@ export function OnboardingPage() {
- + {step < TOTAL_STEPS - 1 ? ( - + ) : ( )}
@@ -219,7 +256,7 @@ function StepWelcome() { className="mx-auto max-w-xl text-base leading-relaxed text-slate-600" > A competency network maps - how skills relate to each other — which ones are prerequisites, which + how skills relate to each other - which ones are prerequisites, which extend others, and which are equivalent. These networks power personalized learning recommendations. @@ -266,7 +303,6 @@ function CompetencyNetworkViz() { return (
- Competency Network Preview @@ -419,24 +455,41 @@ function CompetencyNetworkViz() { ))} -
+
- - Assumes → + + Competency +
- - Extends → +
+ + +
+ Assumes +
+ +
+ + +
+ Extends
Matches @@ -451,26 +504,26 @@ const HOW_IT_WORKS_TILES = [ icon: Layers, color: 'from-[#0a4da2] to-[#4263eb]', iconBg: 'bg-blue-100 text-blue-600', - title: 'See two competencies', - desc: 'We show you a pair of skills from a knowledge domain — like "Recursion" and "Divide and Conquer".', + title: 'See Two Competencies', + desc: 'We show you a pair of skills from a knowledge domain like "Recursion" and "Divide and Conquer".', }, { icon: MousePointerClick, color: 'from-[#7c3aed] to-[#9775fa]', iconBg: 'bg-purple-100 text-purple-600', - title: 'Pick a relationship', + title: 'Pick a Relationship', desc: 'Decide how they relate: prerequisite, extension, equivalent, or unrelated. Use buttons or keyboard shortcuts.', }, { icon: CheckCircle2, color: 'from-emerald-500 to-emerald-600', iconBg: 'bg-emerald-100 text-emerald-600', - title: 'Build the benchmark', + title: 'Build the Benchmark', desc: 'Your label joins a crowd-sourced dataset for fair, reproducible evaluation of recommender systems.', }, ]; -function StepHowItWorks({ onSignIn }: { onSignIn: () => void }) { +function StepHowItWorks() { return (
@@ -526,32 +579,215 @@ function StepHowItWorks({ onSignIn }: { onSignIn: () => void }) { skills.

-
- -
-
- Community-driven + Community-Driven - Open-source research + Open-Source Research
); } +const DEGREES = [ + { id: 'undergrad', label: 'Undergraduate Student' }, + { id: 'grad', label: 'Graduate Student' }, + { id: 'doc', label: 'Doctoral Student' }, + { id: 'postdoc', label: 'Postdoc / Researcher' }, + { id: 'industry', label: 'Industry Professional' }, + { id: 'other', label: 'Other' }, +]; + +const COMMON_DOMAINS = [ + 'Computer Science', + 'Business Administration', + 'Data Science', + 'Mathematics', +]; + +function StepProfile({ + selectedDegree, + onSelectDegree, + fieldOfStudy, + onFieldOfStudyChange, + onSignIn, +}: { + selectedDegree: string | null; + onSelectDegree: (degree: string) => void; + fieldOfStudy: string; + onFieldOfStudyChange: (field: string) => void; + onSignIn: () => void; +}) { + const [domainOpen, setDomainOpen] = useState(false); + const [searchQuery, setSearchQuery] = useState(''); + + return ( +
+
+ + Your Profile + +

+ Set Everything Up +

+

+ Link your university account and share your academic background to + help us better understand the diverse perspectives shaping our + dataset. +

+
+ +
+ {/* Authentication Card */} +
+
+ + Required + +
+
+

+ + Authentication +

+
+

+ We use your university account to securely record your contributions + while keeping your data private. +

+ +
+ + {/* Demographics Card */} +
+
+ + Required + +
+
+

+ + Academic Status +

+
+

+ Please select your current academic progress or highest degree so we + can better understand the demographics of our contributors. +

+ +
+
+ +
+ +
+ + + + + + + + + + {searchQuery.trim() !== '' ? ( + + ) : ( + + Type your domain... + + )} + + + {COMMON_DOMAINS.map(domain => ( + { + onFieldOfStudyChange(currentValue); + setSearchQuery(''); + setDomainOpen(false); + }} + className="cursor-pointer font-medium" + > + + {domain} + + ))} + + + + + +
+
+
+
+
+ ); +} + const StepPractice = forwardRef< OnboardingPracticeRef, { @@ -599,22 +835,22 @@ const StepPractice = forwardRef< const GUIDELINES = [ { emoji: '🎯', - title: 'Accuracy over speed', + title: 'Accuracy Over Speed', desc: 'Take your time. One thoughtful label is better than many rushed ones.', }, { emoji: '⏭️', - title: 'Skip when unsure', + title: 'Skip When Unsure', desc: 'No penalty for skipping. If a pair is ambiguous, move on.', }, { emoji: '🤝', - title: 'No competition', + title: 'No Competition', desc: 'This is a collaboration, not a race. Every contribution matters.', }, { emoji: '↩️', - title: 'Undo is available', + title: 'Undo Is Available', desc: 'Made a mistake? Use the undo button or Shift+Z to fix it.', }, ]; @@ -671,7 +907,8 @@ function StepConsent({ ground-truth benchmark data
{' '} for evaluating competency-aware recommender systems. My - contributions are anonymous and cannot be traced back to me. + contributions are private and will only be accessible anonymized + during this research project.
From c4a25a232adffe2271350fbccf5d2d63b9b2e836 Mon Sep 17 00:00:00 2001 From: Viktoriya Totalova Date: Fri, 27 Feb 2026 16:02:45 +0100 Subject: [PATCH 24/57] add simple auth implementation --- public/silent-check-sso.html | 8 + server/build.gradle | 1 + server/docker-compose.yml | 1 + server/docker/keycloak/memo-realm.json | 5343 ++++++++++++++++- .../keycloak/test-university-realm.json | 84 + server/scripts/configure-keycloak.sh | 46 + server/scripts/register-dfn-aai.sh | 73 + .../cit/memo/controller/AuthController.java | 38 + .../java/de/tum/cit/memo/entity/User.java | 11 +- .../tum/cit/memo/security/SecurityConfig.java | 8 +- .../de/tum/cit/memo/service/UserService.java | 8 + server/src/main/resources/application.yml | 7 + .../V5__update_users_for_keycloak_auth.sql | 10 + src/App.tsx | 28 +- src/components/ProtectedRoute.tsx | 20 + src/components/navbar.tsx | 28 +- src/contexts/AuthContext.tsx | 101 + src/data/universities.ts | 154 + src/index.css | 10 +- src/lib/api/client.ts | 9 + src/lib/api/session-helpers.ts | 27 +- src/lib/auth/keycloak.ts | 17 + src/pages/LoginPage.tsx | 72 + 23 files changed, 6037 insertions(+), 67 deletions(-) create mode 100644 public/silent-check-sso.html create mode 100644 server/docker/keycloak/test-university-realm.json create mode 100755 server/scripts/configure-keycloak.sh create mode 100755 server/scripts/register-dfn-aai.sh create mode 100644 server/src/main/java/de/tum/cit/memo/controller/AuthController.java create mode 100644 server/src/main/resources/db/migration/V5__update_users_for_keycloak_auth.sql create mode 100644 src/components/ProtectedRoute.tsx create mode 100644 src/contexts/AuthContext.tsx create mode 100644 src/data/universities.ts create mode 100644 src/lib/auth/keycloak.ts create mode 100644 src/pages/LoginPage.tsx diff --git a/public/silent-check-sso.html b/public/silent-check-sso.html new file mode 100644 index 0000000..5357587 --- /dev/null +++ b/public/silent-check-sso.html @@ -0,0 +1,8 @@ + + + + + + diff --git a/server/build.gradle b/server/build.gradle index 52b5213..80f16be 100644 --- a/server/build.gradle +++ b/server/build.gradle @@ -66,6 +66,7 @@ dependencies { implementation 'org.flywaydb:flyway-database-postgresql' // Security + implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server' implementation 'com.nimbusds:nimbus-jose-jwt:10.6' // API Documentation diff --git a/server/docker-compose.yml b/server/docker-compose.yml index 693ca9a..87208f8 100644 --- a/server/docker-compose.yml +++ b/server/docker-compose.yml @@ -56,6 +56,7 @@ services: - '8081:8080' volumes: - ./docker/keycloak/memo-realm.json:/opt/keycloak/data/import/memo-realm.json + - ./docker/keycloak/test-university-realm.json:/opt/keycloak/data/import/test-university-realm.json depends_on: keycloak-postgres: condition: service_healthy diff --git a/server/docker/keycloak/memo-realm.json b/server/docker/keycloak/memo-realm.json index e01c586..8953a0f 100644 --- a/server/docker/keycloak/memo-realm.json +++ b/server/docker/keycloak/memo-realm.json @@ -3,7 +3,7 @@ "realm": "memo", "enabled": true, "sslRequired": "none", - "registrationAllowed": true, + "registrationAllowed": false, "loginWithEmailAllowed": true, "duplicateEmailsAllowed": false, "resetPasswordAllowed": true, @@ -14,8 +14,14 @@ "clientId": "memo-client", "enabled": true, "publicClient": true, - "redirectUris": ["http://localhost:3000/*", "http://localhost:5173/*"], - "webOrigins": ["http://localhost:3000", "http://localhost:5173"], + "redirectUris": [ + "http://localhost:3000/*", + "http://localhost:5173/*" + ], + "webOrigins": [ + "http://localhost:3000", + "http://localhost:5173" + ], "directAccessGrantsEnabled": true, "standardFlowEnabled": true, "implicitFlowEnabled": false, @@ -38,36 +44,5313 @@ } ] }, - "users": [ - { - "username": "demo", - "email": "demo@memo.local", - "enabled": true, - "firstName": "Demo", - "lastName": "User", - "credentials": [ - { - "type": "password", - "value": "demo", - "temporary": false - } - ], - "realmRoles": ["USER"] + "identityProviders": [ + { + "alias": "test-university", + "displayName": "Test University (Dev only)", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "http://localhost:8081/realms/test-university/protocol/saml", + "singleLogoutServiceUrl": "http://localhost:8081/realms/test-university/protocol/saml", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + } }, { - "username": "admin", - "email": "admin@memo.local", + "alias": "tum", + "providerId": "saml", "enabled": true, - "firstName": "Admin", - "lastName": "User", - "credentials": [ - { - "type": "password", - "value": "admin", - "temporary": false - } - ], - "realmRoles": ["ADMIN", "USER"] + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://tumidp.lrz.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Technische Universität München" + }, + { + "alias": "lmu", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://lmuidp.lrz.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Ludwig-Maximilians-Universität München" + }, + { + "alias": "rwth-aachen", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://login.rz.rwth-aachen.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "RWTH Aachen University" + }, + { + "alias": "kit", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.scc.kit.edu/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Karlsruher Institut für Technologie (KIT)" + }, + { + "alias": "tu-berlin", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://ephraim.tu-berlin.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Technische Universität Berlin" + }, + { + "alias": "tu-dresden", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.tu-dresden.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Technische Universität Dresden" + }, + { + "alias": "tu-darmstadt", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hrz.tu-darmstadt.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Technische Universität Darmstadt" + }, + { + "alias": "tu-chemnitz", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://wtc.tu-chemnitz.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "TU Chemnitz" + }, + { + "alias": "btu-cottbus", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://www.b-tu.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "BTU Cottbus - Senftenberg" + }, + { + "alias": "fu-berlin", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://identity.fu-berlin.de/idp-fub/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Freie Universität Berlin" + }, + { + "alias": "hu-berlin", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.cms.hu-berlin.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Humboldt-Universität zu Berlin" + }, + { + "alias": "uni-hamburg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://login.uni-hamburg.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Universität Hamburg" + }, + { + "alias": "uni-freiburg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://mylogin.uni-freiburg.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Albert-Ludwigs-Universität Freiburg" + }, + { + "alias": "luh-hannover", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://sso.idm.uni-hannover.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Leibniz Universität Hannover" + }, + { + "alias": "uni-koeln", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.rrz.uni-koeln.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Universität zu Köln" + }, + { + "alias": "uni-frankfurt", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hebis.de/uni-frankfurt/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Goethe-Universität Frankfurt" + }, + { + "alias": "uni-stuttgart", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.uni-stuttgart.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Universität Stuttgart" + }, + { + "alias": "uni-heidelberg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.uni-heidelberg.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Universität Heidelberg" + }, + { + "alias": "uni-tuebingen", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.uni-tuebingen.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Universität Tübingen" + }, + { + "alias": "uni-konstanz", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.uni-konstanz.de/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Universität Konstanz" + }, + { + "alias": "uni-passau", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://sso.uni-passau.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Universität Passau" + }, + { + "alias": "uni-rostock", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.uni-rostock.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Universität Rostock" + }, + { + "alias": "uni-bremen", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.uni-bremen.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Universität Bremen" + }, + { + "alias": "uni-wuerzburg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://shibboleth-idp.uni-wuerzburg.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Julius-Maximilians-Universität Würzburg" + }, + { + "alias": "uni-bamberg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.rz.uni-bamberg.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Otto-Friedrich-Universität Bamberg" + }, + { + "alias": "uni-kiel", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.rz.uni-kiel.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Christian-Albrechts-Universität zu Kiel" + }, + { + "alias": "uni-luebeck", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.uni-luebeck.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Universität zu Lübeck" + }, + { + "alias": "uni-erfurt", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://sinope.uni-erfurt.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Universität Erfurt" + }, + { + "alias": "uni-kassel", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hrz.uni-kassel.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Universität Kassel" + }, + { + "alias": "uni-koblenz", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://shibboleth.uni-koblenz.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Universität Koblenz" + }, + { + "alias": "uni-giessen", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hrz.uni-giessen.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Justus-Liebig-Universität Gießen" + }, + { + "alias": "uni-duisburg-essen", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.uni-duisburg-essen.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Universität Duisburg-Essen" + }, + { + "alias": "leuphana", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp01.leuphana.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Leuphana Universität Lüneburg" + }, + { + "alias": "bauhaus-weimar", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://shibbo.scc.uni-weimar.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Bauhaus-Universität Weimar" + }, + { + "alias": "zeppelin-uni", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.zu.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Zeppelin Universität" + }, + { + "alias": "ipu-berlin", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.ipu-berlin.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Internationale Psychoanalytische Universität Berlin" + }, + { + "alias": "frankfurt-uas", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.cit.frankfurt-university.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Frankfurt University of Applied Sciences" + }, + { + "alias": "haw-hamburg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://login.haw-hamburg.de/realms/HAW-Hamburg/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule für Angewandte Wissenschaften Hamburg" + }, + { + "alias": "bht-berlin", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://login.beuth-hochschule.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Berliner Hochschule für Technik" + }, + { + "alias": "ostfalia", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://shib-idp.ostfalia.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Ostfalia Hochschule" + }, + { + "alias": "hs-harz", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hs-harz.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule Harz" + }, + { + "alias": "hs-rheinmain", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hs-rm.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule RheinMain" + }, + { + "alias": "hs-neubrandenburg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hs-nb.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule Neubrandenburg" + }, + { + "alias": "hs-nachhaltige-eberswalde", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp-prod.hnee.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule für Nachhaltige Entwicklung Eberswalde" + }, + { + "alias": "hcu-hamburg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hcu-hamburg.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "HafenCity Universität Hamburg" + }, + { + "alias": "hs-aalen", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.htw-aalen.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule Aalen" + }, + { + "alias": "th-brandenburg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.th-brandenburg.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Technische Hochschule Brandenburg" + }, + { + "alias": "hs-geisenheim", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://shib-idp-srv1.hs-gm.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule Geisenheim University" + }, + { + "alias": "hs-landshut", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idpsso.haw-landshut.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule Landshut" + }, + { + "alias": "hs-hamm-lippstadt", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hshl.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule Hamm-Lippstadt" + }, + { + "alias": "hs-bonn-rhein-sieg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.h-brs.de/nidp/saml2/metadata/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule Bonn-Rhein-Sieg" + }, + { + "alias": "th-luebeck", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp01.th-luebeck.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Technische Hochschule Lübeck" + }, + { + "alias": "th-ulm", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://login.hs-ulm.de/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Technische Hochschule Ulm" + }, + { + "alias": "th-mittelhessen", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.thm.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Technische Hochschule Mittelhessen" + }, + { + "alias": "hs-trier", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.fh-trier.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule Trier" + }, + { + "alias": "hs-furtwangen", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp2.hs-furtwangen.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule Furtwangen" + }, + { + "alias": "hs-bremerhaven", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hs-bremerhaven.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule Bremerhaven" + }, + { + "alias": "hs-stralsund", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hochschule-stralsund.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule Stralsund" + }, + { + "alias": "hs-anhalt", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hs-anhalt.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule Anhalt" + }, + { + "alias": "hs-weihenstephan", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp2.hswt.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule Weihenstephan-Triesdorf" + }, + { + "alias": "hs-zittau-goerlitz", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hszg.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule Zittau/Görlitz" + }, + { + "alias": "thga-bochum", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://checkin.thga.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "THGA Bochum" + }, + { + "alias": "dhbw-mannheim", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.dhbw-mannheim.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "DHBW Mannheim" + }, + { + "alias": "dhbw-mosbach", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp-mosbach.dhbw.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "DHBW Mosbach" + }, + { + "alias": "ba-sachsen", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.ba-sachsen.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Berufsakademie Sachsen" + }, + { + "alias": "hs-kehl", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hs-kehl.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule für öffentliche Verwaltung Kehl" + }, + { + "alias": "dhpol", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.dhpol.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Deutsche Hochschule der Polizei" + }, + { + "alias": "helmut-schmidt-uni", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.ub.hsu-hh.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Helmut-Schmidt-Universität Hamburg" + }, + { + "alias": "ph-heidelberg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://shib.ph-heidelberg.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Pädagogische Hochschule Heidelberg" + }, + { + "alias": "ph-ludwigsburg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.ph-ludwigsburg.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Pädagogische Hochschule Ludwigsburg" + }, + { + "alias": "ph-schwaebisch-gmuend", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.ph-gmuend.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "PH Schwäbisch Gmünd" + }, + { + "alias": "hfmt-hamburg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://login.hfmt-hamburg.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule für Musik und Theater Hamburg" + }, + { + "alias": "hmt-rostock", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hmt-rostock.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule für Musik und Theater Rostock" + }, + { + "alias": "hfmdk-frankfurt", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hfmdk-frankfurt.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule für Musik und Darstellende Kunst Frankfurt" + }, + { + "alias": "muho-mannheim", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.muho-mannheim.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Staatliche Hochschule für Musik und Darstellende Kunst Mannheim" + }, + { + "alias": "hfmt-koeln", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hfmt-koeln.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule für Musik und Tanz Köln" + }, + { + "alias": "mh-trossingen", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.mh-trossingen.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Staatliche Hochschule für Musik Trossingen" + }, + { + "alias": "rsh-duesseldorf", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://shib.rsh-duesseldorf.de/idp/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Robert Schumann Hochschule Düsseldorf" + }, + { + "alias": "hbk-braunschweig", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://shib-idp.hbk-bs.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule für Bildende Künste Braunschweig" + }, + { + "alias": "hfg-offenbach", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hfg-offenbach.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule für Gestaltung Offenbach" + }, + { + "alias": "hfg-schwaebisch-gmuend", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hfg-gmuend.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "HfG Hochschule für Gestaltung Schwäbisch Gmünd" + }, + { + "alias": "khm-koeln", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.khm.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Kunsthochschule für Medien Köln" + }, + { + "alias": "palucca-dresden", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.palucca.eu/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Palucca Hochschule für Tanz Dresden" + }, + { + "alias": "hertie-school", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.hertie-school.org/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hertie School of Governance" + }, + { + "alias": "esmt-berlin", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.esmt.org/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "ESMT Berlin" + }, + { + "alias": "ism-management", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.ism.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "ISM International School of Management" + }, + { + "alias": "hfph-muenchen", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://sso.hfph.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschule für Philosophie München" + }, + { + "alias": "khsb-berlin", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.khsb-berlin.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Katholische Hochschule für Sozialwesen Berlin" + }, + { + "alias": "katho-nrw", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://shibboleth-idp.katho-nrw.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Katholische Hochschule Nordrhein-Westfalen" + }, + { + "alias": "evh-bochum", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.evh-bochum.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Evangelische Hochschule Rheinland-Westfalen-Lippe" + }, + { + "alias": "bib-international", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.bib.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "bib International College" + }, + { + "alias": "mhb-fontane", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp-dev.mhb-fontane.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Medizinische Hochschule Brandenburg" + }, + { + "alias": "msh-private", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://sso.private-hochschulen-deutschland.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "MSH Medical School Hamburg / BSP Business School Berlin" + }, + { + "alias": "cispa", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp0.cispa.de/simplesaml/saml2/idp/SSOService.php", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "CISPA – Helmholtz-Zentrum für Informationssicherheit" + }, + { + "alias": "charite", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://dfnaai.charite.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Charité – Universitätsmedizin Berlin" + }, + { + "alias": "uk-augsburg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.uk-augsburg.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Universitätsklinikum Augsburg" + }, + { + "alias": "uk-dresden", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://login.uniklinikum-dresden.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Universitätsklinikum Carl Gustav Carus Dresden" + }, + { + "alias": "awi", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://shib-idp.awi.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Alfred-Wegener-Institut (AWI)" + }, + { + "alias": "geomar", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.geomar.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "GEOMAR Helmholtz-Zentrum für Ozeanforschung Kiel" + }, + { + "alias": "pik", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://aai.pik-potsdam.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Potsdam-Institut für Klimafolgenforschung" + }, + { + "alias": "dkrz", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.dkrz.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Deutsches Klimarechenzentrum (DKRZ)" + }, + { + "alias": "dipf", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://login.dipf.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "DIPF – Leibniz-Institut für Bildungsforschung" + }, + { + "alias": "iwm-tuebingen", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.iwm-tuebingen.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Leibniz-Institut für Wissensmedien" + }, + { + "alias": "iamo", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://rakorium.iamo.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Leibniz-Institut für Agrarentwicklung (IAMO)" + }, + { + "alias": "iwt-bremen", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://login.iwt-bremen.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Leibniz-Institut für Werkstofforientierte Technologien (IWT)" + }, + { + "alias": "ifw-dresden", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.ifw-dresden.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "IFW Dresden" + }, + { + "alias": "inp-greifswald", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.inp-greifswald.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Leibniz-Institut für Plasmaforschung (INP Greifswald)" + }, + { + "alias": "likat-rostock", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://srv-idp.catalysis.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Leibniz-Institut für Katalyse (LIKAT)" + }, + { + "alias": "fbn-dummerstorf", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://hotaai.fbn-dummerstorf.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Forschungsinstitut für Nutztierbiologie (FBN)" + }, + { + "alias": "mdc-berlin", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://aai-mdc1.mdc-berlin.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Max-Delbrück-Centrum für Molekulare Medizin" + }, + { + "alias": "mpg-general", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://login.global.mpg.de/idp/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Max-Planck-Gesellschaft (Generalverwaltung)" + }, + { + "alias": "mpcdf", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://shibb.mpcdf.mpg.de/mpcdf/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Max Planck Computing and Data Facility" + }, + { + "alias": "mpi-chemie", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://sso.mpic.de/auth/saml2/idp/SSOService.php", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Max-Planck-Institut für Chemie" + }, + { + "alias": "mpi-biochemie", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.biochem.mpg.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Max-Planck-Institut für Biochemie" + }, + { + "alias": "mpi-chem-oekologie", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://radius.ice.mpg.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Max-Planck-Institut für Chemische Ökologie" + }, + { + "alias": "mpi-intelligente-systeme", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://chip.is.mpg.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Max-Planck-Institut für Intelligente Systeme" + }, + { + "alias": "mpi-plasmaphysik", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://shibb.mpcdf.mpg.de/ipp/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Max-Planck-Institut für Plasmaphysik (IPP)" + }, + { + "alias": "mpi-quantenoptik", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://shibb.mpcdf.mpg.de/mpq/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Max-Planck-Institut für Quantenoptik" + }, + { + "alias": "mpi-kohlenforschung", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://shibboleth1.mpi-muelheim.mpg.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Max-Planck-Institut für Kohlenforschung" + }, + { + "alias": "mpg-gwdg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp/profile/SAML2/POST/SSO-idp.mpg.de/mpg/shibboleth", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Max-Planck-Institute (via GWDG MetaDir)" + }, + { + "alias": "fbh-berlin", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://fbh-idp.fbh-berlin.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Ferdinand-Braun-Institut, Leibniz-Institut für Höchstfrequenztechnik" + }, + { + "alias": "hits-heidelberg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.h-its.org/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "HITS gGmbH (Heidelberg Institute for Theoretical Studies)" + }, + { + "alias": "eso", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.eso.org/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "ESO – European Southern Observatory" + }, + { + "alias": "gwdg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp/profile/SAML2/POST/SSO-idp.gwdg.de/gwdg/shibboleth", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "GWDG (Gesellschaft für Wissenschaftliche Datenverarbeitung Göttingen)" + }, + { + "alias": "leibniz-gemeinschaft", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://login.leibniz-gemeinschaft.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Leibniz-Gemeinschaft (Geschäftsstelle)" + }, + { + "alias": "lrz-badw", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.lrz.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Leibniz-Rechenzentrum / Bayerische Akademie der Wissenschaften (BAdW)" + }, + { + "alias": "bsz-bw", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.bsz-bw.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Bibliotheksservice-Zentrum Baden-Württemberg (BSZ)" + }, + { + "alias": "hbz-nrw", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://shibboleth-idp.hbz-nrw.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Hochschulbibliothekszentrum NRW (hbz)" + }, + { + "alias": "vzg", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://www.vho.de/idpvzg/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Verbundzentrale des GBV (VZG)" + }, + { + "alias": "slub-dresden", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://login.slub-dresden.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "SLUB Dresden" + }, + { + "alias": "bsb-muenchen", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.bsb-muenchen.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Bayerische Staatsbibliothek München" + }, + { + "alias": "blb-karlsruhe", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://blblogin.blb-karlsruhe.de/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Badische Landesbibliothek" + }, + { + "alias": "dsm", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.dsm.museum/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Deutsches Schifffahrtsmuseum (DSM)" + }, + { + "alias": "vhb", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://idp.vhb.org/idp/profile/SAML2/POST/SSO", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "Virtuelle Hochschule Bayern (vhb)" + }, + { + "alias": "daad", + "providerId": "saml", + "enabled": true, + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "singleSignOnServiceUrl": "https://saml.daad.de/saml2/idp/SSOService.php", + "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "principalType": "SUBJECT", + "signatureAlgorithm": "RSA_SHA256", + "xmlSigKeyInfoKeyNameTransformer": "KEY_ID", + "authnContextComparisonType": "exact", + "postBindingResponse": "true", + "postBindingAuthnRequest": "true", + "postBindingLogout": "true", + "wantAuthnRequestsSigned": "false", + "wantAssertionsSigned": "true", + "wantAssertionsEncrypted": "false", + "validateSignature": "false", + "forceAuthn": "false", + "hideOnLoginPage": "true", + "syncMode": "IMPORT" + }, + "displayName": "DAAD" + } + ], + "identityProviderMappers": [ + { + "name": "test-university-username-mapper", + "identityProviderAlias": "test-university", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "tum-username-mapper", + "identityProviderAlias": "tum", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "lmu-username-mapper", + "identityProviderAlias": "lmu", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "rwth-aachen-username-mapper", + "identityProviderAlias": "rwth-aachen", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "kit-username-mapper", + "identityProviderAlias": "kit", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "tu-berlin-username-mapper", + "identityProviderAlias": "tu-berlin", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "tu-dresden-username-mapper", + "identityProviderAlias": "tu-dresden", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "tu-darmstadt-username-mapper", + "identityProviderAlias": "tu-darmstadt", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "tu-chemnitz-username-mapper", + "identityProviderAlias": "tu-chemnitz", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "btu-cottbus-username-mapper", + "identityProviderAlias": "btu-cottbus", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "fu-berlin-username-mapper", + "identityProviderAlias": "fu-berlin", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hu-berlin-username-mapper", + "identityProviderAlias": "hu-berlin", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-hamburg-username-mapper", + "identityProviderAlias": "uni-hamburg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-freiburg-username-mapper", + "identityProviderAlias": "uni-freiburg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "luh-hannover-username-mapper", + "identityProviderAlias": "luh-hannover", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-koeln-username-mapper", + "identityProviderAlias": "uni-koeln", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-frankfurt-username-mapper", + "identityProviderAlias": "uni-frankfurt", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-stuttgart-username-mapper", + "identityProviderAlias": "uni-stuttgart", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-heidelberg-username-mapper", + "identityProviderAlias": "uni-heidelberg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-tuebingen-username-mapper", + "identityProviderAlias": "uni-tuebingen", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-konstanz-username-mapper", + "identityProviderAlias": "uni-konstanz", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-passau-username-mapper", + "identityProviderAlias": "uni-passau", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-rostock-username-mapper", + "identityProviderAlias": "uni-rostock", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-bremen-username-mapper", + "identityProviderAlias": "uni-bremen", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-wuerzburg-username-mapper", + "identityProviderAlias": "uni-wuerzburg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-bamberg-username-mapper", + "identityProviderAlias": "uni-bamberg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-kiel-username-mapper", + "identityProviderAlias": "uni-kiel", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-luebeck-username-mapper", + "identityProviderAlias": "uni-luebeck", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-erfurt-username-mapper", + "identityProviderAlias": "uni-erfurt", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-kassel-username-mapper", + "identityProviderAlias": "uni-kassel", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-koblenz-username-mapper", + "identityProviderAlias": "uni-koblenz", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-giessen-username-mapper", + "identityProviderAlias": "uni-giessen", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uni-duisburg-essen-username-mapper", + "identityProviderAlias": "uni-duisburg-essen", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "leuphana-username-mapper", + "identityProviderAlias": "leuphana", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "bauhaus-weimar-username-mapper", + "identityProviderAlias": "bauhaus-weimar", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "zeppelin-uni-username-mapper", + "identityProviderAlias": "zeppelin-uni", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "ipu-berlin-username-mapper", + "identityProviderAlias": "ipu-berlin", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "frankfurt-uas-username-mapper", + "identityProviderAlias": "frankfurt-uas", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "haw-hamburg-username-mapper", + "identityProviderAlias": "haw-hamburg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "bht-berlin-username-mapper", + "identityProviderAlias": "bht-berlin", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "ostfalia-username-mapper", + "identityProviderAlias": "ostfalia", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-harz-username-mapper", + "identityProviderAlias": "hs-harz", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-rheinmain-username-mapper", + "identityProviderAlias": "hs-rheinmain", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-neubrandenburg-username-mapper", + "identityProviderAlias": "hs-neubrandenburg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-nachhaltige-eberswalde-username-mapper", + "identityProviderAlias": "hs-nachhaltige-eberswalde", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hcu-hamburg-username-mapper", + "identityProviderAlias": "hcu-hamburg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-aalen-username-mapper", + "identityProviderAlias": "hs-aalen", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "th-brandenburg-username-mapper", + "identityProviderAlias": "th-brandenburg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-geisenheim-username-mapper", + "identityProviderAlias": "hs-geisenheim", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-landshut-username-mapper", + "identityProviderAlias": "hs-landshut", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-hamm-lippstadt-username-mapper", + "identityProviderAlias": "hs-hamm-lippstadt", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-bonn-rhein-sieg-username-mapper", + "identityProviderAlias": "hs-bonn-rhein-sieg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "th-luebeck-username-mapper", + "identityProviderAlias": "th-luebeck", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "th-ulm-username-mapper", + "identityProviderAlias": "th-ulm", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "th-mittelhessen-username-mapper", + "identityProviderAlias": "th-mittelhessen", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-trier-username-mapper", + "identityProviderAlias": "hs-trier", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-furtwangen-username-mapper", + "identityProviderAlias": "hs-furtwangen", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-bremerhaven-username-mapper", + "identityProviderAlias": "hs-bremerhaven", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-stralsund-username-mapper", + "identityProviderAlias": "hs-stralsund", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-anhalt-username-mapper", + "identityProviderAlias": "hs-anhalt", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-weihenstephan-username-mapper", + "identityProviderAlias": "hs-weihenstephan", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-zittau-goerlitz-username-mapper", + "identityProviderAlias": "hs-zittau-goerlitz", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "thga-bochum-username-mapper", + "identityProviderAlias": "thga-bochum", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "dhbw-mannheim-username-mapper", + "identityProviderAlias": "dhbw-mannheim", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "dhbw-mosbach-username-mapper", + "identityProviderAlias": "dhbw-mosbach", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "ba-sachsen-username-mapper", + "identityProviderAlias": "ba-sachsen", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hs-kehl-username-mapper", + "identityProviderAlias": "hs-kehl", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "dhpol-username-mapper", + "identityProviderAlias": "dhpol", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "helmut-schmidt-uni-username-mapper", + "identityProviderAlias": "helmut-schmidt-uni", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "ph-heidelberg-username-mapper", + "identityProviderAlias": "ph-heidelberg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "ph-ludwigsburg-username-mapper", + "identityProviderAlias": "ph-ludwigsburg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "ph-schwaebisch-gmuend-username-mapper", + "identityProviderAlias": "ph-schwaebisch-gmuend", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hfmt-hamburg-username-mapper", + "identityProviderAlias": "hfmt-hamburg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hmt-rostock-username-mapper", + "identityProviderAlias": "hmt-rostock", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hfmdk-frankfurt-username-mapper", + "identityProviderAlias": "hfmdk-frankfurt", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "muho-mannheim-username-mapper", + "identityProviderAlias": "muho-mannheim", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hfmt-koeln-username-mapper", + "identityProviderAlias": "hfmt-koeln", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "mh-trossingen-username-mapper", + "identityProviderAlias": "mh-trossingen", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "rsh-duesseldorf-username-mapper", + "identityProviderAlias": "rsh-duesseldorf", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hbk-braunschweig-username-mapper", + "identityProviderAlias": "hbk-braunschweig", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hfg-offenbach-username-mapper", + "identityProviderAlias": "hfg-offenbach", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hfg-schwaebisch-gmuend-username-mapper", + "identityProviderAlias": "hfg-schwaebisch-gmuend", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "khm-koeln-username-mapper", + "identityProviderAlias": "khm-koeln", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "palucca-dresden-username-mapper", + "identityProviderAlias": "palucca-dresden", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hertie-school-username-mapper", + "identityProviderAlias": "hertie-school", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "esmt-berlin-username-mapper", + "identityProviderAlias": "esmt-berlin", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "ism-management-username-mapper", + "identityProviderAlias": "ism-management", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hfph-muenchen-username-mapper", + "identityProviderAlias": "hfph-muenchen", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "khsb-berlin-username-mapper", + "identityProviderAlias": "khsb-berlin", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "katho-nrw-username-mapper", + "identityProviderAlias": "katho-nrw", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "evh-bochum-username-mapper", + "identityProviderAlias": "evh-bochum", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "bib-international-username-mapper", + "identityProviderAlias": "bib-international", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "mhb-fontane-username-mapper", + "identityProviderAlias": "mhb-fontane", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "msh-private-username-mapper", + "identityProviderAlias": "msh-private", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "cispa-username-mapper", + "identityProviderAlias": "cispa", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "charite-username-mapper", + "identityProviderAlias": "charite", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uk-augsburg-username-mapper", + "identityProviderAlias": "uk-augsburg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "uk-dresden-username-mapper", + "identityProviderAlias": "uk-dresden", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "awi-username-mapper", + "identityProviderAlias": "awi", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "geomar-username-mapper", + "identityProviderAlias": "geomar", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "pik-username-mapper", + "identityProviderAlias": "pik", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "dkrz-username-mapper", + "identityProviderAlias": "dkrz", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "dipf-username-mapper", + "identityProviderAlias": "dipf", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "iwm-tuebingen-username-mapper", + "identityProviderAlias": "iwm-tuebingen", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "iamo-username-mapper", + "identityProviderAlias": "iamo", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "iwt-bremen-username-mapper", + "identityProviderAlias": "iwt-bremen", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "ifw-dresden-username-mapper", + "identityProviderAlias": "ifw-dresden", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "inp-greifswald-username-mapper", + "identityProviderAlias": "inp-greifswald", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "likat-rostock-username-mapper", + "identityProviderAlias": "likat-rostock", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "fbn-dummerstorf-username-mapper", + "identityProviderAlias": "fbn-dummerstorf", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "mdc-berlin-username-mapper", + "identityProviderAlias": "mdc-berlin", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "mpg-general-username-mapper", + "identityProviderAlias": "mpg-general", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "mpcdf-username-mapper", + "identityProviderAlias": "mpcdf", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "mpi-chemie-username-mapper", + "identityProviderAlias": "mpi-chemie", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "mpi-biochemie-username-mapper", + "identityProviderAlias": "mpi-biochemie", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "mpi-chem-oekologie-username-mapper", + "identityProviderAlias": "mpi-chem-oekologie", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "mpi-intelligente-systeme-username-mapper", + "identityProviderAlias": "mpi-intelligente-systeme", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "mpi-plasmaphysik-username-mapper", + "identityProviderAlias": "mpi-plasmaphysik", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "mpi-quantenoptik-username-mapper", + "identityProviderAlias": "mpi-quantenoptik", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "mpi-kohlenforschung-username-mapper", + "identityProviderAlias": "mpi-kohlenforschung", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "mpg-gwdg-username-mapper", + "identityProviderAlias": "mpg-gwdg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "fbh-berlin-username-mapper", + "identityProviderAlias": "fbh-berlin", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hits-heidelberg-username-mapper", + "identityProviderAlias": "hits-heidelberg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "eso-username-mapper", + "identityProviderAlias": "eso", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "gwdg-username-mapper", + "identityProviderAlias": "gwdg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "leibniz-gemeinschaft-username-mapper", + "identityProviderAlias": "leibniz-gemeinschaft", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "lrz-badw-username-mapper", + "identityProviderAlias": "lrz-badw", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "bsz-bw-username-mapper", + "identityProviderAlias": "bsz-bw", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "hbz-nrw-username-mapper", + "identityProviderAlias": "hbz-nrw", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "vzg-username-mapper", + "identityProviderAlias": "vzg", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "slub-dresden-username-mapper", + "identityProviderAlias": "slub-dresden", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "bsb-muenchen-username-mapper", + "identityProviderAlias": "bsb-muenchen", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "blb-karlsruhe-username-mapper", + "identityProviderAlias": "blb-karlsruhe", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "dsm-username-mapper", + "identityProviderAlias": "dsm", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "vhb-username-mapper", + "identityProviderAlias": "vhb", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } + }, + { + "name": "daad-username-mapper", + "identityProviderAlias": "daad", + "identityProviderMapper": "saml-username-idp-mapper", + "config": { + "syncMode": "INHERIT", + "template": "${NAMEID}" + } } ] } diff --git a/server/docker/keycloak/test-university-realm.json b/server/docker/keycloak/test-university-realm.json new file mode 100644 index 0000000..285f222 --- /dev/null +++ b/server/docker/keycloak/test-university-realm.json @@ -0,0 +1,84 @@ +{ + "id": "test-university", + "realm": "test-university", + "enabled": true, + "sslRequired": "none", + "registrationAllowed": false, + "loginWithEmailAllowed": true, + "duplicateEmailsAllowed": false, + "bruteForceProtected": false, + "displayName": "Test University IdP (Dev)", + "clients": [ + { + "clientId": "http://localhost:8081/realms/memo", + "name": "Memo Application (SP)", + "enabled": true, + "protocol": "saml", + "publicClient": false, + "frontchannelLogout": true, + "attributes": { + "saml.authnstatement": "true", + "saml.server.signature": "true", + "saml.assertion.signature": "true", + "saml_force_name_id_format": "true", + "saml.force.post.binding": "true", + "saml.client.signature": "false", + "saml_name_id_format": "persistent", + "saml.signing.certificate": "" + }, + "redirectUris": [ + "http://localhost:8081/realms/memo/broker/test-university/endpoint*" + ], + "adminUrl": "http://localhost:8081/realms/memo/broker/test-university/endpoint", + "baseUrl": "http://localhost:3000", + "protocolMappers": [ + { + "name": "username", + "protocol": "saml", + "protocolMapper": "saml-user-property-mapper", + "consentRequired": false, + "config": { + "attribute.nameformat": "Basic", + "user.attribute": "username", + "attribute.name": "username" + } + } + ] + } + ], + "users": [ + { + "username": "student", + "enabled": true, + "credentials": [ + { + "type": "password", + "value": "student123", + "temporary": false + } + ] + }, + { + "username": "demo", + "enabled": true, + "credentials": [ + { + "type": "password", + "value": "demo", + "temporary": false + } + ] + }, + { + "username": "admin", + "enabled": true, + "credentials": [ + { + "type": "password", + "value": "admin", + "temporary": false + } + ] + } + ] +} diff --git a/server/scripts/configure-keycloak.sh b/server/scripts/configure-keycloak.sh new file mode 100755 index 0000000..f6dea26 --- /dev/null +++ b/server/scripts/configure-keycloak.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Configures the memo Keycloak realm after startup: +# - Disables "Review Profile" in the First Broker Login flow +# so university SSO users are created silently with no profile prompt + +set -e + +KEYCLOAK_URL="${KEYCLOAK_URL:-http://localhost:8081}" +REALM="memo" + +echo "Waiting for Keycloak to be ready..." +until curl -sf "$KEYCLOAK_URL/realms/memo" > /dev/null 2>&1; do + sleep 2 +done + +echo "Getting admin token..." +TOKEN=$(curl -sf -X POST "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d "username=admin&password=admin&grant_type=password&client_id=admin-cli" \ + | grep -o '"access_token":"[^"]*"' | cut -d'"' -f4) + +if [ -z "$TOKEN" ]; then + echo "ERROR: Failed to get admin token" + exit 1 +fi + +echo "Fetching First Broker Login flow executions..." +EXECUTIONS=$(curl -sf "$KEYCLOAK_URL/admin/realms/$REALM/authentication/flows/first%20broker%20login/executions" \ + -H "Authorization: Bearer $TOKEN") + +# Extract the Review Profile execution id and current requirement +REVIEW_ID=$(echo "$EXECUTIONS" | grep -o '"id":"[^"]*","requirement":"[^"]*","displayName":"Review Profile[^}]*' | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4) + +if [ -z "$REVIEW_ID" ]; then + echo "Could not find Review Profile execution — may already be disabled or flow differs." + exit 0 +fi + +echo "Disabling Review Profile (id: $REVIEW_ID)..." +curl -sf -X PUT "$KEYCLOAK_URL/admin/realms/$REALM/authentication/flows/first%20broker%20login/executions" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d "{\"id\":\"$REVIEW_ID\",\"requirement\":\"DISABLED\"}" + +echo "" +echo "Done. Review Profile is now disabled — SSO users will be created silently." diff --git a/server/scripts/register-dfn-aai.sh b/server/scripts/register-dfn-aai.sh new file mode 100755 index 0000000..b6db94d --- /dev/null +++ b/server/scripts/register-dfn-aai.sh @@ -0,0 +1,73 @@ +#!/bin/bash +# Outputs the Keycloak SAML SP metadata required for DFN-AAI registration. +# +# Usage (run from the server/ directory): +# KEYCLOAK_URL=https://your-production-keycloak.example.com ./scripts/register-dfn-aai.sh +# +# Or for local testing: +# ./scripts/register-dfn-aai.sh +# +# The generated SP metadata XML must be submitted to DFN-AAI via: +# https://www.aai.dfn.de/en/participants/sp-registration/ +# +# After DFN-AAI approves the registration and distributes the SP metadata to +# member universities, users from those universities will be able to log in. +# +# IMPORTANT: The Keycloak instance must be publicly reachable before registering. +# The ACS (Assertion Consumer Service) URL in the metadata will be based on +# the Keycloak URL — localhost URLs will not work in production. + +set -e + +KEYCLOAK_URL="${KEYCLOAK_URL:-http://localhost:8081}" +REALM="memo" +METADATA_URL="$KEYCLOAK_URL/realms/$REALM/protocol/saml/descriptor" + +echo "Fetching SAML SP metadata from:" +echo " $METADATA_URL" +echo "" + +if command -v curl &>/dev/null; then + curl -sf "$METADATA_URL" | xmllint --format - 2>/dev/null || curl -sf "$METADATA_URL" +elif command -v wget &>/dev/null; then + wget -qO- "$METADATA_URL" +else + echo "ERROR: curl or wget is required to fetch metadata." + exit 1 +fi + +echo "" +echo "--------------------------------------------------------------------" +echo "DFN-AAI SP Registration Steps:" +echo "" +echo "1. Deploy Keycloak to a publicly accessible server (e.g. https://auth.memo.example.com)" +echo "" +echo "2. Re-run this script with your production URL:" +echo " KEYCLOAK_URL=https://auth.memo.example.com ./scripts/register-dfn-aai.sh" +echo "" +echo "3. Save the XML output to a file: memo-sp-metadata.xml" +echo "" +echo "4. Register at https://www.aai.dfn.de/en/participants/sp-registration/" +echo " - Sign the SP participation agreement" +echo " - Upload memo-sp-metadata.xml via the Metadata Administration Tool" +echo " - Provide a security contact email" +echo "" +echo "5. After DFN approval (typically a few business days), update Keycloak:" +echo " a. Open the Keycloak Admin UI for each university IdP" +echo " b. Under Identity Providers → [university] → import the IdP metadata:" +echo " - TUM: https://tumidp.lrz.de/idp/shibboleth" +echo " - LMU: https://idp.lrz.de/idp/shibboleth" +echo " - RWTH: https://login.rz.rwth-aachen.de/shibboleth" +echo " - KIT: https://idp.scc.kit.edu/idp/shibboleth" +echo " - TU Berlin: https://ephraim.tu-berlin.de/shibboleth" +echo " - TU Dresden:https://idp.tu-dresden.de/idp/shibboleth" +echo " - (and so on for other universities)" +echo " c. Enable 'Validate Signatures' for each IdP once certs are imported" +echo "" +echo "6. Add more DFN-AAI universities by looking up their entityID at:" +echo " https://tools.aai.dfn.de/entities/" +echo " Then add them to memo-realm.json and LoginPage.tsx" +echo "" +echo "Full DFN-AAI documentation:" +echo " https://doku.tid.dfn.de/en:production" +echo "--------------------------------------------------------------------" diff --git a/server/src/main/java/de/tum/cit/memo/controller/AuthController.java b/server/src/main/java/de/tum/cit/memo/controller/AuthController.java new file mode 100644 index 0000000..c41cdd0 --- /dev/null +++ b/server/src/main/java/de/tum/cit/memo/controller/AuthController.java @@ -0,0 +1,38 @@ +package de.tum.cit.memo.controller; + +import de.tum.cit.memo.entity.User; +import de.tum.cit.memo.enums.UserRole; +import de.tum.cit.memo.service.UserService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +@RestController +@RequestMapping("/api/auth") +@RequiredArgsConstructor +@Tag(name = "Auth", description = "Authentication and user sync") +@SecurityRequirement(name = "bearer-jwt") +public class AuthController { + + private final UserService userService; + + @GetMapping("/me") + @Operation(summary = "Get or create current authenticated user") + public ResponseEntity> me(@AuthenticationPrincipal Jwt jwt) { + String sub = jwt.getSubject(); + User user = userService.findOrCreateBySubject(sub); + return ResponseEntity.ok(Map.of( + "id", user.getId(), + "role", user.getRole().name() + )); + } +} diff --git a/server/src/main/java/de/tum/cit/memo/entity/User.java b/server/src/main/java/de/tum/cit/memo/entity/User.java index 00f1d7c..fa98c3f 100644 --- a/server/src/main/java/de/tum/cit/memo/entity/User.java +++ b/server/src/main/java/de/tum/cit/memo/entity/User.java @@ -7,8 +7,6 @@ import jakarta.persistence.Enumerated; import jakarta.persistence.Id; import jakarta.persistence.Table; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -26,16 +24,13 @@ public class User { @Id - @Column(length = 30) + @Column(length = 36) private String id; - @NotBlank - @Column(nullable = false) + @Column(nullable = true) private String name; - @NotBlank - @Email - @Column(nullable = false, unique = true) + @Column(nullable = true, unique = true) private String email; @Enumerated(EnumType.STRING) diff --git a/server/src/main/java/de/tum/cit/memo/security/SecurityConfig.java b/server/src/main/java/de/tum/cit/memo/security/SecurityConfig.java index a4a7cf6..5b22e75 100644 --- a/server/src/main/java/de/tum/cit/memo/security/SecurityConfig.java +++ b/server/src/main/java/de/tum/cit/memo/security/SecurityConfig.java @@ -3,6 +3,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; @@ -26,8 +27,11 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(auth -> auth .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() - .anyRequest().permitAll() - ); + .requestMatchers("/swagger-ui/**", "/swagger-ui.html", "/api-docs/**").permitAll() + .requestMatchers("/actuator/health").permitAll() + .anyRequest().authenticated() + ) + .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())); return http.build(); } diff --git a/server/src/main/java/de/tum/cit/memo/service/UserService.java b/server/src/main/java/de/tum/cit/memo/service/UserService.java index 570b976..99309ae 100644 --- a/server/src/main/java/de/tum/cit/memo/service/UserService.java +++ b/server/src/main/java/de/tum/cit/memo/service/UserService.java @@ -78,4 +78,12 @@ public void deleteUser(String id) { } userRepository.deleteById(id); } + + @Transactional + public User findOrCreateBySubject(String sub) { + return userRepository.findById(sub) + .orElseGet(() -> userRepository.save( + User.builder().id(sub).role(UserRole.USER).build() + )); + } } diff --git a/server/src/main/resources/application.yml b/server/src/main/resources/application.yml index 791d75f..02ae328 100644 --- a/server/src/main/resources/application.yml +++ b/server/src/main/resources/application.yml @@ -2,6 +2,13 @@ spring: application: name: memo-api + security: + oauth2: + resourceserver: + jwt: + issuer-uri: ${KEYCLOAK_ISSUER_URI:http://localhost:8081/realms/memo} + jwk-set-uri: ${KEYCLOAK_JWK_SET_URI:http://localhost:8081/realms/memo/protocol/openid-connect/certs} + datasource: url: jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5432}/${DB_NAME:memo} username: ${DB_USER:postgres} diff --git a/server/src/main/resources/db/migration/V5__update_users_for_keycloak_auth.sql b/server/src/main/resources/db/migration/V5__update_users_for_keycloak_auth.sql new file mode 100644 index 0000000..6b36522 --- /dev/null +++ b/server/src/main/resources/db/migration/V5__update_users_for_keycloak_auth.sql @@ -0,0 +1,10 @@ +-- Make name and email nullable (Keycloak/Shibboleth users have no personal data stored) +ALTER TABLE users ALTER COLUMN name DROP NOT NULL; +ALTER TABLE users ALTER COLUMN email DROP NOT NULL; + +-- Extend id column to hold Keycloak UUID (36 chars) +ALTER TABLE users ALTER COLUMN id TYPE VARCHAR(36); + +-- Make the unique constraint on email deferrable to allow null values +ALTER TABLE users DROP CONSTRAINT IF EXISTS users_email_key; +ALTER TABLE users ADD CONSTRAINT users_email_key UNIQUE (email) DEFERRABLE INITIALLY DEFERRED; diff --git a/src/App.tsx b/src/App.tsx index 1c7a3ac..63388ed 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,6 +7,9 @@ import { HomePage } from './pages/HomePage'; import { AboutPage } from './pages/AboutPage'; import { SessionPage } from './pages/SessionPage'; import { OnboardingPage } from './pages/OnboardingPage'; +import { LoginPage } from './pages/LoginPage'; +import { ProtectedRoute } from './components/ProtectedRoute'; +import { AuthProvider } from './contexts/AuthContext'; export function App() { const [queryClient] = useState( @@ -23,16 +26,21 @@ export function App() { return ( - - - }> - } /> - } /> - } /> - } /> - - - + + + + } /> + }> + } /> + } /> + }> + } /> + } /> + + + + + ); } diff --git a/src/components/ProtectedRoute.tsx b/src/components/ProtectedRoute.tsx new file mode 100644 index 0000000..a62f8ac --- /dev/null +++ b/src/components/ProtectedRoute.tsx @@ -0,0 +1,20 @@ +import { Navigate, Outlet } from 'react-router-dom'; +import { useAuth } from '../contexts/AuthContext'; + +export function ProtectedRoute() { + const { isAuthenticated, isLoading } = useAuth(); + + if (isLoading) { + return ( +
+

Loading…

+
+ ); + } + + if (!isAuthenticated) { + return ; + } + + return ; +} diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx index 6126062..a00faea 100644 --- a/src/components/navbar.tsx +++ b/src/components/navbar.tsx @@ -2,6 +2,7 @@ import { Link, useLocation } from 'react-router-dom'; import { useTheme } from './use-theme'; import { useEffect, useState } from 'react'; import { cn } from '@/lib/utils'; +import { useAuth } from '../contexts/AuthContext'; const navItems = [ { href: '/', label: 'Home' }, @@ -14,6 +15,7 @@ export function Navbar() { const location = useLocation(); const pathname = location.pathname; const { theme, setTheme } = useTheme(); + const { isAuthenticated, login, logout } = useAuth(); const [mounted, setMounted] = useState(false); const [scrolled, setScrolled] = useState(false); const activeIndex = navItems.findIndex(item => item.href === pathname); @@ -145,14 +147,24 @@ export function Navbar() { )} - {/* Login button */} - - Start Contributing - + {/* Auth button */} + {isAuthenticated ? ( + + ) : ( + + )}
diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx new file mode 100644 index 0000000..68895b8 --- /dev/null +++ b/src/contexts/AuthContext.tsx @@ -0,0 +1,101 @@ +'use client'; + +import { + createContext, + useContext, + useEffect, + useRef, + useState, + type ReactNode, +} from 'react'; +import { keycloak, initKeycloak } from '../lib/auth/keycloak'; + +interface AuthContextValue { + isAuthenticated: boolean; + isLoading: boolean; + userId: string | null; + role: string | null; + login: (idpHint?: string) => void; + logout: () => void; +} + +const AuthContext = createContext(null); + +export function AuthProvider({ children }: { children: ReactNode }) { + const [isAuthenticated, setIsAuthenticated] = useState(false); + const [isLoading, setIsLoading] = useState(true); + const [userId, setUserId] = useState(null); + const [role, setRole] = useState(null); + const initialised = useRef(false); + + useEffect(() => { + if (initialised.current) return; + initialised.current = true; + + initKeycloak() + .then(async authenticated => { + setIsAuthenticated(authenticated); + if (authenticated) { + await syncUser(); + } + }) + .catch(console.error) + .finally(() => setIsLoading(false)); + + keycloak.onTokenExpired = () => { + keycloak + .updateToken(60) + .catch(() => { + setIsAuthenticated(false); + setUserId(null); + setRole(null); + }); + }; + }, []); + + async function syncUser() { + try { + const res = await fetch( + (import.meta.env.VITE_API_URL || 'http://localhost:8080') + + '/api/auth/me', + { + headers: { + Authorization: `Bearer ${keycloak.token}`, + }, + } + ); + if (res.ok) { + const data = await res.json(); + setUserId(data.id); + setRole(data.role); + } + } catch { + // non-critical: user is still authenticated, just not synced + } + } + + function login(idpHint?: string) { + keycloak.login({ + ...(idpHint ? { idpHint } : {}), + redirectUri: window.location.origin, + }); + } + + function logout() { + keycloak.logout({ redirectUri: window.location.origin + '/login' }); + } + + return ( + + {children} + + ); +} + +export function useAuth(): AuthContextValue { + const ctx = useContext(AuthContext); + if (!ctx) throw new Error('useAuth must be used inside AuthProvider'); + return ctx; +} diff --git a/src/data/universities.ts b/src/data/universities.ts new file mode 100644 index 0000000..374209c --- /dev/null +++ b/src/data/universities.ts @@ -0,0 +1,154 @@ +export interface University { + id: string; + name: string; +} + +export const UNIVERSITIES: University[] = [ + // --- Major Technical Universities --- + { id: 'tum', name: 'Technische Universität München' }, + { id: 'lmu', name: 'Ludwig-Maximilians-Universität München' }, + { id: 'rwth-aachen', name: 'RWTH Aachen University' }, + { id: 'kit', name: 'Karlsruher Institut für Technologie (KIT)' }, + { id: 'tu-berlin', name: 'Technische Universität Berlin' }, + { id: 'tu-dresden', name: 'Technische Universität Dresden' }, + { id: 'tu-darmstadt', name: 'Technische Universität Darmstadt' }, + { id: 'tu-chemnitz', name: 'TU Chemnitz' }, + { id: 'btu-cottbus', name: 'BTU Cottbus - Senftenberg' }, + // --- Major Universities --- + { id: 'fu-berlin', name: 'Freie Universität Berlin' }, + { id: 'hu-berlin', name: 'Humboldt-Universität zu Berlin' }, + { id: 'uni-hamburg', name: 'Universität Hamburg' }, + { id: 'uni-freiburg', name: 'Albert-Ludwigs-Universität Freiburg' }, + { id: 'luh-hannover', name: 'Leibniz Universität Hannover' }, + { id: 'uni-koeln', name: 'Universität zu Köln' }, + { id: 'uni-frankfurt', name: 'Goethe-Universität Frankfurt' }, + { id: 'uni-stuttgart', name: 'Universität Stuttgart' }, + { id: 'uni-heidelberg', name: 'Universität Heidelberg' }, + { id: 'uni-tuebingen', name: 'Universität Tübingen' }, + { id: 'uni-konstanz', name: 'Universität Konstanz' }, + { id: 'uni-passau', name: 'Universität Passau' }, + { id: 'uni-rostock', name: 'Universität Rostock' }, + { id: 'uni-bremen', name: 'Universität Bremen' }, + { id: 'uni-wuerzburg', name: 'Julius-Maximilians-Universität Würzburg' }, + { id: 'uni-bamberg', name: 'Otto-Friedrich-Universität Bamberg' }, + { id: 'uni-kiel', name: 'Christian-Albrechts-Universität zu Kiel' }, + { id: 'uni-luebeck', name: 'Universität zu Lübeck' }, + { id: 'uni-erfurt', name: 'Universität Erfurt' }, + { id: 'uni-kassel', name: 'Universität Kassel' }, + { id: 'uni-koblenz', name: 'Universität Koblenz' }, + { id: 'uni-giessen', name: 'Justus-Liebig-Universität Gießen' }, + { id: 'uni-duisburg-essen', name: 'Universität Duisburg-Essen' }, + { id: 'leuphana', name: 'Leuphana Universität Lüneburg' }, + { id: 'bauhaus-weimar', name: 'Bauhaus-Universität Weimar' }, + { id: 'zeppelin-uni', name: 'Zeppelin Universität' }, + { id: 'ipu-berlin', name: 'Internationale Psychoanalytische Universität Berlin' }, + // --- Fachhochschulen / Hochschulen --- + { id: 'frankfurt-uas', name: 'Frankfurt University of Applied Sciences' }, + { id: 'haw-hamburg', name: 'Hochschule für Angewandte Wissenschaften Hamburg' }, + { id: 'bht-berlin', name: 'Berliner Hochschule für Technik' }, + { id: 'ostfalia', name: 'Ostfalia Hochschule' }, + { id: 'hs-harz', name: 'Hochschule Harz' }, + { id: 'hs-rheinmain', name: 'Hochschule RheinMain' }, + { id: 'hs-neubrandenburg', name: 'Hochschule Neubrandenburg' }, + { id: 'hs-nachhaltige-eberswalde', name: 'Hochschule für Nachhaltige Entwicklung Eberswalde' }, + { id: 'hcu-hamburg', name: 'HafenCity Universität Hamburg' }, + { id: 'hs-aalen', name: 'Hochschule Aalen' }, + { id: 'th-brandenburg', name: 'Technische Hochschule Brandenburg' }, + { id: 'hs-geisenheim', name: 'Hochschule Geisenheim University' }, + { id: 'hs-landshut', name: 'Hochschule Landshut' }, + { id: 'hs-hamm-lippstadt', name: 'Hochschule Hamm-Lippstadt' }, + { id: 'hs-bonn-rhein-sieg', name: 'Hochschule Bonn-Rhein-Sieg' }, + { id: 'th-luebeck', name: 'Technische Hochschule Lübeck' }, + { id: 'th-ulm', name: 'Technische Hochschule Ulm' }, + { id: 'th-mittelhessen', name: 'Technische Hochschule Mittelhessen' }, + { id: 'hs-trier', name: 'Hochschule Trier' }, + { id: 'hs-furtwangen', name: 'Hochschule Furtwangen' }, + { id: 'hs-bremerhaven', name: 'Hochschule Bremerhaven' }, + { id: 'hs-stralsund', name: 'Hochschule Stralsund' }, + { id: 'hs-anhalt', name: 'Hochschule Anhalt' }, + { id: 'hs-weihenstephan', name: 'Hochschule Weihenstephan-Triesdorf' }, + { id: 'hs-zittau-goerlitz', name: 'Hochschule Zittau/Görlitz' }, + { id: 'thga-bochum', name: 'THGA Bochum' }, + { id: 'dhbw-mannheim', name: 'DHBW Mannheim' }, + { id: 'dhbw-mosbach', name: 'DHBW Mosbach' }, + { id: 'ba-sachsen', name: 'Berufsakademie Sachsen' }, + { id: 'hs-kehl', name: 'Hochschule für öffentliche Verwaltung Kehl' }, + { id: 'dhpol', name: 'Deutsche Hochschule der Polizei' }, + { id: 'helmut-schmidt-uni', name: 'Helmut-Schmidt-Universität Hamburg' }, + // --- Pädagogische Hochschulen --- + { id: 'ph-heidelberg', name: 'Pädagogische Hochschule Heidelberg' }, + { id: 'ph-ludwigsburg', name: 'Pädagogische Hochschule Ludwigsburg' }, + { id: 'ph-schwaebisch-gmuend', name: 'PH Schwäbisch Gmünd' }, + // --- Kunsthochschulen / Musikhochschulen --- + { id: 'hfmt-hamburg', name: 'Hochschule für Musik und Theater Hamburg' }, + { id: 'hmt-rostock', name: 'Hochschule für Musik und Theater Rostock' }, + { id: 'hfmdk-frankfurt', name: 'Hochschule für Musik und Darstellende Kunst Frankfurt' }, + { id: 'muho-mannheim', name: 'Staatliche Hochschule für Musik und Darstellende Kunst Mannheim' }, + { id: 'hfmt-koeln', name: 'Hochschule für Musik und Tanz Köln' }, + { id: 'mh-trossingen', name: 'Staatliche Hochschule für Musik Trossingen' }, + { id: 'rsh-duesseldorf', name: 'Robert Schumann Hochschule Düsseldorf' }, + { id: 'hbk-braunschweig', name: 'Hochschule für Bildende Künste Braunschweig' }, + { id: 'hfg-offenbach', name: 'Hochschule für Gestaltung Offenbach' }, + { id: 'hfg-schwaebisch-gmuend', name: 'HfG Hochschule für Gestaltung Schwäbisch Gmünd' }, + { id: 'khm-koeln', name: 'Kunsthochschule für Medien Köln' }, + { id: 'palucca-dresden', name: 'Palucca Hochschule für Tanz Dresden' }, + // --- Private Universities --- + { id: 'hertie-school', name: 'Hertie School of Governance' }, + { id: 'esmt-berlin', name: 'ESMT Berlin' }, + { id: 'ism-management', name: 'ISM International School of Management' }, + { id: 'hfph-muenchen', name: 'Hochschule für Philosophie München' }, + { id: 'khsb-berlin', name: 'Katholische Hochschule für Sozialwesen Berlin' }, + { id: 'katho-nrw', name: 'Katholische Hochschule Nordrhein-Westfalen' }, + { id: 'evh-bochum', name: 'Evangelische Hochschule Rheinland-Westfalen-Lippe' }, + { id: 'bib-international', name: 'bib International College' }, + { id: 'mhb-fontane', name: 'Medizinische Hochschule Brandenburg' }, + { id: 'msh-private', name: 'MSH Medical School Hamburg / BSP Business School Berlin' }, + { id: 'cispa', name: 'CISPA – Helmholtz-Zentrum für Informationssicherheit' }, + // --- Medical / Clinical --- + { id: 'charite', name: 'Charité – Universitätsmedizin Berlin' }, + { id: 'uk-augsburg', name: 'Universitätsklinikum Augsburg' }, + { id: 'uk-dresden', name: 'Universitätsklinikum Carl Gustav Carus Dresden' }, + // --- Research Institutes --- + { id: 'awi', name: 'Alfred-Wegener-Institut (AWI)' }, + { id: 'geomar', name: 'GEOMAR Helmholtz-Zentrum für Ozeanforschung Kiel' }, + { id: 'pik', name: 'Potsdam-Institut für Klimafolgenforschung' }, + { id: 'dkrz', name: 'Deutsches Klimarechenzentrum (DKRZ)' }, + { id: 'dipf', name: 'DIPF – Leibniz-Institut für Bildungsforschung' }, + { id: 'iwm-tuebingen', name: 'Leibniz-Institut für Wissensmedien' }, + { id: 'iamo', name: 'Leibniz-Institut für Agrarentwicklung (IAMO)' }, + { id: 'iwt-bremen', name: 'Leibniz-Institut für Werkstofforientierte Technologien (IWT)' }, + { id: 'ifw-dresden', name: 'IFW Dresden' }, + { id: 'inp-greifswald', name: 'Leibniz-Institut für Plasmaforschung (INP Greifswald)' }, + { id: 'likat-rostock', name: 'Leibniz-Institut für Katalyse (LIKAT)' }, + { id: 'fbn-dummerstorf', name: 'Forschungsinstitut für Nutztierbiologie (FBN)' }, + { id: 'mdc-berlin', name: 'Max-Delbrück-Centrum für Molekulare Medizin' }, + { id: 'mpg-general', name: 'Max-Planck-Gesellschaft (Generalverwaltung)' }, + { id: 'mpcdf', name: 'Max Planck Computing and Data Facility' }, + { id: 'mpi-chemie', name: 'Max-Planck-Institut für Chemie' }, + { id: 'mpi-biochemie', name: 'Max-Planck-Institut für Biochemie' }, + { id: 'mpi-chem-oekologie', name: 'Max-Planck-Institut für Chemische Ökologie' }, + { id: 'mpi-intelligente-systeme', name: 'Max-Planck-Institut für Intelligente Systeme' }, + { id: 'mpi-plasmaphysik', name: 'Max-Planck-Institut für Plasmaphysik (IPP)' }, + { id: 'mpi-quantenoptik', name: 'Max-Planck-Institut für Quantenoptik' }, + { id: 'mpi-kohlenforschung', name: 'Max-Planck-Institut für Kohlenforschung' }, + { id: 'mpg-gwdg', name: 'Max-Planck-Institute (via GWDG)' }, + { id: 'fbh-berlin', name: 'Ferdinand-Braun-Institut, Leibniz-Institut für Höchstfrequenztechnik' }, + { id: 'hits-heidelberg', name: 'HITS gGmbH (Heidelberg Institute for Theoretical Studies)' }, + { id: 'eso', name: 'ESO – European Southern Observatory' }, + { id: 'gwdg', name: 'GWDG Göttingen' }, + { id: 'leibniz-gemeinschaft', name: 'Leibniz-Gemeinschaft' }, + { id: 'lrz-badw', name: 'Leibniz-Rechenzentrum / Bayerische Akademie der Wissenschaften' }, + // --- Libraries --- + { id: 'bsz-bw', name: 'Bibliotheksservice-Zentrum Baden-Württemberg (BSZ)' }, + { id: 'hbz-nrw', name: 'Hochschulbibliothekszentrum NRW (hbz)' }, + { id: 'slub-dresden', name: 'SLUB Dresden' }, + { id: 'bsb-muenchen', name: 'Bayerische Staatsbibliothek München' }, + { id: 'blb-karlsruhe', name: 'Badische Landesbibliothek' }, + // --- Virtual / Other --- + { id: 'vhb', name: 'Virtuelle Hochschule Bayern (vhb)' }, + { id: 'daad', name: 'DAAD' }, +]; + +export const DEV_UNIVERSITIES: University[] = [ + { id: 'test-university', name: 'Test University (Dev only)' }, +]; diff --git a/src/index.css b/src/index.css index fb23c40..bd85b7e 100644 --- a/src/index.css +++ b/src/index.css @@ -29,10 +29,18 @@ --color-ring: var(--ring); --color-border: var(--border); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); --color-muted: var(--muted); - --color-primary: var(--primary); + --color-muted-foreground: var(--muted-foreground); --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); --color-yinmn-blue: oklch(0.38 0.08 245); --color-air-superiority-blue: oklch(0.62 0.05 235); --color-uranian-blue: oklch(0.82 0.04 235); diff --git a/src/lib/api/client.ts b/src/lib/api/client.ts index e610c8a..238abca 100644 --- a/src/lib/api/client.ts +++ b/src/lib/api/client.ts @@ -1,4 +1,5 @@ import axios from 'axios'; +import { keycloak } from '../auth/keycloak'; export const apiClient = axios.create({ baseURL: import.meta.env.VITE_API_URL || 'http://localhost:8080', @@ -8,6 +9,14 @@ export const apiClient = axios.create({ timeout: 10000, }); +apiClient.interceptors.request.use(async config => { + if (keycloak.authenticated) { + await keycloak.updateToken(30).catch(() => {}); + config.headers.Authorization = `Bearer ${keycloak.token}`; + } + return config; +}); + apiClient.interceptors.response.use( response => response, error => { diff --git a/src/lib/api/session-helpers.ts b/src/lib/api/session-helpers.ts index 8b4bdf6..8cd39bf 100644 --- a/src/lib/api/session-helpers.ts +++ b/src/lib/api/session-helpers.ts @@ -2,10 +2,12 @@ * Session API helpers for the session page to use with the Spring Boot API */ +import { apiClient } from './client'; import { competenciesApi } from './competencies'; import { competencyRelationshipsApi } from './competency-relationships'; import { competencyResourceLinksApi } from './competency-resource-links'; import { learningResourcesApi } from './learning-resources'; +import { keycloak } from '../auth/keycloak'; import type { Competency, LearningResource, @@ -13,17 +15,26 @@ import type { CompetencyResourceLink, } from './types'; -const GUEST_USER_ID = 'guest'; - export async function getOrCreateDemoUserAction(): Promise<{ success: boolean; user?: { id: string; name: string }; error?: string; }> { - return { - success: true, - user: { id: GUEST_USER_ID, name: 'Guest User' }, - }; + try { + const response = await apiClient.get<{ id: string; role: string }>( + '/api/auth/me' + ); + return { + success: true, + user: { id: response.data.id, name: '' }, + }; + } catch (error) { + return { + success: false, + error: + error instanceof Error ? error.message : 'Failed to get current user', + }; + } } export async function getRandomCompetenciesAction(count: number): Promise<{ @@ -87,7 +98,7 @@ export async function createCompetencyRelationshipAction( relationshipType: relationshipType as 'ASSUMES' | 'EXTENDS' | 'MATCHES', originId, destinationId, - userId: GUEST_USER_ID, + userId: keycloak.tokenParsed?.sub ?? '', }); return { success: true, relationship }; } catch (error) { @@ -133,7 +144,7 @@ export async function createCompetencyResourceLinkAction( const link = await competencyResourceLinksApi.create({ competencyId, resourceId, - userId: GUEST_USER_ID, + userId: keycloak.tokenParsed?.sub ?? '', matchType: matchType as | 'UNRELATED' | 'WEAK' diff --git a/src/lib/auth/keycloak.ts b/src/lib/auth/keycloak.ts new file mode 100644 index 0000000..f047c2e --- /dev/null +++ b/src/lib/auth/keycloak.ts @@ -0,0 +1,17 @@ +import Keycloak from 'keycloak-js'; + +export const keycloak = new Keycloak({ + url: import.meta.env.VITE_KEYCLOAK_URL || 'http://localhost:8081', + realm: import.meta.env.VITE_KEYCLOAK_REALM || 'memo', + clientId: import.meta.env.VITE_KEYCLOAK_CLIENT_ID || 'memo-client', +}); + +export async function initKeycloak(): Promise { + return keycloak.init({ + onLoad: 'check-sso', + pkceMethod: 'S256', + silentCheckSsoRedirectUri: + window.location.origin + '/silent-check-sso.html', + checkLoginIframe: false, + }); +} diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx new file mode 100644 index 0000000..c6a1eb4 --- /dev/null +++ b/src/pages/LoginPage.tsx @@ -0,0 +1,72 @@ +import { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useAuth } from '../contexts/AuthContext'; +import { Button } from '../components/ui/button'; +import { GraduationCap } from 'lucide-react'; +import { UNIVERSITIES, DEV_UNIVERSITIES } from '../data/universities'; + +const visibleUniversities = + import.meta.env.DEV || import.meta.env.VITE_SHOW_TEST_IDP === 'true' + ? [...UNIVERSITIES, ...DEV_UNIVERSITIES] + : UNIVERSITIES; + +export function LoginPage() { + const { isAuthenticated, isLoading, login } = useAuth(); + const navigate = useNavigate(); + const [selectedUniversity, setSelectedUniversity] = useState(''); + + useEffect(() => { + if (!isLoading && isAuthenticated) { + navigate('/', { replace: true }); + } + }, [isAuthenticated, isLoading, navigate]); + + if (isLoading) { + return ( +
+

Loading…

+
+ ); + } + + return ( +
+
+ +

Sign in to Memo

+

+ Authentication requires a university account +

+
+ +
+
+ + +
+ + +
+
+ ); +} From 513e8c460523d92033710199d9be6c9de314ea89 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 3 Mar 2026 00:35:43 +0100 Subject: [PATCH 25/57] Fix skip feature, update package-lock.json --- package-lock.json | 242 +++++++++--------- package.json | 1 + .../memo/controller/SchedulingController.java | 5 +- .../CompetencyRelationshipRepository.java | 92 +++---- .../CompetencyRelationshipService.java | 3 +- .../cit/memo/service/SchedulingService.java | 32 ++- .../onboarding/OnboardingPractice.tsx | 61 +---- src/components/ui/select.tsx | 2 +- src/lib/api/scheduling.ts | 11 +- src/lib/api/session-helpers.ts | 7 +- src/pages/SessionPage.tsx | 57 ++++- 11 files changed, 254 insertions(+), 259 deletions(-) diff --git a/package-lock.json b/package-lock.json index 32d17ca..8fd6055 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@radix-ui/react-label": "2.1.8", "@radix-ui/react-radio-group": "1.3.8", + "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-slot": "1.2.4", "@tanstack/react-query": "^5.90.16", "axios": "^1.13.2", @@ -4166,9 +4167,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz", - "integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", "cpu": [ "arm" ], @@ -4180,9 +4181,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz", - "integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", "cpu": [ "arm64" ], @@ -4194,9 +4195,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz", - "integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", "cpu": [ "arm64" ], @@ -4208,9 +4209,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz", - "integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", "cpu": [ "x64" ], @@ -4222,9 +4223,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz", - "integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", "cpu": [ "arm64" ], @@ -4236,9 +4237,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz", - "integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", "cpu": [ "x64" ], @@ -4250,9 +4251,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz", - "integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", "cpu": [ "arm" ], @@ -4264,9 +4265,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz", - "integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", "cpu": [ "arm" ], @@ -4278,9 +4279,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz", - "integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", "cpu": [ "arm64" ], @@ -4292,9 +4293,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz", - "integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", "cpu": [ "arm64" ], @@ -4306,9 +4307,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz", - "integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", "cpu": [ "loong64" ], @@ -4320,9 +4321,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz", - "integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", "cpu": [ "loong64" ], @@ -4334,9 +4335,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz", - "integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", "cpu": [ "ppc64" ], @@ -4348,9 +4349,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz", - "integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", "cpu": [ "ppc64" ], @@ -4362,9 +4363,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz", - "integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", "cpu": [ "riscv64" ], @@ -4376,9 +4377,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz", - "integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", "cpu": [ "riscv64" ], @@ -4390,9 +4391,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz", - "integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", "cpu": [ "s390x" ], @@ -4404,9 +4405,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz", - "integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", "cpu": [ "x64" ], @@ -4418,9 +4419,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz", - "integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", "cpu": [ "x64" ], @@ -4432,9 +4433,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz", - "integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", "cpu": [ "x64" ], @@ -4446,9 +4447,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz", - "integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", "cpu": [ "arm64" ], @@ -4460,9 +4461,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz", - "integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", "cpu": [ "arm64" ], @@ -4474,9 +4475,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz", - "integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", "cpu": [ "ia32" ], @@ -4488,9 +4489,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz", - "integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", "cpu": [ "x64" ], @@ -4502,9 +4503,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz", - "integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", "cpu": [ "x64" ], @@ -5089,37 +5090,24 @@ "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" + "balanced-match": "^1.0.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.6.tgz", - "integrity": "sha512-kQAVowdR33euIqeA0+VZTDqU+qo1IeVY+hrKYtZMio3Pg0P0vuh/kwRylLUddJhB6pf3q/botcOvRtx4IN1wqQ==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -6757,9 +6745,9 @@ } }, "node_modules/minimatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.3.tgz", - "integrity": "sha512-M2GCs7Vk83NxkUyQV1bkABc4yxgz9kILhHImZiBPAZ9ybuvCb0/H7lEl5XvIg3g+9d4eNotkZA5IWwYl0tibaA==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -7314,9 +7302,9 @@ } }, "node_modules/rollup": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz", - "integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "dev": true, "license": "MIT", "dependencies": { @@ -7330,31 +7318,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.55.1", - "@rollup/rollup-android-arm64": "4.55.1", - "@rollup/rollup-darwin-arm64": "4.55.1", - "@rollup/rollup-darwin-x64": "4.55.1", - "@rollup/rollup-freebsd-arm64": "4.55.1", - "@rollup/rollup-freebsd-x64": "4.55.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.55.1", - "@rollup/rollup-linux-arm-musleabihf": "4.55.1", - "@rollup/rollup-linux-arm64-gnu": "4.55.1", - "@rollup/rollup-linux-arm64-musl": "4.55.1", - "@rollup/rollup-linux-loong64-gnu": "4.55.1", - "@rollup/rollup-linux-loong64-musl": "4.55.1", - "@rollup/rollup-linux-ppc64-gnu": "4.55.1", - "@rollup/rollup-linux-ppc64-musl": "4.55.1", - "@rollup/rollup-linux-riscv64-gnu": "4.55.1", - "@rollup/rollup-linux-riscv64-musl": "4.55.1", - "@rollup/rollup-linux-s390x-gnu": "4.55.1", - "@rollup/rollup-linux-x64-gnu": "4.55.1", - "@rollup/rollup-linux-x64-musl": "4.55.1", - "@rollup/rollup-openbsd-x64": "4.55.1", - "@rollup/rollup-openharmony-arm64": "4.55.1", - "@rollup/rollup-win32-arm64-msvc": "4.55.1", - "@rollup/rollup-win32-ia32-msvc": "4.55.1", - "@rollup/rollup-win32-x64-gnu": "4.55.1", - "@rollup/rollup-win32-x64-msvc": "4.55.1", + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" } }, diff --git a/package.json b/package.json index f5ad412..73c1964 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "dependencies": { "@radix-ui/react-label": "2.1.8", "@radix-ui/react-radio-group": "1.3.8", + "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-slot": "1.2.4", "@tanstack/react-query": "^5.90.16", "axios": "^1.13.2", diff --git a/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java b/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java index 1f68346..41a6a24 100644 --- a/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java +++ b/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java @@ -27,8 +27,9 @@ public class SchedulingController { @GetMapping("/next-relationship") @Operation(summary = "Get next relationship to vote on", description = "Returns a competency pair for the user to map. Uses coverage (70%) and consensus (30%) pipelines. Returns 204 if no tasks remain.") public ResponseEntity getNextRelationship( - @RequestHeader("X-User-Id") String userId) { - return schedulingService.getNextTask(userId) + @RequestHeader("X-User-Id") String userId, + @org.springframework.web.bind.annotation.RequestParam(required = false) java.util.List skippedIds) { + return schedulingService.getNextTask(userId, skippedIds) .map(ResponseEntity::ok) .orElse(ResponseEntity.noContent().build()); } diff --git a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java index 4daa299..35d776c 100644 --- a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java +++ b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipRepository.java @@ -12,48 +12,52 @@ @Repository public interface CompetencyRelationshipRepository extends JpaRepository { - Optional findByOriginIdAndDestinationId(String originId, String destinationId); - - boolean existsByOriginIdAndDestinationId(String originId, String destinationId); - - /** - * High-entropy relationships the user hasn't voted on yet (for consensus - * pipeline). - */ - @Query(""" - SELECT r FROM CompetencyRelationship r - WHERE r.totalVotes BETWEEN :minVotes AND :maxVotes - AND r.entropy > :minEntropy - AND NOT EXISTS ( - SELECT 1 FROM CompetencyRelationshipVote v - WHERE v.relationshipId = r.id AND v.userId = :userId - ) - ORDER BY r.entropy DESC - """) - List findHighEntropyRelationshipsExcludingUser( - @Param("userId") String userId, - @Param("minVotes") int minVotes, - @Param("maxVotes") int maxVotes, - @Param("minEntropy") double minEntropy, - org.springframework.data.domain.Pageable pageable); - - /** - * Relationships where both origin AND destination are in the given pool of IDs. - */ - @Query("SELECT r FROM CompetencyRelationship r WHERE r.originId IN :ids AND r.destinationId IN :ids") - List findIntraPoolRelationships(@Param("ids") List ids); - - /** - * Relationships the user hasn't voted on (use with PageRequest.of(0, 1) for a - * single result). - */ - @Query(""" - SELECT r FROM CompetencyRelationship r - WHERE NOT EXISTS ( - SELECT 1 FROM CompetencyRelationshipVote v - WHERE v.relationshipId = r.id AND v.userId = :userId - ) - """) - List findUnvotedByUser(@Param("userId") String userId, - org.springframework.data.domain.Pageable pageable); + Optional findByOriginIdAndDestinationId(String originId, String destinationId); + + boolean existsByOriginIdAndDestinationId(String originId, String destinationId); + + /** + * High-entropy relationships the user hasn't voted on yet (for consensus + * pipeline). + */ + @Query(""" + SELECT r FROM CompetencyRelationship r + WHERE r.totalVotes BETWEEN :minVotes AND :maxVotes + AND r.entropy > :minEntropy + AND NOT EXISTS ( + SELECT 1 FROM CompetencyRelationshipVote v + WHERE v.relationshipId = r.id AND v.userId = :userId + ) + AND (:skippedIds IS NULL OR r.id NOT IN :skippedIds) + ORDER BY r.entropy DESC + """) + List findHighEntropyRelationshipsExcludingUser( + @Param("userId") String userId, + @Param("minVotes") int minVotes, + @Param("maxVotes") int maxVotes, + @Param("minEntropy") double minEntropy, + @Param("skippedIds") List skippedIds, + org.springframework.data.domain.Pageable pageable); + + /** + * Relationships where both origin AND destination are in the given pool of IDs. + */ + @Query("SELECT r FROM CompetencyRelationship r WHERE r.originId IN :ids AND r.destinationId IN :ids") + List findIntraPoolRelationships(@Param("ids") List ids); + + /** + * Relationships the user hasn't voted on (use with PageRequest.of(0, 1) for a + * single result). + */ + @Query(""" + SELECT r FROM CompetencyRelationship r + WHERE NOT EXISTS ( + SELECT 1 FROM CompetencyRelationshipVote v + WHERE v.relationshipId = r.id AND v.userId = :userId + ) + AND (:skippedIds IS NULL OR r.id NOT IN :skippedIds) + """) + List findUnvotedByUserAndNotSkipped(@Param("userId") String userId, + @Param("skippedIds") List skippedIds, + org.springframework.data.domain.Pageable pageable); } diff --git a/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java b/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java index 40da523..f097c11 100644 --- a/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java +++ b/server/src/main/java/de/tum/cit/memo/service/CompetencyRelationshipService.java @@ -13,8 +13,7 @@ import java.util.List; /** - * CRUD operations on competency relationships. - * For voting and scheduling, see {@link SchedulingService}. + * CRUD for competency relationships (voting logic lives in SchedulingService). */ @Service @RequiredArgsConstructor diff --git a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java index a347df0..cb1bd68 100644 --- a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java +++ b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java @@ -59,20 +59,23 @@ public class SchedulingService { * Returns empty if the user has voted on every available relationship. */ @Transactional - public Optional getNextTask(String userId) { + public Optional getNextTask(String userId, List skippedIds) { + // Normalize null to empty list + List skipList = skippedIds != null ? skippedIds : List.of(); + if (random.nextDouble() < COVERAGE_WEIGHT) { log.debug("Coverage pipeline for user {}", userId); - return coveragePipeline(userId); + return coveragePipeline(userId, skipList); } log.debug("Consensus pipeline for user {}", userId); - RelationshipTaskResponse task = consensusPipeline(userId); + RelationshipTaskResponse task = consensusPipeline(userId, skipList); if (task != null) { return Optional.of(task); } log.debug("No consensus candidates, falling back to coverage"); - return coveragePipeline(userId); + return coveragePipeline(userId, skipList); } @Transactional @@ -106,7 +109,7 @@ public VoteResponse submitVote(String userId, VoteRequest request) { // --- Pipelines --- - private Optional coveragePipeline(String userId) { + private Optional coveragePipeline(String userId, List skippedIds) { List poolIds = getLowDegreeCompetencyIds(); if (poolIds.size() < 2) { log.debug("Not enough competencies to form pairs"); @@ -117,6 +120,19 @@ private Optional coveragePipeline(String userId) { .flatMap(r -> Stream.of(pairKey(r.getOriginId(), r.getDestinationId()), pairKey(r.getDestinationId(), r.getOriginId()))) .collect(Collectors.toSet()); + // Also add skipped pairs to the set of existing pairs so we don't present them + // again + if (skippedIds != null && !skippedIds.isEmpty()) { + for (String skippedId : skippedIds) { + // skippedIds from frontend are actually encoded as originId:destinationId + // when no true relationshipId exists yet + String[] parts = skippedId.split(":"); + if (parts.length == 2) { + existingPairs.add(pairKey(parts[0], parts[1])); + existingPairs.add(pairKey(parts[1], parts[0])); + } + } + } List pool = new ArrayList<>(poolIds); Collections.shuffle(pool, random); @@ -131,16 +147,16 @@ private Optional coveragePipeline(String userId) { log.debug("Pool fully connected, finding any unvoted relationship"); return relationshipRepository - .findUnvotedByUser(userId, PageRequest.of(0, 1)) + .findUnvotedByUserAndNotSkipped(userId, skippedIds, PageRequest.of(0, 1)) .stream().findFirst() .map(rel -> toTaskResponse(rel, "COVERAGE")); } - private RelationshipTaskResponse consensusPipeline(String userId) { + private RelationshipTaskResponse consensusPipeline(String userId, List skippedIds) { List candidates = relationshipRepository .findHighEntropyRelationshipsExcludingUser( userId, CONSENSUS_MIN_VOTES, CONSENSUS_MAX_VOTES, CONSENSUS_MIN_ENTROPY, - PageRequest.of(0, CONSENSUS_CANDIDATE_LIMIT)); + skippedIds, PageRequest.of(0, CONSENSUS_CANDIDATE_LIMIT)); if (candidates.isEmpty()) { return null; diff --git a/src/components/onboarding/OnboardingPractice.tsx b/src/components/onboarding/OnboardingPractice.tsx index 7c84731..f7db291 100644 --- a/src/components/onboarding/OnboardingPractice.tsx +++ b/src/components/onboarding/OnboardingPractice.tsx @@ -134,16 +134,7 @@ export const OnboardingPractice = forwardRef< const isLastRound = round === TUTORIAL_ROUNDS.length - 1; function handleSelect(value: RelationshipType | null) { - if (!value) { - if (current.guidanceLevel === 'free') { - setSelectedRelation(null); - setWrongAttempt(false); - } - return; - } - - // Once a correct answer is selected in strict/soft mode, it cannot be changed - if (isCorrect && current.guidanceLevel !== 'free') return; + if (!value || isCorrect) return; // Strict mode: only allow the correct answer if (current.guidanceLevel === 'strict' && value !== current.correctAnswer) { @@ -173,47 +164,6 @@ export const OnboardingPractice = forwardRef< } }, [isCorrect, onCorrectStateChange]); - // Effect to handle keyboard shortcuts (1-9) - useEffect(() => { - if (isLastRound && isCorrect) return; // Prevent interaction after finishing - - const handleKeyDown = (e: KeyboardEvent) => { - const target = e.target as HTMLElement; - if ( - target.tagName === 'INPUT' || - target.tagName === 'TEXTAREA' || - target.isContentEditable - ) { - return; - } - - const key = parseInt(e.key); - if (key >= 1 && key <= 4) { - const index = key - 1; - if (index < RELATIONSHIP_TYPES.length) { - const relationType = RELATIONSHIP_TYPES[index].value; - - const isCorrectBtn = relationType === current.correctAnswer; - const isStrictDisabled = - current.guidanceLevel === 'strict' && !isCorrectBtn && !isCorrect; - - if (!isStrictDisabled && !wrongAttempt) { - // Toggle off if already selected, otherwise select - if (selectedRelation === relationType) { - handleSelect(null); - } else { - handleSelect(relationType); - } - } - } - } - }; - - window.addEventListener('keydown', handleKeyDown); - return () => window.removeEventListener('keydown', handleKeyDown); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [current, isCorrect, isLastRound, wrongAttempt]); - function handleNext() { if (isLastRound) { onComplete(); @@ -391,7 +341,7 @@ export const OnboardingPractice = forwardRef< !isCorrect && ( - + )} diff --git a/src/components/ui/select.tsx b/src/components/ui/select.tsx index 7d3305c..4915354 100644 --- a/src/components/ui/select.tsx +++ b/src/components/ui/select.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-react'; -import { Select as SelectPrimitive } from 'radix-ui'; +import * as SelectPrimitive from '@radix-ui/react-select'; import { cn } from '@/lib/utils'; diff --git a/src/lib/api/scheduling.ts b/src/lib/api/scheduling.ts index 1a25eb5..9e3ff4e 100644 --- a/src/lib/api/scheduling.ts +++ b/src/lib/api/scheduling.ts @@ -34,10 +34,17 @@ export const schedulingApi = { * Returns null when there are no more tasks (HTTP 204). */ getNextRelationship: async ( - userId: string + userId: string, + skippedIds?: string[] ): Promise => { + const params = new URLSearchParams(); + if (skippedIds && skippedIds.length > 0) { + skippedIds.forEach(id => params.append('skippedIds', id)); + } + const queryString = params.toString() ? `?${params.toString()}` : ''; + const response = await apiClient.get( - '/api/scheduling/next-relationship', + `/api/scheduling/next-relationship${queryString}`, { headers: { 'X-User-Id': userId } } ); if (response.status === 204) { diff --git a/src/lib/api/session-helpers.ts b/src/lib/api/session-helpers.ts index 3de9ab1..de87347 100644 --- a/src/lib/api/session-helpers.ts +++ b/src/lib/api/session-helpers.ts @@ -58,14 +58,17 @@ export async function getRandomCompetenciesAction(count: number): Promise<{ * Get the next relationship task from the scheduling pipeline. * Returns allDone: true when there are no more pairs to vote on. */ -export async function getNextRelationshipTaskAction(userId: string): Promise<{ +export async function getNextRelationshipTaskAction( + userId: string, + skippedIds?: string[] +): Promise<{ success: boolean; task?: RelationshipTask; allDone?: boolean; error?: string; }> { try { - const task = await schedulingApi.getNextRelationship(userId); + const task = await schedulingApi.getNextRelationship(userId, skippedIds); if (task === null) { return { success: true, allDone: true }; } diff --git a/src/pages/SessionPage.tsx b/src/pages/SessionPage.tsx index 1a0a294..a12cdfb 100644 --- a/src/pages/SessionPage.tsx +++ b/src/pages/SessionPage.tsx @@ -125,7 +125,7 @@ export function SessionPage() { const [isTransitioning, setIsTransitioning] = useState(false); const [swapRotation, setSwapRotation] = useState(0); const [allDone, setAllDone] = useState(false); - const [isSwapped, setIsSwapped] = useState(false); + const [_isSwapped, setIsSwapped] = useState(false); const [currentRelationshipId, setCurrentRelationshipId] = useState< string | null >(null); @@ -175,7 +175,7 @@ export function SessionPage() { }, []); const loadMappingPair = useCallback( - async (isInitialLoad = false) => { + async (isInitialLoad = false, currentSkipId?: string) => { setError(null); if (isInitialLoad) { @@ -195,7 +195,25 @@ export function SessionPage() { return; } - const result = await getNextRelationshipTaskAction(userId); + const skippedIds = history + .filter( + h => + h.type === 'skipped' && + h.mode === 'competency' && + h.competencies && + h.competencies.length === 2 + ) + .map(h => { + if (h.relationshipId) return h.relationshipId; + return `${h.competencies![0]!.id}:${h.competencies![1]!.id}`; + }); + + // Include the current skip ID if provided (handles async state update) + if (currentSkipId && !skippedIds.includes(currentSkipId)) { + skippedIds.push(currentSkipId); + } + + const result = await getNextRelationshipTaskAction(userId, skippedIds); if (!result.success) { setError( @@ -269,7 +287,7 @@ export function SessionPage() { setIsTransitioning(false); }, - [mappingMode, userId] + [mappingMode, userId, history] ); const prevModeRef = useRef(null); @@ -291,7 +309,12 @@ export function SessionPage() { async (type: 'completed' | 'skipped') => { if (type === 'completed') { if (mappingMode === 'competency') { - if ((!currentRelationshipId && !isSwapped) || !relation || !userId) { + if ( + !competencies || + competencies.length < 2 || + !relation || + !userId + ) { setError('Missing required data to submit vote'); return; } @@ -301,13 +324,11 @@ export function SessionPage() { try { const startTime = Date.now(); - const voteOpts = - isSwapped && competencies && competencies.length >= 2 - ? { - originId: competencies[0]!.id, - destinationId: competencies[1]!.id, - } - : { relationshipId: currentRelationshipId! }; + const voteOpts = { + relationshipId: currentRelationshipId ?? undefined, + originId: competencies[0]!.id, + destinationId: competencies[1]!.id, + }; const result = await submitCompetencyVoteAction( userId, relation, @@ -406,19 +427,28 @@ export function SessionPage() { setIsTransitioning(true); await new Promise(resolve => setTimeout(resolve, 300)); + // Build the skip ID before updating history + const currentSkipId = + mappingMode === 'competency' && competencies?.length === 2 + ? (currentRelationshipId ?? + `${competencies[0]!.id}:${competencies[1]!.id}`) + : undefined; + setStats(prev => ({ ...prev, skipped: prev.skipped + 1 })); setHistory(prev => [ ...prev, { type: 'skipped', mode: mappingMode, + relationshipId: currentRelationshipId ?? undefined, competencies: competencies ? [...competencies] : undefined, learningResource: learningResource ?? undefined, }, ]); setRelation(null); try { - await loadMappingPair(); + // Pass the current skip ID directly to avoid stale closure issue + await loadMappingPair(false, currentSkipId); } catch (err) { setError( err instanceof Error @@ -438,7 +468,6 @@ export function SessionPage() { mappingMode, loadMappingPair, currentRelationshipId, - isSwapped, ] ); From 47042eb67873267b2f7f81b59ba4e079a82a164c Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 3 Mar 2026 01:35:36 +0100 Subject: [PATCH 26/57] Add milestone celebration toasts during mapping sessions --- package-lock.json | 676 +++++++++++++++++++---------------- package.json | 1 + src/App.tsx | 2 + src/components/ui/sonner.tsx | 29 ++ src/lib/milestones.ts | 99 +++++ src/pages/DashboardPage.tsx | 92 +---- src/pages/SessionPage.tsx | 67 +++- 7 files changed, 565 insertions(+), 401 deletions(-) create mode 100644 src/components/ui/sonner.tsx create mode 100644 src/lib/milestones.ts diff --git a/package-lock.json b/package-lock.json index 8fd6055..a1f32ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "react": "19.0.0", "react-dom": "19.0.0", "react-router-dom": "^7.1.1", + "sonner": "^2.0.7", "tailwind-merge": "3.3.1", "tailwind-variants": "3.1.1" }, @@ -60,9 +61,9 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", - "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { @@ -75,9 +76,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz", - "integrity": "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, "license": "MIT", "engines": { @@ -85,21 +86,21 @@ } }, "node_modules/@babel/core": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz", - "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/generator": "^7.28.6", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", - "@babel/parser": "^7.28.6", + "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", - "@babel/traverse": "^7.28.6", - "@babel/types": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -116,14 +117,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.6.tgz", - "integrity": "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -246,13 +247,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz", - "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.6" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -309,18 +310,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.6.tgz", - "integrity": "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/generator": "^7.28.6", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.6", + "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", - "@babel/types": "^7.28.6", + "@babel/types": "^7.29.0", "debug": "^4.3.1" }, "engines": { @@ -328,9 +329,9 @@ } }, "node_modules/@babel/types": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz", - "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", "dependencies": { @@ -867,20 +868,20 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", - "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.4.tgz", + "integrity": "sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "^6.12.4", + "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", - "minimatch": "^3.1.2", + "minimatch": "^3.1.3", "strip-json-comments": "^3.1.1" }, "engines": { @@ -904,9 +905,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", - "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "version": "9.39.3", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.3.tgz", + "integrity": "sha512-1B1VkCq6FuUNlQvlBYb+1jDu/gV297TIs/OeiaSR9l1H27SVW55ONE1e1Vp16NqP683+xEGzxYtv4XCiDPaQiw==", "dev": true, "license": "MIT", "engines": { @@ -4517,49 +4518,49 @@ ] }, "node_modules/@tailwindcss/node": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz", - "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", + "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/remapping": "^2.3.4", - "enhanced-resolve": "^5.18.3", + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", - "lightningcss": "1.30.2", + "lightningcss": "1.31.1", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.1.18" + "tailwindcss": "4.2.1" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz", - "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz", + "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", "dev": true, "license": "MIT", "engines": { - "node": ">= 10" + "node": ">= 20" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.18", - "@tailwindcss/oxide-darwin-arm64": "4.1.18", - "@tailwindcss/oxide-darwin-x64": "4.1.18", - "@tailwindcss/oxide-freebsd-x64": "4.1.18", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", - "@tailwindcss/oxide-linux-x64-musl": "4.1.18", - "@tailwindcss/oxide-wasm32-wasi": "4.1.18", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" + "@tailwindcss/oxide-android-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-x64": "4.2.1", + "@tailwindcss/oxide-freebsd-x64": "4.2.1", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-x64-musl": "4.2.1", + "@tailwindcss/oxide-wasm32-wasi": "4.2.1", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz", - "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz", + "integrity": "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==", "cpu": [ "arm64" ], @@ -4570,13 +4571,13 @@ "android" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz", - "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", + "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", "cpu": [ "arm64" ], @@ -4587,13 +4588,13 @@ "darwin" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz", - "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz", + "integrity": "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==", "cpu": [ "x64" ], @@ -4604,13 +4605,13 @@ "darwin" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz", - "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz", + "integrity": "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==", "cpu": [ "x64" ], @@ -4621,13 +4622,13 @@ "freebsd" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz", - "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz", + "integrity": "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==", "cpu": [ "arm" ], @@ -4638,13 +4639,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz", - "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz", + "integrity": "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==", "cpu": [ "arm64" ], @@ -4655,13 +4656,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz", - "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz", + "integrity": "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==", "cpu": [ "arm64" ], @@ -4672,13 +4673,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz", - "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz", + "integrity": "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==", "cpu": [ "x64" ], @@ -4689,13 +4690,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz", - "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz", + "integrity": "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==", "cpu": [ "x64" ], @@ -4706,13 +4707,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz", - "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz", + "integrity": "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -4728,21 +4729,21 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1", + "@emnapi/core": "^1.8.1", + "@emnapi/runtime": "^1.8.1", "@emnapi/wasi-threads": "^1.1.0", - "@napi-rs/wasm-runtime": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.1", "@tybys/wasm-util": "^0.10.1", - "tslib": "^2.4.0" + "tslib": "^2.8.1" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz", - "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz", + "integrity": "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==", "cpu": [ "arm64" ], @@ -4753,13 +4754,13 @@ "win32" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz", - "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz", + "integrity": "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==", "cpu": [ "x64" ], @@ -4770,27 +4771,27 @@ "win32" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/postcss": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.18.tgz", - "integrity": "sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.2.1.tgz", + "integrity": "sha512-OEwGIBnXnj7zJeonOh6ZG9woofIjGrd2BORfvE5p9USYKDCZoQmfqLcfNiRWoJlRWLdNPn2IgVZuWAOM4iTYMw==", "dev": true, "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", - "@tailwindcss/node": "4.1.18", - "@tailwindcss/oxide": "4.1.18", - "postcss": "^8.4.41", - "tailwindcss": "4.1.18" + "@tailwindcss/node": "4.2.1", + "@tailwindcss/oxide": "4.2.1", + "postcss": "^8.5.6", + "tailwindcss": "4.2.1" } }, "node_modules/@tanstack/query-core": { - "version": "5.90.18", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.18.tgz", - "integrity": "sha512-rbGx6bHgPNVzutP7BEr+53UPKohpckqlMAad+To9UxTbeaQ+kC/1SDRj+QzkwbQ7qhLT/1IKp34yS6thda6fzA==", + "version": "5.90.20", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.20.tgz", + "integrity": "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==", "license": "MIT", "funding": { "type": "github", @@ -4798,12 +4799,12 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.90.18", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.18.tgz", - "integrity": "sha512-KqNZX0C5IFz4639zR1ilnQ288tQdJrMNLtzmlzyJ14xauBkhtLEy3mPU/V4KiHsr41eL1ILZbDP36TB12lYfCQ==", + "version": "5.90.21", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.21.tgz", + "integrity": "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.90.18" + "@tanstack/query-core": "5.90.20" }, "funding": { "type": "github", @@ -4873,9 +4874,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.30", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", - "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", + "version": "20.19.35", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.35.tgz", + "integrity": "sha512-Uarfe6J91b9HAUXxjvSOdiO2UPOKLm07Q1oh0JHxoZ1y8HoqxDAu3gVrsrOHeiio0kSsoVBt4wFrKOm0dKxVPQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4883,9 +4884,9 @@ } }, "node_modules/@types/react": { - "version": "19.2.8", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.8.tgz", - "integrity": "sha512-3MbSL37jEchWZz2p2mjntRZtPt837ij10ApxKfgmXCTuHWagYg7iA5bqPw6C8BMPfwidlvfPI/fxOc42HLhcyg==", + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "devOptional": true, "license": "MIT", "dependencies": { @@ -4903,17 +4904,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.53.0.tgz", - "integrity": "sha512-eEXsVvLPu8Z4PkFibtuFJLJOTAV/nPdgtSjkGoPpddpFk3/ym2oy97jynY6ic2m6+nc5M8SE1e9v/mHKsulcJg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.1.tgz", + "integrity": "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.53.0", - "@typescript-eslint/type-utils": "8.53.0", - "@typescript-eslint/utils": "8.53.0", - "@typescript-eslint/visitor-keys": "8.53.0", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/type-utils": "8.56.1", + "@typescript-eslint/utils": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -4926,8 +4927,8 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.53.0", - "eslint": "^8.57.0 || ^9.0.0", + "@typescript-eslint/parser": "^8.56.1", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, @@ -4942,16 +4943,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.53.0.tgz", - "integrity": "sha512-npiaib8XzbjtzS2N4HlqPvlpxpmZ14FjSJrteZpPxGUaYPlvhzlzUZ4mZyABo0EFrOWnvyd0Xxroq//hKhtAWg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.1.tgz", + "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.53.0", - "@typescript-eslint/types": "8.53.0", - "@typescript-eslint/typescript-estree": "8.53.0", - "@typescript-eslint/visitor-keys": "8.53.0", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3" }, "engines": { @@ -4962,19 +4963,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.53.0.tgz", - "integrity": "sha512-Bl6Gdr7NqkqIP5yP9z1JU///Nmes4Eose6L1HwpuVHwScgDPPuEWbUVhvlZmb8hy0vX9syLk5EGNL700WcBlbg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz", + "integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.53.0", - "@typescript-eslint/types": "^8.53.0", + "@typescript-eslint/tsconfig-utils": "^8.56.1", + "@typescript-eslint/types": "^8.56.1", "debug": "^4.4.3" }, "engines": { @@ -4989,14 +4990,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.53.0.tgz", - "integrity": "sha512-kWNj3l01eOGSdVBnfAF2K1BTh06WS0Yet6JUgb9Cmkqaz3Jlu0fdVUjj9UI8gPidBWSMqDIglmEXifSgDT/D0g==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", + "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.53.0", - "@typescript-eslint/visitor-keys": "8.53.0" + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5007,9 +5008,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.53.0.tgz", - "integrity": "sha512-K6Sc0R5GIG6dNoPdOooQ+KtvT5KCKAvTcY8h2rIuul19vxH5OTQk7ArKkd4yTzkw66WnNY0kPPzzcmWA+XRmiA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz", + "integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==", "dev": true, "license": "MIT", "engines": { @@ -5024,15 +5025,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.53.0.tgz", - "integrity": "sha512-BBAUhlx7g4SmcLhn8cnbxoxtmS7hcq39xKCgiutL3oNx1TaIp+cny51s8ewnKMpVUKQUGb41RAUWZ9kxYdovuw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.1.tgz", + "integrity": "sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.53.0", - "@typescript-eslint/typescript-estree": "8.53.0", - "@typescript-eslint/utils": "8.53.0", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/utils": "8.56.1", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -5044,14 +5045,14 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.0.tgz", - "integrity": "sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", + "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", "dev": true, "license": "MIT", "engines": { @@ -5063,18 +5064,18 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.53.0.tgz", - "integrity": "sha512-pw0c0Gdo7Z4xOG987u3nJ8akL9093yEEKv8QTJ+Bhkghj1xyj8cgPaavlr9rq8h7+s6plUJ4QJYw2gCZodqmGw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz", + "integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.53.0", - "@typescript-eslint/tsconfig-utils": "8.53.0", - "@typescript-eslint/types": "8.53.0", - "@typescript-eslint/visitor-keys": "8.53.0", + "@typescript-eslint/project-service": "8.56.1", + "@typescript-eslint/tsconfig-utils": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3", - "minimatch": "^9.0.5", + "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" @@ -5090,36 +5091,49 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.2" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { @@ -5130,16 +5144,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.53.0.tgz", - "integrity": "sha512-XDY4mXTez3Z1iRDI5mbRhH4DFSt46oaIFsLg+Zn97+sYrXACziXSQcSelMybnVZ5pa1P6xYkPr5cMJyunM1ZDA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz", + "integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.53.0", - "@typescript-eslint/types": "8.53.0", - "@typescript-eslint/typescript-estree": "8.53.0" + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5149,19 +5163,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.53.0.tgz", - "integrity": "sha512-LZ2NqIHFhvFwxG0qZeLL9DvdNAHPGCY5dIRwBhyYeU+LfLhcStE1ImjsuTG/WaVh3XysGaeLW8Rqq7cGkPCFvw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz", + "integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.53.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.56.1", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5171,6 +5185,19 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@vitejs/plugin-react": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", @@ -5193,9 +5220,9 @@ } }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", "bin": { @@ -5274,9 +5301,9 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", - "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", @@ -5292,13 +5319,16 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.15", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.15.tgz", - "integrity": "sha512-kX8h7K2srmDyYnXRIppo4AH/wYgzWVCs+eKr3RusRSQ5PvRYoEFmR/I0PbdTjKFAoKqp5+kbxnNTFO9jOfSVJg==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", + "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", "dev": true, "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.js" + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/brace-expansion": { @@ -5370,9 +5400,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001764", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001764.tgz", - "integrity": "sha512-9JGuzl2M+vPL+pz70gtMF9sHdMFbY9FJaQBi186cHKH3pSzDvzoUJUPV6fqiKIMyXbud9ZLg4F3Yza1vJ1+93g==", + "version": "1.0.30001775", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001775.tgz", + "integrity": "sha512-s3Qv7Lht9zbVKE9XoTyRG6wVDCKdtOFIjBGg3+Yhn6JaytuNKPIjBMTMIY1AnOH3seL5mvF+x33oGAyK3hVt3A==", "dev": true, "funding": [ { @@ -5590,21 +5620,21 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.267", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", - "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "version": "1.5.302", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz", + "integrity": "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==", "dev": true, "license": "ISC" }, "node_modules/enhanced-resolve": { - "version": "5.18.4", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", - "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz", + "integrity": "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==", "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "tapable": "^2.3.0" }, "engines": { "node": ">=10.13.0" @@ -5721,9 +5751,9 @@ } }, "node_modules/eslint": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", - "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "version": "9.39.3", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.3.tgz", + "integrity": "sha512-VmQ+sifHUbI/IcSopBCF/HO3YiHQx/AVd3UVyYL6weuwW+HvON9VYn5l6Zl1WZzPWXPNZrSQpxwkkZ/VuvJZzg==", "dev": true, "license": "MIT", "dependencies": { @@ -5733,7 +5763,7 @@ "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.2", + "@eslint/js": "9.39.3", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -5981,9 +6011,9 @@ } }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.4.tgz", + "integrity": "sha512-3+mMldrTAPdta5kjX2G2J7iX4zxtnwpdA8Tr2ZSjkyPSanvbZAcy6flmtnXbEybHrDcU9641lxrMfFuUxVz9vA==", "dev": true, "license": "ISC" }, @@ -6024,13 +6054,13 @@ } }, "node_modules/framer-motion": { - "version": "12.26.2", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.26.2.tgz", - "integrity": "sha512-lflOQEdjquUi9sCg5Y1LrsZDlsjrHw7m0T9Yedvnk7Bnhqfkc89/Uha10J3CFhkL+TCZVCRw9eUGyM/lyYhXQA==", + "version": "12.34.4", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.34.4.tgz", + "integrity": "sha512-q1PwNhc1XJ3qYG7nc9+pEU5P3tnjB6Eh9vv5gGzy61nedDLB4+xk5peMCWhKM0Zn6sfhgunf/q9n0UgCoyKOBA==", "license": "MIT", "dependencies": { - "motion-dom": "^12.26.2", - "motion-utils": "^12.24.10", + "motion-dom": "^12.34.3", + "motion-utils": "^12.29.2", "tslib": "^2.4.0" }, "peerDependencies": { @@ -6369,9 +6399,9 @@ } }, "node_modules/keycloak-js": { - "version": "26.2.2", - "resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-26.2.2.tgz", - "integrity": "sha512-ug7pNZ1xNkd7PPkerOJCEU2VnUhS7CYStDOCFJgqCNQ64h53ppxaKrh4iXH0xM8hFu5b1W6e6lsyYWqBMvaQFg==", + "version": "26.2.3", + "resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-26.2.3.tgz", + "integrity": "sha512-widjzw/9T6bHRgEp6H/Se3NCCarU7u5CwFKBcwtu7xfA1IfdZb+7Q7/KGusAnBo34Vtls8Oz9vzSqkQvQ7+b4Q==", "license": "Apache-2.0", "workspaces": [ "test" @@ -6402,9 +6432,9 @@ } }, "node_modules/lightningcss": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", - "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz", + "integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==", "dev": true, "license": "MPL-2.0", "dependencies": { @@ -6418,23 +6448,23 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-android-arm64": "1.30.2", - "lightningcss-darwin-arm64": "1.30.2", - "lightningcss-darwin-x64": "1.30.2", - "lightningcss-freebsd-x64": "1.30.2", - "lightningcss-linux-arm-gnueabihf": "1.30.2", - "lightningcss-linux-arm64-gnu": "1.30.2", - "lightningcss-linux-arm64-musl": "1.30.2", - "lightningcss-linux-x64-gnu": "1.30.2", - "lightningcss-linux-x64-musl": "1.30.2", - "lightningcss-win32-arm64-msvc": "1.30.2", - "lightningcss-win32-x64-msvc": "1.30.2" + "lightningcss-android-arm64": "1.31.1", + "lightningcss-darwin-arm64": "1.31.1", + "lightningcss-darwin-x64": "1.31.1", + "lightningcss-freebsd-x64": "1.31.1", + "lightningcss-linux-arm-gnueabihf": "1.31.1", + "lightningcss-linux-arm64-gnu": "1.31.1", + "lightningcss-linux-arm64-musl": "1.31.1", + "lightningcss-linux-x64-gnu": "1.31.1", + "lightningcss-linux-x64-musl": "1.31.1", + "lightningcss-win32-arm64-msvc": "1.31.1", + "lightningcss-win32-x64-msvc": "1.31.1" } }, "node_modules/lightningcss-android-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", - "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", + "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", "cpu": [ "arm64" ], @@ -6453,9 +6483,9 @@ } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", - "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", + "integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==", "cpu": [ "arm64" ], @@ -6474,9 +6504,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", - "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", + "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", "cpu": [ "x64" ], @@ -6495,9 +6525,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", - "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", + "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", "cpu": [ "x64" ], @@ -6516,9 +6546,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", - "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", + "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", "cpu": [ "arm" ], @@ -6537,9 +6567,9 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", - "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", + "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", "cpu": [ "arm64" ], @@ -6558,9 +6588,9 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", - "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", + "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", "cpu": [ "arm64" ], @@ -6579,9 +6609,9 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", - "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", + "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", "cpu": [ "x64" ], @@ -6600,9 +6630,9 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", - "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", + "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", "cpu": [ "x64" ], @@ -6621,9 +6651,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", - "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", + "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", "cpu": [ "arm64" ], @@ -6642,9 +6672,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", - "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", + "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", "cpu": [ "x64" ], @@ -6784,18 +6814,18 @@ } }, "node_modules/motion-dom": { - "version": "12.26.2", - "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.26.2.tgz", - "integrity": "sha512-KLMT1BroY8oKNeliA3JMNJ+nbCIsTKg6hJpDb4jtRAJ7nCKnnpg/LTq/NGqG90Limitz3kdAnAVXecdFVGlWTw==", + "version": "12.34.3", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.34.3.tgz", + "integrity": "sha512-sYgFe+pR9aIM7o4fhs2aXtOI+oqlUd33N9Yoxcgo1Fv7M20sRkHtCmzE/VRNIcq7uNJ+qio+Xubt1FXH3pQ+eQ==", "license": "MIT", "dependencies": { - "motion-utils": "^12.24.10" + "motion-utils": "^12.29.2" } }, "node_modules/motion-utils": { - "version": "12.24.10", - "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.24.10.tgz", - "integrity": "sha512-x5TFgkCIP4pPsRLpKoI86jv/q8t8FQOiM/0E8QKBzfMozWHfkKap2gA1hOki+B5g3IsBNpxbUnfOum1+dgvYww==", + "version": "12.29.2", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.29.2.tgz", + "integrity": "sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A==", "license": "MIT" }, "node_modules/ms": { @@ -6942,9 +6972,9 @@ } }, "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "dev": true, "funding": [ { @@ -7232,9 +7262,9 @@ } }, "node_modules/react-router": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.12.0.tgz", - "integrity": "sha512-kTPDYPFzDVGIIGNLS5VJykK0HfHLY5MF3b+xj0/tTyNYL1gF1qs7u67Z9jEhQk2sQ98SUaHxlG31g1JtF7IfVw==", + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.1.tgz", + "integrity": "sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA==", "license": "MIT", "dependencies": { "cookie": "^1.0.1", @@ -7254,12 +7284,12 @@ } }, "node_modules/react-router-dom": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.12.0.tgz", - "integrity": "sha512-pfO9fiBcpEfX4Tx+iTYKDtPbrSLLCbwJ5EqP+SPYQu1VYCXdy79GSj0wttR0U4cikVdlImZuEZ/9ZNCgoaxwBA==", + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.13.1.tgz", + "integrity": "sha512-UJnV3Rxc5TgUPJt2KJpo1Jpy0OKQr0AjgbZzBFjaPJcFOb2Y8jA5H3LT8HUJAiRLlWrEXWHbF1Z4SCZaQjWDHw==", "license": "MIT", "dependencies": { - "react-router": "7.12.0" + "react-router": "7.13.1" }, "engines": { "node": ">=20.0.0" @@ -7391,6 +7421,16 @@ "node": ">=8" } }, + "node_modules/sonner": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.7.tgz", + "integrity": "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==", + "license": "MIT", + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -7457,9 +7497,9 @@ } }, "node_modules/tailwindcss": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", - "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz", + "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", "license": "MIT" }, "node_modules/tapable": { @@ -7550,16 +7590,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.53.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.53.0.tgz", - "integrity": "sha512-xHURCQNxZ1dsWn0sdOaOfCSQG0HKeqSj9OexIxrz6ypU6wHYOdX2I3D2b8s8wFSsSOYJb+6q283cLiLlkEsBYw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.56.1.tgz", + "integrity": "sha512-U4lM6pjmBX7J5wk4szltF7I1cGBHXZopnAXCMXb3+fZ3B/0Z3hq3wS/CCUB2NZBNAExK92mCU2tEohWuwVMsDQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.53.0", - "@typescript-eslint/parser": "8.53.0", - "@typescript-eslint/typescript-estree": "8.53.0", - "@typescript-eslint/utils": "8.53.0" + "@typescript-eslint/eslint-plugin": "8.56.1", + "@typescript-eslint/parser": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/utils": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7569,7 +7609,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, diff --git a/package.json b/package.json index 73c1964..b579866 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "react": "19.0.0", "react-dom": "19.0.0", "react-router-dom": "^7.1.1", + "sonner": "^2.0.7", "tailwind-merge": "3.3.1", "tailwind-variants": "3.1.1" }, diff --git a/src/App.tsx b/src/App.tsx index 3df2686..85a87a4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,7 @@ import { Routes, Route } from 'react-router-dom'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { useState } from 'react'; +import { Toaster } from '@/components/ui/sonner'; import { ThemeProvider } from './components/theme-provider'; import { Layout } from './components/Layout'; import { HomePage } from './pages/HomePage'; @@ -25,6 +26,7 @@ export function App() { return ( + }> } /> diff --git a/src/components/ui/sonner.tsx b/src/components/ui/sonner.tsx new file mode 100644 index 0000000..30de0dc --- /dev/null +++ b/src/components/ui/sonner.tsx @@ -0,0 +1,29 @@ +'use client'; + +import { useTheme } from '@/components/use-theme'; +import { Toaster as Sonner, type ToasterProps } from 'sonner'; + +const Toaster = ({ ...props }: ToasterProps) => { + const { theme = 'system' } = useTheme(); + + return ( + + ); +}; + +export { Toaster }; diff --git a/src/lib/milestones.ts b/src/lib/milestones.ts new file mode 100644 index 0000000..26d9790 --- /dev/null +++ b/src/lib/milestones.ts @@ -0,0 +1,99 @@ +import { + Star, + Target, + Award, + Trophy, + Flame, + Zap, + Mountain, +} from 'lucide-react'; +import type { LucideIcon } from 'lucide-react'; + +export interface MilestoneDef { + id: string; + name: string; + description: string; + icon: LucideIcon; + gradient: string; + glowColor: string; + /** Total mappings threshold (for count-based milestones) */ + threshold?: number; + /** Streak days threshold (for streak-based milestones) */ + streakDays?: number; +} + +export const MILESTONES: MilestoneDef[] = [ + { + id: 'first-steps', + name: 'The First Node', + description: '1+ mapping', + icon: Star, + gradient: 'from-emerald-400 to-teal-500', + glowColor: 'rgba(16,185,129,0.35)', + threshold: 1, + }, + { + id: 'getting-started', + name: 'Getting Started', + description: '10+ mappings', + icon: Target, + gradient: 'from-blue-400 to-indigo-500', + glowColor: 'rgba(99,102,241,0.35)', + threshold: 10, + }, + { + id: 'half-century', + name: 'Half Century', + description: '50+ mappings', + icon: Award, + gradient: 'from-violet-400 to-purple-600', + glowColor: 'rgba(139,92,246,0.35)', + threshold: 50, + }, + { + id: 'century', + name: 'Century', + description: '100+ mappings', + icon: Trophy, + gradient: 'from-amber-400 to-orange-500', + glowColor: 'rgba(245,158,11,0.35)', + threshold: 100, + }, + { + id: 'streak-3', + name: 'On Fire', + description: '3-day streak', + icon: Flame, + gradient: 'from-orange-400 to-red-500', + glowColor: 'rgba(239,68,68,0.35)', + streakDays: 3, + }, + { + id: 'streak-7', + name: 'Dedicated', + description: '7-day streak', + icon: Zap, + gradient: 'from-yellow-400 to-amber-500', + glowColor: 'rgba(245,158,11,0.35)', + streakDays: 7, + }, + { + id: 'streak-30', + name: 'Monthly Mapper', + description: '30-day streak', + icon: Mountain, + gradient: 'from-cyan-400 to-blue-600', + glowColor: 'rgba(6,182,212,0.35)', + streakDays: 30, + }, +]; + +/** Returns milestones that were just crossed going from oldTotal to newTotal */ +export function getNewlyEarnedMilestones( + oldTotal: number, + newTotal: number +): MilestoneDef[] { + return MILESTONES.filter( + m => m.threshold && newTotal >= m.threshold && oldTotal < m.threshold + ); +} diff --git a/src/pages/DashboardPage.tsx b/src/pages/DashboardPage.tsx index 85bce55..861b485 100644 --- a/src/pages/DashboardPage.tsx +++ b/src/pages/DashboardPage.tsx @@ -5,91 +5,21 @@ import { contributorStatsApi, type ContributorStats, } from '@/lib/api/contributor-stats'; -import { - Flame, - Trophy, - Zap, - Mountain, - Target, - Award, - Star, - BookOpen, -} from 'lucide-react'; +import { BookOpen, Flame } from 'lucide-react'; import { ContributionHeatmap } from '@/components/dashboard/ContributionHeatmap'; import { heatmapColor } from '@/lib/heatmap-helpers'; +import { MILESTONES, type MilestoneDef } from '@/lib/milestones'; const GUEST_USER_ID = 'guest'; const ONBOARDED_KEY = 'memo-onboarded'; -interface BadgeDef { - id: string; - name: string; - description: string; - icon: React.ElementType; - gradient: string; - glowColor: string; -} - -const BADGE_DEFS: BadgeDef[] = [ - { - id: 'first-steps', - name: 'The First Node', - description: '1+ mapping', - icon: Star, - gradient: 'from-emerald-400 to-teal-500', - glowColor: 'rgba(16,185,129,0.35)', - }, - { - id: 'getting-started', - name: 'Getting Started', - description: '10+ mappings', - icon: Target, - gradient: 'from-blue-400 to-indigo-500', - glowColor: 'rgba(99,102,241,0.35)', - }, - { - id: 'half-century', - name: 'Half Century', - description: '50+ mappings', - icon: Award, - gradient: 'from-violet-400 to-purple-600', - glowColor: 'rgba(139,92,246,0.35)', - }, - { - id: 'century', - name: 'Century', - description: '100+ mappings', - icon: Trophy, - gradient: 'from-amber-400 to-orange-500', - glowColor: 'rgba(245,158,11,0.35)', - }, - { - id: 'streak-3', - name: 'On Fire', - description: '3-day streak', - icon: Flame, - gradient: 'from-orange-400 to-red-500', - glowColor: 'rgba(239,68,68,0.35)', - }, - { - id: 'streak-7', - name: 'Dedicated', - description: '7-day streak', - icon: Zap, - gradient: 'from-yellow-400 to-amber-500', - glowColor: 'rgba(245,158,11,0.35)', - }, - { - id: 'streak-30', - name: 'Monthly Mapper', - description: '30-day streak', - icon: Mountain, - gradient: 'from-cyan-400 to-blue-600', - glowColor: 'rgba(6,182,212,0.35)', - }, -]; - -function BadgeCard({ badge, earned }: { badge: BadgeDef; earned: boolean }) { +function BadgeCard({ + badge, + earned, +}: { + badge: MilestoneDef; + earned: boolean; +}) { const Icon = badge.icon; return (
- {earnedSet.size} / {BADGE_DEFS.length} earned + {earnedSet.size} / {MILESTONES.length} earned
- {BADGE_DEFS.map(badge => ( + {MILESTONES.map(badge => ( (null); const [showSessionSummary, setShowSessionSummary] = useState(false); + const [initialTotalVotes, setInitialTotalVotes] = useState( + null + ); const { hoveredValue: hoveredRelation, @@ -150,12 +156,58 @@ export function SessionPage() { string | null >(null); + // Track which milestones have been shown + const shownMilestonesRef = useRef>(new Set()); + + // Check for newly earned milestones and celebrate + const checkMilestones = useCallback( + (newCompletedCount: number) => { + if (initialTotalVotes === null) return; + const oldTotal = initialTotalVotes + newCompletedCount - 1; + const newTotal = initialTotalVotes + newCompletedCount; + const newMilestones = getNewlyEarnedMilestones(oldTotal, newTotal); + + newMilestones.forEach(milestone => { + // Skip if already shown + if (shownMilestonesRef.current.has(milestone.id)) return; + shownMilestonesRef.current.add(milestone.id); + + // Show toast with milestone info + const Icon = milestone.icon; + toast.success( +
+
+ +
+
+
{milestone.name}
+
{milestone.description}
+
+
, + { duration: 2500 } + ); + }); + }, + [initialTotalVotes] + ); + useEffect(() => { async function loadDemoUser() { try { const result = await getOrCreateDemoUserAction(); if (result.success && result.user) { setUserId(result.user.id); + // Fetch initial stats for milestone tracking + try { + const userStats = await contributorStatsApi.getStats( + result.user.id + ); + setInitialTotalVotes(userStats.totalVotes); + } catch { + setInitialTotalVotes(0); + } } else { setError( result.error ?? @@ -346,7 +398,12 @@ export function SessionPage() { return; } - setStats(prev => ({ ...prev, completed: prev.completed + 1 })); + setStats(prev => { + const newCompleted = prev.completed + 1; + // Call checkMilestones after state update (outside updater to avoid React Strict Mode double-call) + setTimeout(() => checkMilestones(newCompleted), 0); + return { ...prev, completed: newCompleted }; + }); setHistory(prev => [ ...prev, { @@ -401,7 +458,12 @@ export function SessionPage() { return; } - setStats(prev => ({ ...prev, completed: prev.completed + 1 })); + setStats(prev => { + const newCompleted = prev.completed + 1; + // Call checkMilestones after state update (outside updater to avoid React Strict Mode double-call) + setTimeout(() => checkMilestones(newCompleted), 0); + return { ...prev, completed: newCompleted }; + }); setHistory(prev => [ ...prev, { @@ -468,6 +530,7 @@ export function SessionPage() { mappingMode, loadMappingPair, currentRelationshipId, + checkMilestones, ] ); From 23c8d8b61e2d821a58bff20bcf63632db58cc41f Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Tue, 3 Mar 2026 01:52:23 +0100 Subject: [PATCH 27/57] Update screenshot on main page, extract CompetencyNetworkViz into reusable component to use it on main page and while onboarding --- public/sessionPreview2.png | Bin 0 -> 1716489 bytes .../CompetencyNetworkViz.tsx | 294 ++++++++++++++++++ src/pages/HomePage.tsx | 18 +- src/pages/OnboardingPage.tsx | 228 +------------- 4 files changed, 309 insertions(+), 231 deletions(-) create mode 100644 public/sessionPreview2.png create mode 100644 src/components/competency-network/CompetencyNetworkViz.tsx diff --git a/public/sessionPreview2.png b/public/sessionPreview2.png new file mode 100644 index 0000000000000000000000000000000000000000..4e9dd04f4545eaeb573c962ea8d629b81456a4e1 GIT binary patch literal 1716489 zcmeFZby!s0yEjf+q>6yjpaRm}p@<4dh|{DuhmrUlU%rV0S5<%MB%|*bsQWb zTO6EoIOom)cfO@Q>cPRm1zE|-soBWgmjl~^9Unh40h!&ka(ZTK;-MyhgTwaD=WUr% zlNxzTgJyQR3ppJvE&pq|=*SB-qLo+fI-Jw^yc}JhllQjeek3!Y$gzLGvHyi`d&*#O zanW<{qZa39v%bBb^Wb@%#q1d|J4E9{vZ3dOiJij-+g^8#|!{b&SOG z8_C5bibusVGZ^XZ36&0=hU4R~&u^Ca^3$TPwiqxx`0y2-+H+(5azu3{g@aQ0mCe_) zj;#y+7IoT;^*1%OyFQRNkQdC+k1tQvj2rinIv!Ro*%r2mMPJtbN-Ftmgtzx49^I(S zj|%^W=LU`Fpfj*>q>YD%H{e(hIfB0kLj|8C;YCTn2UDi{(OOm|b*}fvLzZEB_ z;bM{wf4NBicnkm8k~c1XuIc5hSW-QJ>jWSLIW=Mu99(<+nRVcEteLigxw10OE#Ueb z4k7L(9DLvk7x>1(y@o@0a*czdh)eV9S{;||XB#{moM0;)f}d@4fxpG-GD=YU5zIJY0mDJTGcAA=mt%

k!OqdSNsYjb^UogW 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

3d3U-T%khE&bg4 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�n!&u?EGPI}^6zQ5Z)I}0DA;37$+3^`LXX)V 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%0A7BMWW@tOK)8y&VtQ%4<4u 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

  • Jx>d&4OrI0GDu z4$H{_gi#bb>}IPIaeKh=N0Jq9DUwp5U^tPzgXNX1XuhT+s+1qL4U)71P^d5%lN{uk z9T>`wWaHIq4KR{KX}~>QtG&RjLYC;=S~7bqW_+gs$Tk*SlBTPq;@xxq&$cCYt>F)d6n- zY2{VDdXKGJIv-zgL=cE);bD+F`hka}iz@%LE!mKWPy7~>Pu1r$}W6^+DT znQ4U7pPnUowpCCb=uN1IUR`A+@1Uj@1y<1ZdTCpVVb;4-w7M$T`op$UdePPIoj&t? zD(RKT>G8;kL})Aol?ZI@%%@lz14}=_yk!UlS(8&%Z=l3osnz8HxkmzerPNV=Ld_V8 z$(y^U(c3V4xjiO-iX>x*a?&TUdn<_@+k}^XL+WDw4m>}6hVSxG&o=|D(p~BV5@C@M zI%51BLJBuyj*Q1|cIqW%XtBgL`$M~v zA|7rrKnOY&gC;b{|9+ctNB$Z3{#*U z^AGc@OROf{f_m{G+$n@x zb=j@~JLnDWbs)1OH#R^i*FcpGfzLZ`GQ#D0zwXS3KB+n3Rd>Sm3Hipb0gFbWpbxxY zS1ewRtd6Gj5ux+A=Vco_XH|KfoBN|lngfJOB;eK-LfSnK{MK!2Fr&jEt}VVJjetUs z{!OUF=?n_UKil5gZ*orJT?jO;h`ao$G%tP^eqccx@3ltwBR4R1I6psL4yaX;?g$u) zlZZk(o~jiso?EY}$FndNNF(hxIqo)t@Btt?$|zd*J`UQ&*SIFkW0(vUIJW_@1>doB zW!yQn!chiemeA_AGW9$nA{24I*Y{Rk=G$Rjg(Jy;aCqEe)zH=MerLgvZxKtnz`JI@ zm?~Hploz7fJi`4)hcHT=G^RN7(zKVfG4LQj?+c25zd~5hY6rEaWt{f^hXS(dKZ^7x zibeaNGR5Hlu%2cp6IeEfFUe2Hj}~>48AO`Lv{*sa!gGmEM%lu5{xF=FnnSt>kWXi^ z9|C{!Q!EI%kJEyEz<>ycB$HCr=btkCGH0pt$v~DYe|yv~{Lj(RoutT|W!X zpF!F>aEkS>qLnbvBzd8F-_e^}Ond$mPgJ!W=x5sfZVXE4kFI0i|Lr}G__jPeM5qw& zEC&Cu%h`Fnf}xt|HLMIF@DZrt7iQFuWMh0Yvf2g+^C_UugFV(Jf3 zKCqkn$a1p$^3R;LnuC|%)pT$%u(@mHfP{2O-nL55>~To+0^+4mB;aISM};T==jvb3vLv^n0AfI=LR z){D59aT3-TkRAKyXznQOh;$o?w)LhUgJ+`{ykR0zUBOH%KPTNqY~<;agQR(CKv)e! zmgjCbvv7KBtr~bz-X!2M3P-1pk11a1dWP)vN2{86E+!@%F#RuGszIszA@Vxh&IZK9MB7#!1Ji)r6+w`30;l*Qm1L` z!K|_vq)ru}#BJ$=PMXi@ZCO#oc(m}8BQOBHVMARzwlq6SQSp}uPdQ}$toqtpFwicb!Zfzm|>0>R3l&2U)%W?r(m=8fI}wQVuqP)v~B zsh&vG8^7fJH&_uNZJsDYqvmf#-dX<@!JzQATOIfTW0ADU&C4Lnm7@PIYg&h zT#m$xZz_LfP!6BnU@<4yd&Hr-F27V>W*4J4Cr;iD!l6LO+l5Vz^%qnWyX4p*M82}U z2KIoRd|J%1dz1H2lU{$XlkOh*D0SF@`p!>FboBMhvVVv?tEs09Y=(R4DzjUBwK}i_ zwdb3XovZg{I?ZGHMvp2c_ja3leIAEEui%&=nK!Jjt7X^y?XviF9_a{qi`~2NcRX@; z3PiKGjMu5NAnK_;LLM#@t0#;VXy^$&WbMc1Uik|h~T~&3K-T3c0jMo*SKntZM|%r};Mg-!MVa_{b!)6rvWH@Yx3IJ+n3F`Um1VvGw%z8Ra0F zZxA$`aUc5+HnZVQZ5y5wOm|zj8yEM?+{?$E`{Qd3Azo* z+i^1xp8}uIq__@<hZ{;rNWDcU93v3OF4Lqm!zw)bmNgmt0Ylmc(_o!kLbYz( zVme*~x2EfPj7O%HS@r?v+gL%g&S3JhgU9f~qpNGoJ@bBzu`Y$D5v(r;h6?CB+IUM} zgiyumr9^_%>dXRtNq8f@4E1<-&=2g@e*2e#C(@lk*%p0RRpYaOp0`tU zT~oiF#OjBEi1?R+*pCGp%l;~ce=Q=i!1Y>NKkjMssysPExIxI+Dk6-6T1_>9X?0p2 z#?pP~yoWI`@SH-vbg_DK5t3lULlj6a46liO?=eo`3mH(`j146H?zhB8!U0MwZqIA- z?+37;nH^vB@ydAxatoMkS04#YF^@$*S~ukN4iD>4G{Z?5;Lg)}_uC2V+II)urgr`= zTNGBfOU!61{C?)}P_-X|-(L-|5Z&8VXw0$x?btCO`4RWcv`Io1wtFE1$F`&*m1IC_ z)=S09YiN@wZMAjR8}2o1_n)IN=y}E(&2{g-po{iX)hv)~J{J_6ShQHD=^o=}-$-)r zTbruMrvHuoNEq zmn3mBg$j>S{KvDG`SH(rd_>CyWg$f-q9jbRHi(}A_`sWCl>6pe$>m0FPOec~2~x$i zk`55r)B~wT9N0%ELDq8mbxFEeJW46MSHqw@{L|LLI+I+hJ6RTBtgaY_r69V(`%hA% zjqX-)g=55m>%Hd8+p<*vJJpP2)5zK{8uQPhS^^VZ`fEb~pDee}n7Q|`FjjL~;IAlV z?3n13E|yMTtKnfgC@#aL%p2#55i0RM@(`k=P@CPTl-F4HO9`r6IYOX8GtZhOS7 zVGRGXPlGF)`V+PUw_|vys3;X>P+KLEWPVQIWYP{!cnw=g07vy{U8by^iTH_^{QdBc z+4M(bY_BM6S^NI|q<sA*3b@nABG8QmBY3M*#``&8oW3yb$=eF{% zkF>JHg2?@+iMuU+n}|=ek(_R<8^jzSmi3(5Td>)EDeGyneb52TM5@zRbF?pQvo}49 zQWMMu*WAFl&Za5wW->CCh_o93xzG8(R^C@HDjOK8)oXaco9r_8 zOzM!=4Riu>1*DCZ0MYq&p825{{ z`LhO&_XGC?wD`E*q0gM!`nGqaSl#t+%Kh)h!yoRQzr|HWH&c@Z+f0*p%O2f&tGPSh z?_SoC5zrKluN`*$Hc=57$0&9lNRML7uU8{#YD&K9yA7MdNTN+pOi=02a_)Of#g$Zd z)XYH3wW77`GycvwoZd+H@NfLdcqC^sS4(YUXYsC7>pNdkSk8Nf;l~*P9aoW7Og4&Tn-z6AtS$U0ZR;&3MHy(=(fWg74$<5K^Rhv-$sdrvC#V=Y!si^xx*x2mi#aN{qX4x zbfg{@_D=2CLG7JNId$>=$;$u!OZLbe1Ap9W>BLHtH^eqE*| zIOo_@N2#5N&8k@pVuLeKQlZY%oFA)wlL4xv!uT7@Eju1hZQJhgKhTK?x6qI#d(2F_vNS< z`94JMw|HLtpI4@Sc3lFp2Zp~!@3IA2b5!?T4uJy>O1DSe<`)s_mU&@N4q6KFtCjfg z8>4QZ)Cu(L@NAU~wADCEN1GOT^t=h%`Ng}`TFz2k{kfonSmxIrd9%hATWp=9aa0t4 zZfz~eB;drnRu^eyC6~v*fuU4*%ygKf)k#%rwm@!Jx)_Y@IEnZxXlE}lD^{ zH0_{TX1-~g8fND)d2vZW3Q)cOqH^k}rB3f+v>KF4#q$uB;)nAo>lFuYesz%I?Zppp zV7f=|Z{FJ$kVSV^i$Unrh)vo!9Thj-jlrWZgV2|5OVeP4Cyg22+f4_Ek9ZHUJmSZ3 z#LN*7Cc`2=mCCUifnQ%$OAVQ0EemdYHx3h)GLJD&&f(L6BYPfzlX;7)mCPe^B)7tx zxoM6xkFQ9Sk&)9a){m;24PTrWQ*G-HBhkMjbV++cwkyxKMZCb-mgAxYC`)vo;5slh zH^vwq6YQh_+^c?-h@V3c)Vt_{yJMfR@&R|u{c^yvh*>Ro`)I%Caq+vwkT<Nr>ubgR39T4V+xg5ESfcuBf}j4 z7;Z%S*8H{FL8*cfo3wRok``qHbEpr9U89pWhX3%*Z#>k5G3*cs>Bv^z269^`rNq(i z#;#B|@L4*)r$v~j@#B9G@Oo%8-)&>1;T2lU{`J?GbXuF^E<@ySoJ6_%bj|jbT|g(} zyZEOAjB=v1U%WBUDssNgJwj*uC88n(lm4>e-GCR$si1m~`fHP~>qsPhB+=PJD){_u zT(?ZBIQ;Za)U^co+;c5t`RB+oHd~Is+0+HuF{L``$ zCN+!cJ-xS+->5@hu-BpF7@2^`Kc3!*nM##x3Ae{I@ZFuf_gCF3_5U_$tcM+ln{2s_ zon)F1otBd5PF2RC$rEF9*@ZC$wtNx>%tPW$ft<`=N$7~4+_Vy?IefLohzwf#+=^d( zNV`vHF>G#)$1v%U)X0aL{_Pot^zm89;~5gHZf}j`ZA3eVHtSrmS|Kjm>jIj;JiYv; zJ|A9wDJN0vsZ_NEIi5>ZqJA$mdBVQ$zd&A-Bi{G-UmHdOoGl1!o;rLCBAsZ>9VaAb zl417{uwEe&>ce^_^DNM(O}u&e;y&J&u7nyPHXD~}uELGK-G9dF)65bPXA+#&-1|`! zSHRbo;;_fO+HCRGrXbnv+~y_bGD>t9RgUfrUR>$?PwO-Sigt1EVM%;J7@ko<# zGCF#f8{8w8r18GLn3Q^@Oi%5Ak!#^ojg4|axJnedi6(aFB;;u-FD7t9uH@bm``k_? z8$|wml)r|un9X*fFEe(m9Le&79Z-QMaWYdkbjYj9UPCo4@(m@kuQp43}U9 zE`xbE9_^5z)kRa*aLoEL!%FXTFTmndG^cMsTPbn&Xi+Wx;zY_(&xf^x-~+rXkj;YPqDS% zB)g>V(Q!@oIiW8=_RR{6{>_VOIC6NA>jSNk{>qB$cj|0evN zsJ@=V=CxY0yyK?C6p4;YjAfuzoVXHrk+2gMhC3~F>ahtP+}MGr$NsarJV+@Gqc1Q2 zu)c4shy0MtQ5Pu3G*Z{xnvObkAL8<(Jg#EvR)MLVx@|YfRuoxkitY_DN3;$l0iFvY zXXJn%kb={>S|%8ic*Vd*ol`zIH>70G$W77skP=;_NZpZMUBb5B-T#UxGC;cQ<&0uY zs4`|C5?h|&{EY2gi63?ocKHYN#(^oX=*mwx#jqRJ&+FTkKe(eT$!hmsIaWu13)DDe z*KciYd#%f9r#LYUE)-&Z-}lDhIRkLZ`~z3>QJw9Q7s<9aFhiY_9>XbWTB(}UjEz*U zzbUAfa#|#oDnLR0E#vAox%b8s-rstd^`&URvFURObm*un=U{!xK8?|xViJ>0dCWR) zud_Sfj@4Y-AD8d4g3(n7I@LiDfBoAS3P`}?t0sK|GSHKnk|37~w}{4t`|rENrL>?n z`WXv2+yV;Ug}FW$Gujxq&bE)m#!jQp_HrO|4IO0uz2fh&>CD-|?xT}h_~1wgJJNK! z`p;JW8+IFGAe({kdlVLX##UfX*%^QRpb;H5SR@Qbf@Ar{5)2&d_D_R{ej%bYW zW8~;lzN3n+t)g-yHGA@uXcJhT3ivb|WJB0_RrKW-#Np^!@*~ ziQJ>{GK{nUh6CLZhGA5h6U};$X+;!~*IPgbcO3rcM;$XV`o7D%y#P+2@naZj{f#lo z+JbUMpicO#77mtm7UCla%087I&3CHF?v+jxfgCsEaA?G}OCk<6v4~C+J+0IA6H{I( zKtQO7!=N{=WE}w$?qU{H&L#$4)S_k|Zhqo^xT4l=?)+@f-20wf@=t<6QAFvIj=qSi@)8x4-`< zu~f`D jrsEjE<-AE*ChBNjkK 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

    Ip~kIC{zDmYX%1-s>4f32fu?_ua`yrng<4Djfc6 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 z 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�m8g{08lz51?pv;x=Oi&kDgUT#XGV${LmF+y zEBYp9<6G*d-l!8pyxuzg3dyK|M+Fy))q0JoiE9>WAe1E|IST@9S)0h;T1gu{9vL&F zpeZY-p2ad{Pt2>x>&M7c@lhM4UgFBQrn0uB0`)zT(mNZjz0AnBFLwmzy}*~q{s8Ys zG9}vi8>DBqVwi4bGmkG(K)JtvX1j9h3O5voF(rco0q>0Qv*p5sRJh8a3;d48u&uDx ztQfpfaXy4z6@!5Mn2*uk%-Z84?mIomnB()HEk0j=g$sekT`{f5*L(rGe~xzVnFt^i z9JFpX#(Tp)V^15Ail2gvCs}85d8Lb8eGfh!-#2D3UcfxtnSk!)+m$yBAfi6C-*96R zUAj8~!h7dXZUjzVf0g4>J+xWCPFjF|EVv9+DJ95o zZf*U^pDO=}Yl+Rr?pF2}N9i^{rO3aztnd4hk2(1?Z^t~l0v&5F-Fnlr0{}Z6g`S6) zAnX9=U%0D;o87p?Qz-8Vrb!DQLA3zjsiVC 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%0DbST92Bm<;vA`woDV`%cZ>9ad+&2l=SAxH3C5rN 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 z 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∾?A4$`Yok=EZ(3PP#8` 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 z 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

  • From f4f74977240749e0e61b477d44fc26c19907bfba Mon Sep 17 00:00:00 2001 From: Viktoriya Totalova Date: Wed, 4 Mar 2026 14:59:08 +0100 Subject: [PATCH 29/57] fix issues --- server/docker/keycloak/memo-realm.json | 10 ++-------- src/components/ProtectedRoute.tsx | 7 +++++-- src/contexts/AuthContext.tsx | 24 +++++++++++++++--------- src/pages/LoginPage.tsx | 4 +++- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/server/docker/keycloak/memo-realm.json b/server/docker/keycloak/memo-realm.json index 4643333..15b2c41 100644 --- a/server/docker/keycloak/memo-realm.json +++ b/server/docker/keycloak/memo-realm.json @@ -14,14 +14,8 @@ "clientId": "memo-client", "enabled": true, "publicClient": true, - "redirectUris": [ - "http://localhost:3000/*", - "http://localhost:5173/*" - ], - "webOrigins": [ - "http://localhost:3000", - "http://localhost:5173" - ], + "redirectUris": ["http://localhost:3000/*", "http://localhost:5173/*"], + "webOrigins": ["http://localhost:3000", "http://localhost:5173"], "directAccessGrantsEnabled": true, "standardFlowEnabled": true, "implicitFlowEnabled": false, diff --git a/src/components/ProtectedRoute.tsx b/src/components/ProtectedRoute.tsx index 365e2fa..ec8df80 100644 --- a/src/components/ProtectedRoute.tsx +++ b/src/components/ProtectedRoute.tsx @@ -23,9 +23,12 @@ export function ProtectedRoute() {
    -

    Access denied

    +

    + Access denied +

    - Your email domain is not permitted. Please use a university email address. + Your email domain is not permitted. Please use a university email + address.

    diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx index 16121a6..ab3da9d 100644 --- a/src/contexts/AuthContext.tsx +++ b/src/contexts/AuthContext.tsx @@ -41,17 +41,15 @@ export function AuthProvider({ children }: { children: ReactNode }) { await syncUser(); } }) - .catch(console.error) + .catch(() => {}) .finally(() => setIsLoading(false)); keycloak.onTokenExpired = () => { - keycloak - .updateToken(60) - .catch(() => { - setIsAuthenticated(false); - setUserId(null); - setRole(null); - }); + keycloak.updateToken(60).catch(() => { + setIsAuthenticated(false); + setUserId(null); + setRole(null); + }); }; }, []); @@ -88,7 +86,15 @@ export function AuthProvider({ children }: { children: ReactNode }) { return ( {children} diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx index ff833a4..77cbacc 100644 --- a/src/pages/LoginPage.tsx +++ b/src/pages/LoginPage.tsx @@ -26,7 +26,9 @@ export function LoginPage() {
    -

    Sign in to Memo

    +

    + Sign in to Memo +

    Use your university email address to continue

    From 7303eeaca953657026d7d6cffce19f2a919b406a Mon Sep 17 00:00:00 2001 From: Viktoriya Totalova Date: Wed, 4 Mar 2026 15:32:30 +0100 Subject: [PATCH 30/57] fix issues --- postcss.config.mjs | 5 -- server/docker/keycloak/memo-realm.json | 18 +++- .../keycloak/test-university-realm.json | 84 ------------------- server/scripts/configure-keycloak.sh | 46 ---------- server/scripts/register-dfn-aai.sh | 73 ---------------- .../cit/memo/controller/AuthController.java | 2 +- server/src/main/resources/application.yml | 1 - src/contexts/AuthContext.tsx | 2 - src/lib/api/client.ts | 2 +- src/lib/api/session-helpers.ts | 15 ++-- src/pages/SessionPage.tsx | 4 +- 11 files changed, 29 insertions(+), 223 deletions(-) delete mode 100644 postcss.config.mjs delete mode 100644 server/docker/keycloak/test-university-realm.json delete mode 100755 server/scripts/configure-keycloak.sh delete mode 100755 server/scripts/register-dfn-aai.sh diff --git a/postcss.config.mjs b/postcss.config.mjs deleted file mode 100644 index ba720fe..0000000 --- a/postcss.config.mjs +++ /dev/null @@ -1,5 +0,0 @@ -const config = { - plugins: ['@tailwindcss/postcss'], -}; - -export default config; diff --git a/server/docker/keycloak/memo-realm.json b/server/docker/keycloak/memo-realm.json index 15b2c41..17bf7e9 100644 --- a/server/docker/keycloak/memo-realm.json +++ b/server/docker/keycloak/memo-realm.json @@ -23,7 +23,23 @@ "attributes": { "access.token.lifespan": "3600", "post.logout.redirect.uris": "+" - } + }, + "protocolMappers": [ + { + "name": "email", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "true", + "user.attribute": "email", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email", + "jsonType.label": "String" + } + } + ] } ], "roles": { diff --git a/server/docker/keycloak/test-university-realm.json b/server/docker/keycloak/test-university-realm.json deleted file mode 100644 index 285f222..0000000 --- a/server/docker/keycloak/test-university-realm.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "id": "test-university", - "realm": "test-university", - "enabled": true, - "sslRequired": "none", - "registrationAllowed": false, - "loginWithEmailAllowed": true, - "duplicateEmailsAllowed": false, - "bruteForceProtected": false, - "displayName": "Test University IdP (Dev)", - "clients": [ - { - "clientId": "http://localhost:8081/realms/memo", - "name": "Memo Application (SP)", - "enabled": true, - "protocol": "saml", - "publicClient": false, - "frontchannelLogout": true, - "attributes": { - "saml.authnstatement": "true", - "saml.server.signature": "true", - "saml.assertion.signature": "true", - "saml_force_name_id_format": "true", - "saml.force.post.binding": "true", - "saml.client.signature": "false", - "saml_name_id_format": "persistent", - "saml.signing.certificate": "" - }, - "redirectUris": [ - "http://localhost:8081/realms/memo/broker/test-university/endpoint*" - ], - "adminUrl": "http://localhost:8081/realms/memo/broker/test-university/endpoint", - "baseUrl": "http://localhost:3000", - "protocolMappers": [ - { - "name": "username", - "protocol": "saml", - "protocolMapper": "saml-user-property-mapper", - "consentRequired": false, - "config": { - "attribute.nameformat": "Basic", - "user.attribute": "username", - "attribute.name": "username" - } - } - ] - } - ], - "users": [ - { - "username": "student", - "enabled": true, - "credentials": [ - { - "type": "password", - "value": "student123", - "temporary": false - } - ] - }, - { - "username": "demo", - "enabled": true, - "credentials": [ - { - "type": "password", - "value": "demo", - "temporary": false - } - ] - }, - { - "username": "admin", - "enabled": true, - "credentials": [ - { - "type": "password", - "value": "admin", - "temporary": false - } - ] - } - ] -} diff --git a/server/scripts/configure-keycloak.sh b/server/scripts/configure-keycloak.sh deleted file mode 100755 index f6dea26..0000000 --- a/server/scripts/configure-keycloak.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash -# Configures the memo Keycloak realm after startup: -# - Disables "Review Profile" in the First Broker Login flow -# so university SSO users are created silently with no profile prompt - -set -e - -KEYCLOAK_URL="${KEYCLOAK_URL:-http://localhost:8081}" -REALM="memo" - -echo "Waiting for Keycloak to be ready..." -until curl -sf "$KEYCLOAK_URL/realms/memo" > /dev/null 2>&1; do - sleep 2 -done - -echo "Getting admin token..." -TOKEN=$(curl -sf -X POST "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token" \ - -H "Content-Type: application/x-www-form-urlencoded" \ - -d "username=admin&password=admin&grant_type=password&client_id=admin-cli" \ - | grep -o '"access_token":"[^"]*"' | cut -d'"' -f4) - -if [ -z "$TOKEN" ]; then - echo "ERROR: Failed to get admin token" - exit 1 -fi - -echo "Fetching First Broker Login flow executions..." -EXECUTIONS=$(curl -sf "$KEYCLOAK_URL/admin/realms/$REALM/authentication/flows/first%20broker%20login/executions" \ - -H "Authorization: Bearer $TOKEN") - -# Extract the Review Profile execution id and current requirement -REVIEW_ID=$(echo "$EXECUTIONS" | grep -o '"id":"[^"]*","requirement":"[^"]*","displayName":"Review Profile[^}]*' | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4) - -if [ -z "$REVIEW_ID" ]; then - echo "Could not find Review Profile execution — may already be disabled or flow differs." - exit 0 -fi - -echo "Disabling Review Profile (id: $REVIEW_ID)..." -curl -sf -X PUT "$KEYCLOAK_URL/admin/realms/$REALM/authentication/flows/first%20broker%20login/executions" \ - -H "Authorization: Bearer $TOKEN" \ - -H "Content-Type: application/json" \ - -d "{\"id\":\"$REVIEW_ID\",\"requirement\":\"DISABLED\"}" - -echo "" -echo "Done. Review Profile is now disabled — SSO users will be created silently." diff --git a/server/scripts/register-dfn-aai.sh b/server/scripts/register-dfn-aai.sh deleted file mode 100755 index b6db94d..0000000 --- a/server/scripts/register-dfn-aai.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash -# Outputs the Keycloak SAML SP metadata required for DFN-AAI registration. -# -# Usage (run from the server/ directory): -# KEYCLOAK_URL=https://your-production-keycloak.example.com ./scripts/register-dfn-aai.sh -# -# Or for local testing: -# ./scripts/register-dfn-aai.sh -# -# The generated SP metadata XML must be submitted to DFN-AAI via: -# https://www.aai.dfn.de/en/participants/sp-registration/ -# -# After DFN-AAI approves the registration and distributes the SP metadata to -# member universities, users from those universities will be able to log in. -# -# IMPORTANT: The Keycloak instance must be publicly reachable before registering. -# The ACS (Assertion Consumer Service) URL in the metadata will be based on -# the Keycloak URL — localhost URLs will not work in production. - -set -e - -KEYCLOAK_URL="${KEYCLOAK_URL:-http://localhost:8081}" -REALM="memo" -METADATA_URL="$KEYCLOAK_URL/realms/$REALM/protocol/saml/descriptor" - -echo "Fetching SAML SP metadata from:" -echo " $METADATA_URL" -echo "" - -if command -v curl &>/dev/null; then - curl -sf "$METADATA_URL" | xmllint --format - 2>/dev/null || curl -sf "$METADATA_URL" -elif command -v wget &>/dev/null; then - wget -qO- "$METADATA_URL" -else - echo "ERROR: curl or wget is required to fetch metadata." - exit 1 -fi - -echo "" -echo "--------------------------------------------------------------------" -echo "DFN-AAI SP Registration Steps:" -echo "" -echo "1. Deploy Keycloak to a publicly accessible server (e.g. https://auth.memo.example.com)" -echo "" -echo "2. Re-run this script with your production URL:" -echo " KEYCLOAK_URL=https://auth.memo.example.com ./scripts/register-dfn-aai.sh" -echo "" -echo "3. Save the XML output to a file: memo-sp-metadata.xml" -echo "" -echo "4. Register at https://www.aai.dfn.de/en/participants/sp-registration/" -echo " - Sign the SP participation agreement" -echo " - Upload memo-sp-metadata.xml via the Metadata Administration Tool" -echo " - Provide a security contact email" -echo "" -echo "5. After DFN approval (typically a few business days), update Keycloak:" -echo " a. Open the Keycloak Admin UI for each university IdP" -echo " b. Under Identity Providers → [university] → import the IdP metadata:" -echo " - TUM: https://tumidp.lrz.de/idp/shibboleth" -echo " - LMU: https://idp.lrz.de/idp/shibboleth" -echo " - RWTH: https://login.rz.rwth-aachen.de/shibboleth" -echo " - KIT: https://idp.scc.kit.edu/idp/shibboleth" -echo " - TU Berlin: https://ephraim.tu-berlin.de/shibboleth" -echo " - TU Dresden:https://idp.tu-dresden.de/idp/shibboleth" -echo " - (and so on for other universities)" -echo " c. Enable 'Validate Signatures' for each IdP once certs are imported" -echo "" -echo "6. Add more DFN-AAI universities by looking up their entityID at:" -echo " https://tools.aai.dfn.de/entities/" -echo " Then add them to memo-realm.json and LoginPage.tsx" -echo "" -echo "Full DFN-AAI documentation:" -echo " https://doku.tid.dfn.de/en:production" -echo "--------------------------------------------------------------------" diff --git a/server/src/main/java/de/tum/cit/memo/controller/AuthController.java b/server/src/main/java/de/tum/cit/memo/controller/AuthController.java index cec22b6..04fcf63 100644 --- a/server/src/main/java/de/tum/cit/memo/controller/AuthController.java +++ b/server/src/main/java/de/tum/cit/memo/controller/AuthController.java @@ -52,7 +52,7 @@ private static boolean isAllowedDomain(String email, List allowedDomains if (atIndex < 0) { return false; } - String domain = email.substring(atIndex + 1).toLowerCase(); + String domain = email.substring(atIndex + 1).toLowerCase(java.util.Locale.ROOT); return allowedDomains.contains(domain); } } diff --git a/server/src/main/resources/application.yml b/server/src/main/resources/application.yml index 52e9306..d02da65 100644 --- a/server/src/main/resources/application.yml +++ b/server/src/main/resources/application.yml @@ -100,7 +100,6 @@ memo: - student.uni-tuebingen.de # --- Universität Bonn --- - uni-bonn.de - - uni-bonn.de # --- Universität Münster --- - uni-muenster.de - uni-ms.de diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx index ab3da9d..456a8fa 100644 --- a/src/contexts/AuthContext.tsx +++ b/src/contexts/AuthContext.tsx @@ -1,5 +1,3 @@ -'use client'; - import { createContext, useContext, diff --git a/src/lib/api/client.ts b/src/lib/api/client.ts index 238abca..de9f76e 100644 --- a/src/lib/api/client.ts +++ b/src/lib/api/client.ts @@ -12,7 +12,7 @@ export const apiClient = axios.create({ apiClient.interceptors.request.use(async config => { if (keycloak.authenticated) { await keycloak.updateToken(30).catch(() => {}); - config.headers.Authorization = `Bearer ${keycloak.token}`; + config.headers.set('Authorization', `Bearer ${keycloak.token}`); } return config; }); diff --git a/src/lib/api/session-helpers.ts b/src/lib/api/session-helpers.ts index 20de3ce..b4969ae 100644 --- a/src/lib/api/session-helpers.ts +++ b/src/lib/api/session-helpers.ts @@ -18,19 +18,16 @@ import type { import type { RelationshipType } from '@/components/session/session-constants'; import { keycloak } from '../auth/keycloak'; -export async function getOrCreateDemoUserAction(): Promise<{ +export async function getCurrentUserAction(): Promise<{ success: boolean; - user?: { id: string; name: string }; + user?: { id: string; role: string }; error?: string; }> { try { const response = await apiClient.get<{ id: string; role: string }>( '/api/auth/me' ); - return { - success: true, - user: { id: response.data.id, name: '' }, - }; + return { success: true, user: response.data }; } catch (error) { return { success: false, @@ -168,7 +165,11 @@ export async function createCompetencyResourceLinkAction( const link = await competencyResourceLinksApi.create({ competencyId, resourceId, - userId: keycloak.tokenParsed?.sub ?? '', + userId: + keycloak.tokenParsed?.sub ?? + (() => { + throw new Error('User not authenticated'); + })(), matchType: matchType as | 'UNRELATED' | 'WEAK' diff --git a/src/pages/SessionPage.tsx b/src/pages/SessionPage.tsx index 1f20dd0..604e3cb 100644 --- a/src/pages/SessionPage.tsx +++ b/src/pages/SessionPage.tsx @@ -8,7 +8,7 @@ import { createCompetencyResourceLinkAction, deleteCompetencyResourceLinkAction, getRandomLearningResourceAction, - getOrCreateDemoUserAction, + getCurrentUserAction, } from '@/lib/api/session-helpers'; import type { Competency, LearningResource } from '@/lib/api/types'; import { @@ -148,7 +148,7 @@ export function SessionPage() { useEffect(() => { async function loadDemoUser() { try { - const result = await getOrCreateDemoUserAction(); + const result = await getCurrentUserAction(); if (result.success && result.user) { setUserId(result.user.id); } else { From 6f484047b4155d885da8b9ca627205df561cf613 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Wed, 4 Mar 2026 15:46:01 +0100 Subject: [PATCH 31/57] Fix package-lock.json --- package-lock.json | 50 +++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index 06a6b36..19ed4fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5366,9 +5366,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001774", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001774.tgz", - "integrity": "sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA==", + "version": "1.0.30001776", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001776.tgz", + "integrity": "sha512-sg01JDPzZ9jGshqKSckOQthXnYwOEP50jeVFhaSFbZcOy05TiuuaffDOfcwtCisJ9kNQuLBFibYywv2Bgm9osw==", "dev": true, "funding": [ { @@ -5579,16 +5579,16 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.302", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz", - "integrity": "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==", + "version": "1.5.307", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.307.tgz", + "integrity": "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg==", "dev": true, "license": "ISC" }, "node_modules/enhanced-resolve": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", - "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz", + "integrity": "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5970,9 +5970,9 @@ } }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.4.tgz", + "integrity": "sha512-3+mMldrTAPdta5kjX2G2J7iX4zxtnwpdA8Tr2ZSjkyPSanvbZAcy6flmtnXbEybHrDcU9641lxrMfFuUxVz9vA==", "dev": true, "license": "ISC" }, @@ -6013,12 +6013,12 @@ } }, "node_modules/framer-motion": { - "version": "12.34.3", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.34.3.tgz", - "integrity": "sha512-v81ecyZKYO/DfpTwHivqkxSUBzvceOpoI+wLfgCgoUIKxlFKEXdg0oR9imxwXumT4SFy8vRk9xzJ5l3/Du/55Q==", + "version": "12.35.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.35.0.tgz", + "integrity": "sha512-w8hghCMQ4oq10j6aZh3U2yeEQv5K69O/seDI/41PK4HtgkLrcBovUNc0ayBC3UyyU7V1mrY2yLzvYdWJX9pGZQ==", "license": "MIT", "dependencies": { - "motion-dom": "^12.34.3", + "motion-dom": "^12.35.0", "motion-utils": "^12.29.2", "tslib": "^2.4.0" }, @@ -6776,9 +6776,9 @@ } }, "node_modules/motion-dom": { - "version": "12.34.3", - "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.34.3.tgz", - "integrity": "sha512-sYgFe+pR9aIM7o4fhs2aXtOI+oqlUd33N9Yoxcgo1Fv7M20sRkHtCmzE/VRNIcq7uNJ+qio+Xubt1FXH3pQ+eQ==", + "version": "12.35.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.35.0.tgz", + "integrity": "sha512-FFMLEnIejK/zDABn+vqGVAUN4T0+3fw+cVAY8MMT65yR+j5uMuvWdd4npACWhh94OVWQs79CrBBuwOwGRZAQiA==", "license": "MIT", "dependencies": { "motion-utils": "^12.29.2" @@ -6824,9 +6824,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", "dev": true, "license": "MIT" }, @@ -6934,9 +6934,9 @@ } }, "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "dev": true, "funding": [ { From 305892f0731944f454a70a014965032c9e7e52c6 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Wed, 4 Mar 2026 15:48:25 +0100 Subject: [PATCH 32/57] Conform to Prettier formatting --- package-lock.json | 2181 +++++++++++---------------------------------- 1 file changed, 505 insertions(+), 1676 deletions(-) diff --git a/package-lock.json b/package-lock.json index 19ed4fc..8329095 100644 --- a/package-lock.json +++ b/package-lock.json @@ -342,795 +342,567 @@ "node": ">=6.9.0" } }, - "node_modules/@esbuild/aix-ppc64": { + "node_modules/@esbuild/darwin-arm64": { "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", "cpu": [ - "ppc64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "aix" + "darwin" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, "engines": { - "node": ">=18" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], "engines": { - "node": ">=18" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], + "node_modules/@eslint/eslintrc": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.4.tgz", + "integrity": "sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.3", + "strip-json-comments": "^3.1.1" + }, "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], "engines": { "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], + "node_modules/@eslint/js": { + "version": "9.39.3", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.3.tgz", + "integrity": "sha512-1B1VkCq6FuUNlQvlBYb+1jDu/gV297TIs/OeiaSR9l1H27SVW55ONE1e1Vp16NqP683+xEGzxYtv4XCiDPaQiw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, + "node_modules/@floating-ui/core": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", + "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@floating-ui/utils": "^0.2.11" } }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, + "node_modules/@floating-ui/dom": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", + "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@floating-ui/core": "^1.7.5", + "@floating-ui/utils": "^0.2.11" } }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", + "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==", "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@floating-ui/dom": "^1.7.6" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" } }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } + "node_modules/@floating-ui/utils": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", + "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", + "license": "MIT" }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": ">=18.18.0" } }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, "engines": { - "node": ">=18" + "node": ">=18.18.0" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], "engines": { - "node": ">=18" + "node": ">=6.0.0" } }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } + "license": "MIT" }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } + "node_modules/@radix-ui/number": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", + "license": "MIT" }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", - "dev": true, + "node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-accessible-icon": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accessible-icon/-/react-accessible-icon-1.1.7.tgz", + "integrity": "sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A==", "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, - "funding": { - "url": "https://opencollective.com/eslint" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", - "dev": true, + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", + "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", - "dev": true, - "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.2" + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collapsible": "1.1.12", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "license": "Apache-2.0", + "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.15" + "@radix-ui/react-slot": "1.2.3" }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.4.tgz", - "integrity": "sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ==", - "dev": true, + "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", "license": "MIT", "dependencies": { - "ajv": "^6.14.0", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", - "minimatch": "^3.1.3", - "strip-json-comments": "^3.1.1" + "@radix-ui/react-compose-refs": "1.1.2" }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, - "funding": { - "url": "https://opencollective.com/eslint" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, + "node_modules/@radix-ui/react-alert-dialog": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz", + "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==", "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dialog": "1.1.15", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@eslint/js": { - "version": "9.39.3", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.3.tgz", - "integrity": "sha512-1B1VkCq6FuUNlQvlBYb+1jDu/gV297TIs/OeiaSR9l1H27SVW55ONE1e1Vp16NqP683+xEGzxYtv4XCiDPaQiw==", - "dev": true, + "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "dependencies": { + "@radix-ui/react-slot": "1.2.3" }, - "funding": { - "url": "https://eslint.org/donate" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", - "dev": true, - "license": "Apache-2.0", + "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", "dependencies": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" + "@radix-ui/react-compose-refs": "1.1.2" }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@floating-ui/core": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", - "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.2.11" + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@floating-ui/dom": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", - "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", + "node_modules/@radix-ui/react-arrow/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", "license": "MIT", "dependencies": { - "@floating-ui/core": "^1.7.5", - "@floating-ui/utils": "^0.2.11" + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@floating-ui/react-dom": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", - "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==", + "node_modules/@radix-ui/react-arrow/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", "license": "MIT", "dependencies": { - "@floating-ui/dom": "^1.7.6" + "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@floating-ui/utils": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", - "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", - "license": "MIT" - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.4.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@radix-ui/number": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", - "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", - "license": "MIT" - }, - "node_modules/@radix-ui/primitive": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", - "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", - "license": "MIT" - }, - "node_modules/@radix-ui/react-accessible-icon": { + "node_modules/@radix-ui/react-aspect-ratio": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-accessible-icon/-/react-accessible-icon-1.1.7.tgz", - "integrity": "sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-visually-hidden": "1.2.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-accordion": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", - "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.7.tgz", + "integrity": "sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collapsible": "1.1.12", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -1147,7 +919,7 @@ } } }, - "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-primitive": { + "node_modules/@radix-ui/react-aspect-ratio/node_modules/@radix-ui/react-primitive": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", @@ -1170,7 +942,7 @@ } } }, - "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-slot": { + "node_modules/@radix-ui/react-aspect-ratio/node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", @@ -1188,18 +960,17 @@ } } }, - "node_modules/@radix-ui/react-alert-dialog": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz", - "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==", + "node_modules/@radix-ui/react-avatar": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz", + "integrity": "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3" + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-is-hydrated": "0.1.0", + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1216,7 +987,7 @@ } } }, - "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-primitive": { + "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-primitive": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", @@ -1239,7 +1010,7 @@ } } }, - "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-slot": { + "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", @@ -1257,13 +1028,20 @@ } } }, - "node_modules/@radix-ui/react-arrow": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", - "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "node_modules/@radix-ui/react-checkbox": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", + "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1280,7 +1058,7 @@ } } }, - "node_modules/@radix-ui/react-arrow/node_modules/@radix-ui/react-primitive": { + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-primitive": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", @@ -1303,7 +1081,7 @@ } } }, - "node_modules/@radix-ui/react-arrow/node_modules/@radix-ui/react-slot": { + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", @@ -1321,13 +1099,20 @@ } } }, - "node_modules/@radix-ui/react-aspect-ratio": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.7.tgz", - "integrity": "sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==", + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", + "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1344,7 +1129,7 @@ } } }, - "node_modules/@radix-ui/react-aspect-ratio/node_modules/@radix-ui/react-primitive": { + "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-primitive": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", @@ -1367,7 +1152,7 @@ } } }, - "node_modules/@radix-ui/react-aspect-ratio/node_modules/@radix-ui/react-slot": { + "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", @@ -1385,17 +1170,16 @@ } } }, - "node_modules/@radix-ui/react-avatar": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz", - "integrity": "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==", + "node_modules/@radix-ui/react-collection": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", "license": "MIT", "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-is-hydrated": "0.1.0", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -1412,7 +1196,7 @@ } } }, - "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-primitive": { + "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-primitive": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", @@ -1435,7 +1219,7 @@ } } }, - "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-slot": { + "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", @@ -1453,223 +1237,14 @@ } } }, - "node_modules/@radix-ui/react-checkbox": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", - "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-use-size": "1.1.1" - }, "peerDependencies": { "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-primitive": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-slot": "1.2.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-collapsible": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", - "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-primitive": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-slot": "1.2.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-collection": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", - "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-primitive": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-slot": "1.2.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", - "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -4149,626 +3724,90 @@ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/rect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", - "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", - "license": "MIT" - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.27", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", - "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", - "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", - "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", - "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", - "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", - "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", - "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", - "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", - "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", - "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", - "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", - "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", - "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", - "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", - "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", - "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", - "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", - "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", - "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", - "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", - "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", - "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", - "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", - "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", - "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", - "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@tailwindcss/node": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", - "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/remapping": "^2.3.5", - "enhanced-resolve": "^5.19.0", - "jiti": "^2.6.1", - "lightningcss": "1.31.1", - "magic-string": "^0.30.21", - "source-map-js": "^1.2.1", - "tailwindcss": "4.2.1" - } - }, - "node_modules/@tailwindcss/oxide": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz", - "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 20" - }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.2.1", - "@tailwindcss/oxide-darwin-arm64": "4.2.1", - "@tailwindcss/oxide-darwin-x64": "4.2.1", - "@tailwindcss/oxide-freebsd-x64": "4.2.1", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", - "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", - "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", - "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", - "@tailwindcss/oxide-linux-x64-musl": "4.2.1", - "@tailwindcss/oxide-wasm32-wasi": "4.2.1", - "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", - "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" - } - }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz", - "integrity": "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", - "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz", - "integrity": "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz", - "integrity": "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz", - "integrity": "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz", - "integrity": "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" + "@types/react": { + "optional": true + } } }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz", - "integrity": "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } + "node_modules/@radix-ui/rect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", + "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", + "license": "MIT" }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz", - "integrity": "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==", - "cpu": [ - "x64" - ], + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } + "license": "MIT" }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz", - "integrity": "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==", + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } + "darwin" + ] }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "node_modules/@tailwindcss/node": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz", - "integrity": "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==", - "bundleDependencies": [ - "@napi-rs/wasm-runtime", - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util", - "@emnapi/wasi-threads", - "tslib" - ], - "cpu": [ - "wasm32" - ], + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", + "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "@emnapi/core": "^1.8.1", - "@emnapi/runtime": "^1.8.1", - "@emnapi/wasi-threads": "^1.1.0", - "@napi-rs/wasm-runtime": "^1.1.1", - "@tybys/wasm-util": "^0.10.1", - "tslib": "^2.8.1" - }, - "engines": { - "node": ">=14.0.0" + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.19.0", + "jiti": "^2.6.1", + "lightningcss": "1.31.1", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.2.1" } }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "node_modules/@tailwindcss/oxide": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz", - "integrity": "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==", - "cpu": [ - "arm64" - ], + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz", + "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], "engines": { "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-x64": "4.2.1", + "@tailwindcss/oxide-freebsd-x64": "4.2.1", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-x64-musl": "4.2.1", + "@tailwindcss/oxide-wasm32-wasi": "4.2.1", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" } }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "node_modules/@tailwindcss/oxide-darwin-arm64": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz", - "integrity": "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", + "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "darwin" ], "engines": { "node": ">= 20" @@ -6420,27 +5459,6 @@ "lightningcss-win32-x64-msvc": "1.31.1" } }, - "node_modules/lightningcss-android-arm64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", - "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/lightningcss-darwin-arm64": { "version": "1.31.1", "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", @@ -6462,195 +5480,6 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", - "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", - "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", - "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", - "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", - "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", - "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", - "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", - "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", - "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", From 44e8467f97851b723b8681bd5ddb0f78525d7a3c Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Wed, 4 Mar 2026 15:51:25 +0100 Subject: [PATCH 33/57] Fix package-lock.json --- package-lock.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index adea1ab..b7b0a6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4745,6 +4745,7 @@ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", "license": "MIT" + }, "node_modules/devlop": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", @@ -5953,10 +5954,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/motion-dom": { - "version": "12.35.0", - "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.35.0.tgz", - "integrity": "sha512-FFMLEnIejK/zDABn+vqGVAUN4T0+3fw+cVAY8MMT65yR+j5uMuvWdd4npACWhh94OVWQs79CrBBuwOwGRZAQiA==", "node_modules/mdast-util-to-markdown": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", @@ -7063,6 +7060,8 @@ "@types/react": { "optional": true } + } + }, "node_modules/remark-parse": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", @@ -7635,6 +7634,8 @@ "license": "MIT", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/vfile": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", From 0cb944d7ef899e8deb489299f4dc7237ded7a55a Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Wed, 4 Mar 2026 16:02:45 +0100 Subject: [PATCH 34/57] Fix package-lock.json --- package-lock.json | 2182 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 1678 insertions(+), 504 deletions(-) diff --git a/package-lock.json b/package-lock.json index b7b0a6f..c7db927 100644 --- a/package-lock.json +++ b/package-lock.json @@ -343,574 +343,771 @@ "node": ">=6.9.0" } }, - "node_modules/@esbuild/darwin-arm64": { + "node_modules/@esbuild/aix-ppc64": { "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", "cpu": [ - "arm64" + "ppc64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "darwin" + "aix" ], "engines": { "node": ">=18" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "node": ">=18" } }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=18" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=18" } }, - "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.4.tgz", - "integrity": "sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ajv": "^6.14.0", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", - "minimatch": "^3.1.3", - "strip-json-comments": "^3.1.1" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/js": { - "version": "9.39.3", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.3.tgz", - "integrity": "sha512-1B1VkCq6FuUNlQvlBYb+1jDu/gV297TIs/OeiaSR9l1H27SVW55ONE1e1Vp16NqP683+xEGzxYtv4XCiDPaQiw==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" + "node": ">=18" } }, - "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@floating-ui/core": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", - "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@floating-ui/utils": "^0.2.11" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@floating-ui/dom": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", - "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@floating-ui/core": "^1.7.5", - "@floating-ui/utils": "^0.2.11" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@floating-ui/react-dom": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", - "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@floating-ui/dom": "^1.7.6" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@floating-ui/utils": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", - "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", - "license": "MIT" - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18.18.0" + "node": ">=18" } }, - "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.4.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18.18.0" + "node": ">=18" } }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=18" } }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=18" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], "engines": { - "node": ">=6.0.0" + "node": ">=18" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@radix-ui/number": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", - "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", - "license": "MIT" - }, - "node_modules/@radix-ui/primitive": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", - "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", - "license": "MIT" - }, - "node_modules/@radix-ui/react-accessible-icon": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-accessible-icon/-/react-accessible-icon-1.1.7.tgz", - "integrity": "sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A==", + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@radix-ui/react-visually-hidden": "1.2.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@radix-ui/react-accordion": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", - "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collapsible": "1.1.12", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-primitive": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.2.3" + "eslint-visitor-keys": "^3.4.3" }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@radix-ui/react-alert-dialog": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz", - "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==", - "license": "MIT", + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dialog": "1.1.15", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3" + "@eslint/core": "^0.17.0" }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-primitive": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "node_modules/@eslint/eslintrc": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.4.tgz", + "integrity": "sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ==", + "dev": true, "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.2.3" + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.3", + "strip-json-comments": "^3.1.1" }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "engines": { + "node": ">=18" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@radix-ui/react-arrow": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", - "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "node_modules/@eslint/js": { + "version": "9.39.3", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.3.tgz", + "integrity": "sha512-1B1VkCq6FuUNlQvlBYb+1jDu/gV297TIs/OeiaSR9l1H27SVW55ONE1e1Vp16NqP683+xEGzxYtv4XCiDPaQiw==", + "dev": true, "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@radix-ui/react-arrow/node_modules/@radix-ui/react-primitive": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "node_modules/@floating-ui/core": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", + "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.2.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "@floating-ui/utils": "^0.2.11" } }, - "node_modules/@radix-ui/react-arrow/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "node_modules/@floating-ui/dom": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", + "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "@floating-ui/core": "^1.7.5", + "@floating-ui/utils": "^0.2.11" } }, - "node_modules/@radix-ui/react-aspect-ratio": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.7.tgz", - "integrity": "sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==", + "node_modules/@floating-ui/react-dom": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", + "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@floating-ui/dom": "^1.7.6" }, "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", + "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", + "license": "MIT" + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@radix-ui/number": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", + "license": "MIT" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-accessible-icon": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accessible-icon/-/react-accessible-icon-1.1.7.tgz", + "integrity": "sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, "peerDependenciesMeta": { "@types/react": { "optional": true @@ -920,7 +1117,38 @@ } } }, - "node_modules/@radix-ui/react-aspect-ratio/node_modules/@radix-ui/react-primitive": { + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", + "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collapsible": "1.1.12", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-primitive": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", @@ -943,7 +1171,7 @@ } } }, - "node_modules/@radix-ui/react-aspect-ratio/node_modules/@radix-ui/react-slot": { + "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", @@ -961,17 +1189,18 @@ } } }, - "node_modules/@radix-ui/react-avatar": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz", - "integrity": "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==", + "node_modules/@radix-ui/react-alert-dialog": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz", + "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==", "license": "MIT", "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-is-hydrated": "0.1.0", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -988,7 +1217,7 @@ } } }, - "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-primitive": { + "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-primitive": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", @@ -1011,7 +1240,7 @@ } } }, - "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-slot": { + "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", @@ -1029,20 +1258,13 @@ } } }, - "node_modules/@radix-ui/react-checkbox": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", - "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-use-size": "1.1.1" + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -1059,7 +1281,7 @@ } } }, - "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-primitive": { + "node_modules/@radix-ui/react-arrow/node_modules/@radix-ui/react-primitive": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", @@ -1082,7 +1304,7 @@ } } }, - "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-slot": { + "node_modules/@radix-ui/react-arrow/node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", @@ -1100,20 +1322,13 @@ } } }, - "node_modules/@radix-ui/react-collapsible": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", - "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", + "node_modules/@radix-ui/react-aspect-ratio": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.7.tgz", + "integrity": "sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -1130,7 +1345,7 @@ } } }, - "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-primitive": { + "node_modules/@radix-ui/react-aspect-ratio/node_modules/@radix-ui/react-primitive": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", @@ -1153,7 +1368,7 @@ } } }, - "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-slot": { + "node_modules/@radix-ui/react-aspect-ratio/node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", @@ -1171,16 +1386,17 @@ } } }, - "node_modules/@radix-ui/react-collection": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", - "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "node_modules/@radix-ui/react-avatar": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz", + "integrity": "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3" + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-is-hydrated": "0.1.0", + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1197,7 +1413,7 @@ } } }, - "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-primitive": { + "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-primitive": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", @@ -1220,7 +1436,7 @@ } } }, - "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": { + "node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", @@ -1238,11 +1454,220 @@ } } }, - "node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", - "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", - "license": "MIT", + "node_modules/@radix-ui/react-checkbox": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", + "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", + "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -3741,12 +4166,504 @@ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", "dev": true, - "license": "MIT" + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tailwindcss/node": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", + "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.19.0", + "jiti": "^2.6.1", + "lightningcss": "1.31.1", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.2.1" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz", + "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-x64": "4.2.1", + "@tailwindcss/oxide-freebsd-x64": "4.2.1", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-x64-musl": "4.2.1", + "@tailwindcss/oxide-wasm32-wasi": "4.2.1", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz", + "integrity": "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", + "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz", + "integrity": "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz", + "integrity": "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz", + "integrity": "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz", + "integrity": "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", - "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz", + "integrity": "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==", "cpu": [ "arm64" ], @@ -3754,53 +4671,80 @@ "license": "MIT", "optional": true, "os": [ - "darwin" - ] + "linux" + ], + "engines": { + "node": ">= 20" + } }, - "node_modules/@tailwindcss/node": { + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", - "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz", + "integrity": "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@jridgewell/remapping": "^2.3.5", - "enhanced-resolve": "^5.19.0", - "jiti": "^2.6.1", - "lightningcss": "1.31.1", - "magic-string": "^0.30.21", - "source-map-js": "^1.2.1", - "tailwindcss": "4.2.1" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" } }, - "node_modules/@tailwindcss/oxide": { + "node_modules/@tailwindcss/oxide-linux-x64-musl": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz", - "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz", + "integrity": "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz", + "integrity": "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.8.1", + "@emnapi/runtime": "^1.8.1", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.1", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.8.1" }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.2.1", - "@tailwindcss/oxide-darwin-arm64": "4.2.1", - "@tailwindcss/oxide-darwin-x64": "4.2.1", - "@tailwindcss/oxide-freebsd-x64": "4.2.1", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", - "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", - "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", - "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", - "@tailwindcss/oxide-linux-x64-musl": "4.2.1", - "@tailwindcss/oxide-wasm32-wasi": "4.2.1", - "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", - "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", - "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz", + "integrity": "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==", "cpu": [ "arm64" ], @@ -3808,7 +4752,24 @@ "license": "MIT", "optional": true, "os": [ - "darwin" + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz", + "integrity": "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" ], "engines": { "node": ">= 20" @@ -3968,6 +4929,7 @@ "version": "19.2.14", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "dev": true, "license": "MIT", "dependencies": { "csstype": "^3.2.2" @@ -3977,7 +4939,7 @@ "version": "19.2.3", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "devOptional": true, + "dev": true, "license": "MIT", "peerDependencies": { "@types/react": "^19.2.0" @@ -4673,6 +5635,7 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, "license": "MIT" }, "node_modules/debug": { @@ -5743,6 +6706,27 @@ "lightningcss-win32-x64-msvc": "1.31.1" } }, + "node_modules/lightningcss-android-arm64": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", + "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/lightningcss-darwin-arm64": { "version": "1.31.1", "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", @@ -5764,6 +6748,195 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", + "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", + "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", + "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", + "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", + "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", + "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", + "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", + "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", + "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -7316,6 +8489,7 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz", "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", + "dev": true, "license": "MIT" }, "node_modules/tapable": { From 3d6d590a0b44dfffcb2cee6d9f68a3f48ff53c59 Mon Sep 17 00:00:00 2001 From: Viktoriya Totalova Date: Wed, 4 Mar 2026 16:36:29 +0100 Subject: [PATCH 35/57] fix merging of main issues --- .../de/tum/cit/memo/service/ContributorStatsService.java | 1 + ...k_auth.sql => V9__update_users_for_keycloak_auth.sql} | 4 ++-- src/App.tsx | 2 ++ src/pages/DashboardPage.tsx | 9 +++++---- 4 files changed, 10 insertions(+), 6 deletions(-) rename server/src/main/resources/db/migration/{V8__update_users_for_keycloak_auth.sql => V9__update_users_for_keycloak_auth.sql} (80%) diff --git a/server/src/main/java/de/tum/cit/memo/service/ContributorStatsService.java b/server/src/main/java/de/tum/cit/memo/service/ContributorStatsService.java index 8108ad2..d91dcbd 100644 --- a/server/src/main/java/de/tum/cit/memo/service/ContributorStatsService.java +++ b/server/src/main/java/de/tum/cit/memo/service/ContributorStatsService.java @@ -36,6 +36,7 @@ public ContributorStatsResponse getStats(String userId) { // pre-window total List rawCounts = voteRepository.findDailyVoteCountsWithPreWindowTotal(userId, sinceInstant); + Map countMap = new LinkedHashMap<>(); long windowVotes = 0; long preWindowVotes = 0; for (DailyVoteCount row : rawCounts) { diff --git a/server/src/main/resources/db/migration/V8__update_users_for_keycloak_auth.sql b/server/src/main/resources/db/migration/V9__update_users_for_keycloak_auth.sql similarity index 80% rename from server/src/main/resources/db/migration/V8__update_users_for_keycloak_auth.sql rename to server/src/main/resources/db/migration/V9__update_users_for_keycloak_auth.sql index 074fbf4..eeb24e5 100644 --- a/server/src/main/resources/db/migration/V8__update_users_for_keycloak_auth.sql +++ b/server/src/main/resources/db/migration/V9__update_users_for_keycloak_auth.sql @@ -5,9 +5,9 @@ ALTER TABLE users ALTER COLUMN email DROP NOT NULL; -- Extend id column to hold Keycloak UUID (36 chars) ALTER TABLE users ALTER COLUMN id TYPE VARCHAR(36); --- Replace the email unique index with a deferrable constraint (handles both index and constraint forms) -DROP INDEX IF EXISTS users_email_key CASCADE; +-- Replace the email unique constraint with a deferrable one ALTER TABLE users DROP CONSTRAINT IF EXISTS users_email_key; +DROP INDEX IF EXISTS users_email_key; ALTER TABLE users ADD CONSTRAINT users_email_key UNIQUE (email) DEFERRABLE INITIALLY DEFERRED; -- Extend user_id FK columns in related tables to also hold 36-char Keycloak UUIDs diff --git a/src/App.tsx b/src/App.tsx index 9d615a3..24f6053 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -36,6 +36,8 @@ export function App() { }> } /> } /> + } /> + } /> }> } /> } /> diff --git a/src/pages/DashboardPage.tsx b/src/pages/DashboardPage.tsx index 485c0c9..381051a 100644 --- a/src/pages/DashboardPage.tsx +++ b/src/pages/DashboardPage.tsx @@ -16,8 +16,7 @@ import { } from 'lucide-react'; import { ContributionHeatmap } from '@/components/dashboard/ContributionHeatmap'; import { heatmapColor } from '@/lib/heatmap-helpers'; - -const GUEST_USER_ID = 'guest'; +import { useAuth } from '@/contexts/AuthContext'; interface BadgeDef { id: string; @@ -166,15 +165,17 @@ function StatCard({ } export function DashboardPage() { + const { userId } = useAuth(); const [stats, setStats] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { + if (!userId) return; async function loadStats() { try { setLoading(true); - const data = await contributorStatsApi.getStats(GUEST_USER_ID); + const data = await contributorStatsApi.getStats(userId!); setStats(data); } catch (err) { setError( @@ -187,7 +188,7 @@ export function DashboardPage() { } } void loadStats(); - }, []); + }, [userId]); const earnedSet = useMemo( () => new Set(stats?.earnedBadges ?? []), From f05a8020a5aeaff7e4e997e5f5b3dcdf0ca47c83 Mon Sep 17 00:00:00 2001 From: Mark Stockhausen Date: Wed, 4 Mar 2026 17:34:53 +0100 Subject: [PATCH 36/57] Implement AI suggestions --- .../memo/controller/SchedulingController.java | 11 ++++ .../java/de/tum/cit/memo/dto/VoteRequest.java | 29 +++++---- .../CompetencyRelationshipVoteRepository.java | 3 + .../cit/memo/service/SchedulingService.java | 59 +++++++++++++++++-- .../onboarding/OnboardingPractice.tsx | 12 +++- src/lib/api/scheduling.ts | 7 +++ src/lib/api/session-helpers.ts | 13 ++-- src/pages/OnboardingPage.tsx | 11 +++- src/pages/SessionPage.tsx | 45 ++++++++------ 9 files changed, 143 insertions(+), 47 deletions(-) diff --git a/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java b/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java index 41a6a24..1da1718 100644 --- a/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java +++ b/server/src/main/java/de/tum/cit/memo/controller/SchedulingController.java @@ -9,7 +9,9 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; @@ -42,4 +44,13 @@ public ResponseEntity submitVote( VoteResponse response = schedulingService.submitVote(userId, request); return ResponseEntity.ok(response); } + + @DeleteMapping("/vote/{relationshipId}") + @Operation(summary = "Undo a vote on a relationship", description = "Removes the current user's vote from a relationship. Decrements vote counters and deletes the relationship if no votes remain.") + public ResponseEntity unvote( + @RequestHeader("X-User-Id") String userId, + @PathVariable String relationshipId) { + schedulingService.unvote(userId, relationshipId); + return ResponseEntity.noContent().build(); + } } diff --git a/server/src/main/java/de/tum/cit/memo/dto/VoteRequest.java b/server/src/main/java/de/tum/cit/memo/dto/VoteRequest.java index 025a74e..27d4d6b 100644 --- a/server/src/main/java/de/tum/cit/memo/dto/VoteRequest.java +++ b/server/src/main/java/de/tum/cit/memo/dto/VoteRequest.java @@ -1,8 +1,9 @@ package de.tum.cit.memo.dto; -import io.swagger.v3.oas.annotations.media.Schema; +import com.fasterxml.jackson.annotation.JsonIgnore; import de.tum.cit.memo.enums.RelationshipType; -import jakarta.validation.constraints.NotBlank; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.AssertTrue; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; @@ -15,20 +16,24 @@ @AllArgsConstructor public class VoteRequest { - /** - * Origin competency ID. - */ - @NotBlank(message = "originId is required") - @Schema(description = "Origin competency ID", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "Existing relationship ID (alternative to originId+destinationId)") + private String relationshipId; + + @Schema(description = "Origin competency ID (required if relationshipId is absent)") private String originId; - /** - * Destination competency ID. - */ - @NotBlank(message = "destinationId is required") - @Schema(description = "Destination competency ID", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "Destination competency ID (required if relationshipId is absent)") private String destinationId; @NotNull(message = "Relationship type is required") private RelationshipType relationshipType; + + @JsonIgnore + @AssertTrue(message = "Either relationshipId or both originId and destinationId must be provided") + private boolean isIdentifiable() { + boolean hasRelationshipId = relationshipId != null && !relationshipId.isBlank(); + boolean hasOriginAndDestination = originId != null && !originId.isBlank() + && destinationId != null && !destinationId.isBlank(); + return hasRelationshipId || hasOriginAndDestination; + } } diff --git a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipVoteRepository.java b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipVoteRepository.java index 00042bb..ac8579a 100644 --- a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipVoteRepository.java +++ b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRelationshipVoteRepository.java @@ -8,12 +8,15 @@ import java.time.Instant; import java.util.List; +import java.util.Optional; @Repository public interface CompetencyRelationshipVoteRepository extends JpaRepository { boolean existsByRelationshipIdAndUserId(String relationshipId, String userId); + Optional findByRelationshipIdAndUserId(String relationshipId, String userId); + @Query(value = """ SELECT CAST(v.created_at AS DATE) AS vote_date, COUNT(*) AS vote_count diff --git a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java index 430b06b..86f3e85 100644 --- a/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java +++ b/server/src/main/java/de/tum/cit/memo/service/SchedulingService.java @@ -85,13 +85,15 @@ public Optional getNextTask(String userId, List new ResourceNotFoundException( + "Relationship not found: " + request.getRelationshipId())); + } else { + rel = findOrCreateRelationship(request.getOriginId(), request.getDestinationId()); + } if (!recordVoteIfAbsent(rel.getId(), userId, request.getRelationshipType())) { log.debug("Duplicate vote ignored for user {} on {}", userId, rel.getId()); return toVoteResponse(rel); @@ -108,6 +110,51 @@ public VoteResponse submitVote(String userId, VoteRequest request) { return toVoteResponse(rel); } + @Transactional + public void unvote(String userId, String relationshipId) { + assertUserExists(userId); + + CompetencyRelationship rel = relationshipRepository.findById(relationshipId) + .orElseThrow(() -> new ResourceNotFoundException("Relationship not found: " + relationshipId)); + + CompetencyRelationshipVote vote = voteRepository.findByRelationshipIdAndUserId(relationshipId, userId) + .orElseThrow(() -> new ResourceNotFoundException( + "No vote found for user " + userId + " on relationship " + relationshipId)); + + voteRepository.delete(vote); + removeVote(rel, vote.getRelationshipType()); + + // If symmetric, also remove the mirrored vote on the reverse relationship + RelationshipType type = vote.getRelationshipType(); + if (type == RelationshipType.MATCHES || type == RelationshipType.UNRELATED) { + relationshipRepository.findByOriginIdAndDestinationId(rel.getDestinationId(), rel.getOriginId()) + .ifPresent(reverse -> { + voteRepository.findByRelationshipIdAndUserId(reverse.getId(), userId) + .ifPresent(mirrorVote -> { + voteRepository.delete(mirrorVote); + removeVote(reverse, mirrorVote.getRelationshipType()); + }); + }); + } + } + + private void removeVote(CompetencyRelationship rel, RelationshipType type) { + switch (type) { + case ASSUMES -> rel.setVoteAssumes(Math.max(0, rel.getVoteAssumes() - 1)); + case EXTENDS -> rel.setVoteExtends(Math.max(0, rel.getVoteExtends() - 1)); + case MATCHES -> rel.setVoteMatches(Math.max(0, rel.getVoteMatches() - 1)); + case UNRELATED -> rel.setVoteUnrelated(Math.max(0, rel.getVoteUnrelated() - 1)); + } + rel.recalculateEntropy(); + + if (rel.getTotalVotes() == 0) { + competencyRepository.decrementDegree(List.of(rel.getOriginId(), rel.getDestinationId())); + relationshipRepository.delete(rel); + } else { + relationshipRepository.save(rel); + } + } + private Optional coveragePipeline(String userId, List skippedIds) { List poolIds = getLowDegreeCompetencyIds(); if (poolIds.size() < 2) { diff --git a/src/components/onboarding/OnboardingPractice.tsx b/src/components/onboarding/OnboardingPractice.tsx index f7db291..b84e64e 100644 --- a/src/components/onboarding/OnboardingPractice.tsx +++ b/src/components/onboarding/OnboardingPractice.tsx @@ -113,6 +113,7 @@ const TUTORIAL_ROUNDS: TutorialRound[] = [ interface OnboardingPracticeProps { onComplete: () => void; onCorrectStateChange?: (isCorrect: boolean) => void; + onLastRoundChange?: (isLastRound: boolean) => void; } export interface OnboardingPracticeRef { @@ -123,7 +124,10 @@ export interface OnboardingPracticeRef { export const OnboardingPractice = forwardRef< OnboardingPracticeRef, OnboardingPracticeProps ->(function OnboardingPractice({ onComplete, onCorrectStateChange }, ref) { +>(function OnboardingPractice( + { onComplete, onCorrectStateChange, onLastRoundChange }, + ref +) { const [round, setRound] = useState(0); const [selectedRelation, setSelectedRelation] = useState(null); @@ -164,6 +168,12 @@ export const OnboardingPractice = forwardRef< } }, [isCorrect, onCorrectStateChange]); + useEffect(() => { + if (onLastRoundChange) { + onLastRoundChange(isLastRound); + } + }, [isLastRound, onLastRoundChange]); + function handleNext() { if (isLastRound) { onComplete(); diff --git a/src/lib/api/scheduling.ts b/src/lib/api/scheduling.ts index 9e3ff4e..07edaed 100644 --- a/src/lib/api/scheduling.ts +++ b/src/lib/api/scheduling.ts @@ -23,6 +23,7 @@ export interface RelationshipTask { } export interface VoteResponse { + relationshipId: string; success: boolean; updatedVotes: VoteCounts; newEntropy: number; @@ -69,4 +70,10 @@ export const schedulingApi = { ); return response.data; }, + + unvote: async (userId: string, relationshipId: string): Promise => { + await apiClient.delete(`/api/scheduling/vote/${relationshipId}`, { + headers: { 'X-User-Id': userId }, + }); + }, }; diff --git a/src/lib/api/session-helpers.ts b/src/lib/api/session-helpers.ts index de87347..220417a 100644 --- a/src/lib/api/session-helpers.ts +++ b/src/lib/api/session-helpers.ts @@ -3,7 +3,6 @@ */ import { competenciesApi } from './competencies'; -import { competencyRelationshipsApi } from './competency-relationships'; import { competencyResourceLinksApi } from './competency-resource-links'; import { learningResourcesApi } from './learning-resources'; import { schedulingApi } from './scheduling'; @@ -134,19 +133,17 @@ export async function getRandomLearningResourceAction(): Promise<{ } } -export async function deleteCompetencyRelationshipAction( - id: string +export async function unvoteAction( + userId: string, + relationshipId: string ): Promise<{ success: boolean; error?: string }> { try { - await competencyRelationshipsApi.delete(id); + await schedulingApi.unvote(userId, relationshipId); return { success: true }; } catch (error) { return { success: false, - error: - error instanceof Error - ? error.message - : 'Failed to delete relationship', + error: error instanceof Error ? error.message : 'Failed to undo vote', }; } } diff --git a/src/pages/OnboardingPage.tsx b/src/pages/OnboardingPage.tsx index 0b52732..1b67461 100644 --- a/src/pages/OnboardingPage.tsx +++ b/src/pages/OnboardingPage.tsx @@ -53,6 +53,7 @@ export function OnboardingPage() { const [consentChecked, setConsentChecked] = useState(false); const [practiceCompleted, setPracticeCompleted] = useState(false); const [currentPracticeCorrect, setCurrentPracticeCorrect] = useState(false); + const [isPracticeLastRound, setIsPracticeLastRound] = useState(false); const [selectedDegree, setSelectedDegree] = useState(null); const [fieldOfStudy, setFieldOfStudy] = useState(''); const practiceRef = useRef(null); @@ -166,6 +167,7 @@ export function OnboardingPage() { setStep(s => s + 1); }} onCorrectStateChange={setCurrentPracticeCorrect} + onLastRoundChange={setIsPracticeLastRound} completed={practiceCompleted} /> )} @@ -197,7 +199,7 @@ export function OnboardingPage() { className={`flex items-center gap-2 rounded-full bg-gradient-to-r from-[#0a4da2] to-[#5538d1] px-6 py-5 text-sm font-bold text-white shadow-[0_18px_45px_-26px_rgba(7,30,84,0.75)] transition-all hover:-translate-y-0.5 hover:shadow-[0_22px_55px_-28px_rgba(7,30,84,0.85)] disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:translate-y-0`} > {step === 3 && !practiceCompleted - ? practiceRef.current?.isLastRound + ? isPracticeLastRound ? 'Continue' : 'Next Round' : 'Continue'} @@ -569,9 +571,13 @@ const StepPractice = forwardRef< { onComplete: () => void; onCorrectStateChange: (isCorrect: boolean) => void; + onLastRoundChange: (isLastRound: boolean) => void; completed: boolean; } ->(function StepPractice({ onComplete, onCorrectStateChange, completed }, ref) { +>(function StepPractice( + { onComplete, onCorrectStateChange, onLastRoundChange, completed }, + ref +) { return (
    @@ -602,6 +608,7 @@ const StepPractice = forwardRef< ref={ref} onComplete={onComplete} onCorrectStateChange={onCorrectStateChange} + onLastRoundChange={onLastRoundChange} /> )}
    diff --git a/src/pages/SessionPage.tsx b/src/pages/SessionPage.tsx index 4a3ee0f..d8e0018 100644 --- a/src/pages/SessionPage.tsx +++ b/src/pages/SessionPage.tsx @@ -5,7 +5,7 @@ import { getRandomCompetenciesAction, getNextRelationshipTaskAction, submitCompetencyVoteAction, - deleteCompetencyRelationshipAction, + unvoteAction, createCompetencyResourceLinkAction, deleteCompetencyResourceLinkAction, getRandomLearningResourceAction, @@ -118,6 +118,8 @@ export function SessionPage() { learningResource?: LearningResource; }> >([]); + const historyRef = useRef(history); + historyRef.current = history; const [competencies, setCompetencies] = useState(null); const [learningResource, setLearningResource] = useState(null); @@ -128,7 +130,7 @@ export function SessionPage() { const [isTransitioning, setIsTransitioning] = useState(false); const [swapRotation, setSwapRotation] = useState(0); const [allDone, setAllDone] = useState(false); - const [_isSwapped, setIsSwapped] = useState(false); + const [isSwapped, setIsSwapped] = useState(false); const [currentRelationshipId, setCurrentRelationshipId] = useState< string | null >(null); @@ -247,7 +249,7 @@ export function SessionPage() { return; } - const skippedIds = history + const skippedIds = historyRef.current .filter( h => h.type === 'skipped' && @@ -339,7 +341,7 @@ export function SessionPage() { setIsTransitioning(false); }, - [mappingMode, userId, history] + [mappingMode, userId] ); const prevModeRef = useRef(null); @@ -376,11 +378,16 @@ export function SessionPage() { try { const startTime = Date.now(); - const voteOpts = { - relationshipId: currentRelationshipId ?? undefined, - originId: competencies[0]!.id, - destinationId: competencies[1]!.id, - }; + const voteOpts = isSwapped + ? { + originId: competencies[0]!.id, + destinationId: competencies[1]!.id, + } + : { + relationshipId: currentRelationshipId ?? undefined, + originId: competencies[0]!.id, + destinationId: competencies[1]!.id, + }; const result = await submitCompetencyVoteAction( userId, relation, @@ -409,7 +416,10 @@ export function SessionPage() { { type: 'completed', mode: 'competency', - relationshipId: currentRelationshipId ?? undefined, + relationshipId: + result.voteResponse?.relationshipId ?? + currentRelationshipId ?? + undefined, competencies: competencies ? [...competencies] : undefined, }, ]); @@ -530,6 +540,7 @@ export function SessionPage() { mappingMode, loadMappingPair, currentRelationshipId, + isSwapped, checkMilestones, ] ); @@ -581,23 +592,21 @@ export function SessionPage() { }, [history]); useEffect(() => { - if (relationshipToDelete) { - deleteCompetencyRelationshipAction(relationshipToDelete) + if (relationshipToDelete && userId) { + unvoteAction(userId, relationshipToDelete) .then(result => { if (!result.success) { - setError(result.error ?? 'Failed to delete relationship'); + setError(result.error ?? 'Failed to undo vote'); } }) - .catch(err => { - setError( - err instanceof Error ? err.message : 'Failed to delete relationship' - ); + .catch((err: unknown) => { + setError(err instanceof Error ? err.message : 'Failed to undo vote'); }) .finally(() => { setRelationshipToDelete(null); }); } - }, [relationshipToDelete]); + }, [relationshipToDelete, userId]); useEffect(() => { if (resourceLinkToDelete) { From 6b55740181ff45753174eae49e5fcc266a2721c6 Mon Sep 17 00:00:00 2001 From: Viktoriya Totalova Date: Wed, 4 Mar 2026 18:54:04 +0100 Subject: [PATCH 37/57] fix auth process after merging --- src/lib/api/session-helpers.ts | 2 ++ src/pages/OnboardingPage.tsx | 14 +++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/lib/api/session-helpers.ts b/src/lib/api/session-helpers.ts index 41cef61..90b0171 100644 --- a/src/lib/api/session-helpers.ts +++ b/src/lib/api/session-helpers.ts @@ -18,6 +18,8 @@ import type { } from './types'; import type { RelationshipType } from '@/components/session/session-constants'; +const GUEST_USER_ID = 'guest'; + export async function getCurrentUserAction(): Promise<{ success: boolean; user?: { id: string; role: string }; diff --git a/src/pages/OnboardingPage.tsx b/src/pages/OnboardingPage.tsx index a19ce57..61fc29a 100644 --- a/src/pages/OnboardingPage.tsx +++ b/src/pages/OnboardingPage.tsx @@ -51,7 +51,11 @@ const SESSION_DEGREE_KEY = 'onboarding-degree'; const SESSION_FIELD_KEY = 'onboarding-field'; export function OnboardingPage() { - const { isAuthenticated, isLoading: isAuthLoading, onboardingLogin } = useAuth(); + const { + isAuthenticated, + isLoading: isAuthLoading, + onboardingLogin, + } = useAuth(); const [step, setStep] = useState(0); const [direction, setDirection] = useState(1); const [consentChecked, setConsentChecked] = useState(false); @@ -125,7 +129,9 @@ export function OnboardingPage() { const canAdvance = step === 2 - ? isAuthenticated && selectedDegree !== null && fieldOfStudy.trim().length > 0 + ? isAuthenticated && + selectedDegree !== null && + fieldOfStudy.trim().length > 0 : step === 3 ? practiceCompleted || currentPracticeCorrect : step === 4 @@ -462,7 +468,9 @@ function StepProfile({ while keeping your data private.

    {isAuthLoading ? ( - Checking authentication… + + Checking authentication… + ) : isAuthenticated ? (
    From 15c09ab9f9d545cd0d7405d563e6b17499b5a6ab Mon Sep 17 00:00:00 2001 From: Viktoriya Totalova Date: Wed, 4 Mar 2026 19:54:05 +0100 Subject: [PATCH 38/57] implement auth in the onboarding flow --- src/App.tsx | 2 -- src/components/ProtectedRoute.tsx | 2 +- src/contexts/AuthContext.tsx | 17 +++++++++--- src/pages/HomePage.tsx | 28 ++++++++++++-------- src/pages/LoginPage.tsx | 44 ------------------------------- src/pages/OnboardingPage.tsx | 14 ++++++++-- 6 files changed, 44 insertions(+), 63 deletions(-) delete mode 100644 src/pages/LoginPage.tsx diff --git a/src/App.tsx b/src/App.tsx index 39c447a..b567793 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,7 +11,6 @@ import { OnboardingPage } from './pages/OnboardingPage'; import { ImprintPage } from './pages/ImprintPage'; import { PrivacyPage } from './pages/PrivacyPage'; import { DashboardPage } from './pages/DashboardPage'; -import { LoginPage } from './pages/LoginPage'; import { ProtectedRoute } from './components/ProtectedRoute'; import { AuthProvider } from './contexts/AuthContext'; @@ -34,7 +33,6 @@ export function App() { - } /> }> } /> } /> diff --git a/src/components/ProtectedRoute.tsx b/src/components/ProtectedRoute.tsx index ec8df80..5bdcc21 100644 --- a/src/components/ProtectedRoute.tsx +++ b/src/components/ProtectedRoute.tsx @@ -15,7 +15,7 @@ export function ProtectedRoute() { } if (!isAuthenticated) { - return ; + return ; } if (domainError) { diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx index 4ed2763..1a6236a 100644 --- a/src/contexts/AuthContext.tsx +++ b/src/contexts/AuthContext.tsx @@ -76,15 +76,26 @@ export function AuthProvider({ children }: { children: ReactNode }) { } function login() { - keycloak.login({ redirectUri: window.location.origin + '/session' }); + let onboarded = false; + try { + onboarded = !!localStorage.getItem('memo-onboarded'); + } catch { + /* ignore */ + } + keycloak.login({ + redirectUri: + window.location.origin + (onboarded ? '/session' : '/onboarding'), + }); } function onboardingLogin() { - keycloak.login({ redirectUri: window.location.origin + '/onboarding' }); + keycloak.login({ + redirectUri: window.location.origin + '/onboarding?step=2', + }); } function logout() { - keycloak.logout({ redirectUri: window.location.origin + '/login' }); + keycloak.logout({ redirectUri: window.location.origin + '/' }); } return ( diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index 4f2d2b8..28aa3e3 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -1,18 +1,11 @@ -import { Link } from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { CompetencyNetworkViz } from '@/components/competency-network/CompetencyNetworkViz'; +import { useAuth } from '@/contexts/AuthContext'; const ONBOARDED_KEY = 'memo-onboarded'; -function getStartHref(): string { - try { - return localStorage.getItem(ONBOARDED_KEY) ? '/session' : '/onboarding'; - } catch { - return '/onboarding'; - } -} - type ProblemStatement = { headline: string; insight: string; @@ -42,6 +35,19 @@ const problemStatements: ProblemStatement[] = [ const [leadProblem, ...otherProblems] = problemStatements; export function HomePage() { + const { isAuthenticated } = useAuth(); + const navigate = useNavigate(); + + function handleStartContributing() { + let onboarded = false; + try { + onboarded = !!localStorage.getItem(ONBOARDED_KEY); + } catch { + /* ignore */ + } + void navigate(isAuthenticated && onboarded ? '/session' : '/onboarding'); + } + return (
    @@ -65,10 +71,10 @@ export function HomePage() {
    diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx deleted file mode 100644 index 77cbacc..0000000 --- a/src/pages/LoginPage.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { useEffect } from 'react'; -import { useNavigate } from 'react-router-dom'; -import { useAuth } from '../contexts/AuthContext'; -import { Button } from '../components/ui/button'; -import { GraduationCap } from 'lucide-react'; - -export function LoginPage() { - const { isAuthenticated, isLoading, login } = useAuth(); - const navigate = useNavigate(); - - useEffect(() => { - if (!isLoading && isAuthenticated) { - navigate('/session', { replace: true }); - } - }, [isAuthenticated, isLoading, navigate]); - - if (isLoading) { - return ( -
    -

    Loading…

    -
    - ); - } - - return ( -
    -
    - -

    - Sign in to Memo -

    -

    - Use your university email address to continue -

    -
    - -
    - -
    -
    - ); -} diff --git a/src/pages/OnboardingPage.tsx b/src/pages/OnboardingPage.tsx index 61fc29a..78ec02b 100644 --- a/src/pages/OnboardingPage.tsx +++ b/src/pages/OnboardingPage.tsx @@ -56,7 +56,17 @@ export function OnboardingPage() { isLoading: isAuthLoading, onboardingLogin, } = useAuth(); - const [step, setStep] = useState(0); + const [step, setStep] = useState(() => { + try { + const s = parseInt( + new URLSearchParams(window.location.search).get('step') ?? '0', + 10 + ); + return isNaN(s) || s < 0 || s >= TOTAL_STEPS ? 0 : s; + } catch { + return 0; + } + }); const [direction, setDirection] = useState(1); const [consentChecked, setConsentChecked] = useState(false); const [practiceCompleted, setPracticeCompleted] = useState(false); @@ -482,7 +492,7 @@ function StepProfile({ onClick={onSignIn} className="flex w-full sm:w-auto self-start mt-2 items-center justify-center gap-2 rounded-xl bg-white border border-slate-200 px-5 py-2.5 text-sm font-semibold text-slate-700 shadow-sm transition hover:bg-slate-50 hover:border-slate-300 hover:-translate-y-0.5" > - Sign in via University + Sign in via University Email )}
    From a072b81db3861aa03c6e15edab7d8682ff7b8da5 Mon Sep 17 00:00:00 2001 From: Viktoriya Totalova Date: Wed, 4 Mar 2026 20:12:23 +0100 Subject: [PATCH 39/57] fix merge conflict issues --- src/App.tsx | 1 - src/pages/DashboardPage.tsx | 4 --- src/pages/HomePage.tsx | 12 --------- src/pages/OnboardingPage.tsx | 48 ------------------------------------ 4 files changed, 65 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index c8fcbf0..b567793 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,7 +2,6 @@ import { Routes, Route } from 'react-router-dom'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { useState } from 'react'; import { Toaster } from '@/components/ui/sonner'; -import { Toaster } from '@/components/ui/sonner'; import { ThemeProvider } from './components/theme-provider'; import { Layout } from './components/Layout'; import { HomePage } from './pages/HomePage'; diff --git a/src/pages/DashboardPage.tsx b/src/pages/DashboardPage.tsx index e16b883..86fb557 100644 --- a/src/pages/DashboardPage.tsx +++ b/src/pages/DashboardPage.tsx @@ -1,13 +1,11 @@ import { useEffect, useState, useMemo } from 'react'; import { Link, useNavigate } from 'react-router-dom'; -import { Link, useNavigate } from 'react-router-dom'; import { Button } from '@/components/ui/button'; import { contributorStatsApi, type ContributorStats, } from '@/lib/api/contributor-stats'; import { BookOpen, Flame } from 'lucide-react'; -import { BookOpen, Flame } from 'lucide-react'; import { ContributionHeatmap } from '@/components/dashboard/ContributionHeatmap'; import { heatmapColor } from '@/lib/heatmap-helpers'; import { useAuth } from '@/contexts/AuthContext'; @@ -277,11 +275,9 @@ export function DashboardPage() {

    {earnedSet.size} / {MILESTONES.length} earned - {earnedSet.size} / {MILESTONES.length} earned
    - {MILESTONES.map(badge => ( {MILESTONES.map(badge => (
    -
    Preview of a Memo competency mapping session
    @@ -127,14 +123,6 @@ export function HomePage() { floatingNodes={true} />
    -
    - -
    diff --git a/src/pages/OnboardingPage.tsx b/src/pages/OnboardingPage.tsx index b6ea555..78ec02b 100644 --- a/src/pages/OnboardingPage.tsx +++ b/src/pages/OnboardingPage.tsx @@ -16,24 +16,6 @@ import { Check, ChevronsUpDown, } from 'lucide-react'; -import { useCallback, useEffect, useState, useRef, forwardRef } from 'react'; -import { useNavigate } from 'react-router-dom'; -import { motion } from 'motion/react'; -import { CompetencyNetworkViz } from '@/components/competency-network/CompetencyNetworkViz'; -import { - ArrowLeft, - ArrowRight, - BookOpen, - Brain, - CheckCircle2, - GraduationCap, - Layers, - LogIn, - MousePointerClick, - Users, - Check, - ChevronsUpDown, -} from 'lucide-react'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { @@ -174,28 +156,6 @@ export function OnboardingPage() {
    -
    -
    -
    - - Step {step + 1} of {TOTAL_STEPS} - - - { - ['Welcome', 'Our Mission', 'Profile', 'Practice', 'Guidelines'][ - step - ] - } - -
    -
    - -
    @@ -262,14 +222,6 @@ export function OnboardingPage() { onClick={goBack} disabled={step === 0} className="flex items-center gap-2 rounded-full border border-slate-200 bg-white/80 px-5 py-5 text-sm font-semibold text-slate-700 shadow-sm transition-all hover:-translate-y-0.5 hover:bg-white hover:border-slate-300 disabled:opacity-0 disabled:pointer-events-none" - > - - Back - type="button" - variant="outline" - onClick={goBack} - disabled={step === 0} - className="flex items-center gap-2 rounded-full border border-slate-200 bg-white/80 px-5 py-5 text-sm font-semibold text-slate-700 shadow-sm transition-all hover:-translate-y-0.5 hover:bg-white hover:border-slate-300 disabled:opacity-0 disabled:pointer-events-none" > Back From 781c6fe628c2033d013da0ab1af21fb981d0a474 Mon Sep 17 00:00:00 2001 From: Viktoriya Totalova Date: Wed, 4 Mar 2026 20:18:31 +0100 Subject: [PATCH 40/57] update onboarding with policy link --- src/pages/OnboardingPage.tsx | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/pages/OnboardingPage.tsx b/src/pages/OnboardingPage.tsx index 78ec02b..6c67c42 100644 --- a/src/pages/OnboardingPage.tsx +++ b/src/pages/OnboardingPage.tsx @@ -742,9 +742,18 @@ function StepConsent({ ground-truth benchmark data {' '} - for evaluating competency-aware recommender systems. My - contributions are private and will only be accessible anonymized - during this research project. + to evaluate competency-aware recommender systems. My contributions + will remain private and, within this research project, will only be + used in anonymized form. I agree to the{' '} + + privacy policy + + .
    From 72bebe5138d66126aceb6d2b0a2f58970cc0ab31 Mon Sep 17 00:00:00 2001 From: Viktoriya Totalova Date: Wed, 4 Mar 2026 20:25:53 +0100 Subject: [PATCH 41/57] add fast fail if login email not authorized --- src/pages/OnboardingPage.tsx | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/pages/OnboardingPage.tsx b/src/pages/OnboardingPage.tsx index 6c67c42..eb793b7 100644 --- a/src/pages/OnboardingPage.tsx +++ b/src/pages/OnboardingPage.tsx @@ -54,6 +54,8 @@ export function OnboardingPage() { const { isAuthenticated, isLoading: isAuthLoading, + domainError, + logout, onboardingLogin, } = useAuth(); const [step, setStep] = useState(() => { @@ -148,6 +150,28 @@ export function OnboardingPage() { ? consentChecked : true; + if (domainError) { + return ( +
    +
    + +

    + Access denied +

    +

    + Your email domain is not permitted. Please use a university email + address. +

    +
    +
    + +
    +
    + ); + } + return (
    From 1fc4738d24e8be61c667bd10ca6739382c06a6b4 Mon Sep 17 00:00:00 2001 From: Viktoriya Totalova Date: Wed, 4 Mar 2026 21:11:03 +0100 Subject: [PATCH 42/57] remove duplicates --- src/pages/DashboardPage.tsx | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/pages/DashboardPage.tsx b/src/pages/DashboardPage.tsx index 86fb557..e66dc41 100644 --- a/src/pages/DashboardPage.tsx +++ b/src/pages/DashboardPage.tsx @@ -170,29 +170,6 @@ export function DashboardPage() { Start Mapping Session
    -
    - - -
    {error && ( From 32b1769b552e9c225c88196c756cee875f7f3b3e Mon Sep 17 00:00:00 2001 From: Viktoriya Totalova Date: Mon, 23 Mar 2026 11:42:42 +0200 Subject: [PATCH 43/57] fix warnings --- src/components/ProtectedRoute.tsx | 2 +- src/components/navbar.tsx | 2 +- src/contexts/AuthContext.tsx | 29 ++--------------------------- src/contexts/auth-context.ts | 14 ++++++++++++++ src/contexts/useAuth.ts | 8 ++++++++ src/pages/DashboardPage.tsx | 2 +- src/pages/HomePage.tsx | 2 +- src/pages/OnboardingPage.tsx | 2 +- 8 files changed, 29 insertions(+), 32 deletions(-) create mode 100644 src/contexts/auth-context.ts create mode 100644 src/contexts/useAuth.ts diff --git a/src/components/ProtectedRoute.tsx b/src/components/ProtectedRoute.tsx index 5bdcc21..5da0755 100644 --- a/src/components/ProtectedRoute.tsx +++ b/src/components/ProtectedRoute.tsx @@ -1,5 +1,5 @@ import { Navigate, Outlet } from 'react-router-dom'; -import { useAuth } from '../contexts/AuthContext'; +import { useAuth } from '../contexts/useAuth'; import { Button } from './ui/button'; import { GraduationCap } from 'lucide-react'; diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx index cedb403..2f2cf90 100644 --- a/src/components/navbar.tsx +++ b/src/components/navbar.tsx @@ -3,7 +3,7 @@ import { useTheme } from './use-theme'; import { useEffect, useState } from 'react'; import { cn } from '@/lib/utils'; import { CircleUser } from 'lucide-react'; -import { useAuth } from '../contexts/AuthContext'; +import { useAuth } from '../contexts/useAuth'; const navItems = [ { href: '/', label: 'Home' }, diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx index 1a6236a..58490d4 100644 --- a/src/contexts/AuthContext.tsx +++ b/src/contexts/AuthContext.tsx @@ -1,25 +1,6 @@ -import { - createContext, - useContext, - useEffect, - useRef, - useState, - type ReactNode, -} from 'react'; +import { useEffect, useRef, useState, type ReactNode } from 'react'; import { keycloak, initKeycloak } from '../lib/auth/keycloak'; - -interface AuthContextValue { - isAuthenticated: boolean; - isLoading: boolean; - userId: string | null; - role: string | null; - domainError: boolean; - login: () => void; - onboardingLogin: () => void; - logout: () => void; -} - -const AuthContext = createContext(null); +import { AuthContext } from './auth-context'; export function AuthProvider({ children }: { children: ReactNode }) { const [isAuthenticated, setIsAuthenticated] = useState(false); @@ -115,9 +96,3 @@ export function AuthProvider({ children }: { children: ReactNode }) { ); } - -export function useAuth(): AuthContextValue { - const ctx = useContext(AuthContext); - if (!ctx) throw new Error('useAuth must be used inside AuthProvider'); - return ctx; -} diff --git a/src/contexts/auth-context.ts b/src/contexts/auth-context.ts new file mode 100644 index 0000000..95d5c16 --- /dev/null +++ b/src/contexts/auth-context.ts @@ -0,0 +1,14 @@ +import { createContext } from 'react'; + +export interface AuthContextValue { + isAuthenticated: boolean; + isLoading: boolean; + userId: string | null; + role: string | null; + domainError: boolean; + login: () => void; + onboardingLogin: () => void; + logout: () => void; +} + +export const AuthContext = createContext(null); diff --git a/src/contexts/useAuth.ts b/src/contexts/useAuth.ts new file mode 100644 index 0000000..2a6b959 --- /dev/null +++ b/src/contexts/useAuth.ts @@ -0,0 +1,8 @@ +import { useContext } from 'react'; +import { AuthContext, type AuthContextValue } from './auth-context'; + +export function useAuth(): AuthContextValue { + const ctx = useContext(AuthContext); + if (!ctx) throw new Error('useAuth must be used inside AuthProvider'); + return ctx; +} diff --git a/src/pages/DashboardPage.tsx b/src/pages/DashboardPage.tsx index e66dc41..a100c95 100644 --- a/src/pages/DashboardPage.tsx +++ b/src/pages/DashboardPage.tsx @@ -8,7 +8,7 @@ import { import { BookOpen, Flame } from 'lucide-react'; import { ContributionHeatmap } from '@/components/dashboard/ContributionHeatmap'; import { heatmapColor } from '@/lib/heatmap-helpers'; -import { useAuth } from '@/contexts/AuthContext'; +import { useAuth } from '@/contexts/useAuth'; import { MILESTONES, type MilestoneDef } from '@/lib/milestones'; const ONBOARDED_KEY = 'memo-onboarded'; diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index 28aa3e3..2e277ee 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -2,7 +2,7 @@ import { useNavigate } from 'react-router-dom'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { CompetencyNetworkViz } from '@/components/competency-network/CompetencyNetworkViz'; -import { useAuth } from '@/contexts/AuthContext'; +import { useAuth } from '@/contexts/useAuth'; const ONBOARDED_KEY = 'memo-onboarded'; diff --git a/src/pages/OnboardingPage.tsx b/src/pages/OnboardingPage.tsx index eb793b7..5f674ef 100644 --- a/src/pages/OnboardingPage.tsx +++ b/src/pages/OnboardingPage.tsx @@ -43,7 +43,7 @@ import { OnboardingPractice, OnboardingPracticeRef, } from '@/components/onboarding/OnboardingPractice'; -import { useAuth } from '@/contexts/AuthContext'; +import { useAuth } from '@/contexts/useAuth'; const TOTAL_STEPS = 5; const ONBOARDED_KEY = 'memo-onboarded'; From d37c5d8dc6a0a3c5a7896b078bcd871dca6388e9 Mon Sep 17 00:00:00 2001 From: Viktoriya Totalova Date: Mon, 23 Mar 2026 11:45:04 +0200 Subject: [PATCH 44/57] fix quality issues in package --- package-lock.json | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index c7db927..1226611 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4929,7 +4929,6 @@ "version": "19.2.14", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", - "dev": true, "license": "MIT", "dependencies": { "csstype": "^3.2.2" @@ -4939,7 +4938,7 @@ "version": "19.2.3", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "dev": true, + "devOptional": true, "license": "MIT", "peerDependencies": { "@types/react": "^19.2.0" @@ -5635,7 +5634,6 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true, "license": "MIT" }, "node_modules/debug": { @@ -6144,9 +6142,9 @@ } }, "node_modules/flatted": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.4.tgz", - "integrity": "sha512-3+mMldrTAPdta5kjX2G2J7iX4zxtnwpdA8Tr2ZSjkyPSanvbZAcy6flmtnXbEybHrDcU9641lxrMfFuUxVz9vA==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, @@ -8489,7 +8487,6 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz", "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", - "dev": true, "license": "MIT" }, "node_modules/tapable": { From fd6dc022d06a9f1ec191f4ba9f426e0da493f24c Mon Sep 17 00:00:00 2001 From: Viktoriya Totalova Date: Tue, 24 Mar 2026 02:30:34 +0200 Subject: [PATCH 45/57] add admin page --- .../cit/memo/controller/AdminController.java | 104 ++++++ .../tum/cit/memo/dto/CompetencyImportRow.java | 17 + .../de/tum/cit/memo/dto/ImportResult.java | 5 + .../memo/repository/CompetencyRepository.java | 2 + .../DbRoleJwtAuthenticationConverter.java | 33 ++ .../tum/cit/memo/security/SecurityConfig.java | 9 +- .../cit/memo/service/CompetencyService.java | 30 ++ server/src/main/resources/application.yml | 5 + src/App.tsx | 12 + src/components/AdminRoute.tsx | 24 ++ src/components/navbar.tsx | 19 +- src/lib/api/admin.ts | 30 ++ src/lib/api/types.ts | 7 + src/pages/AdminPage.tsx | 66 ++++ src/pages/ImportPage.tsx | 260 +++++++++++++++ src/pages/ModerationPage.tsx | 303 ++++++++++++++++++ 16 files changed, 921 insertions(+), 5 deletions(-) create mode 100644 server/src/main/java/de/tum/cit/memo/controller/AdminController.java create mode 100644 server/src/main/java/de/tum/cit/memo/dto/CompetencyImportRow.java create mode 100644 server/src/main/java/de/tum/cit/memo/dto/ImportResult.java create mode 100644 server/src/main/java/de/tum/cit/memo/security/DbRoleJwtAuthenticationConverter.java create mode 100644 src/components/AdminRoute.tsx create mode 100644 src/lib/api/admin.ts create mode 100644 src/pages/AdminPage.tsx create mode 100644 src/pages/ImportPage.tsx create mode 100644 src/pages/ModerationPage.tsx diff --git a/server/src/main/java/de/tum/cit/memo/controller/AdminController.java b/server/src/main/java/de/tum/cit/memo/controller/AdminController.java new file mode 100644 index 0000000..50c3c13 --- /dev/null +++ b/server/src/main/java/de/tum/cit/memo/controller/AdminController.java @@ -0,0 +1,104 @@ +package de.tum.cit.memo.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import de.tum.cit.memo.dto.CompetencyImportRow; +import de.tum.cit.memo.dto.ImportResult; +import de.tum.cit.memo.service.CompetencyService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +@RestController +@RequestMapping("/api/admin") +@RequiredArgsConstructor +@Tag(name = "Admin", description = "Admin-only operations") +@SecurityRequirement(name = "bearer-jwt") +@SuppressWarnings("null") +public class AdminController { + + private final CompetencyService competencyService; + private final ObjectMapper objectMapper; + + @PostMapping("/competencies/import") + @Operation(summary = "Bulk import competencies from JSON array") + public ResponseEntity importJson( + @Valid @RequestBody List rows + ) { + return ResponseEntity.ok(competencyService.bulkImportCompetencies(rows)); + } + + @PostMapping(value = "/competencies/import/file", consumes = "multipart/form-data") + @Operation(summary = "Bulk import competencies from uploaded CSV or JSON file") + public ResponseEntity importFile( + @RequestParam("file") MultipartFile file + ) throws IOException { + String originalFilename = file.getOriginalFilename(); + List rows; + if (originalFilename != null && originalFilename.endsWith(".csv")) { + rows = parseCsv(file); + } else { + rows = parseJson(file); + } + return ResponseEntity.ok(competencyService.bulkImportCompetencies(rows)); + } + + private List parseCsv(MultipartFile file) throws IOException { + List rows = new ArrayList<>(); + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8))) { + String header = reader.readLine(); + if (header == null) { + return rows; + } + String line; + while ((line = reader.readLine()) != null) { + String[] parts = splitCsvLine(line); + String title = parts.length > 0 ? parts[0].trim() : ""; + String description = parts.length > 1 ? parts[1].trim() : null; + rows.add(new CompetencyImportRow(title, description)); + } + } + return rows; + } + + private String[] splitCsvLine(String line) { + List fields = new ArrayList<>(); + StringBuilder current = new StringBuilder(); + boolean inQuotes = false; + for (int i = 0; i < line.length(); i++) { + char c = line.charAt(i); + if (c == '"') { + inQuotes = !inQuotes; + } else if (c == ',' && !inQuotes) { + fields.add(current.toString()); + current = new StringBuilder(); + } else { + current.append(c); + } + } + fields.add(current.toString()); + return fields.toArray(new String[0]); + } + + private List parseJson(MultipartFile file) throws IOException { + return objectMapper.readValue( + file.getInputStream(), + objectMapper.getTypeFactory().constructCollectionType(List.class, CompetencyImportRow.class) + ); + } +} diff --git a/server/src/main/java/de/tum/cit/memo/dto/CompetencyImportRow.java b/server/src/main/java/de/tum/cit/memo/dto/CompetencyImportRow.java new file mode 100644 index 0000000..7c5a402 --- /dev/null +++ b/server/src/main/java/de/tum/cit/memo/dto/CompetencyImportRow.java @@ -0,0 +1,17 @@ +package de.tum.cit.memo.dto; + +import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CompetencyImportRow { + + @NotBlank(message = "Title is required") + private String title; + + private String description; +} diff --git a/server/src/main/java/de/tum/cit/memo/dto/ImportResult.java b/server/src/main/java/de/tum/cit/memo/dto/ImportResult.java new file mode 100644 index 0000000..1de4427 --- /dev/null +++ b/server/src/main/java/de/tum/cit/memo/dto/ImportResult.java @@ -0,0 +1,5 @@ +package de.tum.cit.memo.dto; + +import java.util.List; + +public record ImportResult(int imported, int skipped, List errors) {} diff --git a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java index fc80203..f655c94 100644 --- a/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java +++ b/server/src/main/java/de/tum/cit/memo/repository/CompetencyRepository.java @@ -27,4 +27,6 @@ public interface CompetencyRepository extends JpaRepository @org.springframework.data.jpa.repository.Modifying(flushAutomatically = true, clearAutomatically = true) @Query(value = "UPDATE competencies SET degree = GREATEST(degree - 1, 0) WHERE id IN :ids", nativeQuery = true) void decrementDegree(@Param("ids") List ids); + + boolean existsByTitle(String title); } diff --git a/server/src/main/java/de/tum/cit/memo/security/DbRoleJwtAuthenticationConverter.java b/server/src/main/java/de/tum/cit/memo/security/DbRoleJwtAuthenticationConverter.java new file mode 100644 index 0000000..005447b --- /dev/null +++ b/server/src/main/java/de/tum/cit/memo/security/DbRoleJwtAuthenticationConverter.java @@ -0,0 +1,33 @@ +package de.tum.cit.memo.security; + +import de.tum.cit.memo.entity.User; +import de.tum.cit.memo.enums.UserRole; +import de.tum.cit.memo.repository.UserRepository; +import java.util.List; +import java.util.Objects; +import lombok.RequiredArgsConstructor; +import org.springframework.core.convert.converter.Converter; +import org.springframework.lang.NonNull; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +@SuppressWarnings("null") +public class DbRoleJwtAuthenticationConverter implements Converter { + + private final UserRepository userRepository; + + @Override + public AbstractAuthenticationToken convert(@NonNull Jwt jwt) { + String subject = Objects.requireNonNullElse(jwt.getSubject(), ""); + UserRole role = userRepository.findById(subject) + .map(User::getRole) + .orElse(UserRole.USER); + return new JwtAuthenticationToken(jwt, + List.of(new SimpleGrantedAuthority("ROLE_" + role.name()))); + } +} diff --git a/server/src/main/java/de/tum/cit/memo/security/SecurityConfig.java b/server/src/main/java/de/tum/cit/memo/security/SecurityConfig.java index 5b22e75..1883953 100644 --- a/server/src/main/java/de/tum/cit/memo/security/SecurityConfig.java +++ b/server/src/main/java/de/tum/cit/memo/security/SecurityConfig.java @@ -3,7 +3,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; -import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; @@ -20,7 +19,7 @@ public class SecurityConfig { @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + public SecurityFilterChain filterChain(HttpSecurity http, DbRoleJwtAuthenticationConverter jwtConverter) throws Exception { http .csrf(AbstractHttpConfigurer::disable) .cors(cors -> cors.configurationSource(corsConfigurationSource())) @@ -29,9 +28,13 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() .requestMatchers("/swagger-ui/**", "/swagger-ui.html", "/api-docs/**").permitAll() .requestMatchers("/actuator/health").permitAll() + .requestMatchers("/api/users/**").hasRole("ADMIN") + .requestMatchers("/api/admin/**").hasRole("ADMIN") + .requestMatchers(HttpMethod.DELETE, "/api/competencies/**").hasRole("ADMIN") + .requestMatchers(HttpMethod.DELETE, "/api/learning-resources/**").hasRole("ADMIN") .anyRequest().authenticated() ) - .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())); + .oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtConverter))); return http.build(); } diff --git a/server/src/main/java/de/tum/cit/memo/service/CompetencyService.java b/server/src/main/java/de/tum/cit/memo/service/CompetencyService.java index f724f8f..05082ed 100644 --- a/server/src/main/java/de/tum/cit/memo/service/CompetencyService.java +++ b/server/src/main/java/de/tum/cit/memo/service/CompetencyService.java @@ -1,6 +1,8 @@ package de.tum.cit.memo.service; +import de.tum.cit.memo.dto.CompetencyImportRow; import de.tum.cit.memo.dto.CreateCompetencyRequest; +import de.tum.cit.memo.dto.ImportResult; import de.tum.cit.memo.dto.UpdateCompetencyRequest; import de.tum.cit.memo.entity.Competency; import de.tum.cit.memo.exception.ResourceNotFoundException; @@ -10,6 +12,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; import java.util.List; @Service @@ -70,4 +73,31 @@ public void deleteCompetency(String id) { } competencyRepository.deleteById(id); } + + @Transactional + public ImportResult bulkImportCompetencies(List rows) { + List toSave = new ArrayList<>(); + List errors = new ArrayList<>(); + int skipped = 0; + + for (int i = 0; i < rows.size(); i++) { + CompetencyImportRow row = rows.get(i); + if (row.getTitle() == null || row.getTitle().isBlank()) { + errors.add("Row " + (i + 1) + ": title is required"); + continue; + } + if (competencyRepository.existsByTitle(row.getTitle())) { + skipped++; + continue; + } + toSave.add(Competency.builder() + .id(IdGenerator.generateCuid()) + .title(row.getTitle()) + .description(row.getDescription()) + .build()); + } + + competencyRepository.saveAll(toSave); + return new ImportResult(toSave.size(), skipped, errors); + } } diff --git a/server/src/main/resources/application.yml b/server/src/main/resources/application.yml index d02da65..18dd62c 100644 --- a/server/src/main/resources/application.yml +++ b/server/src/main/resources/application.yml @@ -26,6 +26,11 @@ spring: jdbc: time_zone: UTC + servlet: + multipart: + max-file-size: 5MB + max-request-size: 5MB + flyway: enabled: true baseline-on-migrate: true diff --git a/src/App.tsx b/src/App.tsx index b567793..2942c7e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,6 +12,10 @@ import { ImprintPage } from './pages/ImprintPage'; import { PrivacyPage } from './pages/PrivacyPage'; import { DashboardPage } from './pages/DashboardPage'; import { ProtectedRoute } from './components/ProtectedRoute'; +import { AdminRoute } from './components/AdminRoute'; +import { AdminPage } from './pages/AdminPage'; +import { ModerationPage } from './pages/ModerationPage'; +import { ImportPage } from './pages/ImportPage'; import { AuthProvider } from './contexts/AuthContext'; export function App() { @@ -42,6 +46,14 @@ export function App() { }> } /> } /> + }> + } /> + } + /> + } /> + diff --git a/src/components/AdminRoute.tsx b/src/components/AdminRoute.tsx new file mode 100644 index 0000000..6db1bba --- /dev/null +++ b/src/components/AdminRoute.tsx @@ -0,0 +1,24 @@ +import { Navigate, Outlet } from 'react-router-dom'; +import { useAuth } from '../contexts/useAuth'; + +export function AdminRoute() { + const { isAuthenticated, isLoading, role } = useAuth(); + + if (isLoading) { + return ( +
    +

    Loading…

    +
    + ); + } + + if (!isAuthenticated) { + return ; + } + + if (role !== 'ADMIN') { + return ; + } + + return ; +} diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx index 2f2cf90..873f471 100644 --- a/src/components/navbar.tsx +++ b/src/components/navbar.tsx @@ -2,7 +2,7 @@ import { Link, useLocation } from 'react-router-dom'; import { useTheme } from './use-theme'; import { useEffect, useState } from 'react'; import { cn } from '@/lib/utils'; -import { CircleUser } from 'lucide-react'; +import { CircleUser, Shield } from 'lucide-react'; import { useAuth } from '../contexts/useAuth'; const navItems = [ @@ -16,7 +16,7 @@ export function Navbar() { const location = useLocation(); const pathname = location.pathname; const { theme, setTheme } = useTheme(); - const { isAuthenticated, login, logout } = useAuth(); + const { isAuthenticated, login, logout, role } = useAuth(); const [mounted, setMounted] = useState(false); const [scrolled, setScrolled] = useState(false); const activeIndex = navItems.findIndex(item => item.href === pathname); @@ -165,6 +165,21 @@ export function Navbar() { Dashboard + {role === 'ADMIN' && ( + + + Admin + + )} +
    + ) : ( + <> +
    + {(['file', 'json'] as Mode[]).map(m => ( + + ))} +
    + + {mode === 'file' ? ( +
    +
    e.preventDefault()} + onClick={() => fileInputRef.current?.click()} + className="flex cursor-pointer flex-col items-center justify-center gap-3 rounded-xl border-2 border-dashed border-slate-200 bg-slate-50/50 p-10 transition hover:border-[#0a4da2]/50 hover:bg-slate-50" + > + {selectedFile ? ( + <> + +

    + {selectedFile.name} +

    +

    + {(selectedFile.size / 1024).toFixed(1)} KB +

    + + ) : ( + <> + +

    + Drop a file here or click to browse +

    +

    + Accepts .json or .csv (max 5 MB) +

    + + )} + +
    +
    +

    + CSV format +

    +
    +                      {`title,description\n"Understand Big-O notation","Time and space complexity"\n"Apply sorting algorithms",`}
    +                    
    +
    +
    + ) : ( +
    +