diff --git a/components.json b/components.json new file mode 100644 index 0000000..bbf779f --- /dev/null +++ b/components.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "tailwind.config.js", + "css": "src/global.css", + "baseColor": "slate", + "cssVariables": false, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/utility/utils" + } +} \ No newline at end of file diff --git a/index.html b/index.html index 9e569d6..d16bdf2 100644 --- a/index.html +++ b/index.html @@ -14,7 +14,7 @@ - +
diff --git a/package.json b/package.json index e05a0ac..19fae1a 100644 --- a/package.json +++ b/package.json @@ -10,15 +10,20 @@ "preview": "vite preview" }, "dependencies": { + "@radix-ui/react-dialog": "^1.0.5", + "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "howler": "^2.2.4", + "lucide-react": "^0.306.0", "pixi.js": "^7.3.3", "react": "^18.2.0", "react-dom": "^18.2.0", "react-helmet": "^6.1.0", "react-router-dom": "^6.21.1", "react-toastify": "^9.1.3", - "tailwind-merge": "^2.2.0" + "tailwind-merge": "^2.2.0", + "tailwindcss-animate": "^1.0.7", + "zustand": "^4.4.7" }, "devDependencies": { "@types/howler": "^2.2.11", @@ -26,6 +31,7 @@ "@types/react": "^18.2.43", "@types/react-dom": "^18.2.17", "@types/react-helmet": "^6.1.11", + "@types/uuid": "^9.0.7", "@typescript-eslint/eslint-plugin": "^6.14.0", "@typescript-eslint/parser": "^6.14.0", "@vitejs/plugin-react": "^4.2.1", diff --git a/public/assets/sfx/kururina-intro.mp3 b/public/assets/sfx/kururina-intro.mp3 new file mode 100644 index 0000000..d5922bf Binary files /dev/null and b/public/assets/sfx/kururina-intro.mp3 differ diff --git a/public/assets/sfx/kururina-intro.ogg b/public/assets/sfx/kururina-intro.ogg new file mode 100644 index 0000000..4b8778a Binary files /dev/null and b/public/assets/sfx/kururina-intro.ogg differ diff --git a/public/assets/sfx/kururina-loop.mp3 b/public/assets/sfx/kururina-loop.mp3 new file mode 100644 index 0000000..0ec1c97 Binary files /dev/null and b/public/assets/sfx/kururina-loop.mp3 differ diff --git a/src/assets/icons/close-outline.svg b/src/assets/icons/close-outline.svg new file mode 100644 index 0000000..5d783ae --- /dev/null +++ b/src/assets/icons/close-outline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/ui/Dialog.tsx b/src/components/ui/Dialog.tsx new file mode 100644 index 0000000..ad9d680 --- /dev/null +++ b/src/components/ui/Dialog.tsx @@ -0,0 +1,120 @@ +import * as React from "react"; +import * as DialogPrimitive from "@radix-ui/react-dialog"; +import { X } from "lucide-react"; + +import { cn } from "@/utility/utils"; + +const Dialog = DialogPrimitive.Root; + +const DialogTrigger = DialogPrimitive.Trigger; + +const DialogPortal = DialogPrimitive.Portal; + +const DialogClose = DialogPrimitive.Close; + +const DialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DialogOverlay.displayName = DialogPrimitive.Overlay.displayName; + +const DialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + {children} + + + Close + + + +)); +DialogContent.displayName = DialogPrimitive.Content.displayName; + +const DialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+); +DialogHeader.displayName = "DialogHeader"; + +const DialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+); +DialogFooter.displayName = "DialogFooter"; + +const DialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DialogTitle.displayName = DialogPrimitive.Title.displayName; + +const DialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DialogDescription.displayName = DialogPrimitive.Description.displayName; + +export { + Dialog, + DialogPortal, + DialogOverlay, + DialogClose, + DialogTrigger, + DialogContent, + DialogHeader, + DialogFooter, + DialogTitle, + DialogDescription, +}; diff --git a/src/components/ui/Modal.tsx b/src/components/ui/Modal.tsx new file mode 100644 index 0000000..2f747ed --- /dev/null +++ b/src/components/ui/Modal.tsx @@ -0,0 +1,58 @@ +import React from "react"; +import { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogOverlay, + DialogPortal, + DialogTitle, +} from "./Dialog"; + +export type ModalProps = { + children?: React.ReactNode; + isOpen?: boolean; + onOpenChange?: (open: boolean) => void; + title?: string; + description?: string; + size?: "sm" | "md" | "lg" | "xl"; +}; + +const Modal = ({ + children, + isOpen, + onOpenChange, + title, + description, + size = "md", +}: ModalProps) => { + return ( + + + + + + {title ? ( + {title} + ) : null} + + {description ? ( + {description} + ) : null} + + {children} + + + + + + ); +}; + +export default Modal; diff --git a/src/hooks/useModal.ts b/src/hooks/useModal.ts new file mode 100644 index 0000000..ec5c121 --- /dev/null +++ b/src/hooks/useModal.ts @@ -0,0 +1,18 @@ +import { useState } from "react"; + +const useModal = () => { + const [isOpen, setOpen] = useState(false); + + return { + isOpen, + onOpen() { + setOpen(true); + }, + onClose() { + setOpen(false); + }, + onOpenChange: setOpen, + }; +}; + +export default useModal; diff --git a/src/pages/home/game.ts b/src/pages/home/game.ts index 24b3d7e..76120f8 100644 --- a/src/pages/home/game.ts +++ b/src/pages/home/game.ts @@ -3,12 +3,14 @@ import { AnimatedSprite, Application, Assets, + FederatedPointerEvent, Sprite, Text, TextStyle, } from "pixi.js"; import StateMachine from "./stateMachine"; import { Howl } from "howler"; +import { gameDataStore } from "./store"; const IMG_URI = "/assets/images/"; const UI_URI = "/assets/ui/"; @@ -28,6 +30,10 @@ const game = async () => { backgroundColor: "#fff", }); + if (app.view.style) { + app.view.style.touchAction = "inherit"; + } + const handPetTextures = [...Array(10)].map((_, idx) => { const uri = `/handpet/handpet_${String(idx + 1).padStart(2, "0")}.webp`; return Assets.load(IMG_URI + uri); @@ -46,12 +52,11 @@ const game = async () => { const sfx = { prepare: new Howl({ - src: SFX_URI + "pet-the-peepo-prepare.ogg", + src: SFX_URI + "kururina-intro.mp3", preload: true, }), music: new Howl({ - // src: SFX_URI + "pet-the-peepo.ogg", - src: SFX_URI + "kuru-kuru-kururin.ogg", + src: SFX_URI + "kururina-loop.mp3", preload: true, loop: true, }), @@ -78,20 +83,24 @@ const game = async () => { }); const startText = new Text( - "Press to Play", + "Press to Pet Furina", new TextStyle({ - fontSize: 28, + fontSize: 48, + fill: ["#fff"], + stroke: "#333", + lineJoin: "round", + strokeThickness: 12, + align: "center", }) ); startText.anchor.set(0.5); - startText.position.set(screen.w * 0.5, screen.h * 0.82); + startText.position.set(screen.w * 0.5, screen.h * 0.85); // let musicPlayTimeout: any; return { onStart() { app.stage.addChild(furina, btnStart, startText); - // musicPlayTimeout = setTimeout(() => sfx.music.play(), 100); }, loop(time) { btnStart.scale.set(1.0 + Math.sin(time) * 0.2); @@ -100,9 +109,6 @@ const game = async () => { }, onEnd() { app.stage.removeChild(furina, btnStart, startText); - - // clearTimeout(musicPlayTimeout); - // sfx.music.stop(); }, }; }); @@ -127,21 +133,26 @@ const game = async () => { return { onStart() { app.stage.addChild(furina, hand); + sfx.prepare.play(); timers.push( setTimeout(() => { furina.visible = true; - furinaPos.y = screen.h * 0.5; - sfx.prepare.play(); }, 500) ); + timers.push( + setTimeout(() => { + furinaPos.y = screen.h * 0.48; + }, 1200) + ); + timers.push( setTimeout(() => { furina.visible = false; hand.visible = true; handPos.y = screen.h * 0.5; - }, 1500) + }, 2500) ); timers.push( @@ -155,22 +166,36 @@ const game = async () => { hand.position.x = screen.w * 0.15; handPos.x = screen.w * 0.25; hand.scale.set(0.4); - }, 2400) + }, 3500) ); timers.push( setTimeout(() => { - furinaPos.x = screen.w * 0.65; - furina.scale.set(0.45); - handPos.x = screen.w * 0.35; + handPos.x = screen.w * 0.28; + furinaPos.x = screen.w * 0.72; + }, 4500) + ); + + timers.push( + setTimeout(() => { + handPos.x = screen.w * 0.3; hand.scale.set(0.45); - }, 3400) + furinaPos.x = screen.w * 0.7; + furina.scale.set(0.45); + }, 5500) + ); + + timers.push( + setTimeout(() => { + handPos.x = screen.w * 0.35; + furinaPos.x = screen.w * 0.65; + }, 6500) ); timers.push( setTimeout(() => { stateMachine.start(STATE.RUNNING); - }, 4500) + }, 7500) ); }, loop(_, dt) { @@ -197,30 +222,56 @@ const game = async () => { const handPet = new AnimatedSprite(tex.handPet); handPet.animationSpeed = 0.2; - handPet.scale.set(0.7); - handPet.anchor.set(0, 0.5); - handPet.position.set(0, screen.h * 0.34); + handPet.scale.set(0.6); + handPet.anchor.set(0.5, 0.6); + let handPetPos = { x: 240, y: 320 }; + handPet.position.set(240, 320); const touchButtonGuide = new Sprite(tex.uiBtnTouch); touchButtonGuide.anchor.set(0.5, 1); touchButtonGuide.position.set(screen.w * 0.5, screen.h * 0.95); + let touchCount = gameDataStore.getState().score; + let lastTouch = 0.0; + let isTouching = false; + const touchText = new Text( - "0", + String(touchCount), new TextStyle({ - fontSize: 64, + fontSize: 80, + fill: ["#fff"], + stroke: "#333", + lineJoin: "round", + strokeThickness: 12, + align: "right", }) ); - touchText.anchor.set(1, 0); - touchText.position.set(screen.w * 0.9, screen.h * 0.1); + touchText.anchor.set(0.5, 0.8); + touchText.position.set(screen.w * 0.5, screen.h * 0.15); - let touchCount = 0; - let lastTouch = 0.0; + const onTouch = (e: FederatedPointerEvent) => { + handPetPos = { x: e.global.x, y: e.global.y }; + isTouching = true; + + gameDataStore.setState((state) => { + touchCount = state.score + 1; + return { score: touchCount }; + }); - const onTouch = () => { lastTouch = stateMachine.time; - touchCount += 1; touchText.text = String(touchCount); + touchText.scale.set(1.3); + touchText.rotation = 0.2; + }; + + const onPointerMove = (e: FederatedPointerEvent) => { + if (isTouching) { + handPetPos = { x: e.global.x, y: e.global.y }; + } + }; + + const onTouchUp = () => { + isTouching = false; }; return { @@ -231,11 +282,18 @@ const game = async () => { sfx.music.play(); app.stage.eventMode = "static"; + app.stage.hitArea = app.screen; app.stage.cursor = "pointer"; app.stage.on("pointerdown", onTouch); + app.stage.on("pointerup", onTouchUp); + app.stage.on("pointermove", onPointerMove); }, loop(time, delta) { - if (time - lastTouch < 0.5) { + if (isTouching) { + lastTouch = time; + } + + if (time - lastTouch < 0.8) { if (!handPet.playing) { handPet.play(); handPet.visible = true; @@ -245,6 +303,8 @@ const game = async () => { } furina.scale.y = 1 + Math.sin(time * 40) * 0.01; furina.rotation = -0.01 + Math.cos(time * 30) * 0.02; + + lerpPos(handPet.position, handPetPos, 12 * delta); } else { if (handPet.playing) { handPet.stop(); @@ -260,6 +320,13 @@ const game = async () => { touchButtonGuide.scale.set(0.5 + Math.sin(time * 40) * 0.01); touchButtonGuide.position.y = screen.h * (0.92 + Math.cos(time * 40) * 0.01); + + if (touchText.scale.x > 1.0) { + touchText.scale.set(Math.max(1.0, touchText.scale.x - 10 * delta)); + } + if (touchText.rotation > 0.0) { + touchText.rotation = Math.max(0.0, touchText.rotation - 2 * delta); + } }, onEnd() { handPet.stop(); @@ -269,6 +336,8 @@ const game = async () => { app.stage.eventMode = "auto"; app.stage.cursor = ""; app.stage.off("pointerdown", onTouch); + app.stage.off("pointerup", onTouchUp); + app.stage.off("pointermove", onPointerMove); }, }; }); diff --git a/src/pages/home/page.tsx b/src/pages/home/page.tsx index 4c89f9b..104aac2 100644 --- a/src/pages/home/page.tsx +++ b/src/pages/home/page.tsx @@ -4,6 +4,8 @@ import styles from "./style.module.css"; import { cn } from "@/utility/utils"; import LoadingPage from "../misc/loading-page"; import PageMetadata from "@/components/containers/PageMetadata"; +import Modal from "@/components/ui/Modal"; +import useModal from "@/hooks/useModal"; const HomePage = () => { const appRef = useRef(); @@ -60,37 +62,35 @@ const HomePage = () => { const Credits = () => { const [toggle, setToggle] = useState(false); + const modal = useModal(); return (
- {toggle ? ( -
+      
+        
           {`
 Furina Stickers:
 Guido_ (https://risibank.fr/media/297778-genshin-archon-hydro-c6-r5-soutine)
 Coll5 (https://risibank.fr/media/317061-furina-focalor-genshin)
 
+Music:
+Kururin Furina Cover by Ariyutta (https://facebook.com/arbi.yudatama)
+pet the peepo by NitroiF (https://www.youtube.com/shorts/ll2Au3CdV2k)
+
 Hand Sprite:
 @soapmangraylace2752 (https://www.youtube.com/shorts/HEguW7Gmu2w)
 Fijiwaterhelp (https://jailbreak.fandom.com/wiki/User_blog:Fijiwaterhelp/hand_petting)
-
-Music:
-Kurururin by Raphiiel (https://www.youtube.com/watch?v=NY0ffyEu6uo)
-pet the peepo by NitroiF (https://www.youtube.com/shorts/ll2Au3CdV2k)
         `.trim()}
         
- ) : null} +
); }; diff --git a/src/pages/home/store.ts b/src/pages/home/store.ts new file mode 100644 index 0000000..5bbd5b4 --- /dev/null +++ b/src/pages/home/store.ts @@ -0,0 +1,15 @@ +import { createStore } from "zustand"; +import { persist } from "zustand/middleware"; + +type GameDataStore = { + score: number; +}; + +export const gameDataStore = createStore( + persist( + () => ({ + score: 0, + }), + { name: "gameData" } + ) +); diff --git a/src/utility/utils.ts b/src/utility/utils.ts index e71d88d..705c521 100644 --- a/src/utility/utils.ts +++ b/src/utility/utils.ts @@ -1,11 +1,10 @@ -import clsx from "clsx"; +import clsx, { ClassValue } from "clsx"; import { toast } from "react-toastify"; import { twMerge } from "tailwind-merge"; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export const cn = (...classNames: any[]) => { - return twMerge(clsx(...classNames)); -}; +export function cn(...classNames: ClassValue[]) { + return twMerge(clsx(classNames)); +} export const copyToClipboard = (data: string) => { if (typeof navigator !== "undefined") { diff --git a/tailwind.config.js b/tailwind.config.js index 926b4e7..be473ac 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,5 +1,6 @@ /** @type {import('tailwindcss').Config} */ -export default { +module.exports = { + darkMode: "class", content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], theme: { extend: { @@ -21,7 +22,21 @@ export default { boxShadow: { DEFAULT: "rgba(7,65,210,0.2) 0px 9px 20px", }, + keyframes: { + "accordion-down": { + from: { height: "0" }, + to: { height: "var(--radix-accordion-content-height)" }, + }, + "accordion-up": { + from: { height: "var(--radix-accordion-content-height)" }, + to: { height: "0" }, + }, + }, + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + }, }, }, - plugins: [], + plugins: [require("tailwindcss-animate")], }; diff --git a/yarn.lock b/yarn.lock index 3f99ed0..c7ae6da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -184,7 +184,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/runtime@^7.23.5": +"@babel/runtime@^7.13.10", "@babel/runtime@^7.23.5": version "7.23.7" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.7.tgz#dd7c88deeb218a0f8bd34d5db1aa242e0f203193" integrity sha512-w06OXVOFso7LcbzMiDGt+3X7Rh7Ho8MmgPoWU3rarH+8upf+wSU/grlGbWzQyr3DkdN6ZeuMFjpdwW0Q+HxobA== @@ -681,6 +681,148 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@radix-ui/primitive@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.1.tgz#e46f9958b35d10e9f6dc71c497305c22e3e55dbd" + integrity sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-compose-refs@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz#7ed868b66946aa6030e580b1ffca386dd4d21989" + integrity sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-context@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.1.tgz#fe46e67c96b240de59187dcb7a1a50ce3e2ec00c" + integrity sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-dialog@^1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz#71657b1b116de6c7a0b03242d7d43e01062c7300" + integrity sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-dismissable-layer" "1.0.5" + "@radix-ui/react-focus-guards" "1.0.1" + "@radix-ui/react-focus-scope" "1.0.4" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-portal" "1.0.4" + "@radix-ui/react-presence" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-slot" "1.0.2" + "@radix-ui/react-use-controllable-state" "1.0.1" + aria-hidden "^1.1.1" + react-remove-scroll "2.5.5" + +"@radix-ui/react-dismissable-layer@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz#3f98425b82b9068dfbab5db5fff3df6ebf48b9d4" + integrity sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-escape-keydown" "1.0.3" + +"@radix-ui/react-focus-guards@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz#1ea7e32092216b946397866199d892f71f7f98ad" + integrity sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-focus-scope@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz#2ac45fce8c5bb33eb18419cdc1905ef4f1906525" + integrity sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-callback-ref" "1.0.1" + +"@radix-ui/react-id@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.1.tgz#73cdc181f650e4df24f0b6a5b7aa426b912c88c0" + integrity sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-use-layout-effect" "1.0.1" + +"@radix-ui/react-portal@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.4.tgz#df4bfd353db3b1e84e639e9c63a5f2565fb00e15" + integrity sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-primitive" "1.0.3" + +"@radix-ui/react-presence@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.1.tgz#491990ba913b8e2a5db1b06b203cb24b5cdef9ba" + integrity sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-use-layout-effect" "1.0.1" + +"@radix-ui/react-primitive@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz#d49ea0f3f0b2fe3ab1cb5667eb03e8b843b914d0" + integrity sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-slot" "1.0.2" + +"@radix-ui/react-slot@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.0.2.tgz#a9ff4423eade67f501ffb32ec22064bc9d3099ab" + integrity sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-compose-refs" "1.0.1" + +"@radix-ui/react-use-callback-ref@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz#f4bb1f27f2023c984e6534317ebc411fc181107a" + integrity sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-use-controllable-state@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz#ecd2ced34e6330caf89a82854aa2f77e07440286" + integrity sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-use-callback-ref" "1.0.1" + +"@radix-ui/react-use-escape-keydown@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz#217b840c250541609c66f67ed7bab2b733620755" + integrity sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-use-callback-ref" "1.0.1" + +"@radix-ui/react-use-layout-effect@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz#be8c7bc809b0c8934acf6657b577daf948a75399" + integrity sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ== + dependencies: + "@babel/runtime" "^7.13.10" + "@remix-run/router@1.14.1": version "1.14.1" resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.14.1.tgz#6d2dd03d52e604279c38911afc1079d58c50a755" @@ -859,6 +1001,11 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== +"@types/uuid@^9.0.7": + version "9.0.7" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.7.tgz#b14cebc75455eeeb160d5fe23c2fcc0c64f724d8" + integrity sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g== + "@typescript-eslint/eslint-plugin@^6.14.0": version "6.17.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.17.0.tgz#dfc38f790704ba8a54a1277c51efdb489f6ecf9f" @@ -1033,6 +1180,13 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +aria-hidden@^1.1.1: + version "1.2.3" + resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.3.tgz#14aeb7fb692bbb72d69bebfa47279c1fd725e954" + integrity sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ== + dependencies: + tslib "^2.0.0" + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -1148,6 +1302,18 @@ chokidar@^3.5.3: optionalDependencies: fsevents "~2.3.2" +class-variance-authority@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/class-variance-authority/-/class-variance-authority-0.7.0.tgz#1c3134d634d80271b1837452b06d821915954522" + integrity sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A== + dependencies: + clsx "2.0.0" + +clsx@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b" + integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== + clsx@^1.1.1: version "1.2.1" resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" @@ -1237,6 +1403,11 @@ define-data-property@^1.1.1: gopd "^1.0.1" has-property-descriptors "^1.0.0" +detect-node-es@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493" + integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== + didyoumean@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" @@ -1547,6 +1718,11 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@ has-symbols "^1.0.3" hasown "^2.0.0" +get-nonce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" + integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -1690,6 +1866,13 @@ inherits@2: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -1834,7 +2017,7 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -1860,6 +2043,11 @@ lru-cache@^6.0.0: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484" integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag== +lucide-react@^0.306.0: + version "0.306.0" + resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.306.0.tgz#07e427c1c0e6c6d50712b746b889ff807606131c" + integrity sha512-eShuk2PI3vxN4YN8kNPmhAsroSvPXbtaxU/UX/zrBcLLg8FeFH9MG7C2EYzYsT2rNrPVjbP7rpBz3mOviZYN3A== + merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" @@ -2197,6 +2385,25 @@ react-refresh@^0.14.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ== +react-remove-scroll-bar@^2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz#53e272d7a5cb8242990c7f144c44d8bd8ab5afd9" + integrity sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A== + dependencies: + react-style-singleton "^2.2.1" + tslib "^2.0.0" + +react-remove-scroll@2.5.5: + version "2.5.5" + resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz#1e31a1260df08887a8a0e46d09271b52b3a37e77" + integrity sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw== + dependencies: + react-remove-scroll-bar "^2.3.3" + react-style-singleton "^2.2.1" + tslib "^2.1.0" + use-callback-ref "^1.3.0" + use-sidecar "^1.1.2" + react-router-dom@^6.21.1: version "6.21.1" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.21.1.tgz#58b459d2fe1841388c95bb068f85128c45e27349" @@ -2217,6 +2424,15 @@ react-side-effect@^2.1.0: resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.2.tgz#dc6345b9e8f9906dc2eeb68700b615e0b4fe752a" integrity sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw== +react-style-singleton@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4" + integrity sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g== + dependencies: + get-nonce "^1.0.0" + invariant "^2.2.4" + tslib "^2.0.0" + react-toastify@^9.1.3: version "9.1.3" resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-9.1.3.tgz#1e798d260d606f50e0fab5ee31daaae1d628c5ff" @@ -2447,6 +2663,11 @@ tailwind-merge@^2.2.0: dependencies: "@babel/runtime" "^7.23.5" +tailwindcss-animate@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz#318b692c4c42676cc9e67b19b78775742388bef4" + integrity sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA== + tailwindcss@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.0.tgz#045a9c474e6885ebd0436354e611a76af1c76839" @@ -2516,6 +2737,11 @@ ts-interface-checker@^0.1.9: resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== +tslib@^2.0.0, tslib@^2.1.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -2561,6 +2787,26 @@ url@^0.11.0: punycode "^1.4.1" qs "^6.11.2" +use-callback-ref@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.1.tgz#9be64c3902cbd72b07fe55e56408ae3a26036fd0" + integrity sha512-Lg4Vx1XZQauB42Hw3kK7JM6yjVjgFmFC5/Ab797s79aARomD2nEErc4mCgM8EZrARLmmbWpi5DGCadmK50DcAQ== + dependencies: + tslib "^2.0.0" + +use-sidecar@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2" + integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw== + dependencies: + detect-node-es "^1.1.0" + tslib "^2.0.0" + +use-sync-external-store@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== + util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -2626,3 +2872,10 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zustand@^4.4.7: + version "4.4.7" + resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.4.7.tgz#355406be6b11ab335f59a66d2cf9815e8f24038c" + integrity sha512-QFJWJMdlETcI69paJwhSMJz7PPWjVP8Sjhclxmxmxv/RYI7ZOvR5BHX+ktH0we9gTWQMxcne8q1OY8xxz604gw== + dependencies: + use-sync-external-store "1.2.0"