Merge branch 'main' into chore/accessability_various-additions

This commit is contained in:
Elrik 2023-03-07 17:44:55 -06:00 committed by GitHub
commit 6b41127421
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
64 changed files with 1122 additions and 1381 deletions

1
.git-blame-ignore-revs Normal file
View File

@ -0,0 +1 @@
b3dccfaeb636599c02effc377cdd8a87d658256c

View File

@ -4,9 +4,17 @@ on:
pull_request: pull_request:
paths: paths:
- 'invokeai/frontend/web/**' - 'invokeai/frontend/web/**'
types:
- 'ready_for_review'
- 'opened'
- 'synchronize'
push: push:
branches:
- 'main'
paths: paths:
- 'invokeai/frontend/web/**' - 'invokeai/frontend/web/**'
merge_group:
workflow_dispatch:
defaults: defaults:
run: run:

View File

@ -6,7 +6,7 @@ on:
- 'invokeai/**' - 'invokeai/**'
- 'invokeai/backend/**' - 'invokeai/backend/**'
- 'invokeai/configs/**' - 'invokeai/configs/**'
- 'invokeai/frontend/dist/**' - 'invokeai/frontend/web/dist/**'
merge_group: merge_group:
workflow_dispatch: workflow_dispatch:

View File

@ -8,14 +8,14 @@ on:
- 'invokeai/**' - 'invokeai/**'
- 'invokeai/backend/**' - 'invokeai/backend/**'
- 'invokeai/configs/**' - 'invokeai/configs/**'
- 'invokeai/frontend/dist/**' - 'invokeai/frontend/web/dist/**'
pull_request: pull_request:
paths: paths:
- 'pyproject.toml' - 'pyproject.toml'
- 'invokeai/**' - 'invokeai/**'
- 'invokeai/backend/**' - 'invokeai/backend/**'
- 'invokeai/configs/**' - 'invokeai/configs/**'
- 'invokeai/frontend/dist/**' - 'invokeai/frontend/web/dist/**'
types: types:
- 'ready_for_review' - 'ready_for_review'
- 'opened' - 'opened'

View File

View File

@ -0,0 +1,202 @@
# Copyright (c) 2023 Kyle Schouviller (https://github.com/kyle0654)
from abc import ABC, abstractmethod
import argparse
from typing import Any, Callable, Iterable, Literal, get_args, get_origin, get_type_hints
from pydantic import BaseModel, Field
from ..invocations.image import ImageField
from ..services.graph import GraphExecutionState
from ..services.invoker import Invoker
def add_parsers(
subparsers,
commands: list[type],
command_field: str = "type",
exclude_fields: list[str] = ["id", "type"],
add_arguments: Callable[[argparse.ArgumentParser], None]|None = None
):
"""Adds parsers for each command to the subparsers"""
# Create subparsers for each command
for command in commands:
hints = get_type_hints(command)
cmd_name = get_args(hints[command_field])[0]
command_parser = subparsers.add_parser(cmd_name, help=command.__doc__)
if add_arguments is not None:
add_arguments(command_parser)
# Convert all fields to arguments
fields = command.__fields__ # type: ignore
for name, field in fields.items():
if name in exclude_fields:
continue
if get_origin(field.type_) == Literal:
allowed_values = get_args(field.type_)
allowed_types = set()
for val in allowed_values:
allowed_types.add(type(val))
allowed_types_list = list(allowed_types)
field_type = allowed_types_list[0] if len(allowed_types) == 1 else Union[allowed_types_list] # type: ignore
command_parser.add_argument(
f"--{name}",
dest=name,
type=field_type,
default=field.default,
choices=allowed_values,
help=field.field_info.description,
)
else:
command_parser.add_argument(
f"--{name}",
dest=name,
type=field.type_,
default=field.default,
help=field.field_info.description,
)
class CliContext:
invoker: Invoker
session: GraphExecutionState
parser: argparse.ArgumentParser
defaults: dict[str, Any]
def __init__(self, invoker: Invoker, session: GraphExecutionState, parser: argparse.ArgumentParser):
self.invoker = invoker
self.session = session
self.parser = parser
self.defaults = dict()
def get_session(self):
self.session = self.invoker.services.graph_execution_manager.get(self.session.id)
return self.session
class ExitCli(Exception):
"""Exception to exit the CLI"""
pass
class BaseCommand(ABC, BaseModel):
"""A CLI command"""
# All commands must include a type name like this:
# type: Literal['your_command_name'] = 'your_command_name'
@classmethod
def get_all_subclasses(cls):
subclasses = []
toprocess = [cls]
while len(toprocess) > 0:
next = toprocess.pop(0)
next_subclasses = next.__subclasses__()
subclasses.extend(next_subclasses)
toprocess.extend(next_subclasses)
return subclasses
@classmethod
def get_commands(cls):
return tuple(BaseCommand.get_all_subclasses())
@classmethod
def get_commands_map(cls):
# Get the type strings out of the literals and into a dictionary
return dict(map(lambda t: (get_args(get_type_hints(t)['type'])[0], t),BaseCommand.get_all_subclasses()))
@abstractmethod
def run(self, context: CliContext) -> None:
"""Run the command. Raise ExitCli to exit."""
pass
class ExitCommand(BaseCommand):
"""Exits the CLI"""
type: Literal['exit'] = 'exit'
def run(self, context: CliContext) -> None:
raise ExitCli()
class HelpCommand(BaseCommand):
"""Shows help"""
type: Literal['help'] = 'help'
def run(self, context: CliContext) -> None:
context.parser.print_help()
def get_graph_execution_history(
graph_execution_state: GraphExecutionState,
) -> Iterable[str]:
"""Gets the history of fully-executed invocations for a graph execution"""
return (
n
for n in reversed(graph_execution_state.executed_history)
if n in graph_execution_state.graph.nodes
)
def get_invocation_command(invocation) -> str:
fields = invocation.__fields__.items()
type_hints = get_type_hints(type(invocation))
command = [invocation.type]
for name, field in fields:
if name in ["id", "type"]:
continue
# TODO: add links
# Skip image fields when serializing command
type_hint = type_hints.get(name) or None
if type_hint is ImageField or ImageField in get_args(type_hint):
continue
field_value = getattr(invocation, name)
field_default = field.default
if field_value != field_default:
if type_hint is str or str in get_args(type_hint):
command.append(f'--{name} "{field_value}"')
else:
command.append(f"--{name} {field_value}")
return " ".join(command)
class HistoryCommand(BaseCommand):
"""Shows the invocation history"""
type: Literal['history'] = 'history'
# Inputs
# fmt: off
count: int = Field(default=5, gt=0, description="The number of history entries to show")
# fmt: on
def run(self, context: CliContext) -> None:
history = list(get_graph_execution_history(context.get_session()))
for i in range(min(self.count, len(history))):
entry_id = history[-1 - i]
entry = context.get_session().graph.get_node(entry_id)
print(f"{entry_id}: {get_invocation_command(entry)}")
class SetDefaultCommand(BaseCommand):
"""Sets a default value for a field"""
type: Literal['default'] = 'default'
# Inputs
# fmt: off
field: str = Field(description="The field to set the default for")
value: str = Field(description="The value to set the default to, or None to clear the default")
# fmt: on
def run(self, context: CliContext) -> None:
if self.value is None:
if self.field in context.defaults:
del context.defaults[self.field]
else:
context.defaults[self.field] = self.value

View File

@ -5,13 +5,7 @@ import os
import shlex import shlex
import time import time
from typing import ( from typing import (
Any,
Dict,
Iterable,
Literal,
Union, Union,
get_args,
get_origin,
get_type_hints, get_type_hints,
) )
@ -19,9 +13,9 @@ from pydantic import BaseModel
from pydantic.fields import Field from pydantic.fields import Field
from ..backend import Args from ..backend import Args
from .cli.commands import BaseCommand, CliContext, ExitCli, add_parsers, get_graph_execution_history
from .invocations import * from .invocations import *
from .invocations.baseinvocation import BaseInvocation from .invocations.baseinvocation import BaseInvocation
from .invocations.image import ImageField
from .services.events import EventServiceBase from .services.events import EventServiceBase
from .services.generate_initializer import get_generate from .services.generate_initializer import get_generate
from .services.graph import EdgeConnection, GraphExecutionState from .services.graph import EdgeConnection, GraphExecutionState
@ -33,15 +27,33 @@ from .services.processor import DefaultInvocationProcessor
from .services.sqlite import SqliteItemStorage from .services.sqlite import SqliteItemStorage
class InvocationCommand(BaseModel): class CliCommand(BaseModel):
invocation: Union[BaseInvocation.get_invocations()] = Field(discriminator="type") # type: ignore command: Union[BaseCommand.get_commands() + BaseInvocation.get_invocations()] = Field(discriminator="type") # type: ignore
class InvalidArgs(Exception): class InvalidArgs(Exception):
pass pass
def get_invocation_parser() -> argparse.ArgumentParser: def add_invocation_args(command_parser):
# Add linking capability
command_parser.add_argument(
"--link",
"-l",
action="append",
nargs=3,
help="A link in the format 'dest_field source_node source_field'. source_node can be relative to history (e.g. -1)",
)
command_parser.add_argument(
"--link_node",
"-ln",
action="append",
help="A link from all fields in the specified node. Node can be relative to history (e.g. -1)",
)
def get_command_parser() -> argparse.ArgumentParser:
# Create invocation parser # Create invocation parser
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
@ -49,129 +61,19 @@ def get_invocation_parser() -> argparse.ArgumentParser:
raise InvalidArgs raise InvalidArgs
parser.exit = exit parser.exit = exit
subparsers = parser.add_subparsers(dest="type") subparsers = parser.add_subparsers(dest="type")
invocation_parsers = dict()
# Add history parser
history_parser = subparsers.add_parser(
"history", help="Shows the invocation history"
)
history_parser.add_argument(
"count",
nargs="?",
default=5,
type=int,
help="The number of history entries to show",
)
# Add default parser
default_parser = subparsers.add_parser(
"default", help="Define a default value for all inputs with a specified name"
)
default_parser.add_argument("input", type=str, help="The input field")
default_parser.add_argument("value", help="The default value")
default_parser = subparsers.add_parser(
"reset_default", help="Resets a default value"
)
default_parser.add_argument("input", type=str, help="The input field")
# Create subparsers for each invocation # Create subparsers for each invocation
invocations = BaseInvocation.get_all_subclasses() invocations = BaseInvocation.get_all_subclasses()
for invocation in invocations: add_parsers(subparsers, invocations, add_arguments=add_invocation_args)
hints = get_type_hints(invocation)
cmd_name = get_args(hints["type"])[0]
command_parser = subparsers.add_parser(cmd_name, help=invocation.__doc__)
invocation_parsers[cmd_name] = command_parser
# Add linking capability # Create subparsers for each command
command_parser.add_argument( commands = BaseCommand.get_all_subclasses()
"--link", add_parsers(subparsers, commands, exclude_fields=["type"])
"-l",
action="append",
nargs=3,
help="A link in the format 'dest_field source_node source_field'. source_node can be relative to history (e.g. -1)",
)
command_parser.add_argument(
"--link_node",
"-ln",
action="append",
help="A link from all fields in the specified node. Node can be relative to history (e.g. -1)",
)
# Convert all fields to arguments
fields = invocation.__fields__
for name, field in fields.items():
if name in ["id", "type"]:
continue
if get_origin(field.type_) == Literal:
allowed_values = get_args(field.type_)
allowed_types = set()
for val in allowed_values:
allowed_types.add(type(val))
allowed_types_list = list(allowed_types)
field_type = allowed_types_list[0] if len(allowed_types) == 1 else Union[allowed_types_list] # type: ignore
command_parser.add_argument(
f"--{name}",
dest=name,
type=field_type,
default=field.default,
choices=allowed_values,
help=field.field_info.description,
)
else:
command_parser.add_argument(
f"--{name}",
dest=name,
type=field.type_,
default=field.default,
help=field.field_info.description,
)
return parser return parser
def get_invocation_command(invocation) -> str:
fields = invocation.__fields__.items()
type_hints = get_type_hints(type(invocation))
command = [invocation.type]
for name, field in fields:
if name in ["id", "type"]:
continue
# TODO: add links
# Skip image fields when serializing command
type_hint = type_hints.get(name) or None
if type_hint is ImageField or ImageField in get_args(type_hint):
continue
field_value = getattr(invocation, name)
field_default = field.default
if field_value != field_default:
if type_hint is str or str in get_args(type_hint):
command.append(f'--{name} "{field_value}"')
else:
command.append(f"--{name} {field_value}")
return " ".join(command)
def get_graph_execution_history(
graph_execution_state: GraphExecutionState,
) -> Iterable[str]:
"""Gets the history of fully-executed invocations for a graph execution"""
return (
n
for n in reversed(graph_execution_state.executed_history)
if n in graph_execution_state.graph.nodes
)
def generate_matching_edges( def generate_matching_edges(
a: BaseInvocation, b: BaseInvocation a: BaseInvocation, b: BaseInvocation
) -> list[tuple[EdgeConnection, EdgeConnection]]: ) -> list[tuple[EdgeConnection, EdgeConnection]]:
@ -233,13 +135,12 @@ def invoke_cli():
invoker = Invoker(services) invoker = Invoker(services)
session: GraphExecutionState = invoker.create_execution_state() session: GraphExecutionState = invoker.create_execution_state()
parser = get_invocation_parser() parser = get_command_parser()
# Uncomment to print out previous sessions at startup # Uncomment to print out previous sessions at startup
# print(services.session_manager.list()) # print(services.session_manager.list())
# Defaults storage context = CliContext(invoker, session, parser)
defaults: Dict[str, Any] = dict()
while True: while True:
try: try:
@ -248,13 +149,6 @@ def invoke_cli():
# Ctrl-c exits # Ctrl-c exits
break break
if cmd_input in ["exit", "q"]:
break
if cmd_input in ["--help", "help", "h", "?"]:
parser.print_help()
continue
try: try:
# Refresh the state of the session # Refresh the state of the session
session = invoker.services.graph_execution_manager.get(session.id) session = invoker.services.graph_execution_manager.get(session.id)
@ -272,35 +166,23 @@ def invoke_cli():
# Parse args to create invocation # Parse args to create invocation
args = vars(parser.parse_args(shlex.split(cmd.strip()))) args = vars(parser.parse_args(shlex.split(cmd.strip())))
# Check for special commands
# TODO: These might be better as Pydantic models, similar to the invocations
if args["type"] == "history":
history_count = args["count"] or 5
for i in range(min(history_count, len(history))):
entry_id = history[-1 - i]
entry = session.graph.get_node(entry_id)
print(f"{entry_id}: {get_invocation_command(entry.invocation)}")
continue
if args["type"] == "reset_default":
if args["input"] in defaults:
del defaults[args["input"]]
continue
if args["type"] == "default":
field = args["input"]
field_value = args["value"]
defaults[field] = field_value
continue
# Override defaults # Override defaults
for field_name, field_default in defaults.items(): for field_name, field_default in context.defaults.items():
if field_name in args: if field_name in args:
args[field_name] = field_default args[field_name] = field_default
# Parse invocation # Parse invocation
args["id"] = current_id args["id"] = current_id
command = InvocationCommand(invocation=args) command = CliCommand(command=args)
# Run any CLI commands immediately
# TODO: this won't behave as expected if piping and using e.g. history,
# since invocations are gathered and then run together at the end.
# This is more efficient if the CLI is running against a distributed
# backend, so it's preferable not to change that behavior.
if isinstance(command.command, BaseCommand):
command.command.run(context)
continue
# Pipe previous command output (if there was a previous command) # Pipe previous command output (if there was a previous command)
edges = [] edges = []
@ -314,7 +196,7 @@ def invoke_cli():
else session.graph.get_node(from_id) else session.graph.get_node(from_id)
) )
matching_edges = generate_matching_edges( matching_edges = generate_matching_edges(
from_node, command.invocation from_node, command.command
) )
edges.extend(matching_edges) edges.extend(matching_edges)
@ -323,22 +205,25 @@ def invoke_cli():
for link in args["link_node"]: for link in args["link_node"]:
link_node = session.graph.get_node(link) link_node = session.graph.get_node(link)
matching_edges = generate_matching_edges( matching_edges = generate_matching_edges(
link_node, command.invocation link_node, command.command
) )
matching_destinations = [e[1] for e in matching_edges]
edges = [e for e in edges if e[1] not in matching_destinations]
edges.extend(matching_edges) edges.extend(matching_edges)
if "link" in args and args["link"]: if "link" in args and args["link"]:
for link in args["link"]: for link in args["link"]:
edges = [e for e in edges if e[1].node_id != command.command.id and e[1].field != link[2]]
edges.append( edges.append(
( (
EdgeConnection(node_id=link[1], field=link[0]), EdgeConnection(node_id=link[1], field=link[0]),
EdgeConnection( EdgeConnection(
node_id=command.invocation.id, field=link[2] node_id=command.command.id, field=link[2]
), ),
) )
) )
new_invocations.append((command.invocation, edges)) new_invocations.append((command.command, edges))
current_id = current_id + 1 current_id = current_id + 1
@ -347,13 +232,14 @@ def invoke_cli():
for invocation in new_invocations: for invocation in new_invocations:
session.add_node(invocation[0]) session.add_node(invocation[0])
for edge in invocation[1]: for edge in invocation[1]:
print(edge)
session.add_edge(edge) session.add_edge(edge)
# Execute all available invocations # Execute all available invocations
invoker.invoke(session, invoke_all=True) invoker.invoke(session, invoke_all=True)
while not session.is_complete(): while not session.is_complete():
# Wait some time # Wait some time
session = invoker.services.graph_execution_manager.get(session.id) session = context.get_session()
time.sleep(0.1) time.sleep(0.1)
# Print any errors # Print any errors
@ -366,11 +252,15 @@ def invoke_cli():
# Start a new session # Start a new session
print("Creating a new session") print("Creating a new session")
session = invoker.create_execution_state() session = invoker.create_execution_state()
context.session = session
except InvalidArgs: except InvalidArgs:
print('Invalid command, use "help" to list commands') print('Invalid command, use "help" to list commands')
continue continue
except ExitCli:
break
except SystemExit: except SystemExit:
continue continue

View File

@ -295,7 +295,7 @@ def download_vaes():
# first the diffusers version # first the diffusers version
repo_id = "stabilityai/sd-vae-ft-mse" repo_id = "stabilityai/sd-vae-ft-mse"
args = dict( args = dict(
cache_dir=global_cache_dir("diffusers"), cache_dir=global_cache_dir("hub"),
) )
if not AutoencoderKL.from_pretrained(repo_id, **args): if not AutoencoderKL.from_pretrained(repo_id, **args):
raise Exception(f"download of {repo_id} failed") raise Exception(f"download of {repo_id} failed")

View File

@ -270,7 +270,6 @@ def _download_diffusion_weights(
path = download_from_hf( path = download_from_hf(
model_class, model_class,
repo_id, repo_id,
cache_subdir="diffusers",
safety_checker=None, safety_checker=None,
**extra_args, **extra_args,
) )

View File

@ -98,16 +98,13 @@ def global_cache_dir(subdir: Union[str, Path] = "") -> Path:
""" """
Returns Path to the model cache directory. If a subdirectory Returns Path to the model cache directory. If a subdirectory
is provided, it will be appended to the end of the path, allowing is provided, it will be appended to the end of the path, allowing
for huggingface-style conventions: for Hugging Face-style conventions. Currently, Hugging Face has
global_cache_dir('diffusers') moved all models into the "hub" subfolder, so for any pretrained
HF model, use:
global_cache_dir('hub') global_cache_dir('hub')
Current HuggingFace documentation (mid-Jan 2023) indicates that
transformers models will be cached into a "transformers" subdirectory, The legacy location for transformers used to be global_cache_dir('transformers')
but in practice they seem to go into "hub". But if needed: and global_cache_dir('diffusers') for diffusers.
global_cache_dir('transformers')
One other caveat is that HuggingFace is moving some diffusers models
into the "hub" subdirectory as well, so this will need to be revisited
from time to time.
""" """
home: str = os.getenv("HF_HOME") home: str = os.getenv("HF_HOME")
@ -115,7 +112,7 @@ def global_cache_dir(subdir: Union[str, Path] = "") -> Path:
home = os.getenv("XDG_CACHE_HOME") home = os.getenv("XDG_CACHE_HOME")
if home is not None: if home is not None:
# Set `home` to $XDG_CACHE_HOME/huggingface, which is the default location mentioned in HuggingFace Hub Client Library. # Set `home` to $XDG_CACHE_HOME/huggingface, which is the default location mentioned in Hugging Face Hub Client Library.
# See: https://huggingface.co/docs/huggingface_hub/main/en/package_reference/environment_variables#xdgcachehome # See: https://huggingface.co/docs/huggingface_hub/main/en/package_reference/environment_variables#xdgcachehome
home += os.sep + "huggingface" home += os.sep + "huggingface"

View File

@ -6,5 +6,4 @@ from .convert_ckpt_to_diffusers import (
load_pipeline_from_original_stable_diffusion_ckpt, load_pipeline_from_original_stable_diffusion_ckpt,
) )
from .model_manager import ModelManager from .model_manager import ModelManager
from invokeai.frontend.merge import merge_diffusion_models

View File

@ -1101,14 +1101,17 @@ def load_pipeline_from_original_stable_diffusion_ckpt(
if original_config_file is None: if original_config_file is None:
model_type = ModelManager.probe_model_type(checkpoint) model_type = ModelManager.probe_model_type(checkpoint)
if model_type == SDLegacyType.V2: if model_type == SDLegacyType.V2_v:
original_config_file = ( original_config_file = (
global_config_dir() / "stable-diffusion" / "v2-inference-v.yaml" global_config_dir() / "stable-diffusion" / "v2-inference-v.yaml"
) )
if global_step == 110000: if global_step == 110000:
# v2.1 needs to upcast attention # v2.1 needs to upcast attention
upcast_attention = True upcast_attention = True
elif model_type == SDLegacyType.V2_e:
original_config_file = (
global_config_dir() / "stable-diffusion" / "v2-inference.yaml"
)
elif model_type == SDLegacyType.V1_INPAINT: elif model_type == SDLegacyType.V1_INPAINT:
original_config_file = ( original_config_file = (
global_config_dir() global_config_dir()

View File

@ -40,16 +40,16 @@ from ..util import CPU_DEVICE, ask_user, download_with_resume
class SDLegacyType(Enum): class SDLegacyType(Enum):
V1 = 1 V1 = 1
V1_INPAINT = 2 V1_INPAINT = 2
V2 = 3 V2 = 3
V2_e = 4
V2_v = 5
UNKNOWN = 99 UNKNOWN = 99
DEFAULT_MAX_MODELS = 2 DEFAULT_MAX_MODELS = 2
VAE_TO_REPO_ID = { # hack, see note in convert_and_import() VAE_TO_REPO_ID = { # hack, see note in convert_and_import()
"vae-ft-mse-840000-ema-pruned": "stabilityai/sd-vae-ft-mse", "vae-ft-mse-840000-ema-pruned": "stabilityai/sd-vae-ft-mse",
} }
class ModelManager(object): class ModelManager(object):
def __init__( def __init__(
self, self,
@ -335,10 +335,23 @@ class ModelManager(object):
tic = time.time() tic = time.time()
with warnings.catch_warnings(): # this does the work
warnings.simplefilter("ignore") model_format = mconfig.get("format", "ckpt")
model, width, height, model_hash = self._load_diffusers_model(mconfig) if model_format == "ckpt":
weights = mconfig.weights
print(f">> Loading {model_name} from {weights}")
model, width, height, model_hash = self._load_ckpt_model(
model_name, mconfig
)
elif model_format == "diffusers":
with warnings.catch_warnings():
warnings.simplefilter("ignore")
model, width, height, model_hash = self._load_diffusers_model(mconfig)
else:
raise NotImplementedError(
f"Unknown model format {model_name}: {model_format}"
)
# usage statistics # usage statistics
toc = time.time() toc = time.time()
print(">> Model loaded in", "%4.2fs" % (toc - tic)) print(">> Model loaded in", "%4.2fs" % (toc - tic))
@ -369,7 +382,7 @@ class ModelManager(object):
if vae := self._load_vae(mconfig["vae"]): if vae := self._load_vae(mconfig["vae"]):
pipeline_args.update(vae=vae) pipeline_args.update(vae=vae)
if not isinstance(name_or_path, Path): if not isinstance(name_or_path, Path):
pipeline_args.update(cache_dir=global_cache_dir("diffusers")) pipeline_args.update(cache_dir=global_cache_dir("hub"))
if using_fp16: if using_fp16:
pipeline_args.update(torch_dtype=torch.float16) pipeline_args.update(torch_dtype=torch.float16)
fp_args_list = [{"revision": "fp16"}, {}] fp_args_list = [{"revision": "fp16"}, {}]
@ -527,7 +540,7 @@ class ModelManager(object):
self, self,
repo_or_path: Union[str, Path], repo_or_path: Union[str, Path],
model_name: str = None, model_name: str = None,
model_description: str = None, description: str = None,
vae: dict = None, vae: dict = None,
commit_to_conf: Path = None, commit_to_conf: Path = None,
) -> bool: ) -> bool:
@ -569,15 +582,24 @@ class ModelManager(object):
format. Valid return values include: format. Valid return values include:
SDLegacyType.V1 SDLegacyType.V1
SDLegacyType.V1_INPAINT SDLegacyType.V1_INPAINT
SDLegacyType.V2 SDLegacyType.V2 (V2 prediction type unknown)
SDLegacyType.V2_e (V2 using 'epsilon' prediction type)
SDLegacyType.V2_v (V2 using 'v_prediction' prediction type)
SDLegacyType.UNKNOWN SDLegacyType.UNKNOWN
""" """
key_name = "model.diffusion_model.input_blocks.2.1.transformer_blocks.0.attn2.to_k.weight" global_step = checkpoint.get('global_step')
if key_name in checkpoint and checkpoint[key_name].shape[-1] == 1024: state_dict = checkpoint.get("state_dict") or checkpoint
return SDLegacyType.V2
try: try:
state_dict = checkpoint.get("state_dict") or checkpoint key_name = "model.diffusion_model.input_blocks.2.1.transformer_blocks.0.attn2.to_k.weight"
if key_name in state_dict and state_dict[key_name].shape[-1] == 1024:
if global_step == 220000:
return SDLegacyType.V2_e
elif global_step == 110000:
return SDLegacyType.V2_v
else:
return SDLegacyType.V2
# otherwise we assume a V1 file
in_channels = state_dict[ in_channels = state_dict[
"model.diffusion_model.input_blocks.0.0.weight" "model.diffusion_model.input_blocks.0.0.weight"
].shape[1] ].shape[1]
@ -591,12 +613,13 @@ class ModelManager(object):
return SDLegacyType.UNKNOWN return SDLegacyType.UNKNOWN
def heuristic_import( def heuristic_import(
self, self,
path_url_or_repo: str, path_url_or_repo: str,
convert: bool = True, convert: bool = True,
model_name: str = None, model_name: str = None,
description: str = None, description: str = None,
commit_to_conf: Path = None, model_config_file: Path = None,
commit_to_conf: Path = None,
) -> str: ) -> str:
""" """
Accept a string which could be: Accept a string which could be:
@ -693,7 +716,7 @@ class ModelManager(object):
if model_path.stem in self.config: # already imported if model_path.stem in self.config: # already imported
print(" | Already imported. Skipping") print(" | Already imported. Skipping")
return return model_path.stem
# another round of heuristics to guess the correct config file. # another round of heuristics to guess the correct config file.
checkpoint = ( checkpoint = (
@ -701,32 +724,46 @@ class ModelManager(object):
if model_path.suffix == ".safetensors" if model_path.suffix == ".safetensors"
else torch.load(model_path) else torch.load(model_path)
) )
model_type = self.probe_model_type(checkpoint)
model_config_file = None # additional probing needed if no config file provided
if model_type == SDLegacyType.V1: if model_config_file is None:
print(" | SD-v1 model detected") model_type = self.probe_model_type(checkpoint)
model_config_file = Path( if model_type == SDLegacyType.V1:
Globals.root, "configs/stable-diffusion/v1-inference.yaml" print(" | SD-v1 model detected")
) model_config_file = Path(
elif model_type == SDLegacyType.V1_INPAINT: Globals.root, "configs/stable-diffusion/v1-inference.yaml"
print(" | SD-v1 inpainting model detected") )
model_config_file = Path( elif model_type == SDLegacyType.V1_INPAINT:
Globals.root, "configs/stable-diffusion/v1-inpainting-inference.yaml" print(" | SD-v1 inpainting model detected")
) model_config_file = Path(
elif model_type == SDLegacyType.V2: Globals.root, "configs/stable-diffusion/v1-inpainting-inference.yaml"
print( )
" | SD-v2 model detected; model will be converted to diffusers format" elif model_type == SDLegacyType.V2_v:
) print(
model_config_file = Path( " | SD-v2-v model detected; model will be converted to diffusers format"
Globals.root, "configs/stable-diffusion/v2-inference-v.yaml" )
) model_config_file = Path(
convert = True Globals.root, "configs/stable-diffusion/v2-inference-v.yaml"
else: )
print( convert = True
f"** {thing} is a legacy checkpoint file but not in a known Stable Diffusion model. Skipping import" elif model_type == SDLegacyType.V2_e:
) print(
return " | SD-v2-e model detected; model will be converted to diffusers format"
)
model_config_file = Path(
Globals.root, "configs/stable-diffusion/v2-inference.yaml"
)
convert = True
elif model_type == SDLegacyType.V2:
print(
f"** {thing} is a V2 checkpoint file, but its parameterization cannot be determined. Please provide configuration file path."
)
return
else:
print(
f"** {thing} is a legacy checkpoint file but not a known Stable Diffusion model. Please provide configuration file path."
)
return
diffuser_path = Path( diffuser_path = Path(
Globals.root, "models", Globals.converted_ckpts_dir, model_path.stem Globals.root, "models", Globals.converted_ckpts_dir, model_path.stem
@ -916,27 +953,40 @@ class ModelManager(object):
to the 2.3.0 "diffusers" version. This should be a one-time operation, called at to the 2.3.0 "diffusers" version. This should be a one-time operation, called at
script startup time. script startup time.
""" """
# Three transformer models to check: bert, clip and safety checker # Three transformer models to check: bert, clip and safety checker, and
# the diffusers as well
models_dir = Path(Globals.root, "models")
legacy_locations = [ legacy_locations = [
Path( Path(
models_dir,
"CompVis/stable-diffusion-safety-checker/models--CompVis--stable-diffusion-safety-checker" "CompVis/stable-diffusion-safety-checker/models--CompVis--stable-diffusion-safety-checker"
), ),
Path("bert-base-uncased/models--bert-base-uncased"), Path(models_dir, "bert-base-uncased/models--bert-base-uncased"),
Path( Path(
models_dir,
"openai/clip-vit-large-patch14/models--openai--clip-vit-large-patch14" "openai/clip-vit-large-patch14/models--openai--clip-vit-large-patch14"
), ),
] ]
models_dir = Path(Globals.root, "models") legacy_locations.extend(list(global_cache_dir("diffusers").glob('*')))
legacy_layout = False legacy_layout = False
for model in legacy_locations: for model in legacy_locations:
legacy_layout = legacy_layout or Path(models_dir, model).exists() legacy_layout = legacy_layout or model.exists()
if not legacy_layout: if not legacy_layout:
return return
print( print(
"** Legacy version <= 2.2.5 model directory layout detected. Reorganizing." """
>> ALERT:
>> The location of your previously-installed diffusers models needs to move from
>> invokeai/models/diffusers to invokeai/models/hub due to a change introduced by
>> diffusers version 0.14. InvokeAI will now move all models from the "diffusers" directory
>> into "hub" and then remove the diffusers directory. This is a quick, safe, one-time
>> operation. However if you have customized either of these directories and need to
>> make adjustments, please press ctrl-C now to abort and relaunch InvokeAI when you are ready.
>> Otherwise press <enter> to continue."""
) )
print("** This is a quick one-time operation.") input('continue> ')
# transformer files get moved into the hub directory # transformer files get moved into the hub directory
if cls._is_huggingface_hub_directory_present(): if cls._is_huggingface_hub_directory_present():
@ -948,33 +998,20 @@ class ModelManager(object):
for model in legacy_locations: for model in legacy_locations:
source = models_dir / model source = models_dir / model
dest = hub / model.stem dest = hub / model.stem
if dest.exists() and not source.exists():
continue
print(f"** {source} => {dest}") print(f"** {source} => {dest}")
if source.exists(): if source.exists():
if dest.exists(): if dest.is_symlink():
rmtree(source) print(f"** Found symlink at {dest.name}. Not migrating.")
elif dest.exists():
if source.is_dir():
rmtree(source)
else:
source.unlink()
else: else:
move(source, dest) move(source, dest)
# anything else gets moved into the diffusers directory
if cls._is_huggingface_hub_directory_present():
diffusers = global_cache_dir("diffusers")
else:
diffusers = models_dir / "diffusers"
os.makedirs(diffusers, exist_ok=True)
for root, dirs, _ in os.walk(models_dir, topdown=False):
for dir in dirs:
full_path = Path(root, dir)
if full_path.is_relative_to(hub) or full_path.is_relative_to(diffusers):
continue
if Path(dir).match("models--*--*"):
dest = diffusers / dir
print(f"** {full_path} => {dest}")
if dest.exists():
rmtree(full_path)
else:
move(full_path, dest)
# now clean up by removing any empty directories # now clean up by removing any empty directories
empty = [ empty = [
root root
@ -1072,7 +1109,7 @@ class ModelManager(object):
path = name_or_path path = name_or_path
else: else:
owner, repo = name_or_path.split("/") owner, repo = name_or_path.split("/")
path = Path(global_cache_dir("diffusers") / f"models--{owner}--{repo}") path = Path(global_cache_dir("hub") / f"models--{owner}--{repo}")
if not path.exists(): if not path.exists():
return None return None
hashpath = path / "checksum.sha256" hashpath = path / "checksum.sha256"
@ -1133,7 +1170,7 @@ class ModelManager(object):
using_fp16 = self.precision == "float16" using_fp16 = self.precision == "float16"
vae_args.update( vae_args.update(
cache_dir=global_cache_dir("diffusers"), cache_dir=global_cache_dir("hub"),
local_files_only=not Globals.internet_available, local_files_only=not Globals.internet_available,
) )
@ -1172,7 +1209,7 @@ class ModelManager(object):
@staticmethod @staticmethod
def _delete_model_from_cache(repo_id): def _delete_model_from_cache(repo_id):
cache_info = scan_cache_dir(global_cache_dir("diffusers")) cache_info = scan_cache_dir(global_cache_dir("hub"))
# I'm sure there is a way to do this with comprehensions # I'm sure there is a way to do this with comprehensions
# but the code quickly became incomprehensible! # but the code quickly became incomprehensible!

View File

@ -640,7 +640,7 @@ def do_textual_inversion_training(
assert ( assert (
pretrained_model_name_or_path pretrained_model_name_or_path
), f"models.yaml error: neither 'repo_id' nor 'path' is defined for {model}" ), f"models.yaml error: neither 'repo_id' nor 'path' is defined for {model}"
pipeline_args = dict(cache_dir=global_cache_dir("diffusers")) pipeline_args = dict(cache_dir=global_cache_dir("hub"))
# Load tokenizer # Load tokenizer
if tokenizer_name: if tokenizer_name:

View File

@ -26,7 +26,7 @@ from ..args import APP_ID, APP_VERSION, Args, calculate_init_img_hash
from ..generator import infill_methods from ..generator import infill_methods
from ..globals import Globals, global_converted_ckpts_dir, global_models_dir from ..globals import Globals, global_converted_ckpts_dir, global_models_dir
from ..image_util import PngWriter, retrieve_metadata from ..image_util import PngWriter, retrieve_metadata
from ..model_management import merge_diffusion_models from ...frontend.merge.merge_diffusers import merge_diffusion_models
from ..prompting import ( from ..prompting import (
get_prompt_structure, get_prompt_structure,
get_tokenizer, get_tokenizer,

View File

@ -20,7 +20,7 @@ stable-diffusion-2.1:
recommended: True recommended: True
sd-inpainting-2.0: sd-inpainting-2.0:
description: Stable Diffusion version 2.0 inpainting model (5.21 GB) description: Stable Diffusion version 2.0 inpainting model (5.21 GB)
repo_id: stabilityai/stable-diffusion-2-1 repo_id: stabilityai/stable-diffusion-2-inpainting
format: diffusers format: diffusers
recommended: False recommended: False
analog-diffusion-1.0: analog-diffusion-1.0:

View File

@ -1,6 +1,6 @@
model: model:
base_learning_rate: 1.0e-4 base_learning_rate: 1.0e-4
target: invokeai.backend.models.diffusion.ddpm.LatentDiffusion target: invokeai.backend.stable_diffusion.diffusion.ddpm.LatentDiffusion
params: params:
parameterization: "v" parameterization: "v"
linear_start: 0.00085 linear_start: 0.00085

View File

@ -0,0 +1,67 @@
model:
base_learning_rate: 1.0e-4
target: invokeai.backend.stable_diffusion.diffusion.ddpm.LatentDiffusion
params:
linear_start: 0.00085
linear_end: 0.0120
num_timesteps_cond: 1
log_every_t: 200
timesteps: 1000
first_stage_key: "jpg"
cond_stage_key: "txt"
image_size: 64
channels: 4
cond_stage_trainable: false
conditioning_key: crossattn
monitor: val/loss_simple_ema
scale_factor: 0.18215
use_ema: False # we set this to false because this is an inference only config
unet_config:
target: invokeai.backend.stable_diffusion.diffusionmodules.openaimodel.UNetModel
params:
use_checkpoint: True
use_fp16: True
image_size: 32 # unused
in_channels: 4
out_channels: 4
model_channels: 320
attention_resolutions: [ 4, 2, 1 ]
num_res_blocks: 2
channel_mult: [ 1, 2, 4, 4 ]
num_head_channels: 64 # need to fix for flash-attn
use_spatial_transformer: True
use_linear_in_transformer: True
transformer_depth: 1
context_dim: 1024
legacy: False
first_stage_config:
target: invokeai.backend.stable_diffusion.autoencoder.AutoencoderKL
params:
embed_dim: 4
monitor: val/rec_loss
ddconfig:
#attn_type: "vanilla-xformers"
double_z: true
z_channels: 4
resolution: 256
in_channels: 3
out_ch: 3
ch: 128
ch_mult:
- 1
- 2
- 4
- 4
num_res_blocks: 2
attn_resolutions: []
dropout: 0.0
lossconfig:
target: torch.nn.Identity
cond_stage_config:
target: invokeai.backend.stable_diffusion.encoders.modules.FrozenOpenCLIPEmbedder
params:
freeze: True
layer: "penultimate"

View File

@ -19,7 +19,7 @@ import invokeai.version as invokeai
from ...backend import Generate, ModelManager from ...backend import Generate, ModelManager
from ...backend.args import Args, dream_cmd_from_png, metadata_dumps, metadata_from_png from ...backend.args import Args, dream_cmd_from_png, metadata_dumps, metadata_from_png
from ...backend.globals import Globals from ...backend.globals import Globals, global_config_dir
from ...backend.image_util import ( from ...backend.image_util import (
PngWriter, PngWriter,
make_grid, make_grid,
@ -66,6 +66,9 @@ def main():
Globals.sequential_guidance = args.sequential_guidance Globals.sequential_guidance = args.sequential_guidance
Globals.ckpt_convert = True # always true now Globals.ckpt_convert = True # always true now
# run any post-install patches needed
run_patches()
print(f">> Internet connectivity is {Globals.internet_available}") print(f">> Internet connectivity is {Globals.internet_available}")
if not args.conf: if not args.conf:
@ -658,7 +661,16 @@ def import_model(model_path: str, gen, opt, completer, convert=False):
) )
if not imported_name: if not imported_name:
print("** Import failed or was skipped") if config_file := _pick_configuration_file(completer):
imported_name = gen.model_manager.heuristic_import(
model_path,
model_name=model_name,
description=model_desc,
convert=convert,
model_config_file=config_file,
)
if not imported_name:
print("** Aborting import.")
return return
if not _verify_load(imported_name, gen): if not _verify_load(imported_name, gen):
@ -672,6 +684,46 @@ def import_model(model_path: str, gen, opt, completer, convert=False):
completer.update_models(gen.model_manager.list_models()) completer.update_models(gen.model_manager.list_models())
print(f">> {imported_name} successfully installed") print(f">> {imported_name} successfully installed")
def _pick_configuration_file(completer)->Path:
print(
"""
Please select the type of this model:
[1] A Stable Diffusion v1.x ckpt/safetensors model
[2] A Stable Diffusion v1.x inpainting ckpt/safetensors model
[3] A Stable Diffusion v2.x base model (512 pixels)
[4] A Stable Diffusion v2.x v-predictive model (768 pixels)
[5] Other (you will be prompted to enter the config file path)
[Q] I have no idea! Skip the import.
""")
choices = [
global_config_dir() / 'stable-diffusion' / x
for x in [
'v1-inference.yaml',
'v1-inpainting-inference.yaml',
'v2-inference.yaml',
'v2-inference-v.yaml',
]
]
ok = False
while not ok:
try:
choice = input('select 0-5, Q > ').strip()
if choice.startswith(('q','Q')):
return
if choice == '5':
completer.complete_extensions(('.yaml'))
choice = Path(input('Select config file for this model> ').strip()).absolute()
completer.complete_extensions(None)
ok = choice.exists()
else:
choice = choices[int(choice)-1]
ok = True
except (ValueError, IndexError):
print(f'{choice} is not a valid choice')
except EOFError:
return
return choice
def _verify_load(model_name: str, gen) -> bool: def _verify_load(model_name: str, gen) -> bool:
print(">> Verifying that new model loads...") print(">> Verifying that new model loads...")
@ -1236,6 +1288,21 @@ def check_internet() -> bool:
except: except:
return False return False
# This routine performs any patch-ups needed after installation
def run_patches():
# install ckpt configuration files that may have been added to the
# distro after original root directory configuration
import invokeai.configs as conf
from shutil import copyfile
root_configs = Path(global_config_dir(), 'stable-diffusion')
repo_configs = Path(conf.__path__[0], 'stable-diffusion')
if not root_configs.exists():
os.makedirs(root_configs, exist_ok=True)
for src in repo_configs.iterdir():
dest = root_configs / src.name
if not dest.exists():
copyfile(src, dest)
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -442,7 +442,7 @@ def main():
args = _parse_args() args = _parse_args()
global_set_root(args.root_dir) global_set_root(args.root_dir)
cache_dir = str(global_cache_dir("diffusers")) cache_dir = str(global_cache_dir("hub"))
os.environ[ os.environ[
"HF_HOME" "HF_HOME"
] = cache_dir # because not clear the merge pipeline is honoring cache_dir ] = cache_dir # because not clear the merge pipeline is honoring cache_dir

View File

@ -1,20 +1,43 @@
# InvokeAI UI dev setup # InvokeAI Web UI
The UI is in `invokeai/frontend`. The UI is a fairly straightforward Typescript React app. The only really fancy stuff is the Unified Canvas.
## Environment set up Code in `invokeai/frontend/web/` if you want to have a look.
Install [node](https://nodejs.org/en/download/) (includes npm) and ## Details
[yarn](https://yarnpkg.com/getting-started/install).
From `invokeai/frontend/` run `yarn install --immutable` to get everything set up. State management is Redux via [Redux Toolkit](https://github.com/reduxjs/redux-toolkit). Communication with server is a mix of HTTP and [socket.io](https://github.com/socketio/socket.io-client) (with a custom redux middleware to help).
## Dev [Chakra-UI](https://github.com/chakra-ui/chakra-ui) for components and styling.
[Konva](https://github.com/konvajs/react-konva) for the canvas, but we are pushing the limits of what is feasible with it (and HTML canvas in general). We plan to rebuild it with [PixiJS](https://github.com/pixijs/pixijs) to take advantage of WebGL's improved raster handling.
[Vite](https://vitejs.dev/) for bundling.
Localisation is via [i18next](https://github.com/i18next/react-i18next), but translation happens on our [Weblate](https://hosted.weblate.org/engage/invokeai/) project. Only the English source strings should be changed on this repo.
## Contributing
Thanks for your interest in contributing to the InvokeAI Web UI!
We encourage you to ping @psychedelicious and @blessedcoolant on [Discord](https://discord.gg/ZmtBAhwWhy) if you want to contribute, just to touch base and ensure your work doesn't conflict with anything else going on. The project is very active.
### Dev Environment
Install [node](https://nodejs.org/en/download/) and [yarn classic](https://classic.yarnpkg.com/lang/en/).
From `invokeai/frontend/web/` run `yarn install` to get everything set up.
Start everything in dev mode:
1. Start the dev server: `yarn dev` 1. Start the dev server: `yarn dev`
2. Start the InvokeAI UI per usual: `invokeai --web` 2. Start the InvokeAI UI per usual: `invokeai --web`
3. Point your browser to the dev server address e.g. `http://localhost:5173/` 3. Point your browser to the dev server address e.g. `http://localhost:5173/`
To build for dev: `yarn build-dev` ### Production builds
To build for production: `yarn build` For a number of technical and logistical reasons, we need to commit UI build artefacts to the repo.
If you submit a PR, there is a good chance we will ask you to include a separate commit with a build of the app.
To build for production, run `yarn build`.

View File

@ -0,0 +1,3 @@
'''
Initialization file for invokeai.frontend.web
'''

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -12,7 +12,7 @@
margin: 0; margin: 0;
} }
</style> </style>
<script type="module" crossorigin src="./assets/index-bcc89564.js"></script> <script type="module" crossorigin src="./assets/index-b928084d.js"></script>
<link rel="stylesheet" href="./assets/index-5483945c.css"> <link rel="stylesheet" href="./assets/index-5483945c.css">
</head> </head>

View File

@ -371,7 +371,8 @@
"convertToDiffusersHelpText6": "Do you wish to convert this model?", "convertToDiffusersHelpText6": "Do you wish to convert this model?",
"convertToDiffusersSaveLocation": "Save Location", "convertToDiffusersSaveLocation": "Save Location",
"v1": "v1", "v1": "v1",
"v2": "v2", "v2_base": "v2 (512px)",
"v2_768": "v2 (768px)",
"inpainting": "v1 Inpainting", "inpainting": "v1 Inpainting",
"customConfig": "Custom Config", "customConfig": "Custom Config",
"pathToCustomConfig": "Path To Custom Config", "pathToCustomConfig": "Path To Custom Config",

View File

@ -4,14 +4,14 @@
"version": "0.0.1", "version": "0.0.1",
"scripts": { "scripts": {
"prepare": "cd ../../../ && husky install invokeai/frontend/web/.husky", "prepare": "cd ../../../ && husky install invokeai/frontend/web/.husky",
"dev": "vite dev", "dev": "concurrently \"vite dev\" \"yarn run theme:watch\"",
"build": "npm run lint && vite build", "build": "yarn run lint && vite build",
"preview": "vite preview", "preview": "vite preview",
"lint:madge": "madge --circular src/main.tsx", "lint:madge": "madge --circular src/main.tsx",
"lint:eslint": "eslint --max-warnings=0", "lint:eslint": "eslint --max-warnings=0",
"lint:prettier": "prettier --check .", "lint:prettier": "prettier --check .",
"lint:tsc": "tsc --noEmit", "lint:tsc": "tsc --noEmit",
"lint": "npm run lint:eslint && npm run lint:prettier && npm run lint:tsc && npm run lint:madge", "lint": "yarn run lint:eslint && yarn run lint:prettier && yarn run lint:tsc && yarn run lint:madge",
"fix": "eslint --fix . && prettier --loglevel warn --write . && tsc --noEmit", "fix": "eslint --fix . && prettier --loglevel warn --write . && tsc --noEmit",
"lint-staged": "lint-staged", "lint-staged": "lint-staged",
"postinstall": "patch-package && yarn run theme", "postinstall": "patch-package && yarn run theme",
@ -38,6 +38,7 @@
"@chakra-ui/anatomy": "^2.1.1", "@chakra-ui/anatomy": "^2.1.1",
"@chakra-ui/icons": "^2.0.17", "@chakra-ui/icons": "^2.0.17",
"@chakra-ui/react": "^2.5.1", "@chakra-ui/react": "^2.5.1",
"@chakra-ui/styled-system": "^2.6.1",
"@chakra-ui/theme-tools": "^2.0.16", "@chakra-ui/theme-tools": "^2.0.16",
"@emotion/react": "^11.10.6", "@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6", "@emotion/styled": "^11.10.6",
@ -82,6 +83,7 @@
"@typescript-eslint/parser": "^5.52.0", "@typescript-eslint/parser": "^5.52.0",
"@vitejs/plugin-react-swc": "^3.2.0", "@vitejs/plugin-react-swc": "^3.2.0",
"babel-plugin-transform-imports": "^2.0.0", "babel-plugin-transform-imports": "^2.0.0",
"concurrently": "^7.6.0",
"eslint": "^8.34.0", "eslint": "^8.34.0",
"eslint-config-prettier": "^8.6.0", "eslint-config-prettier": "^8.6.0",
"eslint-plugin-prettier": "^4.2.1", "eslint-plugin-prettier": "^4.2.1",

View File

@ -371,7 +371,8 @@
"convertToDiffusersHelpText6": "Do you wish to convert this model?", "convertToDiffusersHelpText6": "Do you wish to convert this model?",
"convertToDiffusersSaveLocation": "Save Location", "convertToDiffusersSaveLocation": "Save Location",
"v1": "v1", "v1": "v1",
"v2": "v2", "v2_base": "v2 (512px)",
"v2_768": "v2 (768px)",
"inpainting": "v1 Inpainting", "inpainting": "v1 Inpainting",
"customConfig": "Custom Config", "customConfig": "Custom Config",
"pathToCustomConfig": "Path To Custom Config", "pathToCustomConfig": "Path To Custom Config",

View File

@ -363,7 +363,6 @@
"convertToDiffusersHelpText6": "¿Desea transformar este modelo?", "convertToDiffusersHelpText6": "¿Desea transformar este modelo?",
"convertToDiffusersSaveLocation": "Guardar ubicación", "convertToDiffusersSaveLocation": "Guardar ubicación",
"v1": "v1", "v1": "v1",
"v2": "v2",
"statusConverting": "Adaptar", "statusConverting": "Adaptar",
"modelConverted": "Modelo adaptado", "modelConverted": "Modelo adaptado",
"sameFolder": "La misma carpeta", "sameFolder": "La misma carpeta",

View File

@ -45,7 +45,9 @@
"statusUpscaling": "Mise à échelle", "statusUpscaling": "Mise à échelle",
"statusUpscalingESRGAN": "Mise à échelle (ESRGAN)", "statusUpscalingESRGAN": "Mise à échelle (ESRGAN)",
"statusLoadingModel": "Chargement du modèle", "statusLoadingModel": "Chargement du modèle",
"statusModelChanged": "Modèle changé" "statusModelChanged": "Modèle changé",
"discordLabel": "Discord",
"githubLabel": "Github"
}, },
"gallery": { "gallery": {
"generations": "Générations", "generations": "Générations",

View File

@ -92,7 +92,6 @@
"modelThree": "מודל 3", "modelThree": "מודל 3",
"mergedModelName": "שם מודל ממוזג", "mergedModelName": "שם מודל ממוזג",
"v1": "v1", "v1": "v1",
"v2": "v2",
"invokeRoot": "תיקיית InvokeAI", "invokeRoot": "תיקיית InvokeAI",
"customConfig": "תצורה מותאמת אישית", "customConfig": "תצורה מותאמת אישית",
"pathToCustomConfig": "נתיב לתצורה מותאמת אישית", "pathToCustomConfig": "נתיב לתצורה מותאמת אישית",

View File

@ -361,7 +361,6 @@
"convertToDiffusersHelpText5": "Assicurati di avere spazio su disco sufficiente. I modelli generalmente variano tra 4 GB e 7 GB di dimensioni.", "convertToDiffusersHelpText5": "Assicurati di avere spazio su disco sufficiente. I modelli generalmente variano tra 4 GB e 7 GB di dimensioni.",
"convertToDiffusersHelpText6": "Vuoi convertire questo modello?", "convertToDiffusersHelpText6": "Vuoi convertire questo modello?",
"convertToDiffusersSaveLocation": "Ubicazione salvataggio", "convertToDiffusersSaveLocation": "Ubicazione salvataggio",
"v2": "v2",
"inpainting": "v1 Inpainting", "inpainting": "v1 Inpainting",
"customConfig": "Configurazione personalizzata", "customConfig": "Configurazione personalizzata",
"statusConverting": "Conversione in corso", "statusConverting": "Conversione in corso",

View File

@ -302,7 +302,7 @@
"name": "Naam", "name": "Naam",
"nameValidationMsg": "Geef een naam voor je model", "nameValidationMsg": "Geef een naam voor je model",
"description": "Beschrijving", "description": "Beschrijving",
"descriptionValidationMsg": "Voeg een beschrijving toe voor je model", "descriptionValidationMsg": "Voeg een beschrijving toe voor je model.",
"config": "Configuratie", "config": "Configuratie",
"configValidationMsg": "Pad naar het configuratiebestand van je model.", "configValidationMsg": "Pad naar het configuratiebestand van je model.",
"modelLocation": "Locatie model", "modelLocation": "Locatie model",
@ -364,7 +364,6 @@
"convertToDiffusersHelpText5": "Zorg ervoor dat je genoeg schijfruimte hebt. Modellen nemen gewoonlijk ongeveer 4 - 7 GB ruimte in beslag.", "convertToDiffusersHelpText5": "Zorg ervoor dat je genoeg schijfruimte hebt. Modellen nemen gewoonlijk ongeveer 4 - 7 GB ruimte in beslag.",
"convertToDiffusersSaveLocation": "Bewaarlocatie", "convertToDiffusersSaveLocation": "Bewaarlocatie",
"v1": "v1", "v1": "v1",
"v2": "v2",
"inpainting": "v1-inpainting", "inpainting": "v1-inpainting",
"customConfig": "Eigen configuratie", "customConfig": "Eigen configuratie",
"pathToCustomConfig": "Pad naar eigen configuratie", "pathToCustomConfig": "Pad naar eigen configuratie",

View File

@ -358,7 +358,6 @@
"convertToDiffusersHelpText6": "Você deseja converter este modelo?", "convertToDiffusersHelpText6": "Você deseja converter este modelo?",
"convertToDiffusersSaveLocation": "Local para Salvar", "convertToDiffusersSaveLocation": "Local para Salvar",
"v1": "v1", "v1": "v1",
"v2": "v2",
"inpainting": "v1 Inpainting", "inpainting": "v1 Inpainting",
"customConfig": "Configuração personalizada", "customConfig": "Configuração personalizada",
"pathToCustomConfig": "Caminho para configuração personalizada", "pathToCustomConfig": "Caminho para configuração personalizada",
@ -381,7 +380,19 @@
"allModels": "Todos os Modelos", "allModels": "Todos os Modelos",
"repoIDValidationMsg": "Repositório Online do seu Modelo", "repoIDValidationMsg": "Repositório Online do seu Modelo",
"convert": "Converter", "convert": "Converter",
"convertToDiffusersHelpText2": "Este processo irá substituir sua entrada de Gerenciador de Modelos por uma versão Diffusers do mesmo modelo." "convertToDiffusersHelpText2": "Este processo irá substituir sua entrada de Gerenciador de Modelos por uma versão Diffusers do mesmo modelo.",
"mergedModelCustomSaveLocation": "Caminho Personalizado",
"mergedModelSaveLocation": "Local de Salvamento",
"interpolationType": "Tipo de Interpolação",
"ignoreMismatch": "Ignorar Divergências entre Modelos Selecionados",
"invokeAIFolder": "Pasta Invoke AI",
"weightedSum": "Soma Ponderada",
"sigmoid": "Sigmóide",
"inverseSigmoid": "Sigmóide Inversa",
"modelMergeHeaderHelp1": "Você pode mesclar até três modelos diferentes para criar uma mistura que atenda às suas necessidades.",
"modelMergeInterpAddDifferenceHelp": "Neste modo, o Modelo 3 é primeiro subtraído do Modelo 2. A versão resultante é mesclada com o Modelo 1 com a taxa alpha definida acima.",
"modelMergeAlphaHelp": "Alpha controla a força da mistura dos modelos. Valores de alpha mais baixos resultam em uma influência menor do segundo modelo.",
"modelMergeHeaderHelp2": "Apenas Diffusers estão disponíveis para mesclagem. Se você deseja mesclar um modelo de checkpoint, por favor, converta-o para Diffusers primeiro."
}, },
"parameters": { "parameters": {
"images": "Imagems", "images": "Imagems",
@ -441,7 +452,22 @@
"info": "Informações", "info": "Informações",
"deleteImage": "Apagar Imagem", "deleteImage": "Apagar Imagem",
"initialImage": "Imagem inicial", "initialImage": "Imagem inicial",
"showOptionsPanel": "Mostrar Painel de Opções" "showOptionsPanel": "Mostrar Painel de Opções",
"vSymmetryStep": "V Passo de Simetria",
"hSymmetryStep": "H Passo de Simetria",
"symmetry": "Simetria",
"copyImage": "Copiar imagem",
"negativePrompts": "Indicações negativas",
"hiresStrength": "Força da Alta Resolução",
"denoisingStrength": "A força de remoção de ruído",
"imageToImage": "Imagem para Imagem",
"cancel": {
"setType": "Definir tipo de cancelamento",
"isScheduled": "Cancelando",
"schedule": "Cancelar após a iteração atual",
"immediate": "Cancelar imediatamente"
},
"general": "Geral"
}, },
"settings": { "settings": {
"models": "Modelos", "models": "Modelos",
@ -454,7 +480,8 @@
"resetWebUI": "Reiniciar Interface", "resetWebUI": "Reiniciar Interface",
"resetWebUIDesc1": "Reiniciar a interface apenas reinicia o cache local do broswer para imagens e configurações lembradas. Não apaga nenhuma imagem do disco.", "resetWebUIDesc1": "Reiniciar a interface apenas reinicia o cache local do broswer para imagens e configurações lembradas. Não apaga nenhuma imagem do disco.",
"resetWebUIDesc2": "Se as imagens não estão aparecendo na galeria ou algo mais não está funcionando, favor tentar reiniciar antes de postar um problema no GitHub.", "resetWebUIDesc2": "Se as imagens não estão aparecendo na galeria ou algo mais não está funcionando, favor tentar reiniciar antes de postar um problema no GitHub.",
"resetComplete": "A interface foi reiniciada. Atualize a página para carregar." "resetComplete": "A interface foi reiniciada. Atualize a página para carregar.",
"useSlidersForAll": "Usar deslizadores para todas as opções"
}, },
"toast": { "toast": {
"tempFoldersEmptied": "Pasta de Arquivos Temporários Esvaziada", "tempFoldersEmptied": "Pasta de Arquivos Temporários Esvaziada",
@ -546,5 +573,20 @@
"betaDarkenOutside": "Escurecer Externamente", "betaDarkenOutside": "Escurecer Externamente",
"betaLimitToBox": "Limitar Para a Caixa", "betaLimitToBox": "Limitar Para a Caixa",
"betaPreserveMasked": "Preservar Máscarado" "betaPreserveMasked": "Preservar Máscarado"
},
"tooltip": {
"feature": {
"seed": "O valor da semente afeta o ruído inicial a partir do qual a imagem é formada. Você pode usar as sementes já existentes de imagens anteriores. 'Limiar de ruído' é usado para mitigar artefatos em valores CFG altos (experimente a faixa de 0-10), e o Perlin para adicionar ruído Perlin durante a geração: ambos servem para adicionar variação às suas saídas.",
"gallery": "A galeria exibe as gerações da pasta de saída conforme elas são criadas. As configurações são armazenadas em arquivos e acessadas pelo menu de contexto.",
"other": "Essas opções ativam modos alternativos de processamento para o Invoke. 'Seamless tiling' criará padrões repetidos na saída. 'High resolution' é uma geração em duas etapas com img2img: use essa configuração quando desejar uma imagem maior e mais coerente sem artefatos. Levará mais tempo do que o txt2img usual.",
"boundingBox": "A caixa delimitadora é a mesma que as configurações de largura e altura para Texto para Imagem ou Imagem para Imagem. Apenas a área na caixa será processada.",
"upscale": "Use o ESRGAN para ampliar a imagem imediatamente após a geração.",
"seamCorrection": "Controla o tratamento das emendas visíveis que ocorrem entre as imagens geradas no canvas.",
"faceCorrection": "Correção de rosto com GFPGAN ou Codeformer: o algoritmo detecta rostos na imagem e corrige quaisquer defeitos. Um valor alto mudará mais a imagem, resultando em rostos mais atraentes. Codeformer com uma fidelidade maior preserva a imagem original às custas de uma correção de rosto mais forte.",
"prompt": "Este é o campo de prompt. O prompt inclui objetos de geração e termos estilísticos. Você também pode adicionar peso (importância do token) no prompt, mas comandos e parâmetros de CLI não funcionarão.",
"infillAndScaling": "Gerencie os métodos de preenchimento (usados em áreas mascaradas ou apagadas do canvas) e a escala (útil para tamanhos de caixa delimitadora pequenos).",
"imageToImage": "Image to Image carrega qualquer imagem como inicial, que é então usada para gerar uma nova junto com o prompt. Quanto maior o valor, mais a imagem resultante mudará. Valores de 0.0 a 1.0 são possíveis, a faixa recomendada é de 0.25 a 0.75",
"variations": "Experimente uma variação com um valor entre 0,1 e 1,0 para mudar o resultado para uma determinada semente. Variações interessantes da semente estão entre 0,1 e 0,3."
}
} }
} }

View File

@ -1 +1,24 @@
{} {
"common": {
"nodes": "節點",
"img2img": "圖片轉圖片",
"langSimplifiedChinese": "簡體中文",
"statusError": "錯誤",
"statusDisconnected": "已中斷連線",
"statusConnected": "已連線",
"back": "返回",
"load": "載入",
"close": "關閉",
"langEnglish": "英語",
"settingsLabel": "設定",
"upload": "上傳",
"langArabic": "阿拉伯語",
"greenTheme": "綠色",
"lightTheme": "淺色",
"darkTheme": "深色",
"discordLabel": "Discord",
"nodesDesc": "使用Node生成圖像的系統正在開發中。敬請期待有關於這項功能的更新。",
"reportBugLabel": "回報錯誤",
"githubLabel": "GitHub"
}
}

View File

@ -163,7 +163,8 @@ export default function SearchModels() {
const configFiles = { const configFiles = {
v1: 'configs/stable-diffusion/v1-inference.yaml', v1: 'configs/stable-diffusion/v1-inference.yaml',
v2: 'configs/stable-diffusion/v2-inference-v.yaml', v2_base: 'configs/stable-diffusion/v2-inference-v.yaml',
v2_768: 'configs/stable-diffusion/v2-inference-v.yaml',
inpainting: 'configs/stable-diffusion/v1-inpainting-inference.yaml', inpainting: 'configs/stable-diffusion/v1-inpainting-inference.yaml',
custom: pathToConfig, custom: pathToConfig,
}; };
@ -372,8 +373,11 @@ export default function SearchModels() {
<Radio value="v1"> <Radio value="v1">
<Text fontSize="sm">{t('modelManager.v1')}</Text> <Text fontSize="sm">{t('modelManager.v1')}</Text>
</Radio> </Radio>
<Radio value="v2"> <Radio value="v2_base">
<Text fontSize="sm">{t('modelManager.v2')}</Text> <Text fontSize="sm">{t('modelManager.v2_base')}</Text>
</Radio>
<Radio value="v2_768">
<Text fontSize="sm">{t('modelManager.v2_768')}</Text>
</Radio> </Radio>
<Radio value="inpainting"> <Radio value="inpainting">
<Text fontSize="sm">{t('modelManager.inpainting')}</Text> <Text fontSize="sm">{t('modelManager.inpainting')}</Text>

View File

@ -1,40 +0,0 @@
@mixin Button(
$btn-color: rgb(45, 49, 53),
$btn-color-hover: rgb(65, 69, 73),
$btn-width: 100%,
$btn-height: 100%,
$icon-size: 20px
) {
// min-width: $btn-width;
// min-height: $btn-height;
// background-color: $btn-color;
// &:hover {
// background-color: $btn-color-hover;
// }
// &:disabled {
// background-color: var(--btn-base-color);
// &:hover {
// background-color: var(--btn-base-color);
// }
// }
// svg {
// width: $icon-size;
// height: $icon-size;
// color: var(--btn-svg-color);
// }
}
@mixin BaseButton {
// background-color: var(--btn-base-color);
// &:hover {
// background-color: var(--btn-base-color-hover);
// }
// &:disabled {
// &:hover {
// background-color: var(--btn-base-color);
// }
// }
}

View File

@ -1,159 +0,0 @@
// @media (max-width: 600px) {
// #root {
// .app-content {
// padding: 5px;
// .site-header {
// position: fixed;
// display: flex;
// height: 100px;
// z-index: 1;
// .site-header-left-side {
// position: absolute;
// display: flex;
// min-width: 145px;
// float: left;
// padding-left: 0;
// }
// .site-header-right-side {
// display: grid;
// grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
// grid-template-rows: 25px 25px 25px;
// grid-template-areas:
// 'logoSpace logoSpace logoSpace sampler sampler sampler'
// 'status status status status status status'
// 'btn1 btn2 btn3 btn4 btn5 btn6';
// row-gap: 15px;
// .chakra-popover__popper {
// grid-area: logoSpace;
// }
// > :nth-child(1).chakra-text {
// grid-area: status;
// width: 100%;
// display: flex;
// justify-content: center;
// }
// > :nth-child(2) {
// grid-area: sampler;
// display: flex;
// justify-content: center;
// align-items: center;
// select {
// width: 185px;
// margin-top: 10px;
// }
// .chakra-select__icon-wrapper {
// right: 10px;
// svg {
// margin-top: 10px;
// }
// }
// }
// > :nth-child(3) {
// grid-area: btn1;
// }
// > :nth-child(4) {
// grid-area: btn2;
// }
// > :nth-child(6) {
// grid-area: btn3;
// }
// > :nth-child(7) {
// grid-area: btn4;
// }
// > :nth-child(8) {
// grid-area: btn5;
// }
// > :nth-child(9) {
// grid-area: btn6;
// }
// }
// }
// .app-tabs {
// position: fixed;
// display: flex;
// flex-direction: column;
// row-gap: 15px;
// max-width: 100%;
// overflow: hidden;
// margin-top: 120px;
// .app-tabs-list {
// display: flex;
// justify-content: space-between;
// }
// .app-tabs-panels {
// overflow: hidden;
// overflow-y: scroll;
// .workarea-main {
// display: grid;
// grid-template-areas:
// 'workarea'
// 'options'
// 'gallery';
// row-gap: 15px;
// .parameters-panel-wrapper {
// grid-area: options;
// width: 100%;
// max-width: 100%;
// height: inherit;
// overflow: inherit;
// padding: 0 10px;
// .main-settings-row {
// max-width: 100%;
// }
// .advanced-parameters-item {
// max-width: 100%;
// }
// }
// .workarea-children-wrapper {
// grid-area: workarea;
// .workarea-split-view {
// display: flex;
// flex-direction: column;
// }
// .current-image-options {
// column-gap: 3px;
// }
// .text-to-image-area {
// padding: 0;
// }
// .current-image-preview {
// height: 430px;
// }
// //image 2 image
// .image-upload-button {
// row-gap: 10px;
// padding: 5px;
// svg {
// width: 2rem;
// height: 2rem;
// margin-top: 10px;
// }
// }
// //Cavas Painting
// .inpainting-settings {
// display: flex;
// flex-wrap: wrap;
// row-gap: 10px;
// }
// .inpainting-canvas-area {
// .konvajs-content {
// height: 400px !important;
// }
// }
// }
// .image-gallery-wrapper {
// grid-area: gallery;
// min-height: 400px;
// .image-gallery-popup {
// width: 100% !important;
// max-width: 100% !important;
// }
// }
// }
// }
// }
// }
// }
// }

View File

@ -1,7 +0,0 @@
@mixin HideScrollbar {
-ms-overflow-style: none;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
}

View File

@ -1,20 +0,0 @@
// Calc Values
$app-cutoff: 0px;
$app-content-height-cutoff: calc(70px + 1rem); // default: 7rem
// Usage Variables
// app
$app-padding: 1rem;
$progress-bar-thickness: 0.3rem;
$app-width: calc(100vw - $app-cutoff);
$app-height: calc(100vh - $progress-bar-thickness);
$app-content-height: calc(100vh - $app-content-height-cutoff);
$app-gallery-height: calc(100vh - ($app-content-height-cutoff + 5.5rem));
$app-gallery-popover-height: calc(100vh - ($app-content-height-cutoff + 6rem));
$app-metadata-height: calc(100vh - ($app-content-height-cutoff + 4.4rem));
$app-text-to-image-height: calc(
100vh - 9.4375rem - 1.925rem - 1.15rem
); // do not touch ffs
// option bar
$options-bar-max-width: 22.5rem;

View File

@ -1,4 +0,0 @@
@forward './Shared';
@forward './Buttons';
@forward './Variables';
@forward './Responsive';

View File

@ -1,143 +0,0 @@
[data-theme='asdf'] {
// General Colors
--white: rgb(255, 255, 255);
// Accent Colors
--accent-color-dim: rgb(57, 25, 153);
--accent-color: rgb(80, 40, 200);
--accent-color-bright: rgb(104, 60, 230);
--accent-color-hover: var(--accent-color-bright);
// App Colors
--root-bg-color: rgb(10, 10, 10);
--background-color: rgb(26, 26, 32);
--background-color-light: rgb(40, 44, 48);
--background-color-secondary: rgb(16, 16, 22);
--text-color: rgb(255, 255, 255);
--text-color-secondary: rgb(160, 162, 188);
--subtext-color: rgb(24, 24, 34);
--subtext-color-bright: rgb(48, 48, 64);
--border-color: rgb(30, 30, 46);
--border-color-light: rgb(60, 60, 76);
--svg-color: rgb(255, 255, 255);
--invalid: rgb(255, 75, 75);
--invalid-secondary: rgb(120, 5, 5);
--destructive-color: rgb(185, 55, 55);
--destructive-color-hover: rgb(255, 75, 75);
--warning-color: rgb(200, 88, 40);
--warning-color-hover: rgb(230, 117, 60);
// Error status colors
--border-color-invalid: rgb(255, 80, 50);
--box-shadow-color-invalid: rgb(210, 30, 10);
// Tabs
--tab-color: rgb(30, 32, 42);
--tab-hover-color: rgb(46, 48, 58);
--tab-panel-bg: rgb(36, 38, 48);
--tab-list-bg: var(--accent-color);
--tab-list-text: rgb(202, 204, 216);
--tab-list-text-inactive: rgb(92, 94, 114);
// Button Colors
--btn-base-color: rgb(30, 32, 42);
--btn-base-color-hover: rgb(46, 48, 68);
--btn-load-more: rgb(30, 32, 42);
--btn-load-more-hover: rgb(54, 56, 66);
--btn-svg-color: rgb(255, 255, 255);
--btn-delete-image: rgb(182, 46, 46);
// IAI Button Colors
--btn-checkbox-border-hover: rgb(46, 48, 68);
// Progress Bar Color
--progress-bar-color: var(--accent-color);
// Prompt Box Colors
--prompt-bg-color: rgb(10, 10, 10);
// Switch
--switch-bg-color: rgb(100, 102, 110);
--switch-bg-active-color: var(--accent-color);
// Slider
--slider-color: var(--accent-color-bright);
// Slider
--slider-color: rgb(151, 113, 255);
--slider-mark-color: rgb(151, 113, 255);
// Resizable
--resizeable-handle-border-color: var(--accent-color);
// Metadata Viewer
--metadata-bg-color: rgba(0, 0, 0, 0.7);
--metadata-json-bg-color: rgba(255, 255, 255, 0.1);
// Status Message
--status-good-color: rgb(125, 255, 100);
--status-good-glow: rgb(40, 215, 40);
--status-working-color: rgb(255, 175, 55);
--status-working-glow: rgb(255, 160, 55);
--status-bad-color: rgb(255, 90, 90);
--status-bad-glow: rgb(255, 40, 40);
--notice-color: rgb(130, 71, 19);
// Settings Modal
--settings-modal-bg: rgb(30, 32, 42);
// Input
--input-checkbox-bg: rgb(60, 64, 68);
--input-checkbox-checked-bg: var(--accent-color);
--input-checkbox-checked-tick: rgb(0, 0, 0);
--input-border-color: var(--accent-color-bright);
--input-box-shadow-color: var(--accent-color);
// Console
--error-level-info: rgb(200, 202, 224);
--error-level-warning: rgb(255, 225, 105);
--error-level-error: rgb(255, 81, 46);
--console-bg-color: rgb(30, 30, 36);
--console-icon-button-bg-color: rgb(50, 53, 64);
--console-icon-button-bg-color-hover: rgb(70, 73, 84);
// Img2Img
--img2img-img-bg-color: rgb(30, 32, 42);
// Gallery
// Context Menus
--context-menu-bg-color: rgb(46, 48, 58);
--context-menu-box-shadow: none;
--context-menu-bg-color-hover: rgb(30, 32, 42);
// Shadows
--floating-button-drop-shadow-color: var(--accent-color);
// Canvas
--inpainting-alerts-bg: rgba(20, 20, 26, 0.75);
--inpainting-alerts-icon-color: rgb(255, 255, 255);
--inpainting-alerts-bg-active: var(--accent-color);
--inpainting-alerts-icon-active: rgb(255, 255, 255);
--inpainting-alerts-bg-alert: var(--invalid);
--inpainting-alerts-icon-alert: rgb(255, 255, 255);
// Checkerboard
--checkboard-dots-color: rgb(35, 35, 39);
// Scrollbar
--scrollbar-color: var(--accent-color);
--scrollbar-color-hover: var(--accent-color-bright);
// SubHook
--subhook-color: var(--accent-color);
}

View File

@ -1,141 +0,0 @@
[data-theme='green'] {
// General Colors
--white: rgb(255, 255, 255);
// Accent Colors
--accent-color-dim: rgb(10, 60, 40);
--accent-color: rgb(20, 110, 70);
--accent-color-bright: rgb(30, 180, 100);
--accent-color-hover: var(--accent-color-bright);
// App Colors
--root-bg-color: rgb(10, 10, 14);
--background-color: rgb(30, 32, 37);
--background-color-light: rgb(40, 44, 48);
--background-color-secondary: rgb(22, 24, 28);
--text-color: rgb(255, 255, 255);
--text-color-secondary: rgb(160, 164, 168);
--subtext-color: rgb(24, 24, 28);
--subtext-color-bright: rgb(68, 72, 76);
--border-color: rgb(40, 44, 48);
--border-color-light: rgb(60, 60, 64);
--svg-color: rgb(220, 224, 228);
--invalid: rgb(255, 75, 75);
--invalid-secondary: rgb(120, 5, 5);
--destructive-color: rgb(185, 55, 55);
--destructive-color-hover: rgb(255, 75, 75);
--warning-color: rgb(200, 88, 40);
--warning-color-hover: rgb(230, 117, 60);
// Error status colors
--border-color-invalid: rgb(255, 80, 50);
--box-shadow-color-invalid: rgb(210, 30, 10);
// Tabs
--tab-color: rgb(40, 44, 48);
--tab-hover-color: rgb(48, 52, 56); //done
--tab-panel-bg: rgb(36, 40, 44);
--tab-list-bg: var(--accent-color);
--tab-list-text: rgb(202, 204, 206);
--tab-list-text-inactive: rgb(92, 94, 96); //done
// Button Colors
--btn-base-color: rgb(40, 44, 48);
--btn-base-color-hover: rgb(56, 60, 64);
--btn-load-more: rgb(30, 32, 42);
--btn-load-more-hover: rgb(54, 56, 66);
--btn-svg-color: rgb(255, 255, 255);
--btn-delete-image: rgb(182, 46, 46);
// IAI Button Colors
--btn-checkbox-border-hover: rgb(46, 48, 68);
// Progress Bar Color
--progress-bar-color: var(--accent-color);
// Prompt Box Colors
--prompt-bg-color: rgb(10, 10, 14);
// Switch
--switch-bg-color: rgb(100, 102, 110);
--switch-bg-active-color: var(--accent-color);
// Slider
--slider-color: var(--accent-color-bright);
--slider-mark-color: var(--accent-color-bright);
// Resizable
--resizeable-handle-border-color: var(--accent-color);
// Metadata Viewer
--metadata-bg-color: rgba(0, 0, 0, 0.7);
--metadata-json-bg-color: rgba(255, 255, 255, 0.1);
// Status Message
--status-good-color: rgb(125, 255, 100);
--status-good-glow: rgb(40, 215, 40);
--status-working-color: rgb(255, 175, 55);
--status-working-glow: rgb(255, 160, 55);
--status-bad-color: rgb(255, 90, 90);
--status-bad-glow: rgb(255, 40, 40);
--notice-color: rgb(130, 71, 19);
// Settings Modal
--settings-modal-bg: rgb(30, 32, 42);
// Input
--input-checkbox-bg: rgb(60, 64, 68);
--input-checkbox-checked-bg: var(--accent-color);
--input-checkbox-checked-tick: rgb(0, 0, 0);
--input-border-color: var(--accent-color-bright);
--input-box-shadow-color: var(--accent-color);
// Console
--error-level-info: rgb(200, 202, 224);
--error-level-warning: rgb(255, 225, 105);
--error-level-error: rgb(255, 81, 46);
--console-bg-color: rgb(30, 30, 36);
--console-icon-button-bg-color: rgb(50, 53, 64);
--console-icon-button-bg-color-hover: rgb(70, 73, 84);
// Img2Img
--img2img-img-bg-color: rgb(30, 32, 42);
// Gallery
// Context Menus
--context-menu-bg-color: rgb(46, 48, 58);
--context-menu-box-shadow: none;
--context-menu-bg-color-hover: rgb(30, 32, 42);
// Shadows
--floating-button-drop-shadow-color: var(--accent-color);
// Canvas
--inpainting-alerts-bg: rgba(20, 20, 26, 0.75);
--inpainting-alerts-icon-color: rgb(255, 255, 255);
--inpainting-alerts-bg-active: var(--accent-color);
--inpainting-alerts-icon-active: rgb(255, 255, 255);
--inpainting-alerts-bg-alert: var(--invalid);
--inpainting-alerts-icon-alert: rgb(255, 255, 255);
//Checkerboard
--checkboard-dots-color: rgb(35, 35, 39);
// Scrollbar
--scrollbar-color: var(--accent-color);
--scrollbar-color-hover: var(--accent-color-bright);
// SubHook
--subhook-color: var(--accent-color);
}

View File

@ -1,138 +0,0 @@
// [data-theme='light'] {
// // General Colors
// --white: rgb(255, 255, 255);
// // Accent Colors
// --accent-color-dim: rgb(186, 146, 0);
// --accent-color: rgb(235, 185, 5);
// --accent-color-bright: rgb(255, 200, 0);
// --accent-color-hover: var(--accent-color-bright);
// // App Colors
// --root-bg-color: rgb(255, 255, 255);
// --background-color: rgb(220, 222, 224);
// --background-color-light: rgb(250, 252, 254);
// --background-color-secondary: rgb(208, 210, 212);
// --text-color: rgb(0, 0, 0);
// --text-color-secondary: rgb(40, 40, 40);
// --subtext-color: rgb(24, 24, 34);
// --subtext-color-bright: rgb(142, 144, 146);
// --border-color: rgb(200, 200, 200);
// --border-color-light: rgb(147, 147, 147);
// --svg-color: rgb(50, 50, 50);
// --invalid: rgb(255, 75, 75);
// --invalid-secondary: rgb(120, 5, 5);
// --destructive-color: rgb(237, 51, 51);
// --destructive-color-hover: rgb(255, 55, 55);
// --warning-color: rgb(224, 142, 42);
// --warning-color-hover: rgb(255, 167, 60);
// // Error status colors
// --border-color-invalid: rgb(255, 80, 50);
// --box-shadow-color-invalid: none;
// // Tabs
// --tab-color: rgb(202, 204, 206);
// --tab-hover-color: rgb(196, 198, 200);
// --tab-panel-bg: rgb(206, 208, 210);
// --tab-list-bg: rgb(235, 185, 5);
// --tab-list-text: rgb(0, 0, 0);
// --tab-list-text-inactive: rgb(106, 108, 110);
// // Button Colors
// --btn-base-color: rgb(184, 186, 188);
// --btn-base-color-hover: rgb(230, 232, 234);
// --btn-load-more: rgb(202, 204, 206);
// --btn-load-more-hover: rgb(178, 180, 182);
// --btn-svg-color: rgb(0, 0, 0);
// --btn-delete-image: rgb(213, 49, 49);
// // IAI Button Colors
// --btn-checkbox-border-hover: rgb(176, 178, 182);
// // Progress Bar Color
// --progress-bar-color: rgb(235, 185, 5);
// // Prompt Box Colors
// --prompt-bg-color: rgb(225, 227, 229);
// // Switch
// --switch-bg-color: rgb(178, 180, 182);
// --switch-bg-active-color: rgb(235, 185, 5);
// // Slider
// --slider-color: var(--accent-color);
// --slider-mark-color: rgb(0, 0, 0);
// // Resizable
// --resizeable-handle-border-color: rgb(160, 162, 164);
// // Metadata Viewer
// --metadata-bg-color: rgba(230, 230, 230, 0.9);
// --metadata-json-bg-color: rgba(0, 0, 0, 0.1);
// // Status Message
// --status-good-color: rgb(21, 126, 0);
// --status-good-glow: var(--background-color);
// --status-working-color: rgb(235, 141, 0);
// --status-working-glow: var(--background-color);
// --status-bad-color: rgb(202, 0, 0);
// --status-bad-glow: var(--background-color);
// --notice-color: rgb(255, 71, 90);
// // Settings Modal
// --settings-modal-bg: rgb(202, 204, 206);
// // Input
// --input-checkbox-bg: rgb(167, 167, 171);
// --input-checkbox-checked-bg: rgb(235, 185, 5);
// --input-checkbox-checked-tick: rgb(0, 0, 0);
// --input-border-color: rgb(0, 0, 0);
// --input-box-shadow-color: none;
// // Console
// --error-level-info: rgb(42, 42, 42);
// --error-level-warning: rgb(173, 121, 0);
// --error-level-error: rgb(145, 14, 0);
// --console-bg-color: rgb(220, 224, 230);
// --console-icon-button-bg-color: var(--switch-bg-color);
// --console-icon-button-bg-color-hover: var(--resizeable-handle-border-color);
// // Img2Img
// --img2img-img-bg-color: rgb(180, 182, 184);
// // Gallery
// // Context Menus
// --context-menu-bg-color: var(--background-color);
// --context-menu-box-shadow: 0px 10px 38px -10px rgba(22, 23, 24, 0.35),
// 0px 10px 20px -15px rgba(22, 23, 24, 0.2);
// --context-menu-bg-color-hover: var(--background-color-secondary);
// // Shadows
// --floating-button-drop-shadow-color: rgba(0, 0, 0, 0.7);
// // Canvas
// --inpainting-alerts-bg: rgba(220, 222, 224, 0.75);
// --inpainting-alerts-icon-color: rgb(0, 0, 0);
// --inpainting-alerts-bg-active: rgb(255, 200, 0);
// --inpainting-alerts-icon-active: rgb(0, 0, 0);
// --inpainting-alerts-bg-alert: var(--invalid);
// --inpainting-alerts-icon-alert: rgb(0, 0, 0);
// // Checkerboard
// --checkboard-dots-color: rgb(160, 160, 172);
// // Scrollbar
// --scrollbar-color: rgb(180, 180, 184);
// --scrollbar-color-hover: rgb(150, 150, 154);
// // SubHook
// --subhook-color: rgb(0, 0, 0);
// }

View File

@ -3,7 +3,6 @@ import {
createMultiStyleConfigHelpers, createMultiStyleConfigHelpers,
defineStyle, defineStyle,
} from '@chakra-ui/styled-system'; } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
const { definePartsStyle, defineMultiStyleConfig } = const { definePartsStyle, defineMultiStyleConfig } =
createMultiStyleConfigHelpers(parts.keys); createMultiStyleConfigHelpers(parts.keys);
@ -20,16 +19,16 @@ const invokeAIButton = defineStyle((props) => {
fontSize: 'sm', fontSize: 'sm',
border: 'none', border: 'none',
borderRadius: 'base', borderRadius: 'base',
bg: mode(`${c}.250`, `${c}.800`)(props), bg: `${c}.800`,
color: mode('base.900', 'base.100')(props), color: 'base.100',
_hover: { _hover: {
bg: mode(`${c}.300`, `${c}.700`)(props), bg: `${c}.700`,
}, },
_expanded: { _expanded: {
bg: mode(`${c}.250`, `${c}.750`)(props), bg: `${c}.750`,
borderBottomRadius: 'none', borderBottomRadius: 'none',
_hover: { _hover: {
bg: mode(`${c}.300`, `${c}.700`)(props), bg: `${c}.700`,
}, },
}, },
}; };
@ -38,7 +37,7 @@ const invokeAIButton = defineStyle((props) => {
const invokeAIPanel = defineStyle((props) => { const invokeAIPanel = defineStyle((props) => {
const { colorScheme: c } = props; const { colorScheme: c } = props;
return { return {
bg: mode(`${c}.200`, `${c}.800`)(props), bg: `${c}.800`,
borderRadius: 'base', borderRadius: 'base',
borderTopRadius: 'none', borderTopRadius: 'none',
p: 4, p: 4,

View File

@ -1,45 +1,44 @@
import { defineStyle, defineStyleConfig } from '@chakra-ui/react'; import { defineStyle, defineStyleConfig } from '@chakra-ui/react';
import { mode } from '@chakra-ui/theme-tools';
const invokeAI = defineStyle((props) => { const invokeAI = defineStyle((props) => {
const { colorScheme: c } = props; const { colorScheme: c } = props;
// must specify `_disabled` colors if we override `_hover`, else hover on disabled has no styles // must specify `_disabled` colors if we override `_hover`, else hover on disabled has no styles
const _disabled = { const _disabled = {
bg: mode(`${c}.200`, `${c}.600`)(props), bg: `${c}.600`,
color: mode(`${c}.700`, `${c}.100`)(props), color: `${c}.100`,
svg: { svg: {
fill: mode(`${c}.700`, `${c}.100`)(props), fill: `${c}.100`,
}, },
}; };
return { return {
bg: mode(`${c}.300`, `${c}.700`)(props), bg: `${c}.700`,
color: mode(`${c}.800`, `${c}.100`)(props), color: `${c}.100`,
borderRadius: 'base', borderRadius: 'base',
svg: { svg: {
fill: mode(`${c}.800`, `${c}.100`)(props), fill: `${c}.100`,
}, },
_disabled, _disabled,
_hover: { _hover: {
bg: mode(`${c}.400`, `${c}.650`)(props), bg: `${c}.650`,
color: mode(`black`, `${c}.50`)(props), color: `${c}.50`,
svg: { svg: {
fill: mode(`black`, `${c}.50`)(props), fill: `${c}.50`,
}, },
_disabled, _disabled,
}, },
_checked: { _checked: {
bg: mode('accent.200', 'accent.700')(props), bg: 'accent.700',
color: mode('accent.800', 'accent.100')(props), color: 'accent.100',
svg: { svg: {
fill: mode('accent.800', 'accent.100')(props), fill: 'accent.100',
}, },
_disabled, _disabled,
_hover: { _hover: {
bg: mode('accent.300', 'accent.600')(props), bg: 'accent.600',
color: mode('accent.900', 'accent.50')(props), color: 'accent.50',
svg: { svg: {
fill: mode('accent.900', 'accent.50')(props), fill: 'accent.50',
}, },
_disabled, _disabled,
}, },

View File

@ -3,7 +3,6 @@ import {
createMultiStyleConfigHelpers, createMultiStyleConfigHelpers,
defineStyle, defineStyle,
} from '@chakra-ui/styled-system'; } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
const { definePartsStyle, defineMultiStyleConfig } = const { definePartsStyle, defineMultiStyleConfig } =
createMultiStyleConfigHelpers(parts.keys); createMultiStyleConfigHelpers(parts.keys);
@ -13,31 +12,31 @@ const invokeAIControl = defineStyle((props) => {
return { return {
_checked: { _checked: {
bg: mode(`${c}.500`, `${c}.200`)(props), bg: `${c}.200`,
borderColor: mode(`${c}.500`, `${c}.200`)(props), borderColor: `${c}.200`,
color: mode('white', 'base.900')(props), color: 'base.900',
_hover: { _hover: {
bg: mode(`${c}.600`, `${c}.300`)(props), bg: `${c}.300`,
borderColor: mode(`${c}.600`, `${c}.300`)(props), borderColor: `${c}.300`,
}, },
_disabled: { _disabled: {
borderColor: mode('base.200', 'transparent')(props), borderColor: 'transparent',
bg: mode('base.200', 'whiteAlpha.300')(props), bg: 'whiteAlpha.300',
color: mode('base.500', 'whiteAlpha.500')(props), color: 'whiteAlpha.500',
}, },
}, },
_indeterminate: { _indeterminate: {
bg: mode(`${c}.500`, `${c}.200`)(props), bg: `${c}.200`,
borderColor: mode(`${c}.500`, `${c}.200`)(props), borderColor: `${c}.200`,
color: mode('white', 'base.900')(props), color: 'base.900',
}, },
_disabled: { _disabled: {
bg: mode('base.100', 'whiteAlpha.100')(props), bg: 'whiteAlpha.100',
borderColor: mode('base.100', 'transparent')(props), borderColor: 'transparent',
}, },
_focusVisible: { _focusVisible: {
@ -45,7 +44,7 @@ const invokeAIControl = defineStyle((props) => {
}, },
_invalid: { _invalid: {
borderColor: mode('red.500', 'red.300')(props), borderColor: 'red.300',
}, },
}; };
}); });

View File

@ -1,7 +1,6 @@
import { defineStyle, defineStyleConfig } from '@chakra-ui/styled-system'; import { defineStyle, defineStyleConfig } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
const invokeAI = defineStyle((props) => { const invokeAI = defineStyle((_props) => {
return { return {
fontSize: 'sm', fontSize: 'sm',
marginEnd: 0, marginEnd: 0,
@ -13,7 +12,7 @@ const invokeAI = defineStyle((props) => {
_disabled: { _disabled: {
opacity: 0.4, opacity: 0.4,
}, },
color: mode('base.600', 'base.300')(props), color: 'base.300',
}; };
}); });

View File

@ -3,7 +3,6 @@ import {
createMultiStyleConfigHelpers, createMultiStyleConfigHelpers,
defineStyle, defineStyle,
} from '@chakra-ui/styled-system'; } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
const { defineMultiStyleConfig, definePartsStyle } = const { defineMultiStyleConfig, definePartsStyle } =
createMultiStyleConfigHelpers(parts.keys); createMultiStyleConfigHelpers(parts.keys);
@ -14,18 +13,18 @@ const invokeAIOverlay = defineStyle({
const invokeAIDialogContainer = defineStyle({}); const invokeAIDialogContainer = defineStyle({});
const invokeAIDialog = defineStyle((props) => { const invokeAIDialog = defineStyle((_props) => {
return { return {
bg: mode('base.300', 'base.850')(props), bg: 'base.850',
maxH: '80vh', maxH: '80vh',
}; };
}); });
const invokeAIHeader = defineStyle((props) => { const invokeAIHeader = defineStyle((_props) => {
return { return {
fontWeight: '600', fontWeight: '600',
fontSize: 'lg', fontSize: 'lg',
color: mode('base.700', 'base.200')(props), color: 'base.200',
}; };
}); });

View File

@ -3,7 +3,7 @@ import {
createMultiStyleConfigHelpers, createMultiStyleConfigHelpers,
defineStyle, defineStyle,
} from '@chakra-ui/styled-system'; } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
import { getInputOutlineStyles } from '../util/getInputOutlineStyles'; import { getInputOutlineStyles } from '../util/getInputOutlineStyles';
const { defineMultiStyleConfig, definePartsStyle } = const { defineMultiStyleConfig, definePartsStyle } =
@ -33,7 +33,7 @@ const invokeAIStepperGroup = defineStyle((_props) => {
}; };
}); });
const invokeAIStepper = defineStyle((props) => { const invokeAIStepper = defineStyle((_props) => {
return { return {
border: 'none', border: 'none',
// expand arrow hitbox // expand arrow hitbox
@ -43,11 +43,11 @@ const invokeAIStepper = defineStyle((props) => {
my: 0, my: 0,
svg: { svg: {
color: mode('base.600', 'base.300')(props), color: 'base.300',
width: 2.5, width: 2.5,
height: 2.5, height: 2.5,
_hover: { _hover: {
color: mode('base.900', 'base.50')(props), color: 'base.50',
}, },
}, },
}; };

View File

@ -4,7 +4,6 @@ import {
defineStyle, defineStyle,
} from '@chakra-ui/styled-system'; } from '@chakra-ui/styled-system';
import { cssVar } from '@chakra-ui/theme-tools'; import { cssVar } from '@chakra-ui/theme-tools';
import { mode } from '@chakra-ui/theme-tools';
const { defineMultiStyleConfig, definePartsStyle } = const { defineMultiStyleConfig, definePartsStyle } =
createMultiStyleConfigHelpers(parts.keys); createMultiStyleConfigHelpers(parts.keys);
@ -13,7 +12,7 @@ const $popperBg = cssVar('popper-bg');
const $arrowBg = cssVar('popper-arrow-bg'); const $arrowBg = cssVar('popper-arrow-bg');
const $arrowShadowColor = cssVar('popper-arrow-shadow-color'); const $arrowShadowColor = cssVar('popper-arrow-shadow-color');
const invokeAIContent = defineStyle((props) => { const invokeAIContent = defineStyle((_props) => {
return { return {
[$arrowBg.variable]: `colors.base.800`, [$arrowBg.variable]: `colors.base.800`,
[$popperBg.variable]: `colors.base.800`, [$popperBg.variable]: `colors.base.800`,
@ -23,8 +22,8 @@ const invokeAIContent = defineStyle((props) => {
p: 4, p: 4,
borderWidth: '2px', borderWidth: '2px',
borderStyle: 'solid', borderStyle: 'solid',
borderColor: mode('base.500', 'base.600')(props), borderColor: 'base.600',
bg: mode('base.200', 'base.800')(props), bg: 'base.800',
}; };
}); });

View File

@ -3,25 +3,22 @@ import {
createMultiStyleConfigHelpers, createMultiStyleConfigHelpers,
defineStyle, defineStyle,
} from '@chakra-ui/styled-system'; } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
const { defineMultiStyleConfig, definePartsStyle } = const { defineMultiStyleConfig, definePartsStyle } =
createMultiStyleConfigHelpers(parts.keys); createMultiStyleConfigHelpers(parts.keys);
const invokeAIFilledTrack = defineStyle((props) => ({ const invokeAIFilledTrack = defineStyle((_props) => ({
bg: mode('accent.400', 'accent.600')(props), bg: 'accent.600',
transition: 'width 0.2s ease-in-out', transition: 'width 0.2s ease-in-out',
_indeterminate: { _indeterminate: {
bgGradient: `linear(to-r, transparent 0%, ${mode( bgGradient:
'accent.400', 'linear(to-r, transparent 0%, accent.600 50%, transparent 100%);',
'accent.600'
)(props)} 50%, transparent 100%);`,
}, },
})); }));
const invokeAITrack = defineStyle((props) => { const invokeAITrack = defineStyle((_props) => {
return { return {
bg: mode('base.300', 'base.800')(props), bg: 'base.800',
}; };
}); });

View File

@ -1,14 +1,13 @@
import { selectAnatomy as parts } from '@chakra-ui/anatomy'; import { selectAnatomy as parts } from '@chakra-ui/anatomy';
import { createMultiStyleConfigHelpers, defineStyle } from '@chakra-ui/react'; import { createMultiStyleConfigHelpers, defineStyle } from '@chakra-ui/react';
import { getInputOutlineStyles } from '../util/getInputOutlineStyles'; import { getInputOutlineStyles } from '../util/getInputOutlineStyles';
import { mode } from '@chakra-ui/theme-tools';
const { definePartsStyle, defineMultiStyleConfig } = const { definePartsStyle, defineMultiStyleConfig } =
createMultiStyleConfigHelpers(parts.keys); createMultiStyleConfigHelpers(parts.keys);
const invokeAIIcon = defineStyle((props) => { const invokeAIIcon = defineStyle((_props) => {
return { return {
color: mode('base.600', 'base.300')(props), color: 'base.300',
}; };
}); });

View File

@ -1,13 +1,12 @@
import { sliderAnatomy as parts } from '@chakra-ui/anatomy'; import { sliderAnatomy as parts } from '@chakra-ui/anatomy';
import { createMultiStyleConfigHelpers, defineStyle } from '@chakra-ui/react'; import { createMultiStyleConfigHelpers, defineStyle } from '@chakra-ui/react';
import { mode } from '@chakra-ui/theme-tools';
const { definePartsStyle, defineMultiStyleConfig } = const { definePartsStyle, defineMultiStyleConfig } =
createMultiStyleConfigHelpers(parts.keys); createMultiStyleConfigHelpers(parts.keys);
const invokeAITrack = defineStyle((props) => { const invokeAITrack = defineStyle((_props) => {
return { return {
bg: mode('base.300', 'base.400')(props), bg: 'base.400',
h: 1.5, h: 1.5,
}; };
}); });
@ -15,7 +14,7 @@ const invokeAITrack = defineStyle((props) => {
const invokeAIFilledTrack = defineStyle((props) => { const invokeAIFilledTrack = defineStyle((props) => {
const { colorScheme: c } = props; const { colorScheme: c } = props;
return { return {
bg: mode(`${c}.400`, `${c}.600`)(props), bg: `${c}.600`,
h: 1.5, h: 1.5,
}; };
}); });
@ -27,11 +26,11 @@ const invokeAIThumb = defineStyle((_props) => {
}; };
}); });
const invokeAIMark = defineStyle((props) => { const invokeAIMark = defineStyle((_props) => {
return { return {
fontSize: 'xs', fontSize: 'xs',
fontWeight: '500', fontWeight: '500',
color: mode('base.800', 'base.200')(props), color: 'base.200',
mt: 2, mt: 2,
insetInlineStart: 'unset', insetInlineStart: 'unset',
}; };

View File

@ -3,7 +3,6 @@ import {
createMultiStyleConfigHelpers, createMultiStyleConfigHelpers,
defineStyle, defineStyle,
} from '@chakra-ui/styled-system'; } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
const { defineMultiStyleConfig, definePartsStyle } = const { defineMultiStyleConfig, definePartsStyle } =
createMultiStyleConfigHelpers(parts.keys); createMultiStyleConfigHelpers(parts.keys);
@ -12,13 +11,13 @@ const invokeAITrack = defineStyle((props) => {
const { colorScheme: c } = props; const { colorScheme: c } = props;
return { return {
bg: mode(`base.400`, `base.600`)(props), bg: 'base.600',
_focusVisible: { _focusVisible: {
boxShadow: 'none', boxShadow: 'none',
}, },
_checked: { _checked: {
bg: mode(`${c}.400`, `${c}.600`)(props), bg: `${c}.600`,
}, },
}; };
}); });
@ -27,7 +26,7 @@ const invokeAIThumb = defineStyle((props) => {
const { colorScheme: c } = props; const { colorScheme: c } = props;
return { return {
bg: mode(`${c}.50`, `${c}.50`)(props), bg: `${c}.50`,
}; };
}); });

View File

@ -3,7 +3,6 @@ import {
createMultiStyleConfigHelpers, createMultiStyleConfigHelpers,
defineStyle, defineStyle,
} from '@chakra-ui/styled-system'; } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
const { defineMultiStyleConfig, definePartsStyle } = const { defineMultiStyleConfig, definePartsStyle } =
createMultiStyleConfigHelpers(parts.keys); createMultiStyleConfigHelpers(parts.keys);
@ -17,26 +16,26 @@ const invokeAIRoot = defineStyle((_props) => {
const invokeAITab = defineStyle((_props) => ({})); const invokeAITab = defineStyle((_props) => ({}));
const invokeAITablist = defineStyle((props) => ({ const invokeAITablist = defineStyle((_props) => ({
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
gap: 1, gap: 1,
color: mode('base.500', 'base.700')(props), color: 'base.700',
button: { button: {
fontSize: 'sm', fontSize: 'sm',
padding: 2, padding: 2,
borderRadius: 'base', borderRadius: 'base',
_selected: { _selected: {
bg: mode('accent.200', 'accent.700')(props), bg: 'accent.700',
color: mode('accent.800', 'accent.100')(props), color: 'accent.100',
_hover: { _hover: {
bg: mode('accent.300', 'accent.600')(props), bg: 'accent.600',
color: mode('accent.900', 'accent.50')(props), color: 'accent.50',
}, },
}, },
_hover: { _hover: {
bg: mode('base.300', 'base.600')(props), bg: 'base.600',
color: mode('base.900', 'base.50')(props), color: 'base.50',
}, },
}, },
})); }));

View File

@ -1,8 +1,7 @@
import { defineStyle, defineStyleConfig } from '@chakra-ui/react'; import { defineStyle, defineStyleConfig } from '@chakra-ui/react';
import { mode } from '@chakra-ui/theme-tools';
const subtext = defineStyle((props) => ({ const subtext = defineStyle((_props) => ({
color: mode('base.700', 'base.400')(props), color: 'base.400',
})); }));
export const textTheme = defineStyleConfig({ export const textTheme = defineStyleConfig({

View File

@ -1,6 +1,6 @@
import { ThemeOverride } from '@chakra-ui/react'; import { ThemeOverride } from '@chakra-ui/react';
import type { StyleFunctionProps } from '@chakra-ui/styled-system'; import type { StyleFunctionProps } from '@chakra-ui/styled-system';
import { mode } from '@chakra-ui/theme-tools';
import { invokeAIThemeColors } from './colors/invokeAI'; import { invokeAIThemeColors } from './colors/invokeAI';
import { accordionTheme } from './components/accordion'; import { accordionTheme } from './components/accordion';
import { buttonTheme } from './components/button'; import { buttonTheme } from './components/button';
@ -22,15 +22,13 @@ import { textareaTheme } from './components/textarea';
export const theme: ThemeOverride = { export const theme: ThemeOverride = {
config: { config: {
initialColorMode: 'dark',
useSystemColorMode: false,
cssVarPrefix: 'invokeai', cssVarPrefix: 'invokeai',
}, },
styles: { styles: {
global: (props: StyleFunctionProps) => ({ global: (_props: StyleFunctionProps) => ({
body: { body: {
bg: mode('base.100', 'base.900')(props), bg: 'base.900',
color: mode('base.800', 'base.50')(props), color: 'base.50',
overflow: 'hidden', overflow: 'hidden',
}, },
...scrollbar, ...scrollbar,

View File

@ -1,40 +1,40 @@
import { mode, StyleFunctionProps } from '@chakra-ui/theme-tools'; import { StyleFunctionProps } from '@chakra-ui/theme-tools';
export const getInputOutlineStyles = (props: StyleFunctionProps) => ({ export const getInputOutlineStyles = (_props: StyleFunctionProps) => ({
outline: 'none', outline: 'none',
borderWidth: 2, borderWidth: 2,
borderStyle: 'solid', borderStyle: 'solid',
borderColor: mode('base.300', 'base.800')(props), borderColor: 'base.800',
bg: mode('base.200', 'base.900')(props), bg: 'base.900',
borderRadius: 'base', borderRadius: 'base',
color: mode('base.900', 'base.100')(props), color: 'base.100',
boxShadow: 'none', boxShadow: 'none',
_hover: { _hover: {
borderColor: mode('base.500', 'base.600')(props), borderColor: 'base.600',
}, },
_focus: { _focus: {
borderColor: mode('accent.600', 'accent.700')(props), borderColor: 'accent.700',
boxShadow: 'none', boxShadow: 'none',
_hover: { _hover: {
borderColor: mode('accent.700', 'accent.600')(props), borderColor: 'accent.600',
}, },
}, },
_invalid: { _invalid: {
borderColor: mode('error.300', 'error.700')(props), borderColor: 'error.700',
boxShadow: 'none', boxShadow: 'none',
_hover: { _hover: {
borderColor: mode('error.500', 'error.600')(props), borderColor: 'error.600',
}, },
}, },
_disabled: { _disabled: {
borderColor: mode('base.300', 'base.700')(props), borderColor: 'base.700',
bg: mode('base.400', 'base.700')(props), bg: 'base.700',
color: mode('base.600', 'base.400')(props), color: 'base.400',
_hover: { _hover: {
borderColor: mode('base.300', 'base.700')(props), borderColor: 'base.700',
}, },
}, },
_placeholder: { _placeholder: {
color: mode('base.600', 'base.400')(props), color: 'base.400',
}, },
}); });

File diff suppressed because one or more lines are too long

View File

@ -734,7 +734,7 @@
"@chakra-ui/react-context" "2.0.7" "@chakra-ui/react-context" "2.0.7"
"@chakra-ui/shared-utils" "2.0.5" "@chakra-ui/shared-utils" "2.0.5"
"@chakra-ui/styled-system@2.6.1": "@chakra-ui/styled-system@2.6.1", "@chakra-ui/styled-system@^2.6.1":
version "2.6.1" version "2.6.1"
resolved "https://registry.yarnpkg.com/@chakra-ui/styled-system/-/styled-system-2.6.1.tgz#302d496d34c0b7b30c646a7e3c9b113a2f4588da" resolved "https://registry.yarnpkg.com/@chakra-ui/styled-system/-/styled-system-2.6.1.tgz#302d496d34c0b7b30c646a7e3c9b113a2f4588da"
integrity sha512-jy/1dVi1LxjoRCm+Eo5mqBgvPy5SCWMlIcz6GbIZBDpkGeKZwtqrZLjekxxLBCy8ORY+kJlUB0FT6AzVR/1tjw== integrity sha512-jy/1dVi1LxjoRCm+Eo5mqBgvPy5SCWMlIcz6GbIZBDpkGeKZwtqrZLjekxxLBCy8ORY+kJlUB0FT6AzVR/1tjw==
@ -2107,6 +2107,21 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
concurrently@^7.6.0:
version "7.6.0"
resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-7.6.0.tgz#531a6f5f30cf616f355a4afb8f8fcb2bba65a49a"
integrity sha512-BKtRgvcJGeZ4XttiDiNcFiRlxoAeZOseqUvyYRUp/Vtd+9p1ULmeoSqGsDA+2ivdeDFpqrJvGvmI+StKfKl5hw==
dependencies:
chalk "^4.1.0"
date-fns "^2.29.1"
lodash "^4.17.21"
rxjs "^7.0.0"
shell-quote "^1.7.3"
spawn-command "^0.0.2-1"
supports-color "^8.1.0"
tree-kill "^1.2.2"
yargs "^17.3.1"
configstore@^5.0.1: configstore@^5.0.1:
version "5.0.1" version "5.0.1"
resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96"
@ -2191,6 +2206,11 @@ csstype@^3.0.11, csstype@^3.0.2:
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9"
integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==
date-fns@^2.29.1:
version "2.29.3"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.3.tgz#27402d2fc67eb442b511b70bbdf98e6411cd68a8"
integrity sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==
dateformat@^5.0.3: dateformat@^5.0.3:
version "5.0.3" version "5.0.3"
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-5.0.3.tgz#fe2223eff3cc70ce716931cb3038b59a9280696e" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-5.0.3.tgz#fe2223eff3cc70ce716931cb3038b59a9280696e"
@ -4833,7 +4853,7 @@ run-parallel@^1.1.9:
dependencies: dependencies:
queue-microtask "^1.2.2" queue-microtask "^1.2.2"
rxjs@^7.8.0: rxjs@^7.0.0, rxjs@^7.8.0:
version "7.8.0" version "7.8.0"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4"
integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg== integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==
@ -4916,6 +4936,11 @@ shebang-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
shell-quote@^1.7.3:
version "1.8.0"
resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.0.tgz#20d078d0eaf71d54f43bd2ba14a1b5b9bfa5c8ba"
integrity sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ==
side-channel@^1.0.4: side-channel@^1.0.4:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
@ -5012,6 +5037,11 @@ source-map@^0.7.4:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656"
integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==
spawn-command@^0.0.2-1:
version "0.0.2-1"
resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0"
integrity sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==
stream-to-array@^2.3.0: stream-to-array@^2.3.0:
version "2.3.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/stream-to-array/-/stream-to-array-2.3.0.tgz#bbf6b39f5f43ec30bc71babcb37557acecf34353" resolved "https://registry.yarnpkg.com/stream-to-array/-/stream-to-array-2.3.0.tgz#bbf6b39f5f43ec30bc71babcb37557acecf34353"
@ -5151,6 +5181,13 @@ supports-color@^7.1.0:
dependencies: dependencies:
has-flag "^4.0.0" has-flag "^4.0.0"
supports-color@^8.1.0:
version "8.1.1"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
dependencies:
has-flag "^4.0.0"
supports-preserve-symlinks-flag@^1.0.0: supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
@ -5225,6 +5262,11 @@ tr46@~0.0.3:
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
tree-kill@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
ts-graphviz@^1.5.0: ts-graphviz@^1.5.0:
version "1.5.5" version "1.5.5"
resolved "https://registry.yarnpkg.com/ts-graphviz/-/ts-graphviz-1.5.5.tgz#b5e9079c18289fb36b6b53f3d81da96445c37514" resolved "https://registry.yarnpkg.com/ts-graphviz/-/ts-graphviz-1.5.5.tgz#b5e9079c18289fb36b6b53f3d81da96445c37514"
@ -5628,7 +5670,7 @@ yargs-parser@^21.1.1:
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
yargs@^17.5.1: yargs@^17.3.1, yargs@^17.5.1:
version "17.7.1" version "17.7.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967"
integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw== integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==