diff --git a/invokeai/app/api/dependencies.py b/invokeai/app/api/dependencies.py index 1cd2093ec9..d2be674e53 100644 --- a/invokeai/app/api/dependencies.py +++ b/invokeai/app/api/dependencies.py @@ -32,6 +32,8 @@ from invokeai.app.services.session_processor.session_processor_default import ( ) from invokeai.app.services.session_queue.session_queue_sqlite import SqliteSessionQueue from invokeai.app.services.shared.sqlite.sqlite_util import init_db +from invokeai.app.services.style_preset_images.style_preset_images_disk import StylePresetImageFileStorageDisk +from invokeai.app.services.style_preset_records.style_preset_records_sqlite import SqliteStylePresetRecordsStorage from invokeai.app.services.urls.urls_default import LocalUrlService from invokeai.app.services.workflow_records.workflow_records_sqlite import SqliteWorkflowRecordsStorage from invokeai.backend.stable_diffusion.diffusion.conditioning_data import ConditioningFieldData @@ -80,6 +82,7 @@ class ApiDependencies: image_files = DiskImageFileStorage(f"{output_folder}/images") model_images_folder = config.models_path + style_presets_folder = config.style_presets_path db = init_db(config=config, logger=logger, image_files=image_files) @@ -115,6 +118,8 @@ class ApiDependencies: session_queue = SqliteSessionQueue(db=db) urls = LocalUrlService() workflow_records = SqliteWorkflowRecordsStorage(db=db) + style_preset_records = SqliteStylePresetRecordsStorage(db=db) + style_preset_image_files = StylePresetImageFileStorageDisk(style_presets_folder / "images") services = InvocationServices( board_image_records=board_image_records, @@ -140,6 +145,8 @@ class ApiDependencies: workflow_records=workflow_records, tensors=tensors, conditioning=conditioning, + style_preset_records=style_preset_records, + style_preset_image_files=style_preset_image_files, ) ApiDependencies.invoker = Invoker(services) diff --git a/invokeai/app/api/routers/style_presets.py b/invokeai/app/api/routers/style_presets.py new file mode 100644 index 0000000000..786c522c20 --- /dev/null +++ b/invokeai/app/api/routers/style_presets.py @@ -0,0 +1,227 @@ +import io +import json +import traceback +from typing import Optional + +import pydantic +from fastapi import APIRouter, File, Form, HTTPException, Path, UploadFile +from fastapi.responses import FileResponse +from PIL import Image +from pydantic import BaseModel, Field + +from invokeai.app.api.dependencies import ApiDependencies +from invokeai.app.api.routers.model_manager import IMAGE_MAX_AGE +from invokeai.app.services.style_preset_images.style_preset_images_common import StylePresetImageFileNotFoundException +from invokeai.app.services.style_preset_records.style_preset_records_common import ( + PresetData, + PresetType, + StylePresetChanges, + StylePresetNotFoundError, + StylePresetRecordWithImage, + StylePresetWithoutId, +) + + +class StylePresetUpdateFormData(BaseModel): + name: str = Field(description="Preset name") + positive_prompt: str = Field(description="Positive prompt") + negative_prompt: str = Field(description="Negative prompt") + + +class StylePresetCreateFormData(StylePresetUpdateFormData): + type: PresetType = Field(description="Preset type") + + +style_presets_router = APIRouter(prefix="/v1/style_presets", tags=["style_presets"]) + + +@style_presets_router.get( + "/i/{style_preset_id}", + operation_id="get_style_preset", + responses={ + 200: {"model": StylePresetRecordWithImage}, + }, +) +async def get_style_preset( + style_preset_id: str = Path(description="The style preset to get"), +) -> StylePresetRecordWithImage: + """Gets a style preset""" + try: + image = ApiDependencies.invoker.services.style_preset_image_files.get_url(style_preset_id) + style_preset = ApiDependencies.invoker.services.style_preset_records.get(style_preset_id) + return StylePresetRecordWithImage(image=image, **style_preset.model_dump()) + except StylePresetNotFoundError: + raise HTTPException(status_code=404, detail="Style preset not found") + + +@style_presets_router.patch( + "/i/{style_preset_id}", + operation_id="update_style_preset", + responses={ + 200: {"model": StylePresetRecordWithImage}, + }, +) +async def update_style_preset( + image: Optional[UploadFile] = File(description="The image file to upload", default=None), + style_preset_id: str = Path(description="The id of the style preset to update"), + data: str = Form(description="The data of the style preset to update"), +) -> StylePresetRecordWithImage: + """Updates a style preset""" + if image is not None: + if not image.content_type or not image.content_type.startswith("image"): + raise HTTPException(status_code=415, detail="Not an image") + + contents = await image.read() + try: + pil_image = Image.open(io.BytesIO(contents)) + + except Exception: + ApiDependencies.invoker.services.logger.error(traceback.format_exc()) + raise HTTPException(status_code=415, detail="Failed to read image") + + try: + ApiDependencies.invoker.services.style_preset_image_files.save(style_preset_id, pil_image) + except ValueError as e: + raise HTTPException(status_code=409, detail=str(e)) + else: + try: + ApiDependencies.invoker.services.style_preset_image_files.delete(style_preset_id) + except StylePresetImageFileNotFoundException: + pass + + try: + parsed_data = json.loads(data) + validated_data = StylePresetUpdateFormData(**parsed_data) + + name = validated_data.name + positive_prompt = validated_data.positive_prompt + negative_prompt = validated_data.negative_prompt + + except pydantic.ValidationError: + raise HTTPException(status_code=400, detail="Invalid preset data") + + preset_data = PresetData(positive_prompt=positive_prompt, negative_prompt=negative_prompt) + changes = StylePresetChanges(name=name, preset_data=preset_data) + + style_preset_image = ApiDependencies.invoker.services.style_preset_image_files.get_url(style_preset_id) + style_preset = ApiDependencies.invoker.services.style_preset_records.update( + style_preset_id=style_preset_id, changes=changes + ) + return StylePresetRecordWithImage(image=style_preset_image, **style_preset.model_dump()) + + +@style_presets_router.delete( + "/i/{style_preset_id}", + operation_id="delete_style_preset", +) +async def delete_style_preset( + style_preset_id: str = Path(description="The style preset to delete"), +) -> None: + """Deletes a style preset""" + try: + ApiDependencies.invoker.services.style_preset_image_files.delete(style_preset_id) + except StylePresetImageFileNotFoundException: + pass + + ApiDependencies.invoker.services.style_preset_records.delete(style_preset_id) + + +@style_presets_router.post( + "/", + operation_id="create_style_preset", + responses={ + 200: {"model": StylePresetRecordWithImage}, + }, +) +async def create_style_preset( + image: Optional[UploadFile] = File(description="The image file to upload", default=None), + data: str = Form(description="The data of the style preset to create"), +) -> StylePresetRecordWithImage: + """Creates a style preset""" + + try: + parsed_data = json.loads(data) + validated_data = StylePresetCreateFormData(**parsed_data) + + name = validated_data.name + type = validated_data.type + positive_prompt = validated_data.positive_prompt + negative_prompt = validated_data.negative_prompt + + except pydantic.ValidationError: + raise HTTPException(status_code=400, detail="Invalid preset data") + + preset_data = PresetData(positive_prompt=positive_prompt, negative_prompt=negative_prompt) + style_preset = StylePresetWithoutId(name=name, preset_data=preset_data, type=type) + new_style_preset = ApiDependencies.invoker.services.style_preset_records.create(style_preset=style_preset) + + if image is not None: + if not image.content_type or not image.content_type.startswith("image"): + raise HTTPException(status_code=415, detail="Not an image") + + contents = await image.read() + try: + pil_image = Image.open(io.BytesIO(contents)) + + except Exception: + ApiDependencies.invoker.services.logger.error(traceback.format_exc()) + raise HTTPException(status_code=415, detail="Failed to read image") + + try: + ApiDependencies.invoker.services.style_preset_image_files.save(new_style_preset.id, pil_image) + except ValueError as e: + raise HTTPException(status_code=409, detail=str(e)) + + preset_image = ApiDependencies.invoker.services.style_preset_image_files.get_url(new_style_preset.id) + return StylePresetRecordWithImage(image=preset_image, **new_style_preset.model_dump()) + + +@style_presets_router.get( + "/", + operation_id="list_style_presets", + responses={ + 200: {"model": list[StylePresetRecordWithImage]}, + }, +) +async def list_style_presets() -> list[StylePresetRecordWithImage]: + """Gets a page of style presets""" + style_presets_with_image: list[StylePresetRecordWithImage] = [] + style_presets = ApiDependencies.invoker.services.style_preset_records.get_many() + for preset in style_presets: + image = ApiDependencies.invoker.services.style_preset_image_files.get_url(preset.id) + style_preset_with_image = StylePresetRecordWithImage(image=image, **preset.model_dump()) + style_presets_with_image.append(style_preset_with_image) + + return style_presets_with_image + + +@style_presets_router.get( + "/i/{style_preset_id}/image", + operation_id="get_style_preset_image", + responses={ + 200: { + "description": "The style preset image was fetched successfully", + }, + 400: {"description": "Bad request"}, + 404: {"description": "The style preset image could not be found"}, + }, + status_code=200, +) +async def get_style_preset_image( + style_preset_id: str = Path(description="The id of the style preset image to get"), +) -> FileResponse: + """Gets an image file that previews the model""" + + try: + path = ApiDependencies.invoker.services.style_preset_image_files.get_path(style_preset_id) + + response = FileResponse( + path, + media_type="image/png", + filename=style_preset_id + ".png", + content_disposition_type="inline", + ) + response.headers["Cache-Control"] = f"max-age={IMAGE_MAX_AGE}" + return response + except Exception: + raise HTTPException(status_code=404) diff --git a/invokeai/app/api_app.py b/invokeai/app/api_app.py index cabde15d52..ce61964246 100644 --- a/invokeai/app/api_app.py +++ b/invokeai/app/api_app.py @@ -30,6 +30,7 @@ from invokeai.app.api.routers import ( images, model_manager, session_queue, + style_presets, utilities, workflows, ) @@ -108,6 +109,7 @@ app.include_router(board_images.board_images_router, prefix="/api") app.include_router(app_info.app_router, prefix="/api") app.include_router(session_queue.session_queue_router, prefix="/api") app.include_router(workflows.workflows_router, prefix="/api") +app.include_router(style_presets.style_presets_router, prefix="/api") app.openapi = get_openapi_func(app) diff --git a/invokeai/app/services/config/config_default.py b/invokeai/app/services/config/config_default.py index 6c39760bdc..55f7a095ca 100644 --- a/invokeai/app/services/config/config_default.py +++ b/invokeai/app/services/config/config_default.py @@ -91,6 +91,7 @@ class InvokeAIAppConfig(BaseSettings): db_dir: Path to InvokeAI databases directory. outputs_dir: Path to directory for outputs. custom_nodes_dir: Path to directory for custom nodes. + style_presets_dir: Path to directory for style presets. log_handlers: Log handler. Valid options are "console", "file=", "syslog=path|address:host:port", "http=". log_format: Log format. Use "plain" for text-only, "color" for colorized output, "legacy" for 2.3-style logging and "syslog" for syslog-style.
Valid values: `plain`, `color`, `syslog`, `legacy` log_level: Emit logging messages at this level or higher.
Valid values: `debug`, `info`, `warning`, `error`, `critical` @@ -153,6 +154,7 @@ class InvokeAIAppConfig(BaseSettings): db_dir: Path = Field(default=Path("databases"), description="Path to InvokeAI databases directory.") outputs_dir: Path = Field(default=Path("outputs"), description="Path to directory for outputs.") custom_nodes_dir: Path = Field(default=Path("nodes"), description="Path to directory for custom nodes.") + style_presets_dir: Path = Field(default=Path("style_presets"), description="Path to directory for style presets.") # LOGGING log_handlers: list[str] = Field(default=["console"], description='Log handler. Valid options are "console", "file=", "syslog=path|address:host:port", "http=".') @@ -300,6 +302,11 @@ class InvokeAIAppConfig(BaseSettings): """Path to the models directory, resolved to an absolute path..""" return self._resolve(self.models_dir) + @property + def style_presets_path(self) -> Path: + """Path to the style presets directory, resolved to an absolute path..""" + return self._resolve(self.style_presets_dir) + @property def convert_cache_path(self) -> Path: """Path to the converted cache models directory, resolved to an absolute path..""" diff --git a/invokeai/app/services/invocation_services.py b/invokeai/app/services/invocation_services.py index 90ca613074..db693dc837 100644 --- a/invokeai/app/services/invocation_services.py +++ b/invokeai/app/services/invocation_services.py @@ -4,6 +4,8 @@ from __future__ import annotations from typing import TYPE_CHECKING from invokeai.app.services.object_serializer.object_serializer_base import ObjectSerializerBase +from invokeai.app.services.style_preset_images.style_preset_images_base import StylePresetImageFileStorageBase +from invokeai.app.services.style_preset_records.style_preset_records_base import StylePresetRecordsStorageBase if TYPE_CHECKING: from logging import Logger @@ -61,6 +63,8 @@ class InvocationServices: workflow_records: "WorkflowRecordsStorageBase", tensors: "ObjectSerializerBase[torch.Tensor]", conditioning: "ObjectSerializerBase[ConditioningFieldData]", + style_preset_records: "StylePresetRecordsStorageBase", + style_preset_image_files: "StylePresetImageFileStorageBase", ): self.board_images = board_images self.board_image_records = board_image_records @@ -85,3 +89,5 @@ class InvocationServices: self.workflow_records = workflow_records self.tensors = tensors self.conditioning = conditioning + self.style_preset_records = style_preset_records + self.style_preset_image_files = style_preset_image_files diff --git a/invokeai/app/services/shared/sqlite/sqlite_util.py b/invokeai/app/services/shared/sqlite/sqlite_util.py index 49fd337da2..e35c351ff0 100644 --- a/invokeai/app/services/shared/sqlite/sqlite_util.py +++ b/invokeai/app/services/shared/sqlite/sqlite_util.py @@ -16,6 +16,7 @@ from invokeai.app.services.shared.sqlite_migrator.migrations.migration_10 import from invokeai.app.services.shared.sqlite_migrator.migrations.migration_11 import build_migration_11 from invokeai.app.services.shared.sqlite_migrator.migrations.migration_12 import build_migration_12 from invokeai.app.services.shared.sqlite_migrator.migrations.migration_13 import build_migration_13 +from invokeai.app.services.shared.sqlite_migrator.migrations.migration_14 import build_migration_14 from invokeai.app.services.shared.sqlite_migrator.sqlite_migrator_impl import SqliteMigrator @@ -49,6 +50,7 @@ def init_db(config: InvokeAIAppConfig, logger: Logger, image_files: ImageFileSto migrator.register_migration(build_migration_11(app_config=config, logger=logger)) migrator.register_migration(build_migration_12(app_config=config)) migrator.register_migration(build_migration_13()) + migrator.register_migration(build_migration_14()) migrator.run_migrations() return db diff --git a/invokeai/app/services/shared/sqlite_migrator/migrations/migration_14.py b/invokeai/app/services/shared/sqlite_migrator/migrations/migration_14.py new file mode 100644 index 0000000000..399f5a71d2 --- /dev/null +++ b/invokeai/app/services/shared/sqlite_migrator/migrations/migration_14.py @@ -0,0 +1,61 @@ +import sqlite3 + +from invokeai.app.services.shared.sqlite_migrator.sqlite_migrator_common import Migration + + +class Migration14Callback: + def __call__(self, cursor: sqlite3.Cursor) -> None: + self._create_style_presets(cursor) + + def _create_style_presets(self, cursor: sqlite3.Cursor) -> None: + """Create the table used to store style presets.""" + tables = [ + """--sql + CREATE TABLE IF NOT EXISTS style_presets ( + id TEXT NOT NULL PRIMARY KEY, + name TEXT NOT NULL, + preset_data TEXT NOT NULL, + type TEXT NOT NULL DEFAULT "user", + created_at DATETIME NOT NULL DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')), + -- Updated via trigger + updated_at DATETIME NOT NULL DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) + ); + """ + ] + + # Add trigger for `updated_at`. + triggers = [ + """--sql + CREATE TRIGGER IF NOT EXISTS style_presets + AFTER UPDATE + ON style_presets FOR EACH ROW + BEGIN + UPDATE style_presets SET updated_at = STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW') + WHERE id = old.id; + END; + """ + ] + + # Add indexes for searchable fields + indices = [ + "CREATE INDEX IF NOT EXISTS idx_style_presets_name ON style_presets(name);", + ] + + for stmt in tables + indices + triggers: + cursor.execute(stmt) + + +def build_migration_14() -> Migration: + """ + Build the migration from database version 13 to 14.. + + This migration does the following: + - Create the table used to store style presets. + """ + migration_14 = Migration( + from_version=13, + to_version=14, + callback=Migration14Callback(), + ) + + return migration_14 diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Anime.png b/invokeai/app/services/style_preset_images/default_style_preset_images/Anime.png new file mode 100644 index 0000000000..def6dce259 Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Anime.png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Architectural Visualization.png b/invokeai/app/services/style_preset_images/default_style_preset_images/Architectural Visualization.png new file mode 100644 index 0000000000..97a2e74772 Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Architectural Visualization.png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Concept Art (Character).png b/invokeai/app/services/style_preset_images/default_style_preset_images/Concept Art (Character).png new file mode 100644 index 0000000000..5db78ce086 Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Concept Art (Character).png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Concept Art (Fantasy).png b/invokeai/app/services/style_preset_images/default_style_preset_images/Concept Art (Fantasy).png new file mode 100644 index 0000000000..93c3c5c301 Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Concept Art (Fantasy).png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Concept Art (Painterly).png b/invokeai/app/services/style_preset_images/default_style_preset_images/Concept Art (Painterly).png new file mode 100644 index 0000000000..5d3d0c4af6 Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Concept Art (Painterly).png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Concept Art (Sci-Fi).png b/invokeai/app/services/style_preset_images/default_style_preset_images/Concept Art (Sci-Fi).png new file mode 100644 index 0000000000..3f287fc335 Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Concept Art (Sci-Fi).png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Environment Art.png b/invokeai/app/services/style_preset_images/default_style_preset_images/Environment Art.png new file mode 100644 index 0000000000..a0e1cbfb42 Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Environment Art.png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Illustration.png b/invokeai/app/services/style_preset_images/default_style_preset_images/Illustration.png new file mode 100644 index 0000000000..5b5976c4f9 Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Illustration.png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Interior Design (Visualization).png b/invokeai/app/services/style_preset_images/default_style_preset_images/Interior Design (Visualization).png new file mode 100644 index 0000000000..5c78410377 Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Interior Design (Visualization).png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Line Art.png b/invokeai/app/services/style_preset_images/default_style_preset_images/Line Art.png new file mode 100644 index 0000000000..b8cdfea030 Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Line Art.png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Photography (Black and White).png b/invokeai/app/services/style_preset_images/default_style_preset_images/Photography (Black and White).png new file mode 100644 index 0000000000..b47da9fb94 Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Photography (Black and White).png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Photography (General).png b/invokeai/app/services/style_preset_images/default_style_preset_images/Photography (General).png new file mode 100644 index 0000000000..a034cd197b Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Photography (General).png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Photography (Landscape).png b/invokeai/app/services/style_preset_images/default_style_preset_images/Photography (Landscape).png new file mode 100644 index 0000000000..5985fb6c4b Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Photography (Landscape).png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Photography (Portrait).png b/invokeai/app/services/style_preset_images/default_style_preset_images/Photography (Portrait).png new file mode 100644 index 0000000000..7718735b23 Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Photography (Portrait).png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Photography (Studio Lighting).png b/invokeai/app/services/style_preset_images/default_style_preset_images/Photography (Studio Lighting).png new file mode 100644 index 0000000000..60bd40b1fa Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Photography (Studio Lighting).png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Product Rendering.png b/invokeai/app/services/style_preset_images/default_style_preset_images/Product Rendering.png new file mode 100644 index 0000000000..4a426f4769 Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Product Rendering.png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Sketch.png b/invokeai/app/services/style_preset_images/default_style_preset_images/Sketch.png new file mode 100644 index 0000000000..08d240a29e Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Sketch.png differ diff --git a/invokeai/app/services/style_preset_images/default_style_preset_images/Vehicles.png b/invokeai/app/services/style_preset_images/default_style_preset_images/Vehicles.png new file mode 100644 index 0000000000..73c4c8db08 Binary files /dev/null and b/invokeai/app/services/style_preset_images/default_style_preset_images/Vehicles.png differ diff --git a/invokeai/app/services/style_preset_images/style_preset_images_base.py b/invokeai/app/services/style_preset_images/style_preset_images_base.py new file mode 100644 index 0000000000..d8158ad2ae --- /dev/null +++ b/invokeai/app/services/style_preset_images/style_preset_images_base.py @@ -0,0 +1,33 @@ +from abc import ABC, abstractmethod +from pathlib import Path + +from PIL.Image import Image as PILImageType + + +class StylePresetImageFileStorageBase(ABC): + """Low-level service responsible for storing and retrieving image files.""" + + @abstractmethod + def get(self, style_preset_id: str) -> PILImageType: + """Retrieves a style preset image as PIL Image.""" + pass + + @abstractmethod + def get_path(self, style_preset_id: str) -> Path: + """Gets the internal path to a style preset image.""" + pass + + @abstractmethod + def get_url(self, style_preset_id: str) -> str | None: + """Gets the URL to fetch a style preset image.""" + pass + + @abstractmethod + def save(self, style_preset_id: str, image: PILImageType) -> None: + """Saves a style preset image.""" + pass + + @abstractmethod + def delete(self, style_preset_id: str) -> None: + """Deletes a style preset image.""" + pass diff --git a/invokeai/app/services/style_preset_images/style_preset_images_common.py b/invokeai/app/services/style_preset_images/style_preset_images_common.py new file mode 100644 index 0000000000..054a12b82b --- /dev/null +++ b/invokeai/app/services/style_preset_images/style_preset_images_common.py @@ -0,0 +1,19 @@ +class StylePresetImageFileNotFoundException(Exception): + """Raised when an image file is not found in storage.""" + + def __init__(self, message: str = "Style preset image file not found"): + super().__init__(message) + + +class StylePresetImageFileSaveException(Exception): + """Raised when an image cannot be saved.""" + + def __init__(self, message: str = "Style preset image file not saved"): + super().__init__(message) + + +class StylePresetImageFileDeleteException(Exception): + """Raised when an image cannot be deleted.""" + + def __init__(self, message: str = "Style preset image file not deleted"): + super().__init__(message) diff --git a/invokeai/app/services/style_preset_images/style_preset_images_disk.py b/invokeai/app/services/style_preset_images/style_preset_images_disk.py new file mode 100644 index 0000000000..cd2b29efd2 --- /dev/null +++ b/invokeai/app/services/style_preset_images/style_preset_images_disk.py @@ -0,0 +1,88 @@ +from pathlib import Path + +from PIL import Image +from PIL.Image import Image as PILImageType + +from invokeai.app.services.invoker import Invoker +from invokeai.app.services.style_preset_images.style_preset_images_base import StylePresetImageFileStorageBase +from invokeai.app.services.style_preset_images.style_preset_images_common import ( + StylePresetImageFileDeleteException, + StylePresetImageFileNotFoundException, + StylePresetImageFileSaveException, +) +from invokeai.app.services.style_preset_records.style_preset_records_common import PresetType +from invokeai.app.util.misc import uuid_string +from invokeai.app.util.thumbnails import make_thumbnail + + +class StylePresetImageFileStorageDisk(StylePresetImageFileStorageBase): + """Stores images on disk""" + + def __init__(self, style_preset_images_folder: Path): + self._style_preset_images_folder = style_preset_images_folder + self._validate_storage_folders() + + def start(self, invoker: Invoker) -> None: + self._invoker = invoker + + def get(self, style_preset_id: str) -> PILImageType: + try: + path = self.get_path(style_preset_id) + + return Image.open(path) + except FileNotFoundError as e: + raise StylePresetImageFileNotFoundException from e + + def save(self, style_preset_id: str, image: PILImageType) -> None: + try: + self._validate_storage_folders() + image_path = self._style_preset_images_folder / (style_preset_id + ".webp") + thumbnail = make_thumbnail(image, 256) + thumbnail.save(image_path, format="webp") + + except Exception as e: + raise StylePresetImageFileSaveException from e + + def get_path(self, style_preset_id: str) -> Path: + style_preset = self._invoker.services.style_preset_records.get(style_preset_id) + if style_preset.type is PresetType.Default: + default_images_dir = Path(__file__).parent / Path("default_style_preset_images") + path = default_images_dir / (style_preset.name + ".png") + else: + path = self._style_preset_images_folder / (style_preset_id + ".webp") + + return path + + def get_url(self, style_preset_id: str) -> str | None: + path = self.get_path(style_preset_id) + if not self._validate_path(path): + return + + url = self._invoker.services.urls.get_style_preset_image_url(style_preset_id) + + # The image URL never changes, so we must add random query string to it to prevent caching + url += f"?{uuid_string()}" + + return url + + def delete(self, style_preset_id: str) -> None: + try: + path = self.get_path(style_preset_id) + + if not self._validate_path(path): + raise StylePresetImageFileNotFoundException + + path.unlink() + + except StylePresetImageFileNotFoundException as e: + raise StylePresetImageFileNotFoundException from e + except Exception as e: + raise StylePresetImageFileDeleteException from e + + def _validate_path(self, path: Path) -> bool: + """Validates the path given for an image.""" + return path.exists() + + def _validate_storage_folders(self) -> None: + """Checks if the required folders exist and create them if they don't""" + self._style_preset_images_folder.mkdir(parents=True, exist_ok=True) diff --git a/invokeai/app/services/style_preset_records/__init__.py b/invokeai/app/services/style_preset_records/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/invokeai/app/services/style_preset_records/default_style_presets.json b/invokeai/app/services/style_preset_records/default_style_presets.json new file mode 100644 index 0000000000..aa9ede40dc --- /dev/null +++ b/invokeai/app/services/style_preset_records/default_style_presets.json @@ -0,0 +1,146 @@ +[ + { + "name": "Photography (General)", + "type": "default", + "preset_data": { + "positive_prompt": "[prompt]. photography. f/2.8 macro photo, bokeh, photorealism", + "negative_prompt": "painting, digital art. sketch, blurry" + } + }, + { + "name": "Photography (Studio Lighting)", + "type": "default", + "preset_data": { + "positive_prompt": "[prompt], photography. f/8 photo. centered subject, studio lighting.", + "negative_prompt": "painting, digital art. sketch, blurry" + } + }, + { + "name": "Photography (Landscape)", + "type": "default", + "preset_data": { + "positive_prompt": "[prompt], landscape photograph, f/12, lifelike, highly detailed.", + "negative_prompt": "painting, digital art. sketch, blurry" + } + }, + { + "name": "Photography (Portrait)", + "type": "default", + "preset_data": { + "positive_prompt": "[prompt]. photography. portraiture. catch light in eyes. one flash. rembrandt lighting. Soft box. dark shadows. High contrast. 80mm lens. F2.8.", + "negative_prompt": "painting, digital art. sketch, blurry" + } + }, + { + "name": "Photography (Black and White)", + "type": "default", + "preset_data": { + "positive_prompt": "[prompt] photography. natural light. 80mm lens. F1.4. strong contrast, hard light. dark contrast. blurred background. black and white", + "negative_prompt": "painting, digital art. sketch, colour+" + } + }, + { + "name": "Architectural Visualization", + "type": "default", + "preset_data": { + "positive_prompt": "[prompt]. architectural photography, f/12, luxury, aesthetically pleasing form and function.", + "negative_prompt": "painting, digital art. sketch, blurry" + } + }, + { + "name": "Concept Art (Fantasy)", + "type": "default", + "preset_data": { + "positive_prompt": "concept artwork of a [prompt]. (digital painterly art style)++, mythological, (textured 2d dry media brushpack)++, glazed brushstrokes, otherworldly. painting+, illustration+", + "negative_prompt": "photo. distorted, blurry, out of focus. sketch. (cgi, 3d.)++" + } + }, + { + "name": "Concept Art (Sci-Fi)", + "type": "default", + "preset_data": { + "positive_prompt": "(concept art)++, [prompt], (sleek futurism)++, (textured 2d dry media)++, metallic highlights, digital painting style", + "negative_prompt": "photo. distorted, blurry, out of focus. sketch. (cgi, 3d.)++" + } + }, + { + "name": "Concept Art (Character)", + "type": "default", + "preset_data": { + "positive_prompt": "(character concept art)++, stylized painterly digital painting of [prompt], (painterly, impasto. Dry brush.)++", + "negative_prompt": "photo. distorted, blurry, out of focus. sketch. (cgi, 3d.)++" + } + }, + { + "name": "Concept Art (Painterly)", + "type": "default", + "preset_data": { + "positive_prompt": "[prompt] oil painting. high contrast. impasto. sfumato. chiaroscuro. Palette knife.", + "negative_prompt": "photo. smooth. border. frame" + } + }, + { + "name": "Environment Art", + "type": "default", + "preset_data": { + "positive_prompt": "[prompt] environment artwork, hyper-realistic digital painting style with cinematic composition, atmospheric, depth and detail, voluminous. textured dry brush 2d media", + "negative_prompt": "photo, distorted, blurry, out of focus. sketch." + } + }, + { + "name": "Interior Design (Visualization)", + "type": "default", + "preset_data": { + "positive_prompt": "[prompt] interior design photo, gentle shadows, light mid-tones, dimension, mix of smooth and textured surfaces, focus on negative space and clean lines, focus", + "negative_prompt": "photo, distorted. sketch." + } + }, + { + "name": "Product Rendering", + "type": "default", + "preset_data": { + "positive_prompt": "[prompt] high quality product photography, 3d rendering with key lighting, shallow depth of field, simple plain background, studio lighting.", + "negative_prompt": "blurry, sketch, messy, dirty. unfinished." + } + }, + { + "name": "Sketch", + "type": "default", + "preset_data": { + "positive_prompt": "[prompt] black and white pencil drawing, off-center composition, cross-hatching for shadows, bold strokes, textured paper. sketch+++", + "negative_prompt": "blurry, photo, painting, color. messy, dirty. unfinished. frame, borders." + } + }, + { + "name": "Line Art", + "type": "default", + "preset_data": { + "positive_prompt": "[prompt] Line art. bold outline. simplistic. white background. 2d", + "negative_prompt": "photo. digital art. greyscale. solid black. painting" + } + }, + { + "name": "Anime", + "type": "default", + "preset_data": { + "positive_prompt": "[prompt] anime++, bold outline, cel-shaded coloring, shounen, seinen", + "negative_prompt": "(photo)+++. greyscale. solid black. painting" + } + }, + { + "name": "Illustration", + "type": "default", + "preset_data": { + "positive_prompt": "[prompt] illustration, bold linework, illustrative details, vector art style, flat coloring", + "negative_prompt": "(photo)+++. greyscale. painting, black and white." + } + }, + { + "name": "Vehicles", + "type": "default", + "preset_data": { + "positive_prompt": "A weird futuristic normal auto, [prompt] elegant design, nice color, nice wheels", + "negative_prompt": "sketch. digital art. greyscale. painting" + } + } +] diff --git a/invokeai/app/services/style_preset_records/style_preset_records_base.py b/invokeai/app/services/style_preset_records/style_preset_records_base.py new file mode 100644 index 0000000000..9e3a504e06 --- /dev/null +++ b/invokeai/app/services/style_preset_records/style_preset_records_base.py @@ -0,0 +1,36 @@ +from abc import ABC, abstractmethod + +from invokeai.app.services.style_preset_records.style_preset_records_common import ( + StylePresetChanges, + StylePresetRecordDTO, + StylePresetWithoutId, +) + + +class StylePresetRecordsStorageBase(ABC): + """Base class for style preset storage services.""" + + @abstractmethod + def get(self, style_preset_id: str) -> StylePresetRecordDTO: + """Get style preset by id.""" + pass + + @abstractmethod + def create(self, style_preset: StylePresetWithoutId) -> StylePresetRecordDTO: + """Creates a style preset.""" + pass + + @abstractmethod + def update(self, style_preset_id: str, changes: StylePresetChanges) -> StylePresetRecordDTO: + """Updates a style preset.""" + pass + + @abstractmethod + def delete(self, style_preset_id: str) -> None: + """Deletes a style preset.""" + pass + + @abstractmethod + def get_many(self) -> list[StylePresetRecordDTO]: + """Gets many workflows.""" + pass diff --git a/invokeai/app/services/style_preset_records/style_preset_records_common.py b/invokeai/app/services/style_preset_records/style_preset_records_common.py new file mode 100644 index 0000000000..964489b54d --- /dev/null +++ b/invokeai/app/services/style_preset_records/style_preset_records_common.py @@ -0,0 +1,51 @@ +from enum import Enum +from typing import Any, Optional + +from pydantic import BaseModel, Field, TypeAdapter + +from invokeai.app.util.metaenum import MetaEnum + + +class StylePresetNotFoundError(Exception): + """Raised when a style preset is not found""" + + +class PresetData(BaseModel, extra="forbid"): + positive_prompt: str = Field(description="Positive prompt") + negative_prompt: str = Field(description="Negative prompt") + + +PresetDataValidator = TypeAdapter(PresetData) + + +class PresetType(str, Enum, metaclass=MetaEnum): + User = "user" + Default = "default" + Project = "project" + + +class StylePresetChanges(BaseModel, extra="forbid"): + name: Optional[str] = Field(default=None, description="The style preset's new name.") + preset_data: Optional[PresetData] = Field(default=None, description="The updated data for style preset.") + + +class StylePresetWithoutId(BaseModel): + name: str = Field(description="The name of the style preset.") + preset_data: PresetData = Field(description="The preset data") + type: PresetType = Field(description="The type of style preset") + + +class StylePresetRecordDTO(StylePresetWithoutId): + id: str = Field(description="The style preset ID.") + + @classmethod + def from_dict(cls, data: dict[str, Any]) -> "StylePresetRecordDTO": + data["preset_data"] = PresetDataValidator.validate_json(data.get("preset_data", "")) + return StylePresetRecordDTOValidator.validate_python(data) + + +StylePresetRecordDTOValidator = TypeAdapter(StylePresetRecordDTO) + + +class StylePresetRecordWithImage(StylePresetRecordDTO): + image: Optional[str] = Field(description="The path for image") diff --git a/invokeai/app/services/style_preset_records/style_preset_records_sqlite.py b/invokeai/app/services/style_preset_records/style_preset_records_sqlite.py new file mode 100644 index 0000000000..a98ff462f2 --- /dev/null +++ b/invokeai/app/services/style_preset_records/style_preset_records_sqlite.py @@ -0,0 +1,175 @@ +import json +from pathlib import Path + +from invokeai.app.services.invoker import Invoker +from invokeai.app.services.shared.sqlite.sqlite_database import SqliteDatabase +from invokeai.app.services.style_preset_records.style_preset_records_base import StylePresetRecordsStorageBase +from invokeai.app.services.style_preset_records.style_preset_records_common import ( + StylePresetChanges, + StylePresetNotFoundError, + StylePresetRecordDTO, + StylePresetWithoutId, +) +from invokeai.app.util.misc import uuid_string + + +class SqliteStylePresetRecordsStorage(StylePresetRecordsStorageBase): + def __init__(self, db: SqliteDatabase) -> None: + super().__init__() + self._lock = db.lock + self._conn = db.conn + self._cursor = self._conn.cursor() + + def start(self, invoker: Invoker) -> None: + self._invoker = invoker + self._sync_default_style_presets() + + def get(self, style_preset_id: str) -> StylePresetRecordDTO: + """Gets a style preset by ID.""" + try: + self._lock.acquire() + self._cursor.execute( + """--sql + SELECT * + FROM style_presets + WHERE id = ?; + """, + (style_preset_id,), + ) + row = self._cursor.fetchone() + if row is None: + raise StylePresetNotFoundError(f"Style preset with id {style_preset_id} not found") + return StylePresetRecordDTO.from_dict(dict(row)) + except Exception: + self._conn.rollback() + raise + finally: + self._lock.release() + + def create(self, style_preset: StylePresetWithoutId) -> StylePresetRecordDTO: + style_preset_id = uuid_string() + try: + self._lock.acquire() + self._cursor.execute( + """--sql + INSERT OR IGNORE INTO style_presets ( + id, + name, + preset_data, + type + ) + VALUES (?, ?, ?, ?); + """, + ( + style_preset_id, + style_preset.name, + style_preset.preset_data.model_dump_json(), + style_preset.type, + ), + ) + self._conn.commit() + except Exception: + self._conn.rollback() + raise + finally: + self._lock.release() + return self.get(style_preset_id) + + def update(self, style_preset_id: str, changes: StylePresetChanges) -> StylePresetRecordDTO: + try: + self._lock.acquire() + # Change the name of a style preset + if changes.name is not None: + self._cursor.execute( + """--sql + UPDATE style_presets + SET name = ? + WHERE id = ?; + """, + (changes.name, style_preset_id), + ) + + # Change the preset data for a style preset + if changes.preset_data is not None: + self._cursor.execute( + """--sql + UPDATE style_presets + SET preset_data = ? + WHERE id = ?; + """, + (changes.preset_data.model_dump_json(), style_preset_id), + ) + + self._conn.commit() + except Exception: + self._conn.rollback() + raise + finally: + self._lock.release() + return self.get(style_preset_id) + + def delete(self, style_preset_id: str) -> None: + try: + self._lock.acquire() + self._cursor.execute( + """--sql + DELETE from style_presets + WHERE id = ?; + """, + (style_preset_id,), + ) + self._conn.commit() + except Exception: + self._conn.rollback() + raise + finally: + self._lock.release() + return None + + def get_many( + self, + ) -> list[StylePresetRecordDTO]: + try: + self._lock.acquire() + main_query = """ + SELECT + * + FROM style_presets + ORDER BY LOWER(name) ASC + """ + + self._cursor.execute(main_query) + rows = self._cursor.fetchall() + style_presets = [StylePresetRecordDTO.from_dict(dict(row)) for row in rows] + + return style_presets + except Exception: + self._conn.rollback() + raise + finally: + self._lock.release() + + def _sync_default_style_presets(self) -> None: + """Syncs default style presets to the database. Internal use only.""" + + # First delete all existing default style presets + try: + self._lock.acquire() + self._cursor.execute( + """--sql + DELETE FROM style_presets + WHERE type = "default"; + """ + ) + self._conn.commit() + except Exception: + self._conn.rollback() + raise + finally: + self._lock.release() + # Next, parse and create the default style presets + with self._lock, open(Path(__file__).parent / Path("default_style_presets.json"), "r") as file: + presets = json.load(file) + for preset in presets: + style_preset = StylePresetWithoutId.model_validate(preset) + self.create(style_preset) diff --git a/invokeai/app/services/urls/urls_base.py b/invokeai/app/services/urls/urls_base.py index 477ef04624..b2e41db3e4 100644 --- a/invokeai/app/services/urls/urls_base.py +++ b/invokeai/app/services/urls/urls_base.py @@ -13,3 +13,8 @@ class UrlServiceBase(ABC): def get_model_image_url(self, model_key: str) -> str: """Gets the URL for a model image""" pass + + @abstractmethod + def get_style_preset_image_url(self, style_preset_id: str) -> str: + """Gets the URL for a style preset image""" + pass diff --git a/invokeai/app/services/urls/urls_default.py b/invokeai/app/services/urls/urls_default.py index d570521fb8..f62bebe901 100644 --- a/invokeai/app/services/urls/urls_default.py +++ b/invokeai/app/services/urls/urls_default.py @@ -19,3 +19,6 @@ class LocalUrlService(UrlServiceBase): def get_model_image_url(self, model_key: str) -> str: return f"{self._base_url_v2}/models/i/{model_key}/image" + + def get_style_preset_image_url(self, style_preset_id: str) -> str: + return f"{self._base_url}/style_presets/i/{style_preset_id}/image" diff --git a/invokeai/frontend/web/package.json b/invokeai/frontend/web/package.json index 8ef67a6a9f..1b6432a308 100644 --- a/invokeai/frontend/web/package.json +++ b/invokeai/frontend/web/package.json @@ -59,7 +59,7 @@ "@dnd-kit/sortable": "^8.0.0", "@dnd-kit/utilities": "^3.2.2", "@fontsource-variable/inter": "^5.0.20", - "@invoke-ai/ui-library": "^0.0.25", + "@invoke-ai/ui-library": "^0.0.29", "@nanostores/react": "^0.7.3", "@reduxjs/toolkit": "2.2.3", "@roarr/browser-log-writer": "^1.3.0", @@ -110,7 +110,6 @@ "zod-validation-error": "^3.3.1" }, "peerDependencies": { - "@chakra-ui/react": "^2.8.2", "react": "^18.2.0", "react-dom": "^18.2.0", "ts-toolbelt": "^9.6.0" diff --git a/invokeai/frontend/web/pnpm-lock.yaml b/invokeai/frontend/web/pnpm-lock.yaml index d46b93846b..90b52e6306 100644 --- a/invokeai/frontend/web/pnpm-lock.yaml +++ b/invokeai/frontend/web/pnpm-lock.yaml @@ -5,9 +5,6 @@ settings: excludeLinksFromLockfile: false dependencies: - '@chakra-ui/react': - specifier: ^2.8.2 - version: 2.8.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.3.1)(framer-motion@11.1.8)(react-dom@18.3.1)(react@18.3.1) '@chakra-ui/react-use-size': specifier: ^2.1.0 version: 2.1.0(react@18.3.1) @@ -30,8 +27,8 @@ dependencies: specifier: ^5.0.20 version: 5.0.20 '@invoke-ai/ui-library': - specifier: ^0.0.25 - version: 0.0.25(@chakra-ui/form-control@2.2.0)(@chakra-ui/icon@3.2.0)(@chakra-ui/media-query@3.3.0)(@chakra-ui/menu@2.2.1)(@chakra-ui/spinner@2.1.0)(@chakra-ui/system@2.6.2)(@fontsource-variable/inter@5.0.20)(@internationalized/date@3.5.5)(@types/react@18.3.3)(i18next@23.12.2)(react-dom@18.3.1)(react@18.3.1) + specifier: ^0.0.29 + version: 0.0.29(@chakra-ui/form-control@2.2.0)(@chakra-ui/icon@3.2.0)(@chakra-ui/media-query@3.3.0)(@chakra-ui/menu@2.2.1)(@chakra-ui/spinner@2.1.0)(@chakra-ui/system@2.6.2)(@fontsource-variable/inter@5.0.20)(@types/react@18.3.3)(i18next@23.12.2)(react-dom@18.3.1)(react@18.3.1) '@nanostores/react': specifier: ^0.7.3 version: 0.7.3(nanostores@0.11.2)(react@18.3.1) @@ -310,92 +307,6 @@ packages: '@jridgewell/trace-mapping': 0.3.25 dev: true - /@ark-ui/anatomy@1.3.0(@internationalized/date@3.5.5): - resolution: {integrity: sha512-1yG2MrzUlix6KthjQMCNiHnkXrWwEdFAX6D+HqGJaNu0XvaGul2J+wDNtjsdX+gxiWu1nXXEEOAWlFVYMUf65w==} - dependencies: - '@zag-js/accordion': 0.32.1 - '@zag-js/anatomy': 0.32.1 - '@zag-js/avatar': 0.32.1 - '@zag-js/carousel': 0.32.1 - '@zag-js/checkbox': 0.32.1 - '@zag-js/color-picker': 0.32.1 - '@zag-js/color-utils': 0.32.1 - '@zag-js/combobox': 0.32.1 - '@zag-js/date-picker': 0.32.1 - '@zag-js/date-utils': 0.32.1(@internationalized/date@3.5.5) - '@zag-js/dialog': 0.32.1 - '@zag-js/editable': 0.32.1 - '@zag-js/file-upload': 0.32.1 - '@zag-js/hover-card': 0.32.1 - '@zag-js/menu': 0.32.1 - '@zag-js/number-input': 0.32.1 - '@zag-js/pagination': 0.32.1 - '@zag-js/pin-input': 0.32.1 - '@zag-js/popover': 0.32.1 - '@zag-js/presence': 0.32.1 - '@zag-js/progress': 0.32.1 - '@zag-js/radio-group': 0.32.1 - '@zag-js/rating-group': 0.32.1 - '@zag-js/select': 0.32.1 - '@zag-js/slider': 0.32.1 - '@zag-js/splitter': 0.32.1 - '@zag-js/switch': 0.32.1 - '@zag-js/tabs': 0.32.1 - '@zag-js/tags-input': 0.32.1 - '@zag-js/toast': 0.32.1 - '@zag-js/toggle-group': 0.32.1 - '@zag-js/tooltip': 0.32.1 - transitivePeerDependencies: - - '@internationalized/date' - dev: false - - /@ark-ui/react@1.3.0(@internationalized/date@3.5.5)(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-JHjNoIX50+mUCTaEGMjfGQWGGi31pKsV646jZJlR/1xohpYJigzg8BvO97cTsVk8fwtur+cm11gz3Nf7f5QUnA==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - dependencies: - '@ark-ui/anatomy': 1.3.0(@internationalized/date@3.5.5) - '@zag-js/accordion': 0.32.1 - '@zag-js/avatar': 0.32.1 - '@zag-js/carousel': 0.32.1 - '@zag-js/checkbox': 0.32.1 - '@zag-js/color-picker': 0.32.1 - '@zag-js/color-utils': 0.32.1 - '@zag-js/combobox': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/date-picker': 0.32.1 - '@zag-js/date-utils': 0.32.1(@internationalized/date@3.5.5) - '@zag-js/dialog': 0.32.1 - '@zag-js/editable': 0.32.1 - '@zag-js/file-upload': 0.32.1 - '@zag-js/hover-card': 0.32.1 - '@zag-js/menu': 0.32.1 - '@zag-js/number-input': 0.32.1 - '@zag-js/pagination': 0.32.1 - '@zag-js/pin-input': 0.32.1 - '@zag-js/popover': 0.32.1 - '@zag-js/presence': 0.32.1 - '@zag-js/progress': 0.32.1 - '@zag-js/radio-group': 0.32.1 - '@zag-js/rating-group': 0.32.1 - '@zag-js/react': 0.32.1(react-dom@18.3.1)(react@18.3.1) - '@zag-js/select': 0.32.1 - '@zag-js/slider': 0.32.1 - '@zag-js/splitter': 0.32.1 - '@zag-js/switch': 0.32.1 - '@zag-js/tabs': 0.32.1 - '@zag-js/tags-input': 0.32.1 - '@zag-js/toast': 0.32.1 - '@zag-js/toggle-group': 0.32.1 - '@zag-js/tooltip': 0.32.1 - '@zag-js/types': 0.32.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - transitivePeerDependencies: - - '@internationalized/date' - dev: false - /@babel/code-frame@7.24.2: resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} engines: {node: '>=6.9.0'} @@ -1826,20 +1737,6 @@ packages: resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} dev: true - /@babel/runtime@7.23.9: - resolution: {integrity: sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.14.1 - dev: false - - /@babel/runtime@7.24.1: - resolution: {integrity: sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.14.1 - dev: false - /@babel/runtime@7.24.5: resolution: {integrity: sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==} engines: {node: '>=6.9.0'} @@ -1938,31 +1835,12 @@ packages: '@chakra-ui/react-use-controllable-state': 2.1.0(react@18.3.1) '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) '@chakra-ui/transition': 2.1.0(framer-motion@10.18.0)(react@18.3.1) framer-motion: 10.18.0(react-dom@18.3.1)(react@18.3.1) react: 18.3.1 dev: false - /@chakra-ui/accordion@2.3.1(@chakra-ui/system@2.6.2)(framer-motion@11.1.8)(react@18.3.1): - resolution: {integrity: sha512-FSXRm8iClFyU+gVaXisOSEw0/4Q+qZbFRiuhIAkVU6Boj0FxAMrlo9a8AV5TuF77rgaHytCdHk0Ng+cyUijrag==} - peerDependencies: - '@chakra-ui/system': '>=2.0.0' - framer-motion: '>=4.0.0' - react: '>=18' - dependencies: - '@chakra-ui/descendant': 3.1.0(react@18.3.1) - '@chakra-ui/icon': 3.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/react-context': 2.1.0(react@18.3.1) - '@chakra-ui/react-use-controllable-state': 2.1.0(react@18.3.1) - '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1) - '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) - '@chakra-ui/transition': 2.1.0(framer-motion@11.1.8)(react@18.3.1) - framer-motion: 11.1.8(react-dom@18.3.1)(react@18.3.1) - react: 18.3.1 - dev: false - /@chakra-ui/alert@2.2.2(@chakra-ui/system@2.6.2)(react@18.3.1): resolution: {integrity: sha512-jHg4LYMRNOJH830ViLuicjb3F+v6iriE/2G5T+Sd0Hna04nukNJ1MxUmBPE+vI22me2dIflfelu2v9wdB6Pojw==} peerDependencies: @@ -1973,7 +1851,7 @@ packages: '@chakra-ui/react-context': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 '@chakra-ui/spinner': 2.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -1991,7 +1869,7 @@ packages: '@chakra-ui/react-children-utils': 2.0.6(react@18.3.1) '@chakra-ui/react-context': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2004,7 +1882,7 @@ packages: '@chakra-ui/react-children-utils': 2.0.6(react@18.3.1) '@chakra-ui/react-context': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2024,7 +1902,7 @@ packages: '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 '@chakra-ui/spinner': 2.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2035,7 +1913,7 @@ packages: react: '>=18' dependencies: '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2054,7 +1932,7 @@ packages: '@chakra-ui/react-use-safe-layout-effect': 2.1.0(react@18.3.1) '@chakra-ui/react-use-update-effect': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) '@chakra-ui/visually-hidden': 2.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) '@zag-js/focus-visible': 0.16.0 react: 18.3.1 @@ -2077,7 +1955,7 @@ packages: react: '>=18' dependencies: '@chakra-ui/icon': 3.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2096,7 +1974,7 @@ packages: '@chakra-ui/system': '>=2.0.0' react: '>=18' dependencies: - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2111,13 +1989,13 @@ packages: react: 18.3.1 dev: false - /@chakra-ui/css-reset@2.3.0(@emotion/react@11.11.4)(react@18.3.1): + /@chakra-ui/css-reset@2.3.0(@emotion/react@11.13.0)(react@18.3.1): resolution: {integrity: sha512-cQwwBy5O0jzvl0K7PLTLgp8ijqLPKyuEMiDXwYzl95seD3AoeuoCLyzZcJtVqaUZ573PiBdAbY/IlZcwDOItWg==} peerDependencies: '@emotion/react': '>=10.0.35' react: '>=18' dependencies: - '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) + '@emotion/react': 11.13.0(@types/react@18.3.3)(react@18.3.1) react: 18.3.1 dev: false @@ -2150,7 +2028,7 @@ packages: '@chakra-ui/react-use-safe-layout-effect': 2.1.0(react@18.3.1) '@chakra-ui/react-use-update-effect': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2158,18 +2036,6 @@ packages: resolution: {integrity: sha512-IGM/yGUHS+8TOQrZGpAKOJl/xGBrmRYJrmbHfUE7zrG3PpQyXvbLDP1M+RggkCFVgHlJi2wpYIf0QtQlU0XZfw==} dev: false - /@chakra-ui/focus-lock@2.1.0(@types/react@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-EmGx4PhWGjm4dpjRqM4Aa+rCWBxP+Rq8Uc/nAVnD4YVqkEhBkrPTpui2lnjsuxqNaZ24fIAZ10cF1hlpemte/w==} - peerDependencies: - react: '>=18' - dependencies: - '@chakra-ui/dom-utils': 2.1.0 - react: 18.3.1 - react-focus-lock: 2.11.1(@types/react@18.3.1)(react@18.3.1) - transitivePeerDependencies: - - '@types/react' - dev: false - /@chakra-ui/focus-lock@2.1.0(@types/react@18.3.3)(react@18.3.1): resolution: {integrity: sha512-EmGx4PhWGjm4dpjRqM4Aa+rCWBxP+Rq8Uc/nAVnD4YVqkEhBkrPTpui2lnjsuxqNaZ24fIAZ10cF1hlpemte/w==} peerDependencies: @@ -2177,7 +2043,7 @@ packages: dependencies: '@chakra-ui/dom-utils': 2.1.0 react: 18.3.1 - react-focus-lock: 2.11.1(@types/react@18.3.3)(react@18.3.1) + react-focus-lock: 2.12.1(@types/react@18.3.3)(react@18.3.1) transitivePeerDependencies: - '@types/react' dev: false @@ -2193,7 +2059,7 @@ packages: '@chakra-ui/react-types': 2.0.7(react@18.3.1) '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2216,7 +2082,7 @@ packages: react: '>=18' dependencies: '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2227,7 +2093,7 @@ packages: react: '>=18' dependencies: '@chakra-ui/icon': 3.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2239,7 +2105,7 @@ packages: dependencies: '@chakra-ui/react-use-safe-layout-effect': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2254,7 +2120,7 @@ packages: '@chakra-ui/react-children-utils': 2.0.6(react@18.3.1) '@chakra-ui/react-context': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2270,7 +2136,7 @@ packages: '@chakra-ui/react-children-utils': 2.0.6(react@18.3.1) '@chakra-ui/react-context': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2295,7 +2161,7 @@ packages: '@chakra-ui/breakpoint-utils': 2.0.8 '@chakra-ui/react-env': 3.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2320,39 +2186,12 @@ packages: '@chakra-ui/react-use-outside-click': 2.2.0(react@18.3.1) '@chakra-ui/react-use-update-effect': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) '@chakra-ui/transition': 2.1.0(framer-motion@10.18.0)(react@18.3.1) framer-motion: 10.18.0(react-dom@18.3.1)(react@18.3.1) react: 18.3.1 dev: false - /@chakra-ui/menu@2.2.1(@chakra-ui/system@2.6.2)(framer-motion@11.1.8)(react@18.3.1): - resolution: {integrity: sha512-lJS7XEObzJxsOwWQh7yfG4H8FzFPRP5hVPN/CL+JzytEINCSBvsCDHrYPQGp7jzpCi8vnTqQQGQe0f8dwnXd2g==} - peerDependencies: - '@chakra-ui/system': '>=2.0.0' - framer-motion: '>=4.0.0' - react: '>=18' - dependencies: - '@chakra-ui/clickable': 2.1.0(react@18.3.1) - '@chakra-ui/descendant': 3.1.0(react@18.3.1) - '@chakra-ui/lazy-utils': 2.0.5 - '@chakra-ui/popper': 3.1.0(react@18.3.1) - '@chakra-ui/react-children-utils': 2.0.6(react@18.3.1) - '@chakra-ui/react-context': 2.1.0(react@18.3.1) - '@chakra-ui/react-use-animation-state': 2.1.0(react@18.3.1) - '@chakra-ui/react-use-controllable-state': 2.1.0(react@18.3.1) - '@chakra-ui/react-use-disclosure': 2.1.0(react@18.3.1) - '@chakra-ui/react-use-focus-effect': 2.1.0(react@18.3.1) - '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1) - '@chakra-ui/react-use-outside-click': 2.2.0(react@18.3.1) - '@chakra-ui/react-use-update-effect': 2.1.0(react@18.3.1) - '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.11.5)(react@18.3.1) - '@chakra-ui/transition': 2.1.0(framer-motion@11.1.8)(react@18.3.1) - framer-motion: 11.1.8(react-dom@18.3.1)(react@18.3.1) - react: 18.3.1 - dev: false - /@chakra-ui/menu@2.2.1(@chakra-ui/system@2.6.2)(framer-motion@11.3.24)(react@18.3.1): resolution: {integrity: sha512-lJS7XEObzJxsOwWQh7yfG4H8FzFPRP5hVPN/CL+JzytEINCSBvsCDHrYPQGp7jzpCi8vnTqQQGQe0f8dwnXd2g==} peerDependencies: @@ -2374,38 +2213,12 @@ packages: '@chakra-ui/react-use-outside-click': 2.2.0(react@18.3.1) '@chakra-ui/react-use-update-effect': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) '@chakra-ui/transition': 2.1.0(framer-motion@11.3.24)(react@18.3.1) framer-motion: 11.3.24(react-dom@18.3.1)(react@18.3.1) react: 18.3.1 dev: false - /@chakra-ui/modal@2.3.1(@chakra-ui/system@2.6.2)(@types/react@18.3.1)(framer-motion@11.1.8)(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-TQv1ZaiJMZN+rR9DK0snx/OPwmtaGH1HbZtlYt4W4s6CzyK541fxLRTjIXfEzIGpvNW+b6VFuFjbcR78p4DEoQ==} - peerDependencies: - '@chakra-ui/system': '>=2.0.0' - framer-motion: '>=4.0.0' - react: '>=18' - react-dom: '>=18' - dependencies: - '@chakra-ui/close-button': 2.1.1(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/focus-lock': 2.1.0(@types/react@18.3.1)(react@18.3.1) - '@chakra-ui/portal': 2.1.0(react-dom@18.3.1)(react@18.3.1) - '@chakra-ui/react-context': 2.1.0(react@18.3.1) - '@chakra-ui/react-types': 2.0.7(react@18.3.1) - '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1) - '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) - '@chakra-ui/transition': 2.1.0(framer-motion@11.1.8)(react@18.3.1) - aria-hidden: 1.2.3 - framer-motion: 11.1.8(react-dom@18.3.1)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.5.7(@types/react@18.3.1)(react@18.3.1) - transitivePeerDependencies: - - '@types/react' - dev: false - /@chakra-ui/modal@2.3.1(@chakra-ui/system@2.6.2)(@types/react@18.3.3)(framer-motion@10.18.0)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-TQv1ZaiJMZN+rR9DK0snx/OPwmtaGH1HbZtlYt4W4s6CzyK541fxLRTjIXfEzIGpvNW+b6VFuFjbcR78p4DEoQ==} peerDependencies: @@ -2421,13 +2234,13 @@ packages: '@chakra-ui/react-types': 2.0.7(react@18.3.1) '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) '@chakra-ui/transition': 2.1.0(framer-motion@10.18.0)(react@18.3.1) - aria-hidden: 1.2.3 + aria-hidden: 1.2.4 framer-motion: 10.18.0(react-dom@18.3.1)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.5.7(@types/react@18.3.3)(react@18.3.1) + react-remove-scroll: 2.5.10(@types/react@18.3.3)(react@18.3.1) transitivePeerDependencies: - '@types/react' dev: false @@ -2450,7 +2263,7 @@ packages: '@chakra-ui/react-use-safe-layout-effect': 2.1.0(react@18.3.1) '@chakra-ui/react-use-update-effect': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2474,7 +2287,7 @@ packages: '@chakra-ui/react-use-controllable-state': 2.1.0(react@18.3.1) '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2496,34 +2309,11 @@ packages: '@chakra-ui/react-use-focus-on-pointer-down': 2.1.0(react@18.3.1) '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) framer-motion: 10.18.0(react-dom@18.3.1)(react@18.3.1) react: 18.3.1 dev: false - /@chakra-ui/popover@2.2.1(@chakra-ui/system@2.6.2)(framer-motion@11.1.8)(react@18.3.1): - resolution: {integrity: sha512-K+2ai2dD0ljvJnlrzesCDT9mNzLifE3noGKZ3QwLqd/K34Ym1W/0aL1ERSynrcG78NKoXS54SdEzkhCZ4Gn/Zg==} - peerDependencies: - '@chakra-ui/system': '>=2.0.0' - framer-motion: '>=4.0.0' - react: '>=18' - dependencies: - '@chakra-ui/close-button': 2.1.1(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/lazy-utils': 2.0.5 - '@chakra-ui/popper': 3.1.0(react@18.3.1) - '@chakra-ui/react-context': 2.1.0(react@18.3.1) - '@chakra-ui/react-types': 2.0.7(react@18.3.1) - '@chakra-ui/react-use-animation-state': 2.1.0(react@18.3.1) - '@chakra-ui/react-use-disclosure': 2.1.0(react@18.3.1) - '@chakra-ui/react-use-focus-effect': 2.1.0(react@18.3.1) - '@chakra-ui/react-use-focus-on-pointer-down': 2.1.0(react@18.3.1) - '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1) - '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) - framer-motion: 11.1.8(react-dom@18.3.1)(react@18.3.1) - react: 18.3.1 - dev: false - /@chakra-ui/popper@3.1.0(react@18.3.1): resolution: {integrity: sha512-ciDdpdYbeFG7og6/6J8lkTFxsSvwTdMLFkpVylAF6VNC22jssiWfquj2eyD4rJnzkRFPvIWJq8hvbfhsm+AjSg==} peerDependencies: @@ -2554,11 +2344,11 @@ packages: react: '>=18' dependencies: '@chakra-ui/react-context': 2.1.0(react@18.3.1) - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false - /@chakra-ui/provider@2.4.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react-dom@18.3.1)(react@18.3.1): + /@chakra-ui/provider@2.4.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-w0Tef5ZCJK1mlJorcSjItCSbyvVuqpvyWdxZiVQmE6fvSJR83wZof42ux0+sfWD+I7rHSfj+f9nzhNaEWClysw==} peerDependencies: '@emotion/react': ^11.0.0 @@ -2566,13 +2356,13 @@ packages: react: '>=18' react-dom: '>=18' dependencies: - '@chakra-ui/css-reset': 2.3.0(@emotion/react@11.11.4)(react@18.3.1) + '@chakra-ui/css-reset': 2.3.0(@emotion/react@11.13.0)(react@18.3.1) '@chakra-ui/portal': 2.1.0(react-dom@18.3.1)(react@18.3.1) '@chakra-ui/react-env': 3.1.0(react@18.3.1) - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) '@chakra-ui/utils': 2.0.15 - '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) - '@emotion/styled': 11.11.5(@emotion/react@11.13.0)(@types/react@18.3.3)(react@18.3.1) + '@emotion/react': 11.13.0(@types/react@18.3.3)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.0)(@types/react@18.3.3)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false @@ -2588,7 +2378,7 @@ packages: '@chakra-ui/react-types': 2.0.7(react@18.3.1) '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) '@zag-js/focus-visible': 0.16.0 react: 18.3.1 dev: false @@ -2788,78 +2578,7 @@ packages: react: 18.3.1 dev: false - /@chakra-ui/react@2.8.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.3.1)(framer-motion@11.1.8)(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-Hn0moyxxyCDKuR9ywYpqgX8dvjqwu9ArwpIb9wHNYjnODETjLwazgNIliCVBRcJvysGRiV51U2/JtJVrpeCjUQ==} - peerDependencies: - '@emotion/react': ^11.0.0 - '@emotion/styled': ^11.0.0 - framer-motion: '>=4.0.0' - react: '>=18' - react-dom: '>=18' - dependencies: - '@chakra-ui/accordion': 2.3.1(@chakra-ui/system@2.6.2)(framer-motion@11.1.8)(react@18.3.1) - '@chakra-ui/alert': 2.2.2(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/avatar': 2.3.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/breadcrumb': 2.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/button': 2.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/card': 2.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/checkbox': 2.3.2(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/close-button': 2.1.1(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/control-box': 2.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/counter': 2.1.0(react@18.3.1) - '@chakra-ui/css-reset': 2.3.0(@emotion/react@11.11.4)(react@18.3.1) - '@chakra-ui/editable': 3.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/focus-lock': 2.1.0(@types/react@18.3.1)(react@18.3.1) - '@chakra-ui/form-control': 2.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/hooks': 2.2.1(react@18.3.1) - '@chakra-ui/icon': 3.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/image': 2.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/input': 2.1.2(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/layout': 2.3.1(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/live-region': 2.1.0(react@18.3.1) - '@chakra-ui/media-query': 3.3.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/menu': 2.2.1(@chakra-ui/system@2.6.2)(framer-motion@11.1.8)(react@18.3.1) - '@chakra-ui/modal': 2.3.1(@chakra-ui/system@2.6.2)(@types/react@18.3.1)(framer-motion@11.1.8)(react-dom@18.3.1)(react@18.3.1) - '@chakra-ui/number-input': 2.1.2(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/pin-input': 2.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/popover': 2.2.1(@chakra-ui/system@2.6.2)(framer-motion@11.1.8)(react@18.3.1) - '@chakra-ui/popper': 3.1.0(react@18.3.1) - '@chakra-ui/portal': 2.1.0(react-dom@18.3.1)(react@18.3.1) - '@chakra-ui/progress': 2.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/provider': 2.4.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react-dom@18.3.1)(react@18.3.1) - '@chakra-ui/radio': 2.1.2(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/react-env': 3.1.0(react@18.3.1) - '@chakra-ui/select': 2.1.2(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/skeleton': 2.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/skip-nav': 2.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/slider': 2.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/spinner': 2.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/stat': 2.1.1(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/stepper': 2.3.1(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/styled-system': 2.9.2 - '@chakra-ui/switch': 2.1.2(@chakra-ui/system@2.6.2)(framer-motion@11.1.8)(react@18.3.1) - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) - '@chakra-ui/table': 2.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/tabs': 3.0.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/tag': 3.1.1(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/textarea': 2.1.2(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/theme': 3.3.1(@chakra-ui/styled-system@2.9.2) - '@chakra-ui/theme-utils': 2.0.21 - '@chakra-ui/toast': 7.0.2(@chakra-ui/system@2.6.2)(framer-motion@11.1.8)(react-dom@18.3.1)(react@18.3.1) - '@chakra-ui/tooltip': 2.3.1(@chakra-ui/system@2.6.2)(framer-motion@11.1.8)(react-dom@18.3.1)(react@18.3.1) - '@chakra-ui/transition': 2.1.0(framer-motion@11.1.8)(react@18.3.1) - '@chakra-ui/utils': 2.0.15 - '@chakra-ui/visually-hidden': 2.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@emotion/react': 11.11.4(@types/react@18.3.1)(react@18.3.1) - '@emotion/styled': 11.11.5(@emotion/react@11.11.4)(@types/react@18.3.1)(react@18.3.1) - framer-motion: 11.1.8(react-dom@18.3.1)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - transitivePeerDependencies: - - '@types/react' - dev: false - - /@chakra-ui/react@2.8.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.3.3)(framer-motion@10.18.0)(react-dom@18.3.1)(react@18.3.1): + /@chakra-ui/react@2.8.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(@types/react@18.3.3)(framer-motion@10.18.0)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-Hn0moyxxyCDKuR9ywYpqgX8dvjqwu9ArwpIb9wHNYjnODETjLwazgNIliCVBRcJvysGRiV51U2/JtJVrpeCjUQ==} peerDependencies: '@emotion/react': ^11.0.0 @@ -2878,7 +2597,7 @@ packages: '@chakra-ui/close-button': 2.1.1(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/control-box': 2.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/counter': 2.1.0(react@18.3.1) - '@chakra-ui/css-reset': 2.3.0(@emotion/react@11.11.4)(react@18.3.1) + '@chakra-ui/css-reset': 2.3.0(@emotion/react@11.13.0)(react@18.3.1) '@chakra-ui/editable': 3.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/focus-lock': 2.1.0(@types/react@18.3.3)(react@18.3.1) '@chakra-ui/form-control': 2.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) @@ -2897,7 +2616,7 @@ packages: '@chakra-ui/popper': 3.1.0(react@18.3.1) '@chakra-ui/portal': 2.1.0(react-dom@18.3.1)(react@18.3.1) '@chakra-ui/progress': 2.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/provider': 2.4.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react-dom@18.3.1)(react@18.3.1) + '@chakra-ui/provider': 2.4.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react-dom@18.3.1)(react@18.3.1) '@chakra-ui/radio': 2.1.2(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/react-env': 3.1.0(react@18.3.1) '@chakra-ui/select': 2.1.2(@chakra-ui/system@2.6.2)(react@18.3.1) @@ -2909,7 +2628,7 @@ packages: '@chakra-ui/stepper': 2.3.1(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/styled-system': 2.9.2 '@chakra-ui/switch': 2.1.2(@chakra-ui/system@2.6.2)(framer-motion@10.18.0)(react@18.3.1) - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) '@chakra-ui/table': 2.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/tabs': 3.0.0(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/tag': 3.1.1(@chakra-ui/system@2.6.2)(react@18.3.1) @@ -2921,8 +2640,8 @@ packages: '@chakra-ui/transition': 2.1.0(framer-motion@10.18.0)(react@18.3.1) '@chakra-ui/utils': 2.0.15 '@chakra-ui/visually-hidden': 2.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) - '@emotion/styled': 11.11.5(@emotion/react@11.13.0)(@types/react@18.3.3)(react@18.3.1) + '@emotion/react': 11.13.0(@types/react@18.3.3)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.0)(@types/react@18.3.3)(react@18.3.1) framer-motion: 10.18.0(react-dom@18.3.1)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -2938,7 +2657,7 @@ packages: dependencies: '@chakra-ui/form-control': 2.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2955,7 +2674,7 @@ packages: '@chakra-ui/media-query': 3.3.0(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/react-use-previous': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2965,7 +2684,7 @@ packages: '@chakra-ui/system': '>=2.0.0' react: '>=18' dependencies: - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2985,7 +2704,7 @@ packages: '@chakra-ui/react-use-pan-event': 2.1.0(react@18.3.1) '@chakra-ui/react-use-size': 2.1.0(react@18.3.1) '@chakra-ui/react-use-update-effect': 2.1.0(react@18.3.1) - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -2996,7 +2715,7 @@ packages: react: '>=18' dependencies: '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -3009,7 +2728,7 @@ packages: '@chakra-ui/icon': 3.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/react-context': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -3022,7 +2741,7 @@ packages: '@chakra-ui/icon': 3.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/react-context': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -3043,45 +2762,12 @@ packages: dependencies: '@chakra-ui/checkbox': 2.3.2(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) framer-motion: 10.18.0(react-dom@18.3.1)(react@18.3.1) react: 18.3.1 dev: false - /@chakra-ui/switch@2.1.2(@chakra-ui/system@2.6.2)(framer-motion@11.1.8)(react@18.3.1): - resolution: {integrity: sha512-pgmi/CC+E1v31FcnQhsSGjJnOE2OcND4cKPyTE+0F+bmGm48Q/b5UmKD9Y+CmZsrt/7V3h8KNczowupfuBfIHA==} - peerDependencies: - '@chakra-ui/system': '>=2.0.0' - framer-motion: '>=4.0.0' - react: '>=18' - dependencies: - '@chakra-ui/checkbox': 2.3.2(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) - framer-motion: 11.1.8(react-dom@18.3.1)(react@18.3.1) - react: 18.3.1 - dev: false - - /@chakra-ui/system@2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1): - resolution: {integrity: sha512-EGtpoEjLrUu4W1fHD+a62XR+hzC5YfsWm+6lO0Kybcga3yYEij9beegO0jZgug27V+Rf7vns95VPVP6mFd/DEQ==} - peerDependencies: - '@emotion/react': ^11.0.0 - '@emotion/styled': ^11.0.0 - react: '>=18' - dependencies: - '@chakra-ui/color-mode': 2.2.0(react@18.3.1) - '@chakra-ui/object-utils': 2.1.0 - '@chakra-ui/react-utils': 2.0.12(react@18.3.1) - '@chakra-ui/styled-system': 2.9.2 - '@chakra-ui/theme-utils': 2.0.21 - '@chakra-ui/utils': 2.0.15 - '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) - '@emotion/styled': 11.11.5(@emotion/react@11.13.0)(@types/react@18.3.3)(react@18.3.1) - react: 18.3.1 - react-fast-compare: 3.2.2 - dev: false - - /@chakra-ui/system@2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.11.5)(react@18.3.1): + /@chakra-ui/system@2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1): resolution: {integrity: sha512-EGtpoEjLrUu4W1fHD+a62XR+hzC5YfsWm+6lO0Kybcga3yYEij9beegO0jZgug27V+Rf7vns95VPVP6mFd/DEQ==} peerDependencies: '@emotion/react': ^11.0.0 @@ -3095,7 +2781,7 @@ packages: '@chakra-ui/theme-utils': 2.0.21 '@chakra-ui/utils': 2.0.15 '@emotion/react': 11.13.0(@types/react@18.3.3)(react@18.3.1) - '@emotion/styled': 11.11.5(@emotion/react@11.13.0)(@types/react@18.3.3)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.0)(@types/react@18.3.3)(react@18.3.1) react: 18.3.1 react-fast-compare: 3.2.2 dev: false @@ -3108,7 +2794,7 @@ packages: dependencies: '@chakra-ui/react-context': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -3127,7 +2813,7 @@ packages: '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1) '@chakra-ui/react-use-safe-layout-effect': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -3139,7 +2825,7 @@ packages: dependencies: '@chakra-ui/icon': 3.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/react-context': 2.1.0(react@18.3.1) - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -3151,7 +2837,7 @@ packages: dependencies: '@chakra-ui/form-control': 2.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -3202,36 +2888,13 @@ packages: '@chakra-ui/react-use-update-effect': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 '@chakra-ui/styled-system': 2.9.2 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) '@chakra-ui/theme': 3.3.1(@chakra-ui/styled-system@2.9.2) framer-motion: 10.18.0(react-dom@18.3.1)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false - /@chakra-ui/toast@7.0.2(@chakra-ui/system@2.6.2)(framer-motion@11.1.8)(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-yvRP8jFKRs/YnkuE41BVTq9nB2v/KDRmje9u6dgDmE5+1bFt3bwjdf9gVbif4u5Ve7F7BGk5E093ARRVtvLvXA==} - peerDependencies: - '@chakra-ui/system': 2.6.2 - framer-motion: '>=4.0.0' - react: '>=18' - react-dom: '>=18' - dependencies: - '@chakra-ui/alert': 2.2.2(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/close-button': 2.1.1(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/portal': 2.1.0(react-dom@18.3.1)(react@18.3.1) - '@chakra-ui/react-context': 2.1.0(react@18.3.1) - '@chakra-ui/react-use-timeout': 2.1.0(react@18.3.1) - '@chakra-ui/react-use-update-effect': 2.1.0(react@18.3.1) - '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/styled-system': 2.9.2 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) - '@chakra-ui/theme': 3.3.1(@chakra-ui/styled-system@2.9.2) - framer-motion: 11.1.8(react-dom@18.3.1)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - dev: false - /@chakra-ui/tooltip@2.3.1(@chakra-ui/system@2.6.2)(framer-motion@10.18.0)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-Rh39GBn/bL4kZpuEMPPRwYNnccRCL+w9OqamWHIB3Qboxs6h8cOyXfIdGxjo72lvhu1QI/a4KFqkM3St+WfC0A==} peerDependencies: @@ -3248,34 +2911,12 @@ packages: '@chakra-ui/react-use-event-listener': 2.1.0(react@18.3.1) '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1) '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) framer-motion: 10.18.0(react-dom@18.3.1)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false - /@chakra-ui/tooltip@2.3.1(@chakra-ui/system@2.6.2)(framer-motion@11.1.8)(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-Rh39GBn/bL4kZpuEMPPRwYNnccRCL+w9OqamWHIB3Qboxs6h8cOyXfIdGxjo72lvhu1QI/a4KFqkM3St+WfC0A==} - peerDependencies: - '@chakra-ui/system': '>=2.0.0' - framer-motion: '>=4.0.0' - react: '>=18' - react-dom: '>=18' - dependencies: - '@chakra-ui/dom-utils': 2.1.0 - '@chakra-ui/popper': 3.1.0(react@18.3.1) - '@chakra-ui/portal': 2.1.0(react-dom@18.3.1)(react@18.3.1) - '@chakra-ui/react-types': 2.0.7(react@18.3.1) - '@chakra-ui/react-use-disclosure': 2.1.0(react@18.3.1) - '@chakra-ui/react-use-event-listener': 2.1.0(react@18.3.1) - '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1) - '@chakra-ui/shared-utils': 2.0.5 - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) - framer-motion: 11.1.8(react-dom@18.3.1)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - dev: false - /@chakra-ui/transition@2.1.0(framer-motion@10.18.0)(react@18.3.1): resolution: {integrity: sha512-orkT6T/Dt+/+kVwJNy7zwJ+U2xAZ3EU7M3XCs45RBvUnZDr/u9vdmaM/3D/rOpmQJWgQBwKPJleUXrYWUagEDQ==} peerDependencies: @@ -3287,17 +2928,6 @@ packages: react: 18.3.1 dev: false - /@chakra-ui/transition@2.1.0(framer-motion@11.1.8)(react@18.3.1): - resolution: {integrity: sha512-orkT6T/Dt+/+kVwJNy7zwJ+U2xAZ3EU7M3XCs45RBvUnZDr/u9vdmaM/3D/rOpmQJWgQBwKPJleUXrYWUagEDQ==} - peerDependencies: - framer-motion: '>=4.0.0' - react: '>=18' - dependencies: - '@chakra-ui/shared-utils': 2.0.5 - framer-motion: 11.1.8(react-dom@18.3.1)(react@18.3.1) - react: 18.3.1 - dev: false - /@chakra-ui/transition@2.1.0(framer-motion@11.3.24)(react@18.3.1): resolution: {integrity: sha512-orkT6T/Dt+/+kVwJNy7zwJ+U2xAZ3EU7M3XCs45RBvUnZDr/u9vdmaM/3D/rOpmQJWgQBwKPJleUXrYWUagEDQ==} peerDependencies: @@ -3324,7 +2954,7 @@ packages: '@chakra-ui/system': '>=2.0.0' react: '>=18' dependencies: - '@chakra-ui/system': 2.6.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) react: 18.3.1 dev: false @@ -3457,10 +3087,10 @@ packages: dev: false optional: true - /@emotion/is-prop-valid@1.2.2: - resolution: {integrity: sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==} + /@emotion/is-prop-valid@1.3.0: + resolution: {integrity: sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==} dependencies: - '@emotion/memoize': 0.8.1 + '@emotion/memoize': 0.9.0 dev: false /@emotion/memoize@0.7.4: @@ -3477,27 +3107,6 @@ packages: resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} dev: false - /@emotion/react@11.11.4(@types/react@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==} - peerDependencies: - '@types/react': '*' - react: '>=16.8.0' - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.5 - '@emotion/babel-plugin': 11.11.0 - '@emotion/cache': 11.11.0 - '@emotion/serialize': 1.1.4 - '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.3.1) - '@emotion/utils': 1.2.1 - '@emotion/weak-memoize': 0.3.1 - '@types/react': 18.3.1 - hoist-non-react-statics: 3.3.2 - react: 18.3.1 - dev: false - /@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1): resolution: {integrity: sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==} peerDependencies: @@ -3570,8 +3179,8 @@ packages: resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} dev: false - /@emotion/styled@11.11.5(@emotion/react@11.11.4)(@types/react@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ==} + /@emotion/styled@11.13.0(@emotion/react@11.13.0)(@types/react@18.3.3)(react@18.3.1): + resolution: {integrity: sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==} peerDependencies: '@emotion/react': ^11.0.0-rc.0 '@types/react': '*' @@ -3580,36 +3189,17 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.24.5 - '@emotion/babel-plugin': 11.11.0 - '@emotion/is-prop-valid': 1.2.2 - '@emotion/react': 11.11.4(@types/react@18.3.1)(react@18.3.1) - '@emotion/serialize': 1.1.4 - '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.3.1) - '@emotion/utils': 1.2.1 - '@types/react': 18.3.1 - react: 18.3.1 - dev: false - - /@emotion/styled@11.11.5(@emotion/react@11.13.0)(@types/react@18.3.3)(react@18.3.1): - resolution: {integrity: sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ==} - peerDependencies: - '@emotion/react': ^11.0.0-rc.0 - '@types/react': '*' - react: '>=16.8.0' - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.24.5 - '@emotion/babel-plugin': 11.11.0 - '@emotion/is-prop-valid': 1.2.2 + '@babel/runtime': 7.25.0 + '@emotion/babel-plugin': 11.12.0 + '@emotion/is-prop-valid': 1.3.0 '@emotion/react': 11.13.0(@types/react@18.3.3)(react@18.3.1) - '@emotion/serialize': 1.1.4 - '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.3.1) - '@emotion/utils': 1.2.1 + '@emotion/serialize': 1.3.0 + '@emotion/use-insertion-effect-with-fallbacks': 1.1.0(react@18.3.1) + '@emotion/utils': 1.4.0 '@types/react': 18.3.3 react: 18.3.1 + transitivePeerDependencies: + - supports-color dev: false /@emotion/unitless@0.8.1: @@ -3902,13 +3492,6 @@ packages: '@floating-ui/utils': 0.2.2 dev: false - /@floating-ui/dom@1.5.4: - resolution: {integrity: sha512-jByEsHIY+eEdCjnTVu+E3ephzTOzkQ8hgUfGwos+bg7NlH33Zc5uO+QHz1mrQUOgIKKDD1RtS201P9NvAfq3XQ==} - dependencies: - '@floating-ui/core': 1.6.1 - '@floating-ui/utils': 0.2.2 - dev: false - /@floating-ui/dom@1.6.5: resolution: {integrity: sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==} dependencies: @@ -3944,24 +3527,6 @@ packages: resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} dev: true - /@internationalized/date@3.5.3: - resolution: {integrity: sha512-X9bi8NAEHAjD8yzmPYT2pdJsbe+tYSEBAfowtlxJVJdZR3aK8Vg7ZUT1Fm5M47KLzp/M1p1VwAaeSma3RT7biw==} - dependencies: - '@swc/helpers': 0.5.11 - dev: false - - /@internationalized/date@3.5.5: - resolution: {integrity: sha512-H+CfYvOZ0LTJeeLOqm19E3uj/4YjrmOFtBufDHPfvtI80hFAMqtrp7oCACpe4Cil5l8S0Qu/9dYfZc/5lY8WQQ==} - dependencies: - '@swc/helpers': 0.5.12 - dev: false - - /@internationalized/number@3.5.2: - resolution: {integrity: sha512-4FGHTi0rOEX1giSkt5MH4/te0eHBq3cvAYsfLlpguV6pzJAReXymiYpE5wPCqKqjkUO3PIsyvk+tBiIV1pZtbA==} - dependencies: - '@swc/helpers': 0.5.11 - dev: false - /@invoke-ai/eslint-config-react@0.0.14(eslint@8.57.0)(prettier@3.3.3)(typescript@5.5.4): resolution: {integrity: sha512-6ZUY9zgdDhv2WUoLdDKOQdU9ImnH0CBOFtRlOaNOh34IOsNRfn+JA7wqA0PKnkiNrlfPkIQWhn4GRJp68NT5bw==} peerDependencies: @@ -3996,34 +3561,33 @@ packages: prettier: 3.3.3 dev: true - /@invoke-ai/ui-library@0.0.25(@chakra-ui/form-control@2.2.0)(@chakra-ui/icon@3.2.0)(@chakra-ui/media-query@3.3.0)(@chakra-ui/menu@2.2.1)(@chakra-ui/spinner@2.1.0)(@chakra-ui/system@2.6.2)(@fontsource-variable/inter@5.0.20)(@internationalized/date@3.5.5)(@types/react@18.3.3)(i18next@23.12.2)(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-Fmjdlu62NXHgairYXGjcuCrxPEAl1G6Q6ban8g3excF6pDDdBeS7CmSNCyEDMxnSIOZrQlI04OhaMB17Imi9Uw==} + /@invoke-ai/ui-library@0.0.29(@chakra-ui/form-control@2.2.0)(@chakra-ui/icon@3.2.0)(@chakra-ui/media-query@3.3.0)(@chakra-ui/menu@2.2.1)(@chakra-ui/spinner@2.1.0)(@chakra-ui/system@2.6.2)(@fontsource-variable/inter@5.0.20)(@types/react@18.3.3)(i18next@23.12.2)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-7SYOaiEEKk9iHk0hg2R2yVxiuV3I1x6bDEv0R3Y2tCH/Aq5XDG2tR+d7SQAPqf5+za3S+qfNFjbjl7GvEMwqmA==} peerDependencies: '@fontsource-variable/inter': ^5.0.16 react: ^18.2.0 react-dom: ^18.2.0 dependencies: - '@ark-ui/react': 1.3.0(@internationalized/date@3.5.5)(react-dom@18.3.1)(react@18.3.1) '@chakra-ui/anatomy': 2.2.2 '@chakra-ui/icons': 2.1.1(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/layout': 2.3.1(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/portal': 2.1.0(react-dom@18.3.1)(react@18.3.1) - '@chakra-ui/react': 2.8.2(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.3.3)(framer-motion@10.18.0)(react-dom@18.3.1)(react@18.3.1) + '@chakra-ui/react': 2.8.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(@types/react@18.3.3)(framer-motion@10.18.0)(react-dom@18.3.1)(react@18.3.1) '@chakra-ui/styled-system': 2.9.2 '@chakra-ui/theme-tools': 2.1.2(@chakra-ui/styled-system@2.9.2) - '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) - '@emotion/styled': 11.11.5(@emotion/react@11.13.0)(@types/react@18.3.3)(react@18.3.1) + '@emotion/react': 11.13.0(@types/react@18.3.3)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.0)(@types/react@18.3.3)(react@18.3.1) '@fontsource-variable/inter': 5.0.20 - '@nanostores/react': 0.7.3(nanostores@0.9.5)(react@18.3.1) - chakra-react-select: 4.9.1(@chakra-ui/form-control@2.2.0)(@chakra-ui/icon@3.2.0)(@chakra-ui/layout@2.3.1)(@chakra-ui/media-query@3.3.0)(@chakra-ui/menu@2.2.1)(@chakra-ui/spinner@2.1.0)(@chakra-ui/system@2.6.2)(@emotion/react@11.11.4)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1) + '@nanostores/react': 0.7.3(nanostores@0.11.2)(react@18.3.1) + chakra-react-select: 4.9.1(@chakra-ui/form-control@2.2.0)(@chakra-ui/icon@3.2.0)(@chakra-ui/layout@2.3.1)(@chakra-ui/media-query@3.3.0)(@chakra-ui/menu@2.2.1)(@chakra-ui/spinner@2.1.0)(@chakra-ui/system@2.6.2)(@emotion/react@11.13.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1) framer-motion: 10.18.0(react-dom@18.3.1)(react@18.3.1) lodash-es: 4.17.21 - nanostores: 0.9.5 + nanostores: 0.11.2 overlayscrollbars: 2.10.0 overlayscrollbars-react: 0.5.6(overlayscrollbars@2.10.0)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-i18next: 14.1.3(i18next@23.12.2)(react-dom@18.3.1)(react@18.3.1) + react-i18next: 15.0.1(i18next@23.12.2)(react-dom@18.3.1)(react@18.3.1) react-icons: 5.2.1(react@18.3.1) react-select: 5.8.0(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1) transitivePeerDependencies: @@ -4033,10 +3597,10 @@ packages: - '@chakra-ui/menu' - '@chakra-ui/spinner' - '@chakra-ui/system' - - '@internationalized/date' - '@types/react' - i18next - react-native + - supports-color dev: false /@isaacs/cliui@8.0.2: @@ -4174,17 +3738,6 @@ packages: react: 18.3.1 dev: false - /@nanostores/react@0.7.3(nanostores@0.9.5)(react@18.3.1): - resolution: {integrity: sha512-/XuLAMENRu/Q71biW4AZ4qmU070vkZgiQ28gaTSNRPm2SZF5zGAR81zPE1MaMB4SeOp6ZTst92NBaG75XSspNg==} - engines: {node: ^18.0.0 || >=20.0.0} - peerDependencies: - nanostores: ^0.9.0 || ^0.10.0 || ^0.11.0 - react: '>=18.0.0' - dependencies: - nanostores: 0.9.5 - react: 18.3.1 - dev: false - /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -5199,18 +4752,6 @@ packages: resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} dev: true - /@swc/helpers@0.5.11: - resolution: {integrity: sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==} - dependencies: - tslib: 2.6.2 - dev: false - - /@swc/helpers@0.5.12: - resolution: {integrity: sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==} - dependencies: - tslib: 2.6.3 - dev: false - /@swc/types@0.1.12: resolution: {integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==} dependencies: @@ -5606,15 +5147,15 @@ packages: /@types/lodash.mergewith@4.6.7: resolution: {integrity: sha512-3m+lkO5CLRRYU0fhGRp7zbsGi6+BZj0uTVSwvcKU+nSlhjA9/QRNfuSGnD2mX6hQA7ZbmcCkzk5h4ZYGOtk14A==} dependencies: - '@types/lodash': 4.17.1 + '@types/lodash': 4.17.7 dev: false /@types/lodash@4.17.1: resolution: {integrity: sha512-X+2qazGS3jxLAIz5JDXDzglAF3KpijdhFxlf/V1+hEsOUc+HnWi81L/uv/EvGuV90WY+7mPGFCUDGfQC3Gj95Q==} + dev: true /@types/lodash@4.17.7: resolution: {integrity: sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==} - dev: true /@types/mdx@2.0.13: resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} @@ -5673,13 +5214,6 @@ packages: '@types/react': 18.3.3 dev: false - /@types/react@18.3.1: - resolution: {integrity: sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==} - dependencies: - '@types/prop-types': 15.7.12 - csstype: 3.1.3 - dev: false - /@types/react@18.3.3: resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==} dependencies: @@ -6091,575 +5625,20 @@ packages: tslib: 1.14.1 dev: true - /@zag-js/accordion@0.32.1: - resolution: {integrity: sha512-16beDVpEhXFQsQRMZLmHFruhGphSprJ5XrRu6+OM2U7aTulo1w3ENUd9uI+mIs4oTVO66lYI4Lp+dFcT2UUIYA==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/anatomy@0.32.1: - resolution: {integrity: sha512-bR+tfFfkbxwhBzGGjEQG+RUnbeCjMx7tWJxykGnGdVLwAh0wKTQBEfHEOCOQh5qU8RhKUieqemAdvc7oP3Tp4w==} - dev: false - - /@zag-js/aria-hidden@0.32.1: - resolution: {integrity: sha512-kznwxvUUHDax8Kd7YNVVCzQcwGARTRaZNOcIkw7MTLE8g/pU+C4pYkwR9iqA7/8imGfjYrZfSsQqZRTb4bkS0g==} - dependencies: - '@zag-js/dom-query': 0.32.1 - dev: false - - /@zag-js/auto-resize@0.32.1: - resolution: {integrity: sha512-MO6N5gPs2xDKbFgrakn6LDWv1GgN8uhfwpsqchLJX+EaZVvLIz8cXFD+jDv3RjK+5GRWV4mIF+26SXuHRSt9Ug==} - dependencies: - '@zag-js/dom-query': 0.32.1 - dev: false - - /@zag-js/avatar@0.32.1: - resolution: {integrity: sha512-5P+95pkMX2Na4yljN1etdgYyA+3HPORjWKn0Y3JamkYIAqJwRFO+taEdSm/xcRkuT6aGA3luheUowjt8wZssyA==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/mutation-observer': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/carousel@0.32.1: - resolution: {integrity: sha512-S7dUrPtiLr42Fa+S3O18kqKVqSu2yuk67bqGDtppIZSaFOugYHK4feBkZqjKw+eF12NVRRVO2j+A40d3MvxbSA==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/checkbox@0.32.1: - resolution: {integrity: sha512-5reRreGyDZ5IlBNd5m1QrYXCehVIl/pmfKMEcAfad5DcgCaHGv5j76eahxbKln/8TEdwz4eWzBrqNtwSkKL5+w==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/form-utils': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - '@zag-js/visually-hidden': 0.32.1 - dev: false - - /@zag-js/collection@0.32.1: - resolution: {integrity: sha512-dAzcVQ/n+xAYoxWB/65/CQinv66RNVuq5ig0fEYszBqP+HjFnOpeGkIrEvP+bFI38hFEViiGtfr6oGAsVByOVQ==} - dev: false - - /@zag-js/color-picker@0.32.1: - resolution: {integrity: sha512-ov3FC+c2WBYmEGRXWFVb2jih2Ecejj5JqBjDL9iMLBs2KNY9jnpvtH7WnZbijNY+RMDBj+C/DNI7K2NVaamSIA==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/color-utils': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dismissable': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/form-utils': 0.32.1 - '@zag-js/popper': 0.32.1 - '@zag-js/tabbable': 0.32.1 - '@zag-js/text-selection': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - '@zag-js/visually-hidden': 0.32.1 - dev: false - - /@zag-js/color-utils@0.32.1: - resolution: {integrity: sha512-AzupfOD7oD0mE+H9roTzwnLqtw1wYiJGOQKLPAwdwPQdznJUQD6sMOpxR/6RBuITVTm8Bl12Mr4+7s29LVJruw==} - dependencies: - '@zag-js/numeric-range': 0.32.1 - dev: false - - /@zag-js/combobox@0.32.1: - resolution: {integrity: sha512-skz2C5UxLD5JoYNP4hcPaQJu2cW7vycKqjDNI9ZtygSkZHOHx+JxpYiACBnr1vqzXatIOuDQm/HUuWW9yOT4eA==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/aria-hidden': 0.32.1 - '@zag-js/collection': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dismissable': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/mutation-observer': 0.32.1 - '@zag-js/popper': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/core@0.32.1: - resolution: {integrity: sha512-F9F7920/CisoLWALQACIhqbMvemgbv86qBULJ+UEe+a/9XgGwPh9UGn/H/q5EWkNpgEapz2b3pl3ONgKmXsK1A==} - dependencies: - '@zag-js/store': 0.32.1 - klona: 2.0.6 - dev: false - - /@zag-js/date-picker@0.32.1: - resolution: {integrity: sha512-n/hYmF+/R4+NuyfPRzCgeuLT6LJihKSuKzK29STPWy3sC/tBBHiqhNv1/4UKbatHUJXdBW2XF+N8Rw08RffcFQ==} - dependencies: - '@internationalized/date': 3.5.3 - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/date-utils': 0.32.1(@internationalized/date@3.5.3) - '@zag-js/dismissable': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/form-utils': 0.32.1 - '@zag-js/live-region': 0.32.1 - '@zag-js/popper': 0.32.1 - '@zag-js/text-selection': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/date-utils@0.32.1(@internationalized/date@3.5.3): - resolution: {integrity: sha512-dbBDRSVr5pRUw3rXndyGuSshZiWqQI5JQO4D2KIFGkXzorj6WzoOpcO910Z7AdM/9cCAMpCjUrka8d8o9BpJBg==} - peerDependencies: - '@internationalized/date': '>=3.0.0' - dependencies: - '@internationalized/date': 3.5.3 - dev: false - - /@zag-js/date-utils@0.32.1(@internationalized/date@3.5.5): - resolution: {integrity: sha512-dbBDRSVr5pRUw3rXndyGuSshZiWqQI5JQO4D2KIFGkXzorj6WzoOpcO910Z7AdM/9cCAMpCjUrka8d8o9BpJBg==} - peerDependencies: - '@internationalized/date': '>=3.0.0' - dependencies: - '@internationalized/date': 3.5.5 - dev: false - - /@zag-js/dialog@0.32.1: - resolution: {integrity: sha512-czp+qXcdAOM70SrvDo4gBpYZx6gS6HXyrpiptW3+EHa2eiCfc/Z2w+Nu+ZadOTEQGgNWlKlCLW7Ery0i9mMDsw==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/aria-hidden': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dismissable': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/remove-scroll': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - focus-trap: 7.5.4 - dev: false - - /@zag-js/dismissable@0.32.1: - resolution: {integrity: sha512-UIkG+9Eb5wrus2F2Dy4zqk0pwCV53sdnMYBxk9dpvDzBJHzW+InhVeg3UeKmPL8ELcYlhH/Bap99XCRJvxsXow==} - dependencies: - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/interact-outside': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/dom-event@0.32.1: - resolution: {integrity: sha512-wN6f5Kkf7C/YFN3wbEG3gUockSebyy1fPNL2BuL4C8PIP8vOD14hnHTzZWg5yYfO+veybIAL38r8I46C+bOVBQ==} - dependencies: - '@zag-js/text-selection': 0.32.1 - '@zag-js/types': 0.32.1 - dev: false - /@zag-js/dom-query@0.16.0: resolution: {integrity: sha512-Oqhd6+biWyKnhKwFFuZrrf6lxBz2tX2pRQe6grUnYwO6HJ8BcbqZomy2lpOdr+3itlaUqx+Ywj5E5ZZDr/LBfQ==} dev: false - /@zag-js/dom-query@0.32.1: - resolution: {integrity: sha512-u6hrQHQ0/dcUi6xJn8d2Mu1ClN4KZpPqOKrJFSaxadWjSy+x0qp48WY2CBQ6gZ3j8IwR/XjzU9bu9wY5jJfHgA==} - dev: false - - /@zag-js/editable@0.32.1: - resolution: {integrity: sha512-QEGnfp2P9nWVp9vGNWtszspvQcF3KtBRToZrv5/DT30Mpo/uPDKtqijLs0SnB/W60ELzcIRhK4J9taGoK8O8uw==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/form-utils': 0.32.1 - '@zag-js/interact-outside': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/element-rect@0.32.1: - resolution: {integrity: sha512-tAmxgxU2LsByK8PIs/Cj6cBJ8xZCVXE9RoStxthhuPL7xKYUfZvFGuhHVOHTHd6sDKEqbj6K1ds/TGPuglIh4w==} - dev: false - /@zag-js/element-size@0.10.5: resolution: {integrity: sha512-uQre5IidULANvVkNOBQ1tfgwTQcGl4hliPSe69Fct1VfYb2Fd0jdAcGzqQgPhfrXFpR62MxLPB7erxJ/ngtL8w==} dev: false - /@zag-js/element-size@0.32.1: - resolution: {integrity: sha512-ACklufmJQpah2UqwZUlYFaKi6uWfZBeTghtbfYHcDfzRbg2Hni612v8L1JeS4vAgjeDpcdHQpXXR4AZSpGZgNw==} - dev: false - - /@zag-js/file-upload@0.32.1: - resolution: {integrity: sha512-cD0NRIDof9Vv2DemmnYe9ZPZxOZ6b8XZl8eq4G0e8+WLYtnRXyEURl8Dw0QJpfdDPQaHnnD4CNxPTQcLgP+9Sg==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/file-utils': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - '@zag-js/visually-hidden': 0.32.1 - dev: false - - /@zag-js/file-utils@0.32.1: - resolution: {integrity: sha512-0PxTrljW51Lf9OCuYNlZuaLgF0v1NoVRzXa/osZ9HGceQjfo77R5G9u+/TP3u53W2PTxajEZ4eNzTibgpzNXFg==} - dev: false - /@zag-js/focus-visible@0.16.0: resolution: {integrity: sha512-a7U/HSopvQbrDU4GLerpqiMcHKEkQkNPeDZJWz38cw/6Upunh41GjHetq5TB84hxyCaDzJ6q2nEdNoBQfC0FKA==} dependencies: '@zag-js/dom-query': 0.16.0 dev: false - /@zag-js/form-utils@0.32.1: - resolution: {integrity: sha512-OemLBlHCHHm7t8wNcf78FRudRA7FegSgsNEzAjrRTyx+lJztDyHRLaoyI1gCEIg+0Kzl2nMxjOl4MStGsDj8iw==} - dependencies: - '@zag-js/mutation-observer': 0.32.1 - dev: false - - /@zag-js/hover-card@0.32.1: - resolution: {integrity: sha512-k66YK0z0P4LuK78+jnRoUPxJiM9GA0sbEEz3oPlvcFVXMMwnRTPNIw1OjksfAPI+Nvgg7H6D3A+7HCdRI/oBjw==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dismissable': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/popper': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/interact-outside@0.32.1: - resolution: {integrity: sha512-8zHuswfTAgfMCaQnp3N4WStvnL32VyxURafb21+mE4neAF/DaKfJHWnJpeUMG1Qh/eXsrMRBxVoX+nBMhHj9bg==} - dependencies: - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/tabbable': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/live-region@0.32.1: - resolution: {integrity: sha512-6/9QMLVZbTRh/G6MoJc/auN8r5vjdY9vUgNT680C2LOa2vnRR5/y0DkIpVgttNh1rSenQ/eLEYxp8hQF1rIYNw==} - dependencies: - '@zag-js/visually-hidden': 0.32.1 - dev: false - - /@zag-js/menu@0.32.1: - resolution: {integrity: sha512-IPsTljVF0N9xTwub1cpGl3GAG5ttAq3h38PdZERREzT3qRgw4v3K/I1TG2vIiDXgJz8UZzUKox6ZYdU7UIAkRA==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dismissable': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/mutation-observer': 0.32.1 - '@zag-js/popper': 0.32.1 - '@zag-js/rect-utils': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/mutation-observer@0.32.1: - resolution: {integrity: sha512-/hlObxGnhAaYYVnwRJC227md0M3kSE6mO24vkqVGwq2GglS+u4zbVcBBUuWgHdMML+ZjIQrZuVycCBMfVlHq0g==} - dev: false - - /@zag-js/number-input@0.32.1: - resolution: {integrity: sha512-atyIOvoMITb4hZtQym7yD6I7grvPW83UeMFO8hCQg3HWwd2zR4+63mouWuyMoWb4QrzVFRVQBaU8OG5xGlknEw==} - dependencies: - '@internationalized/number': 3.5.2 - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/form-utils': 0.32.1 - '@zag-js/mutation-observer': 0.32.1 - '@zag-js/number-utils': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/number-utils@0.32.1: - resolution: {integrity: sha512-x/nttU31TtFVTqFBM8e3ZH/0MCc+u15WAfk0rT6ESkoZcdb80rTzZVMokCKCUdpi/JdB1vjEeCLSnj+ig8oAIQ==} - dev: false - - /@zag-js/numeric-range@0.32.1: - resolution: {integrity: sha512-1Qe2URTenlrdsWuArlnQ+v5bBH2mHZD3XsK6jYV+C2lgatVzdcoN4GCSNTiF7w+So6J+NTeLMkVHMGCW1Kzx1g==} - dev: false - - /@zag-js/pagination@0.32.1: - resolution: {integrity: sha512-lhogzKxJnx5D2Xoni/xm5rkOuy15KWSxqBHVwe8+j5aSNqMy7+aRtEN2F2VQCDVL/v1fdciQvOCA9udm37kZ4w==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/pin-input@0.32.1: - resolution: {integrity: sha512-d18cCXKUr7INL0Xm5KyIoiTRSNsPXfIlIEMl2HrAvM3r70wtEag0PmiDNA5NS2tB4LnnX0XowchGB4HsdFS/ng==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/form-utils': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - '@zag-js/visually-hidden': 0.32.1 - dev: false - - /@zag-js/popover@0.32.1: - resolution: {integrity: sha512-B01if49v3crCjkvtSvIX4CBdT/475nj3DttOObc36s0YOxCEt3UihMITBD5JvIKwEqjZ6oU5t0sLcUYOqQ4f2A==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/aria-hidden': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dismissable': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/popper': 0.32.1 - '@zag-js/remove-scroll': 0.32.1 - '@zag-js/tabbable': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - focus-trap: 7.5.4 - dev: false - - /@zag-js/popper@0.32.1: - resolution: {integrity: sha512-aQgogW1N4VreNACSQhXQoZeXtQQtB//FXUvt1CBnW2DtmZ6YkNnaAfn186Q2lkw2/T0chITRy3eYeviwMmMrqg==} - dependencies: - '@floating-ui/dom': 1.5.4 - '@zag-js/dom-query': 0.32.1 - '@zag-js/element-rect': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/presence@0.32.1: - resolution: {integrity: sha512-8189QMUf/L1dztAZdurx18ZwPyWlq58Mrd+GdATSaf8JstgrI1ovzVs606inQghWptKHMsH7dUIaV9UkhbSx3Q==} - dependencies: - '@zag-js/core': 0.32.1 - '@zag-js/types': 0.32.1 - dev: false - - /@zag-js/progress@0.32.1: - resolution: {integrity: sha512-ClkQvNYnuIpKfAPUceZXY5E2m/3NnIm21cvHe4gAoJ88YdqEHd5rIRoHP63g8ET8Ct/2KkBRkgR+LrQnGQOomA==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/radio-group@0.32.1: - resolution: {integrity: sha512-NvdSjwRF38qIh0oM68jERf71uiwV2JFTrGeQEs3EIqONzULwL6jR2p4P1wm3JJNBAkSYBKZMER5cVUUcqM3kjQ==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/element-rect': 0.32.1 - '@zag-js/form-utils': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - '@zag-js/visually-hidden': 0.32.1 - dev: false - - /@zag-js/rating-group@0.32.1: - resolution: {integrity: sha512-RBaFRCw7P00bgTrEjUHT3h/OGRO8XmXKkQYqqhm1tsVbeTsT47iwHoc6XnMEiGBonaJDwN/J0oFasw7GNg5sow==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/form-utils': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/react@0.32.1(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-b1SB7hXXv1K6CmXkcy5Y7mb0YRWkyvulyhK8VW5O5hIAPuGxOTx70psmVeZbmVzhjdORCiro9jKx8Ec0LfolFg==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - dependencies: - '@zag-js/core': 0.32.1 - '@zag-js/store': 0.32.1 - '@zag-js/types': 0.32.1 - proxy-compare: 2.5.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - dev: false - - /@zag-js/rect-utils@0.32.1: - resolution: {integrity: sha512-cI07kgldjUZP+SLhXeG9VSl47nrENlC96Fs7jWcTfHj62rhdY8WsBJ0tiTztvwar9m1chwxXZwJowHN+nPIgDQ==} - dev: false - - /@zag-js/remove-scroll@0.32.1: - resolution: {integrity: sha512-LyXt2rNMSKb9MKeJRyKTgpk4R7jdA+9kEQTSG5qyA94jo1og7FVgA1W/E+pNkdxDEk1VplL768VU6y7E/L3DHg==} - dependencies: - '@zag-js/dom-query': 0.32.1 - dev: false - - /@zag-js/select@0.32.1: - resolution: {integrity: sha512-jSzmTKCN1Fk/ZDDWM8TVGOtwgpYUDgyceegjYT+hW1mmEetu4tQcEvAr0557NOzh8akqLvcVFbg/kMj0IriKAA==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/collection': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dismissable': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/form-utils': 0.32.1 - '@zag-js/mutation-observer': 0.32.1 - '@zag-js/popper': 0.32.1 - '@zag-js/tabbable': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - '@zag-js/visually-hidden': 0.32.1 - dev: false - - /@zag-js/slider@0.32.1: - resolution: {integrity: sha512-iZSB3Y8/Maakxem0Ha3rBRa8AyAplhN5K50Bgz+wsv0VEzNNUmK4QgaTWReWd6SfeTRpnC5ftKCcfM2aQrLm6g==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/element-size': 0.32.1 - '@zag-js/form-utils': 0.32.1 - '@zag-js/numeric-range': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/splitter@0.32.1: - resolution: {integrity: sha512-NdHLUXtQAlnz6QpdPwcqZCqYul7LaVqsp0hgtXR2PN4HbH+VAaDfY76pUk6LBerUcykChGZvtM9U0A5FCo1x4A==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/number-utils': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/store@0.32.1: - resolution: {integrity: sha512-hKwzpqAPljw06oOI+eO+Is2udpmY9GsGfmdoqvZVYoK4f5sawpZY9EC/84tbK9QKWUDTbFS+0Ujc254GUThmDA==} - dependencies: - proxy-compare: 2.5.1 - dev: false - - /@zag-js/switch@0.32.1: - resolution: {integrity: sha512-+5w/AtINA+jpORX1cuUrnyIFXrfjhqV7667EKK/zbPi0Pf1E10+TEihpfFjY6bgms9CSNWZVEb6w2f2C0PNBDA==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/form-utils': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - '@zag-js/visually-hidden': 0.32.1 - dev: false - - /@zag-js/tabbable@0.32.1: - resolution: {integrity: sha512-fMXtVgBiX7z3Qmdv+McrfihiSkqsDbNX2nn3e63L7jdy9ZpgnR3jG9BwUZvv7hvzkuOAFhhdKgBYYT+fkBavGg==} - dependencies: - '@zag-js/dom-query': 0.32.1 - dev: false - - /@zag-js/tabs@0.32.1: - resolution: {integrity: sha512-5l8/k2Pw9Kbfsvvx6HWcVqK7Ns7ca+nyPGLSZtZLMp/Zn2q3xSG32C1U3oDaYtQVIQSiEHdnMjw0C2v+CxGDMA==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/element-rect': 0.32.1 - '@zag-js/tabbable': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/tags-input@0.32.1: - resolution: {integrity: sha512-oliLhiMpRNbWFixHF+Oe7hySQBp7NKtL/s8rN5dLT1G1GFRMzuuht/QnmL1h8EoGGpTwaaokMo4zl4uVzHbwyw==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/auto-resize': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/form-utils': 0.32.1 - '@zag-js/interact-outside': 0.32.1 - '@zag-js/live-region': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/text-selection@0.32.1: - resolution: {integrity: sha512-aK1uswWYF76PFoxGL+3HW/kth9uldFWSW4lOh89NfEcc6Ym7qS5B+P0HKJVM9DuQbihvQX9dyc9PvM7/LJTSRA==} - dependencies: - '@zag-js/dom-query': 0.32.1 - dev: false - - /@zag-js/toast@0.32.1: - resolution: {integrity: sha512-HrfVzFX7ANS9qOewCr8qOCbgko635bZxYKMv+ojjo4U/TtwkGb43+lVU7/qwZj0z18/OtXBH5YQjFwQZXg5x8g==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/toggle-group@0.32.1: - resolution: {integrity: sha512-MM1XI4J45rRCZiDHcMtZWud0+bWMu6IcMnrbd9oig330YAF3RzcjTlxX93YRY35F04OUMBq5el9qe3qc2vyMuw==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/tooltip@0.32.1: - resolution: {integrity: sha512-+rsmDYTELFBHoYKg5iKShGfRD3H9FJDaZRq915Uc9YnyePMXCnWRgnVp+lk3zI+FDgysQm67SDLRJsR24Iioqg==} - dependencies: - '@zag-js/anatomy': 0.32.1 - '@zag-js/core': 0.32.1 - '@zag-js/dom-event': 0.32.1 - '@zag-js/dom-query': 0.32.1 - '@zag-js/popper': 0.32.1 - '@zag-js/types': 0.32.1 - '@zag-js/utils': 0.32.1 - dev: false - - /@zag-js/types@0.32.1: - resolution: {integrity: sha512-BLfqb+im4vtXXJqhd2ZUg/4LquEd1qPt9XN56XVjudGDTftN8n3EDpuail7VKxdL59W4jR7wW8lvl4sSgrQKWw==} - dependencies: - csstype: 3.1.3 - dev: false - - /@zag-js/utils@0.32.1: - resolution: {integrity: sha512-jrcmWYcA3L6TO4fZbPFvpSGEy2Z/mbWt6bPQbmcVgq/BltSS0YxxfPl+eD+S/rZI9aneszwsr04Z5TpladFiVA==} - dev: false - - /@zag-js/visually-hidden@0.32.1: - resolution: {integrity: sha512-Vzieo4vNulzY/0zqmVfeYW/LcFJp5xtEoyUgR1FBctH8uBPBRhTIEXxKtoMablW6/vccOVo7zcu0UrR5Vx+eYQ==} - dev: false - /accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -6794,11 +5773,11 @@ packages: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true - /aria-hidden@1.2.3: - resolution: {integrity: sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==} + /aria-hidden@1.2.4: + resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} engines: {node: '>=10'} dependencies: - tslib: 2.6.2 + tslib: 2.6.3 dev: false /aria-query@5.3.0: @@ -7144,35 +6123,6 @@ packages: type-detect: 4.0.8 dev: true - /chakra-react-select@4.9.1(@chakra-ui/form-control@2.2.0)(@chakra-ui/icon@3.2.0)(@chakra-ui/layout@2.3.1)(@chakra-ui/media-query@3.3.0)(@chakra-ui/menu@2.2.1)(@chakra-ui/spinner@2.1.0)(@chakra-ui/system@2.6.2)(@emotion/react@11.11.4)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-jmgfN+S/wnTaCp3pW30GYDIZ5J8jWcT1gIbhpw6RdKV+atm/U4/sT+gaHOHHhRL8xeaYip+iI/m8MPGREkve0w==} - peerDependencies: - '@chakra-ui/form-control': ^2.0.0 - '@chakra-ui/icon': ^3.0.0 - '@chakra-ui/layout': ^2.0.0 - '@chakra-ui/media-query': ^3.0.0 - '@chakra-ui/menu': ^2.0.0 - '@chakra-ui/spinner': ^2.0.0 - '@chakra-ui/system': ^2.0.0 - '@emotion/react': ^11.8.1 - react: ^18.0.0 - react-dom: ^18.0.0 - dependencies: - '@chakra-ui/form-control': 2.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/icon': 3.2.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/layout': 2.3.1(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/media-query': 3.3.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/menu': 2.2.1(@chakra-ui/system@2.6.2)(framer-motion@11.3.24)(react@18.3.1) - '@chakra-ui/spinner': 2.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.11.5)(react@18.3.1) - '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-select: 5.8.0(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1) - transitivePeerDependencies: - - '@types/react' - dev: false - /chakra-react-select@4.9.1(@chakra-ui/form-control@2.2.0)(@chakra-ui/icon@3.2.0)(@chakra-ui/layout@2.3.1)(@chakra-ui/media-query@3.3.0)(@chakra-ui/menu@2.2.1)(@chakra-ui/spinner@2.1.0)(@chakra-ui/system@2.6.2)(@emotion/react@11.13.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-jmgfN+S/wnTaCp3pW30GYDIZ5J8jWcT1gIbhpw6RdKV+atm/U4/sT+gaHOHHhRL8xeaYip+iI/m8MPGREkve0w==} peerDependencies: @@ -7193,7 +6143,7 @@ packages: '@chakra-ui/media-query': 3.3.0(@chakra-ui/system@2.6.2)(react@18.3.1) '@chakra-ui/menu': 2.2.1(@chakra-ui/system@2.6.2)(framer-motion@11.3.24)(react@18.3.1) '@chakra-ui/spinner': 2.1.0(@chakra-ui/system@2.6.2)(react@18.3.1) - '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.11.5)(react@18.3.1) + '@chakra-ui/system': 2.6.2(@emotion/react@11.13.0)(@emotion/styled@11.13.0)(react@18.3.1) '@emotion/react': 11.13.0(@types/react@18.3.3)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -8615,17 +7565,11 @@ packages: engines: {node: '>=0.4.0'} dev: true - /focus-lock@1.3.3: - resolution: {integrity: sha512-hfXkZha7Xt4RQtrL1HBfspAuIj89Y0fb6GX0dfJilb8S2G/lvL4akPAcHq6xoD2NuZnDMCnZL/zQesMyeu6Psg==} + /focus-lock@1.3.5: + resolution: {integrity: sha512-QFaHbhv9WPUeLYBDe/PAuLKJ4Dd9OPvKs9xZBr3yLXnUrDNaVXKu2baDBXe3naPY30hgHYSsf2JW4jzas2mDEQ==} engines: {node: '>=10'} dependencies: - tslib: 2.6.2 - dev: false - - /focus-trap@7.5.4: - resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==} - dependencies: - tabbable: 6.2.0 + tslib: 2.6.3 dev: false /for-each@0.3.3: @@ -8664,30 +7608,11 @@ packages: dependencies: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - tslib: 2.6.2 + tslib: 2.6.3 optionalDependencies: '@emotion/is-prop-valid': 0.8.8 dev: false - /framer-motion@11.1.8(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-W2OGZmNfUarhh6A/rLXernq/JthjekbgeRWqzigPpbaShe/+HfQKUDSjiEdL302XOlINtO+SCFCiR1hlqN3uOA==} - peerDependencies: - '@emotion/is-prop-valid': '*' - react: ^18.0.0 - react-dom: ^18.0.0 - peerDependenciesMeta: - '@emotion/is-prop-valid': - optional: true - react: - optional: true - react-dom: - optional: true - dependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - tslib: 2.6.2 - dev: false - /framer-motion@11.3.24(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-kl0YI7HwAtyV0VOAWuU/rXoOS8+z5qSkMN6rZS+a9oe6fIha6SC3vjJN6u/hBpvjrg5MQNdSnqnjYxm0WYTX9g==} peerDependencies: @@ -9636,11 +8561,6 @@ packages: engines: {node: '>=6'} dev: true - /klona@2.0.6: - resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} - engines: {node: '>= 8'} - dev: false - /knip@5.27.2(@types/node@20.14.15)(typescript@5.5.4): resolution: {integrity: sha512-Mya1XEDq1oygibQf0uocQd02Fil8RtvNVhcFAcxypjcc6zakT7wsJtS0xvuwEitilfI0tiFC9PghmJQ3DMKuTg==} engines: {node: '>=18.6.0'} @@ -10082,11 +9002,6 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} dev: false - /nanostores@0.9.5: - resolution: {integrity: sha512-Z+p+g8E7yzaWwOe5gEUB2Ox0rCEeXWYIZWmYvw/ajNYX8DlXdMvMDj8DWfM/subqPAcsf8l8Td4iAwO1DeIIRQ==} - engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} - dev: false - /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true @@ -10642,10 +9557,6 @@ packages: ipaddr.js: 1.9.1 dev: true - /proxy-compare@2.5.1: - resolution: {integrity: sha512-oyfc0Tx87Cpwva5ZXezSp5V9vht1c7dZBhvuV/y3ctkgMVUmiAGDVeeB0dKhGSyT0v1ZTEQYpe/RXlBVBNuCLA==} - dev: false - /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -10703,7 +9614,7 @@ packages: peerDependencies: react: ^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 dependencies: - '@babel/runtime': 7.24.1 + '@babel/runtime': 7.25.0 react: 18.3.1 dev: false @@ -10789,8 +9700,8 @@ packages: resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} dev: false - /react-focus-lock@2.11.1(@types/react@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-IXLwnTBrLTlKTpASZXqqXJ8oymWrgAlOfuuDYN4XCuN1YJ72dwX198UCaF1QqGUk5C3QOnlMik//n3ufcfe8Ig==} + /react-focus-lock@2.12.1(@types/react@18.3.3)(react@18.3.1): + resolution: {integrity: sha512-lfp8Dve4yJagkHiFrC1bGtib3mF2ktqwPJw4/WGcgPW+pJ/AVQA5X2vI7xgp13FcxFEpYBBHpXai/N2DBNC0Jw==} peerDependencies: '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -10798,32 +9709,13 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.9 - '@types/react': 18.3.1 - focus-lock: 1.3.3 - prop-types: 15.8.1 - react: 18.3.1 - react-clientside-effect: 1.2.6(react@18.3.1) - use-callback-ref: 1.3.1(@types/react@18.3.1)(react@18.3.1) - use-sidecar: 1.1.2(@types/react@18.3.1)(react@18.3.1) - dev: false - - /react-focus-lock@2.11.1(@types/react@18.3.3)(react@18.3.1): - resolution: {integrity: sha512-IXLwnTBrLTlKTpASZXqqXJ8oymWrgAlOfuuDYN4XCuN1YJ72dwX198UCaF1QqGUk5C3QOnlMik//n3ufcfe8Ig==} - peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.25.0 '@types/react': 18.3.3 - focus-lock: 1.3.3 + focus-lock: 1.3.5 prop-types: 15.8.1 react: 18.3.1 react-clientside-effect: 1.2.6(react@18.3.1) - use-callback-ref: 1.3.1(@types/react@18.3.3)(react@18.3.1) + use-callback-ref: 1.3.2(@types/react@18.3.3)(react@18.3.1) use-sidecar: 1.1.2(@types/react@18.3.3)(react@18.3.1) dev: false @@ -10866,6 +9758,26 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /react-i18next@15.0.1(i18next@23.12.2)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-NwxLqNM6CLbeGA9xPsjits0EnXdKgCRSS6cgkgOdNcPXqL+1fYNl8fBg1wmnnHvFy812Bt4IWTPE9zjoPmFj3w==} + peerDependencies: + i18next: '>= 23.2.3' + react: '>= 16.8.0' + react-dom: '*' + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + dependencies: + '@babel/runtime': 7.25.0 + html-parse-stringify: 3.0.1 + i18next: 23.12.2 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /react-icons@5.2.1(react@18.3.1): resolution: {integrity: sha512-zdbW5GstTzXaVKvGSyTaBalt7HSfuK5ovrzlpyiWHAFXndXTdd/1hdDHI4xBM1Mn7YriT6aqESucFl9kEXzrdw==} peerDependencies: @@ -10935,24 +9847,8 @@ packages: use-sync-external-store: 1.2.2(react@18.3.1) dev: false - /react-remove-scroll-bar@2.3.5(@types/react@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-3cqjOqg6s0XbOjWvmasmqHch+RLxIEk2r/70rzGXuz3iIGQsQheEQyqYCBb5EECoD01Vo2SIbDqW4paLeLTASw==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': 18.3.1 - react: 18.3.1 - react-style-singleton: 2.2.1(@types/react@18.3.1)(react@18.3.1) - tslib: 2.6.2 - dev: false - - /react-remove-scroll-bar@2.3.5(@types/react@18.3.3)(react@18.3.1): - resolution: {integrity: sha512-3cqjOqg6s0XbOjWvmasmqHch+RLxIEk2r/70rzGXuz3iIGQsQheEQyqYCBb5EECoD01Vo2SIbDqW4paLeLTASw==} + /react-remove-scroll-bar@2.3.6(@types/react@18.3.3)(react@18.3.1): + resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} engines: {node: '>=10'} peerDependencies: '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -10964,30 +9860,11 @@ packages: '@types/react': 18.3.3 react: 18.3.1 react-style-singleton: 2.2.1(@types/react@18.3.3)(react@18.3.1) - tslib: 2.6.2 + tslib: 2.6.3 dev: false - /react-remove-scroll@2.5.7(@types/react@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': 18.3.1 - react: 18.3.1 - react-remove-scroll-bar: 2.3.5(@types/react@18.3.1)(react@18.3.1) - react-style-singleton: 2.2.1(@types/react@18.3.1)(react@18.3.1) - tslib: 2.6.2 - use-callback-ref: 1.3.1(@types/react@18.3.1)(react@18.3.1) - use-sidecar: 1.1.2(@types/react@18.3.1)(react@18.3.1) - dev: false - - /react-remove-scroll@2.5.7(@types/react@18.3.3)(react@18.3.1): - resolution: {integrity: sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==} + /react-remove-scroll@2.5.10(@types/react@18.3.3)(react@18.3.1): + resolution: {integrity: sha512-m3zvBRANPBw3qxVVjEIPEQinkcwlFZ4qyomuWVpNJdv4c6MvHfXV0C3L9Jx5rr3HeBHKNRX+1jreB5QloDIJjA==} engines: {node: '>=10'} peerDependencies: '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -10998,10 +9875,10 @@ packages: dependencies: '@types/react': 18.3.3 react: 18.3.1 - react-remove-scroll-bar: 2.3.5(@types/react@18.3.3)(react@18.3.1) + react-remove-scroll-bar: 2.3.6(@types/react@18.3.3)(react@18.3.1) react-style-singleton: 2.2.1(@types/react@18.3.3)(react@18.3.1) - tslib: 2.6.2 - use-callback-ref: 1.3.1(@types/react@18.3.3)(react@18.3.1) + tslib: 2.6.3 + use-callback-ref: 1.3.2(@types/react@18.3.3)(react@18.3.1) use-sidecar: 1.1.2(@types/react@18.3.3)(react@18.3.1) dev: false @@ -11036,23 +9913,6 @@ packages: - '@types/react' dev: false - /react-style-singleton@2.2.1(@types/react@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': 18.3.1 - get-nonce: 1.0.1 - invariant: 2.2.4 - react: 18.3.1 - tslib: 2.6.2 - dev: false - /react-style-singleton@2.2.1(@types/react@18.3.3)(react@18.3.1): resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} engines: {node: '>=10'} @@ -11067,7 +9927,7 @@ packages: get-nonce: 1.0.1 invariant: 2.2.4 react: 18.3.1 - tslib: 2.6.2 + tslib: 2.6.3 dev: false /react-transition-group@4.4.5(react-dom@18.3.1)(react@18.3.1): @@ -12015,10 +10875,6 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - /tabbable@6.2.0: - resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} - dev: false - /tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} @@ -12442,23 +11298,8 @@ packages: punycode: 2.3.1 dev: true - /use-callback-ref@1.3.1(@types/react@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-Lg4Vx1XZQauB42Hw3kK7JM6yjVjgFmFC5/Ab797s79aARomD2nEErc4mCgM8EZrARLmmbWpi5DGCadmK50DcAQ==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': 18.3.1 - react: 18.3.1 - tslib: 2.6.2 - dev: false - - /use-callback-ref@1.3.1(@types/react@18.3.3)(react@18.3.1): - resolution: {integrity: sha512-Lg4Vx1XZQauB42Hw3kK7JM6yjVjgFmFC5/Ab797s79aARomD2nEErc4mCgM8EZrARLmmbWpi5DGCadmK50DcAQ==} + /use-callback-ref@1.3.2(@types/react@18.3.3)(react@18.3.1): + resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} engines: {node: '>=10'} peerDependencies: '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -12469,7 +11310,7 @@ packages: dependencies: '@types/react': 18.3.3 react: 18.3.1 - tslib: 2.6.2 + tslib: 2.6.3 dev: false /use-debounce@10.0.2(react@18.3.1): @@ -12512,22 +11353,6 @@ packages: react: 18.3.1 dev: false - /use-sidecar@1.1.2(@types/react@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': 18.3.1 - detect-node-es: 1.1.0 - react: 18.3.1 - tslib: 2.6.2 - dev: false - /use-sidecar@1.1.2(@types/react@18.3.3)(react@18.3.1): resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} engines: {node: '>=10'} @@ -12541,7 +11366,7 @@ packages: '@types/react': 18.3.3 detect-node-es: 1.1.0 react: 18.3.1 - tslib: 2.6.2 + tslib: 2.6.3 dev: false /use-sync-external-store@1.2.0(react@18.3.1): diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index a784f99b70..5b99a7c11e 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -1689,6 +1689,42 @@ "missingUpscaleModel": "Missing upscale model", "missingTileControlNetModel": "No valid tile ControlNet models installed" }, + "stylePresets": { + "active": "Active", + "choosePromptTemplate": "Choose Prompt Template", + "clearTemplateSelection": "Clear Template Selection", + "copyTemplate": "Copy Template", + "createPromptTemplate": "Create Prompt Template", + "defaultTemplates": "Default Templates", + "deleteImage": "Delete Image", + "deleteTemplate": "Delete Template", + "deleteTemplate2": "Are you sure you want to delete this template? This cannot be undone.", + "editTemplate": "Edit Template", + "flatten": "Flatten selected template into current prompt", + "insertPlaceholder": "Insert placeholder", + "myTemplates": "My Templates", + "name": "Name", + "negativePrompt": "Negative Prompt", + "noMatchingTemplates": "No matching templates", + "promptTemplatesDesc1": "Prompt templates add text to the prompts you write in the prompt box.", + "promptTemplatesDesc2": "Use the placeholder string
{{placeholder}}
to specify where your prompt should be included in the template.", + "promptTemplatesDesc3": "If you omit the placeholder, the template will be appended to the end of your prompt.", + "positivePrompt": "Positive Prompt", + "preview": "Preview", + "private": "Private", + "searchByName": "Search by name", + "shared": "Shared", + "sharedTemplates": "Shared Templates", + "templateDeleted": "Prompt template deleted", + "toggleViewMode": "Toggle View Mode", + "type": "Type", + "unableToDeleteTemplate": "Unable to delete prompt template", + "updatePromptTemplate": "Update Prompt Template", + "uploadImage": "Upload Image", + "useForTemplate": "Use For Prompt Template", + "viewList": "View Template List", + "viewModeTooltip": "This is how your prompt will look with your currently selected template. To edit your prompt, click anywhere in the text box." + }, "upsell": { "inviteTeammates": "Invite Teammates", "professional": "Professional", diff --git a/invokeai/frontend/web/src/app/components/App.tsx b/invokeai/frontend/web/src/app/components/App.tsx index c61f892f49..a918454a14 100644 --- a/invokeai/frontend/web/src/app/components/App.tsx +++ b/invokeai/frontend/web/src/app/components/App.tsx @@ -13,6 +13,7 @@ import ChangeBoardModal from 'features/changeBoardModal/components/ChangeBoardMo import DeleteImageModal from 'features/deleteImageModal/components/DeleteImageModal'; import { DynamicPromptsModal } from 'features/dynamicPrompts/components/DynamicPromptsPreviewModal'; import { useStarterModelsToast } from 'features/modelManagerV2/hooks/useStarterModelsToast'; +import { StylePresetModal } from 'features/stylePresets/components/StylePresetForm/StylePresetModal'; import { configChanged } from 'features/system/store/configSlice'; import { languageSelector } from 'features/system/store/systemSelectors'; import InvokeTabs from 'features/ui/components/InvokeTabs'; @@ -120,6 +121,7 @@ const App = ({ config = DEFAULT_CONFIG, selectedImage, selectedWorkflow, destina + ); diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/promptChanged.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/promptChanged.ts index 4633eb45a5..513c087496 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/promptChanged.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/promptChanged.ts @@ -11,6 +11,8 @@ import { promptsChanged, } from 'features/dynamicPrompts/store/dynamicPromptsSlice'; import { getShouldProcessPrompt } from 'features/dynamicPrompts/util/getShouldProcessPrompt'; +import { getPresetModifiedPrompts } from 'features/nodes/util/graph/graphBuilderUtils'; +import { activeStylePresetIdChanged } from 'features/stylePresets/store/stylePresetSlice'; import { utilitiesApi } from 'services/api/endpoints/utilities'; import { socketConnected } from 'services/events/actions'; @@ -19,7 +21,8 @@ const matcher = isAnyOf( combinatorialToggled, maxPromptsChanged, maxPromptsReset, - socketConnected + socketConnected, + activeStylePresetIdChanged ); export const addDynamicPromptsListener = (startAppListening: AppStartListening) => { @@ -28,7 +31,7 @@ export const addDynamicPromptsListener = (startAppListening: AppStartListening) effect: async (action, { dispatch, getState, cancelActiveListeners, delay }) => { cancelActiveListeners(); const state = getState(); - const { positivePrompt } = state.controlLayers.present; + const { positivePrompt } = getPresetModifiedPrompts(state); const { maxPrompts } = state.dynamicPrompts; if (state.config.disabledFeatures.includes('dynamicPrompting')) { diff --git a/invokeai/frontend/web/src/app/store/store.ts b/invokeai/frontend/web/src/app/store/store.ts index 6ae2011355..cacea30e48 100644 --- a/invokeai/frontend/web/src/app/store/store.ts +++ b/invokeai/frontend/web/src/app/store/store.ts @@ -28,6 +28,7 @@ import { generationPersistConfig, generationSlice } from 'features/parameters/st import { upscalePersistConfig, upscaleSlice } from 'features/parameters/store/upscaleSlice'; import { queueSlice } from 'features/queue/store/queueSlice'; import { sdxlPersistConfig, sdxlSlice } from 'features/sdxl/store/sdxlSlice'; +import { stylePresetPersistConfig, stylePresetSlice } from 'features/stylePresets/store/stylePresetSlice'; import { configSlice } from 'features/system/store/configSlice'; import { systemPersistConfig, systemSlice } from 'features/system/store/systemSlice'; import { uiPersistConfig, uiSlice } from 'features/ui/store/uiSlice'; @@ -69,6 +70,7 @@ const allReducers = { [workflowSettingsSlice.name]: workflowSettingsSlice.reducer, [api.reducerPath]: api.reducer, [upscaleSlice.name]: upscaleSlice.reducer, + [stylePresetSlice.name]: stylePresetSlice.reducer, }; const rootReducer = combineReducers(allReducers); @@ -114,6 +116,7 @@ const persistConfigs: { [key in keyof typeof allReducers]?: PersistConfig } = { [controlLayersPersistConfig.name]: controlLayersPersistConfig, [workflowSettingsPersistConfig.name]: workflowSettingsPersistConfig, [upscalePersistConfig.name]: upscalePersistConfig, + [stylePresetPersistConfig.name]: stylePresetPersistConfig, }; const unserialize: UnserializeFunction = (data, key) => { @@ -164,8 +167,8 @@ export const createStore = (uniqueStoreKey?: string, persist = true) => reducer: rememberedRootReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ - serializableCheck: false, - immutableCheck: false, + serializableCheck: import.meta.env.MODE === 'development', + immutableCheck: import.meta.env.MODE === 'development', }) .concat(api.middleware) .concat(dynamicMiddlewares) diff --git a/invokeai/frontend/web/src/app/types/invokeai.ts b/invokeai/frontend/web/src/app/types/invokeai.ts index 7de441699a..ffc4e1960b 100644 --- a/invokeai/frontend/web/src/app/types/invokeai.ts +++ b/invokeai/frontend/web/src/app/types/invokeai.ts @@ -71,6 +71,7 @@ export type AppConfig = { */ maxUpscaleDimension?: number; allowPrivateBoards: boolean; + allowPrivateStylePresets: boolean; disabledTabs: InvokeTabName[]; disabledFeatures: AppFeature[]; disabledSDFeatures: SDFeature[]; diff --git a/invokeai/frontend/web/src/common/hooks/useCopyImageToClipboard.ts b/invokeai/frontend/web/src/common/hooks/useCopyImageToClipboard.ts index 233b841034..345ea98e13 100644 --- a/invokeai/frontend/web/src/common/hooks/useCopyImageToClipboard.ts +++ b/invokeai/frontend/web/src/common/hooks/useCopyImageToClipboard.ts @@ -1,4 +1,4 @@ -import { useImageUrlToBlob } from 'common/hooks/useImageUrlToBlob'; +import { convertImageUrlToBlob } from 'common/util/convertImageUrlToBlob'; import { copyBlobToClipboard } from 'features/system/util/copyBlobToClipboard'; import { toast } from 'features/toast/toast'; import { useCallback, useMemo } from 'react'; @@ -6,7 +6,6 @@ import { useTranslation } from 'react-i18next'; export const useCopyImageToClipboard = () => { const { t } = useTranslation(); - const imageUrlToBlob = useImageUrlToBlob(); const isClipboardAPIAvailable = useMemo(() => { return Boolean(navigator.clipboard) && Boolean(window.ClipboardItem); @@ -23,7 +22,7 @@ export const useCopyImageToClipboard = () => { }); } try { - const blob = await imageUrlToBlob(image_url); + const blob = await convertImageUrlToBlob(image_url); if (!blob) { throw new Error('Unable to create Blob'); @@ -45,7 +44,7 @@ export const useCopyImageToClipboard = () => { }); } }, - [imageUrlToBlob, isClipboardAPIAvailable, t] + [isClipboardAPIAvailable, t] ); return { isClipboardAPIAvailable, copyImageToClipboard }; diff --git a/invokeai/frontend/web/src/common/hooks/useImageUrlToBlob.ts b/invokeai/frontend/web/src/common/hooks/useImageUrlToBlob.ts deleted file mode 100644 index 31faf5f22f..0000000000 --- a/invokeai/frontend/web/src/common/hooks/useImageUrlToBlob.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { $authToken } from 'app/store/nanostores/authToken'; -import { useCallback } from 'react'; - -/** - * Converts an image URL to a Blob by creating an element, drawing it to canvas - * and then converting the canvas to a Blob. - * - * @returns A function that takes a URL and returns a Promise that resolves with a Blob - */ -export const useImageUrlToBlob = () => { - const imageUrlToBlob = useCallback( - async (url: string) => - new Promise((resolve) => { - const img = new Image(); - img.onload = () => { - const canvas = document.createElement('canvas'); - canvas.width = img.width; - canvas.height = img.height; - - const context = canvas.getContext('2d'); - if (!context) { - return; - } - context.drawImage(img, 0, 0); - resolve( - new Promise((resolve) => { - canvas.toBlob(function (blob) { - resolve(blob); - }, 'image/png'); - }) - ); - }; - img.crossOrigin = $authToken.get() ? 'use-credentials' : 'anonymous'; - img.src = url; - }), - [] - ); - - return imageUrlToBlob; -}; diff --git a/invokeai/frontend/web/src/common/util/convertImageUrlToBlob.ts b/invokeai/frontend/web/src/common/util/convertImageUrlToBlob.ts new file mode 100644 index 0000000000..42fdd46609 --- /dev/null +++ b/invokeai/frontend/web/src/common/util/convertImageUrlToBlob.ts @@ -0,0 +1,33 @@ +import { $authToken } from 'app/store/nanostores/authToken'; + +/** + * Converts an image URL to a Blob by creating an element, drawing it to canvas + * and then converting the canvas to a Blob. + * + * @returns A function that takes a URL and returns a Promise that resolves with a Blob + */ + +export const convertImageUrlToBlob = async (url: string) => + new Promise((resolve) => { + const img = new Image(); + img.onload = () => { + const canvas = document.createElement('canvas'); + canvas.width = img.width; + canvas.height = img.height; + + const context = canvas.getContext('2d'); + if (!context) { + return; + } + context.drawImage(img, 0, 0); + resolve( + new Promise((resolve) => { + canvas.toBlob(function (blob) { + resolve(blob); + }, 'image/png'); + }) + ); + }; + img.crossOrigin = $authToken.get() ? 'use-credentials' : 'anonymous'; + img.src = url; + }); diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/SingleSelectionMenuItems.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/SingleSelectionMenuItems.tsx index ab12684c11..1ae4b7b6bc 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/SingleSelectionMenuItems.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/SingleSelectionMenuItems.tsx @@ -30,6 +30,7 @@ import { PiFlowArrowBold, PiFoldersBold, PiImagesBold, + PiPaintBrushBold, PiPlantBold, PiQuotesBold, PiShareFatBold, @@ -55,8 +56,17 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => { const { downloadImage } = useDownloadImage(); const templates = useStore($templates); - const { recallAll, remix, recallSeed, recallPrompts, hasMetadata, hasSeed, hasPrompts, isLoadingMetadata } = - useImageActions(imageDTO?.image_name); + const { + recallAll, + remix, + recallSeed, + recallPrompts, + hasMetadata, + hasSeed, + hasPrompts, + isLoadingMetadata, + createAsPreset, + } = useImageActions(imageDTO?.image_name); const { getAndLoadEmbeddedWorkflow, getAndLoadEmbeddedWorkflowResult } = useGetAndLoadEmbeddedWorkflow({}); @@ -182,6 +192,13 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => { > {t('parameters.useAll')} + : } + onClickCapture={createAsPreset} + isDisabled={isLoadingMetadata || !hasPrompts} + > + {t('stylePresets.useForTemplate')} + } onClickCapture={handleSendToImageToImage} id="send-to-img2img"> {t('parameters.sendToImg2Img')} diff --git a/invokeai/frontend/web/src/features/gallery/hooks/useImageActions.ts b/invokeai/frontend/web/src/features/gallery/hooks/useImageActions.ts index 2978e08f4f..df67bd93bf 100644 --- a/invokeai/frontend/web/src/features/gallery/hooks/useImageActions.ts +++ b/invokeai/frontend/web/src/features/gallery/hooks/useImageActions.ts @@ -1,7 +1,10 @@ +import { skipToken } from '@reduxjs/toolkit/query'; import { useAppSelector } from 'app/store/storeHooks'; import { handlers, parseAndRecallAllMetadata, parseAndRecallPrompts } from 'features/metadata/util/handlers'; +import { $stylePresetModalState } from 'features/stylePresets/store/stylePresetModal'; import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; import { useCallback, useEffect, useState } from 'react'; +import { useGetImageDTOQuery } from 'services/api/endpoints/images'; import { useDebouncedMetadata } from 'services/api/hooks/useDebouncedMetadata'; export const useImageActions = (image_name?: string) => { @@ -10,6 +13,7 @@ export const useImageActions = (image_name?: string) => { const [hasMetadata, setHasMetadata] = useState(false); const [hasSeed, setHasSeed] = useState(false); const [hasPrompts, setHasPrompts] = useState(false); + const { data: imageDTO } = useGetImageDTOQuery(image_name ?? skipToken); useEffect(() => { const parseMetadata = async () => { @@ -61,5 +65,34 @@ export const useImageActions = (image_name?: string) => { parseAndRecallPrompts(metadata); }, [metadata]); - return { recallAll, remix, recallSeed, recallPrompts, hasMetadata, hasSeed, hasPrompts, isLoadingMetadata }; + const createAsPreset = useCallback(async () => { + if (image_name && metadata && imageDTO) { + const positivePrompt = await handlers.positivePrompt.parse(metadata); + const negativePrompt = await handlers.negativePrompt.parse(metadata); + + $stylePresetModalState.set({ + prefilledFormData: { + name: '', + positivePrompt, + negativePrompt, + imageUrl: imageDTO.image_url, + type: 'user', + }, + updatingStylePresetId: null, + isModalOpen: true, + }); + } + }, [image_name, metadata, imageDTO]); + + return { + recallAll, + remix, + recallSeed, + recallPrompts, + hasMetadata, + hasSeed, + hasPrompts, + isLoadingMetadata, + createAsPreset, + }; }; diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/buildMultidiffusionUpscaleGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/buildMultidiffusionUpscaleGraph.ts index 2905f31b50..7c17b406de 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/buildMultidiffusionUpscaleGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/buildMultidiffusionUpscaleGraph.ts @@ -22,11 +22,10 @@ import { } from './constants'; import { addLoRAs } from './generation/addLoRAs'; import { addSDXLLoRas } from './generation/addSDXLLoRAs'; -import { getBoardField, getSDXLStylePrompts } from './graphBuilderUtils'; +import { getBoardField, getPresetModifiedPrompts } from './graphBuilderUtils'; export const buildMultidiffusionUpscaleGraph = async (state: RootState): Promise => { const { model, cfgScale: cfg_scale, scheduler, steps, vaePrecision, seed, vae } = state.generation; - const { positivePrompt, negativePrompt } = state.controlLayers.present; const { upscaleModel, upscaleInitialImage, structure, creativity, tileControlnetModel, scale } = state.upscale; assert(model, 'No model found in state'); @@ -99,7 +98,8 @@ export const buildMultidiffusionUpscaleGraph = async (state: RootState): Promise let modelNode; if (model.base === 'sdxl') { - const { positiveStylePrompt, negativeStylePrompt } = getSDXLStylePrompts(state); + const { positivePrompt, negativePrompt, positiveStylePrompt, negativeStylePrompt } = + getPresetModifiedPrompts(state); posCondNode = g.addNode({ type: 'sdxl_compel_prompt', @@ -132,6 +132,8 @@ export const buildMultidiffusionUpscaleGraph = async (state: RootState): Promise negative_style_prompt: negativeStylePrompt, }); } else { + const { positivePrompt, negativePrompt } = getPresetModifiedPrompts(state); + posCondNode = g.addNode({ type: 'compel', id: POSITIVE_CONDITIONING, diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/addSDXLRefinerToGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/addSDXLRefinerToGraph.ts index 6fc406ca74..7809744afa 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/addSDXLRefinerToGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/addSDXLRefinerToGraph.ts @@ -16,7 +16,7 @@ import { SDXL_REFINER_POSITIVE_CONDITIONING, SDXL_REFINER_SEAMLESS, } from 'features/nodes/util/graph/constants'; -import { getSDXLStylePrompts } from 'features/nodes/util/graph/graphBuilderUtils'; +import { getPresetModifiedPrompts } from 'features/nodes/util/graph/graphBuilderUtils'; import type { NonNullableGraph } from 'services/api/types'; import { isRefinerMainModelModelConfig } from 'services/api/types'; @@ -59,7 +59,7 @@ export const addSDXLRefinerToGraph = async ( const modelLoaderId = modelLoaderNodeId ? modelLoaderNodeId : SDXL_MODEL_LOADER; // Construct Style Prompt - const { positiveStylePrompt, negativeStylePrompt } = getSDXLStylePrompts(state); + const { positiveStylePrompt, negativeStylePrompt } = getPresetModifiedPrompts(state); // Unplug SDXL Latents Generation To Latents To Image graph.edges = graph.edges.filter((e) => !(e.source.node_id === baseNodeId && ['latents'].includes(e.source.field))); diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasImageToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasImageToImageGraph.ts index 5c89dcbf29..3d17da9b4a 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasImageToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasImageToImageGraph.ts @@ -16,7 +16,11 @@ import { POSITIVE_CONDITIONING, SEAMLESS, } from 'features/nodes/util/graph/constants'; -import { getBoardField, getIsIntermediate } from 'features/nodes/util/graph/graphBuilderUtils'; +import { + getBoardField, + getIsIntermediate, + getPresetModifiedPrompts, +} from 'features/nodes/util/graph/graphBuilderUtils'; import type { ImageDTO, Invocation, NonNullableGraph } from 'services/api/types'; import { isNonRefinerMainModelConfig } from 'services/api/types'; @@ -51,7 +55,6 @@ export const buildCanvasImageToImageGraph = async ( seamlessXAxis, seamlessYAxis, } = state.generation; - const { positivePrompt, negativePrompt } = state.controlLayers.present; // The bounding box determines width and height, not the width and height params const { width, height } = state.canvas.boundingBoxDimensions; @@ -71,6 +74,8 @@ export const buildCanvasImageToImageGraph = async ( const use_cpu = shouldUseCpuNoise; + const { positivePrompt, negativePrompt } = getPresetModifiedPrompts(state); + /** * The easiest way to build linear graphs is to do it in the node editor, then copy and paste the * full graph here as a template. Then use the parameters from app state and set friendlier node diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasInpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasInpaintGraph.ts index 20304b8830..39cdbb31cd 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasInpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasInpaintGraph.ts @@ -19,7 +19,11 @@ import { POSITIVE_CONDITIONING, SEAMLESS, } from 'features/nodes/util/graph/constants'; -import { getBoardField, getIsIntermediate } from 'features/nodes/util/graph/graphBuilderUtils'; +import { + getBoardField, + getIsIntermediate, + getPresetModifiedPrompts, +} from 'features/nodes/util/graph/graphBuilderUtils'; import type { ImageDTO, Invocation, NonNullableGraph } from 'services/api/types'; import { addControlNetToLinearGraph } from './addControlNetToLinearGraph'; @@ -58,7 +62,6 @@ export const buildCanvasInpaintGraph = async ( canvasCoherenceEdgeSize, maskBlur, } = state.generation; - const { positivePrompt, negativePrompt } = state.controlLayers.present; if (!model) { log.error('No model found in state'); @@ -79,6 +82,8 @@ export const buildCanvasInpaintGraph = async ( const use_cpu = shouldUseCpuNoise; + const { positivePrompt, negativePrompt } = getPresetModifiedPrompts(state); + const graph: NonNullableGraph = { id: CANVAS_INPAINT_GRAPH, nodes: { diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasOutpaintGraph.ts index 2c85b20222..ce8f86223f 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasOutpaintGraph.ts @@ -23,7 +23,11 @@ import { POSITIVE_CONDITIONING, SEAMLESS, } from 'features/nodes/util/graph/constants'; -import { getBoardField, getIsIntermediate } from 'features/nodes/util/graph/graphBuilderUtils'; +import { + getBoardField, + getIsIntermediate, + getPresetModifiedPrompts, +} from 'features/nodes/util/graph/graphBuilderUtils'; import type { ImageDTO, Invocation, NonNullableGraph } from 'services/api/types'; import { addControlNetToLinearGraph } from './addControlNetToLinearGraph'; @@ -70,7 +74,6 @@ export const buildCanvasOutpaintGraph = async ( canvasCoherenceEdgeSize, maskBlur, } = state.generation; - const { positivePrompt, negativePrompt } = state.controlLayers.present; if (!model) { log.error('No model found in state'); @@ -91,6 +94,8 @@ export const buildCanvasOutpaintGraph = async ( const use_cpu = shouldUseCpuNoise; + const { positivePrompt, negativePrompt } = getPresetModifiedPrompts(state); + const graph: NonNullableGraph = { id: CANVAS_OUTPAINT_GRAPH, nodes: { diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasSDXLImageToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasSDXLImageToImageGraph.ts index b4549ff582..bcf2f8a93c 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasSDXLImageToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasSDXLImageToImageGraph.ts @@ -16,7 +16,11 @@ import { SDXL_REFINER_SEAMLESS, SEAMLESS, } from 'features/nodes/util/graph/constants'; -import { getBoardField, getIsIntermediate, getSDXLStylePrompts } from 'features/nodes/util/graph/graphBuilderUtils'; +import { + getBoardField, + getIsIntermediate, + getPresetModifiedPrompts, +} from 'features/nodes/util/graph/graphBuilderUtils'; import type { ImageDTO, Invocation, NonNullableGraph } from 'services/api/types'; import { isNonRefinerMainModelConfig } from 'services/api/types'; @@ -51,7 +55,6 @@ export const buildCanvasSDXLImageToImageGraph = async ( seamlessYAxis, img2imgStrength: strength, } = state.generation; - const { positivePrompt, negativePrompt } = state.controlLayers.present; const { refinerModel, refinerStart } = state.sdxl; @@ -75,7 +78,7 @@ export const buildCanvasSDXLImageToImageGraph = async ( const use_cpu = shouldUseCpuNoise; // Construct Style Prompt - const { positiveStylePrompt, negativeStylePrompt } = getSDXLStylePrompts(state); + const { positivePrompt, negativePrompt, positiveStylePrompt, negativeStylePrompt } = getPresetModifiedPrompts(state); /** * The easiest way to build linear graphs is to do it in the node editor, then copy and paste the diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasSDXLInpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasSDXLInpaintGraph.ts index dfbe2436d2..e56e4d0ddb 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasSDXLInpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasSDXLInpaintGraph.ts @@ -19,7 +19,11 @@ import { SDXL_REFINER_SEAMLESS, SEAMLESS, } from 'features/nodes/util/graph/constants'; -import { getBoardField, getIsIntermediate, getSDXLStylePrompts } from 'features/nodes/util/graph/graphBuilderUtils'; +import { + getBoardField, + getIsIntermediate, + getPresetModifiedPrompts, +} from 'features/nodes/util/graph/graphBuilderUtils'; import type { ImageDTO, Invocation, NonNullableGraph } from 'services/api/types'; import { addControlNetToLinearGraph } from './addControlNetToLinearGraph'; @@ -58,7 +62,6 @@ export const buildCanvasSDXLInpaintGraph = async ( canvasCoherenceEdgeSize, maskBlur, } = state.generation; - const { positivePrompt, negativePrompt } = state.controlLayers.present; const { refinerModel, refinerStart } = state.sdxl; @@ -83,7 +86,7 @@ export const buildCanvasSDXLInpaintGraph = async ( const use_cpu = shouldUseCpuNoise; // Construct Style Prompt - const { positiveStylePrompt, negativeStylePrompt } = getSDXLStylePrompts(state); + const { positivePrompt, negativePrompt, positiveStylePrompt, negativeStylePrompt } = getPresetModifiedPrompts(state); const graph: NonNullableGraph = { id: SDXL_CANVAS_INPAINT_GRAPH, diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasSDXLOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasSDXLOutpaintGraph.ts index d58796575c..095918ab71 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasSDXLOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasSDXLOutpaintGraph.ts @@ -23,7 +23,11 @@ import { SDXL_REFINER_SEAMLESS, SEAMLESS, } from 'features/nodes/util/graph/constants'; -import { getBoardField, getIsIntermediate, getSDXLStylePrompts } from 'features/nodes/util/graph/graphBuilderUtils'; +import { + getBoardField, + getIsIntermediate, + getPresetModifiedPrompts, +} from 'features/nodes/util/graph/graphBuilderUtils'; import type { ImageDTO, Invocation, NonNullableGraph } from 'services/api/types'; import { addControlNetToLinearGraph } from './addControlNetToLinearGraph'; @@ -70,7 +74,6 @@ export const buildCanvasSDXLOutpaintGraph = async ( canvasCoherenceEdgeSize, maskBlur, } = state.generation; - const { positivePrompt, negativePrompt } = state.controlLayers.present; const { refinerModel, refinerStart } = state.sdxl; @@ -94,7 +97,7 @@ export const buildCanvasSDXLOutpaintGraph = async ( const use_cpu = shouldUseCpuNoise; // Construct Style Prompt - const { positiveStylePrompt, negativeStylePrompt } = getSDXLStylePrompts(state); + const { positivePrompt, negativePrompt, positiveStylePrompt, negativeStylePrompt } = getPresetModifiedPrompts(state); const graph: NonNullableGraph = { id: SDXL_CANVAS_OUTPAINT_GRAPH, diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasSDXLTextToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasSDXLTextToImageGraph.ts index b9e8e011b3..2b37255070 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasSDXLTextToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasSDXLTextToImageGraph.ts @@ -14,7 +14,11 @@ import { SDXL_REFINER_SEAMLESS, SEAMLESS, } from 'features/nodes/util/graph/constants'; -import { getBoardField, getIsIntermediate, getSDXLStylePrompts } from 'features/nodes/util/graph/graphBuilderUtils'; +import { + getBoardField, + getIsIntermediate, + getPresetModifiedPrompts, +} from 'features/nodes/util/graph/graphBuilderUtils'; import { isNonRefinerMainModelConfig, type NonNullableGraph } from 'services/api/types'; import { addControlNetToLinearGraph } from './addControlNetToLinearGraph'; @@ -44,7 +48,6 @@ export const buildCanvasSDXLTextToImageGraph = async (state: RootState): Promise seamlessXAxis, seamlessYAxis, } = state.generation; - const { positivePrompt, negativePrompt } = state.controlLayers.present; // The bounding box determines width and height, not the width and height params const { width, height } = state.canvas.boundingBoxDimensions; @@ -67,7 +70,7 @@ export const buildCanvasSDXLTextToImageGraph = async (state: RootState): Promise let modelLoaderNodeId = SDXL_MODEL_LOADER; // Construct Style Prompt - const { positiveStylePrompt, negativeStylePrompt } = getSDXLStylePrompts(state); + const { positivePrompt, negativePrompt, positiveStylePrompt, negativeStylePrompt } = getPresetModifiedPrompts(state); /** * The easiest way to build linear graphs is to do it in the node editor, then copy and paste the diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasTextToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasTextToImageGraph.ts index fe33ab5cf3..352dc0771d 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasTextToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/canvas/buildCanvasTextToImageGraph.ts @@ -14,7 +14,11 @@ import { POSITIVE_CONDITIONING, SEAMLESS, } from 'features/nodes/util/graph/constants'; -import { getBoardField, getIsIntermediate } from 'features/nodes/util/graph/graphBuilderUtils'; +import { + getBoardField, + getIsIntermediate, + getPresetModifiedPrompts, +} from 'features/nodes/util/graph/graphBuilderUtils'; import { isNonRefinerMainModelConfig, type NonNullableGraph } from 'services/api/types'; import { addControlNetToLinearGraph } from './addControlNetToLinearGraph'; @@ -44,7 +48,6 @@ export const buildCanvasTextToImageGraph = async (state: RootState): Promise { }; /** - * Gets the SDXL style prompts, based on the concat setting. + * Gets the prompts, modified for the active style preset. */ -export const getSDXLStylePrompts = (state: RootState): { positiveStylePrompt: string; negativeStylePrompt: string } => { +export const getPresetModifiedPrompts = ( + state: RootState +): { positivePrompt: string; negativePrompt: string; positiveStylePrompt?: string; negativeStylePrompt?: string } => { const { positivePrompt, negativePrompt, positivePrompt2, negativePrompt2, shouldConcatPrompts } = state.controlLayers.present; + const { activeStylePresetId } = state.stylePreset; + + if (activeStylePresetId) { + const { data } = stylePresetsApi.endpoints.listStylePresets.select()(state); + + const activeStylePreset = data?.find((item) => item.id === activeStylePresetId); + + if (activeStylePreset) { + const presetModifiedPositivePrompt = buildPresetModifiedPrompt( + activeStylePreset.preset_data.positive_prompt, + positivePrompt + ); + + const presetModifiedNegativePrompt = buildPresetModifiedPrompt( + activeStylePreset.preset_data.negative_prompt, + negativePrompt + ); + + return { + positivePrompt: presetModifiedPositivePrompt, + negativePrompt: presetModifiedNegativePrompt, + positiveStylePrompt: shouldConcatPrompts ? presetModifiedPositivePrompt : positivePrompt2, + negativeStylePrompt: shouldConcatPrompts ? presetModifiedNegativePrompt : negativePrompt2, + }; + } + } return { + positivePrompt, + negativePrompt, positiveStylePrompt: shouldConcatPrompts ? positivePrompt : positivePrompt2, negativeStylePrompt: shouldConcatPrompts ? negativePrompt : negativePrompt2, }; diff --git a/invokeai/frontend/web/src/features/parameters/components/Core/ParamNegativePrompt.tsx b/invokeai/frontend/web/src/features/parameters/components/Core/ParamNegativePrompt.tsx index d75c98c064..0f32bdb435 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Core/ParamNegativePrompt.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Core/ParamNegativePrompt.tsx @@ -1,16 +1,32 @@ import { Box, Textarea } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { negativePromptChanged } from 'features/controlLayers/store/controlLayersSlice'; +import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel'; import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper'; +import { ViewModePrompt } from 'features/parameters/components/Prompts/ViewModePrompt'; import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton'; import { PromptPopover } from 'features/prompt/PromptPopover'; import { usePrompt } from 'features/prompt/usePrompt'; import { memo, useCallback, useRef } from 'react'; import { useTranslation } from 'react-i18next'; +import { useListStylePresetsQuery } from 'services/api/endpoints/stylePresets'; export const ParamNegativePrompt = memo(() => { const dispatch = useAppDispatch(); const prompt = useAppSelector((s) => s.controlLayers.present.negativePrompt); + const viewMode = useAppSelector((s) => s.stylePreset.viewMode); + const activeStylePresetId = useAppSelector((s) => s.stylePreset.activeStylePresetId); + + const { activeStylePreset } = useListStylePresetsQuery(undefined, { + selectFromResult: ({ data }) => { + let activeStylePreset = null; + if (data) { + activeStylePreset = data.find((sp) => sp.id === activeStylePresetId); + } + return { activeStylePreset }; + }, + }); + const textareaRef = useRef(null); const { t } = useTranslation(); const _onChange = useCallback( @@ -27,22 +43,34 @@ export const ParamNegativePrompt = memo(() => { return ( - +