diff --git a/apps/site/index.html b/apps/site/index.html index 0227c313..df6f342a 100644 --- a/apps/site/index.html +++ b/apps/site/index.html @@ -8,6 +8,17 @@ content="width=device-width, initial-scale=1.0,viewport-fit=cover" /> + + + + + Reflections | Projections diff --git a/apps/site/public/finish-line.svg b/apps/site/public/finish-line.svg new file mode 100644 index 00000000..8c18a05b --- /dev/null +++ b/apps/site/public/finish-line.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/apps/site/public/magistral.ttf b/apps/site/public/magistral.ttf new file mode 100644 index 00000000..6a64aed8 Binary files /dev/null and b/apps/site/public/magistral.ttf differ diff --git a/apps/site/public/pro-racing-slant.ttf b/apps/site/public/pro-racing-slant.ttf new file mode 100644 index 00000000..9f099e16 Binary files /dev/null and b/apps/site/public/pro-racing-slant.ttf differ diff --git a/apps/site/public/pro-racing.ttf b/apps/site/public/pro-racing.ttf new file mode 100644 index 00000000..610e42ac Binary files /dev/null and b/apps/site/public/pro-racing.ttf differ diff --git a/apps/site/public/schedule-mobile.svg b/apps/site/public/schedule-mobile.svg new file mode 100644 index 00000000..f8c53bf1 --- /dev/null +++ b/apps/site/public/schedule-mobile.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/site/public/schedule.svg b/apps/site/public/schedule.svg new file mode 100644 index 00000000..4e72793e --- /dev/null +++ b/apps/site/public/schedule.svg @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/site/src/components/Home/Schedule/AudioVisualizer.tsx b/apps/site/src/components/Home/Schedule/AudioVisualizer.tsx new file mode 100644 index 00000000..c3f1cd3c --- /dev/null +++ b/apps/site/src/components/Home/Schedule/AudioVisualizer.tsx @@ -0,0 +1,82 @@ +import React, { useState, useEffect } from "react"; +import { Flex } from "@chakra-ui/react"; +import { motion } from "framer-motion"; + +interface AudioVisualizerProps { + barCount?: number; + maxHeight?: number; + updateInterval?: number; + variance?: number; + // Spring animation properties + stiffness?: number; + damping?: number; + mass?: number; +} + +export const AudioVisualizer: React.FC = ({ + barCount = 40, + maxHeight = 60, + updateInterval = 100, + // Default spring physics values + stiffness = 100, + damping = 10, + mass = 1 +}) => { + const [heights, setHeights] = useState( + Array.from({ length: barCount }, () => Math.random() * maxHeight) + ); + + useEffect(() => { + const timer = setInterval(() => { + setHeights((prev) => + prev.map((h) => { + // Create more dramatic changes by using a new random value + // combined with the previous height + const targetHeight = Math.random() * maxHeight; + // Mix previous height (30%) with new random height (70%) + // This creates more noticeable variations while maintaining some continuity + const newHeight = h * 0.3 + targetHeight * 0.7; + + // Add extra randomness for occasional peaks + const shouldSpike = Math.random() > 0.85; + const spikeMultiplier = shouldSpike ? Math.random() * 0.7 + 0.3 : 0; + + return Math.max( + 5, + Math.min(newHeight + maxHeight * spikeMultiplier, maxHeight) + ); + }) + ); + }, updateInterval); + return () => clearInterval(timer); + }, [maxHeight, updateInterval]); + + return ( + + {heights.map((h, idx) => ( + + ))} + + ); +}; diff --git a/apps/site/src/components/Home/Schedule/EventModal.tsx b/apps/site/src/components/Home/Schedule/EventModal.tsx new file mode 100644 index 00000000..53da9e91 --- /dev/null +++ b/apps/site/src/components/Home/Schedule/EventModal.tsx @@ -0,0 +1,213 @@ +import { EVENT_ICONS } from "@/constants/event-icons"; +import { + Box, + CloseButton, + Flex, + Icon, + Modal, + ModalContent, + ModalHeader, + ModalOverlay, + Text +} from "@chakra-ui/react"; +import { Event } from "@rp/shared"; +import moment from "moment"; +import { FaAward, FaClock, FaMapPin, FaTag } from "react-icons/fa"; +import { AudioVisualizer } from "./AudioVisualizer"; + +export default function EventModal({ + event, + onClose +}: { + event: Event | null; + onClose: () => void; +}) { + return ( + + + {event && ( + + + + + {event.name} + + + + + + + + + + +
+ + + + + {event.description} + +
+ + +
+ )} +
+ ); +} + +function EventCard({ event }: { event: Event }) { + return ( + + + + + + {moment(event.startTime).format("h:mma")} –{" "} + {moment(event.endTime).format("h:mma")} + + + + + + {event.location} + + + + + + + + + {event.eventType} + + + + + + {event.points} points + + + + + ); +} + +function CheckerBoardPattern() { + return ( + + ); +} diff --git a/apps/site/src/components/Home/Schedule/RaceTrack.tsx b/apps/site/src/components/Home/Schedule/RaceTrack.tsx new file mode 100644 index 00000000..35b8b217 --- /dev/null +++ b/apps/site/src/components/Home/Schedule/RaceTrack.tsx @@ -0,0 +1,231 @@ +import { TRACK_PATHS, TrackLocation } from "@/constants/track-paths"; +import { Box, Text, Tooltip } from "@chakra-ui/react"; +import { Event } from "@rp/shared"; +import { useEffect, useMemo, useRef, useState } from "react"; + +export function RaceTrack({ + selectedDayIndex, + dayEvents, + colors, + hoveredIndex, + onHover, + onClick +}: { + selectedDayIndex: number; + dayEvents: Event[]; + colors: string[]; + hoveredIndex: number | null; + onHover?: (index: number) => void; + onClick: (event: Event) => void; +}) { + const pathRef = useRef(null); + + const trackPath = useMemo(() => { + return TRACK_PATHS[(selectedDayIndex - 1) % TRACK_PATHS.length]; + }, [selectedDayIndex]); + + const [selectedLocations, setSelectedLocations] = useState( + [] + ); + + const [finishLineLocation, setFinishLineLocation] = + useState(null); + + useEffect(() => { + if (!pathRef?.current) return; + + const pathEl = pathRef.current; + const totalLen = pathEl.getTotalLength(); + const numLocations = dayEvents.length; // Ensure at least one location + if (numLocations === 0) return; + + const locations: TrackLocation[] = []; + for (let i = 0; i < numLocations; i++) { + const t = i / numLocations; + const { x, y } = pathEl.getPointAtLength(t * totalLen); + if (i === numLocations - 1) { + const t_final = (i + 0.5) / numLocations; + const { x: finalX, y: finalY } = pathEl.getPointAtLength( + t_final * totalLen + ); + setFinishLineLocation({ x: finalX, y: finalY, order: i }); + } + locations.push({ x, y, order: i }); + } + + setSelectedLocations(locations); + }, [trackPath.path, dayEvents.length]); + + return ( + + + + {selectedLocations && + selectedLocations.map((location, index) => { + const hovered = hoveredIndex ? hoveredIndex - 1 === index : false; + + return ( + + ); + })} + {finishLineLocation && } + + + ); +} + +function FinishLocation({ location }: { location: TrackLocation }) { + return ( + + + Finish Line + + + ); +} + +function RaceTrackLocation({ + index, + color, + location, + hovered, + dayEvent, + onClick, + onHover +}: { + index: number; + color: string; + location: TrackLocation; + hovered: boolean; + dayEvent: Event; + onClick: (event: Event) => void; + onHover?: (index: number) => void; +}) { + return ( + onClick(dayEvent)} + > + + + onHover && onHover(index + 1)} + onMouseLeave={() => onHover && onHover(-1)} + > + + {index + 1} + + + + + + ); +} + +function RaceTrackPath({ + path, + pathRef +}: { + path: string; + pathRef?: React.Ref; +}) { + return ( + + ); +} diff --git a/apps/site/src/components/Home/Schedule/Schedule.tsx b/apps/site/src/components/Home/Schedule/Schedule.tsx new file mode 100644 index 00000000..9b34039e --- /dev/null +++ b/apps/site/src/components/Home/Schedule/Schedule.tsx @@ -0,0 +1,519 @@ +import { + Box, + Flex, + Grid, + HStack, + Icon, + Spacer, + Text, + Tooltip, + useToast +} from "@chakra-ui/react"; +import { Event, path, api } from "@rp/shared"; +import moment from "moment"; +import { useEffect, useState } from "react"; + +import { EVENT_ICONS } from "@/constants/event-icons"; +import { AudioVisualizer } from "./AudioVisualizer"; +import EventModal from "./EventModal"; +import { RaceTrack } from "./RaceTrack"; +import ScheduleDaySelector from "./ScheduleDaySelector"; +import { CIRCLE_COLORS } from "@/constants/colors"; + +export default function Schedule() { + const toast = useToast(); + const [eventsByDay, setEventsByDay] = useState<{ [key: string]: Event[] }>( + {} + ); + const [selectedDay, setSelectedDay] = useState(null); + const [selectedEvent, setSelectedEvent] = useState(null); + const [hoveredEventIndex, setHoveredEventIndex] = useState( + null + ); + + const selectedDayIndex = Math.max( + Object.keys(eventsByDay).indexOf(selectedDay || "") + 1, + 1 + ); + + const dayEvents = selectedDay ? eventsByDay[selectedDay] : []; + + const handleLoadEvents = () => { + api + .get(path("/events", {})) + .then((events) => { + const eventsByDay: { [key: string]: Event[] } = {}; + events.data.forEach((event) => { + const date = moment(event.startTime).format("ddd M/D"); + if (!eventsByDay[date]) { + eventsByDay[date] = []; + } + eventsByDay[date].push(event); + }); + setSelectedDay(Object.keys(eventsByDay)[0]); + setEventsByDay(eventsByDay); + }) + .catch((err) => { + console.log(err); + toast({ + title: "Error fetching events", + status: "error", + duration: 9000, + isClosable: true + }); + }); + }; + + useEffect(() => { + handleLoadEvents(); + }, []); + + const handleHover = (index: number) => { + setHoveredEventIndex(index); + }; + + const handleSelectDay = (date: string) => { + setHoveredEventIndex(null); + setSelectedDay(date); + }; + + const handleSelectEvent = (event: Event) => { + setSelectedEvent(event); + }; + + return ( + <> + + + + + + + + setSelectedEvent(null)} + /> + + ); +} + +function DayEventsSection({ + selectedDayIndex, + numDays, + hoveredIndex, + dayEvents, + onHover, + onClick +}: { + selectedDayIndex: number; + numDays: number; + hoveredIndex: number | null; + dayEvents: Event[]; + onHover: (index: number) => void; + onClick: (event: Event) => void; +}) { + return ( + + + + Lap + + + + {selectedDayIndex} + + + /{numDays} + + + + + + {dayEvents.length === 0 && ( + + No events scheduled yet. + + )} + {dayEvents.map((event, index) => ( + + ))} + + + + ); +} + +function RaceTrackSection({ + selectedDayIndex, + dayEvents, + hoveredEventIndex, + handleHover, + handleSelectEvent +}: { + selectedDayIndex: number; + dayEvents: Event[]; + hoveredEventIndex: number | null; + handleHover: (index: number) => void; + handleSelectEvent: (event: Event) => void; +}) { + return ( + + + + + + + + + + + R|P Radio + + + + + LOOKING FOR A JOB IN THE TECH INDUSTRY? + +
+
+
+
+
+ ); +} + +function DayEvent({ + number, + hoveredIndex, + lastIndex, + event, + onHover, + onClick +}: { + number: number; + hoveredIndex: number | null; + lastIndex: number; + event: Event; + onHover: (index: number) => void; + onClick: (event: Event) => void; +}) { + return ( + { + onHover(number); + }} + onMouseLeave={() => { + onHover(-1); + }} + onClick={() => { + onClick(event); + }} + > + + + {number} + + + + + + + + {event.name} + + + + + {event.location} + + + + {moment(event.startTime).format("h:mma")} –{" "} + {moment(event.endTime).format("h:mma")} + + + + + c.toUpperCase())} + placement="top" + hasArrow + > + + + + + + ); +} diff --git a/apps/site/src/components/Home/Schedule/ScheduleDaySelector.tsx b/apps/site/src/components/Home/Schedule/ScheduleDaySelector.tsx new file mode 100644 index 00000000..7b7eafe8 --- /dev/null +++ b/apps/site/src/components/Home/Schedule/ScheduleDaySelector.tsx @@ -0,0 +1,142 @@ +import { DAY_COLORS } from "@/constants/colors"; +import { Box, Flex, Text, VStack } from "@chakra-ui/react"; +import { Event } from "@rp/shared"; +import { useMemo } from "react"; + +export default function ScheduleDaySelector({ + selectedDay, + eventsByDay, + onSelectDay +}: { + selectedDay: string | null; + eventsByDay: { [key: string]: Event[] }; + onSelectDay: (date: string) => void; +}) { + return ( + + {Object.keys(eventsByDay).map((date, index) => ( + + ))} + + ); +} + +function ScheduleDayButton({ + color, + date, + selected, + onSelectDay +}: { + color: string; + date: string; + selected?: boolean; + onSelectDay: (date: string) => void; +}) { + const { displayedDay, displayedDate } = useMemo(() => { + const splitDate = date.split(" "); + if (splitDate.length < 2) { + return { displayedDay: date, displayedDate: "" }; + } + return { + displayedDay: splitDate[0], + displayedDate: splitDate[1] + }; + }, [date]); + return ( + onSelectDay(date)} + transition="all 0.2s" + _hover={{ + cursor: "pointer" + }} + boxShadow="md" + > + + {`${displayedDay.toUpperCase()} ${displayedDate.toUpperCase()}`} + + + + {displayedDay.toUpperCase()} + + + {displayedDate.toUpperCase()} + + + + ); +} diff --git a/apps/site/src/constants/colors.ts b/apps/site/src/constants/colors.ts new file mode 100644 index 00000000..e8c80113 --- /dev/null +++ b/apps/site/src/constants/colors.ts @@ -0,0 +1,20 @@ +export const DAY_COLORS = [ + "#56BF59", + "#E6930D", + "#FFFFFF", + "#FFD93F", + "#322BB7" +]; + +export const CIRCLE_COLORS = [ + "green.400", + "purple.600", + "pink.500", + "red.500", + "orange.500", + "teal.400", + "cyan.400", + "blue.500", + "yellow.400", + "pink.600" +]; diff --git a/apps/site/src/constants/event-icons.ts b/apps/site/src/constants/event-icons.ts new file mode 100644 index 00000000..51a3c2dc --- /dev/null +++ b/apps/site/src/constants/event-icons.ts @@ -0,0 +1,20 @@ +import { EventType } from "@rp/shared"; +import { IconType } from "react-icons"; + +import { + FaBriefcase, + FaCheck, + FaHandshake, + FaMicrophone, + FaStar, + FaUtensils +} from "react-icons/fa"; + +export const EVENT_ICONS: Record = { + SPECIAL: FaStar, // star for special events + SPEAKER: FaMicrophone, // microphone for speaker sessions + CORPORATE: FaBriefcase, // briefcase for corporate events + PARTNERS: FaHandshake, // handshake for partners + MEALS: FaUtensils, // utensils for meal breaks + CHECKIN: FaCheck // checkmark for check-in +}; diff --git a/apps/site/src/constants/track-paths.ts b/apps/site/src/constants/track-paths.ts new file mode 100644 index 00000000..96842a3e --- /dev/null +++ b/apps/site/src/constants/track-paths.ts @@ -0,0 +1,39 @@ +export type TrackLocation = { + x: number; + y: number; + order: number; +}; + +export type TrackPath = { + path: string; + width: number; + height: number; +}; + +export const TRACK_PATHS: TrackPath[] = [ + { + path: "M14.0718 88.218C18.2918 41.578 64.3318 12.188 119.332 8.05796C135.562 6.83796 206.122 9.29795 214.272 47.838C224.492 96.158 264.652 126.888 284.352 142.138C287.922 144.898 292.042 146.858 296.552 147.018L362.502 146.378C366.762 146.528 370.802 144.498 373.202 140.988C377.692 134.438 392.422 119.148 399.502 111.918C401.972 109.398 405.312 107.928 408.832 107.798L475.562 108.658C479.242 108.518 482.902 109.228 486.262 110.728C500.542 117.098 581.162 151.708 608.572 163.468C613.962 165.778 616.992 171.558 615.812 177.308C610.742 202.078 595.302 265.248 568.512 273.618C529.672 285.758 496.332 232.238 472.872 245.578C451.562 257.698 488.382 349.948 444.002 351.378C400.282 352.788 240.902 352.088 210.582 351.378C188.292 350.858 203.092 304.988 183.232 304.948C146.332 304.878 85.9818 305.618 51.9718 306.378C40.7718 306.628 34.5318 293.578 41.7118 284.988C51.9518 272.738 67.5618 258.598 68.8218 249.908C70.4518 238.678 7.61181 205.628 8.00181 186.188C8.63181 154.798 12.2718 107.918 14.0518 88.198L14.0718 88.218Z", + width: 624, + height: 361 + }, + { + path: "M36.4907 275.411C36.4907 275.411 125.441 164.031 198.841 68.1813C207.901 56.3513 230.891 54.2913 246.021 57.4513C280.061 64.5713 276.701 149.071 316.571 124.151C354.171 100.651 388.061 79.6313 469.651 34.8513C575.771 -23.3887 612.111 30.4413 614.941 35.8513C637.121 78.2613 630.141 150.131 590.481 176.511C553.391 201.181 518.721 169.001 465.401 193.221C426.501 210.891 435.791 251.141 394.661 259.831C326.831 274.161 290.021 212.161 250.891 277.511C187.201 383.871 413.381 400.801 321.071 512.671C293.971 545.511 203.301 540.531 128.121 540.901C107.671 541.001 43.7107 550.281 39.5107 499.511C34.4507 438.311 35.0507 315.801 36.5007 275.401L36.4907 275.411Z", + width: 635, + height: 550 + }, + { + path: "M11.01 160.922L162.32 9.83203L594.76 223.972C602.86 227.982 604.95 238.562 599.01 245.372C587.37 258.732 572.62 279.852 577.83 296.532C585.35 320.662 616.6 337.472 597.01 360.322C588.6 370.132 566.55 375.882 533 366.862C493.44 356.232 419.41 291.222 419.41 291.222L349.87 278.532C349.87 278.532 292.56 306.482 250.58 330.862C239.61 337.232 240.88 352.272 228.1 358.002C213.01 364.772 203.22 357.862 188.13 362.942C166.8 370.132 172.45 385.102 150.17 406.682C135.66 420.742 115.3 423.512 94.67 405.462C83.21 395.432 79.14 379.722 70.33 351.432C62.57 326.492 52.62 321.002 49.93 308.102C41.34 266.922 62.99 216.222 56.81 210.042C27.78 181.012 11 160.932 11 160.932L11.01 160.922Z", + width: 611, + height: 426 + }, + { + path: "M14.0718 88.218C18.2918 41.578 64.3318 12.188 119.332 8.05796C135.562 6.83796 206.122 9.29795 214.272 47.838C224.492 96.158 264.652 126.888 284.352 142.138C287.922 144.898 292.042 146.858 296.552 147.018L362.502 146.378C366.762 146.528 370.802 144.498 373.202 140.988C377.692 134.438 392.422 119.148 399.502 111.918C401.972 109.398 405.312 107.928 408.832 107.798L475.562 108.658C479.242 108.518 482.902 109.228 486.262 110.728C500.542 117.098 581.162 151.708 608.572 163.468C613.962 165.778 616.992 171.558 615.812 177.308C610.742 202.078 595.302 265.248 568.512 273.618C529.672 285.758 496.332 232.238 472.872 245.578C451.562 257.698 488.382 349.948 444.002 351.378C400.282 352.788 240.902 352.088 210.582 351.378C188.292 350.858 203.092 304.988 183.232 304.948C146.332 304.878 85.9818 305.618 51.9718 306.378C40.7718 306.628 34.5318 293.578 41.7118 284.988C51.9518 272.738 67.5618 258.598 68.8218 249.908C70.4518 238.678 7.61181 205.628 8.00181 186.188C8.63181 154.798 12.2718 107.918 14.0518 88.198L14.0718 88.218Z", + width: 624, + height: 360 + }, + { + path: "M21.3249 95.8168C16.6149 144.267 8.92486 221.187 8.37486 259.647C8.16486 274.377 26.2649 261.817 33.1649 274.417C40.4749 287.767 29.1849 299.607 39.2649 313.757C47.8449 325.817 64.3049 345.777 79.1249 360.517C85.9649 367.317 89.6249 356.377 90.7449 346.397C96.8149 292.147 105.145 169.557 122.185 148.297C137.045 129.767 171.515 176.487 222.625 195.477C233.745 199.607 250.965 192.757 258.145 202.387C265.885 212.757 257.485 248.577 272.145 249.987C305.935 253.247 312.045 254.467 342.985 258.127C359.655 260.097 357.255 227.197 370.635 218.167C385.995 207.797 412.635 211.867 424.905 226.057C435.405 238.197 418.855 259.937 434.775 263.557C462.935 269.957 490.895 275.447 551.215 285.267C558.105 286.387 589.185 228.577 586.855 219.947C561.995 127.947 543.395 65.8968 528.475 13.6768C527.245 9.38678 461.315 29.8768 454.955 27.2568C433.755 18.5268 414.825 18.2068 407.825 28.3768C399.775 40.0968 395.165 60.9468 429.835 86.9268C453.395 104.587 470.845 112.087 468.635 135.717C467.385 149.117 459.995 167.337 424.275 164.587C364.345 159.977 281.745 152.437 269.885 145.907C189.125 101.407 147.915 63.4968 135.275 71.1868C113.345 84.5368 114.385 121.407 97.2849 122.447C78.7749 123.577 69.8449 74.9068 47.9149 75.5768C39.6549 75.8268 23.1549 76.8268 21.3049 95.8068L21.3249 95.8168Z", + width: 595, + height: 371 + } +]; diff --git a/apps/site/src/index.css b/apps/site/src/index.css index 9bfcb041..a6ea513f 100644 --- a/apps/site/src/index.css +++ b/apps/site/src/index.css @@ -2,3 +2,31 @@ color: #213547; background-color: #ffffff; } + +@font-face { + font-family: "Magistral"; + src: url("/magistral.ttf") format("truetype"); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: "ProRacing"; + src: url("/pro-racing.ttf") format("truetype"); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: "ProRacingSlant"; + src: url("/pro-racing-slant.ttf") format("truetype"); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +.condensed { + font-stretch: condensed; +} diff --git a/apps/site/src/routes/Home.tsx b/apps/site/src/routes/Home.tsx index 33e35e77..51e37d5a 100644 --- a/apps/site/src/routes/Home.tsx +++ b/apps/site/src/routes/Home.tsx @@ -1,7 +1,11 @@ +import Schedule from "@/components/Home/Schedule/Schedule"; + export default function Home() { return ( <>

Reflections | Projections 2025

+
+ ); } diff --git a/apps/site/tsconfig.json b/apps/site/tsconfig.json index b4e8c302..8b61d439 100644 --- a/apps/site/tsconfig.json +++ b/apps/site/tsconfig.json @@ -8,7 +8,7 @@ "@rp/shared": ["../../shared"] } }, - "include": ["src", "vite.config.ts"], + "include": ["src", "vite.config.ts", "svg.d.ts"], "references": [ { "path": "../../shared" diff --git a/package.json b/package.json index 63c1691d..eb1aabee 100644 --- a/package.json +++ b/package.json @@ -44,5 +44,8 @@ "husky": "^9.1.7", "lint-staged": "^15.5.0" }, - "packageManager": "yarn@4.9.1" + "packageManager": "yarn@4.9.1", + "dependencies": { + "fonteditor-core": "^2.6.1" + } } diff --git a/yarn.lock b/yarn.lock index a61cc21b..4d84b1e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1915,6 +1915,13 @@ __metadata: languageName: node linkType: hard +"@xmldom/xmldom@npm:^0.8.3": + version: 0.8.10 + resolution: "@xmldom/xmldom@npm:0.8.10" + checksum: 10c0/c7647c442502720182b0d65b17d45d2d95317c1c8c497626fe524bda79b4fb768a9aa4fae2da919f308e7abcff7d67c058b102a9d641097e9a57f0b80187851f + languageName: node + linkType: hard + "@yudiel/react-qr-scanner@npm:^2.2.1": version: 2.3.1 resolution: "@yudiel/react-qr-scanner@npm:2.3.1" @@ -3069,6 +3076,15 @@ __metadata: languageName: node linkType: hard +"fonteditor-core@npm:^2.6.1": + version: 2.6.1 + resolution: "fonteditor-core@npm:2.6.1" + dependencies: + "@xmldom/xmldom": "npm:^0.8.3" + checksum: 10c0/92147277bc124794aaa34fda9c70b82acf29b49bfbb82ad375189119415797cf63ae223144b430e6a230f1112f7f4e2768b9032066dcb40077354ef9b0080c17 + languageName: node + linkType: hard + "foreground-child@npm:^3.1.0": version: 3.3.1 resolution: "foreground-child@npm:3.3.1" @@ -4847,6 +4863,7 @@ __metadata: version: 0.0.0-use.local resolution: "rp-web@workspace:." dependencies: + fonteditor-core: "npm:^2.6.1" husky: "npm:^9.1.7" lint-staged: "npm:^15.5.0" languageName: unknown