From 65c1972c499df9f9d6b5d390cbc499da97fd8002 Mon Sep 17 00:00:00 2001 From: Aodhan Date: Tue, 8 Jul 2025 23:04:43 +0100 Subject: [PATCH] Lots of stuff --- README.md | 12 +- TODO.md | 4 +- backend/app/router.py | 57 +- backend/requirements.txt | 1 + datasets/inventory.csv | 967 +++++++ docker-compose.yml | 31 +- frontend/Dockerfile | 16 + frontend/nginx.conf | 22 + frontend/package-lock.json | 2365 ++++++++++++++++- frontend/package.json | 6 + frontend/src/App.tsx | 30 +- .../src/__tests__/filterExplorerItems.test.ts | 25 + frontend/src/api.ts | 9 + frontend/src/components/ItemDetailPanel.tsx | 23 +- frontend/src/components/ItemsGrid.tsx | 25 +- frontend/src/components/MobileNav.tsx | 30 + frontend/src/constants/colors.ts | 27 + frontend/src/pages/Inventory.tsx | 167 +- frontend/src/pages/ItemExplorer.tsx | 148 +- frontend/src/pages/Recipes.tsx | 13 +- frontend/src/setupTests.ts | 1 + frontend/src/utils/filterExplorerItems.ts | 39 + frontend/tsconfig.json | 3 +- frontend/vitest.config.ts | 11 + scripts/README.md | 3 +- scripts/load_inventory_to_db.py | 163 ++ 26 files changed, 4094 insertions(+), 104 deletions(-) create mode 100755 datasets/inventory.csv create mode 100644 frontend/Dockerfile create mode 100644 frontend/nginx.conf create mode 100644 frontend/src/__tests__/filterExplorerItems.test.ts create mode 100644 frontend/src/components/MobileNav.tsx create mode 100644 frontend/src/constants/colors.ts create mode 100644 frontend/src/setupTests.ts create mode 100644 frontend/src/utils/filterExplorerItems.ts create mode 100644 frontend/vitest.config.ts create mode 100644 scripts/load_inventory_to_db.py diff --git a/README.md b/README.md index 098fdbc..24f66ac 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,13 @@ ## Key Features -* **Crafting Recipes** – browse every craft with filters, icons, ingredients, HQ yields, and cross-links to inventory. -* **Inventory Manager** – compact grid with tooltips, duplicate highlighting, scroll badges, and wiki links. -* **Item Explorer** – searchable catalogue with dynamic sub-tabs for each item type. -* **Spell Database** – scroll parsing auto-populates a `spells` table with job-level learn data. -* **Responsive UI** – desktop / tablet / mobile layouts. +* **Crafting Recipes** – colour-coded craft tabs (woodworking brown, smithing grey, etc.), full filters, icons, ingredients, HQ yields, and cross-links to inventory. +* **Inventory Manager** – grid view with sorting (slot ▶ default, name, type), duplicate-item indicator (orange bar on top), tooltips, quantity badges, and direct wiki links. +* **Item Explorer** – fast, fuzzy search across all items with type sub-tabs and recipe cross-navigation. +* **Item Detail Dialog** – centred modal with icon, description, usage breakdown, and craft-coloured section headers. +* **Responsive UI** – desktop / tablet / mobile layouts with dropdown storage selector on narrow screens. * **Database-backed** – PostgreSQL stores normalised recipe / item / inventory / spells data. -* **Automation Scripts** – Python ETL & loaders for recipes and spells. +* **Automation Scripts** – Python ETL & loaders for recipes and spells, plus scroll → spell parser. ## Project Structure diff --git a/TODO.md b/TODO.md index 0494cdc..0ef4592 100644 --- a/TODO.md +++ b/TODO.md @@ -1,9 +1,11 @@ # Project TODO ## Bugs +- [ ] Add automated regression test for explorer search (Vitest + RTL) + - [X] Pagination not working -- [ ] Fix search in explorer +- [X] Fix search in explorer ## UI Improvements diff --git a/backend/app/router.py b/backend/app/router.py index d185dfd..065e9bc 100644 --- a/backend/app/router.py +++ b/backend/app/router.py @@ -1,8 +1,8 @@ from typing import List, Optional, Tuple, Any from datetime import datetime -from fastapi import APIRouter, Depends, Query, HTTPException, Path, Response -from sqlalchemy import text, select +from fastapi import APIRouter, Depends, Query, HTTPException, Path, Response, UploadFile, File +from sqlalchemy import text, select, insert from sqlalchemy.ext.asyncio import AsyncSession from pydantic import BaseModel @@ -14,6 +14,52 @@ router = APIRouter() # --------------------------------------------------------------------------- # Crafting Recipes endpoints +@router.post("/inventory/import") +async def import_inventory_csv( + file: UploadFile = File(...), + session: AsyncSession = Depends(get_session), +): + """Replace the entire inventory table with contents from an uploaded CSV. + + The CSV must use the delimiter ``;`` and column headers: ``char;storage;item;quantity``. + """ + import csv + import io + # Read file bytes and decode + contents = await file.read() + try: + text_data = contents.decode("utf-8") + except UnicodeDecodeError: + raise HTTPException(status_code=400, detail="CSV must be UTF-8 encoded") + + reader = csv.DictReader(io.StringIO(text_data), delimiter=";", quotechar='"') + rows = [] + for r in reader: + try: + qty = int(r["quantity"].strip()) if r["quantity"].strip() else 0 + except (KeyError, ValueError): + raise HTTPException(status_code=400, detail="Invalid CSV schema or quantity value") + rows.append( + { + "character_name": r["char"].strip(), + "storage_type": r["storage"].strip(), + "item_name": r["item"].strip(), + "quantity": qty, + } + ) + + # Replace table contents inside a transaction + try: + await session.execute(text("TRUNCATE TABLE inventory;")) + if rows: + await session.execute(insert(Inventory), rows) + await session.commit() + except Exception as e: + await session.rollback() + raise HTTPException(status_code=500, detail=f"Failed to import CSV: {e}") + + return {"imported": len(rows)} + ALLOWED_CRAFTS = { "woodworking": "recipes_woodworking", # Future crafts can be added here, e.g. "smithing": "recipes_smithing" @@ -102,6 +148,7 @@ class ItemSummary(BaseModel): name: str icon_id: Optional[str] type_description: Optional[str] + jobs_description: Optional[List[str]] @router.get("/items", response_model=List[ItemSummary]) @@ -139,12 +186,14 @@ async def items( total_count = total_res.scalar() or 0 response.headers["X-Total-Count"] = str(total_count) + # Use LEFT JOIN to fetch jobs_description from armor_items table; it will be NULL for non-armor. + join_sql = "FROM all_items a LEFT JOIN armor_items ai ON ai.id = a.id" q = text( - f"SELECT id, name, icon_id, type_description FROM all_items {where_sql} ORDER BY id LIMIT :limit OFFSET :offset" + f"SELECT a.id, a.name, a.icon_id, a.type_description, ai.jobs_description {join_sql} {where_sql} ORDER BY a.id LIMIT :limit OFFSET :offset" ) result = await session.execute(q, params) rows = result.fetchall() - return [ItemSummary(id=r.id, name=r.name, icon_id=r.icon_id, type_description=r.type_description) for r in rows] + return [ItemSummary(id=r.id, name=r.name, icon_id=r.icon_id, type_description=r.type_description, jobs_description=r.jobs_description) for r in rows] class ItemDetail(BaseModel): diff --git a/backend/requirements.txt b/backend/requirements.txt index d2ac312..2db5881 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -4,3 +4,4 @@ SQLAlchemy[asyncio]==2.0.27 asyncpg==0.29.0 pydantic==2.7.1 python-dotenv==1.0.1 +python-multipart==0.0.9 diff --git a/datasets/inventory.csv b/datasets/inventory.csv new file mode 100755 index 0000000..4024686 --- /dev/null +++ b/datasets/inventory.csv @@ -0,0 +1,967 @@ +"char";"storage";"item";"quantity" +"Rynore";"inventory";"Bone Quiver";"1" +"Rynore";"inventory";"Instant Warp";"1" +"Rynore";"inventory";"Bone Chip";"1" +"Rynore";"inventory";"Moko Grass";"1" +"Rynore";"inventory";"Florid Leaf Mold";"7" +"Rynore";"inventory";"Adoulinian Kelp";"1" +"Rynore";"inventory";"Linkpearl";"1" +"Rynore";"inventory";"Frgtn. Thought";"1" +"Rynore";"inventory";"Goblin Stir-Fry";"1" +"Rynore";"inventory";"Potion";"1" +"Rynore";"inventory";"Onion Dagger";"2" +"Rynore";"inventory";"Maple Table";"3" +"Rynore";"inventory";"Hatchet";"10" +"Rynore";"inventory";"Onion Rod";"2" +"Rynore";"inventory";"Onion Staff";"1" +"Rynore";"inventory";"Ark Shield";"1" +"Rynore";"inventory";"Apple Pie";"1" +"Rynore";"inventory";"Echo Drops";"1" +"Rynore";"inventory";"Distilled Water";"1" +"Rynore";"inventory";"Derfland Pear";"1" +"Rynore";"inventory";"Rem's Tale Ch.2";"2" +"Rynore";"inventory";"Vlr. Gauntlets -1";"1" +"Rynore";"inventory";"Eggplant";"1" +"Rynore";"inventory";"Roast Mushroom";"5" +"Rynore";"inventory";"Ginger";"1" +"Rynore";"inventory";"Little Worm";"5" +"Rynore";"inventory";"Pugil Scales";"3" +"Rynore";"inventory";"Vile Elixir";"1" +"Rynore";"inventory";"Chariot Band";"1" +"Rynore";"inventory";"Sickle";"1" +"Rynore";"inventory";"San d'Or. Carrot";"6" +"Rynore";"inventory";"Woozyshroom";"12" +"Rynore";"inventory";"Mythril Ore";"1" +"Rynore";"inventory";"Elm Strongbox";"1" +"Rynore";"inventory";"Mahogany Bed";"1" +"Rynore";"inventory";"Venus Orb";"1" +"Rynore";"inventory";"Win. Tea Leaves";"4" +"Rynore";"inventory";"Baked Popoto";"8" +"Rynore";"inventory";"M Rice Cake";"1" +"Rynore";"inventory";"Lilac";"2" +"Rynore";"inventory";"Rockoil";"7" +"Rynore";"inventory";"Flint Caviar";"1" +"Rynore";"inventory";"Selbina Clay";"1" +"Rynore";"inventory";"Napa";"2" +"Rynore";"inventory";"Spider Web";"1" +"Rynore";"inventory";"Iolite";"1" +"Rynore";"inventory";"Rusty Bucket";"5" +"Rynore";"inventory";"Sea Foliage";"1" +"Rynore";"inventory";"Pea Soup";"1" +"Rynore";"inventory";"Auric Sand";"1" +"Rynore";"inventory";"Beetle Jaw";"3" +"Rynore";"inventory";"Roast Mutton";"2" +"Rynore";"inventory";"Saruta Orange";"1" +"Rynore";"inventory";"Herb Seeds";"4" +"Rynore";"inventory";"Vegetable Gruel";"1" +"Rynore";"inventory";"Moldy Torque";"1" +"Rynore";"inventory";"Crawler Cocoon";"5" +"Rynore";"inventory";"Voidleg: DRG";"1" +"Rynore";"inventory";"Parchment";"1" +"Rynore";"inventory";"G. Seed Pouch";"11" +"Rynore";"inventory";"King Locust";"1" +"Rynore";"inventory";"Snapping Mole";"1" +"Rynore";"inventory";"Moat Carp";"5" +"Rynore";"inventory";"Insect Wing";"1" +"Rynore";"inventory";"E Rice Cake";"1" +"Rynore";"inventory";"Gnatbane";"1" +"Rynore";"inventory";"Whine Cellar Key";"1" +"Rynore";"inventory";"Burdock";"1" +"Rynore";"inventory";"Date";"1" +"Rynore";"inventory";"Sheep Tooth";"7" +"Rynore";"inventory";"Tomato Juice";"1" +"Rynore";"wardrobe";"Windshear Hat";"1" +"Rynore";"wardrobe";"Duelist's Gloves";"1" +"Rynore";"wardrobe";"Asn. Poulaines +1";"1" +"Rynore";"wardrobe";"Beetle Leggings";"1" +"Rynore";"wardrobe";"Cuffs";"1" +"Rynore";"wardrobe";"Chocobo Masque +1";"1" +"Rynore";"wardrobe";"She-Slime Hat";"1" +"Rynore";"wardrobe";"Shade Tights";"1" +"Rynore";"wardrobe";"Chocobo Shirt";"1" +"Rynore";"wardrobe";"Targe";"1" +"Rynore";"wardrobe";"Bl. Chocobo Suit";"1" +"Rynore";"wardrobe";"Studded Gloves";"1" +"Rynore";"wardrobe";"Slacks";"1" +"Rynore";"wardrobe";"Scale Greaves";"1" +"Rynore";"wardrobe";"Lizard Ledelsens";"1" +"Rynore";"wardrobe";"Rusty Cap";"3" +"Rynore";"wardrobe";"Purple Ribbon";"1" +"Rynore";"wardrobe";"Scale Cuisses";"1" +"Rynore";"wardrobe";"Chain Hose";"1" +"Rynore";"wardrobe";"Garish Crown";"1" +"Rynore";"wardrobe";"Cotton Gaiters";"1" +"Rynore";"wardrobe";"Vgd. Gloves";"2" +"Rynore";"wardrobe";"Studded Vest";"1" +"Rynore";"wardrobe";"Alumine Moufles";"1" +"Rynore";"wardrobe";"Alumine Sollerets";"1" +"Rynore";"wardrobe";"Mitts";"1" +"Rynore";"wardrobe";"Trader's Slops";"1" +"Rynore";"wardrobe";"Lizard Trousers";"1" +"Rynore";"wardrobe";"Scale Fng. Gnt.";"1" +"Rynore";"wardrobe";"Chocobo Suit +1";"1" +"Rynore";"wardrobe";"Gloves";"1" +"Rynore";"wardrobe";"Blue Ribbon";"1" +"Rynore";"wardrobe";"Raising Earring";"1" +"Rynore";"wardrobe";"Destrier Beret";"1" +"Rynore";"wardrobe";"Naga Hakama";"1" +"Rynore";"wardrobe";"Thur. Gloves +1";"1" +"Rynore";"wardrobe";"White Mitts";"1" +"Rynore";"wardrobe";"Thur. Tabard +1";"1" +"Rynore";"wardrobe";"Bone Pick";"1" +"Rynore";"wardrobe";"Slime Cap";"1" +"Rynore";"wardrobe";"Elm Pole";"1" +"Rynore";"wardrobe";"Tabar";"1" +"Rynore";"wardrobe";"Dream Hat";"1" +"Rynore";"wardrobe";"Bone Hairpin";"1" +"Rynore";"wardrobe";"Alumine Salade";"1" +"Rynore";"wardrobe";"Studded Trousers";"1" +"Rynore";"wardrobe";"Iron Cuisses";"1" +"Rynore";"wardrobe";"Overalls";"1" +"Rynore";"wardrobe";"Trader's Cuffs";"1" +"Rynore";"wardrobe";"Garish Tunic";"1" +"Rynore";"wardrobe";"Alumine Brayettes";"1" +"Rynore";"wardrobe";"Alumine Haubert";"1" +"Rynore";"wardrobe";"Trader's Pigaches";"1" +"Rynore";"wardrobe";"Brass Subligar";"1" +"Rynore";"wardrobe";"Lizard Gloves";"1" +"Rynore";"wardrobe";"Tide Gages";"1" +"Rynore";"wardrobe";"Brass Mittens";"1" +"Rynore";"wardrobe";"Bl. Chocobo Cap";"1" +"Rynore";"wardrobe";"Phl. Trousers";"1" +"Rynore";"wardrobe";"Snowman Cap";"1" +"Rynore";"wardrobe";"Slops";"1" +"Rynore";"wardrobe";"Greaves";"1" +"Rynore";"wardrobe";"Thur. Chapeau +1";"1" +"Rynore";"wardrobe";"Cotton Brais";"1" +"Rynore";"wardrobe";"Sitabaki";"1" +"Rynore";"wardrobe";"Thur. Boots +1";"1" +"Rynore";"wardrobe";"Thur. Tights +1";"1" +"Rynore";"wardrobe";"Temple Torque";"1" +"Rynore";"wardrobe";"Kingdom Aketon";"1" +"Rynore";"wardrobe";"Metal Slime Hat";"1" +"Rynore";"wardrobe";"Solea";"1" +"Rynore";"wardrobe";"Garish Slacks";"1" +"Rynore";"wardrobe";"Cotton Gloves";"1" +"Rynore";"safe";"Bookshelf";"2" +"Rynore";"safe";"Treant Bulb";"8" +"Rynore";"safe";"Giant Fish Bones";"1" +"Rynore";"safe";"Wool Thread";"1" +"Rynore";"safe";"Cabinet";"1" +"Rynore";"safe";"Pugil Scales";"10" +"Rynore";"safe";"Cupboard";"1" +"Rynore";"safe";"VCS Reg. Card";"1" +"Rynore";"safe";"Wastebasket";"1" +"Rynore";"safe";"Qdv. Mage Blood";"1" +"Rynore";"safe";"Gnole Pellets";"1" +"Rynore";"safe";"Mannequin Feet";"1" +"Rynore";"safe";"Recital Bench";"1" +"Rynore";"safe";"Bahut";"1" +"Rynore";"safe";"Bookstack";"1" +"Rynore";"safe";"Regen III";"1" +"Rynore";"safe";"Slime Rocket";"9" +"Rynore";"safe";"R. Orchid Vase";"1" +"Rynore";"safe";"Stationery Set";"1" +"Rynore";"safe";"Ceramic Flowerpot";"1" +"Rynore";"safe";"Ram Skin";"12" +"Rynore";"safe";"Lizard Skin";"8" +"Rynore";"safe";"Dial Key #Ab";"16" +"Rynore";"safe";"Butterfly Cage";"1" +"Rynore";"safe";"Chest";"1" +"Rynore";"safe";"Wicker Box";"1" +"Rynore";"safe";"Maple Table";"1" +"Rynore";"safe";"Wolf Hide";"7" +"Rynore";"safe";"San d'Orian Tree";"1" +"Rynore";"safe";"Noble's Bed";"1" +"Rynore";"safe";"Vana'clock";"1" +"Rynore";"safe";"Thundaga II";"1" +"Rynore";"safe";"Reraise III";"1" +"Rynore";"safe";"Snowman Knight";"1" +"Rynore";"safe";"Gain-STR";"1" +"Rynore";"safe";"Firesand";"1" +"Rynore";"safe";"Fiend Blood";"5" +"Rynore";"safe";"Brass Ingot";"2" +"Rynore";"safe";"Silver Beastcoin";"12" +"Rynore";"safe";"6-Drawer Almirah";"1" +"Rynore";"safe";"F.Abjuration: Bd.";"1" +"Rynore";"safe";"Shellra IV";"1" +"Rynore";"safe";"Wardrobe";"1" +"Rynore";"safe";"Foe Lullaby";"1" +"Rynore";"safe";"Tantra Seal: Ft.";"4" +"Rynore";"safe";"San d'Orian Flag";"1" +"Rynore";"safe";"Bonbori";"1" +"Rynore";"safe";"Arrowwood Lbr.";"5" +"Rynore";"safe";"Refresh";"1" +"Rynore";"safe";"Ram Horn";"5" +"Rynore";"safe";"Luminicloth";"4" +"Rynore";"safe";"Giant Stinger";"4" +"Rynore";"safe";"Cotton Cloth";"4" +"Rynore";"safe";"Yel. VCS Plaque";"1" +"Rynore";"safe";"Deton. Sphere";"5" +"Rynore";"safe";"Ornate Fragment";"1" +"Rynore";"safe";"Adaman Ore";"4" +"Rynore";"safe";"Prismatic Chest";"1" +"Rynore";"safe";"Insect Wing";"12" +"Rynore";"storage";"Red Moko Grass";"4" +"Rynore";"storage";"Va.Abjuration: Ft.";"1" +"Rynore";"storage";"Mahogany Log";"3" +"Rynore";"storage";"Ephemeral Cloth";"1" +"Rynore";"storage";"Sleepshroom";"1" +"Rynore";"storage";"Coeurl Meat";"1" +"Rynore";"storage";"Vegetable Seeds";"7" +"Rynore";"storage";"Mythril Leaf";"1" +"Rynore";"storage";"Titanite";"4" +"Rynore";"storage";"Ash Lumber";"12" +"Rynore";"storage";"Land Crab Meat";"12" +"Rynore";"storage";"Vanilla";"5" +"Rynore";"storage";"Chamomile";"1" +"Rynore";"storage";"Bukktooth";"1" +"Rynore";"storage";"Mhaura Garlic";"3" +"Rynore";"storage";"Cockatrice Meat";"1" +"Rynore";"storage";"Poison Dust";"2" +"Rynore";"storage";"Mushrm. Locust";"3" +"Rynore";"storage";"Cactus Stems";"3" +"Rynore";"storage";"Dried Marjoram";"1" +"Rynore";"storage";"Elm Log";"12" +"Rynore";"storage";"Rotten Meat";"17" +"Rynore";"storage";"Red Terrapin";"16" +"Rynore";"storage";"Mighty Sardonyx";"1" +"Rynore";"storage";"Quus";"18" +"Rynore";"storage";"Hare Meat";"29" +"Rynore";"storage";"Insect Wing";"6" +"Rynore";"storage";"Lizard Egg";"2" +"Rynore";"storage";"Bomb Ash";"1" +"Rynore";"storage";"Eastern Gem";"3" +"Rynore";"storage";"Dhalmel Hide";"1" +"Rynore";"storage";"Blk. Tiger Fang";"12" +"Rynore";"storage";"Mulsum";"11" +"Rynore";"storage";"Crawler Calculus";"1" +"Rynore";"storage";"Royal Jelly";"1" +"Rynore";"storage";"Crystal Petrifact";"1" +"Rynore";"storage";"Chestnut";"7" +"Rynore";"storage";"Win. Tea Leaves";"10" +"Rynore";"storage";"Honey";"31" +"Rynore";"storage";"Hecteyes Eye";"2" +"Rynore";"storage";"Crawler Cocoon";"11" +"Rynore";"storage";"Acorn";"5" +"Rynore";"storage";"Chocobo Fltchg.";"2" +"Rynore";"storage";"Faerie Apple";"8" +"Rynore";"storage";"Deathball";"1" +"Rynore";"storage";"Seedspall Lux";"1" +"Rynore";"storage";"Poison Potion";"3" +"Rynore";"storage";"Recoll. of Pain";"1" +"Rynore";"storage";"Chestnut Log";"1" +"Rynore";"storage";"Pine Nuts";"7" +"Rynore";"storage";"Scop's Operetta";"1" +"Rynore";"storage";"Black Pepper";"7" +"Rynore";"storage";"Jade Cell";"2" +"Rynore";"storage";"Wild Onion";"5" +"Rynore";"storage";"Yogurt";"6" +"Rynore";"storage";"Yagudo Feather";"12" +"Rynore";"storage";"Black C. Feather";"1" +"Rynore";"storage";"Kazham Peppers";"9" +"Rynore";"storage";"Crawler Egg";"1" +"Rynore";"storage";"Fish Mithkabob";"12" +"Rynore";"storage";"Toko. Wildgrass";"12" +"Rynore";"storage";"Dryad Root";"2" +"Rynore";"storage";"Mtl. Beastcoin";"2" +"Rynore";"storage";"Dhalmel Meat";"11" +"Rynore";"storage";"Arrowwood Lbr.";"12" +"Rynore";"storage";"Tarutaru Rice";"12" +"Rynore";"storage";"Danceshroom";"1" +"Rynore";"storage";"G. Sheep Meat";"4" +"Rynore";"storage";"Beetle Shell";"24" +"Rynore";"storage";"Rosewood Log";"1" +"Rynore";"storage";"Soy Milk";"16" +"Rynore";"satchel";"H.Q. Antlion Jaw";"10" +"Rynore";"satchel";"King Truffle";"6" +"Rynore";"satchel";"Slime Oil";"3" +"Rynore";"satchel";"Adamantoise Shell";"5" +"Rynore";"satchel";"Phrygian Ore";"1" +"Rynore";"satchel";"Fire V";"1" +"Rynore";"satchel";"Moko Grass";"1" +"Rynore";"satchel";"Holy Basil";"2" +"Rynore";"satchel";"Adoulinian Kelp";"31" +"Rynore";"satchel";"Bat Fang";"9" +"Rynore";"satchel";"Maple Log";"4" +"Rynore";"satchel";"Antlion Jaw";"4" +"Rynore";"satchel";"Silver Nugget";"2" +"Rynore";"satchel";"Sage";"3" +"Rynore";"satchel";"Eudaemon Blade";"1" +"Rynore";"satchel";"H.Q. Marid Hide";"1" +"Rynore";"satchel";"Tree Cuttings";"5" +"Rynore";"satchel";"Chicken Bone";"1" +"Rynore";"satchel";"Fresh Marjoram";"12" +"Rynore";"satchel";"Senroh Sardine";"20" +"Rynore";"satchel";"Saruta Cotton";"12" +"Rynore";"satchel";"Blue Peas";"2" +"Rynore";"satchel";"Elm Log";"1" +"Rynore";"satchel";"Mackerel";"12" +"Rynore";"satchel";"H.Q. B. Tiger Hide";"1" +"Rynore";"satchel";"Bat Wing";"7" +"Rynore";"satchel";"Saffron";"1" +"Rynore";"satchel";"Insect Wing";"9" +"Rynore";"satchel";"Scorpion Claw";"21" +"Rynore";"satchel";"Eggplant";"11" +"Rynore";"satchel";"Herb Seeds";"12" +"Rynore";"satchel";"Pugil Scales";"10" +"Rynore";"satchel";"Malboro Vine";"1" +"Rynore";"satchel";"Kukuru Bean";"3" +"Rynore";"satchel";"Tomato Juice";"1" +"Rynore";"satchel";"Snow Geode";"1" +"Rynore";"satchel";"Blizzard III";"1" +"Rynore";"satchel";"Flax Flower";"11" +"Rynore";"satchel";"Wyvern Wing";"1" +"Rynore";"satchel";"Scorpion Shell";"3" +"Rynore";"satchel";"Crawler Cocoon";"12" +"Rynore";"satchel";"Stonega III";"1" +"Rynore";"satchel";"Grain Seeds";"12" +"Rynore";"satchel";"Mercury";"10" +"Rynore";"satchel";"Bay Leaves";"5" +"Rynore";"satchel";"Lacquer Tree Log";"4" +"Rynore";"satchel";"Fire III";"1" +"Rynore";"satchel";"Sheep Tooth";"12" +"Rynore";"satchel";"Ladybug Wing";"7" +"Rynore";"satchel";"Rabbit Hide";"4" +"Rynore";"satchel";"Stone IV";"1" +"Rynore";"satchel";"Ash Log";"2" +"Rynore";"satchel";"San d'Or. Flour";"4" +"Rynore";"satchel";"Crab Shell";"1" +"Rynore";"satchel";"Crayfish";"42" +"Rynore";"satchel";"Sacrifice";"1" +"Rynore";"satchel";"Sunflower Seeds";"2" +"Rynore";"satchel";"Tin Ore";"2" +"Rynore";"satchel";"Lizard Tail";"4" +"Rynore";"satchel";"Fresh Mugwort";"3" +"Rynore";"satchel";"King Locust";"3" +"Rynore";"satchel";"Snapping Mole";"12" +"Rynore";"satchel";"Mannequin Body";"1" +"Rynore";"satchel";"Copper Frog";"12" +"Rynore";"satchel";"Ulbukan Lobster";"15" +"Rynore";"satchel";"Spider Web";"21" +"Rynore";"satchel";"Giant Bird Fthr.";"1" +"Rynore";"satchel";"Fish Bones";"5" +"Rynore";"satchel";"Beetle Shell";"4" +"Rynore";"satchel";"Saffron Blossom";"2" +"Rynore";"satchel";"Bee Pollen";"1" +"Rynore";"sack";"Honey Wine";"1" +"Rynore";"sack";"Damselfly Worm";"1" +"Rynore";"sack";"Gold Ore";"2" +"Rynore";"sack";"Crab Sushi";"12" +"Rynore";"sack";"Bone Chip";"30" +"Rynore";"sack";"Maple Lumber";"2" +"Rynore";"sack";"Roasted Corn";"6" +"Rynore";"sack";"Antlion Spirit";"59" +"Rynore";"sack";"Yag. Holy Water";"1" +"Rynore";"sack";"Cactus Arm";"3" +"Rynore";"sack";"Ash Lumber";"7" +"Rynore";"sack";"Silent Oil";"12" +"Rynore";"sack";"Beetle Spirit";"53" +"Rynore";"sack";"Sage";"4" +"Rynore";"sack";"Platinum Ore";"4" +"Rynore";"sack";"Igneous Rock";"8" +"Rynore";"sack";"Marguerite";"2" +"Rynore";"sack";"Graubg. Lettuce";"1" +"Rynore";"sack";"Mola Mola";"2" +"Rynore";"sack";"Frost Turnip";"1" +"Rynore";"sack";"Trail Cookie";"3" +"Rynore";"sack";"Saruta Cotton";"9" +"Rynore";"sack";"Distilled Water";"1" +"Rynore";"sack";"Bkn. Fast. Rod";"1" +"Rynore";"sack";"Silk Cloth";"1" +"Rynore";"sack";"Asphodel";"2" +"Rynore";"sack";"Walnut Log";"1" +"Rynore";"sack";"La Theine Cbg.";"3" +"Rynore";"sack";"Yayla Corbasi";"1" +"Rynore";"sack";"Black Pearl";"1" +"Rynore";"sack";"Gem of the South";"1" +"Rynore";"sack";"Grass Thread";"6" +"Rynore";"sack";"Sole Sushi";"11" +"Rynore";"sack";"San d'Or. Carrot";"8" +"Rynore";"sack";"Mythril Ore";"5" +"Rynore";"sack";"Prism Powder";"12" +"Rynore";"sack";"Cld. Coffer Key";"1" +"Rynore";"sack";"Fruit Seeds";"8" +"Rynore";"sack";"Hard-boiled Egg";"2" +"Rynore";"sack";"Win. Tea Leaves";"12" +"Rynore";"sack";"Beastcoin";"1" +"Rynore";"sack";"Pachy. Spirit";"5" +"Rynore";"sack";"Ladybug Wing";"2" +"Rynore";"sack";"Loc. Elutriator";"1" +"Rynore";"sack";"Vanadium Ore";"1" +"Rynore";"sack";"Popoto";"3" +"Rynore";"sack";"Rancor Tank";"1" +"Rynore";"sack";"O. Bronzepiece";"1" +"Rynore";"sack";"Beastman Blood";"2" +"Rynore";"sack";"Burdock";"1" +"Rynore";"sack";"Deodorizer";"12" +"Rynore";"sack";"Monkey Wine";"1" +"Rynore";"sack";"Twitherym Wing";"1" +"Rynore";"sack";"Beetle Jaw";"8" +"Rynore";"sack";"Rancor Handle";"1" +"Rynore";"sack";"Isleracea";"1" +"Rynore";"sack";"Teak Log";"1" +"Rynore";"sack";"Yagudo Cherry";"3" +"Rynore";"sack";"P. DRK Card";"1" +"Rynore";"sack";"Snowy Cermet";"1" +"Rynore";"sack";"Umbril Ooze";"1" +"Rynore";"sack";"Remedy";"3" +"Rynore";"sack";"Misx. Parsley";"7" +"Rynore";"sack";"Shrimp Lantern";"1" +"Rynore";"sack";"Darksteel Ore";"11" +"Rynore";"sack";"Star Spinel";"1" +"Rynore";"sack";"Vegetable Seeds";"8" +"Rynore";"sack";"Auric Sand";"6" +"Rynore";"sack";"Counterfeit Gil";"3" +"Rynore";"sack";"Beetle Shell";"3" +"Rynore";"sack";"Shall Shell";"16" +"Rynore";"sack";"Meteorite";"2" +"Rynore";"sack";"Ph. Gold Ingot";"1" +"Rynore";"sack";"Obr. Bull. Pouch";"1" +"Rynore";"case";"Prelate Key";"1" +"Rynore";"case";"Beitetsu";"58" +"Rynore";"case";"Kitchen Stove";"1" +"Rynore";"case";"Goblin Helm";"3" +"Rynore";"case";"Stone Arrowhd.";"36" +"Rynore";"case";"Bat Fang";"60" +"Rynore";"case";"Voiddust";"1" +"Rynore";"case";"Ram Skin";"2" +"Rynore";"case";"Tonberry Lantern";"1" +"Rynore";"case";"Ametrine";"1" +"Rynore";"case";"G. Bird Plume";"1" +"Rynore";"case";"Nyumomo Doll";"1" +"Rynore";"case";"Goblin Mail";"2" +"Rynore";"case";"Xhifhut Body";"1" +"Rynore";"case";"Cactus Stems";"1" +"Rynore";"case";"Fluorite";"1" +"Rynore";"case";"Silver Beastcoin";"1" +"Rynore";"case";"Unlit Lantern";"1" +"Rynore";"case";"Breeze Geode";"1" +"Rynore";"case";"Bat Wing";"22" +"Rynore";"case";"Echo Drops";"12" +"Rynore";"case";"Xhifhut Strings";"1" +"Rynore";"case";"Antican Pauldron";"1" +"Rynore";"case";"Gold Beastcoin";"1" +"Rynore";"case";"Roast Mushroom";"12" +"Rynore";"case";"Raptor Skin";"2" +"Rynore";"case";"Cobalt Cell";"1" +"Rynore";"case";"Amemet Skin";"1" +"Rynore";"case";"Blk. Tiger Fang";"3" +"Rynore";"case";"Gigas Socks";"5" +"Rynore";"case";"Prism Powder";"12" +"Rynore";"case";"Mermaid Hands";"1" +"Rynore";"case";"Xhifhut Bow";"1" +"Rynore";"case";"Xanthous Cell";"1" +"Rynore";"case";"Rabbit Hide";"20" +"Rynore";"case";"Percolator";"1" +"Rynore";"case";"Sun Water";"1" +"Rynore";"case";"Diorite";"1" +"Rynore";"case";"P. WHM Card";"1" +"Rynore";"case";"Chocobo Fltchg.";"198" +"Rynore";"case";"Animal Glue";"3" +"Rynore";"case";"Sanguinet";"1" +"Rynore";"case";"Revival Root";"19" +"Rynore";"case";"Seasoning Stone";"24" +"Rynore";"case";"Fish Bones";"6" +"Rynore";"case";"Cotton Thread";"9" +"Rynore";"case";"Samwell's Shank";"1" +"Rynore";"case";"Beetle Jaw";"12" +"Rynore";"case";"Kitchen Brick";"1" +"Rynore";"case";"Jade Cell";"1" +"Rynore";"case";"Tree Sap";"1" +"Rynore";"case";"Flickering Lantern";"1" +"Rynore";"case";"Oak Log";"1" +"Rynore";"case";"Tonberry Coat";"21" +"Rynore";"case";"Tin Ore";"1" +"Rynore";"case";"Cockatrice Meat";"2" +"Rynore";"case";"Arrowwood Lbr.";"15" +"Rynore";"case";"Delkfutt Key";"1" +"Rynore";"case";"Sheepskin";"3" +"Rynore";"case";"Legshard: GEO";"1" +"Rynore";"case";"Indi-Frailty";"1" +"Rynore";"case";"Elm Lumber";"1" +"Rynore";"case";"Lufet Salt";"2" +"Rynore";"case";"Soil Geode";"1" +"Rynore";"case";"Rubicund Cell";"1" +"Rynore";"case";"Beetle Shell";"8" +"Rynore";"case";"Fenrite";"1" +"Rynore";"case";"Wamoura Silk";"1" +"Rynore";"safe2";"Grass Cloth";"2" +"Rynore";"safe2";"Bronze Rose";"1" +"Rynore";"safe2";"Bst. Testimony";"1" +"Rynore";"safe2";"Seasoning Stone";"8" +"Rynore";"safe2";"Tonko: Ni";"1" +"Rynore";"safe2";"Flint Stone";"16" +"Rynore";"safe2";"Argyro Rivet";"1" +"Rynore";"safe2";"Pld. Testimony";"1" +"Rynore";"safe2";"Absorb-INT";"1" +"Rynore";"safe2";"Beeswax";"5" +"Rynore";"safe2";"Absorb-VIT";"1" +"Rynore";"safe2";"Indi-Wilt";"1" +"Rynore";"safe2";"Archer's Prelude";"1" +"Rynore";"safe2";"Rng. Testimony";"1" +"Rynore";"safe2";"E.Abjuration: Hd.";"1" +"Rynore";"safe2";"Mizu-Deppo";"99" +"Rynore";"safe2";"Fossilized Fang";"6" +"Rynore";"safe2";"Drk. Testimony";"1" +"Rynore";"safe2";"P.Abjuration: Ft.";"1" +"Rynore";"safe2";"Raiton: Ni";"1" +"Rynore";"safe2";"Riftborn Boulder";"69" +"Rynore";"safe2";"War. Testimony";"1" +"Rynore";"safe2";"A.Abjuration: Ft.";"1" +"Rynore";"safe2";"Silver Ore";"9" +"Rynore";"safe2";"Mercury";"7" +"Rynore";"safe2";"Mythril Ore";"12" +"Rynore";"safe2";"E.Abjuration: Hn.";"1" +"Rynore";"safe2";"Papaka Grass";"2" +"Rynore";"safe2";"Sciss. Sphere";"8" +"Rynore";"safe2";"Drg. Testimony";"1" +"Rynore";"safe2";"Bird Feather";"14" +"Rynore";"safe2";"Lindwurm Skin";"2" +"Rynore";"safe2";"Iron Ore";"15" +"Rynore";"safe2";"Spect. Goldenrod";"2" +"Rynore";"safe2";"Ancient Blood";"1" +"Rynore";"safe2";"Nin. Testimony";"1" +"Rynore";"safe2";"Saruta Cotton";"7" +"Rynore";"safe2";"Absorb-AGI";"1" +"Rynore";"safe2";"Doton: Ni";"1" +"Rynore";"safe2";"Huton: Ni";"1" +"Rynore";"safe2";"Yagudo Feather";"7" +"Rynore";"safe2";"2Leaf Mandra Bud";"4" +"Rynore";"safe2";"Mnk. Testimony";"1" +"Rynore";"safe2";"Barrage Turbine";"1" +"Rynore";"safe2";"Bkn. Taru. Rod";"1" +"Rynore";"safe2";"Kopparnickel Ore";"7" +"Rynore";"safe2";"Slv. Arrowheads";"1" +"Rynore";"safe2";"Whm. Testimony";"1" +"Rynore";"safe2";"Silk Thread";"9" +"Rynore";"safe2";"Zinc Ore";"23" +"Rynore";"safe2";"Rdm. Testimony";"1" +"Rynore";"safe2";"Pluton";"22" +"Rynore";"safe2";"Steel Nugget";"1" +"Rynore";"safe2";"Dokumori: Ichi";"1" +"Rynore";"safe2";"Blm. Testimony";"1" +"Rynore";"safe2";"Dresser";"1" +"Rynore";"wardrobe2";"Wayfarer Clogs";"1" +"Rynore";"wardrobe2";"Buckler";"1" +"Rynore";"wardrobe2";"Carapace Mask";"1" +"Rynore";"wardrobe2";"Almogavar Bow";"1" +"Rynore";"wardrobe2";"Agile Mantle";"1" +"Rynore";"wardrobe2";"Shinobi Gi";"1" +"Rynore";"wardrobe2";"Velvet Hat";"1" +"Rynore";"wardrobe2";"Iron Mittens";"1" +"Rynore";"wardrobe2";"Gauntlets";"1" +"Rynore";"wardrobe2";"Hoplon";"1" +"Rynore";"wardrobe2";"Channeling Robe";"1" +"Rynore";"wardrobe2";"Shinobi Hakama";"1" +"Rynore";"wardrobe2";"Sahip Helm";"1" +"Rynore";"wardrobe2";"Shinobi Hachigane";"1" +"Rynore";"wardrobe2";"Wayfarer Circlet";"1" +"Rynore";"wardrobe2";"Cuir Trousers";"1" +"Rynore";"wardrobe2";"Wayfarer Slops";"1" +"Rynore";"wardrobe2";"Ogre Trousers";"1" +"Rynore";"wardrobe2";"Padded Armor";"1" +"Rynore";"wardrobe2";"Crow Beret";"1" +"Rynore";"wardrobe2";"Gambison";"1" +"Rynore";"wardrobe2";"Sallet";"1" +"Rynore";"wardrobe2";"Ryl.Sqr. Robe";"1" +"Rynore";"wardrobe2";"Wool Cuffs";"1" +"Rynore";"wardrobe2";"Gnd.T.K. Bangles";"1" +"Rynore";"wardrobe2";"Crow Hose";"1" +"Rynore";"wardrobe2";"Espial Cap";"1" +"Rynore";"wardrobe2";"Ryl.Kgt. Aketon";"1" +"Rynore";"wardrobe2";"Velvet Cuffs";"1" +"Rynore";"wardrobe2";"Gothic Sabatons";"1" +"Rynore";"wardrobe2";"Wayfarer Cuffs";"1" +"Rynore";"wardrobe2";"Wayfarer Robe";"1" +"Rynore";"wardrobe2";"Carapace Harness";"1" +"Rynore";"wardrobe2";"Cuir Highboots";"1" +"Rynore";"wardrobe2";"Carapace Subligar";"1" +"Rynore";"wardrobe2";"Cuisses";"1" +"Rynore";"wardrobe2";"Red Cap";"1" +"Rynore";"wardrobe2";"Crow Gaiters";"1" +"Rynore";"wardrobe2";"Iron Subligar";"1" +"Rynore";"wardrobe2";"Shinobi Tekko";"1" +"Rynore";"wardrobe2";"Garish Pumps";"1" +"Rynore";"wardrobe2";"Breastplate";"1" +"Rynore";"wardrobe2";"Espial Bracers";"1" +"Rynore";"wardrobe2";"Crow Jupon";"1" +"Rynore";"wardrobe2";"Darksteel Axe";"1" +"Rynore";"wardrobe2";"Hose";"1" +"Rynore";"wardrobe2";"Shinobi Kyahan";"1" +"Rynore";"wardrobe2";"Kacura Cap";"1" +"Rynore";"wardrobe2";"Cuir Bouilli";"1" +"Rynore";"wardrobe2";"Alkyoneus's Brc.";"1" +"Rynore";"wardrobe2";"Plain Pick";"1" +"Rynore";"wardrobe2";"Coalrake Sabots";"1" +"Rynore";"wardrobe2";"Banded Mail";"1" +"Rynore";"wardrobe2";"Plate Leggings";"1" +"Rynore";"wardrobe2";"Velvet Robe";"1" +"Rynore";"wardrobe2";"Espial Hose";"1" +"Rynore";"wardrobe2";"Espial Socks";"1" +"Rynore";"wardrobe2";"Socks";"1" +"Rynore";"wardrobe2";"Gothic Gauntlets";"1" +"Rynore";"wardrobe2";"Padded Cap";"1" +"Rynore";"wardrobe2";"Pyro Robe";"1" +"Rynore";"wardrobe2";"Espial Gambison";"1" +"Rynore";"wardrobe2";"Bracers";"1" +"Rynore";"wardrobe2";"Garish Mitts";"1" +"Rynore";"wardrobe2";"Cuir Bandana";"1" +"Rynore";"wardrobe2";"Ebony Sabots";"1" +"Rynore";"wardrobe2";"Brigandine";"1" +"Rynore";"wardrobe2";"Crow Bracers";"1" +"Rynore";"wardrobe2";"Cpc. Leggings";"1" +"Rynore";"wardrobe2";"Leggings";"1" +"Rynore";"wardrobe2";"Velvet Slops";"1" +"Rynore";"wardrobe3";"Deathbringer";"1" +"Rynore";"wardrobe3";"Hagoita";"1" +"Rynore";"wardrobe3";"Holy Mace";"1" +"Rynore";"wardrobe3";"Custodes";"1" +"Rynore";"wardrobe3";"Bomb Arm";"3" +"Rynore";"wardrobe3";"Brass Rod";"1" +"Rynore";"wardrobe3";"Kite Shield";"1" +"Rynore";"wardrobe3";"Spear";"1" +"Rynore";"wardrobe3";"Lilith's Rod";"1" +"Rynore";"wardrobe3";"Willow Wand";"1" +"Rynore";"wardrobe3";"Hoplon";"1" +"Rynore";"wardrobe3";"Em. Baghnakhs";"1" +"Rynore";"wardrobe3";"Yew Wand";"1" +"Rynore";"wardrobe3";"Bronze Axe";"1" +"Rynore";"wardrobe3";"Maple Shield";"1" +"Rynore";"wardrobe3";"Flame Boomerang";"1" +"Rynore";"wardrobe3";"Bronze Knife";"1" +"Rynore";"wardrobe3";"Ceres' Spica";"1" +"Rynore";"wardrobe3";"Flame Degen";"1" +"Rynore";"wardrobe3";"Katayama";"1" +"Rynore";"wardrobe3";"Power Crossbow";"1" +"Rynore";"wardrobe3";"Brass Xiphos";"1" +"Rynore";"wardrobe3";"Nymph Shield";"1" +"Rynore";"wardrobe3";"Rose Wand";"1" +"Rynore";"wardrobe3";"Misery Staff";"1" +"Rynore";"wardrobe3";"Shortbow";"1" +"Rynore";"wardrobe3";"Floral Hagoita";"1" +"Rynore";"wardrobe3";"Broadsword";"1" +"Rynore";"wardrobe3";"Pebble";"13" +"Rynore";"wardrobe3";"Maul";"1" +"Rynore";"wardrobe3";"Ebony Wand";"1" +"Rynore";"wardrobe3";"Spellcaster's Ecu";"1" +"Rynore";"wardrobe3";"Wrapped Bow";"1" +"Rynore";"wardrobe3";"Eyra Baghnakhs";"1" +"Rynore";"wardrobe3";"Shell Shield";"1" +"Rynore";"wardrobe3";"Hard Shield";"1" +"Rynore";"wardrobe3";"Mahogany Shield";"1" +"Rynore";"wardrobe3";"Hunting Sword";"1" +"Rynore";"wardrobe3";"Slime Shield";"1" +"Rynore";"wardrobe3";"Stone Arrow";"450" +"Rynore";"wardrobe3";"Firefly";"1" +"Rynore";"wardrobe3";"Bone Arrow";"1" +"Rynore";"wardrobe3";"Holly Pole";"1" +"Rynore";"wardrobe3";"Targe";"1" +"Rynore";"wardrobe3";"She-Slime Shield";"1" +"Rynore";"wardrobe3";"Fish Scale Shield";"1" +"Rynore";"wardrobe3";"Holy Maul";"1" +"Rynore";"wardrobe3";"Elm Staff";"1" +"Rynore";"wardrobe3";"Oak Pole";"1" +"Rynore";"wardrobe3";"Leather Shield";"1" +"Rynore";"wardrobe3";"Bone Knife";"1" +"Rynore";"wardrobe3";"Flame Blade";"1" +"Rynore";"wardrobe3";"Composite Bow";"1" +"Rynore";"wardrobe3";"San d'Orian Bow";"1" +"Rynore";"wardrobe3";"Small Sword";"1" +"Rynore";"wardrobe3";"Othinus' Bow";"1" +"Rynore";"wardrobe3";"Metal Slime Shield";"1" +"Rynore";"wardrobe3";"Janus Guard";"1" +"Rynore";"wardrobe3";"Kukri";"1" +"Rynore";"wardrobe3";"Bronze Bolt";"190" +"Rynore";"wardrobe3";"Battleaxe";"1" +"Rynore";"wardrobe3";"Beetle Knife";"1" +"Rynore";"wardrobe3";"Aspir Knife";"2" +"Rynore";"wardrobe3";"Light Crossbow";"1" +"Rynore";"wardrobe3";"Lohar";"1" +"Rynore";"wardrobe3";"Gladius";"1" +"Rynore";"wardrobe3";"Spatha";"1" +"Rynore";"wardrobe3";"Mammut";"1" +"Rynore";"wardrobe4";"Brass Ring";"1" +"Rynore";"wardrobe4";"Gyokuto Obi";"1" +"Rynore";"wardrobe4";"Corsette";"1" +"Rynore";"wardrobe4";"Sardonyx Ring";"1" +"Rynore";"wardrobe4";"Desperado Ring";"1" +"Rynore";"wardrobe4";"Grand T.K. Collar";"1" +"Rynore";"wardrobe4";"Brocade Obi";"1" +"Rynore";"wardrobe4";"Ryl. Army Mantle";"1" +"Rynore";"wardrobe4";"Silver Ring";"1" +"Rynore";"wardrobe4";"High Brth. Mantle";"1" +"Rynore";"wardrobe4";"Green Earring";"1" +"Rynore";"wardrobe4";"Qiqirn Sash";"1" +"Rynore";"wardrobe4";"Lleu's Charm";"1" +"Rynore";"wardrobe4";"Torque";"1" +"Rynore";"wardrobe4";"Beast Whistle";"1" +"Rynore";"wardrobe4";"Tiger Stole";"1" +"Rynore";"wardrobe4";"Rabbit Mantle";"1" +"Rynore";"wardrobe4";"Arete del Sol";"1" +"Rynore";"wardrobe4";"Tourmaline Ring";"1" +"Rynore";"wardrobe4";"Vehemence Ring";"1" +"Rynore";"wardrobe4";"Warp Ring";"1" +"Rynore";"wardrobe4";"Sardonyx Earring";"1" +"Rynore";"wardrobe4";"Peiste Mantle";"1" +"Rynore";"wardrobe4";"Rancorous Mantle";"1" +"Rynore";"wardrobe4";"M. Slime Earring";"1" +"Rynore";"wardrobe4";"Swordbelt";"1" +"Rynore";"wardrobe4";"Protect Earring";"1" +"Rynore";"wardrobe4";"Dhalmel Mantle";"1" +"Rynore";"wardrobe4";"Hard Leather Ring";"1" +"Rynore";"wardrobe4";"Little Worm Belt";"1" +"Rynore";"wardrobe4";"Clear Ring";"1" +"Rynore";"wardrobe4";"Gold Earring";"1" +"Rynore";"wardrobe4";"Sun Earring";"1" +"Rynore";"wardrobe4";"Leather Ring";"1" +"Rynore";"wardrobe4";"Beak Necklace";"1" +"Rynore";"wardrobe4";"Ranger's Necklace";"1" +"Rynore";"wardrobe4";"Bushinomimi";"1" +"Rynore";"wardrobe4";"Invisible Mantle";"1" +"Rynore";"wardrobe4";"Chocobo Rope";"1" +"Rynore";"wardrobe4";"Flower Necklace";"1" +"Rynore";"wardrobe4";"Amethyst Earring";"1" +"Rynore";"wardrobe4";"Friar's Rope";"1" +"Rynore";"wardrobe4";"Justice Badge";"1" +"Rynore";"wardrobe4";"Opo-opo Necklace";"1" +"Rynore";"wardrobe4";"Flagellant's Rope";"1" +"Rynore";"wardrobe4";"Black Cape";"1" +"Rynore";"wardrobe4";"Tortoise Earring";"1" +"Rynore";"wardrobe4";"Pinwheel Belt";"1" +"Rynore";"wardrobe4";"Nexus Cape";"1" +"Rynore";"wardrobe4";"Mythril Earring";"1" +"Rynore";"wardrobe4";"Cape";"1" +"Rynore";"wardrobe4";"Coral Gorget";"1" +"Rynore";"wardrobe4";"Purple Earring";"1" +"Rynore";"wardrobe4";"Physical Earring";"1" +"Rynore";"wardrobe4";"Peiste Belt";"1" +"Rynore";"wardrobe4";"Mohbwa Scarf";"1" +"Rynore";"wardrobe4";"Hi-Potion Tank";"1" +"Rynore";"wardrobe4";"She-Slime Earring";"1" +"Rynore";"wardrobe4";"Twinthread Obi";"1" +"Rynore";"wardrobe4";"Jester's Cape";"1" +"Rynore";"wardrobe4";"Pile Chain";"1" +"Rynore";"wardrobe4";"Amber Ring";"1" +"Rynore";"wardrobe4";"Gaia Mantle";"1" +"Rynore";"wardrobe4";"Rainbow Obi";"1" +"Rynore";"wardrobe4";"White Belt";"1" +"Rynore";"wardrobe4";"Tenax Strap";"1" +"Rynore";"wardrobe4";"Medieval Collar";"1" +"Rynore";"wardrobe4";"Hi-Ether Tank";"1" +"Rynore";"wardrobe4";"Cotton Cape";"1" +"Rynore";"wardrobe4";"Homing Ring";"1" +"Rynore";"wardrobe4";"Slime Earring";"1" +"Rynore";"wardrobe4";"Wing Pendant";"1" +"Rynore";"wardrobe4";"Accura Cape";"1" +"Rynore";"wardrobe4";"Focus Collar";"1" +"Rynore";"wardrobe4";"Blind Ring";"1" +"Rynore";"wardrobe4";"Opal Ring";"1" +"Rynore";"wardrobe4";"Echad Ring";"1" +"Rynore";"wardrobe4";"Aquamrne. Earring";"1" +"Rynore";"wardrobe4";"Opal Earring";"1" +"Rynore";"wardrobe4";"Mythril Ring";"1" +"Rynore";"wardrobe5";"Dwarf Pugil";"1" +"Rynore";"wardrobe5";"Drill Calamary";"2" +"Rynore";"wardrobe5";"Pet Food Beta";"12" +"Rynore";"wardrobe5";"Svg. Mole Broth";"1" +"Rynore";"wardrobe5";"Clothespole";"1" +"Rynore";"wardrobe5";"Carrot Broth";"10" +"Rynore";"wardrobe5";"Carrion Broth";"1" +"Rynore";"wardrobe5";"Yew Fishing Rod";"1" +"Rynore";"wardrobe5";"S. Herbal Broth";"5" +"Rynore";"wardrobe5";"Bamboo Fish. Rod";"1" +"Rynore";"wardrobe5";"Sliced Sardine";"90" +"Rynore";"wardrobe5";"Wormy Broth";"4" +"Rynore";"wardrobe5";"Crayfish Ball";"10" +"Rynore";"wardrobe5";"Peeled Crayfish";"6" +"Rynore";"wardrobe6";"Analgesia Torque";"1" +"Rynore";"wardrobe6";"Esse Earring";"1" +"Rynore";"wardrobe6";"Metamorph Ring";"1" +"Rynore";"key items";"job gesture: black mage";"1" +"Rynore";"key items";"crimson orb";"1" +"Rynore";"key items";"map of Pso'Xja";"1" +"Rynore";"key items";"Ancient Melody: O";"1" +"Rynore";"key items";"Holla gate crystal";"1" +"Rynore";"key items";"cerulean crystal";"1" +"Rynore";"key items";"story of an impatient chocobo";"1" +"Rynore";"key items";"ring of supernal disjunction";"1" +"Rynore";"key items";"♪Doll companion";"1" +"Rynore";"key items";"Delkfutt key";"1" +"Rynore";"key items";"clear abyssite";"1" +"Rynore";"key items";"Mog Patio design document";"1" +"Rynore";"key items";"Mea gate crystal";"1" +"Rynore";"key items";"Windurst Trust permit";"1" +"Rynore";"key items";"Shard of Rage";"1" +"Rynore";"key items";"green invitation card";"1" +"Rynore";"key items";"scroll of treasure";"1" +"Rynore";"key items";"map of Bibiki Bay";"1" +"Rynore";"key items";"Vahzl gate crystal";"1" +"Rynore";"key items";"Shard of Apathy";"1" +"Rynore";"key items";"job gesture: dark knight";"1" +"Rynore";"key items";"map of Ru'Hmet";"1" +"Rynore";"key items";"story of a diligent chocobo";"1" +"Rynore";"key items";"map of the Boyahda Tree";"1" +"Rynore";"key items";"map of Cape Riverne";"1" +"Rynore";"key items";"♪Raptor companion";"1" +"Rynore";"key items";"map of the Kuftal Tunnel";"1" +"Rynore";"key items";"Moghancement: Gardening";"1" +"Rynore";"key items";"job gesture: red mage";"1" +"Rynore";"key items";"map of Tavnazia";"1" +"Rynore";"key items";"map of Carpenters' Landing";"1" +"Rynore";"key items";"job gesture: paladin";"1" +"Rynore";"key items";"job gesture: summoner";"1" +"Rynore";"key items";"Magian learner's log";"1" +"Rynore";"key items";"♪Buffalo companion";"1" +"Rynore";"key items";"map of the Elshimo regions";"1" +"Rynore";"key items";"prospector's pan";"1" +"Rynore";"key items";"map of the Toraimarai Canal";"1" +"Rynore";"key items";"Adventurer's Certificate";"1" +"Rynore";"key items";"map of Bhaflau Thickets";"1" +"Rynore";"key items";""Adoulin's Topiary Treasures"";"1" +"Rynore";"key items";"Angelica's autograph";"1" +"Rynore";"key items";"map of the Horutoto Ruins";"1" +"Rynore";"key items";"map of Halvung";"1" +"Rynore";"key items";"map of Ordelle's Caves";"1" +"Rynore";"key items";"map of Oldton Movalpolos";"1" +"Rynore";"key items";"map of Temple of Uggalepih";"1" +"Rynore";"key items";"map of the Gusgen Mines";"1" +"Rynore";"key items";"airship pass";"1" +"Rynore";"key items";""A Farewell to Freshwater"";"1" +"Rynore";"key items";"map of Delkfutt's Tower";"1" +"Rynore";"key items";"Ambuscade Primer Volume Two";"1" +"Rynore";"key items";"map of Wajaom Woodlands";"1" +"Rynore";"key items";"map of Mamook";"1" +"Rynore";"key items";"map of Ve'Lugannon Palace";"1" +"Rynore";"key items";"traverser stone";"1" +"Rynore";"key items";"map of the Vollbow region";"1" +"Rynore";"key items";"map of the Garlaige Citadel";"1" +"Rynore";"key items";"map of Sea Serpent Grotto";"1" +"Rynore";"key items";"blue invitation card";"1" +"Rynore";"key items";"map of Qufim Island";"1" +"Rynore";"key items";"map of Al'Taieu";"1" +"Rynore";"key items";"map of the Crawlers' Nest";"1" +"Rynore";"key items";"geomagnetron";"1" +"Rynore";"key items";"tuning fork of fire";"1" +"Rynore";"key items";"map of Castle Oztroja";"1" +"Rynore";"key items";"map of Labyrinth of Onzozo";"1" +"Rynore";"key items";"synergy crucible";"1" +"Rynore";"key items";"job gesture: beastmaster";"1" +"Rynore";"key items";"map of the Dangruf Wadi";"1" +"Rynore";"key items";"job gesture: monk";"1" +"Rynore";"key items";"black matinee necklace";"1" +"Rynore";"key items";"prototype attuner";"1" +"Rynore";"key items";"Ballista License";"1" +"Rynore";"key items";"map of Castle Zvahl";"1" +"Rynore";"key items";"GPS crystal";"1" +"Rynore";"key items";"seal of banishing";"1" +"Rynore";"key items";"map of the Maze of Shakhrami";"1" +"Rynore";"key items";"map of Fei'Yin";"1" +"Rynore";"key items";"trainer's whistle";"1" +"Rynore";"key items";"map of Bostaunieux Oubliette";"1" +"Rynore";"key items";"lamb memento";"1" +"Rynore";"key items";"vial of shrouded sand";"1" +"Rynore";"key items";"♪Byakko";"1" +"Rynore";"key items";"map of King Ranperre's Tomb";"1" +"Rynore";"key items";"map of the Den of Rancor";"1" +"Rynore";"key items";"♪Iron Giant companion";"1" +"Rynore";"key items";"Tenshodo Member's Card";"1" +"Rynore";"key items";"map of the Kuzotz region";"1" +"Rynore";"key items";"♪Red crab companion";"1" +"Rynore";"key items";"deed to Purgonorgo Isle";"1" +"Rynore";"key items";""Grandiloquent Groves"";"1" +"Rynore";"key items";"map of the Ranguemont Pass";"1" +"Rynore";"key items";"shimmering invitation";"1" +"Rynore";"key items";""Susuroon's Biiig Catch"";"1" +"Rynore";"key items";"map of Vunkerl Inlet";"1" +"Rynore";"key items";"map of Beadeaux";"1" +"Rynore";"key items";"archducal audience permit";"1" +"Rynore";"key items";""Rhapsody in White"";"1" +"Rynore";"key items";""My First Furrow"";"1" +"Rynore";"key items";"Reisenjima Sanctorium orb";"1" +"Rynore";"key items";"map of the Attohwa Chasm";"1" +"Rynore";"key items";"prismatic fragment";"1" +"Rynore";"key items";"map of the Palborough Mines";"1" +"Rynore";"key items";"concordoll";"1" +"Rynore";"key items";"limit breaker";"1" +"Rynore";"key items";"map of the Zeruhn Mines";"1" +"Rynore";"key items";"white handkerchief";"1" +"Rynore";"key items";"San d'Oria Trust permit";"1" +"Rynore";"key items";"map of Giddeus";"1" +"Rynore";"key items";"map of Newton Movalpolos";"1" +"Rynore";"key items";"memorandoll";"1" +"Rynore";"key items";"map of the Quicksand Caves";"1" +"Rynore";"key items";"crab caller";"1" +"Rynore";"key items";"gil repository";"1" +"Rynore";"key items";""20,000 Yalms Under the Sea"";"1" +"Rynore";"key items";"map of the Jeuno area";"1" +"Rynore";"key items";"map of the Eldieme Necropolis";"1" +"Rynore";"key items";"map of Grauberg";"1" +"Rynore";"key items";"map of Ifrit's Cauldron";"1" +"Rynore";"key items";""The Old Men of the Sea"";"1" +"Rynore";"key items";"timber survey checklist";"1" +"Rynore";"key items";"♪Phuabo companion";"1" +"Rynore";"key items";"Shard of Arrogance";"1" +"Rynore";"key items";"Yhoator gate crystal";"1" +"Rynore";"key items";"treasure map";"1" +"Rynore";"key items";""Dredging's No Drudgery"";"1" +"Rynore";"key items";""Varicose Mineral Veins"";"1" +"Rynore";"key items";""Water, Water Everywhere!"";"1" +"Rynore";"key items";""Take A Lode Off"";"1" +"Rynore";"key items";""Mythril Marathon Quarterly"";"1" +"Rynore";"key items";"Altepa gate crystal";"1" +"Rynore";"key items";"Shard of Cowardice";"1" +"Rynore";"key items";""Give My Regards to Reodoan"";"1" +"Rynore";"key items";""Sow★Your★Seed!"";"1" +"Rynore";"key items";"Dem gate crystal";"1" +"Rynore";"key items";"traverser stone";"1" +"Rynore";"key items";"map of the Aqueducts";"1" +"Rynore";"key items";"loadstone";"1" +"Rynore";"key items";"map of Nashmau";"1" +"Rynore";"key items";"mysterious amulet";"1" +"Rynore";"key items";"map of Fort Karugo-Narugo";"1" +"Rynore";"key items";"map of Aydeewa Subterrane";"1" +"Rynore";"key items";""Black Fish of the Family"";"1" +"Rynore";"key items";"map of Alzadaal Ruins";"1" +"Rynore";"key items";"map of Arrapago Reef";"1" +"Rynore";"key items";"map of Mount Zhayolm";"1" +"Rynore";"key items";"map of Caedarva Mire";"1" +"Rynore";"key items";"spirit incense";"1" +"Rynore";"key items";"piece of rugged tree bark";"1" +"Rynore";"key items";""All the Ways to Skin a Carp"";"1" +"Rynore";"key items";"Shard of Envy";"1" +"Rynore";"key items";"crest of Davoi";"1" +"Rynore";"key items";"silver bell";"1" +"Rynore";"key items";"pouch of weighted stones";"1" +"Rynore";"key items";"map of the Li'Telor region";"1" +"Rynore";"key items";"job gesture: ranger";"1" +"Rynore";"key items";"squire certificate";"1" +"Rynore";"key items";"traverser stone";"1" +"Rynore";"key items";"job gesture: thief";"1" +"Rynore";"key items";"job gesture: white mage";"1" +"Rynore";"key items";"chocobo license";"1" +"Rynore";"key items";"map of the Sacrarium";"1" +"Rynore";"key items";"magicked astrolabe";"1" +"Rynore";"key items";"coruscant rosary";"1" +"Rynore";"key items";"baby rabbit memento";"1" +"Rynore";"key items";"rabbit memento";"1" +"Rynore";"key items";"map of Al Zahbi";"1" +"Rynore";"key items";"map of the Windurst area";"1" +"Rynore";"key items";"job gesture: warrior";"1" +"Rynore";"key items";"map of the Uleguerand Range";"1" +"Rynore";"key items";"map of Norg";"1" +"Rynore";"key items";"red invitation card";"1" +"Rynore";"key items";"white invitation card";"1" +"Rynore";"key items";"♪Warmachine companion";"1" +"Rynore";"key items";"map of the Ru'Aun Gardens";"1" +"Rynore";"key items";"map of the Northlands area";"1" +"Rynore";"key items";"corked ampoule";"1" +"Rynore";"key items";"map of Davoi";"1" +"Rynore";"key items";"map of Hu'Xzoi";"1" +"Rynore";"key items";"heart of the bushin";"1" +"Rynore";"key items";"Bastok Trust permit";"1" +"Rynore";"key items";"map of Ghelsba";"1" +"Rynore";"key items";"Yagudo torch";"1" +"Rynore";"key items";"map of the Korroloka Tunnel";"1" +"Rynore";"key items";"map of the San d'Oria area";"1" +"Rynore";"key items";"map of the Bastok area";"1" diff --git a/docker-compose.yml b/docker-compose.yml index 97b0e54..1ccb02f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,16 +1,33 @@ +version: "3.9" + services: api: build: ./backend + container_name: mogapp-api environment: - - PSQL_HOST=10.0.0.199 - - PSQL_PORT=5432 - - PSQL_USER=postgres - - PSQL_PASSWORD=DP3Wv*QM#t8bY*N - - PSQL_DBNAME=ffxi_items + # Database lives on the Docker host, expose via host networking + - PSQL_HOST=${PSQL_HOST:-host.docker.internal} + - PSQL_PORT=${PSQL_PORT:-5432} + - PSQL_USER=${PSQL_USER:-postgres} + - PSQL_PASSWORD=${PSQL_PASSWORD:-postgres} + - PSQL_DBNAME=${PSQL_DBNAME:-ffxi_items} ports: - "8000:8000" volumes: - ./backend/app:/app/app + networks: + - mognet -volumes: - pgdata: + frontend: + build: ./frontend + container_name: mogapp-web + depends_on: + - api + ports: + - "3050:80" + networks: + - mognet + +networks: + mognet: + driver: bridge diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..711eb42 --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,16 @@ +# ---------- Build stage ---------- +FROM node:20-alpine AS builder +WORKDIR /app +COPY package.json package-lock.json* pnpm-lock.yaml* ./ +RUN npm ci --ignore-scripts --prefer-offline +COPY . . +RUN npm run build + +# ---------- Production stage ---------- +FROM nginx:1.25-alpine AS prod +COPY --from=builder /app/dist /usr/share/nginx/html +# Remove default config and add minimal one +RUN rm /etc/nginx/conf.d/default.conf +COPY nginx.conf /etc/nginx/conf.d +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] diff --git a/frontend/nginx.conf b/frontend/nginx.conf new file mode 100644 index 0000000..be98754 --- /dev/null +++ b/frontend/nginx.conf @@ -0,0 +1,22 @@ +server { + listen 80; + server_name _; + + # Serve static assets + root /usr/share/nginx/html; + index index.html; + + # Forward API requests to backend + location /api/ { + proxy_pass http://api:8000/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # All other routes – SPA fallback + location / { + try_files $uri $uri/ /index.html; + } +} diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ddd7b32..8ab8890 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -18,13 +18,24 @@ "react-dom": "^18.2.0" }, "devDependencies": { + "@testing-library/jest-dom": "^6.1.5", + "@testing-library/react": "^14.1.2", + "@testing-library/user-event": "^14.4.3", "@types/react": "^18.2.50", "@types/react-dom": "^18.2.17", "@vitejs/plugin-react": "^4.0.3", + "jsdom": "^23.0.0", "typescript": "^5.3.3", - "vite": "^5.2.0" + "vite": "^5.2.0", + "vitest": "^1.5.0" } }, + "node_modules/@adobe/css-tools": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.3.tgz", + "integrity": "sha512-VQKMkwriZbaOgVCby1UDY/LDk5fIjhQicCvVPFqfe+69fWaPWydbWJ3wRt59/YzIwda1I81loas3oCoHxnqvdA==", + "dev": true + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -38,6 +49,36 @@ "node": ">=6.0.0" } }, + "node_modules/@asamuzakjp/css-color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", + "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "dev": true, + "dependencies": { + "@csstools/css-calc": "^2.1.3", + "@csstools/css-color-parser": "^3.0.9", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-2.0.2.tgz", + "integrity": "sha512-x1KXOatwofR6ZAYzXRBL5wrdV0vwNxlTCK9NCuLqAzQYARqGcvFwiJA6A1ERuh+dgeA4Dxm3JBYictIes+SqUQ==", + "dev": true, + "dependencies": { + "bidi-js": "^1.0.3", + "css-tree": "^2.3.1", + "is-potential-custom-element-name": "^1.0.1" + } + }, "node_modules/@babel/code-frame": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", @@ -297,6 +338,116 @@ "node": ">=6.9.0" } }, + "node_modules/@csstools/color-helpers": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", + "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.10.tgz", + "integrity": "sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/color-helpers": "^5.0.2", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@emotion/babel-plugin": { "version": "11.13.5", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", @@ -798,6 +949,18 @@ "node": ">=12" } }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.12", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", @@ -1320,6 +1483,12 @@ "win32" ] }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, "node_modules/@tanstack/query-core": { "version": "5.81.5", "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.81.5.tgz", @@ -1344,6 +1513,130 @@ "react": "^18 || ^19" } }, + "node_modules/@testing-library/dom": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz", + "integrity": "sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==", + "dev": true, + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true + }, + "node_modules/@testing-library/react": { + "version": "14.3.1", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.3.1.tgz", + "integrity": "sha512-H99XjUhWQw0lTgyMN05W3xQG1Nh4lq574D8keFf1dDoNTJgp66VbJozRaczoF+wsiaPJNt/TcnfpLGufGxSrZQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^9.0.0", + "@types/react-dom": "^18.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@testing-library/react/node_modules/@testing-library/dom": { + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", + "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@testing-library/react/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/@testing-library/user-event": { + "version": "14.6.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", + "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "dev": true, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -1447,11 +1740,250 @@ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" } }, + "node_modules/@vitest/expect": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.1.tgz", + "integrity": "sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==", + "dev": true, + "dependencies": { + "@vitest/spy": "1.6.1", + "@vitest/utils": "1.6.1", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.1.tgz", + "integrity": "sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==", + "dev": true, + "dependencies": { + "@vitest/utils": "1.6.1", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.1.tgz", + "integrity": "sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==", + "dev": true, + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@vitest/snapshot/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@vitest/snapshot/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/@vitest/spy": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.1.tgz", + "integrity": "sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==", + "dev": true, + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.1.tgz", + "integrity": "sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@vitest/utils/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@vitest/utils/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/axios": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", @@ -1476,6 +2008,15 @@ "npm": ">=6" } }, + "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==", + "dev": true, + "dependencies": { + "require-from-string": "^2.0.2" + } + }, "node_modules/browserslist": { "version": "4.25.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", @@ -1508,6 +2049,33 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -1520,6 +2088,22 @@ "node": ">= 0.4" } }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1548,6 +2132,52 @@ } ] }, + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -1556,6 +2186,24 @@ "node": ">=6" } }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1567,6 +2215,12 @@ "node": ">= 0.8" } }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true + }, "node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", @@ -1587,11 +2241,76 @@ "node": ">=10" } }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "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.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", + "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", + "dev": true, + "dependencies": { + "@asamuzakjp/css-color": "^3.2.0", + "rrweb-cssom": "^0.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cssstyle/node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "dev": true + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/debug": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", @@ -1608,6 +2327,90 @@ } } }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1616,6 +2419,30 @@ "node": ">=0.4.0" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true + }, "node_modules/dom-helpers": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", @@ -1644,6 +2471,18 @@ "integrity": "sha512-wObbz/ar3Bc6e4X5vf0iO8xTN8YAjN/tgiAOJLr7yjYFtP9wAjq8Mb5h0yn6kResir+VYx2DXBj9NNobs0ETSA==", "dev": true }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -1668,6 +2507,26 @@ "node": ">= 0.4" } }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", @@ -1751,6 +2610,38 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, "node_modules/find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -1775,6 +2666,21 @@ } } }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/form-data": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", @@ -1812,6 +2718,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -1821,6 +2736,15 @@ "node": ">=6.9.0" } }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -1856,6 +2780,18 @@ "node": ">= 0.4" } }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -1875,6 +2811,39 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -1924,6 +2893,65 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -1939,11 +2967,110 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-core-module": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", @@ -1958,11 +3085,231 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, + "node_modules/jsdom": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.2.0.tgz", + "integrity": "sha512-L88oL7D/8ufIES+Zjz7v0aes+oBMh2Xnh3ygWvL0OaICOomKEPKuPnIfBJekiXr+BHbbMjrWn/xqrDQuxFTeyA==", + "dev": true, + "dependencies": { + "@asamuzakjp/dom-selector": "^2.0.1", + "cssstyle": "^4.0.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.3", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.16.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^2.11.2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -1996,6 +3343,28 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/local-pkg": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz", + "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==", + "dev": true, + "dependencies": { + "mlly": "^1.7.3", + "pkg-types": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -2007,6 +3376,15 @@ "loose-envify": "cli.js" } }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -2016,6 +3394,24 @@ "yallist": "^3.0.2" } }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -2024,6 +3420,18 @@ "node": ">= 0.4" } }, + "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/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -2043,6 +3451,45 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mlly": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", + "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", + "dev": true, + "dependencies": { + "acorn": "^8.14.0", + "pathe": "^2.0.1", + "pkg-types": "^1.3.0", + "ufo": "^1.5.4" + } + }, + "node_modules/mlly/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2072,6 +3519,33 @@ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -2080,6 +3554,93 @@ "node": ">=0.10.0" } }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -2108,6 +3669,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -2121,11 +3703,52 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/pkg-types/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -2154,6 +3777,38 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -2174,6 +3829,33 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "dev": true, + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -2226,6 +3908,54 @@ "react-dom": ">=16.6.0" } }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -2292,6 +4022,47 @@ "fsevents": "~2.3.2" } }, + "node_modules/rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", @@ -2309,6 +4080,149 @@ "semver": "bin/semver.js" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -2326,11 +4240,90 @@ "node": ">=0.10.0" } }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true + }, + "node_modules/std-env": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", + "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", + "dev": true + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-literal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.1.tgz", + "integrity": "sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==", + "dev": true, + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true + }, "node_modules/stylis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -2342,6 +4335,72 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true + }, + "node_modules/tinypool": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", + "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "dev": true, + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/typescript": { "version": "5.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", @@ -2355,6 +4414,21 @@ "node": ">=14.17" } }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "dev": true + }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", @@ -2385,6 +4459,16 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/vite": { "version": "5.4.19", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz", @@ -2444,6 +4528,273 @@ } } }, + "node_modules/vite-node": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.1.tgz", + "integrity": "sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==", + "dev": true, + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.1.tgz", + "integrity": "sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==", + "dev": true, + "dependencies": { + "@vitest/expect": "1.6.1", + "@vitest/runner": "1.6.1", + "@vitest/snapshot": "1.6.1", + "@vitest/spy": "1.6.1", + "@vitest/utils": "1.6.1", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.3", + "vite": "^5.0.0", + "vite-node": "1.6.1", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.6.1", + "@vitest/ui": "1.6.1", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "dev": true, + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -2457,6 +4808,18 @@ "engines": { "node": ">= 6" } + }, + "node_modules/yocto-queue": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz", + "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/frontend/package.json b/frontend/package.json index 1af3c1b..4f61048 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "scripts": { + "test": "vitest", "dev": "vite", "build": "vite build", "preview": "vite preview" @@ -18,6 +19,11 @@ "react-dom": "^18.2.0" }, "devDependencies": { + "vitest": "^1.5.0", + "@testing-library/react": "^14.1.2", + "@testing-library/jest-dom": "^6.1.5", + "@testing-library/user-event": "^14.4.3", + "jsdom": "^23.0.0", "@types/react": "^18.2.50", "@types/react-dom": "^18.2.17", "typescript": "^5.3.3", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index b8decaf..178900d 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -9,9 +9,15 @@ import InventoryPage from "./pages/Inventory"; import ItemExplorerPage from "./pages/ItemExplorer"; import RecipesPage from "./pages/Recipes"; import Footer from "./components/Footer"; +import { inventoryColor, explorerColor, recipesColor } from "./constants/colors"; +import MobileNav from "./components/MobileNav"; +import useMediaQuery from "@mui/material/useMediaQuery"; +import { useTheme } from "@mui/material/styles"; export default function App() { const [page, setPage] = useState(0); + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down('sm')); const { data: metadata } = useQuery({ queryKey: ["metadata"], @@ -29,8 +35,9 @@ export default function App() { MOG SQUIRE - {(() => { - const tabColors = ['#66bb6a', '#42a5f5', '#ffa726']; + {!isMobile && (() => { + const tabColors = [inventoryColor, explorerColor, recipesColor]; + const tabLabels = ['Inventory','Item Explorer','Recipes']; return ( - {['Inventory','Item Explorer','Recipes'].map((label, idx) => ( - + {tabLabels.map((label, idx) => ( + ))} ); })()} - {page === 0 && metadata && ( + {/* Main content */} + {/* bottom padding for nav */} + {page === 0 && metadata && ( )} {page === 1 && metadata && ( @@ -58,7 +68,9 @@ export default function App() { )} -