From b8865a7da644030d86dc0085d8d84b29882dc08b Mon Sep 17 00:00:00 2001 From: Aaron Chan <42254254+aaronchan32@users.noreply.github.com> Date: Tue, 21 May 2024 14:40:03 -0700 Subject: [PATCH] Progress Notes Frontend & Backend (#102) * feat: add create program notes backend * fix: THead unique key prop warning * feat: add edited by field to notes * fix: fix styling issues * feat: add edit and delete functionality to progress notes and change userId to uid for backend * fix: fix calendar styling * feat: add download progress notes functionality using react-pdf * feat: add mobile responsiveness * feat: create program context provider shared across Home, Programs, and Notes page * fix: fix styling to be consistent across pages * feat: add progress note filtering and add loading spinner to pages * feat: add account type authorization checks on frontend and backend * refactor: refactor notes logic and fix styling * feat: add logic to check for no students and refactor filter * feat: add shadows using overflow clip * fix: fix styling for search filter * fix: fix small style inconsistencies * fix: update poppins font url to use https * fix: fix modal close button styling to be more consistent * fix: fix escape key overriding dialog close * Squashed commit of the following: commit 0b133b8a0f9465224f927564ff42c7ee95798d38 Author: Michael Sullivan <96799955+mraysu@users.noreply.github.com> Date: Tue May 14 09:09:16 2024 -0700 Feature/mraysu/program form v2 (#100) * Update Backend Program Schema * V2 UI * Disabled Editing Program Type * Frontend-backend integration * Lint fixes --------- Co-authored-by: mraysu Co-authored-by: Adhithya Ananthan <85322002+adhi0331@users.noreply.github.com> commit e17b509601b89d1a34eaddf55d652b5213ea9d8d Author: parth4apple <72187062+parth4apple@users.noreply.github.com> Date: Tue May 14 09:01:15 2024 -0700 Student and Enrollment Schema modifications (#101) * feat: initial schema * feat: edit routes * feat: test and fix routes --------- Co-authored-by: Adhithya Ananthan <85322002+adhi0331@users.noreply.github.com> --- backend/src/controllers/progressNote.ts | 161 + .../controllers/types/progressNoteTypes.ts | 37 + backend/src/controllers/types/types.ts | 7 + .../{types.ts => types/userTypes.ts} | 17 +- backend/src/controllers/user.ts | 76 +- backend/src/errors/validation.ts | 20 +- backend/src/models/progressNote.ts | 13 + backend/src/models/student.ts | 6 + backend/src/routes/api.ts | 2 + backend/src/routes/progressNote.ts | 32 + backend/src/util/image.ts | 8 +- backend/src/validators/auth.ts | 2 +- backend/src/validators/progressNote.ts | 50 + frontend/next.config.js | 27 + frontend/package-lock.json | 2708 ++++++++++++++++- frontend/package.json | 2 + frontend/public/icons/back.svg | 3 + frontend/public/icons/close.svg | 3 + frontend/public/icons/delete.svg | 3 + frontend/public/icons/download.svg | 4 + frontend/public/icons/edit.svg | 5 + frontend/public/icons/edit_pencil.svg | 3 + frontend/public/icons/green_check_mark.svg | 4 + frontend/public/icons/green_download.svg | 4 + frontend/public/icons/left_arrow.svg | 3 + frontend/public/icons/mobile_download.svg | 5 + frontend/public/icons/mobile_plus.svg | 4 + frontend/public/icons/plus.svg | 3 + frontend/public/icons/red_delete.svg | 3 + frontend/public/icons/red_question_mark.svg | 5 + frontend/public/icons/right_arrow.svg | 3 + frontend/public/icons/search.svg | 3 + frontend/public/loading-spinner.png | Bin 0 -> 6026 bytes frontend/src/api/progressNotes.ts | 69 + frontend/src/api/students.ts | 1 + frontend/src/components/Button.tsx | 11 +- frontend/src/components/DebouncedInput.tsx | 10 +- frontend/src/components/Dropdown.tsx | 19 +- frontend/src/components/LoadingSpinner.tsx | 22 + .../components/Modals/ModalConfirmation.tsx | 77 + .../components/Modals/SaveCancelButtons.tsx | 86 + frontend/src/components/Navigation.tsx | 2 +- frontend/src/components/NoStudents.tsx | 15 + .../NotificationCard/NotificationCard.tsx | 14 +- .../components/ProfileForm/BasicInfoFrame.tsx | 4 +- .../ProfileForm/ContactInfoFrame.tsx | 2 +- .../ProfileForm/ProfileDialogContent.tsx | 35 +- .../ProgressNotes/DownloadNotesDialog.tsx | 122 + .../ProgressNotes/DownloadNotesPDF.tsx | 164 + .../src/components/ProgressNotes/EditNote.tsx | 265 ++ .../components/ProgressNotes/NotePreview.tsx | 185 ++ .../components/ProgressNotes/NotesFilter.tsx | 40 + .../ProgressNotes/NotesSelectionList.tsx | 82 + .../ProgressNotes/hooks/useProgressNotes.ts | 243 ++ .../src/components/ProgressNotes/types.ts | 8 + frontend/src/components/SaveCancelButtons.tsx | 46 - .../components/StudentForm/StudentInfo.tsx | 4 +- frontend/src/components/StudentFormButton.tsx | 29 +- .../components/StudentsTable/FilterFns.tsx | 31 +- .../StudentsTable/StudentsTable.tsx | 64 +- .../src/components/StudentsTable/THead.tsx | 27 +- frontend/src/components/Textfield.tsx | 4 +- frontend/src/components/ui/calendar.tsx | 14 +- frontend/src/components/ui/dropdown.tsx | 12 +- frontend/src/constants/navigation.tsx | 25 + frontend/src/contexts/program.tsx | 49 + frontend/src/lib/validateDate.ts | 21 + frontend/src/pages/_app.tsx | 7 +- frontend/src/pages/notes.tsx | 114 + frontend/src/pages/notifications.tsx | 4 +- frontend/src/pages/profile.tsx | 74 +- frontend/src/pages/programs.tsx | 86 +- frontend/src/styles/Button.module.css | 23 +- frontend/src/styles/LoadingSpinner.module.css | 12 + frontend/src/styles/global.css | 12 + frontend/tailwind.config.ts | 6 + 76 files changed, 4879 insertions(+), 487 deletions(-) create mode 100644 backend/src/controllers/progressNote.ts create mode 100644 backend/src/controllers/types/progressNoteTypes.ts create mode 100644 backend/src/controllers/types/types.ts rename backend/src/controllers/{types.ts => types/userTypes.ts} (75%) create mode 100644 backend/src/models/progressNote.ts create mode 100644 backend/src/routes/progressNote.ts create mode 100644 backend/src/validators/progressNote.ts create mode 100644 frontend/public/icons/back.svg create mode 100644 frontend/public/icons/close.svg create mode 100644 frontend/public/icons/delete.svg create mode 100644 frontend/public/icons/download.svg create mode 100644 frontend/public/icons/edit.svg create mode 100644 frontend/public/icons/edit_pencil.svg create mode 100644 frontend/public/icons/green_check_mark.svg create mode 100644 frontend/public/icons/green_download.svg create mode 100644 frontend/public/icons/left_arrow.svg create mode 100644 frontend/public/icons/mobile_download.svg create mode 100644 frontend/public/icons/mobile_plus.svg create mode 100644 frontend/public/icons/plus.svg create mode 100644 frontend/public/icons/red_delete.svg create mode 100644 frontend/public/icons/red_question_mark.svg create mode 100644 frontend/public/icons/right_arrow.svg create mode 100644 frontend/public/icons/search.svg create mode 100644 frontend/public/loading-spinner.png create mode 100644 frontend/src/api/progressNotes.ts create mode 100644 frontend/src/components/LoadingSpinner.tsx create mode 100644 frontend/src/components/Modals/ModalConfirmation.tsx create mode 100644 frontend/src/components/Modals/SaveCancelButtons.tsx create mode 100644 frontend/src/components/NoStudents.tsx create mode 100644 frontend/src/components/ProgressNotes/DownloadNotesDialog.tsx create mode 100644 frontend/src/components/ProgressNotes/DownloadNotesPDF.tsx create mode 100644 frontend/src/components/ProgressNotes/EditNote.tsx create mode 100644 frontend/src/components/ProgressNotes/NotePreview.tsx create mode 100644 frontend/src/components/ProgressNotes/NotesFilter.tsx create mode 100644 frontend/src/components/ProgressNotes/NotesSelectionList.tsx create mode 100644 frontend/src/components/ProgressNotes/hooks/useProgressNotes.ts create mode 100644 frontend/src/components/ProgressNotes/types.ts delete mode 100644 frontend/src/components/SaveCancelButtons.tsx create mode 100644 frontend/src/contexts/program.tsx create mode 100644 frontend/src/lib/validateDate.ts create mode 100644 frontend/src/pages/notes.tsx create mode 100644 frontend/src/styles/LoadingSpinner.module.css diff --git a/backend/src/controllers/progressNote.ts b/backend/src/controllers/progressNote.ts new file mode 100644 index 00000000..e5d1676d --- /dev/null +++ b/backend/src/controllers/progressNote.ts @@ -0,0 +1,161 @@ +import { NextFunction, Request, Response } from "express"; +import { validationResult } from "express-validator"; + +import { ValidationError } from "../errors"; +import ProgressNote from "../models/progressNote"; +import StudentModel from "../models/student"; +import UserModel from "../models/user"; +import validationErrorParser from "../util/validationErrorParser"; + +import { + CreateProgressNoteRequestBody, + DeleteProgressNoteRequestBody, + EditProgressNoteRequestBody, + ExistingProgressNoteType, + ProgressNoteType, +} from "./types/progressNoteTypes"; +import { LoginUserRequestBody } from "./types/userTypes"; + +export const createProgressNote = async ( + req: Request, Record, CreateProgressNoteRequestBody>, + res: Response, + next: NextFunction, +) => { + try { + const { uid, studentId } = req.body; + + const user = await UserModel.findById(uid); + if (!user) { + throw ValidationError.USER_NOT_FOUND; + } + + const student = await StudentModel.findById(studentId); + if (!student) { + throw ValidationError.STUDENT_NOT_FOUND; + } + + const errors = validationResult(req); + validationErrorParser(errors); + + const newProgressNote = { + ...req.body, + lastEditedBy: user.name, + userId: uid, + } as ProgressNoteType; + + const createdProgressNote = await ProgressNote.create(newProgressNote); + + // Add the progress note to the student + await StudentModel.findOneAndUpdate( + { _id: newProgressNote.studentId }, + { $push: { progressNotes: createdProgressNote._id } }, + ); + + res.status(201).json(createdProgressNote); + } catch (error) { + next(error); + } +}; + +export const editProgressNote = async ( + req: Request, Record, EditProgressNoteRequestBody>, + res: Response, + next: NextFunction, +) => { + try { + const { uid } = req.body; + + const user = await UserModel.findById(uid); + if (!user) { + throw ValidationError.USER_NOT_FOUND; + } + + if (user.accountType !== "admin") { + throw ValidationError.UNAUTHORIZED_USER; + } + + const errors = validationResult(req); + validationErrorParser(errors); + + const newProgressNote = { + ...req.body, + lastEditedBy: user.name, + userId: uid, + } as ExistingProgressNoteType; + + const editedProgressNote = await ProgressNote.findOneAndUpdate( + { _id: newProgressNote._id }, + newProgressNote, + { new: true }, //returns updated document + ); + + if (!editedProgressNote) { + throw ValidationError.PROGRESS_NOTE_NOT_FOUND; + } + + res.status(200).json(editedProgressNote); + } catch (error) { + next(error); + } +}; + +export const deleteProgressNote = async ( + req: Request, Record, DeleteProgressNoteRequestBody>, + res: Response, + next: NextFunction, +) => { + try { + const { noteId, studentId, uid } = req.body; + + const user = await UserModel.findById(uid); + if (!user) { + throw ValidationError.USER_NOT_FOUND; + } + + if (user.accountType !== "admin") { + throw ValidationError.UNAUTHORIZED_USER; + } + + const errors = validationResult(req); + validationErrorParser(errors); + + const deletedProgressNote = await ProgressNote.findOneAndDelete({ _id: noteId }); + + if (!deletedProgressNote) { + throw ValidationError.PROGRESS_NOTE_NOT_FOUND; + } + + const student = await StudentModel.findOneAndUpdate( + { _id: studentId }, + { $pull: { progressNotes: noteId } }, + ); + + if (!student) { + throw ValidationError.STUDENT_NOT_FOUND; + } + + res.status(200).json(deletedProgressNote); + } catch (error) { + next(error); + } +}; + +export const getAllProgressNotes = async ( + req: Request, Record, LoginUserRequestBody>, + res: Response, + next: NextFunction, +) => { + try { + const { uid } = req.body; + const user = await UserModel.findById(uid); + if (!user) { + throw ValidationError.USER_NOT_FOUND; + } + + const allNotes = await ProgressNote.find(); + + res.status(200).json(allNotes); + } catch (error) { + next(error); + } +}; diff --git a/backend/src/controllers/types/progressNoteTypes.ts b/backend/src/controllers/types/progressNoteTypes.ts new file mode 100644 index 00000000..e526e730 --- /dev/null +++ b/backend/src/controllers/types/progressNoteTypes.ts @@ -0,0 +1,37 @@ +import { Schema } from "mongoose"; + +export type ProgressNoteType = { + studentId: Schema.Types.ObjectId; + userId: string; + lastEditedBy: string; + dateLastUpdated: Date; + content: string; +}; + +export type ExistingProgressNoteType = { + _id: Schema.Types.ObjectId; + userId: string; + lastEditedBy: string; + dateLastUpdated: Date; + content: string; +}; + +export type CreateProgressNoteRequestBody = { + studentId: Schema.Types.ObjectId; + uid: string; + dateLastUpdated: Date; + content: string; +}; + +export type EditProgressNoteRequestBody = { + _id: Schema.Types.ObjectId; + uid: string; + dateLastUpdated: Date; + content: string; +}; + +export type DeleteProgressNoteRequestBody = { + uid: string; + noteId: Schema.Types.ObjectId; + studentId: Schema.Types.ObjectId; +}; diff --git a/backend/src/controllers/types/types.ts b/backend/src/controllers/types/types.ts new file mode 100644 index 00000000..2f755e63 --- /dev/null +++ b/backend/src/controllers/types/types.ts @@ -0,0 +1,7 @@ +import { Request } from "express"; + +export type UserId = { + uid: string; +}; + +export type UserIdRequestBody = Request & UserId; diff --git a/backend/src/controllers/types.ts b/backend/src/controllers/types/userTypes.ts similarity index 75% rename from backend/src/controllers/types.ts rename to backend/src/controllers/types/userTypes.ts index 361647bc..8294b4d8 100644 --- a/backend/src/controllers/types.ts +++ b/backend/src/controllers/types/userTypes.ts @@ -1,5 +1,7 @@ import { Request } from "express"; +import { UserId } from "./types"; + export type CreateUserRequestBody = { name: string; accountType: "admin" | "team"; @@ -11,13 +13,7 @@ export type LoginUserRequestBody = { uid: string; }; -type UserId = { - userId: string; -}; - -export type UserIdRequest = Request & UserId; - -export type EditNameRequestBody = { +export type EditNameRequestBody = UserId & { newName: string; }; @@ -42,7 +38,6 @@ export type SaveImageRequest = { }; }; -export type EditPhotoRequest = Request & - UserId & { - rawBody?: Buffer; - }; +export type EditPhotoRequestBody = Request, Record, UserId> & { + rawBody?: Buffer; +}; diff --git a/backend/src/controllers/user.ts b/backend/src/controllers/user.ts index 2394ce36..e4e9a660 100644 --- a/backend/src/controllers/user.ts +++ b/backend/src/controllers/user.ts @@ -12,15 +12,15 @@ import { firebaseAdminAuth } from "../util/firebase"; import { handleImageParsing } from "../util/image"; import validationErrorParser from "../util/validationErrorParser"; +import { UserIdRequestBody } from "./types/types"; import { CreateUserRequestBody, EditEmailRequestBody, EditLastChangedPasswordRequestBody, EditNameRequestBody, - EditPhotoRequest, + EditPhotoRequestBody, LoginUserRequestBody, - UserIdRequest, -} from "./types"; +} from "./types/userTypes"; export const createUser = async ( req: Request, Record, CreateUserRequestBody>, @@ -93,30 +93,32 @@ export const loginUser = async ( } }; -export const editPhoto = (req: Request, res: Response, nxt: NextFunction) => { +export const editPhoto = (req: EditPhotoRequestBody, res: Response, nxt: NextFunction) => { try { - const customReq = req as EditPhotoRequest; - //Validation logic inside handleImageParsing - handleImageParsing(customReq, res, nxt); + handleImageParsing(req, res, nxt); } catch (e) { console.log(e); nxt(e); } }; -export const getPhoto = async (req: Request, res: Response, nxt: NextFunction) => { +export const getPhoto = async ( + req: Request, Record, UserIdRequestBody>, + res: Response, + nxt: NextFunction, +) => { try { - const customReq = req as UserIdRequest; - const imageId = req.params.id; - const userId = customReq.userId; + const { uid } = req.body; + const { id: imageId } = req.params; + if (!mongoose.Types.ObjectId.isValid(imageId)) { return res .status(ValidationError.INVALID_MONGO_ID.status) .send({ error: ValidationError.INVALID_MONGO_ID.message }); } - const user = await UserModel.findById(userId); + const user = await UserModel.findById(uid); if (!user) { throw ValidationError.USER_NOT_FOUND; } @@ -126,7 +128,7 @@ export const getPhoto = async (req: Request, res: Response, nxt: NextFunction) = throw ValidationError.IMAGE_NOT_FOUND; } - if (image.userId !== userId) { + if (image.userId !== uid) { throw ValidationError.IMAGE_USER_MISMATCH; } @@ -142,23 +144,25 @@ export const getPhoto = async (req: Request, res: Response, nxt: NextFunction) = } }; -export const editName = async (req: Request, res: Response, nxt: NextFunction) => { +export const editName = async ( + req: Request, Record, EditNameRequestBody>, + res: Response, + nxt: NextFunction, +) => { try { - const customReq = req as UserIdRequest; - const { newName } = customReq.body as EditNameRequestBody; - const userId = customReq.userId; + const { uid, newName } = req.body; - const errors = validationResult(customReq); + const errors = validationResult(req); validationErrorParser(errors); - const user = await UserModel.findById(userId); + const user = await UserModel.findById(uid); if (!user) { throw ValidationError.USER_NOT_FOUND; } - await UserModel.findByIdAndUpdate(userId, { name: newName }); + await UserModel.findByIdAndUpdate(uid, { name: newName }); res.status(200).json(newName); } catch (error) { @@ -169,25 +173,27 @@ export const editName = async (req: Request, res: Response, nxt: NextFunction) = } }; -export const editEmail = async (req: Request, res: Response, nxt: NextFunction) => { +export const editEmail = async ( + req: Request, Record, EditEmailRequestBody>, + res: Response, + nxt: NextFunction, +) => { try { - const customReq = req as UserIdRequest; - const { newEmail } = customReq.body as EditEmailRequestBody; - const userId = customReq.userId; + const { uid, newEmail } = req.body; - const errors = validationResult(customReq); + const errors = validationResult(req); validationErrorParser(errors); - await firebaseAdminAuth.updateUser(userId, { email: newEmail }); + await firebaseAdminAuth.updateUser(uid, { email: newEmail }); - const user = await UserModel.findById(userId); + const user = await UserModel.findById(uid); if (!user) { throw ValidationError.USER_NOT_FOUND; } - await UserModel.findByIdAndUpdate(userId, { email: newEmail }); + await UserModel.findByIdAndUpdate(uid, { email: newEmail }); return res.status(200).json(newEmail); } catch (error) { @@ -195,23 +201,25 @@ export const editEmail = async (req: Request, res: Response, nxt: NextFunction) } }; -export const editLastChangedPassword = async (req: Request, res: Response, nxt: NextFunction) => { +export const editLastChangedPassword = async ( + req: Request, Record, EditLastChangedPasswordRequestBody>, + res: Response, + nxt: NextFunction, +) => { try { - const customReq = req as UserIdRequest; - const { currentDate } = customReq.body as EditLastChangedPasswordRequestBody; - const userId = customReq.userId; + const { uid, currentDate } = req.body; const errors = validationResult(req); validationErrorParser(errors); - const user = await UserModel.findById(userId); + const user = await UserModel.findById(uid); if (!user) { throw ValidationError.USER_NOT_FOUND; } - await UserModel.findByIdAndUpdate(userId, { lastChangedPassword: currentDate }); + await UserModel.findByIdAndUpdate(uid, { lastChangedPassword: currentDate }); res.status(200).json(currentDate); } catch (error) { diff --git a/backend/src/errors/validation.ts b/backend/src/errors/validation.ts index 2ca3318f..0ad6af68 100644 --- a/backend/src/errors/validation.ts +++ b/backend/src/errors/validation.ts @@ -2,20 +2,26 @@ import { CustomError } from "./errors"; const USER_CREATION_UNSUCCESSFUL = "User not created successfully"; const USER_NOT_FOUND = "User not found in database"; +const UNAUTHORIZED_USER = "User is not authorized to perform this action"; +const STUDENT_NOT_FOUND = "Student not found in database"; const IMAGE_EXCEED_SIZE = "Image size exceeds 3MB limit"; const IMAGE_UNSUPPORTED_TYPE = "Invalid file type. Only JPG, PNG, and WEBP are allowed."; const IMAGE_NOT_UPLOADED = "Image not uploaded successfully"; const IMAGE_NOT_FOUND = "Image was not found. Please make sure id passed in route is valid"; const INVALID_MONGO_ID = "Mongo ID was invalid. Please ensure that the id is correct"; const IMAGE_USER_MISMATCH = "Image does not belong to the user"; +const PROGRESS_NOTE_NOT_FOUND = "Progress note not found in database"; export class ValidationError extends CustomError { static USER_CREATION_UNSUCCESSFUL = new ValidationError(1, 400, USER_CREATION_UNSUCCESSFUL); - static USER_NOT_FOUND = new ValidationError(2, 400, USER_NOT_FOUND); - static IMAGE_EXCEED_SIZE = new ValidationError(3, 400, IMAGE_EXCEED_SIZE); - static IMAGE_UNSUPPORTED_TYPE = new ValidationError(4, 400, IMAGE_UNSUPPORTED_TYPE); - static IMAGE_NOT_UPLOADED = new ValidationError(5, 400, IMAGE_NOT_UPLOADED); - static IMAGE_NOT_FOUND = new ValidationError(6, 404, IMAGE_NOT_FOUND); - static INVALID_MONGO_ID = new ValidationError(7, 404, INVALID_MONGO_ID); - static IMAGE_USER_MISMATCH = new ValidationError(8, 404, IMAGE_USER_MISMATCH); + static USER_NOT_FOUND = new ValidationError(2, 404, USER_NOT_FOUND); + static UNAUTHORIZED_USER = new ValidationError(3, 401, UNAUTHORIZED_USER); + static STUDENT_NOT_FOUND = new ValidationError(4, 404, STUDENT_NOT_FOUND); + static IMAGE_EXCEED_SIZE = new ValidationError(5, 400, IMAGE_EXCEED_SIZE); + static IMAGE_UNSUPPORTED_TYPE = new ValidationError(6, 400, IMAGE_UNSUPPORTED_TYPE); + static IMAGE_NOT_UPLOADED = new ValidationError(7, 400, IMAGE_NOT_UPLOADED); + static IMAGE_NOT_FOUND = new ValidationError(8, 404, IMAGE_NOT_FOUND); + static INVALID_MONGO_ID = new ValidationError(9, 400, INVALID_MONGO_ID); + static IMAGE_USER_MISMATCH = new ValidationError(10, 401, IMAGE_USER_MISMATCH); + static PROGRESS_NOTE_NOT_FOUND = new ValidationError(11, 404, PROGRESS_NOTE_NOT_FOUND); } diff --git a/backend/src/models/progressNote.ts b/backend/src/models/progressNote.ts new file mode 100644 index 00000000..1f081e7b --- /dev/null +++ b/backend/src/models/progressNote.ts @@ -0,0 +1,13 @@ +import { InferSchemaType, Schema, model } from "mongoose"; + +const progressNoteSchema = new Schema({ + studentId: { type: Schema.Types.ObjectId, ref: "Student", required: true }, + userId: { type: String, ref: "User", required: true }, + lastEditedBy: { type: String, required: true }, + dateLastUpdated: { type: Date, required: true }, + content: { type: String, required: true }, +}); + +type ProgressNote = InferSchemaType; + +export default model("ProgressNotes", progressNoteSchema); diff --git a/backend/src/models/student.ts b/backend/src/models/student.ts index 1c46ae18..26242fed 100644 --- a/backend/src/models/student.ts +++ b/backend/src/models/student.ts @@ -40,6 +40,12 @@ const studentSchema = new Schema({ incidentForm: { type: String, required: true }, documents: { type: [String], required: true }, profilePicture: { type: Schema.Types.ObjectId, ref: "Image", required: false }, + progressNotes: { + type: [Schema.Types.ObjectId], + ref: "ProgressNote", + default: [], + required: false, + }, //Will contain list of all dietary restrictions dietary: { type: [String] }, diff --git a/backend/src/routes/api.ts b/backend/src/routes/api.ts index 0bd73c2c..684c22d0 100644 --- a/backend/src/routes/api.ts +++ b/backend/src/routes/api.ts @@ -1,6 +1,7 @@ import express from "express"; import programRoutes from "./program"; +import progressNoteRoutes from "./progressNote"; import studentRoutes from "./student"; import userRouter from "./user"; @@ -10,5 +11,6 @@ const router = express.Router(); router.use("/user", userRouter); router.use("/student", studentRoutes); router.use("/program", programRoutes); +router.use("/progressNote", progressNoteRoutes); export default router; diff --git a/backend/src/routes/progressNote.ts b/backend/src/routes/progressNote.ts new file mode 100644 index 00000000..6e229c88 --- /dev/null +++ b/backend/src/routes/progressNote.ts @@ -0,0 +1,32 @@ +import express from "express"; + +import * as ProgressNoteController from "../controllers/progressNote"; +import { verifyAuthToken } from "../validators/auth"; +import * as ProgressNoteValidator from "../validators/progressNote"; + +const router = express.Router(); + +router.post( + "/create", + [verifyAuthToken], + ProgressNoteValidator.createProgressNote, + ProgressNoteController.createProgressNote, +); + +router.put( + "/edit", + [verifyAuthToken], + ProgressNoteValidator.editProgressNote, + ProgressNoteController.editProgressNote, +); + +router.delete( + "/delete", + [verifyAuthToken], + ProgressNoteValidator.deleteProgressNote, + ProgressNoteController.deleteProgressNote, +); + +router.get("/all", [verifyAuthToken], ProgressNoteController.getAllProgressNotes); + +export default router; diff --git a/backend/src/util/image.ts b/backend/src/util/image.ts index ee754574..7ef31726 100644 --- a/backend/src/util/image.ts +++ b/backend/src/util/image.ts @@ -2,7 +2,7 @@ import busboy from "busboy"; import { NextFunction, Response } from "express"; import mongoose from "mongoose"; -import { EditPhotoRequest, SaveImageRequest } from "../controllers/types"; +import { EditPhotoRequestBody, SaveImageRequest } from "../controllers/types/userTypes"; import { ValidationError } from "../errors"; import { ServiceError } from "../errors/service"; import { Image } from "../models/image"; @@ -68,10 +68,10 @@ async function saveImage(req: SaveImageRequest) { } } -export function handleImageParsing(req: EditPhotoRequest, res: Response, nxt: NextFunction) { +export function handleImageParsing(req: EditPhotoRequestBody, res: Response, nxt: NextFunction) { let previousImageId = ""; //req.userId is assigned in verifyAuthToken middleware - const userId: string = req.userId; + const uid = req.body.uid; const bb = busboy({ headers: req.headers }); @@ -92,7 +92,7 @@ export function handleImageParsing(req: EditPhotoRequest, res: Response, nxt: Ne const saveImageRequest: SaveImageRequest = { body: { previousImageId, - userId, + userId: uid, }, file: { buffer: fileBuffer, diff --git a/backend/src/validators/auth.ts b/backend/src/validators/auth.ts index 99fea377..3efdc5e2 100644 --- a/backend/src/validators/auth.ts +++ b/backend/src/validators/auth.ts @@ -34,7 +34,7 @@ const verifyAuthToken = async (req: RequestWithUserId, res: Response, next: Next let userInfo: DecodedIdToken; try { userInfo = await decodeAuthToken(token); - req.userId = userInfo.uid; + // req.userId = userInfo.uid; } catch (e) { return res .status(AuthError.INVALID_AUTH_TOKEN.status) diff --git a/backend/src/validators/progressNote.ts b/backend/src/validators/progressNote.ts new file mode 100644 index 00000000..3fdb8caa --- /dev/null +++ b/backend/src/validators/progressNote.ts @@ -0,0 +1,50 @@ +import { ValidationChain, body } from "express-validator"; + +export const createProgressNote: ValidationChain[] = [ + body("studentId") + .exists() + .withMessage("Student ID cannot be empty.") + .isString() + .withMessage("Student ID must be a string."), + body("dateLastUpdated") + .notEmpty() + .withMessage("Date cannot be empty.") + .isISO8601() + .withMessage("Invalid Date format."), + body("content") + .isString() + .withMessage("Content must be a string.") + .notEmpty() + .withMessage("Content cannot be empty."), +]; + +export const editProgressNote: ValidationChain[] = [ + body("_id") + .exists() + .withMessage("Note ID cannot be empty.") + .isString() + .withMessage("Note ID must be a string."), + body("dateLastUpdated") + .notEmpty() + .withMessage("Date cannot be empty.") + .isISO8601() + .withMessage("Invalid Date format."), + body("content") + .isString() + .withMessage("Content must be a string.") + .notEmpty() + .withMessage("Content cannot be empty."), +]; + +export const deleteProgressNote: ValidationChain[] = [ + body("noteId") + .exists() + .withMessage("Note ID cannot be empty.") + .isString() + .withMessage("Note ID must be a string."), + body("studentId") + .exists() + .withMessage("Student ID cannot be empty.") + .isString() + .withMessage("Student ID must be a string."), +]; diff --git a/frontend/next.config.js b/frontend/next.config.js index 0153bfaa..f4cc85ee 100644 --- a/frontend/next.config.js +++ b/frontend/next.config.js @@ -5,6 +5,33 @@ const nextConfig = { unoptimized: true, }, trailingSlash: true, + + // https://react-svgr.com/docs/next/ + webpack(config) { + // Grab the existing rule that handles SVG imports + const fileLoaderRule = config.module.rules.find((rule) => rule.test?.test?.(".svg")); + + config.module.rules.push( + // Reapply the existing rule, but only for svg imports ending in ?url + { + ...fileLoaderRule, + test: /\.svg$/i, + resourceQuery: /url/, // *.svg?url + }, + // Convert all other *.svg imports to React components + { + test: /\.svg$/i, + issuer: fileLoaderRule.issuer, + resourceQuery: { not: [...fileLoaderRule.resourceQuery.not, /url/] }, // exclude if *.svg?url + use: ["@svgr/webpack"], + }, + ); + + // Modify the file loader rule to ignore *.svg, since we have it handled now. + fileLoaderRule.exclude = /\.svg$/i; + + return config; + }, }; module.exports = nextConfig; diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 77700127..5fd73087 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -13,6 +13,7 @@ "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-slot": "^1.0.2", + "@react-pdf/renderer": "^3.4.4", "@tanstack/match-sorter-utils": "^8.11.8", "@tanstack/react-table": "^8.12.0", "@testing-library/jest-dom": "^6.1.5", @@ -37,6 +38,7 @@ }, "devDependencies": { "@babel/preset-typescript": "^7.23.3", + "@svgr/webpack": "^8.1.0", "@types/jest": "^29.5.11", "@types/node": "^20", "@types/react": "^18", @@ -83,7 +85,6 @@ "version": "2.2.1", "devOptional": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -161,10 +162,10 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.23.5", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz", + "integrity": "sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==", "devOptional": true, - "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" } @@ -173,7 +174,6 @@ "version": "7.23.6", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", @@ -203,7 +203,6 @@ "version": "2.2.3", "devOptional": true, "license": "MIT", - "peer": true, "bin": { "json5": "lib/cli.js" }, @@ -215,7 +214,6 @@ "version": "6.3.1", "devOptional": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -224,7 +222,6 @@ "version": "7.23.6", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", @@ -246,11 +243,22 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-compilation-targets": { "version": "7.23.6", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/compat-data": "^7.23.5", "@babel/helper-validator-option": "^7.23.5", @@ -266,7 +274,6 @@ "version": "5.1.1", "devOptional": true, "license": "ISC", - "peer": true, "dependencies": { "yallist": "^3.0.2" } @@ -275,7 +282,6 @@ "version": "6.3.1", "devOptional": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -283,20 +289,20 @@ "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { "version": "3.1.1", "devOptional": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.23.6", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.4.tgz", + "integrity": "sha512-lG75yeuUSVu0pIcbhiYMXBXANHrpUPaOfu7ryAzskCgKUHuAxRQI5ssrtmF0X9UXldPlvT0XM/A4F44OXRt6iQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-replace-supers": "^7.24.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" @@ -316,6 +322,48 @@ "semver": "bin/semver.js" } }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, "node_modules/@babel/helper-environment-visitor": { "version": "7.22.20", "devOptional": true, @@ -340,7 +388,6 @@ "version": "7.22.5", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -350,8 +397,9 @@ }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.23.0" }, @@ -360,11 +408,12 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", + "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", "devOptional": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.22.15" + "@babel/types": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -390,8 +439,9 @@ }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -400,20 +450,39 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-replace-supers": { + "node_modules/@babel/helper-remap-async-to-generator": { "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", + "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5" }, "engines": { @@ -479,11 +548,24 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helpers": { "version": "7.23.6", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/template": "^7.22.15", "@babel/traverse": "^7.23.6", @@ -563,9 +645,10 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.6", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", + "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", "devOptional": true, - "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -573,11 +656,86 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.4.tgz", + "integrity": "sha512-qpl6vOOEEzTLLcsuqYYo8yDtrTocmu2xkGvgNebvPjT9DTtfFYGmgDqY+rBYXNlqL4s9qLDn6xkrJv4RxAPiTA==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz", + "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz", + "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.24.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz", + "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -601,7 +759,6 @@ "version": "7.12.13", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -609,11 +766,79 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz", + "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz", + "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -625,7 +850,6 @@ "version": "7.8.3", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -651,7 +875,6 @@ "version": "7.10.4", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -663,7 +886,6 @@ "version": "7.8.3", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -675,7 +897,6 @@ "version": "7.10.4", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -687,7 +908,6 @@ "version": "7.8.3", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -699,7 +919,6 @@ "version": "7.8.3", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -711,7 +930,6 @@ "version": "7.8.3", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -719,11 +937,25 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -748,31 +980,1029 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.23.3", + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz", + "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz", + "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", + "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-remap-async-to-generator": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz", + "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.4.tgz", + "integrity": "sha512-nIFUZIpGKDf9O9ttyRXpHFpKC+X3Y5mtshZONuEUYBomAKoM4y029Jr+uB1bHGPhNmK8YXHevDtKDOLmtRrp6g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz", + "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.4.tgz", + "integrity": "sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.4", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz", + "integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-replace-supers": "^7.24.1", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz", + "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/template": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz", + "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz", + "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz", + "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz", + "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz", + "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz", + "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz", + "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz", + "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz", + "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz", + "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz", + "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz", + "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz", + "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz", + "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz", + "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz", + "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz", + "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz", + "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz", + "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz", + "integrity": "sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz", + "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-replace-supers": "^7.24.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz", + "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz", + "integrity": "sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz", + "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", + "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz", + "integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz", + "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.24.1.tgz", + "integrity": "sha512-QXp1U9x0R7tkiGB0FOk8o74jhnap0FlZ5gNkRIWdG3eP+SvMFg118e1zaWewDzgABb106QSKpVsD3Wgd8t6ifA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.1.tgz", + "integrity": "sha512-mvoQg2f9p2qlpDQRBC7M3c3XTr0k7cp/0+kFKKO/7Gtu0LSw16eKB+Fabe2bDT/UpsyasTBBkAnbdsLrkD5XMw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", + "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/types": "^7.23.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", + "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", + "dev": true, + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.1.tgz", + "integrity": "sha512-+pWEAaDJvSm9aFvJNpLiM2+ktl2Sn2U5DdyiWdZBxmLc6+xGt88dvFqsHiAiDS+8WqUwbDfkKz9jRxK3M0k+kA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz", + "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz", + "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz", + "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz", + "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz", + "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz", + "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz", + "integrity": "sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.23.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.23.6", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", + "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz", + "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz", + "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz", + "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.4.tgz", + "integrity": "sha512-7Kl6cSmYkak0FK/FXjSEnLJ1N9T/WA2RkMhu17gZ/dsxKJUuTYNIylahPTzqpLyJN4WhDif8X0XK1R8Wsguo/A==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.24.4", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.4", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.24.1", + "@babel/plugin-syntax-import-attributes": "^7.24.1", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.1", + "@babel/plugin-transform-async-generator-functions": "^7.24.3", + "@babel/plugin-transform-async-to-generator": "^7.24.1", + "@babel/plugin-transform-block-scoped-functions": "^7.24.1", + "@babel/plugin-transform-block-scoping": "^7.24.4", + "@babel/plugin-transform-class-properties": "^7.24.1", + "@babel/plugin-transform-class-static-block": "^7.24.4", + "@babel/plugin-transform-classes": "^7.24.1", + "@babel/plugin-transform-computed-properties": "^7.24.1", + "@babel/plugin-transform-destructuring": "^7.24.1", + "@babel/plugin-transform-dotall-regex": "^7.24.1", + "@babel/plugin-transform-duplicate-keys": "^7.24.1", + "@babel/plugin-transform-dynamic-import": "^7.24.1", + "@babel/plugin-transform-exponentiation-operator": "^7.24.1", + "@babel/plugin-transform-export-namespace-from": "^7.24.1", + "@babel/plugin-transform-for-of": "^7.24.1", + "@babel/plugin-transform-function-name": "^7.24.1", + "@babel/plugin-transform-json-strings": "^7.24.1", + "@babel/plugin-transform-literals": "^7.24.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.1", + "@babel/plugin-transform-member-expression-literals": "^7.24.1", + "@babel/plugin-transform-modules-amd": "^7.24.1", + "@babel/plugin-transform-modules-commonjs": "^7.24.1", + "@babel/plugin-transform-modules-systemjs": "^7.24.1", + "@babel/plugin-transform-modules-umd": "^7.24.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.24.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", + "@babel/plugin-transform-numeric-separator": "^7.24.1", + "@babel/plugin-transform-object-rest-spread": "^7.24.1", + "@babel/plugin-transform-object-super": "^7.24.1", + "@babel/plugin-transform-optional-catch-binding": "^7.24.1", + "@babel/plugin-transform-optional-chaining": "^7.24.1", + "@babel/plugin-transform-parameters": "^7.24.1", + "@babel/plugin-transform-private-methods": "^7.24.1", + "@babel/plugin-transform-private-property-in-object": "^7.24.1", + "@babel/plugin-transform-property-literals": "^7.24.1", + "@babel/plugin-transform-regenerator": "^7.24.1", + "@babel/plugin-transform-reserved-words": "^7.24.1", + "@babel/plugin-transform-shorthand-properties": "^7.24.1", + "@babel/plugin-transform-spread": "^7.24.1", + "@babel/plugin-transform-sticky-regex": "^7.24.1", + "@babel/plugin-transform-template-literals": "^7.24.1", + "@babel/plugin-transform-typeof-symbol": "^7.24.1", + "@babel/plugin-transform-unicode-escapes": "^7.24.1", + "@babel/plugin-transform-unicode-property-regex": "^7.24.1", + "@babel/plugin-transform-unicode-regex": "^7.24.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.1", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.23.6", + "node_modules/@babel/preset-react": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.1.tgz", + "integrity": "sha512-eFa8up2/8cZXLIpkafhaADTXSnl7IsUFCYenRWrARBz0/qZwcT0RBXpys0LJU4+WfPoF2ZG6ew6s2V6izMCwRA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.23.6", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-typescript": "^7.23.3" + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-transform-react-display-name": "^7.24.1", + "@babel/plugin-transform-react-jsx": "^7.23.4", + "@babel/plugin-transform-react-jsx-development": "^7.22.5", + "@babel/plugin-transform-react-pure-annotations": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -799,6 +2029,12 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, "node_modules/@babel/runtime": { "version": "7.23.9", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", @@ -812,13 +2048,14 @@ } }, "node_modules/@babel/template": { - "version": "7.22.15", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", "devOptional": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -828,7 +2065,6 @@ "version": "7.23.6", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.23.5", "@babel/generator": "^7.23.6", @@ -849,15 +2085,15 @@ "version": "11.12.0", "devOptional": true, "license": "MIT", - "peer": true, "engines": { "node": ">=4" } }, "node_modules/@babel/types": { - "version": "7.23.6", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", "devOptional": true, - "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -2856,53 +4092,483 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz", "integrity": "sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-layout-effect": "1.0.1" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.1.tgz", + "integrity": "sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@react-pdf/fns": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@react-pdf/fns/-/fns-2.2.1.tgz", + "integrity": "sha512-s78aDg0vDYaijU5lLOCsUD+qinQbfOvcNeaoX9AiE7+kZzzCo6B/nX+l48cmt9OosJmvZvE9DWR9cLhrhOi2pA==", + "dependencies": { + "@babel/runtime": "^7.20.13" + } + }, + "node_modules/@react-pdf/font": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@react-pdf/font/-/font-2.5.1.tgz", + "integrity": "sha512-Hyb2zBb92Glc3lvhmJfy4dO2Mj29KB26Uk12Ua9EhKAdiuCTLBqgP8Oe1cGwrvDI7xA4OOcwvBMdYh0vhOUHzA==", + "dependencies": { + "@babel/runtime": "^7.20.13", + "@react-pdf/types": "^2.5.0", + "cross-fetch": "^3.1.5", + "fontkit": "^2.0.2", + "is-url": "^1.2.4" + } + }, + "node_modules/@react-pdf/image": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/@react-pdf/image/-/image-2.3.6.tgz", + "integrity": "sha512-7iZDYZrZlJqNzS6huNl2XdMcLFUo68e6mOdzQeJ63d5eApdthhSHBnkGzHfLhH5t8DCpZNtClmklzuLL63ADfw==", + "dependencies": { + "@babel/runtime": "^7.20.13", + "@react-pdf/png-js": "^2.3.1", + "cross-fetch": "^3.1.5", + "jay-peg": "^1.0.2" + } + }, + "node_modules/@react-pdf/layout": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/@react-pdf/layout/-/layout-3.12.1.tgz", + "integrity": "sha512-BxSeykDxvADlpe4OGtQ7NH46QXq3uImAYsTHOPLCwbXMniQ1O3uCBx7H+HthxkCNshgYVPp9qS3KyvQv/oIZwg==", + "dependencies": { + "@babel/runtime": "^7.20.13", + "@react-pdf/fns": "2.2.1", + "@react-pdf/image": "^2.3.6", + "@react-pdf/pdfkit": "^3.1.10", + "@react-pdf/primitives": "^3.1.1", + "@react-pdf/stylesheet": "^4.2.5", + "@react-pdf/textkit": "^4.4.1", + "@react-pdf/types": "^2.5.0", + "cross-fetch": "^3.1.5", + "emoji-regex": "^10.3.0", + "queue": "^6.0.1", + "yoga-layout": "^2.0.1" + } + }, + "node_modules/@react-pdf/layout/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==" + }, + "node_modules/@react-pdf/pdfkit": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/@react-pdf/pdfkit/-/pdfkit-3.1.10.tgz", + "integrity": "sha512-P/qPBtCFo2HDJD0i6NfbmoBRrsOVO8CIogYsefwG4fklTo50zNgnMM5U1WLckTuX8Qt1ThiQuokmTG5arheblA==", + "dependencies": { + "@babel/runtime": "^7.20.13", + "@react-pdf/png-js": "^2.3.1", + "browserify-zlib": "^0.2.0", + "crypto-js": "^4.2.0", + "fontkit": "^2.0.2", + "jay-peg": "^1.0.2", + "vite-compatible-readable-stream": "^3.6.1" + } + }, + "node_modules/@react-pdf/png-js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@react-pdf/png-js/-/png-js-2.3.1.tgz", + "integrity": "sha512-pEZ18I4t1vAUS4lmhvXPmXYP4PHeblpWP/pAlMMRkEyP7tdAeHUN7taQl9sf9OPq7YITMY3lWpYpJU6t4CZgZg==", + "dependencies": { + "browserify-zlib": "^0.2.0" + } + }, + "node_modules/@react-pdf/primitives": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@react-pdf/primitives/-/primitives-3.1.1.tgz", + "integrity": "sha512-miwjxLwTnO3IjoqkTVeTI+9CdyDggwekmSLhVCw+a/7FoQc+gF3J2dSKwsHvAcVFM0gvU8mzCeTofgw0zPDq0w==" + }, + "node_modules/@react-pdf/render": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@react-pdf/render/-/render-3.4.4.tgz", + "integrity": "sha512-CfGxWmVgrY3JgmB1iMnz2W6Ck+8pisZeFt8vGlxP+JfT+0onr208pQvGSV5KwA9LGhAdABxqc/+y17V3vtKdFA==", + "dependencies": { + "@babel/runtime": "^7.20.13", + "@react-pdf/fns": "2.2.1", + "@react-pdf/primitives": "^3.1.1", + "@react-pdf/textkit": "^4.4.1", + "@react-pdf/types": "^2.5.0", + "abs-svg-path": "^0.1.1", + "color-string": "^1.9.1", + "normalize-svg-path": "^1.1.0", + "parse-svg-path": "^0.1.2", + "svg-arc-to-cubic-bezier": "^3.2.0" + } + }, + "node_modules/@react-pdf/renderer": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@react-pdf/renderer/-/renderer-3.4.4.tgz", + "integrity": "sha512-j1TWMHHXDeHdoQE3xjhBh0MZ2rn7wHIlP/uglr/EJZXqnPbfg6bfLzRJCM6bs+XJV3d8+zLQjHf6sF/fWcBDfg==", + "dependencies": { + "@babel/runtime": "^7.20.13", + "@react-pdf/font": "^2.5.1", + "@react-pdf/layout": "^3.12.1", + "@react-pdf/pdfkit": "^3.1.10", + "@react-pdf/primitives": "^3.1.1", + "@react-pdf/render": "^3.4.4", + "@react-pdf/types": "^2.5.0", + "events": "^3.3.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "queue": "^6.0.1", + "scheduler": "^0.17.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-pdf/renderer/node_modules/scheduler": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.17.0.tgz", + "integrity": "sha512-7rro8Io3tnCPuY4la/NuI5F2yfESpnfZyT6TtkXnSWVkcu0BCDJ+8gk5ozUaFaxpIyNuWAPXrH0yFcSi28fnDA==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/@react-pdf/stylesheet": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@react-pdf/stylesheet/-/stylesheet-4.2.5.tgz", + "integrity": "sha512-XnmapeCW+hDuNdVwpuvO04WKv71wAs8aH+saIq29Bo2fp1SxznHTcQArTZtK6Wgr/E9BHXeB2iAPpUZuI6G+xA==", + "dependencies": { + "@babel/runtime": "^7.20.13", + "@react-pdf/fns": "2.2.1", + "@react-pdf/types": "^2.5.0", + "color-string": "^1.9.1", + "hsl-to-hex": "^1.0.0", + "media-engine": "^1.0.3", + "postcss-value-parser": "^4.1.0" + } + }, + "node_modules/@react-pdf/textkit": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@react-pdf/textkit/-/textkit-4.4.1.tgz", + "integrity": "sha512-Jl9wdTqIvJ5pX+vAGz0EOhP7ut5Two9H6CzTKo/YYPeD79cM2yTXF3JzTERBC28y7LR0Waq9D2LHQjI+b/EYUQ==", + "dependencies": { + "@babel/runtime": "^7.20.13", + "@react-pdf/fns": "2.2.1", + "bidi-js": "^1.0.2", + "hyphen": "^1.6.4", + "unicode-properties": "^1.4.1" + } + }, + "node_modules/@react-pdf/types": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@react-pdf/types/-/types-2.5.0.tgz", + "integrity": "sha512-XsVRkt0hQ60I4e3leAVt+aZR3KJCaJd179BfJHAv4F4x6Vq3yqkry8lcbUWKGKDw1j3/8sW4FsgGR41SFvsG9A==" + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.6.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "devOptional": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.0", + "devOptional": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "devOptional": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "dev": true, + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/core/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "engines": { + "node": ">=14" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" } }, - "node_modules/@radix-ui/rect": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.1.tgz", - "integrity": "sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==", + "node_modules/@svgr/plugin-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.13.10" + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" } }, - "node_modules/@rushstack/eslint-patch": { - "version": "1.6.1", + "node_modules/@svgr/plugin-svgo": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", + "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", "dev": true, - "license": "MIT" - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "devOptional": true, - "license": "MIT" - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.0", - "devOptional": true, - "license": "BSD-3-Clause", - "peer": true, "dependencies": { - "type-detect": "4.0.8" + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "devOptional": true, - "license": "BSD-3-Clause", - "peer": true, + "node_modules/@svgr/webpack": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", + "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", + "dev": true, "dependencies": { - "@sinonjs/commons": "^3.0.0" + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" } }, "node_modules/@swc/helpers": { @@ -3074,6 +4740,15 @@ "react-dom": "^18.0.0" } }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/@types/aria-query": { "version": "5.0.4", "license": "MIT" @@ -3408,6 +5083,11 @@ "dev": true, "license": "ISC" }, + "node_modules/abs-svg-path": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/abs-svg-path/-/abs-svg-path-0.1.1.tgz", + "integrity": "sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA==" + }, "node_modules/acorn": { "version": "8.11.2", "dev": true, @@ -3804,6 +5484,54 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", "devOptional": true, @@ -3847,6 +5575,33 @@ "version": "1.0.2", "license": "MIT" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "license": "MIT", @@ -3854,6 +5609,12 @@ "node": ">=8" } }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, "node_modules/brace-expansion": { "version": "1.1.11", "devOptional": true, @@ -3873,8 +5634,26 @@ "node": ">=8" } }, + "node_modules/brotli": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz", + "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==", + "dependencies": { + "base64-js": "^1.1.2" + } + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dependencies": { + "pako": "~1.0.5" + } + }, "node_modules/browserslist": { - "version": "4.22.2", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "devOptional": true, "funding": [ { @@ -3890,10 +5669,9 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" }, @@ -3976,7 +5754,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001570", + "version": "1.0.30001612", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", + "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", "funding": [ { "type": "opencollective", @@ -3990,8 +5770,7 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ], - "license": "CC-BY-4.0" + ] }, "node_modules/chalk": { "version": "4.1.2", @@ -4106,6 +5885,14 @@ "node": ">=12" } }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/clsx": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", @@ -4145,6 +5932,15 @@ "version": "1.1.4", "license": "MIT" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/commander": { "version": "4.1.1", "license": "MIT", @@ -4160,8 +5956,46 @@ "node_modules/convert-source-map": { "version": "2.0.0", "devOptional": true, - "license": "MIT", - "peer": true + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.0.tgz", + "integrity": "sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } }, "node_modules/create-jest": { "version": "29.7.0", @@ -4184,6 +6018,14 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/cross-fetch": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "license": "MIT", @@ -4196,6 +6038,52 @@ "node": ">= 8" } }, + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/css.escape": { "version": "1.5.1", "license": "MIT" @@ -4210,6 +6098,39 @@ "node": ">=4" } }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true + }, "node_modules/csstype": { "version": "3.1.3", "license": "MIT" @@ -4297,7 +6218,6 @@ "version": "4.3.1", "devOptional": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -4350,6 +6270,11 @@ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, + "node_modules/dfa": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz", + "integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==" + }, "node_modules/didyoumean": { "version": "1.2.2", "license": "Apache-2.0" @@ -4362,35 +6287,100 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/dir-glob": { - "version": "3.0.1", + "node_modules/dir-glob": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "license": "MIT" + }, + "node_modules/doctrine": { + "version": "3.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "license": "MIT" + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, - "license": "MIT", "dependencies": { - "path-type": "^4.0.0" + "domelementtype": "^2.3.0" }, "engines": { - "node": ">=8" + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/dlv": { - "version": "1.1.3", - "license": "MIT" - }, - "node_modules/doctrine": { - "version": "3.0.0", + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dev": true, - "license": "Apache-2.0", "dependencies": { - "esutils": "^2.0.2" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" }, - "engines": { - "node": ">=6.0.0" + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/dom-accessibility-api": { - "version": "0.5.16", - "license": "MIT" + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } }, "node_modules/dotenv": { "version": "16.4.5", @@ -4408,9 +6398,10 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.615", - "devOptional": true, - "license": "ISC" + "version": "1.4.748", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.748.tgz", + "integrity": "sha512-VWqjOlPZn70UZ8FTKUOkUvBLeTQ0xpty66qV0yJcAGY2/CthI4xyW9aEozRVtuwv3Kpf5xTesmJUcPwuJmgP4A==", + "devOptional": true }, "node_modules/emittery": { "version": "0.13.1", @@ -4440,6 +6431,18 @@ "node": ">=10.13.0" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/envalid": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/envalid/-/envalid-8.0.0.tgz", @@ -4455,7 +6458,6 @@ "version": "1.3.2", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "is-arrayish": "^0.2.1" } @@ -5016,6 +7018,14 @@ "node": ">=0.10.0" } }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/execa": { "version": "5.1.1", "devOptional": true, @@ -5064,7 +7074,6 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "dev": true, "license": "MIT" }, "node_modules/fast-glob": { @@ -5215,6 +7224,31 @@ "dev": true, "license": "ISC" }, + "node_modules/fontkit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fontkit/-/fontkit-2.0.2.tgz", + "integrity": "sha512-jc4k5Yr8iov8QfS6u8w2CnHWVmbOGtdBtOXMze5Y+QD966Rx6PEVWXSEGwXlsDlKtu1G12cJjcsybnqhSk/+LA==", + "dependencies": { + "@swc/helpers": "^0.4.2", + "brotli": "^1.3.2", + "clone": "^2.1.2", + "dfa": "^1.2.0", + "fast-deep-equal": "^3.1.3", + "restructure": "^3.0.0", + "tiny-inflate": "^1.0.3", + "unicode-properties": "^1.4.0", + "unicode-trie": "^2.0.0" + } + }, + "node_modules/fontkit/node_modules/@swc/helpers": { + "version": "0.4.36", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.36.tgz", + "integrity": "sha512-5lxnyLEYFskErRPenYItLRSge5DjrJngYKdVjRSrWfza9G6KkgHEXi0vUZiyUeMU5JfXH1YnvXZzSp8ul88o2Q==", + "dependencies": { + "legacy-swc-helpers": "npm:@swc/helpers@=0.4.14", + "tslib": "^2.4.0" + } + }, "node_modules/for-each": { "version": "0.3.3", "license": "MIT", @@ -5309,7 +7343,6 @@ "version": "1.0.0-beta.2", "devOptional": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" } @@ -5555,6 +7588,19 @@ "node": ">= 0.4" } }, + "node_modules/hsl-to-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-to-hex/-/hsl-to-hex-1.0.0.tgz", + "integrity": "sha512-K6GVpucS5wFf44X0h2bLVRDsycgJmf9FF2elg+CrqD8GcFU8c6vYhgXn8NjUkFCwj+xDFb70qgLbTUm6sxwPmA==", + "dependencies": { + "hsl-to-rgb-for-reals": "^1.1.0" + } + }, + "node_modules/hsl-to-rgb-for-reals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/hsl-to-rgb-for-reals/-/hsl-to-rgb-for-reals-1.1.1.tgz", + "integrity": "sha512-LgOWAkrN0rFaQpfdWBQlv/VhkOxb5AsBjk6NQVx4yEzWS923T07X0M1Y0VNko2H52HeSpZrZNNMJ0aFqsdVzQg==" + }, "node_modules/html-escaper": { "version": "2.0.2", "devOptional": true, @@ -5589,6 +7635,11 @@ "url": "https://github.com/sponsors/typicode" } }, + "node_modules/hyphen": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/hyphen/-/hyphen-1.10.4.tgz", + "integrity": "sha512-SejXzIpv9gOVdDWXd4suM1fdF1k2dxZGvuTdkOVLoazYfK7O4DykIQbdrvuyG+EaTNlXAGhMndtKrhykgbt0gg==" + }, "node_modules/idb": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", @@ -5662,7 +7713,6 @@ }, "node_modules/inherits": { "version": "2.0.4", - "devOptional": true, "license": "ISC" }, "node_modules/internal-slot": { @@ -5714,8 +7764,7 @@ "node_modules/is-arrayish": { "version": "0.2.1", "devOptional": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/is-async-function": { "version": "2.0.0", @@ -5984,6 +8033,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" + }, "node_modules/is-weakmap": { "version": "2.0.1", "license": "MIT", @@ -6115,6 +8169,14 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/jay-peg": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/jay-peg/-/jay-peg-1.0.2.tgz", + "integrity": "sha512-fyV3NVvv6pTys/3BTapBUGAWAuU9rM2gRcgijZHzptd5KKL+s+S7hESFN+wOsbDH1MzFwdlRAXi0aGxS6uiMKg==", + "dependencies": { + "restructure": "^3.0.0" + } + }, "node_modules/jest": { "version": "29.7.0", "devOptional": true, @@ -6700,7 +8762,6 @@ "version": "2.5.2", "devOptional": true, "license": "MIT", - "peer": true, "bin": { "jsesc": "bin/jsesc" }, @@ -6716,8 +8777,7 @@ "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "devOptional": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -6787,6 +8847,15 @@ "node": ">=0.10" } }, + "node_modules/legacy-swc-helpers": { + "name": "@swc/helpers", + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", + "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==", + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/leven": { "version": "3.1.0", "devOptional": true, @@ -6842,6 +8911,12 @@ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, "node_modules/lodash.memoize": { "version": "4.1.2", "dev": true, @@ -6867,6 +8942,15 @@ "loose-envify": "cli.js" } }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "devOptional": true, @@ -6922,6 +9006,17 @@ "tmpl": "1.0.5" } }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, + "node_modules/media-engine": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/media-engine/-/media-engine-1.0.3.tgz", + "integrity": "sha512-aa5tG6sDoK+k70B9iEX1NeyfT8ObCKhNDs6lJVpwF6r8vhUfuKMslIcirq6HIUYuuUYLefcEQOn9bSBOvawtwg==" + }, "node_modules/merge-stream": { "version": "2.0.0", "devOptional": true, @@ -7095,6 +9190,35 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-int64": { "version": "0.4.0", "devOptional": true, @@ -7121,6 +9245,14 @@ "node": ">=0.10.0" } }, + "node_modules/normalize-svg-path": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/normalize-svg-path/-/normalize-svg-path-1.1.0.tgz", + "integrity": "sha512-r9KHKG2UUeB5LoTouwDzBy2VxXlHsiM6fyLQvnJa0S5hrhzqElH/CH7TUGhT1fVvIYBIKf3OpY4YJ4CK+iaqHg==", + "dependencies": { + "svg-arc-to-cubic-bezier": "^3.0.0" + } + }, "node_modules/npm-run-path": { "version": "4.0.1", "devOptional": true, @@ -7133,6 +9265,18 @@ "node": ">=8" } }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/object-assign": { "version": "4.1.1", "license": "MIT", @@ -7335,6 +9479,11 @@ "node": ">=6" } }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "node_modules/parent-module": { "version": "1.0.1", "dev": true, @@ -7350,7 +9499,6 @@ "version": "5.2.0", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -7364,6 +9512,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-svg-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz", + "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==" + }, "node_modules/path-exists": { "version": "4.0.0", "devOptional": true, @@ -7776,7 +9929,6 @@ }, "node_modules/prop-types": { "version": "15.8.1", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -7831,6 +9983,14 @@ "license": "MIT", "peer": true }, + "node_modules/queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "dependencies": { + "inherits": "~2.0.3" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "funding": [ @@ -7901,7 +10061,6 @@ }, "node_modules/react-is": { "version": "16.13.1", - "dev": true, "license": "MIT" }, "node_modules/react-remove-scroll": { @@ -8018,10 +10177,37 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/regenerator-runtime": { "version": "0.14.1", "license": "MIT" }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.5.1", "license": "MIT", @@ -8037,6 +10223,44 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, "node_modules/remove-accents": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", @@ -8049,6 +10273,14 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "1.22.8", "license": "MIT", @@ -8110,6 +10342,11 @@ "node": ">=10" } }, + "node_modules/restructure": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/restructure/-/restructure-3.0.1.tgz", + "integrity": "sha512-6neDpI/yE9eogQo22qmWwKIA9wFPRyYjQleDEh6zaNAf2ZPqLJYUvNBJBWEWNoBlCeQMQkvIOe2YI/K2GOag+g==" + }, "node_modules/reusify": { "version": "1.0.4", "license": "MIT", @@ -8283,6 +10520,19 @@ "license": "ISC", "peer": true }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/sisteransi": { "version": "1.0.5", "devOptional": true, @@ -8297,6 +10547,16 @@ "node": ">=8" } }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/source-map": { "version": "0.6.1", "devOptional": true, @@ -8364,6 +10624,14 @@ "node": ">=10.0.0" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-length": { "version": "4.0.2", "devOptional": true, @@ -8631,6 +10899,51 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/svg-arc-to-cubic-bezier": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/svg-arc-to-cubic-bezier/-/svg-arc-to-cubic-bezier-3.2.0.tgz", + "integrity": "sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g==" + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "dev": true + }, + "node_modules/svgo": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz", + "integrity": "sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==", + "dev": true, + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/tailwind-merge": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.2.1.tgz", @@ -8730,6 +11043,11 @@ "node": ">=0.8" } }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==" + }, "node_modules/tmpl": { "version": "1.0.5", "devOptional": true, @@ -8754,6 +11072,11 @@ "node": ">=8.0" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/ts-api-utils": { "version": "1.0.3", "dev": true, @@ -8970,6 +11293,69 @@ "version": "5.26.5", "license": "MIT" }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-properties": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz", + "integrity": "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==", + "dependencies": { + "base64-js": "^1.3.0", + "unicode-trie": "^2.0.0" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-trie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz", + "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==", + "dependencies": { + "pako": "^0.2.5", + "tiny-inflate": "^1.0.0" + } + }, + "node_modules/unicode-trie/node_modules/pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==" + }, "node_modules/update-browserslist-db": { "version": "1.0.13", "devOptional": true, @@ -9066,6 +11452,19 @@ "node": ">=10.12.0" } }, + "node_modules/vite-compatible-readable-stream": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/vite-compatible-readable-stream/-/vite-compatible-readable-stream-3.6.1.tgz", + "integrity": "sha512-t20zYkrSf868+j/p31cRIGN28Phrjm3nRSLR2fyc2tiWi4cZGVdv68yNlwnIINTkMTmPoMiSlc0OadaO7DXZaQ==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/walker": { "version": "1.0.8", "devOptional": true, @@ -9086,6 +11485,11 @@ "node": ">=10.13.0" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, "node_modules/websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", @@ -9107,6 +11511,15 @@ "node": ">=0.8.0" } }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "license": "ISC", @@ -9290,6 +11703,11 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yoga-layout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-2.0.1.tgz", + "integrity": "sha512-tT/oChyDXelLo2A+UVnlW9GU7CsvFMaEnd9kVFsaiCQonFAXd3xrHhkLYu+suwwosrAEQ746xBU+HvYtm1Zs2Q==" } } } diff --git a/frontend/package.json b/frontend/package.json index 2546c583..2db45b74 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -20,6 +20,7 @@ "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-slot": "^1.0.2", + "@react-pdf/renderer": "^3.4.4", "@tanstack/match-sorter-utils": "^8.11.8", "@tanstack/react-table": "^8.12.0", "@testing-library/jest-dom": "^6.1.5", @@ -44,6 +45,7 @@ }, "devDependencies": { "@babel/preset-typescript": "^7.23.3", + "@svgr/webpack": "^8.1.0", "@types/jest": "^29.5.11", "@types/node": "^20", "@types/react": "^18", diff --git a/frontend/public/icons/back.svg b/frontend/public/icons/back.svg new file mode 100644 index 00000000..a06137be --- /dev/null +++ b/frontend/public/icons/back.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/public/icons/close.svg b/frontend/public/icons/close.svg new file mode 100644 index 00000000..4b9cb438 --- /dev/null +++ b/frontend/public/icons/close.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/public/icons/delete.svg b/frontend/public/icons/delete.svg new file mode 100644 index 00000000..510a672d --- /dev/null +++ b/frontend/public/icons/delete.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/public/icons/download.svg b/frontend/public/icons/download.svg new file mode 100644 index 00000000..e5852aa9 --- /dev/null +++ b/frontend/public/icons/download.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/public/icons/edit.svg b/frontend/public/icons/edit.svg new file mode 100644 index 00000000..8a4abc93 --- /dev/null +++ b/frontend/public/icons/edit.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/public/icons/edit_pencil.svg b/frontend/public/icons/edit_pencil.svg new file mode 100644 index 00000000..3512add4 --- /dev/null +++ b/frontend/public/icons/edit_pencil.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/public/icons/green_check_mark.svg b/frontend/public/icons/green_check_mark.svg new file mode 100644 index 00000000..07fab4e2 --- /dev/null +++ b/frontend/public/icons/green_check_mark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/public/icons/green_download.svg b/frontend/public/icons/green_download.svg new file mode 100644 index 00000000..44298e4d --- /dev/null +++ b/frontend/public/icons/green_download.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/public/icons/left_arrow.svg b/frontend/public/icons/left_arrow.svg new file mode 100644 index 00000000..75f63780 --- /dev/null +++ b/frontend/public/icons/left_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/public/icons/mobile_download.svg b/frontend/public/icons/mobile_download.svg new file mode 100644 index 00000000..51440ed3 --- /dev/null +++ b/frontend/public/icons/mobile_download.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/public/icons/mobile_plus.svg b/frontend/public/icons/mobile_plus.svg new file mode 100644 index 00000000..a2be7fc6 --- /dev/null +++ b/frontend/public/icons/mobile_plus.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/public/icons/plus.svg b/frontend/public/icons/plus.svg new file mode 100644 index 00000000..64db175b --- /dev/null +++ b/frontend/public/icons/plus.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/frontend/public/icons/red_delete.svg b/frontend/public/icons/red_delete.svg new file mode 100644 index 00000000..42a89b16 --- /dev/null +++ b/frontend/public/icons/red_delete.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/public/icons/red_question_mark.svg b/frontend/public/icons/red_question_mark.svg new file mode 100644 index 00000000..001927eb --- /dev/null +++ b/frontend/public/icons/red_question_mark.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/public/icons/right_arrow.svg b/frontend/public/icons/right_arrow.svg new file mode 100644 index 00000000..f24437fd --- /dev/null +++ b/frontend/public/icons/right_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/public/icons/search.svg b/frontend/public/icons/search.svg new file mode 100644 index 00000000..34891a74 --- /dev/null +++ b/frontend/public/icons/search.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/public/loading-spinner.png b/frontend/public/loading-spinner.png new file mode 100644 index 0000000000000000000000000000000000000000..486f8fe42c6957288f26c39173656ed303d347eb GIT binary patch literal 6026 zcmV;57j@`~P)rA~3CKziy zfn-7m&KggTg`j$i4HonmeE{&d^+xs;+(7-`!RvG(@Na$V$}8W4<0!`*z^^|3cw^td zz+&gjA0sUDEshv0fng8~@W`rQjec|=0rQD6&k#TeB7=nhS^^M(25W;8P`$C#3$N!4 z9oXwac+cc=FWh_i<@@0n%P|9xfa@O^_%e>`FA#u+2ofGb#vpq@0YU(fi2{UzDGUpq z`v5aeSZ4v^zSHxFfzH?fsP0C71iFXEQxW6jUHtF$yO%C~9gdMqI)DURPha0syzrNi zEe!+=-NhPJMH*ZMBnAivO{aKLPv(*VR%`tBjv0x}!~P6(sHm@DdeU}~c4rtk{J~NN zlSfFV!0a~}c=3+Qu6P3`Stb?0OCNgZZxD>7po}vSFv}p|KoBlqfXL3NJqxOqkxhp8 z@jN~!s`S(hv6OR+ust5f-l;x|eIJ^de!6z?;vSeJnG^t*eCIn~ zKvh|W5BW!ySwsUBJ7?m6Aqa3d5J!%|(jXC3v3U%p91~SkXHo{x3X^yre+V)IqV`~e zvaPJ@jzJ4$$3uP4HU>*=2_8$s<~2)~Zh=XVPYmEC4}SYf3+_5qGiH&MUt54gYD7H}0DNusgZ7^!;@ZbCzrv`z8{VBG40+h##BNTm; z@$e>a4?@YP9ix5k`G=sZu%~6u9k_c?a1_Kcc>GO{MNL6uU-=v>*Mg9K>08e~|7S1( z85e*Z-@fO}kj*}bL!IUc40=jWKeM+A99wgKMt(42Adis;PoWxZ$vJYI;SoO(Nhsp| z9=zbb5YoMPqamV90ut{q?!-u_@YD%AD~vNy9b}Xt0%sIF{q2H;Qnb17{-6JR35-*Y z+6EHyd?tAaAF@%%CZUNMc|y~dJ+EP;NDsx1(J}U%>?GJTs^cJ=*X@PWH#`BLVe@$?yzHUWVG9I}8YDLRBe)+z!Pod^R} zovs;^;={k?gWr*4a+`nr^{?-SPaxlX^2yIOB*{XX*z*`P1q3*gaTUiwSOwlj2!nWR z5FoiF2xC2&=Thm7TQ0qH^U>V@hyY&rzyq^NrNVddb~ELs5?fV!S)gAPL8O01y{Bb$ z!iTGBLom0a8b0~-iWNIxlI0(sc%scUHqOV*FJX?|%pnYdLt2sq4QHYaB(|Y#WVI%n zs>j%=iB5-%hb=2Fx#WnM%Mk%Q|K58aMin`a!IPWQFGlyJcus7J#C^&{$_lIm!DQqd z1+ZotmaCrlk7EGb!LsJ*r&}RO&c)3RW*@7rV`dWD*vL8wZ$bpGtj5AbM;F4rS%9Cc zxcK5-hr8cl0YvbwMby3lF-*{SPcjTu0ajPKp9ad3`wEBw`tSiCfBwcBpMm2n1f;90 zTZ)f+dP2Yj$&=X*s)x4fjbqMC(ScLj2#%VP128b~uPZORYM#JfK4 zKJ}^PCmKAGe_XQUmEhsu&=cpKg5$}-NDSjOr16R6oEemn(=I>zP`W4q_Qa% zV97`)mYK|0VL4#5{=LgBY7`n7+(AdIxR2p|0}<^<(BWmNh}1S%jTX! zaE4+^#|+cdk7|z2CS1tixX>gX(v*)+~k?yps4LbTZjWHiIt-N6V76wT(Cf<&OexiBURYI7fDr9`~lFA3W(S(4Vt}iZ3(#k zo{Cqt#nf+nZT0GpVX8@?@GE3lFBf{PggDGbjQ=uRsnN6$gr&;X%)so~XH{RO4B-4V zYrawnzCB2ZN_v5WCSw1Xk!1U9NIi#0*#7Ywt5-h>Q&7mG)>-?amE2c~4FXacv}6`E z#IZ7kDz!8$WK>_Lnt^{wwF^~GE);XADzK-Gv7aFi>^bJ+^40Ayh2nd@+eQJD?PDfM8h*5O>x_5}2Jmxt-Z?uB{)?cY37OGUK;n<6GHuH@UoV80 z-ni|yS7C|^Li8FlOjbNFXbCvUk2MZN2a*Q1i3xk>QmHg2_LqWevG^x6p&>CJaFGJ>?2CeR$=?vuOhOE_I^U9V2qU05EwFRt2@x@k zkH7h5Bee+wjX6u=N|~3&Xxxg^@Z>-o`*q-~guOC`>+7M0q&}DXe*|V&sxuh#VU_|m zLp98l@Jy76R`X=Ci`jghS!mC^_13eHWpgA@26h}EwvYjfYE8#e0n}pL_baF&xoW|J z0+MJa(6lJpIRY_yWiIk#d&1$4sJFz2ww3zY)VX%`wzLAmrWi!0shGH8;@XM=`w**xK|C$Z zrg07&q^Q6rnUe7}r@m#$X7|}rI1Ql0C3a#SH5;zT@Jxx+^D@XgZ0Zl80fTQiUGrRt za&&>7F4N$KxGEyW-JzuZw@{MabTt*9&?^A-5eU}hM^!F)c0 zaEE4Yr1f7x7W;6%!E;I4BXD_(bo?WzVaXQ?^cDaW4Y2MKsF+IAbCi`pT+v15(8?NZ z$XS~t8YBx=T!cn1obv2BDYO*}alOmmyOk2M;xVd4`4wP(~Wl0hR) zPJ*z@csYklsYch^3jbuA+k9;UnC5aJ$>%Y%Eg1rfRyC3%@yJ9zA&_%%tiGhF87eS% zS?i=FEU8(M&mpu(q18Lfn*|11poS$gIGAx6nsv+|W+|^V1YR?MF(GXQ@y}!zOT3TU zxW5Yn&kw>%Hl`~Z=`GmBdam$p#gY?&gNFGJRNFOP<5Mv77OS@AaO1nBnMXKk@8yvxSgFg ztw`C$4$r}h&h65)QHb-uGz&)`E$!oW*4ocQjS9~FIxE#_{zMQ-2t@igP3suse7=M> z(0@p43?N!NaVntc8?Uw1IpR2#Iu~kGu*%Ycy6H(p4cWjzixya2jni{dbR<}@K@VMm z+=2zY6ght=WqeKhf=*XLT}C_mf2y^U2hek={yb0HxiwH077u;GPq z9z*HEVndUlN!Si*>r_p3B1!6lsV)|mS|Jq|!a1$0R<%NnNn;3&PRmy0aS1RitP-pA z1q80b_@F9{$2lXzP`dstU&TBxWqYYcb1hK!Baq&=^%sj@fEp8*$$XkX3j`WvBc&3> zfn1J{PQ_wK$Zh0-0s5$)-GASG2T+CoTPx9Y9HRH-dEshC3V^hp>1$9!^3qE$<**V{ zPXG~flwm%ykU+^YsJf;Pw=?ziytZ2=l>oL=Af3u<7Yvek;W(KjstqzrM@vt?0yU(@ zb#vylCtSvJ{H9X`FGS;yHn3PMhO$60z}&gKltm_$O8#f+VQJx?3sTZDagJD4B$SJ- z6k)c(@X$)A0eR=0cj_QXnh3B&)RWY-%tBIWIZTQQoElV2(>eS`E~1FMt~0R zoCmPNYehQf(hgaX>ZPpD%iS<7xv3UdxI33SCF6Z2$b7GQk%ZR|5-XjmtoOo7>XR)N z%PVgy#eonu32+j^ga}*&QB;`Uoz`+h3k(k42vb=86WM2r#pzKq39M``my(?esIpOw zBbc#mdM;Of!?O$^cKLS&j@4ehE=090-&N~kECyD=^5t`3iptE!#+gZ7T|xlm5?Qt( z1WZDX*hr&QClZ;7Kz7fYH?O?Zw+u{a{rW8k;>+dyx57HfNGk2pfwB{0S|Oz0hbbtp zzV}{>86IvURuNznG!u}rVp+hV^IXh}alek7O9;QOzRrmH9@@7%g2sO!WgIhtae>zi z8&HqKZN_%k<;!k|DI_~~?8u_3&SIR@t481wRb?l6FFO|ML&q`p%b!1Q-iRrUkpn84Etziu;|GN&DB9d=zo)c2!R6~PD_F<4A>MNm4CG#NA zJS|4o*szez9x|mdN`=|11y$GB62^KVr<#euJ`LAidoG;h^1r)xpVpit*@Vi;g#v>_ zn+=(aVuos~_AsYjS63qB7tfx(=iuud3Lvr&|KD6iu*%!smBun7CFE2}Sg+vt&TyMXqQ0~iGI_xtv}JK8lzpW{gVO2`fnhb zJcyIXD&kDyGLSRy#1~ISCcfX@Jp%!2^VzJ=W->aiLcko@M-aJlS@lvx4`7q-HM7yc5qZq369kPkliAlIL!r>0yB;CT&`$GMHVY!-)>fWvLC zW3V&}hyV0Xq8N))oU|e)-`m@@aKVBxU*Rx^eFC&+h}IhjSF5R*yE1S_J#}2V5DxAy z2RqRvt%dcE{s4}XkoD>8>1n}9pC)>?!tk)Irxld^R|r(}9o`~-W1+y-VZVa57jWB^ zO16-udlt=|d)QYv%n_ev`SNShQulkMKU zyAc{1rsao*7^`8_2?8*O$8CMRRX~MxbWA}*=VA(qZ4tMPbH#IJ&wkhF>kVVckpU!G zzI+Wn-t7tmh-D1AprHbuu0(=z6dBtq+jJP?O#2wDUq5M##Cl%xxsHx3bagc}H#gfs zycdDPAT~4@{6@=S`Nh&<1P|?+PWU2NreOK+R#bslO4Cx>-rl*033_-rIsj2H+jtBE z=Bp1mFd{cLBQQLygwTWM{}jP|2Di5%Gdp1%LbkuNvoq7!*qCIq*-W2;X7yVvG}?99v6^WF9`DxG0ops> zPN~>AW5%v|>}!r*#=lr-!=u;WbKD+d!8nP`+tunEr79q=KF5p%|M1|+bw1Nq7~VL4 z<;vCc@?>|n)-?C+gP2JipldfZm4o8`z=>@+MH|xR3AtPt(l(Fbib;~fdwqT522aO7 zK_SNy{OwQ)1uN!I$vIXI9rbsj^6A#LKkvTho?qam-9u`;f4^;OYcn4y3tg2BWYt9` zqGyI`RTcx8H-%EE*wxIu8!A&J$nGbBclmTkyTV2(0L7FV|_zIFzAUxeSH{$SnvyBpj7JpQG5Hx69tdt zldbpTn9d-G<_FcG48Ta|to!A#koRNz1hgRa=|x}Nw5g@)Pl5#KK?qw~U|LfX7e)I( zswglpAX-~rFBKMStE1BWz`*VWbLQ+@dxSXeNb<=SOj7vq$RmG?zdL@Qvl_Ng@xIFQ2nVyQ?7>5&!VTl}=wbba2D;R4{<}Y5`g?j@Yilc*0|)R*EvDb}*`}r@ z80_!IsAkY)3WZ{OdwV}QVVFdjTmYj8kZW+5*Nkv3Q7Q>^n1~8HYhLcWb@dY4-fm(z za|(X%r;r9?LJF!|nwt&u^%*Q6ln~efa}-&{MC914c_y{qumM%toDo9Gs%@ewSJf56 z1b@JWZ1#u9CP452b6<0csBVD$`ysTnglWyq9^;Y1+i$;p03A%vu>z0e*f4N3S+U|z zG3>bpw>t2qpMk2_uR8xbl3~nRcgOI$b@V4zY!`MR1`>#;o_Z=^Y#3(Dm_Z)3pf%oO zF2@hRYN3j?gL9FSSD-2rnCBg-3);<|Y$o}q*Op(u?(DPAu6}L;iq=8;;|1D?=Yo?( z2-GB@w*ck>y**_@*~>c2i&K+46CQrJydvO4fHj)@0iL@xNDA!dSpWb407*qoM6N<$ Eg1t0XOaK4? literal 0 HcmV?d00001 diff --git a/frontend/src/api/progressNotes.ts b/frontend/src/api/progressNotes.ts new file mode 100644 index 00000000..9a9c45dc --- /dev/null +++ b/frontend/src/api/progressNotes.ts @@ -0,0 +1,69 @@ +import { APIResult, DELETE, GET, POST, PUT, handleAPIError } from "@/api/requests"; +import { ProgressNote } from "@/components/ProgressNotes/types"; + +export const createAuthHeader = (firebaseToken: string) => ({ + Authorization: `Bearer ${firebaseToken}`, +}); + +export async function createProgressNote( + studentId: string, + dateLastUpdated: Date, + content: string, + firebaseToken: string, +): Promise> { + try { + const headers = createAuthHeader(firebaseToken); + const progressNote = { studentId, dateLastUpdated, content }; + const response = await POST("/progressNote/create", progressNote, headers); + const json = (await response.json()) as ProgressNote; + return { success: true, data: json }; + } catch (error) { + return handleAPIError(error); + } +} + +export async function editProgressNote( + noteId: string, + dateLastUpdated: Date, + content: string, + firebaseToken: string, +): Promise> { + try { + const headers = createAuthHeader(firebaseToken); + const progressNote = { _id: noteId, dateLastUpdated, content }; + const response = await PUT("/progressNote/edit", progressNote, headers); + const json = (await response.json()) as ProgressNote; + return { success: true, data: json }; + } catch (error) { + return handleAPIError(error); + } +} + +export async function deleteProgressNote( + noteId: string, + studentId: string, + firebaseToken: string, +): Promise> { + try { + const headers = createAuthHeader(firebaseToken); + const progressNote = { noteId, studentId }; + const response = await DELETE("/progressNote/delete", progressNote, headers); + const json = (await response.json()) as ProgressNote; + return { success: true, data: json }; + } catch (error) { + return handleAPIError(error); + } +} + +export async function getAllProgressNotes( + firebaseToken: string, +): Promise> { + try { + const headers = createAuthHeader(firebaseToken); + const response = await GET("/progressNote/all", headers); + const json = (await response.json()) as ProgressNote[]; + return { success: true, data: json }; + } catch (error) { + return handleAPIError(error); + } +} diff --git a/frontend/src/api/students.ts b/frontend/src/api/students.ts index f47510fc..8a1583cc 100644 --- a/frontend/src/api/students.ts +++ b/frontend/src/api/students.ts @@ -7,6 +7,7 @@ export type Student = CreateStudentRequest & { _id: string; medication: string; otherString: string; + progressNotes?: string[]; }; export async function createStudent(student: CreateStudentRequest): Promise> { diff --git a/frontend/src/components/Button.tsx b/frontend/src/components/Button.tsx index 02df9255..dbc72f49 100644 --- a/frontend/src/components/Button.tsx +++ b/frontend/src/components/Button.tsx @@ -15,15 +15,17 @@ type ButtonStyles = { selected: string; big: string; wide: string; + rounded: string; }; const poppins = Poppins({ weight: "400", style: "normal", subsets: [] }); export type ButtonProps = { label: React.ReactNode | string; - + icon?: React.ReactNode | null; kind?: "primary" | "secondary" | "destructive" | "destructive-secondary"; size?: "default" | "small" | "big" | "wide"; + rounded?: boolean; disabled?: boolean; selected?: boolean; } & React.ComponentProps<"button">; @@ -31,8 +33,10 @@ export type ButtonProps = { export const Button = React.forwardRef(function Button( { label, + icon = null, kind = "primary", size = "default", + rounded = false, disabled = false, selected = false, className, @@ -91,10 +95,15 @@ export const Button = React.forwardRef(function buttonClass += ` ${className}`; } + if (rounded) { + buttonClass += ` ${buttonStyles.rounded}`; + } + // Set font to poppins buttonClass += ` ${poppins.className}`; return ( ); diff --git a/frontend/src/components/DebouncedInput.tsx b/frontend/src/components/DebouncedInput.tsx index 1ddced1c..4c29d152 100644 --- a/frontend/src/components/DebouncedInput.tsx +++ b/frontend/src/components/DebouncedInput.tsx @@ -4,15 +4,19 @@ import { useForm } from "react-hook-form"; import { Textfield } from "./Textfield"; const DebouncedInput = ({ - value: initialValue, + initialValue = "", onChange, debounce = 500, placeholder = "", + icon, + className, }: { - value: string; + initialValue?: string; onChange: (val: string) => void; debounce?: number; placeholder?: string; + icon?: React.ReactNode; + className?: string; } & Omit, "onChange">) => { const [value, setValue] = useState(initialValue); const { register } = useForm(); @@ -33,12 +37,14 @@ const DebouncedInput = ({ return ( { setValue(e.target.value); }} + icon={icon} /> ); }; diff --git a/frontend/src/components/Dropdown.tsx b/frontend/src/components/Dropdown.tsx index 0d97f000..27bb1dff 100644 --- a/frontend/src/components/Dropdown.tsx +++ b/frontend/src/components/Dropdown.tsx @@ -1,5 +1,5 @@ import Image from "next/image"; -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { FieldValues, Path, PathValue, UseFormSetValue } from "react-hook-form"; import { @@ -36,6 +36,7 @@ export function Dropdown({ }: DropdownProps) { const [selectedOption, setSelectedOption] = useState(defaultValue); const [open, setOpen] = useState(false); + const triggerRef = useRef(null); useEffect(() => { if (selectedOption && setDropdownValue) { @@ -43,6 +44,10 @@ export function Dropdown({ } }, [selectedOption]); + const menuItemStyle = `cursor-pointer py-6 h-10 w-[240px] before:absolute before:bottom-0 before:h-[1px] before:w-full before:bg-[#B4B4B4] before:content-[''] + hover:bg-pia_primary_light_green + ${triggerRef.current ? `w-[${triggerRef.current.clientWidth}px]` : `w-[240px]`}`; + return ( ({ }} > @@ -69,25 +75,26 @@ export function Dropdown({ { onChange(""); setSelectedOption(defaultValue); }} > - {defaultValue} + {defaultValue} {options.map((option) => ( { onChange(option); setSelectedOption(option); }} > - {option} + {option} ))} diff --git a/frontend/src/components/LoadingSpinner.tsx b/frontend/src/components/LoadingSpinner.tsx new file mode 100644 index 00000000..10505678 --- /dev/null +++ b/frontend/src/components/LoadingSpinner.tsx @@ -0,0 +1,22 @@ +import Image from "next/image"; + +import loadingSpinner from "../../public/loading-spinner.png"; +import styles from "../styles/LoadingSpinner.module.css"; + +export default function LoadingSpinner() { + return ( +
+
+ Loading Spinner +

Loading...

+
+
+ ); +} diff --git a/frontend/src/components/Modals/ModalConfirmation.tsx b/frontend/src/components/Modals/ModalConfirmation.tsx new file mode 100644 index 00000000..43a238df --- /dev/null +++ b/frontend/src/components/Modals/ModalConfirmation.tsx @@ -0,0 +1,77 @@ +import { forwardRef } from "react"; + +import { Button } from "../Button"; +import { Dialog, DialogClose, DialogContent, DialogTrigger } from "../ui/dialog"; + +type ModalConfirmationProps = { + ref?: React.RefObject; + icon: React.ReactNode; + triggerElement: React.ReactNode; + onCancelClick?: (e: React.MouseEvent) => void; + onConfirmClick?: (e: React.MouseEvent) => void; + title: string; + description?: string; + cancelText?: string; + confirmText: string; + kind: "primary" | "destructive"; + nestedDialog?: React.ReactNode; + //Used for nested dialog to close parent dialog + isParentOpen?: boolean; + setIsParentOpen?: React.Dispatch>; +}; + +const ModalConfirmation = forwardRef( + ( + { + icon, + triggerElement, + onCancelClick = () => {}, + onConfirmClick = () => {}, + title, + description, + cancelText = "Cancel", + confirmText, + kind, + nestedDialog, + isParentOpen, + setIsParentOpen, + }, + ref, + ) => { + return ( + + {triggerElement} + +
+
{icon}
+

{title}

+ {description ?

{description}

: null} +
+ +
+
+
+
+ ); + }, +); + +ModalConfirmation.displayName = "ModalConfirmation"; + +export default ModalConfirmation; diff --git a/frontend/src/components/Modals/SaveCancelButtons.tsx b/frontend/src/components/Modals/SaveCancelButtons.tsx new file mode 100644 index 00000000..dbfb3c29 --- /dev/null +++ b/frontend/src/components/Modals/SaveCancelButtons.tsx @@ -0,0 +1,86 @@ +import React from "react"; + +import RedQuestionMarkIcon from "../../../public/icons/red_question_mark.svg"; +import { Button } from "../Button"; +import { Dialog, DialogContent, DialogTrigger } from "../ui/dialog"; + +import ModalConfirmation from "./ModalConfirmation"; + +type SaveCancelButtonsPropsBase = { + setOpen: React.Dispatch>; + onCancelClick?: (e: React.MouseEvent) => void; + onSaveClick?: (e: React.MouseEvent) => void; + onLeave?: () => void; +}; + +type SaveCancelButtonsPropsWithAutoClose = SaveCancelButtonsPropsBase & { + isOpen: boolean; + //Children is used for save button dialog content + children?: React.ReactNode; + //Will automatically close save button dialog after specified time in seconds + automaticClose: number; +}; + +type SaveCancelButtonsPropsWithoutAutoClose = SaveCancelButtonsPropsBase & { + isOpen?: never; + automaticClose?: never; + children?: never; +}; + +type SaveCancelButtonsProps = + | SaveCancelButtonsPropsWithAutoClose + | SaveCancelButtonsPropsWithoutAutoClose; + +export default function SaveCancelButtons({ + isOpen, + setOpen, + onCancelClick = () => {}, + onSaveClick = () => {}, + onLeave = () => {}, + automaticClose, + children, +}: SaveCancelButtonsProps) { + const handleAutomaticClose = () => { + if (automaticClose) { + setTimeout(() => { + setOpen(false); + }, automaticClose * 1000); + } + }; + + return ( +
+
+ ); +} diff --git a/frontend/src/components/Navigation.tsx b/frontend/src/components/Navigation.tsx index dc34747b..3dca7ff2 100644 --- a/frontend/src/components/Navigation.tsx +++ b/frontend/src/components/Navigation.tsx @@ -139,7 +139,7 @@ function Navigation({ children }: { children: React.ReactNode }) {
{ if (isMobile) { e.stopPropagation(); diff --git a/frontend/src/components/NoStudents.tsx b/frontend/src/components/NoStudents.tsx new file mode 100644 index 00000000..84ca8302 --- /dev/null +++ b/frontend/src/components/NoStudents.tsx @@ -0,0 +1,15 @@ +import Link from "next/link"; + +import NoStudentsIcon from "../../public/noStudents.svg"; + +export default function NoStudents() { + return ( +
+ +

No Students

+ + Add a student to continue + +
+ ); +} diff --git a/frontend/src/components/NotificationCard/NotificationCard.tsx b/frontend/src/components/NotificationCard/NotificationCard.tsx index 234b3d95..a5380c14 100644 --- a/frontend/src/components/NotificationCard/NotificationCard.tsx +++ b/frontend/src/components/NotificationCard/NotificationCard.tsx @@ -1,3 +1,5 @@ +import { Button } from "../Button"; + type UserInfo = { name: string; email: string; @@ -9,7 +11,7 @@ export default function NotificationCard({ name, email, account_type }: UserInfo <>
@@ -19,13 +21,9 @@ export default function NotificationCard({ name, email, account_type }: UserInfo Account Type: {account_type}
-
- - +
+
diff --git a/frontend/src/components/ProfileForm/BasicInfoFrame.tsx b/frontend/src/components/ProfileForm/BasicInfoFrame.tsx index 1328db4b..5130de77 100644 --- a/frontend/src/components/ProfileForm/BasicInfoFrame.tsx +++ b/frontend/src/components/ProfileForm/BasicInfoFrame.tsx @@ -6,7 +6,7 @@ import { useForm } from "react-hook-form"; import { cn } from "../../lib/utils"; import { FrameProps } from "../../pages/profile"; import { Button } from "../Button"; -import SaveCancelButtons from "../SaveCancelButtons"; +import SaveCancelButtons from "../Modals/SaveCancelButtons"; import { Textfield } from "../Textfield"; import { Dialog, DialogTrigger } from "../ui/dialog"; @@ -134,7 +134,7 @@ export function BasicInfoFrame({ return (
{/*Info header*/} -
Basic Info
+
Basic Info
{/*Info Fields*/}
diff --git a/frontend/src/components/ProfileForm/ContactInfoFrame.tsx b/frontend/src/components/ProfileForm/ContactInfoFrame.tsx index e3d92dfb..bf0c2410 100644 --- a/frontend/src/components/ProfileForm/ContactInfoFrame.tsx +++ b/frontend/src/components/ProfileForm/ContactInfoFrame.tsx @@ -7,7 +7,7 @@ import { useForm } from "react-hook-form"; import { cn } from "../../lib/utils"; import { FrameProps } from "../../pages/profile"; -import SaveCancelButtons from "../SaveCancelButtons"; +import SaveCancelButtons from "../Modals/SaveCancelButtons"; import { Textfield } from "../Textfield"; import { Dialog, DialogTrigger } from "../ui/dialog"; diff --git a/frontend/src/components/ProfileForm/ProfileDialogContent.tsx b/frontend/src/components/ProfileForm/ProfileDialogContent.tsx index 8239dfb2..d5dbd1aa 100644 --- a/frontend/src/components/ProfileForm/ProfileDialogContent.tsx +++ b/frontend/src/components/ProfileForm/ProfileDialogContent.tsx @@ -1,3 +1,5 @@ +import BackIcon from "../../../public/icons/back.svg"; +import CloseIcon from "../../../public/icons/close.svg"; import { DialogClose, DialogContent } from "../ui/dialog"; type ProfileDialogProps = { @@ -19,35 +21,16 @@ export default function ProfileDialogContent({
{backIcon ? ( - - - +
+ +
+ + + ); +} diff --git a/frontend/src/components/ProgressNotes/DownloadNotesPDF.tsx b/frontend/src/components/ProgressNotes/DownloadNotesPDF.tsx new file mode 100644 index 00000000..336861a1 --- /dev/null +++ b/frontend/src/components/ProgressNotes/DownloadNotesPDF.tsx @@ -0,0 +1,164 @@ +// React PDF Documentation: https://react-pdf.org/ +import { + Document, + Font, + Line, + PDFDownloadLink, + Page, + StyleSheet, + Svg, + Text, + View, +} from "@react-pdf/renderer"; + +import { Button } from "../Button"; + +import { dateOptions } from "./NotesSelectionList"; +import { ProgressNote } from "./types"; + +type DownloadNotesPDFProps = { + allProgressNotes: Record; + studentId: string; + studentName: string; + downloadStartDate: string; + downloadEndDate: string; + downloadDisabled: boolean; +}; + +type NotesDocProps = Omit; + +Font.register({ + family: "Poppins", + src: "https://fonts.gstatic.com/s/poppins/v1/TDTjCH39JjVycIF24TlO-Q.ttf", +}); +Font.registerEmojiSource({ + format: "png", + url: "https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/", +}); + +const styles = StyleSheet.create({ + page: { + flexDirection: "column", + backgroundColor: "white", + paddingHorizontal: 30, + paddingVertical: 20, + fontSize: 12, + fontFamily: "Poppins", + }, + section: { + margin: 10, + padding: 10, + flexGrow: 1, + }, + horizontalLineTitle: { + marginBottom: 15, + marginLeft: -30, + }, + horizontalLine: { + marginVertical: 15, + marginLeft: -30, + }, + title: { + fontSize: 20, + fontWeight: "bold", + marginBottom: 10, + }, + dateText: { + color: "#929292", + display: "flex", + justifyContent: "space-between", + paddingBottom: 5, + }, +}); + +const NotesDoc = ({ + allProgressNotes, + studentId, + studentName, + downloadStartDate, + downloadEndDate, +}: NotesDocProps) => { + const title = `Progress Notes for ${studentName}`; + return ( + + + {title} + + + + {Object.values(allProgressNotes) + .filter((note) => { + return ( + note.studentId === studentId && + new Date(note.dateLastUpdated).setHours(0, 0, 0, 0) >= + new Date(downloadStartDate).setHours(0, 0, 0, 0) && + new Date(note.dateLastUpdated).setHours(0, 0, 0, 0) <= + new Date(downloadEndDate).setHours(0, 0, 0, 0) + ); + }) + .sort( + (a, b) => new Date(b.dateLastUpdated).getTime() - new Date(a.dateLastUpdated).getTime(), + ) + .map((note) => ( + + + {new Date(note.dateLastUpdated).toLocaleDateString("en-US", dateOptions)} +  | By {note.lastEditedBy} + + {note.content} + + + + + ))} + + + ); +}; + +const DownloadNotesPDF = ({ + allProgressNotes, + studentId, + studentName, + downloadStartDate, + downloadEndDate, + downloadDisabled, +}: DownloadNotesPDFProps) => { + const underlinedName = studentName.replace(" ", "_"); + return ( +
+ + } + fileName={`progress_notes_${underlinedName}.pdf`} + > + {({ blob: _blob, url: _url, loading, error }) => { + console.log(error); + return ( +
+ ); +}; + +export default DownloadNotesPDF; diff --git a/frontend/src/components/ProgressNotes/EditNote.tsx b/frontend/src/components/ProgressNotes/EditNote.tsx new file mode 100644 index 00000000..4ac28b14 --- /dev/null +++ b/frontend/src/components/ProgressNotes/EditNote.tsx @@ -0,0 +1,265 @@ +import { useContext, useEffect, useRef, useState } from "react"; + +import BackIcon from "../../../public/icons/back.svg"; +import CloseIcon from "../../../public/icons/close.svg"; +import DeleteIcon from "../../../public/icons/delete.svg"; +import EditIcon from "../../../public/icons/edit.svg"; +import GreenCheckMarkIcon from "../../../public/icons/green_check_mark.svg"; +import RedDeleteIcon from "../../../public/icons/red_delete.svg"; +import { Button } from "../Button"; +import ModalConfirmation from "../Modals/ModalConfirmation"; +import SaveCancelButtons from "../Modals/SaveCancelButtons"; + +import { dateOptions } from "./NotesSelectionList"; +import { ProgressNote } from "./types"; + +import { createProgressNote, deleteProgressNote, editProgressNote } from "@/api/progressNotes"; +import { UserContext } from "@/contexts/user"; +import { HandleNoteUpdate, StudentWithNotes, ViewMode } from "@/pages/notes"; + +type EditNoteProps = { + selectedStudent: StudentWithNotes; + selectedNote: ProgressNote; + firebaseToken: string; + handleBackButton: () => void; + handleEditButton: (e: React.MouseEvent, note: ProgressNote) => void; + handleNoteUpdate: (data: HandleNoteUpdate) => void; + handleFinishDelete: () => void; + noteMode: ViewMode; +}; + +function EditNote({ + selectedStudent, + selectedNote, + firebaseToken, + handleBackButton, + handleEditButton, + handleNoteUpdate, + handleFinishDelete, + noteMode, +}: EditNoteProps) { + const inputRef = useRef(null); + const [openSaveDialog, setOpenSaveDialog] = useState(false); + const [openDeleteDialog, setOpenDeleteDialog] = useState(false); + const [deletedNote, setDeletedNote] = useState(undefined); + const deleteDialogRef = useRef(null); + const { piaUser, isAdmin } = useContext(UserContext); + const articleRef = useRef(null); + const currentUser = piaUser?.name; + + const handleSaveClick = (e: React.MouseEvent) => { + e.preventDefault(); + const noteContent = inputRef.current?.value ?? ""; + if (noteContent === "") { + return; + } + + if (noteMode === "add") { + createProgressNote(selectedStudent._id, new Date(), noteContent, firebaseToken).then( + (result) => { + if (result.success) { + handleNoteUpdate({ action: "add", noteData: result.data }); + } else { + console.error(result.error); + } + }, + (error) => { + console.error(error); + }, + ); + } else if (noteMode === "edit") { + editProgressNote(selectedNote._id, new Date(), noteContent, firebaseToken).then( + (result) => { + if (result.success) { + handleNoteUpdate({ action: "edit", noteData: result.data }); + } else { + console.error(result.error); + } + }, + (error) => { + console.error(error); + }, + ); + } + }; + + const handleDelete = () => { + setDeletedNote(selectedNote); + deleteProgressNote(selectedNote._id, selectedStudent._id, firebaseToken).then( + (result) => { + if (result.success) { + handleNoteUpdate({ action: "delete", noteData: result.data }); + } else { + console.error(result.error); + } + }, + (error) => { + console.error(error); + }, + ); + }; + + const handleUndoDelete = () => { + if (deletedNote) { + createProgressNote( + deletedNote.studentId, + deletedNote.dateLastUpdated, + deletedNote.content, + firebaseToken, + ).then( + (result) => { + if (result.success) { + handleNoteUpdate({ action: "add", noteData: result.data }); + } else { + console.error(result.error); + } + }, + (error) => { + console.error(error); + }, + ); + setDeletedNote(undefined); + } + }; + + useEffect(() => { + if (noteMode === "edit" && inputRef.current) { + inputRef.current.focus(); + inputRef.current.selectionStart = inputRef.current.value.length; + } + }, [noteMode]); + + useEffect(() => { + // If the dialog closes after deleting a note + if (!openDeleteDialog && deleteDialogRef.current?.style.opacity === "0") { + handleFinishDelete(); + } + }, [openDeleteDialog]); + + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === "Escape") { + handleBackButton(); + } + }; + articleRef.current?.addEventListener("keydown", handleKeyDown); + return () => { + articleRef.current?.removeEventListener("keydown", handleKeyDown); + }; + }, []); + + return ( +
+
+ + {isAdmin ? ( +
+ + } + triggerElement={ + + } + title="Are you sure you want to delete?" + confirmText="Delete" + kind="destructive" + isParentOpen={openDeleteDialog} + setIsParentOpen={setOpenDeleteDialog} + nestedDialog={ + } + triggerElement={ +
+ ) : null} +
+

+ Notes for {`${selectedStudent.student.firstName} ${selectedStudent.student.lastName}`} +

+
+ {noteMode === "view" ? ( +

+ {new Date(selectedNote.dateLastUpdated).toLocaleDateString("en-US", dateOptions)} +  | By {selectedNote.lastEditedBy} +

+ ) : ( +

+ {new Date().toLocaleDateString("en-US", dateOptions)} +  | By {currentUser} +

+ )} +