mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-01-15 08:28:14 -05:00
Compare commits
81 Commits
v5.0.0.rc2
...
v5.0.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c224971cb4 | ||
|
|
ca55ef1da5 | ||
|
|
3072d80171 | ||
|
|
d5f2f4dc4e | ||
|
|
b2552323b8 | ||
|
|
61d217e377 | ||
|
|
57a80c456a | ||
|
|
211b2f84ed | ||
|
|
ea4104c7c4 | ||
|
|
8b46c2dc53 | ||
|
|
9812b9676b | ||
|
|
6efa1597eb | ||
|
|
cd6ef3edb3 | ||
|
|
fcdbb729d3 | ||
|
|
c0657072ec | ||
|
|
7167a5d3f4 | ||
|
|
8cf0d8c8d3 | ||
|
|
48311f38ba | ||
|
|
7631d55c2a | ||
|
|
ea0dc09c64 | ||
|
|
a424552c82 | ||
|
|
ba8ef6ff0f | ||
|
|
3463a968c7 | ||
|
|
c256826015 | ||
|
|
7d38a9b7fb | ||
|
|
249da858df | ||
|
|
d332d81866 | ||
|
|
21017edcde | ||
|
|
4a8d0f4671 | ||
|
|
4ee037a7c3 | ||
|
|
9a49374e12 | ||
|
|
81a4c5c23c | ||
|
|
5217d931ae | ||
|
|
75bedf6709 | ||
|
|
bdeec54886 | ||
|
|
8d50ecdfc3 | ||
|
|
ba07e255f5 | ||
|
|
8efa0668e0 | ||
|
|
fae96f3b9f | ||
|
|
154cd7dd17 | ||
|
|
65ed771f6d | ||
|
|
00dd5dbbce | ||
|
|
5a053b645e | ||
|
|
3ca6c35212 | ||
|
|
eb0f3c42d5 | ||
|
|
843f507e16 | ||
|
|
fa6e0583bc | ||
|
|
39585ccac0 | ||
|
|
0fccd9936c | ||
|
|
841178ceb7 | ||
|
|
70a35cc25a | ||
|
|
29bd5834c8 | ||
|
|
35685194f3 | ||
|
|
ffd088a693 | ||
|
|
3abc80b88e | ||
|
|
15020e615c | ||
|
|
bd0aabb064 | ||
|
|
97013e08ef | ||
|
|
cca807ed01 | ||
|
|
c8246b99d3 | ||
|
|
aad81a83a3 | ||
|
|
00bd4561fc | ||
|
|
a6062a4229 | ||
|
|
aa9594cb42 | ||
|
|
4f6b21c6d9 | ||
|
|
9c0d357817 | ||
|
|
8b9b64d21c | ||
|
|
417ef36eb0 | ||
|
|
7c53812d22 | ||
|
|
6bbaaed8cb | ||
|
|
de809ec1d4 | ||
|
|
b95be09788 | ||
|
|
a7ce420f35 | ||
|
|
ecfab29543 | ||
|
|
10fd3e6a0d | ||
|
|
d65dd32a17 | ||
|
|
1768798883 | ||
|
|
c4737379d6 | ||
|
|
df20450988 | ||
|
|
e70059b5a6 | ||
|
|
c41534b78f |
10
README.md
10
README.md
@@ -126,15 +126,15 @@ Invoke is a combined effort of [passionate and talented people from across the w
|
||||
|
||||
Original portions of the software are Copyright © 2024 by respective contributors.
|
||||
|
||||
[features docs]: https://invoke-ai.github.io/InvokeAI/features/
|
||||
[faq]: https://invoke-ai.github.io/InvokeAI/help/FAQ/
|
||||
[contributors]: https://invoke-ai.github.io/InvokeAI/other/CONTRIBUTORS/
|
||||
[features docs]: https://invoke-ai.github.io/InvokeAI/features/database/
|
||||
[faq]: https://invoke-ai.github.io/InvokeAI/faq/
|
||||
[contributors]: https://invoke-ai.github.io/InvokeAI/contributing/contributors/
|
||||
[invoke.com]: https://www.invoke.com/about
|
||||
[github issues]: https://github.com/invoke-ai/InvokeAI/issues
|
||||
[docs home]: https://invoke-ai.github.io/InvokeAI
|
||||
[installation docs]: https://invoke-ai.github.io/InvokeAI/installation/INSTALLATION/
|
||||
[installation docs]: https://invoke-ai.github.io/InvokeAI/installation/
|
||||
[#dev-chat]: https://discord.com/channels/1020123559063990373/1049495067846524939
|
||||
[contributing docs]: https://invoke-ai.github.io/InvokeAI/contributing/CONTRIBUTING/
|
||||
[contributing docs]: https://invoke-ai.github.io/InvokeAI/contributing/
|
||||
[CI checks on main badge]: https://flat.badgen.net/github/checks/invoke-ai/InvokeAI/main?label=CI%20status%20on%20main&cache=900&icon=github
|
||||
[CI checks on main link]: https://github.com/invoke-ai/InvokeAI/actions?query=branch%3Amain
|
||||
[discord badge]: https://flat.badgen.net/discord/members/ZmtBAhwWhy?icon=discord
|
||||
|
||||
@@ -39,7 +39,8 @@ To use a community workflow, download the `.json` node graph file and load it in
|
||||
+ [Match Histogram](#match-histogram)
|
||||
+ [Metadata-Linked](#metadata-linked-nodes)
|
||||
+ [Negative Image](#negative-image)
|
||||
+ [Nightmare Promptgen](#nightmare-promptgen)
|
||||
+ [Nightmare Promptgen](#nightmare-promptgen)
|
||||
+ [One Button Prompt](#one-button-prompt)
|
||||
+ [Oobabooga](#oobabooga)
|
||||
+ [Prompt Tools](#prompt-tools)
|
||||
+ [Remote Image](#remote-image)
|
||||
@@ -389,6 +390,21 @@ View:
|
||||
|
||||
**Node Link:** [https://github.com/gogurtenjoyer/nightmare-promptgen](https://github.com/gogurtenjoyer/nightmare-promptgen)
|
||||
|
||||
--------------------------------
|
||||
### One Button Prompt
|
||||
|
||||
<img src="https://github.com/AIrjen/OneButtonPrompt_X_InvokeAI/blob/main/images/background.png" width="800" />
|
||||
|
||||
**Description:** an extensive suite of auto prompt generation and prompt helper nodes based on extensive logic. Get creative with the best prompt generator in the world.
|
||||
|
||||
The main node generates interesting prompts based on a set of parameters. There are also some additional nodes such as Auto Negative Prompt, One Button Artify, Create Prompt Variant and other cool prompt toys to play around with.
|
||||
|
||||
**Node Link:** [https://github.com/AIrjen/OneButtonPrompt_X_InvokeAI](https://github.com/AIrjen/OneButtonPrompt_X_InvokeAI)
|
||||
|
||||
**Nodes:**
|
||||
|
||||
<img src="https://github.com/AIrjen/OneButtonPrompt_X_InvokeAI/blob/main/images/OBP_nodes_invokeai.png" width="800" />
|
||||
|
||||
--------------------------------
|
||||
### Oobabooga
|
||||
|
||||
|
||||
@@ -7,13 +7,14 @@ from pathlib import Path
|
||||
|
||||
import torch
|
||||
import uvicorn
|
||||
from fastapi import FastAPI
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.middleware.gzip import GZipMiddleware
|
||||
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
|
||||
from fastapi.responses import HTMLResponse
|
||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||
from fastapi_events.handlers.local import local_handler
|
||||
from fastapi_events.middleware import EventHandlerASGIMiddleware
|
||||
from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
|
||||
from torch.backends.mps import is_available as is_mps_available
|
||||
|
||||
# for PyCharm:
|
||||
@@ -78,6 +79,29 @@ app = FastAPI(
|
||||
lifespan=lifespan,
|
||||
)
|
||||
|
||||
|
||||
class RedirectRootWithQueryStringMiddleware(BaseHTTPMiddleware):
|
||||
"""When a request is made to the root path with a query string, redirect to the root path without the query string.
|
||||
|
||||
For example, to force a Gradio app to use dark mode, users may append `?__theme=dark` to the URL. Their browser may
|
||||
have this query string saved in history or a bookmark, so when the user navigates to `http://127.0.0.1:9090/`, the
|
||||
browser takes them to `http://127.0.0.1:9090/?__theme=dark`.
|
||||
|
||||
This breaks the static file serving in the UI, so we redirect the user to the root path without the query string.
|
||||
"""
|
||||
|
||||
async def dispatch(self, request: Request, call_next: RequestResponseEndpoint):
|
||||
if request.url.path == "/" and request.url.query:
|
||||
return RedirectResponse(url="/")
|
||||
|
||||
response = await call_next(request)
|
||||
return response
|
||||
|
||||
|
||||
# Add the middleware
|
||||
app.add_middleware(RedirectRootWithQueryStringMiddleware)
|
||||
|
||||
|
||||
# Add event handler
|
||||
event_handler_id: int = id(app)
|
||||
app.add_middleware(
|
||||
|
||||
@@ -20,16 +20,17 @@ from invokeai.app.invocations.model import TransformerField
|
||||
from invokeai.app.invocations.primitives import LatentsOutput
|
||||
from invokeai.app.services.shared.invocation_context import InvocationContext
|
||||
from invokeai.backend.flux.denoise import denoise
|
||||
from invokeai.backend.flux.inpaint_extension import InpaintExtension
|
||||
from invokeai.backend.flux.model import Flux
|
||||
from invokeai.backend.flux.sampling_utils import (
|
||||
clip_timestep_schedule,
|
||||
clip_timestep_schedule_fractional,
|
||||
generate_img_ids,
|
||||
get_noise,
|
||||
get_schedule,
|
||||
pack,
|
||||
unpack,
|
||||
)
|
||||
from invokeai.backend.flux.trajectory_guidance_extension import TrajectoryGuidanceExtension
|
||||
from invokeai.backend.lora.conversions.flux_kohya_lora_conversion_utils import FLUX_KOHYA_TRANFORMER_PREFIX
|
||||
from invokeai.backend.lora.lora_model_raw import LoRAModelRaw
|
||||
from invokeai.backend.lora.lora_patcher import LoRAPatcher
|
||||
from invokeai.backend.model_manager.config import ModelFormat
|
||||
@@ -43,7 +44,7 @@ from invokeai.backend.util.devices import TorchDevice
|
||||
title="FLUX Denoise",
|
||||
tags=["image", "flux"],
|
||||
category="image",
|
||||
version="2.1.0",
|
||||
version="3.0.0",
|
||||
classification=Classification.Prototype,
|
||||
)
|
||||
class FluxDenoiseInvocation(BaseInvocation, WithMetadata, WithBoard):
|
||||
@@ -68,12 +69,6 @@ class FluxDenoiseInvocation(BaseInvocation, WithMetadata, WithBoard):
|
||||
description=FieldDescriptions.denoising_start,
|
||||
)
|
||||
denoising_end: float = InputField(default=1.0, ge=0, le=1, description=FieldDescriptions.denoising_end)
|
||||
trajectory_guidance_strength: float = InputField(
|
||||
default=0.0,
|
||||
ge=0.0,
|
||||
le=1.0,
|
||||
description="Value indicating how strongly to guide the denoising process towards the initial latents (during image-to-image). Range [0, 1]. A value of 0.0 is equivalent to vanilla image-to-image. A value of 1.0 will guide the denoising process very close to the original latents.",
|
||||
)
|
||||
transformer: TransformerField = InputField(
|
||||
description=FieldDescriptions.flux_model,
|
||||
input=Input.Connection,
|
||||
@@ -143,7 +138,7 @@ class FluxDenoiseInvocation(BaseInvocation, WithMetadata, WithBoard):
|
||||
)
|
||||
|
||||
# Clip the timesteps schedule based on denoising_start and denoising_end.
|
||||
timesteps = clip_timestep_schedule(timesteps, self.denoising_start, self.denoising_end)
|
||||
timesteps = clip_timestep_schedule_fractional(timesteps, self.denoising_start, self.denoising_end)
|
||||
|
||||
# Prepare input latent image.
|
||||
if init_latents is not None:
|
||||
@@ -187,13 +182,14 @@ class FluxDenoiseInvocation(BaseInvocation, WithMetadata, WithBoard):
|
||||
# Now that we have 'packed' the latent tensors, verify that we calculated the image_seq_len correctly.
|
||||
assert image_seq_len == x.shape[1]
|
||||
|
||||
# Prepare trajectory guidance extension.
|
||||
traj_guidance_extension: TrajectoryGuidanceExtension | None = None
|
||||
if init_latents is not None:
|
||||
traj_guidance_extension = TrajectoryGuidanceExtension(
|
||||
# Prepare inpaint extension.
|
||||
inpaint_extension: InpaintExtension | None = None
|
||||
if inpaint_mask is not None:
|
||||
assert init_latents is not None
|
||||
inpaint_extension = InpaintExtension(
|
||||
init_latents=init_latents,
|
||||
inpaint_mask=inpaint_mask,
|
||||
trajectory_guidance_strength=self.trajectory_guidance_strength,
|
||||
noise=noise,
|
||||
)
|
||||
|
||||
with (
|
||||
@@ -213,7 +209,7 @@ class FluxDenoiseInvocation(BaseInvocation, WithMetadata, WithBoard):
|
||||
LoRAPatcher.apply_lora_patches(
|
||||
model=transformer,
|
||||
patches=self._lora_iterator(context),
|
||||
prefix="",
|
||||
prefix=FLUX_KOHYA_TRANFORMER_PREFIX,
|
||||
cached_weights=cached_weights,
|
||||
)
|
||||
)
|
||||
@@ -224,7 +220,7 @@ class FluxDenoiseInvocation(BaseInvocation, WithMetadata, WithBoard):
|
||||
LoRAPatcher.apply_lora_sidecar_patches(
|
||||
model=transformer,
|
||||
patches=self._lora_iterator(context),
|
||||
prefix="",
|
||||
prefix=FLUX_KOHYA_TRANFORMER_PREFIX,
|
||||
dtype=inference_dtype,
|
||||
)
|
||||
)
|
||||
@@ -241,7 +237,7 @@ class FluxDenoiseInvocation(BaseInvocation, WithMetadata, WithBoard):
|
||||
timesteps=timesteps,
|
||||
step_callback=self._build_step_callback(context),
|
||||
guidance=self.guidance,
|
||||
traj_guidance_extension=traj_guidance_extension,
|
||||
inpaint_extension=inpaint_extension,
|
||||
)
|
||||
|
||||
x = unpack(x.float(), self.height, self.width)
|
||||
|
||||
@@ -8,7 +8,7 @@ from invokeai.app.invocations.baseinvocation import (
|
||||
invocation_output,
|
||||
)
|
||||
from invokeai.app.invocations.fields import FieldDescriptions, Input, InputField, OutputField, UIType
|
||||
from invokeai.app.invocations.model import LoRAField, ModelIdentifierField, TransformerField
|
||||
from invokeai.app.invocations.model import CLIPField, LoRAField, ModelIdentifierField, TransformerField
|
||||
from invokeai.app.services.shared.invocation_context import InvocationContext
|
||||
from invokeai.backend.model_manager.config import BaseModelType
|
||||
|
||||
@@ -20,6 +20,7 @@ class FluxLoRALoaderOutput(BaseInvocationOutput):
|
||||
transformer: Optional[TransformerField] = OutputField(
|
||||
default=None, description=FieldDescriptions.transformer, title="FLUX Transformer"
|
||||
)
|
||||
clip: Optional[CLIPField] = OutputField(default=None, description=FieldDescriptions.clip, title="CLIP")
|
||||
|
||||
|
||||
@invocation(
|
||||
@@ -27,21 +28,28 @@ class FluxLoRALoaderOutput(BaseInvocationOutput):
|
||||
title="FLUX LoRA",
|
||||
tags=["lora", "model", "flux"],
|
||||
category="model",
|
||||
version="1.0.0",
|
||||
version="1.1.0",
|
||||
classification=Classification.Prototype,
|
||||
)
|
||||
class FluxLoRALoaderInvocation(BaseInvocation):
|
||||
"""Apply a LoRA model to a FLUX transformer."""
|
||||
"""Apply a LoRA model to a FLUX transformer and/or text encoder."""
|
||||
|
||||
lora: ModelIdentifierField = InputField(
|
||||
description=FieldDescriptions.lora_model, title="LoRA", ui_type=UIType.LoRAModel
|
||||
)
|
||||
weight: float = InputField(default=0.75, description=FieldDescriptions.lora_weight)
|
||||
transformer: TransformerField = InputField(
|
||||
transformer: TransformerField | None = InputField(
|
||||
default=None,
|
||||
description=FieldDescriptions.transformer,
|
||||
input=Input.Connection,
|
||||
title="FLUX Transformer",
|
||||
)
|
||||
clip: CLIPField | None = InputField(
|
||||
default=None,
|
||||
title="CLIP",
|
||||
description=FieldDescriptions.clip,
|
||||
input=Input.Connection,
|
||||
)
|
||||
|
||||
def invoke(self, context: InvocationContext) -> FluxLoRALoaderOutput:
|
||||
lora_key = self.lora.key
|
||||
@@ -49,18 +57,33 @@ class FluxLoRALoaderInvocation(BaseInvocation):
|
||||
if not context.models.exists(lora_key):
|
||||
raise ValueError(f"Unknown lora: {lora_key}!")
|
||||
|
||||
if any(lora.lora.key == lora_key for lora in self.transformer.loras):
|
||||
# Check for existing LoRAs with the same key.
|
||||
if self.transformer and any(lora.lora.key == lora_key for lora in self.transformer.loras):
|
||||
raise ValueError(f'LoRA "{lora_key}" already applied to transformer.')
|
||||
if self.clip and any(lora.lora.key == lora_key for lora in self.clip.loras):
|
||||
raise ValueError(f'LoRA "{lora_key}" already applied to CLIP encoder.')
|
||||
|
||||
transformer = self.transformer.model_copy(deep=True)
|
||||
transformer.loras.append(
|
||||
LoRAField(
|
||||
lora=self.lora,
|
||||
weight=self.weight,
|
||||
output = FluxLoRALoaderOutput()
|
||||
|
||||
# Attach LoRA layers to the models.
|
||||
if self.transformer is not None:
|
||||
output.transformer = self.transformer.model_copy(deep=True)
|
||||
output.transformer.loras.append(
|
||||
LoRAField(
|
||||
lora=self.lora,
|
||||
weight=self.weight,
|
||||
)
|
||||
)
|
||||
if self.clip is not None:
|
||||
output.clip = self.clip.model_copy(deep=True)
|
||||
output.clip.loras.append(
|
||||
LoRAField(
|
||||
lora=self.lora,
|
||||
weight=self.weight,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
return FluxLoRALoaderOutput(transformer=transformer)
|
||||
return output
|
||||
|
||||
|
||||
@invocation(
|
||||
@@ -68,7 +91,7 @@ class FluxLoRALoaderInvocation(BaseInvocation):
|
||||
title="FLUX LoRA Collection Loader",
|
||||
tags=["lora", "model", "flux"],
|
||||
category="model",
|
||||
version="1.0.0",
|
||||
version="1.1.0",
|
||||
classification=Classification.Prototype,
|
||||
)
|
||||
class FLUXLoRACollectionLoader(BaseInvocation):
|
||||
@@ -84,6 +107,12 @@ class FLUXLoRACollectionLoader(BaseInvocation):
|
||||
input=Input.Connection,
|
||||
title="Transformer",
|
||||
)
|
||||
clip: CLIPField | None = InputField(
|
||||
default=None,
|
||||
title="CLIP",
|
||||
description=FieldDescriptions.clip,
|
||||
input=Input.Connection,
|
||||
)
|
||||
|
||||
def invoke(self, context: InvocationContext) -> FluxLoRALoaderOutput:
|
||||
output = FluxLoRALoaderOutput()
|
||||
@@ -106,4 +135,9 @@ class FLUXLoRACollectionLoader(BaseInvocation):
|
||||
output.transformer = self.transformer.model_copy(deep=True)
|
||||
output.transformer.loras.append(lora)
|
||||
|
||||
if self.clip is not None:
|
||||
if output.clip is None:
|
||||
output.clip = self.clip.model_copy(deep=True)
|
||||
output.clip.loras.append(lora)
|
||||
|
||||
return output
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from typing import Literal
|
||||
from contextlib import ExitStack
|
||||
from typing import Iterator, Literal, Tuple
|
||||
|
||||
import torch
|
||||
from transformers import CLIPTextModel, CLIPTokenizer, T5EncoderModel, T5Tokenizer
|
||||
@@ -9,6 +10,10 @@ from invokeai.app.invocations.model import CLIPField, T5EncoderField
|
||||
from invokeai.app.invocations.primitives import FluxConditioningOutput
|
||||
from invokeai.app.services.shared.invocation_context import InvocationContext
|
||||
from invokeai.backend.flux.modules.conditioner import HFEncoder
|
||||
from invokeai.backend.lora.conversions.flux_kohya_lora_conversion_utils import FLUX_KOHYA_CLIP_PREFIX
|
||||
from invokeai.backend.lora.lora_model_raw import LoRAModelRaw
|
||||
from invokeai.backend.lora.lora_patcher import LoRAPatcher
|
||||
from invokeai.backend.model_manager.config import ModelFormat
|
||||
from invokeai.backend.stable_diffusion.diffusion.conditioning_data import ConditioningFieldData, FLUXConditioningInfo
|
||||
|
||||
|
||||
@@ -17,7 +22,7 @@ from invokeai.backend.stable_diffusion.diffusion.conditioning_data import Condit
|
||||
title="FLUX Text Encoding",
|
||||
tags=["prompt", "conditioning", "flux"],
|
||||
category="conditioning",
|
||||
version="1.0.0",
|
||||
version="1.1.0",
|
||||
classification=Classification.Prototype,
|
||||
)
|
||||
class FluxTextEncoderInvocation(BaseInvocation):
|
||||
@@ -78,15 +83,42 @@ class FluxTextEncoderInvocation(BaseInvocation):
|
||||
prompt = [self.prompt]
|
||||
|
||||
with (
|
||||
clip_text_encoder_info as clip_text_encoder,
|
||||
clip_text_encoder_info.model_on_device() as (cached_weights, clip_text_encoder),
|
||||
clip_tokenizer_info as clip_tokenizer,
|
||||
ExitStack() as exit_stack,
|
||||
):
|
||||
assert isinstance(clip_text_encoder, CLIPTextModel)
|
||||
assert isinstance(clip_tokenizer, CLIPTokenizer)
|
||||
|
||||
clip_text_encoder_config = clip_text_encoder_info.config
|
||||
assert clip_text_encoder_config is not None
|
||||
|
||||
# Apply LoRA models to the CLIP encoder.
|
||||
# Note: We apply the LoRA after the transformer has been moved to its target device for faster patching.
|
||||
if clip_text_encoder_config.format in [ModelFormat.Diffusers]:
|
||||
# The model is non-quantized, so we can apply the LoRA weights directly into the model.
|
||||
exit_stack.enter_context(
|
||||
LoRAPatcher.apply_lora_patches(
|
||||
model=clip_text_encoder,
|
||||
patches=self._clip_lora_iterator(context),
|
||||
prefix=FLUX_KOHYA_CLIP_PREFIX,
|
||||
cached_weights=cached_weights,
|
||||
)
|
||||
)
|
||||
else:
|
||||
# There are currently no supported CLIP quantized models. Add support here if needed.
|
||||
raise ValueError(f"Unsupported model format: {clip_text_encoder_config.format}")
|
||||
|
||||
clip_encoder = HFEncoder(clip_text_encoder, clip_tokenizer, True, 77)
|
||||
|
||||
pooled_prompt_embeds = clip_encoder(prompt)
|
||||
|
||||
assert isinstance(pooled_prompt_embeds, torch.Tensor)
|
||||
return pooled_prompt_embeds
|
||||
|
||||
def _clip_lora_iterator(self, context: InvocationContext) -> Iterator[Tuple[LoRAModelRaw, float]]:
|
||||
for lora in self.clip.loras:
|
||||
lora_info = context.models.load(lora.lora)
|
||||
assert isinstance(lora_info.model, LoRAModelRaw)
|
||||
yield (lora_info.model, lora.weight)
|
||||
del lora_info
|
||||
|
||||
@@ -256,7 +256,7 @@ class InvokeAIAppConfig(BaseSettings):
|
||||
file.write("# Internal metadata - do not edit:\n")
|
||||
file.write(yaml.dump(meta_dict, sort_keys=False))
|
||||
file.write("\n")
|
||||
file.write("# Put user settings here - see https://invoke-ai.github.io/InvokeAI/features/CONFIGURATION/:\n")
|
||||
file.write("# Put user settings here - see https://invoke-ai.github.io/InvokeAI/configuration/:\n")
|
||||
if len(config_dict) > 0:
|
||||
file.write(yaml.dump(config_dict, sort_keys=False))
|
||||
|
||||
|
||||
@@ -38,12 +38,12 @@
|
||||
},
|
||||
"nodes": [
|
||||
{
|
||||
"id": "eebd7252-0bd8-401a-bb26-2b8bc64892fa",
|
||||
"id": "cd367e62-2b45-4118-b4ba-7c33e2e0b370",
|
||||
"type": "invocation",
|
||||
"data": {
|
||||
"id": "eebd7252-0bd8-401a-bb26-2b8bc64892fa",
|
||||
"id": "cd367e62-2b45-4118-b4ba-7c33e2e0b370",
|
||||
"type": "flux_denoise",
|
||||
"version": "2.1.0",
|
||||
"version": "3.0.0",
|
||||
"label": "",
|
||||
"notes": "",
|
||||
"isOpen": true,
|
||||
@@ -77,11 +77,6 @@
|
||||
"label": "",
|
||||
"value": 1
|
||||
},
|
||||
"trajectory_guidance_strength": {
|
||||
"name": "trajectory_guidance_strength",
|
||||
"label": "",
|
||||
"value": 0.0
|
||||
},
|
||||
"transformer": {
|
||||
"name": "transformer",
|
||||
"label": ""
|
||||
@@ -118,8 +113,8 @@
|
||||
}
|
||||
},
|
||||
"position": {
|
||||
"x": 1159.584057771928,
|
||||
"y": -175.90561201366845
|
||||
"x": 1176.8139201354052,
|
||||
"y": -244.36724863022368
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -201,14 +196,7 @@
|
||||
"inputs": {
|
||||
"model": {
|
||||
"name": "model",
|
||||
"label": "Model (dev variant recommended for Image-to-Image)",
|
||||
"value": {
|
||||
"key": "b4990a6c-0899-48e9-969b-d6f3801acc6a",
|
||||
"hash": "random:aad8f7bc19ce76541dfb394b62a30f77722542b66e48064a9f25453263b45fba",
|
||||
"name": "FLUX Dev (Quantized)_2",
|
||||
"base": "flux",
|
||||
"type": "main"
|
||||
}
|
||||
"label": "Model (dev variant recommended for Image-to-Image)"
|
||||
},
|
||||
"t5_encoder_model": {
|
||||
"name": "t5_encoder_model",
|
||||
@@ -314,67 +302,67 @@
|
||||
}
|
||||
},
|
||||
"position": {
|
||||
"x": 725.834098928012,
|
||||
"y": 496.2710031089931
|
||||
"x": 750.4061458984118,
|
||||
"y": 279.2179215371294
|
||||
}
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"id": "reactflow__edge-eebd7252-0bd8-401a-bb26-2b8bc64892falatents-7e5172eb-48c1-44db-a770-8fd83e1435d1latents",
|
||||
"id": "reactflow__edge-cd367e62-2b45-4118-b4ba-7c33e2e0b370latents-7e5172eb-48c1-44db-a770-8fd83e1435d1latents",
|
||||
"type": "default",
|
||||
"source": "eebd7252-0bd8-401a-bb26-2b8bc64892fa",
|
||||
"source": "cd367e62-2b45-4118-b4ba-7c33e2e0b370",
|
||||
"target": "7e5172eb-48c1-44db-a770-8fd83e1435d1",
|
||||
"sourceHandle": "latents",
|
||||
"targetHandle": "latents"
|
||||
},
|
||||
{
|
||||
"id": "reactflow__edge-f8d9d7c8-9ed7-4bd7-9e42-ab0e89bfac90transformer-eebd7252-0bd8-401a-bb26-2b8bc64892fatransformer",
|
||||
"id": "reactflow__edge-4754c534-a5f3-4ad0-9382-7887985e668cvalue-cd367e62-2b45-4118-b4ba-7c33e2e0b370seed",
|
||||
"type": "default",
|
||||
"source": "f8d9d7c8-9ed7-4bd7-9e42-ab0e89bfac90",
|
||||
"target": "eebd7252-0bd8-401a-bb26-2b8bc64892fa",
|
||||
"sourceHandle": "transformer",
|
||||
"targetHandle": "transformer"
|
||||
"source": "4754c534-a5f3-4ad0-9382-7887985e668c",
|
||||
"target": "cd367e62-2b45-4118-b4ba-7c33e2e0b370",
|
||||
"sourceHandle": "value",
|
||||
"targetHandle": "seed"
|
||||
},
|
||||
{
|
||||
"id": "reactflow__edge-01f674f8-b3d1-4df1-acac-6cb8e0bfb63cconditioning-eebd7252-0bd8-401a-bb26-2b8bc64892fapositive_text_conditioning",
|
||||
"type": "default",
|
||||
"source": "01f674f8-b3d1-4df1-acac-6cb8e0bfb63c",
|
||||
"target": "eebd7252-0bd8-401a-bb26-2b8bc64892fa",
|
||||
"sourceHandle": "conditioning",
|
||||
"targetHandle": "positive_text_conditioning"
|
||||
},
|
||||
{
|
||||
"id": "reactflow__edge-2981a67c-480f-4237-9384-26b68dbf912blatents-eebd7252-0bd8-401a-bb26-2b8bc64892falatents",
|
||||
"id": "reactflow__edge-2981a67c-480f-4237-9384-26b68dbf912bheight-cd367e62-2b45-4118-b4ba-7c33e2e0b370height",
|
||||
"type": "default",
|
||||
"source": "2981a67c-480f-4237-9384-26b68dbf912b",
|
||||
"target": "eebd7252-0bd8-401a-bb26-2b8bc64892fa",
|
||||
"sourceHandle": "latents",
|
||||
"targetHandle": "latents"
|
||||
},
|
||||
{
|
||||
"id": "reactflow__edge-2981a67c-480f-4237-9384-26b68dbf912bwidth-eebd7252-0bd8-401a-bb26-2b8bc64892fawidth",
|
||||
"type": "default",
|
||||
"source": "2981a67c-480f-4237-9384-26b68dbf912b",
|
||||
"target": "eebd7252-0bd8-401a-bb26-2b8bc64892fa",
|
||||
"sourceHandle": "width",
|
||||
"targetHandle": "width"
|
||||
},
|
||||
{
|
||||
"id": "reactflow__edge-2981a67c-480f-4237-9384-26b68dbf912bheight-eebd7252-0bd8-401a-bb26-2b8bc64892faheight",
|
||||
"type": "default",
|
||||
"source": "2981a67c-480f-4237-9384-26b68dbf912b",
|
||||
"target": "eebd7252-0bd8-401a-bb26-2b8bc64892fa",
|
||||
"target": "cd367e62-2b45-4118-b4ba-7c33e2e0b370",
|
||||
"sourceHandle": "height",
|
||||
"targetHandle": "height"
|
||||
},
|
||||
{
|
||||
"id": "reactflow__edge-4754c534-a5f3-4ad0-9382-7887985e668cvalue-eebd7252-0bd8-401a-bb26-2b8bc64892faseed",
|
||||
"id": "reactflow__edge-2981a67c-480f-4237-9384-26b68dbf912bwidth-cd367e62-2b45-4118-b4ba-7c33e2e0b370width",
|
||||
"type": "default",
|
||||
"source": "4754c534-a5f3-4ad0-9382-7887985e668c",
|
||||
"target": "eebd7252-0bd8-401a-bb26-2b8bc64892fa",
|
||||
"sourceHandle": "value",
|
||||
"targetHandle": "seed"
|
||||
"source": "2981a67c-480f-4237-9384-26b68dbf912b",
|
||||
"target": "cd367e62-2b45-4118-b4ba-7c33e2e0b370",
|
||||
"sourceHandle": "width",
|
||||
"targetHandle": "width"
|
||||
},
|
||||
{
|
||||
"id": "reactflow__edge-01f674f8-b3d1-4df1-acac-6cb8e0bfb63cconditioning-cd367e62-2b45-4118-b4ba-7c33e2e0b370positive_text_conditioning",
|
||||
"type": "default",
|
||||
"source": "01f674f8-b3d1-4df1-acac-6cb8e0bfb63c",
|
||||
"target": "cd367e62-2b45-4118-b4ba-7c33e2e0b370",
|
||||
"sourceHandle": "conditioning",
|
||||
"targetHandle": "positive_text_conditioning"
|
||||
},
|
||||
{
|
||||
"id": "reactflow__edge-f8d9d7c8-9ed7-4bd7-9e42-ab0e89bfac90transformer-cd367e62-2b45-4118-b4ba-7c33e2e0b370transformer",
|
||||
"type": "default",
|
||||
"source": "f8d9d7c8-9ed7-4bd7-9e42-ab0e89bfac90",
|
||||
"target": "cd367e62-2b45-4118-b4ba-7c33e2e0b370",
|
||||
"sourceHandle": "transformer",
|
||||
"targetHandle": "transformer"
|
||||
},
|
||||
{
|
||||
"id": "reactflow__edge-2981a67c-480f-4237-9384-26b68dbf912blatents-cd367e62-2b45-4118-b4ba-7c33e2e0b370latents",
|
||||
"type": "default",
|
||||
"source": "2981a67c-480f-4237-9384-26b68dbf912b",
|
||||
"target": "cd367e62-2b45-4118-b4ba-7c33e2e0b370",
|
||||
"sourceHandle": "latents",
|
||||
"targetHandle": "latents"
|
||||
},
|
||||
{
|
||||
"id": "reactflow__edge-f8d9d7c8-9ed7-4bd7-9e42-ab0e89bfac90vae-2981a67c-480f-4237-9384-26b68dbf912bvae",
|
||||
|
||||
@@ -34,12 +34,12 @@
|
||||
},
|
||||
"nodes": [
|
||||
{
|
||||
"id": "4ecda92d-ee0e-45ca-aa35-6e9410ac39b9",
|
||||
"id": "0940bc54-21fb-4346-bc68-fca5724c2747",
|
||||
"type": "invocation",
|
||||
"data": {
|
||||
"id": "4ecda92d-ee0e-45ca-aa35-6e9410ac39b9",
|
||||
"id": "0940bc54-21fb-4346-bc68-fca5724c2747",
|
||||
"type": "flux_denoise",
|
||||
"version": "2.1.0",
|
||||
"version": "3.0.0",
|
||||
"label": "",
|
||||
"notes": "",
|
||||
"isOpen": true,
|
||||
@@ -61,7 +61,7 @@
|
||||
},
|
||||
"denoise_mask": {
|
||||
"name": "denoise_mask",
|
||||
"label": ""
|
||||
"label": "Denoise Mask"
|
||||
},
|
||||
"denoising_start": {
|
||||
"name": "denoising_start",
|
||||
@@ -73,11 +73,6 @@
|
||||
"label": "",
|
||||
"value": 1
|
||||
},
|
||||
"trajectory_guidance_strength": {
|
||||
"name": "trajectory_guidance_strength",
|
||||
"label": "",
|
||||
"value": 0
|
||||
},
|
||||
"transformer": {
|
||||
"name": "transformer",
|
||||
"label": ""
|
||||
@@ -114,8 +109,8 @@
|
||||
}
|
||||
},
|
||||
"position": {
|
||||
"x": 1161.0101524413685,
|
||||
"y": -223.33548695623742
|
||||
"x": 1180.8001377784371,
|
||||
"y": -219.96908055568326
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -169,14 +164,7 @@
|
||||
"inputs": {
|
||||
"model": {
|
||||
"name": "model",
|
||||
"label": "",
|
||||
"value": {
|
||||
"key": "b4990a6c-0899-48e9-969b-d6f3801acc6a",
|
||||
"hash": "random:aad8f7bc19ce76541dfb394b62a30f77722542b66e48064a9f25453263b45fba",
|
||||
"name": "FLUX Dev (Quantized)_2",
|
||||
"base": "flux",
|
||||
"type": "main"
|
||||
}
|
||||
"label": ""
|
||||
},
|
||||
"t5_encoder_model": {
|
||||
"name": "t5_encoder_model",
|
||||
@@ -289,36 +277,36 @@
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"id": "reactflow__edge-f8d9d7c8-9ed7-4bd7-9e42-ab0e89bfac90transformer-4ecda92d-ee0e-45ca-aa35-6e9410ac39b9transformer",
|
||||
"id": "reactflow__edge-0940bc54-21fb-4346-bc68-fca5724c2747latents-7e5172eb-48c1-44db-a770-8fd83e1435d1latents",
|
||||
"type": "default",
|
||||
"source": "f8d9d7c8-9ed7-4bd7-9e42-ab0e89bfac90",
|
||||
"target": "4ecda92d-ee0e-45ca-aa35-6e9410ac39b9",
|
||||
"sourceHandle": "transformer",
|
||||
"targetHandle": "transformer"
|
||||
"source": "0940bc54-21fb-4346-bc68-fca5724c2747",
|
||||
"target": "7e5172eb-48c1-44db-a770-8fd83e1435d1",
|
||||
"sourceHandle": "latents",
|
||||
"targetHandle": "latents"
|
||||
},
|
||||
{
|
||||
"id": "reactflow__edge-01f674f8-b3d1-4df1-acac-6cb8e0bfb63cconditioning-4ecda92d-ee0e-45ca-aa35-6e9410ac39b9positive_text_conditioning",
|
||||
"type": "default",
|
||||
"source": "01f674f8-b3d1-4df1-acac-6cb8e0bfb63c",
|
||||
"target": "4ecda92d-ee0e-45ca-aa35-6e9410ac39b9",
|
||||
"sourceHandle": "conditioning",
|
||||
"targetHandle": "positive_text_conditioning"
|
||||
},
|
||||
{
|
||||
"id": "reactflow__edge-4754c534-a5f3-4ad0-9382-7887985e668cvalue-4ecda92d-ee0e-45ca-aa35-6e9410ac39b9seed",
|
||||
"id": "reactflow__edge-4754c534-a5f3-4ad0-9382-7887985e668cvalue-0940bc54-21fb-4346-bc68-fca5724c2747seed",
|
||||
"type": "default",
|
||||
"source": "4754c534-a5f3-4ad0-9382-7887985e668c",
|
||||
"target": "4ecda92d-ee0e-45ca-aa35-6e9410ac39b9",
|
||||
"target": "0940bc54-21fb-4346-bc68-fca5724c2747",
|
||||
"sourceHandle": "value",
|
||||
"targetHandle": "seed"
|
||||
},
|
||||
{
|
||||
"id": "reactflow__edge-4ecda92d-ee0e-45ca-aa35-6e9410ac39b9latents-7e5172eb-48c1-44db-a770-8fd83e1435d1latents",
|
||||
"id": "reactflow__edge-01f674f8-b3d1-4df1-acac-6cb8e0bfb63cconditioning-0940bc54-21fb-4346-bc68-fca5724c2747positive_text_conditioning",
|
||||
"type": "default",
|
||||
"source": "4ecda92d-ee0e-45ca-aa35-6e9410ac39b9",
|
||||
"target": "7e5172eb-48c1-44db-a770-8fd83e1435d1",
|
||||
"sourceHandle": "latents",
|
||||
"targetHandle": "latents"
|
||||
"source": "01f674f8-b3d1-4df1-acac-6cb8e0bfb63c",
|
||||
"target": "0940bc54-21fb-4346-bc68-fca5724c2747",
|
||||
"sourceHandle": "conditioning",
|
||||
"targetHandle": "positive_text_conditioning"
|
||||
},
|
||||
{
|
||||
"id": "reactflow__edge-f8d9d7c8-9ed7-4bd7-9e42-ab0e89bfac90transformer-0940bc54-21fb-4346-bc68-fca5724c2747transformer",
|
||||
"type": "default",
|
||||
"source": "f8d9d7c8-9ed7-4bd7-9e42-ab0e89bfac90",
|
||||
"target": "0940bc54-21fb-4346-bc68-fca5724c2747",
|
||||
"sourceHandle": "transformer",
|
||||
"targetHandle": "transformer"
|
||||
},
|
||||
{
|
||||
"id": "reactflow__edge-f8d9d7c8-9ed7-4bd7-9e42-ab0e89bfac90vae-7e5172eb-48c1-44db-a770-8fd83e1435d1vae",
|
||||
|
||||
@@ -3,8 +3,8 @@ from typing import Callable
|
||||
import torch
|
||||
from tqdm import tqdm
|
||||
|
||||
from invokeai.backend.flux.inpaint_extension import InpaintExtension
|
||||
from invokeai.backend.flux.model import Flux
|
||||
from invokeai.backend.flux.trajectory_guidance_extension import TrajectoryGuidanceExtension
|
||||
from invokeai.backend.stable_diffusion.diffusers_pipeline import PipelineIntermediateState
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ def denoise(
|
||||
timesteps: list[float],
|
||||
step_callback: Callable[[PipelineIntermediateState], None],
|
||||
guidance: float,
|
||||
traj_guidance_extension: TrajectoryGuidanceExtension | None, # noqa: F821
|
||||
inpaint_extension: InpaintExtension | None,
|
||||
):
|
||||
# step 0 is the initial state
|
||||
total_steps = len(timesteps) - 1
|
||||
@@ -48,14 +48,13 @@ def denoise(
|
||||
guidance=guidance_vec,
|
||||
)
|
||||
|
||||
if traj_guidance_extension is not None:
|
||||
pred = traj_guidance_extension.update_noise(
|
||||
t_curr_latents=img, pred_noise=pred, t_curr=t_curr, t_prev=t_prev
|
||||
)
|
||||
|
||||
preview_img = img - t_curr * pred
|
||||
img = img + (t_prev - t_curr) * pred
|
||||
|
||||
if inpaint_extension is not None:
|
||||
img = inpaint_extension.merge_intermediate_latents_with_init_latents(img, t_prev)
|
||||
preview_img = inpaint_extension.merge_intermediate_latents_with_init_latents(preview_img, 0.0)
|
||||
|
||||
step_callback(
|
||||
PipelineIntermediateState(
|
||||
step=step,
|
||||
|
||||
@@ -19,8 +19,26 @@ class InpaintExtension:
|
||||
self._inpaint_mask = inpaint_mask
|
||||
self._noise = noise
|
||||
|
||||
def _apply_mask_gradient_adjustment(self, t_prev: float) -> torch.Tensor:
|
||||
"""Applies inpaint mask gradient adjustment and returns the inpaint mask to be used at the current timestep."""
|
||||
# As we progress through the denoising process, we promote gradient regions of the mask to have a full weight of
|
||||
# 1.0. This helps to produce more coherent seams around the inpainted region. We experimented with a (small)
|
||||
# number of promotion strategies (e.g. gradual promotion based on timestep), but found that a simple cutoff
|
||||
# threshold worked well.
|
||||
# We use a small epsilon to avoid any potential issues with floating point precision.
|
||||
eps = 1e-4
|
||||
mask_gradient_t_cutoff = 0.5
|
||||
if t_prev > mask_gradient_t_cutoff:
|
||||
# Early in the denoising process, use the inpaint mask as-is.
|
||||
return self._inpaint_mask
|
||||
else:
|
||||
# After the cut-off, promote all non-zero mask values to 1.0.
|
||||
mask = self._inpaint_mask.where(self._inpaint_mask <= (0.0 + eps), 1.0)
|
||||
|
||||
return mask
|
||||
|
||||
def merge_intermediate_latents_with_init_latents(
|
||||
self, intermediate_latents: torch.Tensor, timestep: float
|
||||
self, intermediate_latents: torch.Tensor, t_prev: float
|
||||
) -> torch.Tensor:
|
||||
"""Merge the intermediate latents with the initial latents for the current timestep using the inpaint mask. I.e.
|
||||
update the intermediate latents to keep the regions that are not being inpainted on the correct noise
|
||||
@@ -28,8 +46,10 @@ class InpaintExtension:
|
||||
|
||||
This function should be called after each denoising step.
|
||||
"""
|
||||
mask = self._apply_mask_gradient_adjustment(t_prev)
|
||||
|
||||
# Noise the init latents for the current timestep.
|
||||
noised_init_latents = self._noise * timestep + (1.0 - timestep) * self._init_latents
|
||||
noised_init_latents = self._noise * t_prev + (1.0 - t_prev) * self._init_latents
|
||||
|
||||
# Merge the intermediate latents with the noised_init_latents using the inpaint_mask.
|
||||
return intermediate_latents * self._inpaint_mask + noised_init_latents * (1.0 - self._inpaint_mask)
|
||||
return intermediate_latents * mask + noised_init_latents * (1.0 - mask)
|
||||
|
||||
@@ -97,6 +97,46 @@ def clip_timestep_schedule(timesteps: list[float], denoising_start: float, denoi
|
||||
return clipped_timesteps
|
||||
|
||||
|
||||
def clip_timestep_schedule_fractional(
|
||||
timesteps: list[float], denoising_start: float, denoising_end: float
|
||||
) -> list[float]:
|
||||
"""Clip the timestep schedule to the denoising range. Insert new timesteps to exactly match the desired denoising
|
||||
range. (A fractional version of clip_timestep_schedule().)
|
||||
|
||||
Args:
|
||||
timesteps (list[float]): The original timestep schedule: [1.0, ..., 0.0].
|
||||
denoising_start (float): A value in [0, 1] specifying the start of the denoising process. E.g. a value of 0.2
|
||||
would mean that the denoising process start at t=0.8.
|
||||
denoising_end (float): A value in [0, 1] specifying the end of the denoising process. E.g. a value of 0.8 would
|
||||
mean that the denoising process ends at t=0.2.
|
||||
|
||||
Returns:
|
||||
list[float]: The clipped timestep schedule.
|
||||
"""
|
||||
assert 0.0 <= denoising_start <= 1.0
|
||||
assert 0.0 <= denoising_end <= 1.0
|
||||
assert denoising_start <= denoising_end
|
||||
|
||||
t_start_val = 1.0 - denoising_start
|
||||
t_end_val = 1.0 - denoising_end
|
||||
|
||||
t_start_idx = _find_last_index_ge_val(timesteps, t_start_val)
|
||||
t_end_idx = _find_last_index_ge_val(timesteps, t_end_val)
|
||||
|
||||
clipped_timesteps = timesteps[t_start_idx : t_end_idx + 1]
|
||||
|
||||
# We know that clipped_timesteps[0] >= t_start_val. Replace clipped_timesteps[0] with t_start_val.
|
||||
clipped_timesteps[0] = t_start_val
|
||||
|
||||
# We know that clipped_timesteps[-1] >= t_end_val. If clipped_timesteps[-1] > t_end_val, add another step to
|
||||
# t_end_val.
|
||||
eps = 1e-6
|
||||
if clipped_timesteps[-1] > t_end_val + eps:
|
||||
clipped_timesteps.append(t_end_val)
|
||||
|
||||
return clipped_timesteps
|
||||
|
||||
|
||||
def unpack(x: torch.Tensor, height: int, width: int) -> torch.Tensor:
|
||||
"""Unpack flat array of patch embeddings to latent image."""
|
||||
return rearrange(
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
import torch
|
||||
|
||||
from invokeai.backend.util.build_line import build_line
|
||||
|
||||
|
||||
class TrajectoryGuidanceExtension:
|
||||
"""An implementation of trajectory guidance for FLUX.
|
||||
|
||||
What is trajectory guidance?
|
||||
----------------------------
|
||||
With SD 1 and SDXL, the amount of change in image-to-image denoising is largely controlled by the denoising_start
|
||||
parameter. Doing the same thing with the FLUX model does not work as well, because the FLUX model converges very
|
||||
quickly (roughly time 1.0 to 0.9) to the structure of the final image. The result of this model characteristic is
|
||||
that you typically get one of two outcomes:
|
||||
1) a result that is very similar to the original image
|
||||
2) a result that is very different from the original image, as though it was generated from the text prompt with
|
||||
pure noise.
|
||||
|
||||
To address this issue with image-to-image workflows with FLUX, we employ the concept of trajectory guidance. The
|
||||
idea is that in addition to controlling the denoising_start parameter (i.e. the amount of noise added to the
|
||||
original image), we can also guide the denoising process to stay close to the trajectory that would reproduce the
|
||||
original. By controlling the strength of the trajectory guidance throughout the denoising process, we can achieve
|
||||
FLUX image-to-image behavior with the same level of control offered by SD1 and SDXL.
|
||||
|
||||
What is the trajectory_guidance_strength?
|
||||
-----------------------------------------
|
||||
In the limit, we could apply a different trajectory guidance 'strength' for every latent value in every timestep.
|
||||
This would be impractical for a user, so instead we have engineered a strength schedule that is more convenient to
|
||||
use. The `trajectory_guidance_strength` parameter is a single scalar value that maps to a schedule. The engineered
|
||||
schedule is defined as:
|
||||
1) An initial change_ratio at t=1.0.
|
||||
2) A linear ramp up to change_ratio=1.0 at t = t_cutoff.
|
||||
3) A constant change_ratio=1.0 after t = t_cutoff.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, init_latents: torch.Tensor, inpaint_mask: torch.Tensor | None, trajectory_guidance_strength: float
|
||||
):
|
||||
"""Initialize TrajectoryGuidanceExtension.
|
||||
|
||||
Args:
|
||||
init_latents (torch.Tensor): The initial latents (i.e. un-noised at timestep 0). In 'packed' format.
|
||||
inpaint_mask (torch.Tensor | None): A mask specifying which elements to inpaint. Range [0, 1]. Values of 1
|
||||
will be re-generated. Values of 0 will remain unchanged. Values between 0 and 1 can be used to blend the
|
||||
inpainted region with the background. In 'packed' format. If None, will be treated as a mask of all 1s.
|
||||
trajectory_guidance_strength (float): A value in [0, 1] specifying the strength of the trajectory guidance.
|
||||
A value of 0.0 is equivalent to vanilla image-to-image. A value of 1.0 will guide the denoising process
|
||||
very close to the original latents.
|
||||
"""
|
||||
assert 0.0 <= trajectory_guidance_strength <= 1.0
|
||||
self._init_latents = init_latents
|
||||
if inpaint_mask is None:
|
||||
# The inpaing mask is None, so we initialize a mask with a single value of 1.0.
|
||||
# This value will be broadcasted and treated as a mask of all 1s.
|
||||
self._inpaint_mask = torch.ones(1, device=init_latents.device, dtype=init_latents.dtype)
|
||||
else:
|
||||
self._inpaint_mask = inpaint_mask
|
||||
|
||||
# Calculate the params that define the trajectory guidance schedule.
|
||||
# These mappings from trajectory_guidance_strength have no theoretical basis - they were tuned manually.
|
||||
self._trajectory_guidance_strength = trajectory_guidance_strength
|
||||
self._change_ratio_at_t_1 = build_line(x1=0.0, y1=1.0, x2=1.0, y2=0.0)(self._trajectory_guidance_strength)
|
||||
self._change_ratio_at_cutoff = 1.0
|
||||
self._t_cutoff = build_line(x1=0.0, y1=1.0, x2=1.0, y2=0.5)(self._trajectory_guidance_strength)
|
||||
|
||||
def _apply_mask_gradient_adjustment(self, t_prev: float) -> torch.Tensor:
|
||||
"""Applies inpaint mask gradient adjustment and returns the inpaint mask to be used at the current timestep."""
|
||||
# As we progress through the denoising process, we promote gradient regions of the mask to have a full weight of
|
||||
# 1.0. This helps to produce more coherent seams around the inpainted region. We experimented with a (small)
|
||||
# number of promotion strategies (e.g. gradual promotion based on timestep), but found that a simple cutoff
|
||||
# threshold worked well.
|
||||
# We use a small epsilon to avoid any potential issues with floating point precision.
|
||||
eps = 1e-4
|
||||
mask_gradient_t_cutoff = 0.5
|
||||
if t_prev > mask_gradient_t_cutoff:
|
||||
# Early in the denoising process, use the inpaint mask as-is.
|
||||
return self._inpaint_mask
|
||||
else:
|
||||
# After the cut-off, promote all non-zero mask values to 1.0.
|
||||
mask = self._inpaint_mask.where(self._inpaint_mask <= (0.0 + eps), 1.0)
|
||||
|
||||
return mask
|
||||
|
||||
def _get_change_ratio(self, t_prev: float) -> float:
|
||||
"""Get the change_ratio for t_prev based on the change schedule."""
|
||||
change_ratio = 1.0
|
||||
if t_prev > self._t_cutoff:
|
||||
# If we are before the cutoff, linearly interpolate between the change_ratio at t=1.0 and the change_ratio
|
||||
# at the cutoff.
|
||||
change_ratio = build_line(
|
||||
x1=1.0, y1=self._change_ratio_at_t_1, x2=self._t_cutoff, y2=self._change_ratio_at_cutoff
|
||||
)(t_prev)
|
||||
|
||||
# The change_ratio should be in the range [0, 1]. Assert that we didn't make any mistakes.
|
||||
eps = 1e-5
|
||||
assert 0.0 - eps <= change_ratio <= 1.0 + eps
|
||||
return change_ratio
|
||||
|
||||
def update_noise(
|
||||
self, t_curr_latents: torch.Tensor, pred_noise: torch.Tensor, t_curr: float, t_prev: float
|
||||
) -> torch.Tensor:
|
||||
# Handle gradient cutoff.
|
||||
mask = self._apply_mask_gradient_adjustment(t_prev)
|
||||
|
||||
mask = mask * self._get_change_ratio(t_prev)
|
||||
|
||||
# NOTE(ryand): During inpainting, it is common to guide the denoising process by noising the initial latents for
|
||||
# the current timestep and then blending the predicted intermediate latents with the noised initial latents.
|
||||
# For example:
|
||||
# ```
|
||||
# noised_init_latents = self._noise * t_prev + (1.0 - t_prev) * self._init_latents
|
||||
# return t_prev_latents * self._inpaint_mask + noised_init_latents * (1.0 - self._inpaint_mask)
|
||||
# ```
|
||||
# Instead of guiding based on the noised initial latents, we have decided to guide based on the noise prediction
|
||||
# that points towards the initial latents. The difference between these guidance strategies is minor, but
|
||||
# qualitatively we found the latter to produce slightly better results. When change_ratio is 0.0 or 1.0 there is
|
||||
# no difference between the two strategies.
|
||||
#
|
||||
# We experimented with a number of related guidance strategies, but not exhaustively. It's entirely possible
|
||||
# that there's a much better way to do this.
|
||||
|
||||
# Calculate noise guidance
|
||||
# What noise should the model have predicted at this timestep to step towards self._init_latents?
|
||||
# Derivation:
|
||||
# > t_prev_latents = t_curr_latents + (t_prev - t_curr) * pred_noise
|
||||
# > t_0_latents = t_curr_latents + (0 - t_curr) * init_traj_noise
|
||||
# > t_0_latents = t_curr_latents - t_curr * init_traj_noise
|
||||
# > init_traj_noise = (t_curr_latents - t_0_latents) / t_curr)
|
||||
init_traj_noise = (t_curr_latents - self._init_latents) / t_curr
|
||||
|
||||
# Blend the init_traj_noise with the pred_noise according to the inpaint mask and the trajectory guidance.
|
||||
noise = pred_noise * mask + init_traj_noise * (1.0 - mask)
|
||||
|
||||
return noise
|
||||
@@ -7,14 +7,25 @@ from invokeai.backend.lora.layers.any_lora_layer import AnyLoRALayer
|
||||
from invokeai.backend.lora.layers.utils import any_lora_layer_from_state_dict
|
||||
from invokeai.backend.lora.lora_model_raw import LoRAModelRaw
|
||||
|
||||
# A regex pattern that matches all of the keys in the Kohya FLUX LoRA format.
|
||||
# A regex pattern that matches all of the transformer keys in the Kohya FLUX LoRA format.
|
||||
# Example keys:
|
||||
# lora_unet_double_blocks_0_img_attn_proj.alpha
|
||||
# lora_unet_double_blocks_0_img_attn_proj.lora_down.weight
|
||||
# lora_unet_double_blocks_0_img_attn_proj.lora_up.weight
|
||||
FLUX_KOHYA_KEY_REGEX = (
|
||||
FLUX_KOHYA_TRANSFORMER_KEY_REGEX = (
|
||||
r"lora_unet_(\w+_blocks)_(\d+)_(img_attn|img_mlp|img_mod|txt_attn|txt_mlp|txt_mod|linear1|linear2|modulation)_?(.*)"
|
||||
)
|
||||
# A regex pattern that matches all of the CLIP keys in the Kohya FLUX LoRA format.
|
||||
# Example keys:
|
||||
# lora_te1_text_model_encoder_layers_0_mlp_fc1.alpha
|
||||
# lora_te1_text_model_encoder_layers_0_mlp_fc1.lora_down.weight
|
||||
# lora_te1_text_model_encoder_layers_0_mlp_fc1.lora_up.weight
|
||||
FLUX_KOHYA_CLIP_KEY_REGEX = r"lora_te1_text_model_encoder_layers_(\d+)_(mlp|self_attn)_(\w+)\.?.*"
|
||||
|
||||
|
||||
# Prefixes used to distinguish between transformer and CLIP text encoder keys in the InvokeAI LoRA format.
|
||||
FLUX_KOHYA_TRANFORMER_PREFIX = "lora_transformer-"
|
||||
FLUX_KOHYA_CLIP_PREFIX = "lora_clip-"
|
||||
|
||||
|
||||
def is_state_dict_likely_in_flux_kohya_format(state_dict: Dict[str, Any]) -> bool:
|
||||
@@ -23,7 +34,10 @@ def is_state_dict_likely_in_flux_kohya_format(state_dict: Dict[str, Any]) -> boo
|
||||
This is intended to be a high-precision detector, but it is not guaranteed to have perfect precision. (A
|
||||
perfect-precision detector would require checking all keys against a whitelist and verifying tensor shapes.)
|
||||
"""
|
||||
return all(re.match(FLUX_KOHYA_KEY_REGEX, k) for k in state_dict.keys())
|
||||
return all(
|
||||
re.match(FLUX_KOHYA_TRANSFORMER_KEY_REGEX, k) or re.match(FLUX_KOHYA_CLIP_KEY_REGEX, k)
|
||||
for k in state_dict.keys()
|
||||
)
|
||||
|
||||
|
||||
def lora_model_from_flux_kohya_state_dict(state_dict: Dict[str, torch.Tensor]) -> LoRAModelRaw:
|
||||
@@ -35,13 +49,27 @@ def lora_model_from_flux_kohya_state_dict(state_dict: Dict[str, torch.Tensor]) -
|
||||
grouped_state_dict[layer_name] = {}
|
||||
grouped_state_dict[layer_name][param_name] = value
|
||||
|
||||
# Convert the state dict to the InvokeAI format.
|
||||
grouped_state_dict = convert_flux_kohya_state_dict_to_invoke_format(grouped_state_dict)
|
||||
# Split the grouped state dict into transformer and CLIP state dicts.
|
||||
transformer_grouped_sd: dict[str, dict[str, torch.Tensor]] = {}
|
||||
clip_grouped_sd: dict[str, dict[str, torch.Tensor]] = {}
|
||||
for layer_name, layer_state_dict in grouped_state_dict.items():
|
||||
if layer_name.startswith("lora_unet"):
|
||||
transformer_grouped_sd[layer_name] = layer_state_dict
|
||||
elif layer_name.startswith("lora_te1"):
|
||||
clip_grouped_sd[layer_name] = layer_state_dict
|
||||
else:
|
||||
raise ValueError(f"Layer '{layer_name}' does not match the expected pattern for FLUX LoRA weights.")
|
||||
|
||||
# Convert the state dicts to the InvokeAI format.
|
||||
transformer_grouped_sd = _convert_flux_transformer_kohya_state_dict_to_invoke_format(transformer_grouped_sd)
|
||||
clip_grouped_sd = _convert_flux_clip_kohya_state_dict_to_invoke_format(clip_grouped_sd)
|
||||
|
||||
# Create LoRA layers.
|
||||
layers: dict[str, AnyLoRALayer] = {}
|
||||
for layer_key, layer_state_dict in grouped_state_dict.items():
|
||||
layers[layer_key] = any_lora_layer_from_state_dict(layer_state_dict)
|
||||
for layer_key, layer_state_dict in transformer_grouped_sd.items():
|
||||
layers[FLUX_KOHYA_TRANFORMER_PREFIX + layer_key] = any_lora_layer_from_state_dict(layer_state_dict)
|
||||
for layer_key, layer_state_dict in clip_grouped_sd.items():
|
||||
layers[FLUX_KOHYA_CLIP_PREFIX + layer_key] = any_lora_layer_from_state_dict(layer_state_dict)
|
||||
|
||||
# Create and return the LoRAModelRaw.
|
||||
return LoRAModelRaw(layers=layers)
|
||||
@@ -50,16 +78,34 @@ def lora_model_from_flux_kohya_state_dict(state_dict: Dict[str, torch.Tensor]) -
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
def convert_flux_kohya_state_dict_to_invoke_format(state_dict: Dict[str, T]) -> Dict[str, T]:
|
||||
"""Converts a state dict from the Kohya FLUX LoRA format to LoRA weight format used internally by InvokeAI.
|
||||
def _convert_flux_clip_kohya_state_dict_to_invoke_format(state_dict: Dict[str, T]) -> Dict[str, T]:
|
||||
"""Converts a CLIP LoRA state dict from the Kohya FLUX LoRA format to LoRA weight format used internally by
|
||||
InvokeAI.
|
||||
|
||||
Example key conversions:
|
||||
|
||||
"lora_te1_text_model_encoder_layers_0_mlp_fc1" -> "text_model.encoder.layers.0.mlp.fc1",
|
||||
"lora_te1_text_model_encoder_layers_0_self_attn_k_proj" -> "text_model.encoder.layers.0.self_attn.k_proj"
|
||||
"""
|
||||
converted_sd: dict[str, T] = {}
|
||||
for k, v in state_dict.items():
|
||||
match = re.match(FLUX_KOHYA_CLIP_KEY_REGEX, k)
|
||||
if match:
|
||||
new_key = f"text_model.encoder.layers.{match.group(1)}.{match.group(2)}.{match.group(3)}"
|
||||
converted_sd[new_key] = v
|
||||
else:
|
||||
raise ValueError(f"Key '{k}' does not match the expected pattern for FLUX LoRA weights.")
|
||||
|
||||
return converted_sd
|
||||
|
||||
|
||||
def _convert_flux_transformer_kohya_state_dict_to_invoke_format(state_dict: Dict[str, T]) -> Dict[str, T]:
|
||||
"""Converts a FLUX tranformer LoRA state dict from the Kohya FLUX LoRA format to LoRA weight format used internally
|
||||
by InvokeAI.
|
||||
|
||||
Example key conversions:
|
||||
"lora_unet_double_blocks_0_img_attn_proj" -> "double_blocks.0.img_attn.proj"
|
||||
"lora_unet_double_blocks_0_img_attn_proj" -> "double_blocks.0.img_attn.proj"
|
||||
"lora_unet_double_blocks_0_img_attn_proj" -> "double_blocks.0.img_attn.proj"
|
||||
"lora_unet_double_blocks_0_img_attn_qkv" -> "double_blocks.0.img_attn.qkv"
|
||||
"lora_unet_double_blocks_0_img_attn_qkv" -> "double_blocks.0.img.attn.qkv"
|
||||
"lora_unet_double_blocks_0_img_attn_qkv" -> "double_blocks.0.img.attn.qkv"
|
||||
"""
|
||||
|
||||
def replace_func(match: re.Match[str]) -> str:
|
||||
@@ -70,9 +116,9 @@ def convert_flux_kohya_state_dict_to_invoke_format(state_dict: Dict[str, T]) ->
|
||||
|
||||
converted_dict: dict[str, T] = {}
|
||||
for k, v in state_dict.items():
|
||||
match = re.match(FLUX_KOHYA_KEY_REGEX, k)
|
||||
match = re.match(FLUX_KOHYA_TRANSFORMER_KEY_REGEX, k)
|
||||
if match:
|
||||
new_key = re.sub(FLUX_KOHYA_KEY_REGEX, replace_func, k)
|
||||
new_key = re.sub(FLUX_KOHYA_TRANSFORMER_KEY_REGEX, replace_func, k)
|
||||
converted_dict[new_key] = v
|
||||
else:
|
||||
raise ValueError(f"Key '{k}' does not match the expected pattern for FLUX LoRA weights.")
|
||||
|
||||
@@ -157,6 +157,7 @@ class MainModelDefaultSettings(BaseModel):
|
||||
)
|
||||
width: int | None = Field(default=None, multiple_of=8, ge=64, description="Default width for this model")
|
||||
height: int | None = Field(default=None, multiple_of=8, ge=64, description="Default height for this model")
|
||||
guidance: float | None = Field(default=None, ge=1, description="Default Guidance for this model")
|
||||
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"reportBugLabel": "بلغ عن خطأ",
|
||||
"settingsLabel": "إعدادات",
|
||||
"img2img": "صورة إلى صورة",
|
||||
"unifiedCanvas": "لوحة موحدة",
|
||||
"nodes": "عقد",
|
||||
"upload": "رفع",
|
||||
"load": "تحميل",
|
||||
@@ -16,204 +15,8 @@
|
||||
"galleryImageSize": "حجم الصورة",
|
||||
"gallerySettings": "إعدادات المعرض",
|
||||
"autoSwitchNewImages": "التبديل التلقائي إلى الصور الجديدة",
|
||||
"loadMore": "تحميل المزيد",
|
||||
"noImagesInGallery": "لا توجد صور في المعرض"
|
||||
},
|
||||
"hotkeys": {
|
||||
"keyboardShortcuts": "مفاتيح الأزرار المختصرة",
|
||||
"appHotkeys": "مفاتيح التطبيق",
|
||||
"generalHotkeys": "مفاتيح عامة",
|
||||
"galleryHotkeys": "مفاتيح المعرض",
|
||||
"unifiedCanvasHotkeys": "مفاتيح اللوحةالموحدة ",
|
||||
"invoke": {
|
||||
"title": "أدعو",
|
||||
"desc": "إنشاء صورة"
|
||||
},
|
||||
"cancel": {
|
||||
"title": "إلغاء",
|
||||
"desc": "إلغاء إنشاء الصورة"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"title": "تركيز الإشعار",
|
||||
"desc": "تركيز منطقة الإدخال الإشعار"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"title": "تبديل الخيارات",
|
||||
"desc": "فتح وإغلاق لوحة الخيارات"
|
||||
},
|
||||
"pinOptions": {
|
||||
"title": "خيارات التثبيت",
|
||||
"desc": "ثبت لوحة الخيارات"
|
||||
},
|
||||
"toggleGallery": {
|
||||
"title": "تبديل المعرض",
|
||||
"desc": "فتح وإغلاق درابزين المعرض"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"title": "تكبير مساحة العمل",
|
||||
"desc": "إغلاق اللوحات وتكبير مساحة العمل"
|
||||
},
|
||||
"changeTabs": {
|
||||
"title": "تغيير الألسنة",
|
||||
"desc": "التبديل إلى مساحة عمل أخرى"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"title": "تبديل الطرفية",
|
||||
"desc": "فتح وإغلاق الطرفية"
|
||||
},
|
||||
"setPrompt": {
|
||||
"title": "ضبط التشعب",
|
||||
"desc": "استخدم تشعب الصورة الحالية"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "ضبط البذور",
|
||||
"desc": "استخدم بذور الصورة الحالية"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "ضبط المعلمات",
|
||||
"desc": "استخدم جميع المعلمات الخاصة بالصورة الحالية"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "استعادة الوجوه",
|
||||
"desc": "استعادة الصورة الحالية"
|
||||
},
|
||||
"showInfo": {
|
||||
"title": "عرض المعلومات",
|
||||
"desc": "عرض معلومات البيانات الخاصة بالصورة الحالية"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"title": "أرسل إلى صورة إلى صورة",
|
||||
"desc": "أرسل الصورة الحالية إلى صورة إلى صورة"
|
||||
},
|
||||
"deleteImage": {
|
||||
"title": "حذف الصورة",
|
||||
"desc": "حذف الصورة الحالية"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "أغلق اللوحات",
|
||||
"desc": "يغلق اللوحات المفتوحة"
|
||||
},
|
||||
"previousImage": {
|
||||
"title": "الصورة السابقة",
|
||||
"desc": "عرض الصورة السابقة في الصالة"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "الصورة التالية",
|
||||
"desc": "عرض الصورة التالية في الصالة"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "زيادة حجم صورة الصالة",
|
||||
"desc": "يزيد حجم الصور المصغرة في الصالة"
|
||||
},
|
||||
"decreaseGalleryThumbSize": {
|
||||
"title": "انقاص حجم صورة الصالة",
|
||||
"desc": "ينقص حجم الصور المصغرة في الصالة"
|
||||
},
|
||||
"selectBrush": {
|
||||
"title": "تحديد الفرشاة",
|
||||
"desc": "يحدد الفرشاة على اللوحة"
|
||||
},
|
||||
"selectEraser": {
|
||||
"title": "تحديد الممحاة",
|
||||
"desc": "يحدد الممحاة على اللوحة"
|
||||
},
|
||||
"decreaseBrushSize": {
|
||||
"title": "تصغير حجم الفرشاة",
|
||||
"desc": "يصغر حجم الفرشاة/الممحاة على اللوحة"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "زيادة حجم الفرشاة",
|
||||
"desc": "يزيد حجم فرشة اللوحة / الممحاة"
|
||||
},
|
||||
"decreaseBrushOpacity": {
|
||||
"title": "تخفيض شفافية الفرشاة",
|
||||
"desc": "يخفض شفافية فرشة اللوحة"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"title": "زيادة شفافية الفرشاة",
|
||||
"desc": "يزيد شفافية فرشة اللوحة"
|
||||
},
|
||||
"moveTool": {
|
||||
"title": "أداة التحريك",
|
||||
"desc": "يتيح التحرك في اللوحة"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "ملء الصندوق المحدد",
|
||||
"desc": "يملأ الصندوق المحدد بلون الفرشاة"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"title": "محو الصندوق المحدد",
|
||||
"desc": "يمحو منطقة الصندوق المحدد"
|
||||
},
|
||||
"colorPicker": {
|
||||
"title": "اختيار منتقي اللون",
|
||||
"desc": "يختار منتقي اللون الخاص باللوحة"
|
||||
},
|
||||
"toggleSnap": {
|
||||
"title": "تبديل التأكيد",
|
||||
"desc": "يبديل تأكيد الشبكة"
|
||||
},
|
||||
"quickToggleMove": {
|
||||
"title": "تبديل سريع للتحريك",
|
||||
"desc": "يبديل مؤقتا وضع التحريك"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"title": "تبديل الطبقة",
|
||||
"desc": "يبديل إختيار الطبقة القناع / الأساسية"
|
||||
},
|
||||
"clearMask": {
|
||||
"title": "مسح القناع",
|
||||
"desc": "مسح القناع بأكمله"
|
||||
},
|
||||
"hideMask": {
|
||||
"title": "إخفاء الكمامة",
|
||||
"desc": "إخفاء وإظهار الكمامة"
|
||||
},
|
||||
"showHideBoundingBox": {
|
||||
"title": "إظهار / إخفاء علبة التحديد",
|
||||
"desc": "تبديل ظهور علبة التحديد"
|
||||
},
|
||||
"mergeVisible": {
|
||||
"title": "دمج الطبقات الظاهرة",
|
||||
"desc": "دمج جميع الطبقات الظاهرة في اللوحة"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "حفظ إلى صالة الأزياء",
|
||||
"desc": "حفظ اللوحة الحالية إلى صالة الأزياء"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "نسخ إلى الحافظة",
|
||||
"desc": "نسخ اللوحة الحالية إلى الحافظة"
|
||||
},
|
||||
"downloadImage": {
|
||||
"title": "تنزيل الصورة",
|
||||
"desc": "تنزيل اللوحة الحالية"
|
||||
},
|
||||
"undoStroke": {
|
||||
"title": "تراجع عن الخط",
|
||||
"desc": "تراجع عن خط الفرشاة"
|
||||
},
|
||||
"redoStroke": {
|
||||
"title": "إعادة الخط",
|
||||
"desc": "إعادة خط الفرشاة"
|
||||
},
|
||||
"resetView": {
|
||||
"title": "إعادة تعيين العرض",
|
||||
"desc": "إعادة تعيين عرض اللوحة"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"title": "الصورة السابقة في المرحلة التجريبية",
|
||||
"desc": "الصورة السابقة في منطقة المرحلة التجريبية"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"title": "الصورة التالية في المرحلة التجريبية",
|
||||
"desc": "الصورة التالية في منطقة المرحلة التجريبية"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"title": "قبول الصورة في المرحلة التجريبية",
|
||||
"desc": "قبول الصورة الحالية في منطقة المرحلة التجريبية"
|
||||
}
|
||||
},
|
||||
"modelManager": {
|
||||
"modelManager": "مدير النموذج",
|
||||
"model": "نموذج",
|
||||
@@ -258,8 +61,6 @@
|
||||
"scaledHeight": "الارتفاع المحجوب",
|
||||
"infillMethod": "طريقة التعبئة",
|
||||
"tileSize": "حجم البلاطة",
|
||||
"sendToImg2Img": "أرسل إلى صورة إلى صورة",
|
||||
"sendToUnifiedCanvas": "أرسل إلى الخطوط الموحدة",
|
||||
"copyImage": "نسخ الصورة",
|
||||
"downloadImage": "تحميل الصورة",
|
||||
"usePrompt": "استخدم المحث",
|
||||
@@ -272,7 +73,6 @@
|
||||
"models": "موديلات",
|
||||
"displayInProgress": "عرض الصور المؤرشفة",
|
||||
"confirmOnDelete": "تأكيد عند الحذف",
|
||||
"enableImageDebugging": "تمكين التصحيح عند التصوير",
|
||||
"resetWebUI": "إعادة تعيين واجهة الويب",
|
||||
"resetWebUIDesc1": "إعادة تعيين واجهة الويب يعيد فقط ذاكرة التخزين المؤقت للمتصفح لصورك وإعداداتك المذكورة. لا يحذف أي صور من القرص.",
|
||||
"resetWebUIDesc2": "إذا لم تظهر الصور في الصالة أو إذا كان شيء آخر غير ناجح، يرجى المحاولة إعادة تعيين قبل تقديم مشكلة على جيت هب.",
|
||||
@@ -281,71 +81,6 @@
|
||||
"toast": {
|
||||
"uploadFailed": "فشل التحميل",
|
||||
"imageCopied": "تم نسخ الصورة",
|
||||
"imageNotLoadedDesc": "لم يتم العثور على صورة لإرسالها إلى وحدة الصورة",
|
||||
"canvasMerged": "تم دمج الخط",
|
||||
"sentToImageToImage": "تم إرسال إلى صورة إلى صورة",
|
||||
"sentToUnifiedCanvas": "تم إرسال إلى لوحة موحدة",
|
||||
"parametersNotSet": "لم يتم تعيين المعلمات",
|
||||
"metadataLoadFailed": "فشل تحميل البيانات الوصفية"
|
||||
},
|
||||
"tooltip": {
|
||||
"feature": {
|
||||
"prompt": "هذا هو حقل التحذير. يشمل التحذير عناصر الإنتاج والمصطلحات الأسلوبية. يمكنك إضافة الأوزان (أهمية الرمز) في التحذير أيضًا، ولكن أوامر CLI والمعلمات لن تعمل.",
|
||||
"gallery": "تعرض Gallery منتجات من مجلد الإخراج عندما يتم إنشاؤها. تخزن الإعدادات داخل الملفات ويتم الوصول إليها عن طريق قائمة السياق.",
|
||||
"other": "ستمكن هذه الخيارات من وضع عمليات معالجة بديلة لـاستحضر الذكاء الصناعي. سيؤدي 'الزخرفة بلا جدران' إلى إنشاء أنماط تكرارية في الإخراج. 'دقة عالية' هي الإنتاج خلال خطوتين عبر صورة إلى صورة: استخدم هذا الإعداد عندما ترغب في توليد صورة أكبر وأكثر تجانبًا دون العيوب. ستستغرق الأشياء وقتًا أطول من نص إلى صورة المعتاد.",
|
||||
"seed": "يؤثر قيمة البذور على الضوضاء الأولي الذي يتم تكوين الصورة منه. يمكنك استخدام البذور الخاصة بالصور السابقة. 'عتبة الضوضاء' يتم استخدامها لتخفيف العناصر الخللية في قيم CFG العالية (جرب مدى 0-10), و Perlin لإضافة ضوضاء Perlin أثناء الإنتاج: كلا منهما يعملان على إضافة التنوع إلى النتائج الخاصة بك.",
|
||||
"upscale": "استخدم إي إس آر جان لتكبير الصورة على الفور بعد الإنتاج.",
|
||||
"boundingBox": "مربع الحدود هو نفس الإعدادات العرض والارتفاع لنص إلى صورة أو صورة إلى صورة. فقط المنطقة في المربع سيتم معالجتها."
|
||||
}
|
||||
},
|
||||
"unifiedCanvas": {
|
||||
"layer": "طبقة",
|
||||
"base": "قاعدة",
|
||||
"mask": "قناع",
|
||||
"maskingOptions": "خيارات القناع",
|
||||
"enableMask": "مكن القناع",
|
||||
"preserveMaskedArea": "الحفاظ على المنطقة المقنعة",
|
||||
"clearMask": "مسح القناع",
|
||||
"brush": "فرشاة",
|
||||
"eraser": "ممحاة",
|
||||
"fillBoundingBox": "ملئ إطار الحدود",
|
||||
"eraseBoundingBox": "مسح إطار الحدود",
|
||||
"colorPicker": "اختيار اللون",
|
||||
"brushOptions": "خيارات الفرشاة",
|
||||
"brushSize": "الحجم",
|
||||
"move": "تحريك",
|
||||
"resetView": "إعادة تعيين العرض",
|
||||
"mergeVisible": "دمج الظاهر",
|
||||
"saveToGallery": "حفظ إلى المعرض",
|
||||
"copyToClipboard": "نسخ إلى الحافظة",
|
||||
"downloadAsImage": "تنزيل على شكل صورة",
|
||||
"undo": "تراجع",
|
||||
"redo": "إعادة",
|
||||
"clearCanvas": "مسح سبيكة الكاملة",
|
||||
"canvasSettings": "إعدادات سبيكة الكاملة",
|
||||
"showIntermediates": "إظهار الوسطاء",
|
||||
"showGrid": "إظهار الشبكة",
|
||||
"snapToGrid": "الالتفاف إلى الشبكة",
|
||||
"darkenOutsideSelection": "تعمية خارج التحديد",
|
||||
"autoSaveToGallery": "حفظ تلقائي إلى المعرض",
|
||||
"saveBoxRegionOnly": "حفظ منطقة الصندوق فقط",
|
||||
"limitStrokesToBox": "تحديد عدد الخطوط إلى الصندوق",
|
||||
"showCanvasDebugInfo": "إظهار معلومات تصحيح سبيكة الكاملة",
|
||||
"clearCanvasHistory": "مسح تاريخ سبيكة الكاملة",
|
||||
"clearHistory": "مسح التاريخ",
|
||||
"clearCanvasHistoryMessage": "مسح تاريخ اللوحة تترك اللوحة الحالية عائمة، ولكن تمسح بشكل غير قابل للتراجع تاريخ التراجع والإعادة.",
|
||||
"clearCanvasHistoryConfirm": "هل أنت متأكد من رغبتك في مسح تاريخ اللوحة؟",
|
||||
"activeLayer": "الطبقة النشطة",
|
||||
"canvasScale": "مقياس اللوحة",
|
||||
"boundingBox": "صندوق الحدود",
|
||||
"scaledBoundingBox": "صندوق الحدود المكبر",
|
||||
"boundingBoxPosition": "موضع صندوق الحدود",
|
||||
"canvasDimensions": "أبعاد اللوحة",
|
||||
"canvasPosition": "موضع اللوحة",
|
||||
"cursorPosition": "موضع المؤشر",
|
||||
"previous": "السابق",
|
||||
"next": "التالي",
|
||||
"accept": "قبول",
|
||||
"discardAll": "تجاهل الكل"
|
||||
"parametersNotSet": "لم يتم تعيين المعلمات"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,8 +12,7 @@
|
||||
"resetUI": "$t(accessibility.reset) UI",
|
||||
"showGalleryPanel": "Show Gallery Panel",
|
||||
"showOptionsPanel": "Show Side Panel",
|
||||
"uploadImage": "Upload Image",
|
||||
"loadMore": "Load More"
|
||||
"uploadImage": "Upload Image"
|
||||
},
|
||||
"boards": {
|
||||
"addBoard": "Add Board",
|
||||
@@ -128,10 +127,8 @@
|
||||
"load": "Load",
|
||||
"loading": "Loading",
|
||||
"localSystem": "Local System",
|
||||
"loglevel": "Log Level",
|
||||
"learnMore": "Learn More",
|
||||
"modelManager": "Model Manager",
|
||||
"nodeEditor": "Node Editor",
|
||||
"nodes": "Workflows",
|
||||
"notInstalled": "Not $t(common.installed)",
|
||||
"openInNewTab": "Open in New Tab",
|
||||
@@ -152,7 +149,6 @@
|
||||
"template": "Template",
|
||||
"toResolve": "To resolve",
|
||||
"txt2img": "Text To Image",
|
||||
"unifiedCanvas": "Unified Canvas",
|
||||
"unknown": "Unknown",
|
||||
"upload": "Upload",
|
||||
"updated": "Updated",
|
||||
@@ -167,11 +163,7 @@
|
||||
"selected": "Selected",
|
||||
"tab": "Tab",
|
||||
"view": "View",
|
||||
"viewDesc": "Review images in a large gallery view",
|
||||
"edit": "Edit",
|
||||
"editDesc": "Edit on the Canvas",
|
||||
"comparing": "Comparing",
|
||||
"comparingDesc": "Comparing two images",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"placeholderSelectAModel": "Select a model",
|
||||
@@ -309,14 +301,12 @@
|
||||
"image": "image",
|
||||
"jump": "Jump",
|
||||
"loading": "Loading",
|
||||
"loadMore": "Load More",
|
||||
"newestFirst": "Newest First",
|
||||
"oldestFirst": "Oldest First",
|
||||
"sortDirection": "Sort Direction",
|
||||
"showStarredImagesFirst": "Show Starred Images First",
|
||||
"noImageSelected": "No Image Selected",
|
||||
"noImagesInGallery": "No Images to Display",
|
||||
"setCurrentImage": "Set as Current Image",
|
||||
"starImage": "Star Image",
|
||||
"unstarImage": "Unstar Image",
|
||||
"unableToLoad": "Unable to load Gallery",
|
||||
@@ -326,14 +316,11 @@
|
||||
"bulkDownloadRequestedDesc": "Your download request is being prepared. This may take a few moments.",
|
||||
"bulkDownloadRequestFailed": "Problem Preparing Download",
|
||||
"bulkDownloadFailed": "Download Failed",
|
||||
"problemDeletingImages": "Problem Deleting Images",
|
||||
"problemDeletingImagesDesc": "One or more images could not be deleted",
|
||||
"viewerImage": "Viewer Image",
|
||||
"compareImage": "Compare Image",
|
||||
"openInViewer": "Open in Viewer",
|
||||
"searchImages": "Search by Metadata",
|
||||
"selectAllOnPage": "Select All On Page",
|
||||
"selectAllOnBoard": "Select All On Board",
|
||||
"showArchivedBoards": "Show Archived Boards",
|
||||
"selectForCompare": "Select for Compare",
|
||||
"selectAnImageToCompare": "Select an Image to Compare",
|
||||
@@ -341,16 +328,15 @@
|
||||
"sideBySide": "Side-by-Side",
|
||||
"hover": "Hover",
|
||||
"swapImages": "Swap Images",
|
||||
"compareOptions": "Comparison Options",
|
||||
"stretchToFit": "Stretch to Fit",
|
||||
"exitCompare": "Exit Compare",
|
||||
"compareHelp1": "Hold <Kbd>Alt</Kbd> while clicking a gallery image or using the arrow keys to change the compare image.",
|
||||
"compareHelp2": "Press <Kbd>M</Kbd> to cycle through comparison modes.",
|
||||
"compareHelp3": "Press <Kbd>C</Kbd> to swap the compared images.",
|
||||
"compareHelp4": "Press <Kbd>Z</Kbd> or <Kbd>Esc</Kbd> to exit.",
|
||||
"toggleMiniViewer": "Toggle Mini Viewer",
|
||||
"openViewer": "Open Viewer",
|
||||
"closeViewer": "Close Viewer"
|
||||
"closeViewer": "Close Viewer",
|
||||
"move": "Move"
|
||||
},
|
||||
"hotkeys": {
|
||||
"hotkeys": "Hotkeys",
|
||||
@@ -517,41 +503,57 @@
|
||||
"transformSelected": {
|
||||
"title": "Transform",
|
||||
"desc": "Transform the selected layer."
|
||||
},
|
||||
"applyFilter": {
|
||||
"title": "Apply Filter",
|
||||
"desc": "Apply the pending filter to the selected layer."
|
||||
},
|
||||
"cancelFilter": {
|
||||
"title": "Cancel Filter",
|
||||
"desc": "Cancel the pending filter."
|
||||
},
|
||||
"applyTransform": {
|
||||
"title": "Apply Transform",
|
||||
"desc": "Apply the pending transform to the selected layer."
|
||||
},
|
||||
"cancelTransform": {
|
||||
"title": "Cancel Transform",
|
||||
"desc": "Cancel the pending transform."
|
||||
}
|
||||
},
|
||||
"workflows": {
|
||||
"title": "Workflows",
|
||||
"addNode": {
|
||||
"title": "Add Node",
|
||||
"descl": "Open the add node menu."
|
||||
"desc": "Open the add node menu."
|
||||
},
|
||||
"copySelection": {
|
||||
"title": "Copy",
|
||||
"descl": "Copy selected nodes and edges."
|
||||
"desc": "Copy selected nodes and edges."
|
||||
},
|
||||
"pasteSelection": {
|
||||
"title": "Paste",
|
||||
"descl": "Paste copied nodes and edges."
|
||||
"desc": "Paste copied nodes and edges."
|
||||
},
|
||||
"pasteSelectionWithEdges": {
|
||||
"title": "Paste with Edges",
|
||||
"descl": "Paste copied nodes, edges, and all edges connected to copied nodes."
|
||||
"desc": "Paste copied nodes, edges, and all edges connected to copied nodes."
|
||||
},
|
||||
"selectAll": {
|
||||
"title": "Select All",
|
||||
"descl": "Select all nodes and edges."
|
||||
"desc": "Select all nodes and edges."
|
||||
},
|
||||
"deleteSelection": {
|
||||
"title": "Delete",
|
||||
"descl": "Delete selected nodes and edges."
|
||||
"desc": "Delete selected nodes and edges."
|
||||
},
|
||||
"undo": {
|
||||
"title": "Undo",
|
||||
"descl": "Undo the last workflow action."
|
||||
"desc": "Undo the last workflow action."
|
||||
},
|
||||
"redo": {
|
||||
"title": "Redo",
|
||||
"descl": "Redo the last workflow action."
|
||||
"desc": "Redo the last workflow action."
|
||||
}
|
||||
},
|
||||
"viewer": {
|
||||
@@ -654,12 +656,10 @@
|
||||
"cfgScale": "CFG scale",
|
||||
"cfgRescaleMultiplier": "$t(parameters.cfgRescaleMultiplier)",
|
||||
"createdBy": "Created By",
|
||||
"fit": "Image to image fit",
|
||||
"generationMode": "Generation Mode",
|
||||
"height": "Height",
|
||||
"imageDetails": "Image Details",
|
||||
"imageDimensions": "Image Dimensions",
|
||||
"initImage": "Initial image",
|
||||
"metadata": "Metadata",
|
||||
"model": "Model",
|
||||
"negativePrompt": "Negative Prompt",
|
||||
@@ -679,7 +679,8 @@
|
||||
"Threshold": "Noise Threshold",
|
||||
"vae": "VAE",
|
||||
"width": "Width",
|
||||
"workflow": "Workflow"
|
||||
"workflow": "Workflow",
|
||||
"canvasV2Metadata": "Canvas"
|
||||
},
|
||||
"modelManager": {
|
||||
"active": "active",
|
||||
@@ -692,7 +693,6 @@
|
||||
"baseModel": "Base Model",
|
||||
"cancel": "Cancel",
|
||||
"clipEmbed": "CLIP Embed",
|
||||
"clipVision": "CLIP Vision",
|
||||
"config": "Config",
|
||||
"convert": "Convert",
|
||||
"convertingModelBegin": "Converting Model. Please wait.",
|
||||
@@ -719,13 +719,6 @@
|
||||
"huggingFaceRepoID": "HuggingFace Repo ID",
|
||||
"huggingFaceHelper": "If multiple models are found in this repo, you will be prompted to select one to install.",
|
||||
"hfToken": "HuggingFace Token",
|
||||
"hfTokenHelperText": "A HF token is required to use checkpoint models. Click here to create or get your token.",
|
||||
"hfTokenInvalid": "Invalid or Missing HF Token",
|
||||
"hfTokenInvalidErrorMessage": "Invalid or missing HuggingFace token.",
|
||||
"hfTokenInvalidErrorMessage2": "Update it in the ",
|
||||
"hfTokenUnableToVerify": "Unable to Verify HF Token",
|
||||
"hfTokenUnableToVerifyErrorMessage": "Unable to verify HuggingFace token. This is likely due to a network error. Please try again later.",
|
||||
"hfTokenSaved": "HF Token Saved",
|
||||
"imageEncoderModelId": "Image Encoder Model ID",
|
||||
"installQueue": "Install Queue",
|
||||
"inplaceInstall": "In-place install",
|
||||
@@ -734,6 +727,7 @@
|
||||
"installAll": "Install All",
|
||||
"installRepo": "Install Repo",
|
||||
"ipAdapters": "IP Adapters",
|
||||
"learnMoreAboutSupportedModels": "Learn more about the models we support",
|
||||
"load": "Load",
|
||||
"localOnly": "local only",
|
||||
"manual": "Manual",
|
||||
@@ -752,8 +746,6 @@
|
||||
"modelManager": "Model Manager",
|
||||
"modelName": "Model Name",
|
||||
"modelSettings": "Model Settings",
|
||||
"modelsSynced": "Models Synced",
|
||||
"modelSyncFailed": "Model Sync Failed",
|
||||
"modelType": "Model Type",
|
||||
"modelUpdated": "Model Updated",
|
||||
"modelUpdateFailed": "Model Update Failed",
|
||||
@@ -795,8 +787,6 @@
|
||||
"urlOrLocalPath": "URL or Local Path",
|
||||
"urlOrLocalPathHelper": "URLs should point to a single file. Local paths can point to a single file or folder for a single diffusers model.",
|
||||
"useDefaultSettings": "Use Default Settings",
|
||||
"v2_768": "v2 (768px)",
|
||||
"v2_base": "v2 (512px)",
|
||||
"vae": "VAE",
|
||||
"vaePrecision": "VAE Precision",
|
||||
"variant": "Variant",
|
||||
@@ -805,7 +795,6 @@
|
||||
"models": {
|
||||
"addLora": "Add LoRA",
|
||||
"concepts": "Concepts",
|
||||
"esrganModel": "ESRGAN Model",
|
||||
"loading": "loading",
|
||||
"noMatchingLoRAs": "No matching LoRAs",
|
||||
"noMatchingModels": "No matching Models",
|
||||
@@ -871,7 +860,6 @@
|
||||
"sourceNodeFieldDoesNotExist": "Invalid edge: source/output field {{node}}.{{field}} does not exist",
|
||||
"targetNodeFieldDoesNotExist": "Invalid edge: target/input field {{node}}.{{field}} does not exist",
|
||||
"deletedInvalidEdge": "Deleted invalid edge {{source}} -> {{target}}",
|
||||
"noConnectionData": "No connection data",
|
||||
"noConnectionInProgress": "No connection in progress",
|
||||
"node": "Node",
|
||||
"nodeOutputs": "Node Outputs",
|
||||
@@ -880,8 +868,6 @@
|
||||
"nodeType": "Node Type",
|
||||
"noFieldsLinearview": "No fields added to Linear View",
|
||||
"noFieldsViewMode": "This workflow has no selected fields to display. View the full workflow to configure values.",
|
||||
"noFieldType": "No field type",
|
||||
"noMatchingNodes": "No matching nodes",
|
||||
"noNodeSelected": "No node selected",
|
||||
"nodeOpacity": "Node Opacity",
|
||||
"nodeVersion": "Node Version",
|
||||
@@ -951,7 +937,6 @@
|
||||
"zoomOutNodes": "Zoom Out",
|
||||
"betaDesc": "This invocation is in beta. Until it is stable, it may have breaking changes during app updates. We plan to support this invocation long-term.",
|
||||
"prototypeDesc": "This invocation is a prototype. It may have breaking changes during app updates and may be removed at any time.",
|
||||
"internalDesc": "This invocation is used internally by Invoke. It may have breaking changes during app updates and may be removed at any time.",
|
||||
"imageAccessError": "Unable to find image {{image_name}}, resetting to default",
|
||||
"boardAccessError": "Unable to find board {{board_id}}, resetting to default",
|
||||
"modelAccessError": "Unable to find model {{key}}, resetting to default",
|
||||
@@ -978,16 +963,11 @@
|
||||
"denoisingStrength": "Denoising Strength",
|
||||
"downloadImage": "Download Image",
|
||||
"general": "General",
|
||||
"globalSettings": "Global Settings",
|
||||
"guidance": "Guidance",
|
||||
"height": "Height",
|
||||
"imageFit": "Fit Initial Image To Output Size",
|
||||
"images": "Images",
|
||||
"infillMethod": "Infill Method",
|
||||
"infillMosaicTileWidth": "Tile Width",
|
||||
"infillMosaicTileHeight": "Tile Height",
|
||||
"infillMosaicMinColor": "Min Color",
|
||||
"infillMosaicMaxColor": "Max Color",
|
||||
"infillColorValue": "Fill Color",
|
||||
"info": "Info",
|
||||
"invoke": {
|
||||
@@ -996,21 +976,14 @@
|
||||
"missingFieldTemplate": "Missing field template",
|
||||
"missingInputForField": "{{nodeLabel}} -> {{fieldLabel}} missing input",
|
||||
"missingNodeTemplate": "Missing node template",
|
||||
"noControlImageForControlAdapter": "Control Adapter #{{number}} has no control image",
|
||||
"imageNotProcessedForControlAdapter": "Control Adapter #{{number}}'s image is not processed",
|
||||
"noInitialImageSelected": "No initial image selected",
|
||||
"noModelForControlAdapter": "Control Adapter #{{number}} has no model selected.",
|
||||
"incompatibleBaseModelForControlAdapter": "Control Adapter #{{number}} model is incompatible with main model.",
|
||||
"noModelSelected": "No model selected",
|
||||
"noT5EncoderModelSelected": "No T5 Encoder model selected for FLUX generation",
|
||||
"noFLUXVAEModelSelected": "No VAE model selected for FLUX generation",
|
||||
"noCLIPEmbedModelSelected": "No CLIP Embed model selected for FLUX generation",
|
||||
"canvasManagerNotLoaded": "Canvas Manager not loaded",
|
||||
"fluxRequiresDimensionsToBeMultipleOf16": "FLUX requires width/height to be multiple of 16",
|
||||
"fluxModelIncompatibleBboxWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), bbox width is {{width}}",
|
||||
"fluxModelIncompatibleBboxHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), bbox height is {{height}}",
|
||||
"fluxModelIncompatibleScaledWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), scaled bbox width is {{width}}",
|
||||
"fluxModelIncompatibleScaledHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), scaled bbox height is {{height}}",
|
||||
"fluxModelIncompatibleScaledBboxWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), scaled bbox width is {{width}}",
|
||||
"fluxModelIncompatibleScaledBboxHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16), scaled bbox height is {{height}}",
|
||||
"canvasIsFiltering": "Canvas is filtering",
|
||||
"canvasIsTransforming": "Canvas is transforming",
|
||||
"canvasIsRasterizing": "Canvas is rasterizing",
|
||||
@@ -1019,12 +992,8 @@
|
||||
"noNodesInGraph": "No nodes in graph",
|
||||
"systemDisconnected": "System disconnected",
|
||||
"layer": {
|
||||
"initialImageNoImageSelected": "no initial image selected",
|
||||
"controlAdapterNoModelSelected": "no Control Adapter model selected",
|
||||
"controlAdapterIncompatibleBaseModel": "incompatible Control Adapter base model",
|
||||
"controlAdapterNoImageSelected": "no Control Adapter image selected",
|
||||
"controlAdapterImageNotProcessed": "Control Adapter image not processed",
|
||||
"t2iAdapterRequiresDimensionsToBeMultipleOf": "T2I Adapter requires width/height to be multiple of",
|
||||
"t2iAdapterIncompatibleBboxWidth": "$t(parameters.invoke.layer.t2iAdapterRequiresDimensionsToBeMultipleOf) {{multiple}}, bbox width is {{width}}",
|
||||
"t2iAdapterIncompatibleBboxHeight": "$t(parameters.invoke.layer.t2iAdapterRequiresDimensionsToBeMultipleOf) {{multiple}}, bbox height is {{height}}",
|
||||
"t2iAdapterIncompatibleScaledBboxWidth": "$t(parameters.invoke.layer.t2iAdapterRequiresDimensionsToBeMultipleOf) {{multiple}}, scaled bbox width is {{width}}",
|
||||
@@ -1038,12 +1007,10 @@
|
||||
},
|
||||
"maskBlur": "Mask Blur",
|
||||
"negativePromptPlaceholder": "Negative Prompt",
|
||||
"globalNegativePromptPlaceholder": "Global Negative Prompt",
|
||||
"noiseThreshold": "Noise Threshold",
|
||||
"patchmatchDownScaleSize": "Downscale",
|
||||
"perlinNoise": "Perlin Noise",
|
||||
"positivePromptPlaceholder": "Positive Prompt",
|
||||
"globalPositivePromptPlaceholder": "Global Positive Prompt",
|
||||
"iterations": "Iterations",
|
||||
"scale": "Scale",
|
||||
"scaleBeforeProcessing": "Scale Before Processing",
|
||||
@@ -1062,7 +1029,7 @@
|
||||
"strength": "Strength",
|
||||
"symmetry": "Symmetry",
|
||||
"tileSize": "Tile Size",
|
||||
"optimizedInpainting": "Optimized Inpainting",
|
||||
"optimizedImageToImage": "Optimized Image-to-Image",
|
||||
"type": "Type",
|
||||
"postProcessing": "Post-Processing (Shift + U)",
|
||||
"processImage": "Process Image",
|
||||
@@ -1073,15 +1040,16 @@
|
||||
"remixImage": "Remix Image",
|
||||
"usePrompt": "Use Prompt",
|
||||
"useSeed": "Use Seed",
|
||||
"width": "Width"
|
||||
"width": "Width",
|
||||
"gaussianBlur": "Gaussian Blur",
|
||||
"boxBlur": "Box Blur",
|
||||
"staged": "Staged"
|
||||
},
|
||||
"dynamicPrompts": {
|
||||
"showDynamicPrompts": "Show Dynamic Prompts",
|
||||
"dynamicPrompts": "Dynamic Prompts",
|
||||
"maxPrompts": "Max Prompts",
|
||||
"promptsPreview": "Prompts Preview",
|
||||
"promptsWithCount_one": "{{count}} Prompt",
|
||||
"promptsWithCount_other": "{{count}} Prompts",
|
||||
"seedBehaviour": {
|
||||
"label": "Seed Behaviour",
|
||||
"perIterationLabel": "Seed per Iteration",
|
||||
@@ -1127,7 +1095,6 @@
|
||||
"resetWebUI": "Reset Web UI",
|
||||
"resetWebUIDesc1": "Resetting the web UI only resets the browser's local cache of your images and remembered settings. It does not delete any images from disk.",
|
||||
"resetWebUIDesc2": "If images aren't showing up in the gallery or something else isn't working, please try resetting before submitting an issue on GitHub.",
|
||||
"shouldLogToConsole": "Console Logging",
|
||||
"showProgressInViewer": "Show Progress Images in Viewer",
|
||||
"ui": "User Interface",
|
||||
"clearIntermediatesDisabled": "Queue must be empty to clear intermediates",
|
||||
@@ -1148,13 +1115,12 @@
|
||||
"baseModelChangedCleared_one": "Cleared or disabled {{count}} incompatible submodel",
|
||||
"baseModelChangedCleared_other": "Cleared or disabled {{count}} incompatible submodels",
|
||||
"canceled": "Processing Canceled",
|
||||
"canvasCopiedClipboard": "Canvas Copied to Clipboard",
|
||||
"canvasDownloaded": "Canvas Downloaded",
|
||||
"canvasMerged": "Canvas Merged",
|
||||
"canvasSavedGallery": "Canvas Saved to Gallery",
|
||||
"canvasSentControlnetAssets": "Canvas Sent to ControlNet & Assets",
|
||||
"connected": "Connected to Server",
|
||||
"imageCopied": "Image Copied",
|
||||
"unableToLoadImage": "Unable to Load Image",
|
||||
"unableToLoadImageMetadata": "Unable to Load Image Metadata",
|
||||
"unableToLoadStylePreset": "Unable to Load Style Preset",
|
||||
"stylePresetLoaded": "Style Preset Loaded",
|
||||
"imageNotLoadedDesc": "Could not find image",
|
||||
"imageSaved": "Image Saved",
|
||||
"imageSavingFailed": "Image Saving Failed",
|
||||
@@ -1166,9 +1132,6 @@
|
||||
"layerCopiedToClipboard": "Layer Copied to Clipboard",
|
||||
"layerSavedToAssets": "Layer Saved to Assets",
|
||||
"loadedWithWarnings": "Workflow Loaded with Warnings",
|
||||
"maskSavedAssets": "Mask Saved to Assets",
|
||||
"maskSentControlnetAssets": "Mask Sent to ControlNet & Assets",
|
||||
"metadataLoadFailed": "Failed to load metadata",
|
||||
"modelAddedSimple": "Model Added to Queue",
|
||||
"modelImportCanceled": "Model Import Canceled",
|
||||
"outOfMemoryError": "Out of Memory Error",
|
||||
@@ -1182,52 +1145,25 @@
|
||||
"parametersSet": "Parameters Recalled",
|
||||
"parametersNotSet": "Parameters Not Recalled",
|
||||
"errorCopied": "Error Copied",
|
||||
"problemCopyingCanvas": "Problem Copying Canvas",
|
||||
"problemCopyingCanvasDesc": "Unable to export base layer",
|
||||
"problemCopyingImage": "Unable to Copy Image",
|
||||
"problemCopyingLayer": "Unable to Copy Layer",
|
||||
"problemSavingLayer": "Unable to Save Layer",
|
||||
"problemDownloadingImage": "Unable to Download Image",
|
||||
"problemDownloadingCanvas": "Problem Downloading Canvas",
|
||||
"problemDownloadingCanvasDesc": "Unable to export base layer",
|
||||
"problemImportingMask": "Problem Importing Mask",
|
||||
"problemImportingMaskDesc": "Unable to export mask",
|
||||
"problemMergingCanvas": "Problem Merging Canvas",
|
||||
"problemMergingCanvasDesc": "Unable to export base layer",
|
||||
"problemSavingCanvas": "Problem Saving Canvas",
|
||||
"problemSavingCanvasDesc": "Unable to export base layer",
|
||||
"problemSavingMask": "Problem Saving Mask",
|
||||
"problemSavingMaskDesc": "Unable to export mask",
|
||||
"prunedQueue": "Pruned Queue",
|
||||
"resetInitialImage": "Reset Initial Image",
|
||||
"sentToCanvas": "Sent to Canvas",
|
||||
"sentToUpscale": "Sent to Upscale",
|
||||
"serverError": "Server Error",
|
||||
"sessionRef": "Session: {{sessionId}}",
|
||||
"setAsCanvasInitialImage": "Set as canvas initial image",
|
||||
"setCanvasInitialImage": "Set canvas initial image",
|
||||
"setControlImage": "Set as control image",
|
||||
"setInitialImage": "Set as initial image",
|
||||
"setNodeField": "Set as node field",
|
||||
"somethingWentWrong": "Something Went Wrong",
|
||||
"uploadFailed": "Upload failed",
|
||||
"uploadFailedInvalidUploadDesc": "Must be single PNG or JPEG image",
|
||||
"uploadInitialImage": "Upload Initial Image",
|
||||
"workflowLoaded": "Workflow Loaded",
|
||||
"problemRetrievingWorkflow": "Problem Retrieving Workflow",
|
||||
"workflowDeleted": "Workflow Deleted",
|
||||
"problemDeletingWorkflow": "Problem Deleting Workflow"
|
||||
},
|
||||
"tooltip": {
|
||||
"feature": {
|
||||
"boundingBox": "The bounding box is the same as the Width and Height settings for Text to Image or Image to Image. Only the area in the box will be processed.",
|
||||
"gallery": "Gallery displays generations from the outputs folder as they're created. Settings are stored within files and accesed by context menu.",
|
||||
"other": "These options will enable alternative processing modes for Invoke. 'Seamless tiling' will create repeating patterns in the output. 'High resolution' is generation in two steps with img2img: use this setting when you want a larger and more coherent image without artifacts. It will take longer than usual txt2img.",
|
||||
"prompt": "This is the prompt field. Prompt includes generation objects and stylistic terms. You can add weight (token importance) in the prompt as well, but CLI commands and parameters will not work.",
|
||||
"seed": "Seed value affects the initial noise from which the image is formed. You can use the already existing seeds from previous images. 'Noise Threshold' is used to mitigate artifacts at high CFG values (try the 0-10 range), and Perlin to add Perlin noise during generation: both serve to add variation to your outputs.",
|
||||
"upscale": "Use ESRGAN to enlarge the image immediately after generation."
|
||||
}
|
||||
},
|
||||
"popovers": {
|
||||
"clipSkip": {
|
||||
"heading": "CLIP Skip",
|
||||
@@ -1570,83 +1506,21 @@
|
||||
]
|
||||
},
|
||||
"optimizedDenoising": {
|
||||
"heading": "Optimized Inpainting",
|
||||
"heading": "Optimized Image-to-Image",
|
||||
"paragraphs": [
|
||||
"Enable optimized denoising for enhanced inpainting transformations with Flux models. This setting improves detail and clarity during generation, but may be turned off to preserve more of your original image. This setting is still being tuned and is in beta status."
|
||||
"Enable 'Optimized Image-to-Image' for a more gradual Denoise Strength scale for image-to-image and inpainting transformations with Flux models. This setting improves the ability to control the amount of change applied to an image, but may be turned off if you prefer to use the standard Denoise Strength scale. This setting is still being tuned and is in beta status."
|
||||
]
|
||||
}
|
||||
},
|
||||
"unifiedCanvas": {
|
||||
"accept": "Accept",
|
||||
"activeLayer": "Active Layer",
|
||||
"antialiasing": "Antialiasing",
|
||||
"autoSaveToGallery": "Auto Save to Gallery",
|
||||
"base": "Base",
|
||||
"boundingBox": "Bounding Box",
|
||||
"boundingBoxPosition": "Bounding Box Position",
|
||||
"brush": "Brush",
|
||||
"brushOptions": "Brush Options",
|
||||
"brushSize": "Size",
|
||||
"canvasDimensions": "Canvas Dimensions",
|
||||
"canvasPosition": "Canvas Position",
|
||||
"canvasScale": "Canvas Scale",
|
||||
"canvasSettings": "Canvas Settings",
|
||||
"clearCanvas": "Clear Canvas",
|
||||
"clearCanvasHistory": "Clear Canvas History",
|
||||
"clearCanvasHistoryConfirm": "Are you sure you want to clear the canvas history?",
|
||||
"clearCanvasHistoryMessage": "Clearing the canvas history leaves your current canvas intact, but irreversibly clears the undo and redo history.",
|
||||
"clearHistory": "Clear History",
|
||||
"clearMask": "Clear Mask (Shift+C)",
|
||||
"coherenceModeGaussianBlur": "Gaussian Blur",
|
||||
"coherenceModeBoxBlur": "Box Blur",
|
||||
"coherenceModeStaged": "Staged",
|
||||
"colorPicker": "Color Picker",
|
||||
"copyToClipboard": "Copy to Clipboard",
|
||||
"cursorPosition": "Cursor Position",
|
||||
"darkenOutsideSelection": "Darken Outside Selection",
|
||||
"discardAll": "Discard All & Cancel Pending Generations",
|
||||
"discardCurrent": "Discard Current",
|
||||
"downloadAsImage": "Download As Image",
|
||||
"enableMask": "Enable Mask",
|
||||
"eraseBoundingBox": "Erase Bounding Box",
|
||||
"eraser": "Eraser",
|
||||
"fillBoundingBox": "Fill Bounding Box",
|
||||
"hideBoundingBox": "Hide Bounding Box",
|
||||
"initialFitImageSize": "Fit Image Size on Drop",
|
||||
"invertBrushSizeScrollDirection": "Invert Scroll for Brush Size",
|
||||
"layer": "Layer",
|
||||
"limitStrokesToBox": "Limit Strokes to Box",
|
||||
"mask": "Mask",
|
||||
"maskingOptions": "Masking Options",
|
||||
"mergeVisible": "Merge Visible",
|
||||
"move": "Move",
|
||||
"next": "Next",
|
||||
"preserveMaskedArea": "Preserve Masked Area",
|
||||
"previous": "Previous",
|
||||
"redo": "Redo",
|
||||
"resetView": "Reset View",
|
||||
"saveBoxRegionOnly": "Save Box Region Only",
|
||||
"saveMask": "Save $t(unifiedCanvas.mask)",
|
||||
"saveToGallery": "Save To Gallery",
|
||||
"scaledBoundingBox": "Scaled Bounding Box",
|
||||
"showBoundingBox": "Show Bounding Box",
|
||||
"showCanvasDebugInfo": "Show Additional Canvas Info",
|
||||
"showGrid": "Show Grid",
|
||||
"showResultsOn": "Show Results (On)",
|
||||
"showResultsOff": "Show Results (Off)",
|
||||
"showIntermediates": "Show Intermediates",
|
||||
"snapToGrid": "Snap to Grid",
|
||||
"undo": "Undo"
|
||||
},
|
||||
"workflows": {
|
||||
"defaultWorkflows": "Default Workflows",
|
||||
"userWorkflows": "User Workflows",
|
||||
"projectWorkflows": "Project Workflows",
|
||||
"ascending": "Ascending",
|
||||
"created": "Created",
|
||||
"descending": "Descending",
|
||||
"workflows": "Workflows",
|
||||
"workflowLibrary": "Library",
|
||||
"userWorkflows": "My Workflows",
|
||||
"defaultWorkflows": "Default Workflows",
|
||||
"projectWorkflows": "Project Workflows",
|
||||
"opened": "Opened",
|
||||
"openWorkflow": "Open Workflow",
|
||||
"updated": "Updated",
|
||||
@@ -1661,8 +1535,6 @@
|
||||
"problemSavingWorkflow": "Problem Saving Workflow",
|
||||
"workflowSaved": "Workflow Saved",
|
||||
"name": "Name",
|
||||
"noRecentWorkflows": "No Recent Workflows",
|
||||
"noUserWorkflows": "No User Workflows",
|
||||
"noWorkflows": "No Workflows",
|
||||
"problemLoading": "Problem Loading Workflows",
|
||||
"loading": "Loading Workflows",
|
||||
@@ -1678,9 +1550,7 @@
|
||||
"loadWorkflow": "$t(common.load) Workflow",
|
||||
"autoLayout": "Auto Layout"
|
||||
},
|
||||
"app": {
|
||||
"storeNotInitialized": "Store is not initialized"
|
||||
},
|
||||
"app": {},
|
||||
"controlLayers": {
|
||||
"regional": "Regional",
|
||||
"global": "Global",
|
||||
@@ -1691,8 +1561,6 @@
|
||||
"saveCanvasToGallery": "Save Canvas to Gallery",
|
||||
"saveBboxToGallery": "Save Bbox to Gallery",
|
||||
"saveLayerToAssets": "Save Layer to Assets",
|
||||
"newControlLayerFromBbox": "New Control Layer from Bbox",
|
||||
"newRasterLayerFromBbox": "New Raster Layer from Bbox",
|
||||
"savedToGalleryOk": "Saved to Gallery",
|
||||
"savedToGalleryError": "Error saving to gallery",
|
||||
"newGlobalReferenceImageOk": "Created Global Reference Image",
|
||||
@@ -1713,13 +1581,7 @@
|
||||
"mergeVisibleError": "Error merging visible layers",
|
||||
"clearHistory": "Clear History",
|
||||
"bboxOverlay": "Show Bbox Overlay",
|
||||
"generateMode": "Generate",
|
||||
"generateModeDesc": "Create individual images. Generated images are added directly to the gallery.",
|
||||
"composeMode": "Compose",
|
||||
"composeModeDesc": "Compose your work iterative. Generated images are added back to the canvas.",
|
||||
"autoSave": "Auto-save to Gallery",
|
||||
"resetCanvas": "Reset Canvas",
|
||||
"resetAll": "Reset All",
|
||||
"clearCaches": "Clear Caches",
|
||||
"recalculateRects": "Recalculate Rects",
|
||||
"clipToBbox": "Clip Strokes to Bbox",
|
||||
@@ -1730,19 +1592,12 @@
|
||||
"moveToBack": "Move to Back",
|
||||
"moveForward": "Move Forward",
|
||||
"moveBackward": "Move Backward",
|
||||
"brushSize": "Brush Size",
|
||||
"width": "Width",
|
||||
"zoom": "Zoom",
|
||||
"resetView": "Reset View",
|
||||
"controlLayers": "Control Layers",
|
||||
"globalMaskOpacity": "Global Mask Opacity",
|
||||
"autoNegative": "Auto Negative",
|
||||
"enableAutoNegative": "Enable Auto Negative",
|
||||
"disableAutoNegative": "Disable Auto Negative",
|
||||
"deletePrompt": "Delete Prompt",
|
||||
"deleteReferenceImage": "Delete Reference Image",
|
||||
"resetRegion": "Reset Region",
|
||||
"debugLayers": "Debug Layers",
|
||||
"showHUD": "Show HUD",
|
||||
"rectangle": "Rectangle",
|
||||
"maskFill": "Mask Fill",
|
||||
@@ -1754,8 +1609,6 @@
|
||||
"addInpaintMask": "Add $t(controlLayers.inpaintMask)",
|
||||
"addRegionalGuidance": "Add $t(controlLayers.regionalGuidance)",
|
||||
"addGlobalReferenceImage": "Add $t(controlLayers.globalReferenceImage)",
|
||||
"regionalGuidanceLayer": "$t(controlLayers.regionalGuidance) $t(unifiedCanvas.layer)",
|
||||
"raster": "Raster",
|
||||
"rasterLayer": "Raster Layer",
|
||||
"controlLayer": "Control Layer",
|
||||
"inpaintMask": "Inpaint Mask",
|
||||
@@ -1796,17 +1649,10 @@
|
||||
"globalReferenceImages_withCount_visible": "Global Reference Images ({{count}})",
|
||||
"inpaintMasks_withCount_visible": "Inpaint Masks ({{count}})",
|
||||
"layer": "Layer",
|
||||
"opacityFilter": "Opacity Filter",
|
||||
"clearProcessor": "Clear Processor",
|
||||
"resetProcessor": "Reset Processor to Defaults",
|
||||
"noLayersAdded": "No Layers Added",
|
||||
"layer_one": "Layer",
|
||||
"layer_other": "Layers",
|
||||
"layer_withCount_one": "Layer ({{count}})",
|
||||
"layer_withCount_other": "Layers ({{count}})",
|
||||
"objects_zero": "empty",
|
||||
"objects_one": "{{count}} object",
|
||||
"objects_other": "{{count}} objects",
|
||||
"convertToControlLayer": "Convert to Control Layer",
|
||||
"convertToRasterLayer": "Convert to Raster Layer",
|
||||
"transparency": "Transparency",
|
||||
@@ -1819,9 +1665,6 @@
|
||||
"locked": "Locked",
|
||||
"unlocked": "Unlocked",
|
||||
"deleteSelected": "Delete Selected",
|
||||
"deleteAll": "Delete All",
|
||||
"flipHorizontal": "Flip Horizontal",
|
||||
"flipVertical": "Flip Vertical",
|
||||
"stagingOnCanvas": "Staging images on",
|
||||
"replaceLayer": "Replace Layer",
|
||||
"pullBboxIntoLayer": "Pull Bbox into Layer",
|
||||
@@ -1844,8 +1687,6 @@
|
||||
"style": "Style Only",
|
||||
"composition": "Composition Only"
|
||||
},
|
||||
"useSizeOptimizeForModel": "Copy size to W/H (optimize for model)",
|
||||
"useSizeIgnoreModel": "Copy size to W/H (ignore model)",
|
||||
"fill": {
|
||||
"fillColor": "Fill Color",
|
||||
"fillStyle": "Fill Style",
|
||||
@@ -1971,12 +1812,12 @@
|
||||
"isolatedPreview": "Isolated Preview",
|
||||
"isolatedStagingPreview": "Isolated Staging Preview",
|
||||
"isolatedFilteringPreview": "Isolated Filtering Preview",
|
||||
"isolatedTransformingPreview": "Isolated Transforming Preview"
|
||||
"isolatedTransformingPreview": "Isolated Transforming Preview",
|
||||
"invertBrushSizeScrollDirection": "Invert Scroll for Brush Size"
|
||||
},
|
||||
"HUD": {
|
||||
"bbox": "Bbox",
|
||||
"scaledBbox": "Scaled Bbox",
|
||||
"autoSave": "Auto Save",
|
||||
"entityStatus": {
|
||||
"isFiltering": "{{title}} is filtering",
|
||||
"isTransforming": "{{title}} is transforming",
|
||||
@@ -1995,6 +1836,16 @@
|
||||
"newRegionalReferenceImage": "New Regional Reference Image",
|
||||
"newControlLayer": "New Control Layer",
|
||||
"newRasterLayer": "New Raster Layer"
|
||||
},
|
||||
"stagingArea": {
|
||||
"accept": "Accept",
|
||||
"discardAll": "Discard All",
|
||||
"discard": "Discard",
|
||||
"previous": "Previous",
|
||||
"next": "Next",
|
||||
"saveToGallery": "Save To Gallery",
|
||||
"showResultsOn": "Showing Results",
|
||||
"showResultsOff": "Hiding Results"
|
||||
}
|
||||
},
|
||||
"upscaling": {
|
||||
@@ -2051,7 +1902,6 @@
|
||||
"searchByName": "Search by name",
|
||||
"shared": "Shared",
|
||||
"sharedTemplates": "Shared Templates",
|
||||
"templateActions": "Template Actions",
|
||||
"templateDeleted": "Prompt template deleted",
|
||||
"toggleViewMode": "Toggle View Mode",
|
||||
"type": "Type",
|
||||
@@ -2065,25 +1915,21 @@
|
||||
"upsell": {
|
||||
"inviteTeammates": "Invite Teammates",
|
||||
"professional": "Professional",
|
||||
"professionalUpsell": "Available in Invoke’s Professional Edition. Click here or visit invoke.com/pricing for more details.",
|
||||
"professionalUpsell": "Available in Invoke's Professional Edition. Click here or visit invoke.com/pricing for more details.",
|
||||
"shareAccess": "Share Access"
|
||||
},
|
||||
"ui": {
|
||||
"tabs": {
|
||||
"generation": "Generation",
|
||||
"generationTab": "$t(ui.tabs.generation) $t(common.tab)",
|
||||
"canvas": "Canvas",
|
||||
"canvasTab": "$t(ui.tabs.canvas) $t(common.tab)",
|
||||
"workflows": "Workflows",
|
||||
"workflowsTab": "$t(ui.tabs.workflows) $t(common.tab)",
|
||||
"models": "Models",
|
||||
"modelsTab": "$t(ui.tabs.models) $t(common.tab)",
|
||||
"queue": "Queue",
|
||||
"queueTab": "$t(ui.tabs.queue) $t(common.tab)",
|
||||
"upscaling": "Upscaling",
|
||||
"upscalingTab": "$t(ui.tabs.upscaling) $t(common.tab)",
|
||||
"gallery": "Gallery",
|
||||
"galleryTab": "$t(ui.tabs.gallery) $t(common.tab)"
|
||||
"gallery": "Gallery"
|
||||
}
|
||||
},
|
||||
"system": {
|
||||
@@ -2109,8 +1955,7 @@
|
||||
"events": "Events",
|
||||
"queue": "Queue",
|
||||
"metadata": "Metadata"
|
||||
},
|
||||
"showSendingToAlerts": "Alert When Sending to Different View"
|
||||
}
|
||||
},
|
||||
"newUserExperience": {
|
||||
"toGetStarted": "To get started, enter a prompt in the box and click <StrongComponent>Invoke</StrongComponent> to generate your first image. You can choose to save your images directly to the <StrongComponent>Gallery</StrongComponent> or edit them to the <StrongComponent>Canvas</StrongComponent>.",
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"reportBugLabel": "Reportar errores",
|
||||
"settingsLabel": "Ajustes",
|
||||
"img2img": "Imagen a Imagen",
|
||||
"unifiedCanvas": "Lienzo Unificado",
|
||||
"nodes": "Flujos de trabajo",
|
||||
"upload": "Subir imagen",
|
||||
"load": "Cargar",
|
||||
@@ -61,13 +60,11 @@
|
||||
"format": "formato",
|
||||
"unknown": "Desconocido",
|
||||
"input": "Entrada",
|
||||
"nodeEditor": "Editor de nodos",
|
||||
"template": "Plantilla",
|
||||
"prevPage": "Página Anterior",
|
||||
"red": "Rojo",
|
||||
"alpha": "Transparencia",
|
||||
"outputs": "Salidas",
|
||||
"editing": "Editando",
|
||||
"learnMore": "Aprende más",
|
||||
"enabled": "Activado",
|
||||
"disabled": "Desactivado",
|
||||
@@ -76,14 +73,12 @@
|
||||
"created": "Creado",
|
||||
"save": "Guardar",
|
||||
"unknownError": "Error Desconocido",
|
||||
"blue": "Azul",
|
||||
"viewingDesc": "Revisar imágenes en una vista de galería grande"
|
||||
"blue": "Azul"
|
||||
},
|
||||
"gallery": {
|
||||
"galleryImageSize": "Tamaño de la imagen",
|
||||
"gallerySettings": "Ajustes de la galería",
|
||||
"autoSwitchNewImages": "Auto seleccionar Imágenes nuevas",
|
||||
"loadMore": "Cargar más",
|
||||
"noImagesInGallery": "No hay imágenes para mostrar",
|
||||
"deleteImage_one": "Eliminar Imagen",
|
||||
"deleteImage_many": "Eliminar {{count}} Imágenes",
|
||||
@@ -92,206 +87,6 @@
|
||||
"assets": "Activos",
|
||||
"autoAssignBoardOnClick": "Asignación automática de tableros al hacer clic"
|
||||
},
|
||||
"hotkeys": {
|
||||
"keyboardShortcuts": "Atajos de teclado",
|
||||
"appHotkeys": "Atajos de aplicación",
|
||||
"generalHotkeys": "Atajos generales",
|
||||
"galleryHotkeys": "Atajos de galería",
|
||||
"unifiedCanvasHotkeys": "Atajos de lienzo unificado",
|
||||
"invoke": {
|
||||
"title": "Invocar",
|
||||
"desc": "Generar una imagen"
|
||||
},
|
||||
"cancel": {
|
||||
"title": "Cancelar",
|
||||
"desc": "Cancelar el proceso de generación de imagen"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"title": "Mover foco a Entrada de texto",
|
||||
"desc": "Mover foco hacia el campo de texto de la Entrada"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"title": "Alternar opciones",
|
||||
"desc": "Mostar y ocultar el panel de opciones"
|
||||
},
|
||||
"pinOptions": {
|
||||
"title": "Fijar opciones",
|
||||
"desc": "Fijar el panel de opciones"
|
||||
},
|
||||
"toggleGallery": {
|
||||
"title": "Alternar galería",
|
||||
"desc": "Mostar y ocultar la galería de imágenes"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"title": "Maximizar espacio de trabajo",
|
||||
"desc": "Cerrar otros páneles y maximizar el espacio de trabajo"
|
||||
},
|
||||
"changeTabs": {
|
||||
"title": "Cambiar",
|
||||
"desc": "Cambiar entre áreas de trabajo"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"title": "Alternar consola",
|
||||
"desc": "Mostar y ocultar la consola"
|
||||
},
|
||||
"setPrompt": {
|
||||
"title": "Establecer Entrada",
|
||||
"desc": "Usar el texto de entrada de la imagen actual"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "Establecer semilla",
|
||||
"desc": "Usar la semilla de la imagen actual"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "Establecer parámetros",
|
||||
"desc": "Usar todos los parámetros de la imagen actual"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "Restaurar rostros",
|
||||
"desc": "Restaurar rostros en la imagen actual"
|
||||
},
|
||||
"showInfo": {
|
||||
"title": "Mostrar información",
|
||||
"desc": "Mostar metadatos de la imagen actual"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"title": "Enviar hacia Imagen a Imagen",
|
||||
"desc": "Enviar imagen actual hacia Imagen a Imagen"
|
||||
},
|
||||
"deleteImage": {
|
||||
"title": "Eliminar imagen",
|
||||
"desc": "Eliminar imagen actual"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "Cerrar páneles",
|
||||
"desc": "Cerrar los páneles abiertos"
|
||||
},
|
||||
"previousImage": {
|
||||
"title": "Imagen anterior",
|
||||
"desc": "Muetra la imagen anterior en la galería"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "Imagen siguiente",
|
||||
"desc": "Muetra la imagen siguiente en la galería"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "Aumentar imagen en galería",
|
||||
"desc": "Aumenta el tamaño de las miniaturas de la galería"
|
||||
},
|
||||
"decreaseGalleryThumbSize": {
|
||||
"title": "Reducir imagen en galería",
|
||||
"desc": "Reduce el tamaño de las miniaturas de la galería"
|
||||
},
|
||||
"selectBrush": {
|
||||
"title": "Seleccionar pincel",
|
||||
"desc": "Selecciona el pincel en el lienzo"
|
||||
},
|
||||
"selectEraser": {
|
||||
"title": "Seleccionar borrador",
|
||||
"desc": "Selecciona el borrador en el lienzo"
|
||||
},
|
||||
"decreaseBrushSize": {
|
||||
"title": "Disminuir tamaño de herramienta",
|
||||
"desc": "Disminuye el tamaño del pincel/borrador en el lienzo"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "Aumentar tamaño del pincel",
|
||||
"desc": "Aumenta el tamaño del pincel en el lienzo"
|
||||
},
|
||||
"decreaseBrushOpacity": {
|
||||
"title": "Disminuir opacidad del pincel",
|
||||
"desc": "Disminuye la opacidad del pincel en el lienzo"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"title": "Aumentar opacidad del pincel",
|
||||
"desc": "Aumenta la opacidad del pincel en el lienzo"
|
||||
},
|
||||
"moveTool": {
|
||||
"title": "Herramienta de movimiento",
|
||||
"desc": "Permite navegar por el lienzo"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "Rellenar Caja contenedora",
|
||||
"desc": "Rellena la caja contenedora con el color seleccionado"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"title": "Borrar Caja contenedora",
|
||||
"desc": "Borra el contenido dentro de la caja contenedora"
|
||||
},
|
||||
"colorPicker": {
|
||||
"title": "Selector de color",
|
||||
"desc": "Selecciona un color del lienzo"
|
||||
},
|
||||
"toggleSnap": {
|
||||
"title": "Alternar ajuste de cuadrícula",
|
||||
"desc": "Activa o desactiva el ajuste automático a la cuadrícula"
|
||||
},
|
||||
"quickToggleMove": {
|
||||
"title": "Alternar movimiento rápido",
|
||||
"desc": "Activa momentáneamente la herramienta de movimiento"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"title": "Alternar capa",
|
||||
"desc": "Alterna entre las capas de máscara y base"
|
||||
},
|
||||
"clearMask": {
|
||||
"title": "Limpiar máscara",
|
||||
"desc": "Limpia toda la máscara actual"
|
||||
},
|
||||
"hideMask": {
|
||||
"title": "Ocultar máscara",
|
||||
"desc": "Oculta o muetre la máscara actual"
|
||||
},
|
||||
"showHideBoundingBox": {
|
||||
"title": "Alternar caja contenedora",
|
||||
"desc": "Muestra u oculta la caja contenedora"
|
||||
},
|
||||
"mergeVisible": {
|
||||
"title": "Consolida capas visibles",
|
||||
"desc": "Consolida todas las capas visibles en una sola"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "Guardar en galería",
|
||||
"desc": "Guardar la imagen actual del lienzo en la galería"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "Copiar al portapapeles",
|
||||
"desc": "Copiar el lienzo actual al portapapeles"
|
||||
},
|
||||
"downloadImage": {
|
||||
"title": "Descargar imagen",
|
||||
"desc": "Descargar la imagen actual del lienzo"
|
||||
},
|
||||
"undoStroke": {
|
||||
"title": "Deshar trazo",
|
||||
"desc": "Desahacer el último trazo del pincel"
|
||||
},
|
||||
"redoStroke": {
|
||||
"title": "Rehacer trazo",
|
||||
"desc": "Rehacer el último trazo del pincel"
|
||||
},
|
||||
"resetView": {
|
||||
"title": "Restablecer vista",
|
||||
"desc": "Restablecer la vista del lienzo"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"title": "Imagen anterior",
|
||||
"desc": "Imagen anterior en el área de preparación"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"title": "Imagen siguiente",
|
||||
"desc": "Siguiente imagen en el área de preparación"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"title": "Aceptar imagen",
|
||||
"desc": "Aceptar la imagen actual en el área de preparación"
|
||||
},
|
||||
"addNodes": {
|
||||
"title": "Añadir Nodos",
|
||||
"desc": "Abre el menú para añadir nodos"
|
||||
},
|
||||
"nodesHotkeys": "Teclas de acceso rápido a los nodos"
|
||||
},
|
||||
"modelManager": {
|
||||
"modelManager": "Gestor de Modelos",
|
||||
"model": "Modelo",
|
||||
@@ -325,9 +120,7 @@
|
||||
"alpha": "Alfa",
|
||||
"allModels": "Todos los modelos",
|
||||
"repo_id": "Identificador del repositorio",
|
||||
"v2_base": "v2 (512px)",
|
||||
"none": "ninguno",
|
||||
"v2_768": "v2 (768px)",
|
||||
"vae": "VAE",
|
||||
"variant": "Variante",
|
||||
"baseModel": "Modelo básico",
|
||||
@@ -338,9 +131,7 @@
|
||||
"modelDeleted": "Modelo eliminado",
|
||||
"modelDeleteFailed": "Error al borrar el modelo",
|
||||
"settings": "Ajustes",
|
||||
"syncModels": "Sincronizar las plantillas",
|
||||
"modelsSynced": "Plantillas sincronizadas",
|
||||
"modelSyncFailed": "La sincronización de la plantilla falló"
|
||||
"syncModels": "Sincronizar las plantillas"
|
||||
},
|
||||
"parameters": {
|
||||
"images": "Imágenes",
|
||||
@@ -362,8 +153,6 @@
|
||||
"scaledHeight": "Alto escalado",
|
||||
"infillMethod": "Método de relleno",
|
||||
"tileSize": "Tamaño del mosaico",
|
||||
"sendToImg2Img": "Enviar a Imagen a Imagen",
|
||||
"sendToUnifiedCanvas": "Enviar a Lienzo Unificado",
|
||||
"downloadImage": "Descargar imagen",
|
||||
"usePrompt": "Usar Entrada",
|
||||
"useSeed": "Usar Semilla",
|
||||
@@ -389,13 +178,11 @@
|
||||
"models": "Modelos",
|
||||
"displayInProgress": "Mostrar las imágenes del progreso",
|
||||
"confirmOnDelete": "Confirmar antes de eliminar",
|
||||
"enableImageDebugging": "Habilitar depuración de imágenes",
|
||||
"resetWebUI": "Restablecer interfaz web",
|
||||
"resetWebUIDesc1": "Al restablecer la interfaz web, solo se restablece la caché local del navegador de sus imágenes y la configuración guardada. No se elimina ninguna imagen de su disco duro.",
|
||||
"resetWebUIDesc2": "Si las imágenes no se muestran en la galería o algo más no funciona, intente restablecer antes de reportar un incidente en GitHub.",
|
||||
"resetComplete": "Se ha restablecido la interfaz web.",
|
||||
"general": "General",
|
||||
"shouldLogToConsole": "Registro de la consola",
|
||||
"developer": "Desarrollador",
|
||||
"antialiasProgressImages": "Imágenes del progreso de Antialias",
|
||||
"showProgressInViewer": "Mostrar las imágenes del progreso en el visor",
|
||||
@@ -411,12 +198,7 @@
|
||||
"toast": {
|
||||
"uploadFailed": "Error al subir archivo",
|
||||
"imageCopied": "Imágen copiada",
|
||||
"imageNotLoadedDesc": "No se pudo encontrar la imagen",
|
||||
"canvasMerged": "Lienzo consolidado",
|
||||
"sentToImageToImage": "Enviar hacia Imagen a Imagen",
|
||||
"sentToUnifiedCanvas": "Enviar hacia Lienzo Consolidado",
|
||||
"parametersNotSet": "Parámetros no recuperados",
|
||||
"metadataLoadFailed": "Error al cargar metadatos",
|
||||
"serverError": "Error en el servidor",
|
||||
"canceled": "Procesando la cancelación",
|
||||
"connected": "Conectado al servidor",
|
||||
@@ -431,67 +213,6 @@
|
||||
"baseModelChangedCleared_many": "Borrados o desactivados {{count}} submodelos incompatibles",
|
||||
"baseModelChangedCleared_other": "Borrados o desactivados {{count}} submodelos incompatibles"
|
||||
},
|
||||
"tooltip": {
|
||||
"feature": {
|
||||
"prompt": "Este campo tomará todo el texto de entrada, incluidos tanto los términos de contenido como los estilísticos. Si bien se pueden incluir pesos en la solicitud, los comandos/parámetros estándar de línea de comandos no funcionarán.",
|
||||
"gallery": "Conforme se generan nuevas invocaciones, los archivos del directorio de salida se mostrarán aquí. Las generaciones tienen opciones adicionales para configurar nuevas generaciones.",
|
||||
"other": "Estas opciones habilitarán modos de procesamiento alternativos para Invoke. 'Seamless mosaico' creará patrones repetitivos en la salida. 'Alta resolución' es la generación en dos pasos con img2img: use esta configuración cuando desee una imagen más grande y más coherente sin artefactos. tomar más tiempo de lo habitual txt2img.",
|
||||
"seed": "Los valores de semilla proporcionan un conjunto inicial de ruido que guían el proceso de eliminación de ruido y se pueden aleatorizar o rellenar con una semilla de una invocación anterior. La función Umbral se puede usar para mitigar resultados indeseables a valores CFG más altos (intente entre 0-10), y Perlin se puede usar para agregar ruido Perlin al proceso de eliminación de ruido. Ambos sirven para agregar variación a sus salidas.",
|
||||
"upscale": "Usando ESRGAN, puede aumentar la resolución de salida sin requerir un ancho/alto más alto en la generación inicial.",
|
||||
"boundingBox": "La caja delimitadora es análoga a las configuraciones de Ancho y Alto para Texto a Imagen o Imagen a Imagen. Solo se procesará el área en la caja."
|
||||
}
|
||||
},
|
||||
"unifiedCanvas": {
|
||||
"layer": "Capa",
|
||||
"base": "Base",
|
||||
"mask": "Máscara",
|
||||
"maskingOptions": "Opciones de máscara",
|
||||
"enableMask": "Habilitar Máscara",
|
||||
"preserveMaskedArea": "Preservar área enmascarada",
|
||||
"clearMask": "Limpiar máscara",
|
||||
"brush": "Pincel",
|
||||
"eraser": "Borrador",
|
||||
"fillBoundingBox": "Rellenar Caja Contenedora",
|
||||
"eraseBoundingBox": "Eliminar Caja Contenedora",
|
||||
"colorPicker": "Selector de color",
|
||||
"brushOptions": "Opciones de pincel",
|
||||
"brushSize": "Tamaño",
|
||||
"move": "Mover",
|
||||
"resetView": "Restablecer vista",
|
||||
"mergeVisible": "Consolidar vista",
|
||||
"saveToGallery": "Guardar en galería",
|
||||
"copyToClipboard": "Copiar al portapapeles",
|
||||
"downloadAsImage": "Descargar como imagen",
|
||||
"undo": "Deshacer",
|
||||
"redo": "Rehacer",
|
||||
"clearCanvas": "Limpiar lienzo",
|
||||
"canvasSettings": "Ajustes de lienzo",
|
||||
"showIntermediates": "Mostrar intermedios",
|
||||
"showGrid": "Mostrar cuadrícula",
|
||||
"snapToGrid": "Ajustar a cuadrícula",
|
||||
"darkenOutsideSelection": "Oscurecer fuera de la selección",
|
||||
"autoSaveToGallery": "Guardar automáticamente en galería",
|
||||
"saveBoxRegionOnly": "Guardar solo región dentro de la caja",
|
||||
"limitStrokesToBox": "Limitar trazos a la caja",
|
||||
"showCanvasDebugInfo": "Mostrar la información adicional del lienzo",
|
||||
"clearCanvasHistory": "Limpiar historial de lienzo",
|
||||
"clearHistory": "Limpiar historial",
|
||||
"clearCanvasHistoryMessage": "Limpiar el historial de lienzo también restablece completamente el lienzo unificado. Esto incluye todo el historial de deshacer/rehacer, las imágenes en el área de preparación y la capa base del lienzo.",
|
||||
"clearCanvasHistoryConfirm": "¿Está seguro de que desea limpiar el historial del lienzo?",
|
||||
"activeLayer": "Capa activa",
|
||||
"canvasScale": "Escala de lienzo",
|
||||
"boundingBox": "Caja contenedora",
|
||||
"scaledBoundingBox": "Caja contenedora escalada",
|
||||
"boundingBoxPosition": "Posición de caja contenedora",
|
||||
"canvasDimensions": "Dimensiones de lienzo",
|
||||
"canvasPosition": "Posición de lienzo",
|
||||
"cursorPosition": "Posición del cursor",
|
||||
"previous": "Anterior",
|
||||
"next": "Siguiente",
|
||||
"accept": "Aceptar",
|
||||
"discardAll": "Descartar todo",
|
||||
"antialiasing": "Suavizado"
|
||||
},
|
||||
"accessibility": {
|
||||
"invokeProgressBar": "Activar la barra de progreso",
|
||||
"reset": "Reiniciar",
|
||||
@@ -501,7 +222,6 @@
|
||||
"showOptionsPanel": "Mostrar el panel lateral",
|
||||
"menu": "Menú",
|
||||
"showGalleryPanel": "Mostrar panel de galería",
|
||||
"loadMore": "Cargar más",
|
||||
"about": "Acerca de",
|
||||
"createIssue": "Crear un problema",
|
||||
"resetUI": "Interfaz de usuario $t(accessibility.reset)",
|
||||
@@ -578,44 +298,15 @@
|
||||
},
|
||||
"ui": {
|
||||
"tabs": {
|
||||
"generationTab": "$t(ui.tabs.generation) $t(common.tab)",
|
||||
"canvas": "Lienzo",
|
||||
"generation": "Generación",
|
||||
"queue": "Cola",
|
||||
"queueTab": "$t(ui.tabs.queue) $t(common.tab)",
|
||||
"workflows": "Flujos de trabajo",
|
||||
"models": "Modelos",
|
||||
"modelsTab": "$t(ui.tabs.models) $t(common.tab)",
|
||||
"canvasTab": "$t(ui.tabs.canvas) $t(common.tab)",
|
||||
"workflowsTab": "$t(ui.tabs.workflows) $t(common.tab)"
|
||||
}
|
||||
},
|
||||
"controlLayers": {
|
||||
"layers_one": "Capa",
|
||||
"layers_many": "Capas",
|
||||
"layers_other": "Capas"
|
||||
},
|
||||
"controlnet": {
|
||||
"crop": "Cortar",
|
||||
"delete": "Eliminar",
|
||||
"depthAnythingDescription": "Generación de mapa de profundidad usando la técnica de Depth Anything",
|
||||
"duplicate": "Duplicar",
|
||||
"colorMapDescription": "Genera un mapa de color desde la imagen",
|
||||
"depthMidasDescription": "Crea un mapa de profundidad con Midas",
|
||||
"balanced": "Equilibrado",
|
||||
"beginEndStepPercent": "Inicio / Final Porcentaje de pasos",
|
||||
"detectResolution": "Detectar resolución",
|
||||
"beginEndStepPercentShort": "Inicio / Final %",
|
||||
"t2i_adapter": "$t(controlnet.controlAdapter_one) #{{number}} ($t(common.t2iAdapter))",
|
||||
"controlnet": "$t(controlnet.controlAdapter_one) #{{number}} ($t(common.controlNet))",
|
||||
"ip_adapter": "$t(controlnet.controlAdapter_one) #{{number}} ($t(common.ipAdapter))",
|
||||
"addControlNet": "Añadir $t(common.controlNet)",
|
||||
"addIPAdapter": "Añadir $t(common.ipAdapter)",
|
||||
"controlAdapter_one": "Adaptador de control",
|
||||
"controlAdapter_many": "Adaptadores de control",
|
||||
"controlAdapter_other": "Adaptadores de control",
|
||||
"addT2IAdapter": "Añadir $t(common.t2iAdapter)"
|
||||
},
|
||||
"queue": {
|
||||
"back": "Atrás",
|
||||
"front": "Delante",
|
||||
|
||||
@@ -24,28 +24,12 @@
|
||||
"back": "Takaisin",
|
||||
"statusDisconnected": "Yhteys katkaistu",
|
||||
"loading": "Ladataan",
|
||||
"txt2img": "Teksti kuvaksi",
|
||||
"unifiedCanvas": "Yhdistetty kanvas"
|
||||
"txt2img": "Teksti kuvaksi"
|
||||
},
|
||||
"gallery": {
|
||||
"galleryImageSize": "Kuvan koko",
|
||||
"gallerySettings": "Gallerian asetukset",
|
||||
"autoSwitchNewImages": "Vaihda uusiin kuviin automaattisesti",
|
||||
"noImagesInGallery": "Ei kuvia galleriassa",
|
||||
"loadMore": "Lataa lisää"
|
||||
},
|
||||
"hotkeys": {
|
||||
"keyboardShortcuts": "näppäimistön pikavalinnat",
|
||||
"appHotkeys": "Sovelluksen pikanäppäimet",
|
||||
"generalHotkeys": "Yleiset pikanäppäimet",
|
||||
"galleryHotkeys": "Gallerian pikanäppäimet",
|
||||
"unifiedCanvasHotkeys": "Yhdistetyn kanvaan pikanäppäimet",
|
||||
"cancel": {
|
||||
"desc": "Peruuta kuvan luominen",
|
||||
"title": "Peruuta"
|
||||
},
|
||||
"invoke": {
|
||||
"desc": "Luo kuva"
|
||||
}
|
||||
"noImagesInGallery": "Ei kuvia galleriassa"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
"languagePickerLabel": "Langue",
|
||||
"reportBugLabel": "Signaler un bug",
|
||||
"settingsLabel": "Paramètres",
|
||||
"img2img": "Image en image",
|
||||
"unifiedCanvas": "Canvas unifié",
|
||||
"nodes": "Nœuds",
|
||||
"img2img": "Image vers Image",
|
||||
"nodes": "Processus",
|
||||
"upload": "Télécharger",
|
||||
"load": "Charger",
|
||||
"back": "Retour",
|
||||
@@ -16,14 +15,12 @@
|
||||
"accept": "Accepter",
|
||||
"cancel": "Annuler",
|
||||
"loading": "Chargement",
|
||||
"txt2img": "Texte vers image",
|
||||
"txt2img": "Texte vers Image",
|
||||
"postprocessing": "Post-Traitement",
|
||||
"file": "Fichier",
|
||||
"orderBy": "Trier par",
|
||||
"comparing": "Comparaison",
|
||||
"add": "Ajouter",
|
||||
"dontAskMeAgain": "Ne plus me demander",
|
||||
"nodeEditor": "Éditeur de nœud",
|
||||
"outputs": "Sorties",
|
||||
"unknown": "Inconnu",
|
||||
"editor": "Éditeur",
|
||||
@@ -31,7 +28,7 @@
|
||||
"installed": "Installé",
|
||||
"format": "format",
|
||||
"goTo": "Aller à",
|
||||
"input": "Saisie",
|
||||
"input": "Entrée",
|
||||
"linear": "Linéaire",
|
||||
"localSystem": "Système local",
|
||||
"learnMore": "En savoir plus",
|
||||
@@ -42,7 +39,7 @@
|
||||
"created": "Créé",
|
||||
"tab": "Onglet",
|
||||
"folder": "Dossier",
|
||||
"imageFailedToLoad": "Impossible de charger l'image",
|
||||
"imageFailedToLoad": "Impossible de charger l'Image",
|
||||
"prevPage": "Page précédente",
|
||||
"nextPage": "Page suivante",
|
||||
"selected": "Sélectionné",
|
||||
@@ -60,212 +57,107 @@
|
||||
"saveAs": "Enregistrer sous",
|
||||
"blue": "Bleu",
|
||||
"alpha": "Alpha",
|
||||
"editing": "Édition",
|
||||
"enabled": "Activé",
|
||||
"disabled": "Désactivé",
|
||||
"direction": "Direction"
|
||||
"direction": "Direction",
|
||||
"aboutHeading": "Possédez Votre Pouvoir Créatif",
|
||||
"ai": "ia",
|
||||
"safetensors": "Safetensors",
|
||||
"apply": "Appliquer",
|
||||
"communityLabel": "Communauté",
|
||||
"loadingImage": "Chargement de l'Image",
|
||||
"view": "Visualisateur",
|
||||
"beta": "Beta",
|
||||
"on": "Activé",
|
||||
"batch": "Gestionaire de Lots",
|
||||
"outpaint": "Extension",
|
||||
"openInViewer": "Ouvrir dans le Visualisateur",
|
||||
"edit": "Édition",
|
||||
"off": "Désactivé",
|
||||
"areYouSure": "Êtes-vous sûr ?",
|
||||
"data": "Donnée",
|
||||
"details": "Détails",
|
||||
"placeholderSelectAModel": "Séléctionner un modèle",
|
||||
"reset": "Réinitialiser",
|
||||
"none": "Aucun",
|
||||
"new": "Nouveau",
|
||||
"dontShowMeThese": "Ne pas me montrer ceci",
|
||||
"auto": "Auto",
|
||||
"or": "ou",
|
||||
"checkpoint": "Point de sauvegarde",
|
||||
"ipAdapter": "IP Adapter",
|
||||
"t2iAdapter": "T2I Adapter",
|
||||
"inpaint": "Retouche",
|
||||
"toResolve": "À résoudre",
|
||||
"aboutDesc": "Utilisez vous Invoke pour le travail ? Consultez :",
|
||||
"copyError": "$t(gallery.copy) Erreur",
|
||||
"controlNet": "ControlNet",
|
||||
"positivePrompt": "Prompt Positif",
|
||||
"negativePrompt": "Prompt Négatif"
|
||||
},
|
||||
"gallery": {
|
||||
"galleryImageSize": "Taille de l'image",
|
||||
"gallerySettings": "Paramètres de la galerie",
|
||||
"autoSwitchNewImages": "Basculer automatiquement vers de nouvelles images",
|
||||
"loadMore": "Charger plus",
|
||||
"noImagesInGallery": "Aucune image dans la galerie"
|
||||
},
|
||||
"hotkeys": {
|
||||
"keyboardShortcuts": "Raccourcis clavier",
|
||||
"appHotkeys": "Raccourcis de l'application",
|
||||
"generalHotkeys": "Raccourcis généraux",
|
||||
"galleryHotkeys": "Raccourcis de la galerie",
|
||||
"unifiedCanvasHotkeys": "Raccourcis du canvas unifié",
|
||||
"invoke": {
|
||||
"title": "Invoquer",
|
||||
"desc": "Générer une image"
|
||||
},
|
||||
"cancel": {
|
||||
"title": "Annuler",
|
||||
"desc": "Annuler la génération d'image"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"title": "Prompt de focus",
|
||||
"desc": "Mettre en focus la zone de saisie de la commande"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"title": "Affichage des options",
|
||||
"desc": "Afficher et masquer le panneau d'options"
|
||||
},
|
||||
"pinOptions": {
|
||||
"title": "Epinglage des options",
|
||||
"desc": "Epingler le panneau d'options"
|
||||
},
|
||||
"toggleGallery": {
|
||||
"title": "Affichage de la galerie",
|
||||
"desc": "Afficher et masquer la galerie"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"title": "Maximiser la zone de travail",
|
||||
"desc": "Fermer les panneaux et maximiser la zone de travail"
|
||||
},
|
||||
"changeTabs": {
|
||||
"title": "Changer d'onglet",
|
||||
"desc": "Passer à un autre espace de travail"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"title": "Affichage de la console",
|
||||
"desc": "Afficher et masquer la console"
|
||||
},
|
||||
"setPrompt": {
|
||||
"title": "Définir le prompt",
|
||||
"desc": "Utiliser le prompt de l'image actuelle"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "Définir la graine",
|
||||
"desc": "Utiliser la graine de l'image actuelle"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "Définir les paramètres",
|
||||
"desc": "Utiliser tous les paramètres de l'image actuelle"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "Restaurer les visages",
|
||||
"desc": "Restaurer l'image actuelle"
|
||||
},
|
||||
"showInfo": {
|
||||
"title": "Afficher les informations",
|
||||
"desc": "Afficher les informations de métadonnées de l'image actuelle"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"title": "Envoyer à l'image à l'image",
|
||||
"desc": "Envoyer l'image actuelle à l'image à l'image"
|
||||
},
|
||||
"deleteImage": {
|
||||
"title": "Supprimer l'image",
|
||||
"desc": "Supprimer l'image actuelle"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "Fermer les panneaux",
|
||||
"desc": "Fermer les panneaux ouverts"
|
||||
},
|
||||
"previousImage": {
|
||||
"title": "Image précédente",
|
||||
"desc": "Afficher l'image précédente dans la galerie"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "Image suivante",
|
||||
"desc": "Afficher l'image suivante dans la galerie"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "Augmenter la taille des miniatures de la galerie",
|
||||
"desc": "Augmente la taille des miniatures de la galerie"
|
||||
},
|
||||
"decreaseGalleryThumbSize": {
|
||||
"title": "Diminuer la taille des miniatures de la galerie",
|
||||
"desc": "Diminue la taille des miniatures de la galerie"
|
||||
},
|
||||
"selectBrush": {
|
||||
"title": "Sélectionner un pinceau",
|
||||
"desc": "Sélectionne le pinceau de la toile"
|
||||
},
|
||||
"selectEraser": {
|
||||
"title": "Sélectionner un gomme",
|
||||
"desc": "Sélectionne la gomme de la toile"
|
||||
},
|
||||
"decreaseBrushSize": {
|
||||
"title": "Diminuer la taille du pinceau",
|
||||
"desc": "Diminue la taille du pinceau/gomme de la toile"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "Augmenter la taille du pinceau",
|
||||
"desc": "Augmente la taille du pinceau/gomme de la toile"
|
||||
},
|
||||
"decreaseBrushOpacity": {
|
||||
"title": "Diminuer l'opacité du pinceau",
|
||||
"desc": "Diminue l'opacité du pinceau de la toile"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"title": "Augmenter l'opacité du pinceau",
|
||||
"desc": "Augmente l'opacité du pinceau de la toile"
|
||||
},
|
||||
"moveTool": {
|
||||
"title": "Outil de déplacement",
|
||||
"desc": "Permet la navigation sur la toile"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "Remplir la boîte englobante",
|
||||
"desc": "Remplit la boîte englobante avec la couleur du pinceau"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"title": "Effacer la boîte englobante",
|
||||
"desc": "Efface la zone de la boîte englobante"
|
||||
},
|
||||
"colorPicker": {
|
||||
"title": "Sélectionnez le sélecteur de couleur",
|
||||
"desc": "Sélectionne le sélecteur de couleur de la toile"
|
||||
},
|
||||
"toggleSnap": {
|
||||
"title": "Basculer Snap",
|
||||
"desc": "Basculer Snap à la grille"
|
||||
},
|
||||
"quickToggleMove": {
|
||||
"title": "Basculer rapidement déplacer",
|
||||
"desc": "Basculer temporairement le mode Déplacer"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"title": "Basculer la couche",
|
||||
"desc": "Basculer la sélection de la couche masque/base"
|
||||
},
|
||||
"clearMask": {
|
||||
"title": "Effacer le masque",
|
||||
"desc": "Effacer entièrement le masque"
|
||||
},
|
||||
"hideMask": {
|
||||
"title": "Masquer le masque",
|
||||
"desc": "Masquer et démasquer le masque"
|
||||
},
|
||||
"showHideBoundingBox": {
|
||||
"title": "Afficher/Masquer la boîte englobante",
|
||||
"desc": "Basculer la visibilité de la boîte englobante"
|
||||
},
|
||||
"mergeVisible": {
|
||||
"title": "Fusionner visible",
|
||||
"desc": "Fusionner toutes les couches visibles de la toile"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "Enregistrer dans la galerie",
|
||||
"desc": "Enregistrer la toile actuelle dans la galerie"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "Copier dans le presse-papiers",
|
||||
"desc": "Copier la toile actuelle dans le presse-papiers"
|
||||
},
|
||||
"downloadImage": {
|
||||
"title": "Télécharger l'image",
|
||||
"desc": "Télécharger la toile actuelle"
|
||||
},
|
||||
"undoStroke": {
|
||||
"title": "Annuler le trait",
|
||||
"desc": "Annuler un coup de pinceau"
|
||||
},
|
||||
"redoStroke": {
|
||||
"title": "Rétablir le trait",
|
||||
"desc": "Rétablir un coup de pinceau"
|
||||
},
|
||||
"resetView": {
|
||||
"title": "Réinitialiser la vue",
|
||||
"desc": "Réinitialiser la vue de la toile"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"title": "Image de mise en scène précédente",
|
||||
"desc": "Image précédente de la zone de mise en scène"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"title": "Image de mise en scène suivante",
|
||||
"desc": "Image suivante de la zone de mise en scène"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"title": "Accepter l'image de mise en scène",
|
||||
"desc": "Accepter l'image actuelle de la zone de mise en scène"
|
||||
}
|
||||
"noImagesInGallery": "Aucune image à afficher",
|
||||
"bulkDownloadRequestedDesc": "Votre demande de téléchargement est en cours de traitement. Cela peut prendre quelques instants.",
|
||||
"deleteSelection": "Supprimer la sélection",
|
||||
"selectAllOnPage": "Séléctionner toute la page",
|
||||
"unableToLoad": "Impossible de charger la Galerie",
|
||||
"featuresWillReset": "Si vous supprimez cette image, ces fonctionnalités vont être réinitialisés.",
|
||||
"loading": "Chargement",
|
||||
"sortDirection": "Direction de tri",
|
||||
"sideBySide": "Côte-à-Côte",
|
||||
"hover": "Au passage de la souris",
|
||||
"assets": "Ressources",
|
||||
"alwaysShowImageSizeBadge": "Toujours montrer le badge de taille de l'Image",
|
||||
"gallery": "Galerie",
|
||||
"bulkDownloadRequestFailed": "Problème lors de la préparation du téléchargement",
|
||||
"copy": "Copier",
|
||||
"autoAssignBoardOnClick": "Assigner automatiquement une Planche lors du clic",
|
||||
"dropToUpload": "$t(gallery.drop) pour Charger",
|
||||
"dropOrUpload": "$t(gallery.drop) ou Séléctioner",
|
||||
"oldestFirst": "Plus Ancien en premier",
|
||||
"deleteImagePermanent": "Les Images supprimées ne peuvent pas être restorées.",
|
||||
"displaySearch": "Recherche d'Image",
|
||||
"exitBoardSearch": "Sortir de la recherche de Planche",
|
||||
"go": "Aller",
|
||||
"newestFirst": "Plus Récents en permier",
|
||||
"showStarredImagesFirst": "Monter les Images partagées en premier",
|
||||
"bulkDownloadFailed": "Téléchargement échoué",
|
||||
"bulkDownloadRequested": "Préparation du téléchargement",
|
||||
"compareImage": "Comparer l'Image",
|
||||
"openInViewer": "Ouvrir dans le Visualiseur",
|
||||
"showArchivedBoards": "Montrer les Planches archivées",
|
||||
"selectForCompare": "Séléctionner pour comparaison",
|
||||
"selectAnImageToCompare": "Séléctionner une Image à comparer",
|
||||
"exitCompare": "Sortir de la comparaison",
|
||||
"compareHelp2": "Appuyez sur <Kbd>M</Kbd> pour faire défiler les modes de comparaison.",
|
||||
"swapImages": "Échanger les Images",
|
||||
"move": "Déplacer",
|
||||
"compareHelp1": "Maintenir <Kbd>Alt</Kbd> lors du clic d'une image dans la galerie ou en utilisant les flèches du clavier pour changer l'Image à comparer.",
|
||||
"compareHelp3": "Appuyer sur <Kbd>C</Kbd> pour échanger les images à comparer.",
|
||||
"image": "image",
|
||||
"openViewer": "Ouvrir le Visualisateur",
|
||||
"closeViewer": "Fermer le Visualisateur",
|
||||
"currentlyInUse": "Cette image est actuellement utilisée dans ces fonctionalités :",
|
||||
"jump": "Sauter",
|
||||
"starImage": "Marquer l'Image",
|
||||
"download": "Téléchargement",
|
||||
"deleteImage_one": "Supprimer l'Image",
|
||||
"deleteImage_many": "Supprimer {{count}} Images",
|
||||
"deleteImage_other": "Supprimer {{count}} Images",
|
||||
"displayBoardSearch": "Recherche dans la Planche",
|
||||
"searchImages": "Chercher par Métadonnées",
|
||||
"slider": "Curseur",
|
||||
"stretchToFit": "Étirer pour remplir",
|
||||
"compareHelp4": "Appuyer sur <Kbd>Z</Kbd> ou <Kbd>Esc</Kbd> pour sortir.",
|
||||
"drop": "Déposer",
|
||||
"noImageSelected": "Pas d'Image séléctionnée",
|
||||
"downloadSelection": "Télécharger la sélection",
|
||||
"exitSearch": "Sortir de la recherche d'Image",
|
||||
"unstarImage": "Retirer le marquage de l'Image",
|
||||
"viewerImage": "Visualisation de l'Image"
|
||||
},
|
||||
"modelManager": {
|
||||
"modelManager": "Gestionnaire de modèle",
|
||||
@@ -311,8 +203,6 @@
|
||||
"scaledHeight": "Haut. Échelle",
|
||||
"infillMethod": "Méthode de Remplissage",
|
||||
"tileSize": "Taille des Tuiles",
|
||||
"sendToImg2Img": "Envoyer à Image à Image",
|
||||
"sendToUnifiedCanvas": "Envoyer au Canvas Unifié",
|
||||
"copyImage": "Copier Image",
|
||||
"downloadImage": "Télécharger Image",
|
||||
"usePrompt": "Utiliser la suggestion",
|
||||
@@ -325,7 +215,6 @@
|
||||
"models": "Modèles",
|
||||
"displayInProgress": "Afficher les images en cours",
|
||||
"confirmOnDelete": "Confirmer la suppression",
|
||||
"enableImageDebugging": "Activer le débogage d'image",
|
||||
"resetWebUI": "Réinitialiser l'interface Web",
|
||||
"resetWebUIDesc1": "Réinitialiser l'interface Web ne réinitialise que le cache local du navigateur de vos images et de vos paramètres enregistrés. Cela n'efface pas les images du disque.",
|
||||
"resetWebUIDesc2": "Si les images ne s'affichent pas dans la galerie ou si quelque chose d'autre ne fonctionne pas, veuillez essayer de réinitialiser avant de soumettre une demande sur GitHub.",
|
||||
@@ -334,84 +223,22 @@
|
||||
"toast": {
|
||||
"uploadFailed": "Téléchargement échoué",
|
||||
"imageCopied": "Image copiée",
|
||||
"imageNotLoadedDesc": "Aucune image trouvée pour envoyer à module d'image",
|
||||
"canvasMerged": "Canvas fusionné",
|
||||
"sentToImageToImage": "Envoyé à Image à Image",
|
||||
"sentToUnifiedCanvas": "Envoyé à Canvas unifié",
|
||||
"parametersNotSet": "Paramètres non définis",
|
||||
"metadataLoadFailed": "Échec du chargement des métadonnées"
|
||||
},
|
||||
"tooltip": {
|
||||
"feature": {
|
||||
"prompt": "Ceci est le champ prompt. Le prompt inclut des objets de génération et des termes stylistiques. Vous pouvez également ajouter un poids (importance du jeton) dans le prompt, mais les commandes CLI et les paramètres ne fonctionneront pas.",
|
||||
"gallery": "La galerie affiche les générations à partir du dossier de sortie à mesure qu'elles sont créées. Les paramètres sont stockés dans des fichiers et accessibles via le menu contextuel.",
|
||||
"other": "Ces options activent des modes de traitement alternatifs pour Invoke. 'Tuilage seamless' créera des motifs répétitifs dans la sortie. 'Haute résolution' est la génération en deux étapes avec img2img : utilisez ce paramètre lorsque vous souhaitez une image plus grande et plus cohérente sans artefacts. Cela prendra plus de temps que d'habitude txt2img.",
|
||||
"seed": "La valeur de grain affecte le bruit initial à partir duquel l'image est formée. Vous pouvez utiliser les graines déjà existantes provenant d'images précédentes. 'Seuil de bruit' est utilisé pour atténuer les artefacts à des valeurs CFG élevées (essayez la plage de 0 à 10), et Perlin pour ajouter du bruit Perlin pendant la génération : les deux servent à ajouter de la variété à vos sorties.",
|
||||
"upscale": "Utilisez ESRGAN pour agrandir l'image immédiatement après la génération.",
|
||||
"boundingBox": "La boîte englobante est la même que les paramètres Largeur et Hauteur pour Texte à Image ou Image à Image. Seulement la zone dans la boîte sera traitée."
|
||||
}
|
||||
},
|
||||
"unifiedCanvas": {
|
||||
"layer": "Couche",
|
||||
"base": "Base",
|
||||
"mask": "Masque",
|
||||
"maskingOptions": "Options de masquage",
|
||||
"enableMask": "Activer le masque",
|
||||
"preserveMaskedArea": "Préserver la zone masquée",
|
||||
"clearMask": "Effacer le masque",
|
||||
"brush": "Pinceau",
|
||||
"eraser": "Gomme",
|
||||
"fillBoundingBox": "Remplir la boîte englobante",
|
||||
"eraseBoundingBox": "Effacer la boîte englobante",
|
||||
"colorPicker": "Sélecteur de couleur",
|
||||
"brushOptions": "Options de pinceau",
|
||||
"brushSize": "Taille",
|
||||
"move": "Déplacer",
|
||||
"resetView": "Réinitialiser la vue",
|
||||
"mergeVisible": "Fusionner les visibles",
|
||||
"saveToGallery": "Enregistrer dans la galerie",
|
||||
"copyToClipboard": "Copier dans le presse-papiers",
|
||||
"downloadAsImage": "Télécharger en tant qu'image",
|
||||
"undo": "Annuler",
|
||||
"redo": "Refaire",
|
||||
"clearCanvas": "Effacer le canvas",
|
||||
"canvasSettings": "Paramètres du canvas",
|
||||
"showIntermediates": "Afficher les intermédiaires",
|
||||
"showGrid": "Afficher la grille",
|
||||
"snapToGrid": "Aligner sur la grille",
|
||||
"darkenOutsideSelection": "Assombrir à l'extérieur de la sélection",
|
||||
"autoSaveToGallery": "Enregistrement automatique dans la galerie",
|
||||
"saveBoxRegionOnly": "Enregistrer uniquement la région de la boîte",
|
||||
"limitStrokesToBox": "Limiter les traits à la boîte",
|
||||
"showCanvasDebugInfo": "Afficher les informations de débogage du canvas",
|
||||
"clearCanvasHistory": "Effacer l'historique du canvas",
|
||||
"clearHistory": "Effacer l'historique",
|
||||
"clearCanvasHistoryMessage": "Effacer l'historique du canvas laisse votre canvas actuel intact, mais efface de manière irréversible l'historique annuler et refaire.",
|
||||
"clearCanvasHistoryConfirm": "Voulez-vous vraiment effacer l'historique du canvas ?",
|
||||
"activeLayer": "Calque actif",
|
||||
"canvasScale": "Échelle du canevas",
|
||||
"boundingBox": "Boîte englobante",
|
||||
"scaledBoundingBox": "Boîte englobante mise à l'échelle",
|
||||
"boundingBoxPosition": "Position de la boîte englobante",
|
||||
"canvasDimensions": "Dimensions du canevas",
|
||||
"canvasPosition": "Position du canevas",
|
||||
"cursorPosition": "Position du curseur",
|
||||
"previous": "Précédent",
|
||||
"next": "Suivant",
|
||||
"accept": "Accepter",
|
||||
"discardAll": "Tout abandonner"
|
||||
"parametersNotSet": "Paramètres non définis"
|
||||
},
|
||||
"accessibility": {
|
||||
"uploadImage": "Charger une image",
|
||||
"reset": "Réinitialiser",
|
||||
"nextImage": "Image suivante",
|
||||
"previousImage": "Image précédente",
|
||||
"showOptionsPanel": "Montrer la page d'options",
|
||||
"showOptionsPanel": "Afficher le panneau latéral",
|
||||
"invokeProgressBar": "Barre de Progression Invoke",
|
||||
"menu": "Menu",
|
||||
"loadMore": "Charger plus",
|
||||
"about": "À propos",
|
||||
"mode": "Mode"
|
||||
"mode": "Mode",
|
||||
"createIssue": "Créer un ticket",
|
||||
"submitSupportTicket": "Envoyer un ticket de support",
|
||||
"showGalleryPanel": "Afficher la galerie",
|
||||
"resetUI": "$t(accessibility.reset) l'Interface Utilisateur"
|
||||
},
|
||||
"boards": {
|
||||
"move": "Déplacer",
|
||||
@@ -421,31 +248,62 @@
|
||||
"clearSearch": "Effacer la recherche",
|
||||
"imagesWithCount_one": "{{count}} image",
|
||||
"imagesWithCount_many": "{{count}} images",
|
||||
"imagesWithCount_other": "{{count}} images"
|
||||
"imagesWithCount_other": "{{count}} images",
|
||||
"bottomMessage": "Supprimer cette planche et ses images va réinitialiser toutes les fonctionnalités les utilisant.",
|
||||
"deleteBoardAndImages": "Supprimer la Planche et les Images",
|
||||
"deleteBoardOnly": "Supprimer la Planche uniquement",
|
||||
"assetsWithCount_one": "{{count}} ressource",
|
||||
"assetsWithCount_many": "{{count}} ressources",
|
||||
"assetsWithCount_other": "{{count}} ressources",
|
||||
"selectedForAutoAdd": "Séléctioné pour Ajout Automatique",
|
||||
"noMatching": "Pas de Planches correspondantes",
|
||||
"myBoard": "Ma Planche",
|
||||
"menuItemAutoAdd": "Ajouter automatiquement à cette Planche",
|
||||
"changeBoard": "Changer de Planche",
|
||||
"movingImagesToBoard_one": "Déplacer {{count}} image à cette planche :",
|
||||
"movingImagesToBoard_many": "Déplacer {{count}} images à cette planche :",
|
||||
"movingImagesToBoard_other": "Déplacer {{count}} image à cette planche :",
|
||||
"viewBoards": "Voir les Planches",
|
||||
"hideBoards": "Cacher les Planches",
|
||||
"noBoards": "Pas de Planches {{boardType}}",
|
||||
"shared": "Planches Partagées",
|
||||
"searchBoard": "Chercher les Planches...",
|
||||
"addSharedBoard": "Créer une Planche Partagée",
|
||||
"addPrivateBoard": "Créer une Planche Privée",
|
||||
"boards": "Planches",
|
||||
"deletedPrivateBoardsCannotbeRestored": "Les planches supprimées ne peuvent pas être restaurées. Séléctionner 'Supprimer la planche uniquement' placera les images dans un état non catégorisé pour le créateur des images.",
|
||||
"uncategorized": "Non catégorisé",
|
||||
"downloadBoard": "Télécharger la Planche",
|
||||
"private": "Planches Privées",
|
||||
"deleteBoard": "Supprimer la Planche",
|
||||
"autoAddBoard": "Création de Planche Automatique",
|
||||
"addBoard": "Créer une Planche",
|
||||
"topMessage": "Cette planche contient des images utilisée dans ces fonctionnalités :",
|
||||
"selectBoard": "Séléctionner une Planche",
|
||||
"archiveBoard": "Archiver la Planche",
|
||||
"unarchiveBoard": "Déarchiver la Planche",
|
||||
"deletedBoardsCannotbeRestored": "Les planches supprimées ne peuvent pas être restaurées. Séléctionner 'Supprimer la planche uniquement' placera les images dans un état non catégorisé."
|
||||
},
|
||||
"accordions": {
|
||||
"advanced": {
|
||||
"title": "Avancé"
|
||||
"title": "Avancé",
|
||||
"options": "$t(accordions.advanced.title) Options"
|
||||
},
|
||||
"image": {
|
||||
"title": "Image"
|
||||
},
|
||||
"compositing": {
|
||||
"title": "Composition",
|
||||
"coherenceTab": "Passe de Cohérence",
|
||||
"infillTab": "Remplissage"
|
||||
},
|
||||
"generation": {
|
||||
"title": "Génération"
|
||||
},
|
||||
"control": {
|
||||
"title": "Controle"
|
||||
}
|
||||
},
|
||||
"controlnet": {
|
||||
"none": "Aucun",
|
||||
"detectResolution": "Détecter la résolution",
|
||||
"balanced": "Équilibré",
|
||||
"colorMap": "Couleur",
|
||||
"control": "Contrôle",
|
||||
"controlMode": "Mode de contrôle",
|
||||
"processor": "Processeur",
|
||||
"ipAdapterMethod": "Méthode",
|
||||
"delete": "Supprimer",
|
||||
"duplicate": "Dupliquer",
|
||||
"crop": "Rogner",
|
||||
"imageResolution": "Résolution d'image",
|
||||
"resize": "Redimensionner"
|
||||
},
|
||||
"queue": {
|
||||
"clear": "Effacer",
|
||||
"failed": "Échec",
|
||||
@@ -465,6 +323,96 @@
|
||||
"canceled": "Annulé",
|
||||
"clearQueueAlertDialog2": "Voulez-vous vraiment effacer la file d'attente ?",
|
||||
"queueBack": "Ajouter à la file d'attente",
|
||||
"completed": "Terminé"
|
||||
"completed": "Terminé",
|
||||
"pauseSucceeded": "Traitement intérompu",
|
||||
"cancelBatchFailed": "Problème lors de l'annulation du Lot",
|
||||
"resumeTooltip": "Reprendre le traitement",
|
||||
"resumeFailed": "Problème lors de la reprise du traitement",
|
||||
"cancelItem": "Annuler l'élément",
|
||||
"pruneSucceeded": "Purgé {{item_count}} éléments complété de la file d'attente",
|
||||
"cancelTooltip": "Annuler l'élément actuel",
|
||||
"current": "Actuel",
|
||||
"pause": "Pause",
|
||||
"clearTooltip": "Annuler et Effacer tous les éléments",
|
||||
"pauseFailed": "Problème lors de l'intéruption du traitement",
|
||||
"cancelBatch": "Annuler le Lot",
|
||||
"pauseTooltip": "Intérrompre le traitement",
|
||||
"prune": "Purger",
|
||||
"pruneFailed": "Problème lors du Purgeage de la file d'attente",
|
||||
"clearQueueAlertDialog": "Effacer la file d'attente immédiatement annule tous les éléments en cours de traitement et efface entièrement la file d'attente. Les filtres en attente seront également annulés.",
|
||||
"pruneTooltip": "Purger {{item_count}} élémentscomplétés",
|
||||
"cancelSucceeded": "Élément annulé",
|
||||
"cancelFailed": "Problème lors de l'annulation de l'élément",
|
||||
"clearFailed": "Problème lors de l'Effacement de la file d'attente",
|
||||
"cancelBatchSucceeded": "Lot Annulé",
|
||||
"resume": "Reprendre",
|
||||
"resumeSucceeded": "Traitement repris",
|
||||
"enqueueing": "Ajout du Lot à la file d'attente",
|
||||
"origin": "Origine",
|
||||
"destination": "Destination",
|
||||
"batch": "Lot",
|
||||
"completedIn": "Complété en",
|
||||
"upscaling": "Agrandissement",
|
||||
"canvas": "Toile",
|
||||
"batchQueuedDesc_one": "Ajouté {{count}} session à {{direction}} de la file d'attente",
|
||||
"batchQueuedDesc_many": "Ajouté {{count}} sessions à {{direction}} de la file d'attente",
|
||||
"batchQueuedDesc_other": "Ajouté {{count}} sessions à {{direction}} de la file d'attente",
|
||||
"prompts_one": "Prompt",
|
||||
"prompts_many": "Prompts",
|
||||
"prompts_other": "Prompts",
|
||||
"batchQueued": "Lot ajouté à la file d'attente",
|
||||
"gallery": "Galerie",
|
||||
"notReady": "Impossible d'ajouter à la file d'attente",
|
||||
"batchFieldValues": "Valeurs Champ Lot",
|
||||
"front": "début",
|
||||
"graphQueued": "Graph ajouté à la file d'attente",
|
||||
"other": "Autre",
|
||||
"generation": "Génération",
|
||||
"workflows": "Processus",
|
||||
"batchFailedToQueue": "Impossible d'ajouter le Lot dans à la file d'attente",
|
||||
"graphFailedToQueue": "Impossible d'ajouter le graph à la file d'attente",
|
||||
"item": "Élément",
|
||||
"generations_one": "Génération",
|
||||
"generations_many": "Générations",
|
||||
"generations_other": "Générations",
|
||||
"iterations_one": "Itération",
|
||||
"iterations_many": "Itérations",
|
||||
"iterations_other": "Itérations",
|
||||
"back": "fin"
|
||||
},
|
||||
"prompt": {
|
||||
"noMatchingTriggers": "Pas de déclancheurs correspondants",
|
||||
"addPromptTrigger": "Ajouter un déclencheur de Prompt",
|
||||
"compatibleEmbeddings": "Embeddings Compatibles"
|
||||
},
|
||||
"hrf": {
|
||||
"upscaleMethod": "Méthode d'Agrandissement",
|
||||
"metadata": {
|
||||
"enabled": "Correction Haute Résolution Activée",
|
||||
"strength": "Force de la Correction Haute Résolution",
|
||||
"method": "Méthode de la Correction Haute Résolution"
|
||||
},
|
||||
"enableHrf": "Activer la Correction Haute Résolution",
|
||||
"hrf": "Correction Haute Résolution"
|
||||
},
|
||||
"invocationCache": {
|
||||
"clear": "Vider",
|
||||
"useCache": "Utiliser le Cache",
|
||||
"invocationCache": "Cache des Invocations",
|
||||
"enableFailed": "Problème lors de l'activation du Cache d'Invocation",
|
||||
"enable": "Activer",
|
||||
"enableSucceeded": "Cache d'Invocation Activé",
|
||||
"clearSucceeded": "Cache d'Invocation vidé",
|
||||
"disable": "Désactiver",
|
||||
"disableSucceeded": "Cache d'Invocation désactivé",
|
||||
"maxCacheSize": "Taille du Cache maximum",
|
||||
"misses": "Non trouvé dans le Cache",
|
||||
"clearFailed": "Problème lors du vidage du Cache d'Invocation",
|
||||
"cacheSize": "Taille du Cache",
|
||||
"hits": "Trouvé dans le Cache",
|
||||
"disableFailed": "Problème lors de la désactivation du Cache d'Invocation"
|
||||
},
|
||||
"hotkeys": {
|
||||
"hotkeys": "Raccourci clavier"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
"discordLabel": "דיסקורד",
|
||||
"settingsLabel": "הגדרות",
|
||||
"img2img": "תמונה לתמונה",
|
||||
"unifiedCanvas": "קנבס מאוחד",
|
||||
"nodes": "צמתים",
|
||||
"statusDisconnected": "מנותק",
|
||||
"hotkeysLabel": "מקשים חמים",
|
||||
@@ -48,206 +47,10 @@
|
||||
"load": "טעינה",
|
||||
"back": "אחורה"
|
||||
},
|
||||
"hotkeys": {
|
||||
"toggleGallery": {
|
||||
"desc": "פתח וסגור את מגירת הגלריה",
|
||||
"title": "הצג את הגלריה"
|
||||
},
|
||||
"keyboardShortcuts": "קיצורי מקלדת",
|
||||
"appHotkeys": "קיצורי אפליקציה",
|
||||
"generalHotkeys": "קיצורי דרך כלליים",
|
||||
"galleryHotkeys": "קיצורי דרך של הגלריה",
|
||||
"unifiedCanvasHotkeys": "קיצורי דרך לקנבס המאוחד",
|
||||
"invoke": {
|
||||
"title": "הפעל",
|
||||
"desc": "צור תמונה"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"title": "התמקדות על הבקשה",
|
||||
"desc": "התמקדות על איזור הקלדת הבקשה"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"desc": "פתח וסגור את פאנל ההגדרות",
|
||||
"title": "הצג הגדרות"
|
||||
},
|
||||
"pinOptions": {
|
||||
"title": "הצמד הגדרות",
|
||||
"desc": "הצמד את פאנל ההגדרות"
|
||||
},
|
||||
"changeTabs": {
|
||||
"title": "החלף לשוניות",
|
||||
"desc": "החלף לאיזור עבודה אחר"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"desc": "פתח וסגור את הקונסול",
|
||||
"title": "הצג קונסול"
|
||||
},
|
||||
"setPrompt": {
|
||||
"title": "הגדרת בקשה",
|
||||
"desc": "שימוש בבקשה של התמונה הנוכחית"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"desc": "שחזור התמונה הנוכחית",
|
||||
"title": "שחזור פרצופים"
|
||||
},
|
||||
"showInfo": {
|
||||
"title": "הצג מידע",
|
||||
"desc": "הצגת פרטי מטא-נתונים של התמונה הנוכחית"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"title": "שלח לתמונה לתמונה",
|
||||
"desc": "שלח תמונה נוכחית לתמונה לתמונה"
|
||||
},
|
||||
"deleteImage": {
|
||||
"title": "מחק תמונה",
|
||||
"desc": "מחק את התמונה הנוכחית"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "סגור לוחות",
|
||||
"desc": "סוגר לוחות פתוחים"
|
||||
},
|
||||
"previousImage": {
|
||||
"title": "תמונה קודמת",
|
||||
"desc": "הצג את התמונה הקודמת בגלריה"
|
||||
},
|
||||
"decreaseGalleryThumbSize": {
|
||||
"title": "הקטנת גודל תמונת גלריה",
|
||||
"desc": "מקטין את גודל התמונות הממוזערות של הגלריה"
|
||||
},
|
||||
"selectBrush": {
|
||||
"desc": "בוחר את מברשת הקנבס",
|
||||
"title": "בחר מברשת"
|
||||
},
|
||||
"selectEraser": {
|
||||
"title": "בחר מחק",
|
||||
"desc": "בוחר את מחק הקנבס"
|
||||
},
|
||||
"decreaseBrushSize": {
|
||||
"title": "הקטנת גודל המברשת",
|
||||
"desc": "מקטין את גודל מברשת הקנבס/מחק"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"desc": "מגדיל את גודל מברשת הקנבס/מחק",
|
||||
"title": "הגדלת גודל המברשת"
|
||||
},
|
||||
"decreaseBrushOpacity": {
|
||||
"title": "הפחת את אטימות המברשת",
|
||||
"desc": "מקטין את האטימות של מברשת הקנבס"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"title": "הגדל את אטימות המברשת",
|
||||
"desc": "מגביר את האטימות של מברשת הקנבס"
|
||||
},
|
||||
"moveTool": {
|
||||
"title": "כלי הזזה",
|
||||
"desc": "מאפשר ניווט על קנבס"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"desc": "ממלא את התיבה התוחמת בצבע מברשת",
|
||||
"title": "מילוי תיבה תוחמת"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"desc": "מוחק את אזור התיבה התוחמת",
|
||||
"title": "מחק תיבה תוחמת"
|
||||
},
|
||||
"colorPicker": {
|
||||
"title": "בחר בבורר צבעים",
|
||||
"desc": "בוחר את בורר צבעי הקנבס"
|
||||
},
|
||||
"toggleSnap": {
|
||||
"title": "הפעל הצמדה",
|
||||
"desc": "מפעיל הצמדה לרשת"
|
||||
},
|
||||
"quickToggleMove": {
|
||||
"title": "הפעלה מהירה להזזה",
|
||||
"desc": "מפעיל זמנית את מצב ההזזה"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"title": "הפעל שכבה",
|
||||
"desc": "הפעל בחירת שכבת בסיס/מסיכה"
|
||||
},
|
||||
"clearMask": {
|
||||
"title": "נקה מסיכה",
|
||||
"desc": "נקה את כל המסכה"
|
||||
},
|
||||
"hideMask": {
|
||||
"desc": "הסתרה והצגה של מסיכה",
|
||||
"title": "הסתר מסיכה"
|
||||
},
|
||||
"showHideBoundingBox": {
|
||||
"title": "הצגה/הסתרה של תיבה תוחמת",
|
||||
"desc": "הפעל תצוגה של התיבה התוחמת"
|
||||
},
|
||||
"mergeVisible": {
|
||||
"title": "מיזוג תוכן גלוי",
|
||||
"desc": "מיזוג כל השכבות הגלויות של הקנבס"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "שמור לגלריה",
|
||||
"desc": "שמור את הקנבס הנוכחי בגלריה"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "העתק ללוח ההדבקה",
|
||||
"desc": "העתק את הקנבס הנוכחי ללוח ההדבקה"
|
||||
},
|
||||
"downloadImage": {
|
||||
"title": "הורד תמונה",
|
||||
"desc": "הורד את הקנבס הנוכחי"
|
||||
},
|
||||
"undoStroke": {
|
||||
"title": "בטל משיכה",
|
||||
"desc": "בטל משיכת מברשת"
|
||||
},
|
||||
"redoStroke": {
|
||||
"title": "בצע שוב משיכה",
|
||||
"desc": "ביצוע מחדש של משיכת מברשת"
|
||||
},
|
||||
"resetView": {
|
||||
"title": "איפוס תצוגה",
|
||||
"desc": "אפס תצוגת קנבס"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"desc": "תמונת אזור ההערכות הקודמת",
|
||||
"title": "תמונת הערכות קודמת"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"title": "תמנות הערכות הבאה",
|
||||
"desc": "תמונת אזור ההערכות הבאה"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"desc": "אשר את תמונת איזור ההערכות הנוכחית",
|
||||
"title": "אשר תמונת הערכות"
|
||||
},
|
||||
"cancel": {
|
||||
"desc": "ביטול יצירת תמונה",
|
||||
"title": "ביטול"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"title": "מקסם את איזור העבודה",
|
||||
"desc": "סגור פאנלים ומקסם את איזור העבודה"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "הגדר זרע",
|
||||
"desc": "השתמש בזרע התמונה הנוכחית"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "הגדרת פרמטרים",
|
||||
"desc": "שימוש בכל הפרמטרים של התמונה הנוכחית"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "הגדל את גודל תמונת הגלריה",
|
||||
"desc": "מגדיל את התמונות הממוזערות של הגלריה"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "תמונה הבאה",
|
||||
"desc": "הצג את התמונה הבאה בגלריה"
|
||||
}
|
||||
},
|
||||
"gallery": {
|
||||
"galleryImageSize": "גודל תמונה",
|
||||
"gallerySettings": "הגדרות גלריה",
|
||||
"autoSwitchNewImages": "החלף אוטומטית לתמונות חדשות",
|
||||
"loadMore": "טען עוד",
|
||||
"noImagesInGallery": "אין תמונות בגלריה"
|
||||
},
|
||||
"parameters": {
|
||||
@@ -268,8 +71,6 @@
|
||||
"symmetry": "סימטריה",
|
||||
"copyImage": "העתקת תמונה",
|
||||
"downloadImage": "הורדת תמונה",
|
||||
"sendToImg2Img": "שליחה לתמונה לתמונה",
|
||||
"sendToUnifiedCanvas": "שליחה אל קנבס מאוחד",
|
||||
"usePrompt": "שימוש בבקשה",
|
||||
"useSeed": "שימוש בזרע",
|
||||
"useAll": "שימוש בהכל",
|
||||
@@ -290,77 +91,11 @@
|
||||
"resetWebUI": "איפוס ממשק משתמש",
|
||||
"resetWebUIDesc1": "איפוס ממשק המשתמש האינטרנטי מאפס רק את המטמון המקומי של הדפדפן של התמונות וההגדרות שנשמרו. זה לא מוחק תמונות מהדיסק.",
|
||||
"resetComplete": "ממשק המשתמש אופס. יש לבצע רענון דף בכדי לטעון אותו מחדש.",
|
||||
"enableImageDebugging": "הפעלת איתור באגים בתמונה",
|
||||
"resetWebUIDesc2": "אם תמונות לא מופיעות בגלריה או שמשהו אחר לא עובד, נא לנסות איפוס /או אתחול לפני שליחת תקלה ב-GitHub."
|
||||
},
|
||||
"toast": {
|
||||
"uploadFailed": "העלאה נכשלה",
|
||||
"imageCopied": "התמונה הועתקה",
|
||||
"imageNotLoadedDesc": "לא נמצאה תמונה לשליחה למודול תמונה לתמונה",
|
||||
"canvasMerged": "קנבס מוזג",
|
||||
"sentToImageToImage": "נשלח לתמונה לתמונה",
|
||||
"sentToUnifiedCanvas": "נשלח אל קנבס מאוחד",
|
||||
"parametersNotSet": "פרמטרים לא הוגדרו",
|
||||
"metadataLoadFailed": "טעינת מטא-נתונים נכשלה"
|
||||
},
|
||||
"tooltip": {
|
||||
"feature": {
|
||||
"gallery": "הגלריה מציגה יצירות מתיקיית הפלטים בעת יצירתם. ההגדרות מאוחסנות בתוך קבצים ונגישות באמצעות תפריט הקשר.",
|
||||
"upscale": "השתמש ב-ESRGAN כדי להגדיל את התמונה מיד לאחר היצירה.",
|
||||
"prompt": "זהו שדה הבקשה. הבקשה כוללת אובייקטי יצירה ומונחים סגנוניים. באפשרותך להוסיף משקל (חשיבות אסימון) גם בשורת הפקודה, אך פקודות ופרמטרים של CLI לא יפעלו.",
|
||||
"other": "אפשרויות אלה יאפשרו מצבי עיבוד חלופיים עבור ההרצה. 'ריצוף חלק' ייצור תבניות חוזרות בפלט. 'רזולוציה גבוהה' נוצר בשני שלבים עם img2img: השתמש בהגדרה זו כאשר אתה רוצה תמונה גדולה וקוהרנטית יותר ללא חפצים. פעולה זאת תקח יותר זמן מפעולת טקסט לתמונה רגילה.",
|
||||
"seed": "ערך הזרע משפיע על הרעש הראשוני שממנו נוצרת התמונה. אתה יכול להשתמש בזרעים שכבר קיימים מתמונות קודמות. 'סף רעש' משמש להפחתת חפצים בערכי CFG גבוהים (נסה את טווח 0-10), ופרלין כדי להוסיף רעשי פרלין במהלך היצירה: שניהם משמשים להוספת וריאציה לתפוקות שלך.",
|
||||
"boundingBox": "התיבה התוחמת זהה להגדרות 'רוחב' ו'גובה' עבור 'טקסט לתמונה' או 'תמונה לתמונה'. רק האזור בתיבה יעובד."
|
||||
}
|
||||
},
|
||||
"unifiedCanvas": {
|
||||
"layer": "שכבה",
|
||||
"base": "בסיס",
|
||||
"maskingOptions": "אפשרויות מסכות",
|
||||
"enableMask": "הפעלת מסיכה",
|
||||
"colorPicker": "בוחר הצבעים",
|
||||
"preserveMaskedArea": "שימור איזור ממוסך",
|
||||
"clearMask": "ניקוי מסיכה",
|
||||
"brush": "מברשת",
|
||||
"eraser": "מחק",
|
||||
"fillBoundingBox": "מילוי תיבה תוחמת",
|
||||
"eraseBoundingBox": "מחק תיבה תוחמת",
|
||||
"copyToClipboard": "העתק ללוח ההדבקה",
|
||||
"downloadAsImage": "הורדה כתמונה",
|
||||
"undo": "ביטול",
|
||||
"redo": "ביצוע מחדש",
|
||||
"clearCanvas": "ניקוי קנבס",
|
||||
"showGrid": "הצגת רשת",
|
||||
"snapToGrid": "הצמדה לרשת",
|
||||
"darkenOutsideSelection": "הכהיית בחירה חיצונית",
|
||||
"saveBoxRegionOnly": "שמירת איזור תיבה בלבד",
|
||||
"limitStrokesToBox": "הגבלת משיכות לקופסא",
|
||||
"showCanvasDebugInfo": "הצגת מידע איתור באגים בקנבס",
|
||||
"clearCanvasHistory": "ניקוי הסטוריית קנבס",
|
||||
"clearHistory": "ניקוי היסטוריה",
|
||||
"clearCanvasHistoryConfirm": "האם את/ה בטוח/ה שברצונך לנקות את היסטוריית הקנבס?",
|
||||
"activeLayer": "שכבה פעילה",
|
||||
"canvasScale": "קנה מידה של קנבס",
|
||||
"canvasDimensions": "מידות קנבס",
|
||||
"previous": "הקודם",
|
||||
"next": "הבא",
|
||||
"accept": "אישור",
|
||||
"discardAll": "בטל הכל",
|
||||
"boundingBox": "תיבה תוחמת",
|
||||
"scaledBoundingBox": "תיבה תוחמת לאחר שינוי קנה מידה",
|
||||
"brushOptions": "אפשרויות מברשת",
|
||||
"brushSize": "גודל",
|
||||
"mergeVisible": "מיזוג תוכן גלוי",
|
||||
"move": "הזזה",
|
||||
"resetView": "איפוס תצוגה",
|
||||
"saveToGallery": "שמור לגלריה",
|
||||
"canvasSettings": "הגדרות קנבס",
|
||||
"showIntermediates": "הצגת מתווכים",
|
||||
"autoSaveToGallery": "שמירה אוטומטית בגלריה",
|
||||
"clearCanvasHistoryMessage": "ניקוי היסטוריית הקנבס משאיר את הקנבס הנוכחי ללא שינוי, אך מנקה באופן בלתי הפיך את היסטוריית הביטול והביצוע מחדש.",
|
||||
"boundingBoxPosition": "מיקום תיבה תוחמת",
|
||||
"canvasPosition": "מיקום קנבס",
|
||||
"cursorPosition": "מיקום הסמן",
|
||||
"mask": "מסכה"
|
||||
"parametersNotSet": "פרמטרים לא הוגדרו"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
"uploadImage": "Fénykép feltöltése",
|
||||
"nextImage": "Következő kép",
|
||||
"previousImage": "Előző kép",
|
||||
"menu": "Menü",
|
||||
"loadMore": "Több betöltése"
|
||||
"menu": "Menü"
|
||||
},
|
||||
"boards": {
|
||||
"cancel": "Mégsem",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,6 @@
|
||||
"cancel": "キャンセル",
|
||||
"accept": "同意",
|
||||
"img2img": "img2img",
|
||||
"unifiedCanvas": "Unified Canvas",
|
||||
"loading": "ロード中",
|
||||
"githubLabel": "Github",
|
||||
"hotkeysLabel": "ホットキー",
|
||||
@@ -23,7 +22,6 @@
|
||||
"dontAskMeAgain": "次回から確認しない",
|
||||
"areYouSure": "本当によろしいですか?",
|
||||
"on": "オン",
|
||||
"nodeEditor": "ノードエディター",
|
||||
"ipAdapter": "IPアダプター",
|
||||
"auto": "自動",
|
||||
"openInNewTab": "新しいタブで開く",
|
||||
@@ -71,8 +69,6 @@
|
||||
"prevPage": "前のページ",
|
||||
"unknownError": "未知のエラー",
|
||||
"orderBy": "並び順:",
|
||||
"comparing": "比較中",
|
||||
"comparingDesc": "2 つの画像の比較する",
|
||||
"enabled": "有効",
|
||||
"notInstalled": "未インストール",
|
||||
"positivePrompt": "プロンプト",
|
||||
@@ -81,31 +77,24 @@
|
||||
"aboutDesc": "Invokeを業務で利用する場合はマークしてください:",
|
||||
"beta": "ベータ",
|
||||
"disabled": "無効",
|
||||
"loglevel": "ログラベル",
|
||||
"editor": "エディタ",
|
||||
"safetensors": "Safetensors",
|
||||
"tab": "タブ",
|
||||
"viewingDesc": "画像を大きなギャラリービューで開く",
|
||||
"editing": "編集",
|
||||
"editingDesc": "コントロールレイヤキャンバスで編集",
|
||||
"toResolve": "解決方法"
|
||||
},
|
||||
"gallery": {
|
||||
"galleryImageSize": "画像のサイズ",
|
||||
"gallerySettings": "ギャラリーの設定",
|
||||
"loadMore": "さらに読み込む",
|
||||
"noImagesInGallery": "表示する画像がありません",
|
||||
"autoSwitchNewImages": "新しい画像に自動切替",
|
||||
"copy": "コピー",
|
||||
"image": "画像",
|
||||
"setCurrentImage": "現在の画像としてセット",
|
||||
"autoAssignBoardOnClick": "クリックしたボードに自動追加",
|
||||
"featuresWillReset": "この画像を削除すると、これらの機能は即座にリセットされます。",
|
||||
"unstarImage": "スターを外す",
|
||||
"loading": "ロード中",
|
||||
"assets": "アセット",
|
||||
"currentlyInUse": "この画像は現在下記の機能を使用しています:",
|
||||
"problemDeletingImages": "画像の削除中に問題が発生",
|
||||
"drop": "ドロップ",
|
||||
"dropOrUpload": "$t(gallery.drop) またはアップロード",
|
||||
"deleteImage_other": "画像を削除",
|
||||
@@ -116,7 +105,6 @@
|
||||
"bulkDownloadRequestedDesc": "ダウンロードの準備中です。しばらくお待ちください。",
|
||||
"bulkDownloadRequestFailed": "ダウンロード準備中に問題が発生",
|
||||
"bulkDownloadFailed": "ダウンロード失敗",
|
||||
"problemDeletingImagesDesc": "1つ以上の画像を削除できませんでした",
|
||||
"alwaysShowImageSizeBadge": "画像サイズバッジを常に表示",
|
||||
"dropToUpload": "$t(gallery.drop) してアップロード",
|
||||
"noImageSelected": "画像が選択されていません",
|
||||
@@ -132,7 +120,6 @@
|
||||
"sideBySide": "横並び",
|
||||
"hover": "ホバー",
|
||||
"swapImages": "画像を入れ替える",
|
||||
"compareOptions": "比較オプション",
|
||||
"stretchToFit": "画面に合わせる",
|
||||
"exitCompare": "比較を終了する",
|
||||
"compareHelp1": "<Kbd>Alt</Kbd> キーを押しながらギャラリー画像をクリックするか、矢印キーを使用して比較画像を変更します。",
|
||||
@@ -141,227 +128,9 @@
|
||||
"compareHelp2": "<Kbd>M</Kbd> キーを押して比較モードを切り替えます。"
|
||||
},
|
||||
"hotkeys": {
|
||||
"keyboardShortcuts": "ホットキー",
|
||||
"appHotkeys": "アプリケーション",
|
||||
"generalHotkeys": "一般",
|
||||
"galleryHotkeys": "ギャラリー",
|
||||
"unifiedCanvasHotkeys": "Unified Canvasのホットキー",
|
||||
"invoke": {
|
||||
"desc": "画像を生成",
|
||||
"title": "Invoke"
|
||||
},
|
||||
"cancel": {
|
||||
"title": "キャンセル",
|
||||
"desc": "現在のキューをキャンセル"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"desc": "プロンプトテキストボックスにフォーカス",
|
||||
"title": "プロンプトにフォーカス"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"title": "オプションパネルのトグル",
|
||||
"desc": "オプションパネルの開閉"
|
||||
},
|
||||
"pinOptions": {
|
||||
"title": "ピン",
|
||||
"desc": "オプションパネルを固定"
|
||||
},
|
||||
"toggleGallery": {
|
||||
"title": "ギャラリーのトグル",
|
||||
"desc": "ギャラリードロワーの開閉"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"title": "作業領域の最大化",
|
||||
"desc": "パネルを閉じて、作業領域を最大に"
|
||||
},
|
||||
"changeTabs": {
|
||||
"title": "タブの切替",
|
||||
"desc": "他の作業領域と切替"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"title": "コンソールのトグル",
|
||||
"desc": "コンソールの開閉"
|
||||
},
|
||||
"setPrompt": {
|
||||
"title": "プロンプトをセット",
|
||||
"desc": "現在の画像のプロンプトを使用"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "シード値をセット",
|
||||
"desc": "現在の画像のシード値を使用"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "パラメータをセット",
|
||||
"desc": "現在の画像のすべてのパラメータを使用"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "顔の修復",
|
||||
"desc": "現在の画像を修復"
|
||||
},
|
||||
"showInfo": {
|
||||
"title": "情報を見る",
|
||||
"desc": "現在の画像のメタデータ情報を表示"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"title": "Image To Imageに転送",
|
||||
"desc": "現在の画像をImage to Imageに転送"
|
||||
},
|
||||
"deleteImage": {
|
||||
"title": "画像を削除",
|
||||
"desc": "現在の画像を削除"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "パネルを閉じる",
|
||||
"desc": "開いているパネルを閉じる"
|
||||
},
|
||||
"previousImage": {
|
||||
"title": "前の画像",
|
||||
"desc": "ギャラリー内の1つ前の画像を表示"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "次の画像",
|
||||
"desc": "ギャラリー内の1つ後の画像を表示"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "ギャラリーの画像を拡大",
|
||||
"desc": "ギャラリーのサムネイル画像を拡大"
|
||||
},
|
||||
"decreaseGalleryThumbSize": {
|
||||
"title": "ギャラリーの画像サイズを縮小",
|
||||
"desc": "ギャラリーのサムネイル画像を縮小"
|
||||
},
|
||||
"selectBrush": {
|
||||
"title": "ブラシを選択",
|
||||
"desc": "ブラシを選択"
|
||||
},
|
||||
"selectEraser": {
|
||||
"title": "消しゴムを選択",
|
||||
"desc": "消しゴムを選択"
|
||||
},
|
||||
"decreaseBrushSize": {
|
||||
"title": "ブラシサイズを縮小",
|
||||
"desc": "ブラシ/消しゴムのサイズを縮小"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "ブラシサイズを拡大",
|
||||
"desc": "ブラシ/消しゴムのサイズを拡大"
|
||||
},
|
||||
"decreaseBrushOpacity": {
|
||||
"title": "ブラシの不透明度を下げる",
|
||||
"desc": "キャンバスブラシの不透明度を下げる"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"title": "ブラシの不透明度を上げる",
|
||||
"desc": "キャンバスブラシの不透明度を上げる"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "バウンディングボックスを塗りつぶす",
|
||||
"desc": "ブラシの色でバウンディングボックス領域を塗りつぶす"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"title": "バウンディングボックスを消す",
|
||||
"desc": "バウンディングボックス領域を消す"
|
||||
},
|
||||
"colorPicker": {
|
||||
"title": "カラーピッカーを選択",
|
||||
"desc": "カラーピッカーを選択"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"title": "レイヤーを切替",
|
||||
"desc": "マスク/ベースレイヤの選択を切替"
|
||||
},
|
||||
"clearMask": {
|
||||
"title": "マスクを消す",
|
||||
"desc": "マスク全体を消す"
|
||||
},
|
||||
"hideMask": {
|
||||
"title": "マスクを非表示",
|
||||
"desc": "マスクを表示/非表示"
|
||||
},
|
||||
"showHideBoundingBox": {
|
||||
"title": "バウンディングボックスを表示/非表示",
|
||||
"desc": "バウンディングボックスの表示/非表示を切替"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "ギャラリーに保存",
|
||||
"desc": "現在のキャンバスをギャラリーに保存"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "クリップボードにコピー",
|
||||
"desc": "現在のキャンバスをクリップボードにコピー"
|
||||
},
|
||||
"downloadImage": {
|
||||
"title": "画像をダウンロード",
|
||||
"desc": "現在の画像をダウンロード"
|
||||
},
|
||||
"resetView": {
|
||||
"title": "キャンバスをリセット",
|
||||
"desc": "キャンバスをリセット"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"title": "プレビュー画像の採用",
|
||||
"desc": "現在のプレビュー画像を採用する"
|
||||
},
|
||||
"addNodes": {
|
||||
"desc": "ノード追加メニューを開く",
|
||||
"title": "ノードを追加"
|
||||
},
|
||||
"moveTool": {
|
||||
"desc": "キャンバスを移動する",
|
||||
"title": "手のひらツール"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"desc": "次のプレビュー画像",
|
||||
"title": "次のステージング画像"
|
||||
},
|
||||
"cancelAndClear": {
|
||||
"desc": "生成をキャンセルしキューもクリアします",
|
||||
"title": "キャンセルとクリア"
|
||||
},
|
||||
"mergeVisible": {
|
||||
"title": "表示レイヤーを統合",
|
||||
"desc": "全ての表示レイヤーを統合"
|
||||
},
|
||||
"searchHotkeys": "ホットキーを検索",
|
||||
"clearSearch": "検索をクリア",
|
||||
"noHotkeysFound": "ホットキーが見つかりません",
|
||||
"remixImage": {
|
||||
"title": "画像をリミックス",
|
||||
"desc": "現在の画像のシード値を除く全パラメータを使用"
|
||||
},
|
||||
"redoStroke": {
|
||||
"title": "ストロークをやり直す",
|
||||
"desc": "ブラシストロークのやり直し"
|
||||
},
|
||||
"resetOptionsAndGallery": {
|
||||
"title": "オプションとギャラリーをリセット",
|
||||
"desc": "オプションとギャラリーパネルをリセット"
|
||||
},
|
||||
"quickToggleMove": {
|
||||
"title": "高速トグル切り替え",
|
||||
"desc": "一時的に移動モードを切り替える"
|
||||
},
|
||||
"toggleSnap": {
|
||||
"title": "スナップの切り替え",
|
||||
"desc": "グリッドへのスナップの切り替え"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"desc": "ステージング領域の前の画像",
|
||||
"title": "前のステージング画像"
|
||||
},
|
||||
"nodesHotkeys": "ノード",
|
||||
"toggleOptionsAndGallery": {
|
||||
"desc": "オプションとギャラリーパネルのオンオフを切り替える",
|
||||
"title": "オプションとギャラリーを切り替える"
|
||||
},
|
||||
"undoStroke": {
|
||||
"desc": "ブラシストロークの取り消し",
|
||||
"title": "ストロークの取り消し"
|
||||
},
|
||||
"toggleViewer": {
|
||||
"desc": "イメージ ビューアーと現在のタブのワークスペースを切り替えます。",
|
||||
"title": "画像ビューアの切り替え"
|
||||
}
|
||||
"noHotkeysFound": "ホットキーが見つかりません"
|
||||
},
|
||||
"modelManager": {
|
||||
"modelManager": "モデルマネージャ",
|
||||
@@ -398,7 +167,6 @@
|
||||
"modelConverted": "モデル変換が完了しました",
|
||||
"predictionType": "予測タイプ(安定したディフュージョン 2.x モデルおよび一部の安定したディフュージョン 1.x モデル用)",
|
||||
"selectModel": "モデルを選択",
|
||||
"modelSyncFailed": "モデルの同期に失敗しました",
|
||||
"advanced": "高度な設定",
|
||||
"modelDeleted": "モデルが削除されました",
|
||||
"convertToDiffusersHelpText2": "このプロセスでは、モデルマネージャーのエントリーを同じモデルのディフューザーバージョンに置き換えます。",
|
||||
@@ -408,7 +176,6 @@
|
||||
"syncModels": "モデルを同期",
|
||||
"modelType": "モデルタイプ",
|
||||
"convertToDiffusersHelpText1": "このモデルは 🧨 Diffusers フォーマットに変換されます。",
|
||||
"modelsSynced": "モデルが同期されました",
|
||||
"convertToDiffusersHelpText3": "チェックポイントファイルは、InvokeAIルートフォルダ内にある場合、ディスクから削除されます。カスタムロケーションにある場合は、削除されません。",
|
||||
"convertToDiffusersHelpText4": "これは一回限りのプロセスです。コンピュータの仕様によっては、約30秒から60秒かかる可能性があります。",
|
||||
"cancel": "キャンセル"
|
||||
@@ -426,18 +193,12 @@
|
||||
"scaleBeforeProcessing": "処理前のスケール",
|
||||
"scaledWidth": "幅のスケール",
|
||||
"scaledHeight": "高さのスケール",
|
||||
"sendToImg2Img": "Image to Imageに転送",
|
||||
"sendToUnifiedCanvas": "Unified Canvasに転送",
|
||||
"downloadImage": "画像をダウンロード",
|
||||
"usePrompt": "プロンプトを使用",
|
||||
"useSeed": "シード値を使用",
|
||||
"useAll": "すべてを使用",
|
||||
"info": "情報",
|
||||
"showOptionsPanel": "オプションパネルを表示",
|
||||
"invoke": {
|
||||
"noControlImageForControlAdapter": "コントロールアダプター #{{number}} に画像がありません",
|
||||
"noModelForControlAdapter": "コントロールアダプター #{{number}} のモデルが選択されていません。"
|
||||
},
|
||||
"iterations": "生成回数",
|
||||
"general": "基本設定"
|
||||
},
|
||||
@@ -445,7 +206,6 @@
|
||||
"models": "モデル",
|
||||
"displayInProgress": "生成中の画像を表示する",
|
||||
"confirmOnDelete": "削除時に確認",
|
||||
"enableImageDebugging": "画像のデバッグを有効化",
|
||||
"resetWebUI": "WebUIをリセット",
|
||||
"resetWebUIDesc1": "WebUIのリセットは、画像と保存された設定のキャッシュをリセットするだけです。画像を削除するわけではありません。",
|
||||
"resetWebUIDesc2": "もしギャラリーに画像が表示されないなど、何か問題が発生した場合はGitHubにissueを提出する前にリセットを試してください。",
|
||||
@@ -453,63 +213,7 @@
|
||||
},
|
||||
"toast": {
|
||||
"uploadFailed": "アップロード失敗",
|
||||
"imageCopied": "画像をコピー",
|
||||
"imageNotLoadedDesc": "Image To Imageに転送する画像が見つかりません。",
|
||||
"canvasMerged": "Canvas Merged",
|
||||
"sentToImageToImage": "Image To Imageに転送",
|
||||
"sentToUnifiedCanvas": "Unified Canvasに転送",
|
||||
"metadataLoadFailed": "メタデータの読み込みに失敗。"
|
||||
},
|
||||
"tooltip": {
|
||||
"feature": {
|
||||
"prompt": "これはプロンプトフィールドです。プロンプトには生成オブジェクトや文法用語が含まれます。プロンプトにも重み(Tokenの重要度)を付けることができますが、CLIコマンドやパラメータは機能しません。",
|
||||
"gallery": "ギャラリーは、出力先フォルダから生成物を表示します。設定はファイル内に保存され、コンテキストメニューからアクセスできます。.",
|
||||
"seed": "シード値は、画像が形成される際の初期ノイズに影響します。以前の画像から既に存在するシードを使用することができます。ノイズしきい値は高いCFG値でのアーティファクトを軽減するために使用され、Perlinは生成中にPerlinノイズを追加します(0-10の範囲を試してみてください): どちらも出力にバリエーションを追加するのに役立ちます。",
|
||||
"upscale": "生成直後の画像をアップスケールするには、ESRGANを使用します。",
|
||||
"boundingBox": "バウンディングボックスは、Text To ImageまたはImage To Imageの幅/高さの設定と同じです。ボックス内の領域のみが処理されます。"
|
||||
}
|
||||
},
|
||||
"unifiedCanvas": {
|
||||
"mask": "マスク",
|
||||
"maskingOptions": "マスクのオプション",
|
||||
"enableMask": "マスクを有効化",
|
||||
"preserveMaskedArea": "マスク領域の保存",
|
||||
"clearMask": "マスクを解除",
|
||||
"brush": "ブラシ",
|
||||
"eraser": "消しゴム",
|
||||
"fillBoundingBox": "バウンディングボックスの塗りつぶし",
|
||||
"eraseBoundingBox": "バウンディングボックスの消去",
|
||||
"colorPicker": "カラーピッカー",
|
||||
"brushOptions": "ブラシオプション",
|
||||
"brushSize": "サイズ",
|
||||
"saveToGallery": "ギャラリーに保存",
|
||||
"copyToClipboard": "クリップボードにコピー",
|
||||
"downloadAsImage": "画像としてダウンロード",
|
||||
"undo": "取り消し",
|
||||
"redo": "やり直し",
|
||||
"clearCanvas": "キャンバスを片付ける",
|
||||
"canvasSettings": "キャンバスの設定",
|
||||
"showGrid": "グリッドを表示",
|
||||
"darkenOutsideSelection": "外周を暗くする",
|
||||
"autoSaveToGallery": "ギャラリーに自動保存",
|
||||
"saveBoxRegionOnly": "ボックス領域のみ保存",
|
||||
"showCanvasDebugInfo": "キャンバスのデバッグ情報を表示",
|
||||
"clearCanvasHistory": "キャンバスの履歴を削除",
|
||||
"clearHistory": "履歴を削除",
|
||||
"clearCanvasHistoryMessage": "履歴を消去すると現在のキャンバスは残りますが、取り消しややり直しの履歴は不可逆的に消去されます。",
|
||||
"clearCanvasHistoryConfirm": "履歴を削除しますか?",
|
||||
"activeLayer": "Active Layer",
|
||||
"canvasScale": "Canvas Scale",
|
||||
"boundingBox": "バウンディングボックス",
|
||||
"boundingBoxPosition": "バウンディングボックスの位置",
|
||||
"canvasDimensions": "キャンバスの大きさ",
|
||||
"canvasPosition": "キャンバスの位置",
|
||||
"cursorPosition": "カーソルの位置",
|
||||
"previous": "前",
|
||||
"next": "次",
|
||||
"accept": "同意",
|
||||
"discardAll": "すべて破棄",
|
||||
"snapToGrid": "グリッドにスナップ"
|
||||
"imageCopied": "画像をコピー"
|
||||
},
|
||||
"accessibility": {
|
||||
"invokeProgressBar": "進捗バー",
|
||||
@@ -520,103 +224,12 @@
|
||||
"showOptionsPanel": "サイドパネルを表示",
|
||||
"showGalleryPanel": "ギャラリーパネルを表示",
|
||||
"menu": "メニュー",
|
||||
"loadMore": "さらに読み込む",
|
||||
"createIssue": "問題を報告",
|
||||
"resetUI": "$t(accessibility.reset) UI",
|
||||
"mode": "モード:",
|
||||
"about": "Invoke について",
|
||||
"submitSupportTicket": "サポート依頼を送信する"
|
||||
},
|
||||
"controlnet": {
|
||||
"resize": "リサイズ",
|
||||
"showAdvanced": "高度な設定を表示",
|
||||
"addT2IAdapter": "$t(common.t2iAdapter)を追加",
|
||||
"importImageFromCanvas": "キャンバスから画像をインポート",
|
||||
"lineartDescription": "画像を線画に変換",
|
||||
"importMaskFromCanvas": "キャンバスからマスクをインポート",
|
||||
"hideAdvanced": "高度な設定を非表示",
|
||||
"resetControlImage": "コントロール画像をリセット",
|
||||
"beginEndStepPercent": "開始 / 終了ステップパーセンテージ",
|
||||
"duplicate": "複製",
|
||||
"balanced": "バランス",
|
||||
"prompt": "プロンプト",
|
||||
"depthMidasDescription": "Midasを使用して深度マップを生成",
|
||||
"control": "コントロール",
|
||||
"resizeMode": "リサイズモード",
|
||||
"weight": "重み",
|
||||
"selectModel": "モデルを選択",
|
||||
"crop": "切り抜き",
|
||||
"w": "幅",
|
||||
"processor": "プロセッサー",
|
||||
"addControlNet": "$t(common.controlNet)を追加",
|
||||
"none": "なし",
|
||||
"detectResolution": "検出解像度",
|
||||
"pidiDescription": "PIDI画像処理",
|
||||
"controlMode": "コントロールモード",
|
||||
"fill": "塗りつぶし",
|
||||
"cannyDescription": "Canny 境界検出",
|
||||
"addIPAdapter": "$t(common.ipAdapter)を追加",
|
||||
"colorMapDescription": "画像からカラーマップを生成",
|
||||
"lineartAnimeDescription": "アニメスタイルの線画処理",
|
||||
"imageResolution": "画像解像度",
|
||||
"megaControl": "メガコントロール",
|
||||
"lowThreshold": "最低閾値",
|
||||
"autoConfigure": "プロセッサーを自動設定",
|
||||
"highThreshold": "最大閾値",
|
||||
"saveControlImage": "コントロール画像を保存",
|
||||
"toggleControlNet": "このコントロールネットを切り替え",
|
||||
"delete": "削除",
|
||||
"controlAdapter_other": "コントロールアダプター",
|
||||
"colorMapTileSize": "タイルサイズ",
|
||||
"mediapipeFaceDescription": "Mediapipeを使用して顔を検出",
|
||||
"depthZoeDescription": "Zoeを使用して深度マップを生成",
|
||||
"setControlImageDimensions": "コントロール画像のサイズを幅と高さにセット",
|
||||
"amult": "a_mult",
|
||||
"contentShuffleDescription": "画像の内容をシャッフルします",
|
||||
"bgth": "bg_th",
|
||||
"controlnet": "$t(controlnet.controlAdapter_one) #{{number}} ($t(common.controlNet))",
|
||||
"ip_adapter": "$t(controlnet.controlAdapter_one) #{{number}} ($t(common.ipAdapter))",
|
||||
"t2i_adapter": "$t(controlnet.controlAdapter_one) #{{number}} ($t(common.t2iAdapter))",
|
||||
"minConfidence": "最小確信度",
|
||||
"colorMap": "Color",
|
||||
"noneDescription": "処理は行われていません",
|
||||
"canny": "Canny",
|
||||
"hedDescription": "階層的エッジ検出",
|
||||
"maxFaces": "顔の最大数",
|
||||
"depthMidas": "深度 (Midas)",
|
||||
"f": "F",
|
||||
"h": "H",
|
||||
"lineart": "線画",
|
||||
"depthAnythingDescription": "Depth Anything 技術を使って深度マップを生成します",
|
||||
"hed": "HED",
|
||||
"normalBaeDescription": "法線 BAE 処理中",
|
||||
"pidi": "PIDI",
|
||||
"resizeSimple": "リサイズ(シンプル)",
|
||||
"scribble": "らくがき",
|
||||
"small": "小型",
|
||||
"mediapipeFace": "Mediapipe 顔",
|
||||
"mlsd": "M-LSD",
|
||||
"normalBae": "法線 BAE",
|
||||
"base": "ベース",
|
||||
"contentShuffle": "シャッフル",
|
||||
"modelSize": "モデルサイズ",
|
||||
"safe": "セーフモード",
|
||||
"depthZoe": "深度 (Zoe)",
|
||||
"face": "顔",
|
||||
"body": "体",
|
||||
"hands": "手",
|
||||
"large": "大型",
|
||||
"lineartAnime": "アニメ線画",
|
||||
"mlsdDescription": "最小線分検知",
|
||||
"dwOpenpose": "DW オープンポーズ",
|
||||
"dwOpenposeDescription": "DW オープンポーズによる人体ポーズの推定",
|
||||
"ipAdapterMethod": "方式",
|
||||
"setControlImageDimensionsForce": "モデルを無視してサイズを W/H にコピー",
|
||||
"style": "スタイルのみ",
|
||||
"selectCLIPVisionModel": "CLIP Visionのモデルを選択",
|
||||
"composition": "構図のみ",
|
||||
"beginEndStepPercentShort": "開始 / 終了 %"
|
||||
},
|
||||
"metadata": {
|
||||
"seamless": "シームレス",
|
||||
"Threshold": "ノイズ閾値",
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
"reportBugLabel": "버그 리포트",
|
||||
"githubLabel": "Github",
|
||||
"settingsLabel": "설정",
|
||||
"unifiedCanvas": "통합 캔버스",
|
||||
"nodes": "Workflow Editor",
|
||||
"upload": "업로드",
|
||||
"load": "불러오기",
|
||||
@@ -27,7 +26,6 @@
|
||||
"on": "켜기",
|
||||
"save": "저장",
|
||||
"created": "생성됨",
|
||||
"nodeEditor": "Node Editor",
|
||||
"error": "에러",
|
||||
"prevPage": "이전 페이지",
|
||||
"ipAdapter": "IP 어댑터",
|
||||
@@ -71,15 +69,12 @@
|
||||
"deleteSelection": "선택 항목 삭제",
|
||||
"featuresWillReset": "이 이미지를 삭제하면 해당 기능이 즉시 재설정됩니다.",
|
||||
"assets": "자산",
|
||||
"problemDeletingImagesDesc": "하나 이상의 이미지를 삭제할 수 없습니다",
|
||||
"noImagesInGallery": "보여줄 이미지가 없음",
|
||||
"autoSwitchNewImages": "새로운 이미지로 자동 전환",
|
||||
"loading": "불러오는 중",
|
||||
"unableToLoad": "갤러리를 로드할 수 없음",
|
||||
"image": "이미지",
|
||||
"loadMore": "더 불러오기",
|
||||
"drop": "드랍",
|
||||
"problemDeletingImages": "이미지 삭제 중 발생한 문제",
|
||||
"downloadSelection": "선택 항목 다운로드",
|
||||
"deleteImage_other": "이미지 삭제",
|
||||
"currentlyInUse": "이 이미지는 현재 다음 기능에서 사용되고 있습니다:",
|
||||
@@ -89,7 +84,6 @@
|
||||
"deleteImagePermanent": "삭제된 이미지는 복원할 수 없습니다.",
|
||||
"noImageSelected": "선택된 이미지 없음",
|
||||
"autoAssignBoardOnClick": "클릭 시 Board로 자동 할당",
|
||||
"setCurrentImage": "현재 이미지로 설정",
|
||||
"dropToUpload": "업로드를 위해 $t(gallery.drop)"
|
||||
},
|
||||
"accessibility": {
|
||||
@@ -100,7 +94,6 @@
|
||||
"uploadImage": "이미지 업로드",
|
||||
"showGalleryPanel": "갤러리 패널 표시",
|
||||
"reset": "리셋",
|
||||
"loadMore": "더 불러오기",
|
||||
"showOptionsPanel": "사이드 패널 표시"
|
||||
},
|
||||
"modelManager": {
|
||||
@@ -117,7 +110,6 @@
|
||||
"predictionType": "예측 유형(안정 확산 2.x 모델 및 간혹 안정 확산 1.x 모델의 경우)",
|
||||
"selectModel": "모델 선택",
|
||||
"repo_id": "Repo ID",
|
||||
"modelSyncFailed": "모델 동기화 실패",
|
||||
"convertToDiffusersHelpText6": "이 모델을 변환하시겠습니까?",
|
||||
"config": "구성",
|
||||
"selected": "선택된",
|
||||
@@ -136,10 +128,8 @@
|
||||
"syncModels": "동기화 모델",
|
||||
"modelType": "모델 유형",
|
||||
"convertingModelBegin": "모델 변환 중입니다. 잠시만 기다려 주십시오.",
|
||||
"v2_base": "v2 (512px)",
|
||||
"name": "이름",
|
||||
"convertToDiffusersHelpText1": "이 모델은 🧨 Diffusers 형식으로 변환됩니다.",
|
||||
"modelsSynced": "동기화된 모델",
|
||||
"vaePrecision": "VAE 정밀도",
|
||||
"deleteMsg2": "모델이 InvokeAI root 폴더에 있으면 디스크에서 모델이 삭제됩니다. 사용자 지정 위치를 사용하는 경우 모델이 디스크에서 삭제되지 않습니다.",
|
||||
"baseModel": "기본 모델",
|
||||
@@ -152,279 +142,10 @@
|
||||
"allModels": "모든 모델",
|
||||
"alpha": "Alpha",
|
||||
"noModelSelected": "선택한 모델 없음",
|
||||
"v2_768": "v2 (768px)",
|
||||
"convertToDiffusersHelpText4": "이것은 한 번의 과정일 뿐입니다. 컴퓨터 사양에 따라 30-60초 정도 소요될 수 있습니다.",
|
||||
"model": "모델",
|
||||
"delete": "삭제"
|
||||
},
|
||||
"controlnet": {
|
||||
"amult": "a_mult",
|
||||
"resize": "크기 조정",
|
||||
"showAdvanced": "고급 표시",
|
||||
"contentShuffleDescription": "이미지에서 content 섞기",
|
||||
"bgth": "bg_th",
|
||||
"addT2IAdapter": "$t(common.t2iAdapter) 추가",
|
||||
"pidi": "PIDI",
|
||||
"importImageFromCanvas": "캔버스에서 이미지 가져오기",
|
||||
"lineartDescription": "이미지->lineart 변환",
|
||||
"normalBae": "Normal BAE",
|
||||
"importMaskFromCanvas": "캔버스에서 Mask 가져오기",
|
||||
"hed": "HED",
|
||||
"contentShuffle": "Content Shuffle",
|
||||
"resetControlImage": "Control Image 재설정",
|
||||
"beginEndStepPercent": "Begin / End Step Percentage",
|
||||
"mlsdDescription": "Minimalist Line Segment Detector",
|
||||
"duplicate": "복제",
|
||||
"balanced": "Balanced",
|
||||
"f": "F",
|
||||
"h": "H",
|
||||
"prompt": "프롬프트",
|
||||
"depthMidasDescription": "Midas를 사용하여 Depth map 생성하기",
|
||||
"control": "Control",
|
||||
"resizeMode": "크기 조정 모드",
|
||||
"coarse": "Coarse",
|
||||
"weight": "Weight",
|
||||
"selectModel": "모델 선택",
|
||||
"crop": "Crop",
|
||||
"depthMidas": "Depth (Midas)",
|
||||
"w": "W",
|
||||
"processor": "프로세서",
|
||||
"addControlNet": "$t(common.controlNet) 추가",
|
||||
"none": "해당없음",
|
||||
"detectResolution": "해상도 탐지",
|
||||
"pidiDescription": "PIDI image 처리",
|
||||
"mediapipeFace": "Mediapipe Face",
|
||||
"mlsd": "M-LSD",
|
||||
"controlMode": "Control Mode",
|
||||
"fill": "채우기",
|
||||
"cannyDescription": "Canny 모서리 삭제",
|
||||
"addIPAdapter": "$t(common.ipAdapter) 추가",
|
||||
"lineart": "Lineart",
|
||||
"colorMapDescription": "이미지에서 color map을 생성합니다",
|
||||
"lineartAnimeDescription": "Anime-style lineart 처리",
|
||||
"minConfidence": "Min Confidence",
|
||||
"imageResolution": "이미지 해상도",
|
||||
"megaControl": "Mega Control",
|
||||
"depthZoe": "Depth (Zoe)",
|
||||
"colorMap": "색",
|
||||
"lowThreshold": "Low Threshold",
|
||||
"autoConfigure": "프로세서 자동 구성",
|
||||
"highThreshold": "High Threshold",
|
||||
"normalBaeDescription": "Normal BAE 처리",
|
||||
"noneDescription": "처리되지 않음",
|
||||
"saveControlImage": "Control Image 저장",
|
||||
"toggleControlNet": "해당 ControlNet으로 전환",
|
||||
"delete": "삭제",
|
||||
"controlAdapter_other": "Control Adapter(s)",
|
||||
"safe": "Safe",
|
||||
"colorMapTileSize": "타일 크기",
|
||||
"lineartAnime": "Lineart Anime",
|
||||
"mediapipeFaceDescription": "Mediapipe를 사용하여 Face 탐지",
|
||||
"canny": "Canny",
|
||||
"depthZoeDescription": "Zoe를 사용하여 Depth map 생성하기",
|
||||
"hedDescription": "Holistically-Nested 모서리 탐지",
|
||||
"setControlImageDimensions": "Control Image Dimensions를 W/H로 설정",
|
||||
"scribble": "scribble",
|
||||
"maxFaces": "Max Faces"
|
||||
},
|
||||
"hotkeys": {
|
||||
"toggleSnap": {
|
||||
"desc": "Snap을 Grid로 전환",
|
||||
"title": "Snap 전환"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "시드 설정",
|
||||
"desc": "현재 이미지의 시드 사용"
|
||||
},
|
||||
"keyboardShortcuts": "키보드 바로 가기",
|
||||
"decreaseGalleryThumbSize": {
|
||||
"desc": "갤러리 미리 보기 크기 축소",
|
||||
"title": "갤러리 이미지 크기 축소"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"title": "이전 스테이징 이미지",
|
||||
"desc": "이전 스테이징 영역 이미지"
|
||||
},
|
||||
"decreaseBrushSize": {
|
||||
"title": "브러시 크기 줄이기",
|
||||
"desc": "캔버스 브러시/지우개 크기 감소"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"desc": "콘솔 열고 닫기",
|
||||
"title": "콘솔 전환"
|
||||
},
|
||||
"selectBrush": {
|
||||
"desc": "캔버스 브러시를 선택",
|
||||
"title": "브러시 선택"
|
||||
},
|
||||
"previousImage": {
|
||||
"title": "이전 이미지",
|
||||
"desc": "갤러리에 이전 이미지 표시"
|
||||
},
|
||||
"unifiedCanvasHotkeys": "Unified Canvas Hotkeys",
|
||||
"toggleOptions": {
|
||||
"desc": "옵션 패널을 열고 닫기",
|
||||
"title": "옵션 전환"
|
||||
},
|
||||
"selectEraser": {
|
||||
"title": "지우개 선택",
|
||||
"desc": "캔버스 지우개를 선택"
|
||||
},
|
||||
"setPrompt": {
|
||||
"title": "프롬프트 설정",
|
||||
"desc": "현재 이미지의 프롬프트 사용"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"desc": "현재 준비 영역 이미지 허용",
|
||||
"title": "준비 이미지 허용"
|
||||
},
|
||||
"resetView": {
|
||||
"desc": "Canvas View 초기화",
|
||||
"title": "View 초기화"
|
||||
},
|
||||
"hideMask": {
|
||||
"title": "Mask 숨김",
|
||||
"desc": "mask 숨김/숨김 해제"
|
||||
},
|
||||
"pinOptions": {
|
||||
"title": "옵션 고정",
|
||||
"desc": "옵션 패널을 고정"
|
||||
},
|
||||
"toggleGallery": {
|
||||
"desc": "gallery drawer 열기 및 닫기",
|
||||
"title": "Gallery 전환"
|
||||
},
|
||||
"quickToggleMove": {
|
||||
"title": "빠른 토글 이동",
|
||||
"desc": "일시적으로 이동 모드 전환"
|
||||
},
|
||||
"generalHotkeys": "General Hotkeys",
|
||||
"showHideBoundingBox": {
|
||||
"desc": "bounding box 표시 전환",
|
||||
"title": "Bounding box 표시/숨김"
|
||||
},
|
||||
"showInfo": {
|
||||
"desc": "현재 이미지의 metadata 정보 표시",
|
||||
"title": "정보 표시"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "클립보드로 복사",
|
||||
"desc": "현재 캔버스를 클립보드로 복사"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "Faces 복원",
|
||||
"desc": "현재 이미지 복원"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "Bounding Box 채우기",
|
||||
"desc": "bounding box를 브러시 색으로 채웁니다"
|
||||
},
|
||||
"closePanels": {
|
||||
"desc": "열린 panels 닫기",
|
||||
"title": "panels 닫기"
|
||||
},
|
||||
"downloadImage": {
|
||||
"desc": "현재 캔버스 다운로드",
|
||||
"title": "이미지 다운로드"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "매개 변수 설정",
|
||||
"desc": "현재 이미지의 모든 매개 변수 사용"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"desc": "패널을 닫고 작업 면적을 극대화",
|
||||
"title": "작업 공간 극대화"
|
||||
},
|
||||
"galleryHotkeys": "Gallery Hotkeys",
|
||||
"cancel": {
|
||||
"desc": "이미지 생성 취소",
|
||||
"title": "취소"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "갤러리에 저장",
|
||||
"desc": "현재 캔버스를 갤러리에 저장"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"desc": "bounding box 영역을 지웁니다",
|
||||
"title": "Bounding Box 지우기"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "다음 이미지",
|
||||
"desc": "갤러리에 다음 이미지 표시"
|
||||
},
|
||||
"colorPicker": {
|
||||
"desc": "canvas color picker 선택",
|
||||
"title": "Color Picker 선택"
|
||||
},
|
||||
"invoke": {
|
||||
"desc": "이미지 생성",
|
||||
"title": "불러오기"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"desc": "현재 이미지를 이미지로 보내기"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"desc": "mask/base layer 선택 전환",
|
||||
"title": "Layer 전환"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "브러시 크기 증가",
|
||||
"desc": "캔버스 브러시/지우개 크기 증가"
|
||||
},
|
||||
"appHotkeys": "App Hotkeys",
|
||||
"deleteImage": {
|
||||
"title": "이미지 삭제",
|
||||
"desc": "현재 이미지 삭제"
|
||||
},
|
||||
"moveTool": {
|
||||
"desc": "캔버스 탐색 허용",
|
||||
"title": "툴 옮기기"
|
||||
},
|
||||
"clearMask": {
|
||||
"desc": "전체 mask 제거",
|
||||
"title": "Mask 제거"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "갤러리 이미지 크기 증가",
|
||||
"desc": "갤러리 미리 보기 크기를 늘립니다"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"desc": "캔버스 브러시의 불투명도를 높입니다",
|
||||
"title": "브러시 불투명도 증가"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"desc": "프롬프트 입력 영역에 초점을 맞춥니다",
|
||||
"title": "프롬프트에 초점 맞추기"
|
||||
},
|
||||
"decreaseBrushOpacity": {
|
||||
"desc": "캔버스 브러시의 불투명도를 줄입니다",
|
||||
"title": "브러시 불투명도 감소"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"desc": "다음 스테이징 영역 이미지",
|
||||
"title": "다음 스테이징 이미지"
|
||||
},
|
||||
"redoStroke": {
|
||||
"title": "Stroke 다시 실행",
|
||||
"desc": "brush stroke 다시 실행"
|
||||
},
|
||||
"nodesHotkeys": "Nodes Hotkeys",
|
||||
"addNodes": {
|
||||
"desc": "노드 추가 메뉴 열기",
|
||||
"title": "노드 추가"
|
||||
},
|
||||
"undoStroke": {
|
||||
"title": "Stroke 실행 취소",
|
||||
"desc": "brush stroke 실행 취소"
|
||||
},
|
||||
"changeTabs": {
|
||||
"desc": "다른 workspace으로 전환",
|
||||
"title": "탭 바꾸기"
|
||||
},
|
||||
"mergeVisible": {
|
||||
"desc": "캔버스의 보이는 모든 레이어 병합"
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"missingTemplate": "잘못된 노드: {{type}} 유형의 {{node}} 템플릿 누락(설치되지 않으셨나요?)",
|
||||
"noNodeSelected": "선택한 노드 없음",
|
||||
@@ -451,7 +172,6 @@
|
||||
"downloadWorkflow": "Workflow JSON 다운로드",
|
||||
"ipAdapter": "IP-Adapter",
|
||||
"noConnectionInProgress": "진행중인 연결이 없습니다",
|
||||
"noConnectionData": "연결 데이터 없음",
|
||||
"fieldTypesMustMatch": "필드 유형은 일치해야 합니다",
|
||||
"edge": "Edge",
|
||||
"sourceNodeFieldDoesNotExist": "잘못된 모서리: 소스/출력 필드 {{node}}. {{field}}이(가) 없습니다",
|
||||
@@ -461,10 +181,8 @@
|
||||
"fullyContainNodesHelp": "선택하려면 노드가 선택 상자 안에 완전히 있어야 합니다",
|
||||
"nodePack": "Node pack",
|
||||
"nodeType": "노드 유형",
|
||||
"noMatchingNodes": "일치하는 노드 없음",
|
||||
"fullyContainNodes": "선택할 노드 전체 포함",
|
||||
"executionStateInProgress": "진행중",
|
||||
"noFieldType": "필드 유형 없음",
|
||||
"executionStateError": "에러",
|
||||
"boolean": "Booleans",
|
||||
"hideMinimapnodes": "미니맵 숨기기",
|
||||
@@ -551,7 +269,6 @@
|
||||
"model": "모델",
|
||||
"noImageDetails": "이미지 세부 정보를 찾을 수 없습니다",
|
||||
"cfgScale": "CFG scale",
|
||||
"initImage": "초기이미지",
|
||||
"recallParameters": "매개변수 호출",
|
||||
"height": "Height",
|
||||
"noMetaData": "metadata를 찾을 수 없습니다",
|
||||
@@ -593,7 +310,6 @@
|
||||
},
|
||||
"models": {
|
||||
"noMatchingModels": "일치하는 모델 없음",
|
||||
"esrganModel": "ESRGAN 모델",
|
||||
"loading": "로딩중",
|
||||
"noMatchingLoRAs": "일치하는 LoRA 없음",
|
||||
"noModelsAvailable": "사용 가능한 모델이 없음",
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"reportBugLabel": "Meld bug",
|
||||
"settingsLabel": "Instellingen",
|
||||
"img2img": "Afbeelding naar afbeelding",
|
||||
"unifiedCanvas": "Centraal canvas",
|
||||
"nodes": "Werkstromen",
|
||||
"upload": "Upload",
|
||||
"load": "Laad",
|
||||
@@ -28,7 +27,6 @@
|
||||
"communityLabel": "Gemeenschap",
|
||||
"t2iAdapter": "T2I-adapter",
|
||||
"on": "Aan",
|
||||
"nodeEditor": "Knooppunteditor",
|
||||
"ipAdapter": "IP-adapter",
|
||||
"auto": "Autom.",
|
||||
"controlNet": "ControlNet",
|
||||
@@ -55,7 +53,6 @@
|
||||
"goTo": "Ga naar",
|
||||
"template": "Sjabloon",
|
||||
"input": "Invoer",
|
||||
"loglevel": "Logboekniveau",
|
||||
"safetensors": "Safetensors",
|
||||
"saveAs": "Bewaar als",
|
||||
"created": "Gemaakt",
|
||||
@@ -76,10 +73,6 @@
|
||||
"or": "of",
|
||||
"updated": "Bijgewerkt",
|
||||
"outpaint": "outpainten",
|
||||
"viewing": "Bekijken",
|
||||
"viewingDesc": "Beoordeel afbeelding in een grote galerijweergave",
|
||||
"editing": "Bewerken",
|
||||
"editingDesc": "Bewerk op het canvas Stuurlagen",
|
||||
"ai": "ai",
|
||||
"inpaint": "inpainten",
|
||||
"unknown": "Onbekend",
|
||||
@@ -93,7 +86,6 @@
|
||||
"galleryImageSize": "Afbeeldingsgrootte",
|
||||
"gallerySettings": "Instellingen galerij",
|
||||
"autoSwitchNewImages": "Wissel autom. naar nieuwe afbeeldingen",
|
||||
"loadMore": "Laad meer",
|
||||
"noImagesInGallery": "Geen afbeeldingen om te tonen",
|
||||
"deleteImage_one": "Verwijder afbeelding",
|
||||
"deleteImage_other": "",
|
||||
@@ -106,208 +98,7 @@
|
||||
"downloadSelection": "Download selectie",
|
||||
"currentlyInUse": "Deze afbeelding is momenteel in gebruik door de volgende functies:",
|
||||
"copy": "Kopieer",
|
||||
"download": "Download",
|
||||
"setCurrentImage": "Stel in als huidige afbeelding"
|
||||
},
|
||||
"hotkeys": {
|
||||
"keyboardShortcuts": "Sneltoetsen",
|
||||
"appHotkeys": "Appsneltoetsen",
|
||||
"generalHotkeys": "Algemene sneltoetsen",
|
||||
"galleryHotkeys": "Sneltoetsen galerij",
|
||||
"unifiedCanvasHotkeys": "Sneltoetsen centraal canvas",
|
||||
"invoke": {
|
||||
"title": "Genereer",
|
||||
"desc": "Genereert een afbeelding"
|
||||
},
|
||||
"cancel": {
|
||||
"title": "Annuleer",
|
||||
"desc": "Annuleert het genereren van een afbeelding"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"title": "Focus op invoer",
|
||||
"desc": "Legt de focus op het invoertekstvak"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"title": "Open/sluit Opties",
|
||||
"desc": "Opent of sluit het deelscherm Opties"
|
||||
},
|
||||
"pinOptions": {
|
||||
"title": "Zet Opties vast",
|
||||
"desc": "Zet het deelscherm Opties vast"
|
||||
},
|
||||
"toggleGallery": {
|
||||
"title": "Zet Galerij vast",
|
||||
"desc": "Opent of sluit het deelscherm Galerij"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"title": "Maximaliseer werkgebied",
|
||||
"desc": "Sluit deelschermen en maximaliseer het werkgebied"
|
||||
},
|
||||
"changeTabs": {
|
||||
"title": "Wissel van tabblad",
|
||||
"desc": "Wissel naar een ander werkgebied"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"title": "Open/sluit console",
|
||||
"desc": "Opent of sluit de console"
|
||||
},
|
||||
"setPrompt": {
|
||||
"title": "Stel invoertekst in",
|
||||
"desc": "Gebruikt de invoertekst van de huidige afbeelding"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "Stel seed in",
|
||||
"desc": "Gebruikt de seed van de huidige afbeelding"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "Stel parameters in",
|
||||
"desc": "Gebruikt alle parameters van de huidige afbeelding"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "Herstel gezichten",
|
||||
"desc": "Herstelt de huidige afbeelding"
|
||||
},
|
||||
"showInfo": {
|
||||
"title": "Toon info",
|
||||
"desc": "Toont de metagegevens van de huidige afbeelding"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"title": "Stuur naar Afbeelding naar afbeelding",
|
||||
"desc": "Stuurt de huidige afbeelding naar Afbeelding naar afbeelding"
|
||||
},
|
||||
"deleteImage": {
|
||||
"title": "Verwijder afbeelding",
|
||||
"desc": "Verwijdert de huidige afbeelding"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "Sluit deelschermen",
|
||||
"desc": "Sluit geopende deelschermen"
|
||||
},
|
||||
"previousImage": {
|
||||
"title": "Vorige afbeelding",
|
||||
"desc": "Toont de vorige afbeelding in de galerij"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "Volgende afbeelding",
|
||||
"desc": "Toont de volgende afbeelding in de galerij"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "Vergroot afbeeldingsgrootte galerij",
|
||||
"desc": "Vergroot de grootte van de galerijminiaturen"
|
||||
},
|
||||
"decreaseGalleryThumbSize": {
|
||||
"title": "Verklein afbeeldingsgrootte galerij",
|
||||
"desc": "Verkleint de grootte van de galerijminiaturen"
|
||||
},
|
||||
"selectBrush": {
|
||||
"title": "Kies penseel",
|
||||
"desc": "Kiest de penseel op het canvas"
|
||||
},
|
||||
"selectEraser": {
|
||||
"title": "Kies gum",
|
||||
"desc": "Kiest de gum op het canvas"
|
||||
},
|
||||
"decreaseBrushSize": {
|
||||
"title": "Verklein penseelgrootte",
|
||||
"desc": "Verkleint de grootte van het penseel/gum op het canvas"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "Vergroot penseelgrootte",
|
||||
"desc": "Vergroot de grootte van het penseel/gum op het canvas"
|
||||
},
|
||||
"decreaseBrushOpacity": {
|
||||
"title": "Verlaag ondoorzichtigheid penseel",
|
||||
"desc": "Verlaagt de ondoorzichtigheid van de penseel op het canvas"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"title": "Verhoog ondoorzichtigheid penseel",
|
||||
"desc": "Verhoogt de ondoorzichtigheid van de penseel op het canvas"
|
||||
},
|
||||
"moveTool": {
|
||||
"title": "Verplaats canvas",
|
||||
"desc": "Maakt canvasnavigatie mogelijk"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "Vul tekenvak",
|
||||
"desc": "Vult het tekenvak met de penseelkleur"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"title": "Wis tekenvak",
|
||||
"desc": "Wist het gebied van het tekenvak"
|
||||
},
|
||||
"colorPicker": {
|
||||
"title": "Kleurkiezer",
|
||||
"desc": "Opent de kleurkiezer op het canvas"
|
||||
},
|
||||
"toggleSnap": {
|
||||
"title": "Zet uitlijnen aan/uit",
|
||||
"desc": "Zet uitlijnen op raster aan/uit"
|
||||
},
|
||||
"quickToggleMove": {
|
||||
"title": "Verplaats canvas even",
|
||||
"desc": "Verplaats kortstondig het canvas"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"title": "Zet laag aan/uit",
|
||||
"desc": "Wisselt tussen de masker- en basislaag"
|
||||
},
|
||||
"clearMask": {
|
||||
"title": "Wis masker",
|
||||
"desc": "Wist het volledig masker"
|
||||
},
|
||||
"hideMask": {
|
||||
"title": "Toon/verberg masker",
|
||||
"desc": "Toont of verbegt het masker"
|
||||
},
|
||||
"showHideBoundingBox": {
|
||||
"title": "Toon/verberg tekenvak",
|
||||
"desc": "Wisselt de zichtbaarheid van het tekenvak"
|
||||
},
|
||||
"mergeVisible": {
|
||||
"title": "Voeg lagen samen",
|
||||
"desc": "Voegt alle zichtbare lagen op het canvas samen"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "Bewaar in galerij",
|
||||
"desc": "Bewaart het huidige canvas in de galerij"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "Kopieer naar klembord",
|
||||
"desc": "Kopieert het huidige canvas op het klembord"
|
||||
},
|
||||
"downloadImage": {
|
||||
"title": "Download afbeelding",
|
||||
"desc": "Downloadt het huidige canvas"
|
||||
},
|
||||
"undoStroke": {
|
||||
"title": "Maak streek ongedaan",
|
||||
"desc": "Maakt een penseelstreek ongedaan"
|
||||
},
|
||||
"redoStroke": {
|
||||
"title": "Herhaal streek",
|
||||
"desc": "Voert een ongedaan gemaakte penseelstreek opnieuw uit"
|
||||
},
|
||||
"resetView": {
|
||||
"title": "Herstel weergave",
|
||||
"desc": "Herstelt de canvasweergave"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"title": "Vorige sessie-afbeelding",
|
||||
"desc": "Bladert terug naar de vorige afbeelding in het sessiegebied"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"title": "Volgende sessie-afbeelding",
|
||||
"desc": "Bladert vooruit naar de volgende afbeelding in het sessiegebied"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"title": "Accepteer sessie-afbeelding",
|
||||
"desc": "Accepteert de huidige sessie-afbeelding"
|
||||
},
|
||||
"addNodes": {
|
||||
"title": "Voeg knooppunten toe",
|
||||
"desc": "Opent het menu Voeg knooppunt toe"
|
||||
},
|
||||
"nodesHotkeys": "Sneltoetsen knooppunten"
|
||||
"download": "Download"
|
||||
},
|
||||
"modelManager": {
|
||||
"modelManager": "Modelonderhoud",
|
||||
@@ -342,8 +133,6 @@
|
||||
"convertToDiffusersHelpText5": "Zorg ervoor dat je genoeg schijfruimte hebt. Modellen nemen gewoonlijk ongeveer 2 tot 7 GB ruimte in beslag.",
|
||||
"modelConverted": "Model omgezet",
|
||||
"alpha": "Alfa",
|
||||
"v2_base": "v2 (512px)",
|
||||
"v2_768": "v2 (768px)",
|
||||
"none": "geen",
|
||||
"baseModel": "Basismodel",
|
||||
"vae": "VAE",
|
||||
@@ -354,8 +143,6 @@
|
||||
"settings": "Instellingen",
|
||||
"modelDeleted": "Model verwijderd",
|
||||
"syncModels": "Synchroniseer Modellen",
|
||||
"modelsSynced": "Modellen Gesynchroniseerd",
|
||||
"modelSyncFailed": "Synchronisatie modellen mislukt",
|
||||
"modelDeleteFailed": "Model kon niet verwijderd worden",
|
||||
"convertingModelBegin": "Model aan het converteren. Even geduld.",
|
||||
"predictionType": "Soort voorspelling",
|
||||
@@ -414,8 +201,6 @@
|
||||
"scaledHeight": "Geschaalde H",
|
||||
"infillMethod": "Infill-methode",
|
||||
"tileSize": "Grootte tegel",
|
||||
"sendToImg2Img": "Stuur naar Afbeelding naar afbeelding",
|
||||
"sendToUnifiedCanvas": "Stuur naar Centraal canvas",
|
||||
"downloadImage": "Download afbeelding",
|
||||
"usePrompt": "Hergebruik invoertekst",
|
||||
"useSeed": "Hergebruik seed",
|
||||
@@ -442,29 +227,20 @@
|
||||
"noModelSelected": "Geen model ingesteld",
|
||||
"invoke": "Start",
|
||||
"noPrompts": "Geen prompts gegenereerd",
|
||||
"noInitialImageSelected": "Geen initiële afbeelding gekozen",
|
||||
"missingInputForField": "{{nodeLabel}} -> {{fieldLabel}} invoer ontbreekt",
|
||||
"noControlImageForControlAdapter": "Controle-adapter #{{number}} heeft geen controle-afbeelding",
|
||||
"noModelForControlAdapter": "Control-adapter #{{number}} heeft geen model ingesteld staan.",
|
||||
"incompatibleBaseModelForControlAdapter": "Model van controle-adapter #{{number}} is niet compatibel met het hoofdmodel.",
|
||||
"systemDisconnected": "Systeem is niet verbonden",
|
||||
"missingNodeTemplate": "Knooppuntsjabloon ontbreekt",
|
||||
"missingFieldTemplate": "Veldsjabloon ontbreekt",
|
||||
"addingImagesTo": "Bezig met toevoegen van afbeeldingen aan",
|
||||
"layer": {
|
||||
"initialImageNoImageSelected": "geen initiële afbeelding geselecteerd",
|
||||
"controlAdapterNoModelSelected": "geen controle-adaptermodel geselecteerd",
|
||||
"controlAdapterIncompatibleBaseModel": "niet-compatibele basismodel voor controle-adapter",
|
||||
"controlAdapterNoImageSelected": "geen afbeelding voor controle-adapter geselecteerd",
|
||||
"controlAdapterImageNotProcessed": "Afbeelding voor controle-adapter niet verwerkt",
|
||||
"ipAdapterIncompatibleBaseModel": "niet-compatibele basismodel voor IP-adapter",
|
||||
"ipAdapterNoImageSelected": "geen afbeelding voor IP-adapter geselecteerd",
|
||||
"rgNoRegion": "geen gebied geselecteerd",
|
||||
"rgNoPromptsOrIPAdapters": "geen tekstprompts of IP-adapters",
|
||||
"t2iAdapterIncompatibleDimensions": "T2I-adapter vereist een afbeelding met afmetingen met een veelvoud van 64",
|
||||
"ipAdapterNoModelSelected": "geen IP-adapter geselecteerd"
|
||||
},
|
||||
"imageNotProcessedForControlAdapter": "De afbeelding van controle-adapter #{{number}} is niet verwerkt"
|
||||
}
|
||||
},
|
||||
"patchmatchDownScaleSize": "Verklein",
|
||||
"useCpuNoise": "Gebruik CPU-ruis",
|
||||
@@ -476,31 +252,22 @@
|
||||
"setToOptimalSize": "Optimaliseer grootte voor het model",
|
||||
"setToOptimalSizeTooSmall": "$t(parameters.setToOptimalSize) (is mogelijk te klein)",
|
||||
"aspect": "Beeldverhouding",
|
||||
"infillMosaicTileWidth": "Breedte tegel",
|
||||
"setToOptimalSizeTooLarge": "$t(parameters.setToOptimalSize) (is mogelijk te groot)",
|
||||
"lockAspectRatio": "Zet beeldverhouding vast",
|
||||
"infillMosaicTileHeight": "Hoogte tegel",
|
||||
"globalNegativePromptPlaceholder": "Globale negatieve prompt",
|
||||
"globalPositivePromptPlaceholder": "Globale positieve prompt",
|
||||
"useSize": "Gebruik grootte",
|
||||
"swapDimensions": "Wissel afmetingen om",
|
||||
"globalSettings": "Globale instellingen",
|
||||
"coherenceEdgeSize": "Randgrootte",
|
||||
"coherenceMinDenoise": "Min. ontruising",
|
||||
"infillMosaicMinColor": "Min. kleur",
|
||||
"infillMosaicMaxColor": "Max. kleur",
|
||||
"cfgRescaleMultiplier": "Vermenigvuldiger voor CFG-herschaling"
|
||||
},
|
||||
"settings": {
|
||||
"models": "Modellen",
|
||||
"displayInProgress": "Toon voortgangsafbeeldingen",
|
||||
"confirmOnDelete": "Bevestig bij verwijderen",
|
||||
"enableImageDebugging": "Schakel foutopsporing afbeelding in",
|
||||
"resetWebUI": "Herstel web-UI",
|
||||
"resetWebUIDesc1": "Herstel web-UI herstelt alleen de lokale afbeeldingscache en de onthouden instellingen van je browser. Het verwijdert geen afbeeldingen van schijf.",
|
||||
"resetWebUIDesc2": "Als afbeeldingen niet getoond worden in de galerij of iets anders werkt niet, probeer dan eerst deze herstelfunctie voordat je een fout aanmeldt op GitHub.",
|
||||
"resetComplete": "Webinterface is hersteld.",
|
||||
"shouldLogToConsole": "Schrijf logboek naar console",
|
||||
"developer": "Ontwikkelaar",
|
||||
"general": "Algemeen",
|
||||
"showProgressInViewer": "Toon voortgangsafbeeldingen in viewer",
|
||||
@@ -526,12 +293,7 @@
|
||||
"toast": {
|
||||
"uploadFailed": "Upload mislukt",
|
||||
"imageCopied": "Afbeelding gekopieerd",
|
||||
"imageNotLoadedDesc": "Geen afbeeldingen gevonden",
|
||||
"canvasMerged": "Canvas samengevoegd",
|
||||
"sentToImageToImage": "Gestuurd naar Afbeelding naar afbeelding",
|
||||
"sentToUnifiedCanvas": "Gestuurd naar Centraal canvas",
|
||||
"parametersNotSet": "Parameters niet ingesteld",
|
||||
"metadataLoadFailed": "Fout bij laden metagegevens",
|
||||
"serverError": "Serverfout",
|
||||
"connected": "Verbonden met server",
|
||||
"canceled": "Verwerking geannuleerd",
|
||||
@@ -541,110 +303,22 @@
|
||||
"problemCopyingImage": "Kan Afbeelding Niet Kopiëren",
|
||||
"baseModelChangedCleared_one": "Basismodel is gewijzigd: {{count}} niet-compatibel submodel weggehaald of uitgeschakeld",
|
||||
"baseModelChangedCleared_other": "Basismodel is gewijzigd: {{count}} niet-compatibele submodellen weggehaald of uitgeschakeld",
|
||||
"imageSavingFailed": "Fout bij bewaren afbeelding",
|
||||
"canvasSentControlnetAssets": "Canvas gestuurd naar ControlNet en Assets",
|
||||
"problemCopyingCanvasDesc": "Kan basislaag niet exporteren",
|
||||
"loadedWithWarnings": "Werkstroom geladen met waarschuwingen",
|
||||
"setInitialImage": "Ingesteld als initiële afbeelding",
|
||||
"canvasCopiedClipboard": "Canvas gekopieerd naar klembord",
|
||||
"setControlImage": "Ingesteld als controle-afbeelding",
|
||||
"setNodeField": "Ingesteld als knooppuntveld",
|
||||
"problemSavingMask": "Fout bij bewaren masker",
|
||||
"problemSavingCanvasDesc": "Kan basislaag niet exporteren",
|
||||
"maskSavedAssets": "Masker bewaard in Assets",
|
||||
"problemDownloadingCanvas": "Fout bij downloaden van canvas",
|
||||
"problemMergingCanvas": "Fout bij samenvoegen canvas",
|
||||
"setCanvasInitialImage": "Initiële canvasafbeelding ingesteld",
|
||||
"imageUploaded": "Afbeelding geüpload",
|
||||
"addedToBoard": "Toegevoegd aan bord",
|
||||
"workflowLoaded": "Werkstroom geladen",
|
||||
"modelAddedSimple": "Model toegevoegd aan wachtrij",
|
||||
"problemImportingMaskDesc": "Kan masker niet exporteren",
|
||||
"problemCopyingCanvas": "Fout bij kopiëren canvas",
|
||||
"problemSavingCanvas": "Fout bij bewaren canvas",
|
||||
"canvasDownloaded": "Canvas gedownload",
|
||||
"problemMergingCanvasDesc": "Kan basislaag niet exporteren",
|
||||
"problemDownloadingCanvasDesc": "Kan basislaag niet exporteren",
|
||||
"problemSavingMaskDesc": "Kan masker niet exporteren",
|
||||
"imageSaved": "Afbeelding bewaard",
|
||||
"maskSentControlnetAssets": "Masker gestuurd naar ControlNet en Assets",
|
||||
"canvasSavedGallery": "Canvas bewaard in galerij",
|
||||
"imageUploadFailed": "Fout bij uploaden afbeelding",
|
||||
"problemImportingMask": "Fout bij importeren masker",
|
||||
"workflowDeleted": "Werkstroom verwijderd",
|
||||
"invalidUpload": "Ongeldige upload",
|
||||
"uploadInitialImage": "Initiële afbeelding uploaden",
|
||||
"setAsCanvasInitialImage": "Ingesteld als initiële afbeelding voor canvas",
|
||||
"problemRetrievingWorkflow": "Fout bij ophalen van werkstroom",
|
||||
"parameters": "Parameters",
|
||||
"modelImportCanceled": "Importeren model geannuleerd",
|
||||
"problemDeletingWorkflow": "Fout bij verwijderen van werkstroom",
|
||||
"prunedQueue": "Wachtrij gesnoeid",
|
||||
"problemDownloadingImage": "Fout bij downloaden afbeelding",
|
||||
"resetInitialImage": "Initiële afbeelding hersteld"
|
||||
},
|
||||
"tooltip": {
|
||||
"feature": {
|
||||
"prompt": "Dit is het invoertekstvak. De invoertekst bevat de te genereren voorwerpen en stylistische termen. Je kunt hiernaast in de invoertekst ook het gewicht (het belang van een trefwoord) toekennen. Opdrachten en parameters voor op de opdrachtregelinterface werken hier niet.",
|
||||
"gallery": "De galerij toont gegenereerde afbeeldingen uit de uitvoermap nadat ze gegenereerd zijn. Instellingen worden opgeslagen binnen de bestanden zelf en zijn toegankelijk via het contextmenu.",
|
||||
"other": "Deze opties maken alternative werkingsstanden voor Invoke mogelijk. De optie 'Naadloze tegels' maakt herhalende patronen in de uitvoer. 'Hoge resolutie' genereert in twee stappen via Afbeelding naar afbeelding: gebruik dit als je een grotere en coherentere afbeelding wilt zonder artifacten. Dit zal meer tijd in beslag nemen t.o.v. Tekst naar afbeelding.",
|
||||
"seed": "Seedwaarden hebben invloed op de initiële ruis op basis waarvan de afbeelding wordt gevormd. Je kunt de al bestaande seeds van eerdere afbeeldingen gebruiken. De waarde 'Drempelwaarde ruis' wordt gebruikt om de hoeveelheid artifacten te verkleinen bij hoge CFG-waarden (beperk je tot 0 - 10). De Perlinruiswaarde wordt gebruikt om Perlinruis toe te voegen bij het genereren: beide dienen als variatie op de uitvoer.",
|
||||
"upscale": "Gebruik ESRGAN om de afbeelding direct na het genereren te vergroten.",
|
||||
"boundingBox": "Het tekenvak is gelijk aan de instellingen Breedte en Hoogte voor de functies Tekst naar afbeelding en Afbeelding naar afbeelding. Alleen het gebied in het tekenvak wordt verwerkt."
|
||||
}
|
||||
},
|
||||
"unifiedCanvas": {
|
||||
"layer": "Laag",
|
||||
"base": "Basis",
|
||||
"mask": "Masker",
|
||||
"maskingOptions": "Maskeropties",
|
||||
"enableMask": "Schakel masker in",
|
||||
"preserveMaskedArea": "Behoud gemaskeerd gebied",
|
||||
"clearMask": "Wis masker",
|
||||
"brush": "Penseel",
|
||||
"eraser": "Gum",
|
||||
"fillBoundingBox": "Vul tekenvak",
|
||||
"eraseBoundingBox": "Wis tekenvak",
|
||||
"colorPicker": "Kleurenkiezer",
|
||||
"brushOptions": "Penseelopties",
|
||||
"brushSize": "Grootte",
|
||||
"move": "Verplaats",
|
||||
"resetView": "Herstel weergave",
|
||||
"mergeVisible": "Voeg lagen samen",
|
||||
"saveToGallery": "Bewaar in galerij",
|
||||
"copyToClipboard": "Kopieer naar klembord",
|
||||
"downloadAsImage": "Download als afbeelding",
|
||||
"undo": "Maak ongedaan",
|
||||
"redo": "Herhaal",
|
||||
"clearCanvas": "Wis canvas",
|
||||
"canvasSettings": "Canvasinstellingen",
|
||||
"showIntermediates": "Toon tussenafbeeldingen",
|
||||
"showGrid": "Toon raster",
|
||||
"snapToGrid": "Lijn uit op raster",
|
||||
"darkenOutsideSelection": "Verduister buiten selectie",
|
||||
"autoSaveToGallery": "Bewaar automatisch naar galerij",
|
||||
"saveBoxRegionOnly": "Bewaar alleen tekengebied",
|
||||
"limitStrokesToBox": "Beperk streken tot tekenvak",
|
||||
"showCanvasDebugInfo": "Toon aanvullende canvasgegevens",
|
||||
"clearCanvasHistory": "Wis canvasgeschiedenis",
|
||||
"clearHistory": "Wis geschiedenis",
|
||||
"clearCanvasHistoryMessage": "Het wissen van de canvasgeschiedenis laat het huidige canvas ongemoeid, maar wist onherstelbaar de geschiedenis voor het ongedaan maken en herhalen.",
|
||||
"clearCanvasHistoryConfirm": "Weet je zeker dat je de canvasgeschiedenis wilt wissen?",
|
||||
"activeLayer": "Actieve laag",
|
||||
"canvasScale": "Schaal canvas",
|
||||
"boundingBox": "Tekenvak",
|
||||
"scaledBoundingBox": "Geschaalde tekenvak",
|
||||
"boundingBoxPosition": "Positie tekenvak",
|
||||
"canvasDimensions": "Afmetingen canvas",
|
||||
"canvasPosition": "Positie canvas",
|
||||
"cursorPosition": "Positie cursor",
|
||||
"previous": "Vorige",
|
||||
"next": "Volgende",
|
||||
"accept": "Accepteer",
|
||||
"discardAll": "Gooi alles weg",
|
||||
"antialiasing": "Anti-aliasing",
|
||||
"showResultsOn": "Toon resultaten (aan)",
|
||||
"showResultsOff": "Toon resultaten (uit)"
|
||||
"problemDownloadingImage": "Fout bij downloaden afbeelding"
|
||||
},
|
||||
"accessibility": {
|
||||
"invokeProgressBar": "Voortgangsbalk Invoke",
|
||||
@@ -655,7 +329,6 @@
|
||||
"showOptionsPanel": "Toon zijscherm",
|
||||
"menu": "Menu",
|
||||
"showGalleryPanel": "Toon deelscherm Galerij",
|
||||
"loadMore": "Laad meer",
|
||||
"about": "Over",
|
||||
"mode": "Modus",
|
||||
"resetUI": "$t(accessibility.reset) UI",
|
||||
@@ -705,7 +378,6 @@
|
||||
"ipAdapter": "IP-adapter",
|
||||
"noConnectionInProgress": "Geen verbinding bezig te maken",
|
||||
"workflowVersion": "Versie",
|
||||
"noConnectionData": "Geen verbindingsgegevens",
|
||||
"fieldTypesMustMatch": "Veldsoorten moeten overeenkomen",
|
||||
"workflow": "Werkstroom",
|
||||
"edge": "Rand",
|
||||
@@ -718,10 +390,8 @@
|
||||
"fullyContainNodesHelp": "Knooppunten moeten zich volledig binnen het keuzevak bevinden om te worden gekozen",
|
||||
"workflowValidation": "Validatiefout werkstroom",
|
||||
"nodeType": "Soort knooppunt",
|
||||
"noMatchingNodes": "Geen overeenkomende knooppunten",
|
||||
"fullyContainNodes": "Omvat knooppunten volledig om ze te kiezen",
|
||||
"executionStateInProgress": "Bezig",
|
||||
"noFieldType": "Geen soort veld",
|
||||
"executionStateError": "Fout",
|
||||
"boolean": "Booleaanse waarden",
|
||||
"executionStateCompleted": "Voltooid",
|
||||
@@ -791,100 +461,6 @@
|
||||
"unableToUpdateNodes_one": "Fout bij bijwerken van {{count}} knooppunt",
|
||||
"unableToUpdateNodes_other": "Fout bij bijwerken van {{count}} knooppunten"
|
||||
},
|
||||
"controlnet": {
|
||||
"amult": "a_mult",
|
||||
"resize": "Schaal",
|
||||
"showAdvanced": "Toon uitgebreide opties",
|
||||
"contentShuffleDescription": "Verschuift het materiaal in de afbeelding",
|
||||
"bgth": "bg_th",
|
||||
"addT2IAdapter": "Voeg $t(common.t2iAdapter) toe",
|
||||
"pidi": "PIDI",
|
||||
"importImageFromCanvas": "Importeer afbeelding uit canvas",
|
||||
"lineartDescription": "Zet afbeelding om naar line-art",
|
||||
"normalBae": "Normale BAE",
|
||||
"importMaskFromCanvas": "Importeer masker uit canvas",
|
||||
"hed": "HED",
|
||||
"hideAdvanced": "Verberg uitgebreid",
|
||||
"contentShuffle": "Verschuif materiaal",
|
||||
"resetControlImage": "Herstel controle-afbeelding",
|
||||
"beginEndStepPercent": "Percentage begin-/eindstap",
|
||||
"mlsdDescription": "Minimalistische herkenning lijnsegmenten",
|
||||
"duplicate": "Maak kopie",
|
||||
"balanced": "Gebalanceerd",
|
||||
"f": "F",
|
||||
"h": "H",
|
||||
"prompt": "Prompt",
|
||||
"depthMidasDescription": "Genereer diepteblad via Midas",
|
||||
"controlnet": "$t(controlnet.controlAdapter_one) #{{number}} ($t(common.controlNet))",
|
||||
"control": "Controle",
|
||||
"resizeMode": "Modus schaling",
|
||||
"coarse": "Grof",
|
||||
"weight": "Gewicht",
|
||||
"selectModel": "Kies een model",
|
||||
"crop": "Snij bij",
|
||||
"depthMidas": "Diepte (Midas)",
|
||||
"w": "B",
|
||||
"processor": "Verwerker",
|
||||
"addControlNet": "Voeg $t(common.controlNet) toe",
|
||||
"none": "Geen",
|
||||
"detectResolution": "Herken resolutie",
|
||||
"ip_adapter": "$t(controlnet.controlAdapter_one) #{{number}} ($t(common.ipAdapter))",
|
||||
"pidiDescription": "PIDI-afbeeldingsverwerking",
|
||||
"mediapipeFace": "Mediapipe - Gezicht",
|
||||
"mlsd": "M-LSD",
|
||||
"controlMode": "Controlemodus",
|
||||
"fill": "Vul",
|
||||
"cannyDescription": "Herkenning Canny-rand",
|
||||
"addIPAdapter": "Voeg $t(common.ipAdapter) toe",
|
||||
"lineart": "Line-art",
|
||||
"colorMapDescription": "Genereert een kleurenblad van de afbeelding",
|
||||
"lineartAnimeDescription": "Lineartverwerking in anime-stijl",
|
||||
"t2i_adapter": "$t(controlnet.controlAdapter_one) #{{number}} ($t(common.t2iAdapter))",
|
||||
"minConfidence": "Min. vertrouwensniveau",
|
||||
"imageResolution": "Resolutie afbeelding",
|
||||
"megaControl": "Zeer veel controle",
|
||||
"depthZoe": "Diepte (Zoe)",
|
||||
"colorMap": "Kleur",
|
||||
"lowThreshold": "Lage drempelwaarde",
|
||||
"autoConfigure": "Configureer verwerker automatisch",
|
||||
"highThreshold": "Hoge drempelwaarde",
|
||||
"normalBaeDescription": "Normale BAE-verwerking",
|
||||
"noneDescription": "Geen verwerking toegepast",
|
||||
"saveControlImage": "Bewaar controle-afbeelding",
|
||||
"toggleControlNet": "Zet deze ControlNet aan/uit",
|
||||
"delete": "Verwijder",
|
||||
"controlAdapter_one": "Control-adapter",
|
||||
"controlAdapter_other": "Control-adapters",
|
||||
"safe": "Veilig",
|
||||
"colorMapTileSize": "Grootte tegel",
|
||||
"lineartAnime": "Line-art voor anime",
|
||||
"mediapipeFaceDescription": "Gezichtsherkenning met Mediapipe",
|
||||
"canny": "Canny",
|
||||
"depthZoeDescription": "Genereer diepteblad via Zoe",
|
||||
"hedDescription": "Herkenning van holistisch-geneste randen",
|
||||
"setControlImageDimensions": "Kopieer grootte naar B/H (optimaliseer voor model)",
|
||||
"scribble": "Krabbel",
|
||||
"maxFaces": "Max. gezichten",
|
||||
"dwOpenpose": "DW Openpose",
|
||||
"depthAnything": "Depth Anything",
|
||||
"base": "Basis",
|
||||
"hands": "Handen",
|
||||
"selectCLIPVisionModel": "Selecteer een CLIP Vision-model",
|
||||
"modelSize": "Modelgrootte",
|
||||
"small": "Klein",
|
||||
"large": "Groot",
|
||||
"resizeSimple": "Wijzig grootte (eenvoudig)",
|
||||
"beginEndStepPercentShort": "Begin-/eind-%",
|
||||
"depthAnythingDescription": "Genereren dieptekaart d.m.v. de techniek Depth Anything",
|
||||
"face": "Gezicht",
|
||||
"body": "Lichaam",
|
||||
"dwOpenposeDescription": "Schatting menselijke pose d.m.v. DW Openpose",
|
||||
"ipAdapterMethod": "Methode",
|
||||
"full": "Volledig",
|
||||
"style": "Alleen stijl",
|
||||
"composition": "Alleen samenstelling",
|
||||
"setControlImageDimensionsForce": "Kopieer grootte naar B/H (negeer model)"
|
||||
},
|
||||
"dynamicPrompts": {
|
||||
"seedBehaviour": {
|
||||
"perPromptDesc": "Gebruik een verschillende seedwaarde per afbeelding",
|
||||
@@ -894,8 +470,6 @@
|
||||
"label": "Gedrag seedwaarde"
|
||||
},
|
||||
"maxPrompts": "Max. prompts",
|
||||
"promptsWithCount_one": "{{count}} prompt",
|
||||
"promptsWithCount_other": "{{count}} prompts",
|
||||
"dynamicPrompts": "Dynamische prompts",
|
||||
"showDynamicPrompts": "Toon dynamische prompts",
|
||||
"loading": "Genereren van dynamische prompts...",
|
||||
@@ -1106,8 +680,6 @@
|
||||
"model": "Model",
|
||||
"noImageDetails": "Geen afbeeldingsdetails gevonden",
|
||||
"cfgScale": "CFG-schaal",
|
||||
"fit": "Schaal aanpassen in Afbeelding naar afbeelding",
|
||||
"initImage": "Initiële afbeelding",
|
||||
"recallParameters": "Opnieuw aan te roepen parameters",
|
||||
"height": "Hoogte",
|
||||
"noMetaData": "Geen metagegevens gevonden",
|
||||
@@ -1201,7 +773,6 @@
|
||||
"noRefinerModelsInstalled": "Geen SDXL-verfijningsmodellen geïnstalleerd",
|
||||
"defaultVAE": "Standaard-VAE",
|
||||
"lora": "LoRA",
|
||||
"esrganModel": "ESRGAN-model",
|
||||
"addLora": "Voeg LoRA toe",
|
||||
"concepts": "Concepten"
|
||||
},
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"reportBugLabel": "Zgłoś błąd",
|
||||
"settingsLabel": "Ustawienia",
|
||||
"img2img": "Obraz na obraz",
|
||||
"unifiedCanvas": "Tryb uniwersalny",
|
||||
"nodes": "Węzły",
|
||||
"upload": "Prześlij",
|
||||
"load": "Załaduj",
|
||||
@@ -17,204 +16,8 @@
|
||||
"galleryImageSize": "Rozmiar obrazów",
|
||||
"gallerySettings": "Ustawienia galerii",
|
||||
"autoSwitchNewImages": "Przełączaj na nowe obrazy",
|
||||
"loadMore": "Wczytaj więcej",
|
||||
"noImagesInGallery": "Brak obrazów w galerii"
|
||||
},
|
||||
"hotkeys": {
|
||||
"keyboardShortcuts": "Skróty klawiszowe",
|
||||
"appHotkeys": "Podstawowe",
|
||||
"generalHotkeys": "Pomocnicze",
|
||||
"galleryHotkeys": "Galeria",
|
||||
"unifiedCanvasHotkeys": "Tryb uniwersalny",
|
||||
"invoke": {
|
||||
"title": "Wywołaj",
|
||||
"desc": "Generuje nowy obraz"
|
||||
},
|
||||
"cancel": {
|
||||
"title": "Anuluj",
|
||||
"desc": "Zatrzymuje generowanie obrazu"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"title": "Aktywuj pole tekstowe",
|
||||
"desc": "Aktywuje pole wprowadzania sugestii"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"title": "Przełącz panel opcji",
|
||||
"desc": "Wysuwa lub chowa panel opcji"
|
||||
},
|
||||
"pinOptions": {
|
||||
"title": "Przypnij opcje",
|
||||
"desc": "Przypina panel opcji"
|
||||
},
|
||||
"toggleGallery": {
|
||||
"title": "Przełącz galerię",
|
||||
"desc": "Wysuwa lub chowa galerię"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"title": "Powiększ obraz roboczy",
|
||||
"desc": "Chowa wszystkie panele, zostawia tylko podgląd obrazu"
|
||||
},
|
||||
"changeTabs": {
|
||||
"title": "Przełącznie trybu",
|
||||
"desc": "Przełącza na n-ty tryb pracy"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"title": "Przełącz konsolę",
|
||||
"desc": "Otwiera lub chowa widok konsoli"
|
||||
},
|
||||
"setPrompt": {
|
||||
"title": "Skopiuj sugestie",
|
||||
"desc": "Kopiuje sugestie z aktywnego obrazu"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "Skopiuj inicjator",
|
||||
"desc": "Kopiuje inicjator z aktywnego obrazu"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "Skopiuj wszystko",
|
||||
"desc": "Kopiuje wszystkie parametry z aktualnie aktywnego obrazu"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "Popraw twarze",
|
||||
"desc": "Uruchamia proces poprawiania twarzy dla aktywnego obrazu"
|
||||
},
|
||||
"showInfo": {
|
||||
"title": "Pokaż informacje",
|
||||
"desc": "Pokazuje metadane zapisane w aktywnym obrazie"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"title": "Użyj w trybie \"Obraz na obraz\"",
|
||||
"desc": "Ustawia aktywny obraz jako źródło w trybie \"Obraz na obraz\""
|
||||
},
|
||||
"deleteImage": {
|
||||
"title": "Usuń obraz",
|
||||
"desc": "Usuwa aktywny obraz"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "Zamknij panele",
|
||||
"desc": "Zamyka wszystkie otwarte panele"
|
||||
},
|
||||
"previousImage": {
|
||||
"title": "Poprzedni obraz",
|
||||
"desc": "Aktywuje poprzedni obraz z galerii"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "Następny obraz",
|
||||
"desc": "Aktywuje następny obraz z galerii"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "Powiększ obrazy",
|
||||
"desc": "Powiększa rozmiar obrazów w galerii"
|
||||
},
|
||||
"decreaseGalleryThumbSize": {
|
||||
"title": "Pomniejsz obrazy",
|
||||
"desc": "Pomniejsza rozmiar obrazów w galerii"
|
||||
},
|
||||
"selectBrush": {
|
||||
"title": "Aktywuj pędzel",
|
||||
"desc": "Aktywuje narzędzie malowania"
|
||||
},
|
||||
"selectEraser": {
|
||||
"title": "Aktywuj gumkę",
|
||||
"desc": "Aktywuje narzędzie usuwania"
|
||||
},
|
||||
"decreaseBrushSize": {
|
||||
"title": "Zmniejsz rozmiar narzędzia",
|
||||
"desc": "Zmniejsza rozmiar aktywnego narzędzia"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "Zwiększ rozmiar narzędzia",
|
||||
"desc": "Zwiększa rozmiar aktywnego narzędzia"
|
||||
},
|
||||
"decreaseBrushOpacity": {
|
||||
"title": "Zmniejsz krycie",
|
||||
"desc": "Zmniejsza poziom krycia pędzla"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"title": "Zwiększ",
|
||||
"desc": "Zwiększa poziom krycia pędzla"
|
||||
},
|
||||
"moveTool": {
|
||||
"title": "Aktywuj przesunięcie",
|
||||
"desc": "Włącza narzędzie przesuwania"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "Wypełnij zaznaczenie",
|
||||
"desc": "Wypełnia zaznaczony obszar aktualnym kolorem pędzla"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"title": "Wyczyść zaznaczenia",
|
||||
"desc": "Usuwa całą zawartość zaznaczonego obszaru"
|
||||
},
|
||||
"colorPicker": {
|
||||
"title": "Aktywuj pipetę",
|
||||
"desc": "Włącza narzędzie kopiowania koloru"
|
||||
},
|
||||
"toggleSnap": {
|
||||
"title": "Przyciąganie do siatki",
|
||||
"desc": "Włącza lub wyłącza opcje przyciągania do siatki"
|
||||
},
|
||||
"quickToggleMove": {
|
||||
"title": "Szybkie przesunięcie",
|
||||
"desc": "Tymczasowo włącza tryb przesuwania obszaru roboczego"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"title": "Przełącz wartwę",
|
||||
"desc": "Przełącza pomiędzy warstwą bazową i maskowania"
|
||||
},
|
||||
"clearMask": {
|
||||
"title": "Wyczyść maskę",
|
||||
"desc": "Usuwa całą zawartość warstwy maskowania"
|
||||
},
|
||||
"hideMask": {
|
||||
"title": "Przełącz maskę",
|
||||
"desc": "Pokazuje lub ukrywa podgląd maski"
|
||||
},
|
||||
"showHideBoundingBox": {
|
||||
"title": "Przełącz zaznaczenie",
|
||||
"desc": "Pokazuje lub ukrywa podgląd zaznaczenia"
|
||||
},
|
||||
"mergeVisible": {
|
||||
"title": "Połącz widoczne",
|
||||
"desc": "Łączy wszystkie widoczne maski w jeden obraz"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "Zapisz w galerii",
|
||||
"desc": "Zapisuje całą zawartość płótna w galerii"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "Skopiuj do schowka",
|
||||
"desc": "Zapisuje zawartość płótna w schowku systemowym"
|
||||
},
|
||||
"downloadImage": {
|
||||
"title": "Pobierz obraz",
|
||||
"desc": "Zapisuje zawartość płótna do pliku obrazu"
|
||||
},
|
||||
"undoStroke": {
|
||||
"title": "Cofnij",
|
||||
"desc": "Cofa ostatnie pociągnięcie pędzlem"
|
||||
},
|
||||
"redoStroke": {
|
||||
"title": "Ponawia",
|
||||
"desc": "Ponawia cofnięte pociągnięcie pędzlem"
|
||||
},
|
||||
"resetView": {
|
||||
"title": "Resetuj widok",
|
||||
"desc": "Centruje widok płótna"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"title": "Poprzedni obraz tymczasowy",
|
||||
"desc": "Pokazuje poprzedni obraz tymczasowy"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"title": "Następny obraz tymczasowy",
|
||||
"desc": "Pokazuje następny obraz tymczasowy"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"title": "Akceptuj obraz tymczasowy",
|
||||
"desc": "Akceptuje aktualnie wybrany obraz tymczasowy"
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"images": "L. obrazów",
|
||||
"steps": "L. kroków",
|
||||
@@ -235,8 +38,6 @@
|
||||
"scaledHeight": "Sk. do wys.",
|
||||
"infillMethod": "Metoda wypełniania",
|
||||
"tileSize": "Rozmiar kafelka",
|
||||
"sendToImg2Img": "Użyj w trybie \"Obraz na obraz\"",
|
||||
"sendToUnifiedCanvas": "Użyj w trybie uniwersalnym",
|
||||
"downloadImage": "Pobierz obraz",
|
||||
"usePrompt": "Skopiuj sugestie",
|
||||
"useSeed": "Skopiuj inicjator",
|
||||
@@ -248,7 +49,6 @@
|
||||
"models": "Modele",
|
||||
"displayInProgress": "Podgląd generowanego obrazu",
|
||||
"confirmOnDelete": "Potwierdzaj usuwanie",
|
||||
"enableImageDebugging": "Włącz debugowanie obrazu",
|
||||
"resetWebUI": "Zresetuj interfejs",
|
||||
"resetWebUIDesc1": "Resetowanie interfejsu wyczyści jedynie dane i ustawienia zapisane w pamięci przeglądarki. Nie usunie żadnych obrazów z dysku.",
|
||||
"resetWebUIDesc2": "Jeśli obrazy nie są poprawnie wyświetlane w galerii lub doświadczasz innych problemów, przed zgłoszeniem błędu spróbuj zresetować interfejs.",
|
||||
@@ -257,72 +57,7 @@
|
||||
"toast": {
|
||||
"uploadFailed": "Błąd przesyłania obrazu",
|
||||
"imageCopied": "Skopiowano obraz",
|
||||
"imageNotLoadedDesc": "Nie znaleziono obrazu, który można użyć w Obraz na obraz",
|
||||
"canvasMerged": "Scalono widoczne warstwy",
|
||||
"sentToImageToImage": "Wysłano do Obraz na obraz",
|
||||
"sentToUnifiedCanvas": "Wysłano do trybu uniwersalnego",
|
||||
"parametersNotSet": "Nie ustawiono parametrów",
|
||||
"metadataLoadFailed": "Błąd wczytywania metadanych"
|
||||
},
|
||||
"tooltip": {
|
||||
"feature": {
|
||||
"prompt": "To pole musi zawierać cały tekst sugestii, w tym zarówno opis oczekiwanej zawartości, jak i terminy stylistyczne. Chociaż wagi mogą być zawarte w sugestiach, inne parametry znane z linii poleceń nie będą działać.",
|
||||
"gallery": "W miarę generowania nowych wywołań w tym miejscu będą wyświetlane pliki z katalogu wyjściowego. Obrazy mają dodatkowo opcje konfiguracji nowych wywołań.",
|
||||
"other": "Opcje umożliwią alternatywne tryby przetwarzania. Płynne scalanie będzie pomocne przy generowaniu powtarzających się wzorów. Optymalizacja wysokiej rozdzielczości wykonuje dwuetapowy cykl generowania i powinna być używana przy wyższych rozdzielczościach, gdy potrzebny jest bardziej spójny obraz/kompozycja.",
|
||||
"seed": "Inicjator określa początkowy zestaw szumów, który kieruje procesem odszumiania i może być losowy lub pobrany z poprzedniego wywołania. Funkcja \"Poziom szumu\" może być użyta do złagodzenia saturacji przy wyższych wartościach CFG (spróbuj między 0-10), a Perlin może być użyty w celu dodania wariacji do twoich wyników.",
|
||||
"upscale": "Korzystając z ESRGAN, możesz zwiększyć rozdzielczość obrazu wyjściowego bez konieczności zwiększania szerokości/wysokości w ustawieniach początkowych.",
|
||||
"boundingBox": "Zaznaczony obszar odpowiada ustawieniom wysokości i szerokości w trybach Tekst na obraz i Obraz na obraz. Jedynie piksele znajdujące się w obszarze zaznaczenia zostaną uwzględnione podczas wywoływania nowego obrazu."
|
||||
}
|
||||
},
|
||||
"unifiedCanvas": {
|
||||
"layer": "Warstwa",
|
||||
"base": "Główna",
|
||||
"mask": "Maska",
|
||||
"maskingOptions": "Opcje maski",
|
||||
"enableMask": "Włącz maskę",
|
||||
"preserveMaskedArea": "Zachowaj obszar",
|
||||
"clearMask": "Wyczyść maskę",
|
||||
"brush": "Pędzel",
|
||||
"eraser": "Gumka",
|
||||
"fillBoundingBox": "Wypełnij zaznaczenie",
|
||||
"eraseBoundingBox": "Wyczyść zaznaczenie",
|
||||
"colorPicker": "Pipeta",
|
||||
"brushOptions": "Ustawienia pędzla",
|
||||
"brushSize": "Rozmiar",
|
||||
"move": "Przesunięcie",
|
||||
"resetView": "Resetuj widok",
|
||||
"mergeVisible": "Scal warstwy",
|
||||
"saveToGallery": "Zapisz w galerii",
|
||||
"copyToClipboard": "Skopiuj do schowka",
|
||||
"downloadAsImage": "Zapisz do pliku",
|
||||
"undo": "Cofnij",
|
||||
"redo": "Ponów",
|
||||
"clearCanvas": "Wyczyść obraz",
|
||||
"canvasSettings": "Ustawienia obrazu",
|
||||
"showIntermediates": "Pokazuj stany pośrednie",
|
||||
"showGrid": "Pokazuj siatkę",
|
||||
"snapToGrid": "Przyciągaj do siatki",
|
||||
"darkenOutsideSelection": "Przyciemnij poza zaznaczeniem",
|
||||
"autoSaveToGallery": "Zapisuj automatycznie do galerii",
|
||||
"saveBoxRegionOnly": "Zapisuj tylko zaznaczony obszar",
|
||||
"limitStrokesToBox": "Rysuj tylko wewnątrz zaznaczenia",
|
||||
"showCanvasDebugInfo": "Informacje dla developera",
|
||||
"clearCanvasHistory": "Wyczyść historię operacji",
|
||||
"clearHistory": "Wyczyść historię",
|
||||
"clearCanvasHistoryMessage": "Wyczyszczenie historii nie będzie miało wpływu na sam obraz, ale niemożliwe będzie cofnięcie i otworzenie wszystkich wykonanych do tej pory operacji.",
|
||||
"clearCanvasHistoryConfirm": "Czy na pewno chcesz wyczyścić historię operacji?",
|
||||
"activeLayer": "Warstwa aktywna",
|
||||
"canvasScale": "Poziom powiększenia",
|
||||
"boundingBox": "Rozmiar zaznaczenia",
|
||||
"scaledBoundingBox": "Rozmiar po skalowaniu",
|
||||
"boundingBoxPosition": "Pozycja zaznaczenia",
|
||||
"canvasDimensions": "Rozmiar płótna",
|
||||
"canvasPosition": "Pozycja płótna",
|
||||
"cursorPosition": "Pozycja kursora",
|
||||
"previous": "Poprzedni",
|
||||
"next": "Następny",
|
||||
"accept": "Zaakceptuj",
|
||||
"discardAll": "Odrzuć wszystkie"
|
||||
"parametersNotSet": "Nie ustawiono parametrów"
|
||||
},
|
||||
"accessibility": {
|
||||
"invokeProgressBar": "Pasek postępu",
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"languagePickerLabel": "Seletor de Idioma",
|
||||
"hotkeysLabel": "Hotkeys",
|
||||
"img2img": "Imagem para Imagem",
|
||||
"unifiedCanvas": "Tela Unificada",
|
||||
"nodes": "Nós",
|
||||
"upload": "Upload",
|
||||
"load": "Abrir",
|
||||
@@ -18,205 +17,9 @@
|
||||
"gallery": {
|
||||
"gallerySettings": "Configurações de Galeria",
|
||||
"autoSwitchNewImages": "Trocar para Novas Imagens Automaticamente",
|
||||
"loadMore": "Carregar Mais",
|
||||
"noImagesInGallery": "Sem Imagens na Galeria",
|
||||
"galleryImageSize": "Tamanho da Imagem"
|
||||
},
|
||||
"hotkeys": {
|
||||
"generalHotkeys": "Atalhos Gerais",
|
||||
"galleryHotkeys": "Atalhos da Galeria",
|
||||
"maximizeWorkSpace": {
|
||||
"desc": "Fechar painéis e maximixar área de trabalho",
|
||||
"title": "Maximizar a Área de Trabalho"
|
||||
},
|
||||
"changeTabs": {
|
||||
"title": "Mudar Guias",
|
||||
"desc": "Trocar para outra área de trabalho"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"desc": "Abrir e fechar console",
|
||||
"title": "Ativar Console"
|
||||
},
|
||||
"setPrompt": {
|
||||
"title": "Definir Prompt",
|
||||
"desc": "Usar o prompt da imagem atual"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"desc": "Manda a imagem atual para Imagem Para Imagem",
|
||||
"title": "Mandar para Imagem Para Imagem"
|
||||
},
|
||||
"previousImage": {
|
||||
"desc": "Mostra a imagem anterior na galeria",
|
||||
"title": "Imagem Anterior"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "Próxima Imagem",
|
||||
"desc": "Mostra a próxima imagem na galeria"
|
||||
},
|
||||
"decreaseGalleryThumbSize": {
|
||||
"desc": "Diminui o tamanho das thumbs na galeria",
|
||||
"title": "Diminuir Tamanho da Galeria de Imagem"
|
||||
},
|
||||
"selectBrush": {
|
||||
"title": "Selecionar Pincel",
|
||||
"desc": "Seleciona o pincel"
|
||||
},
|
||||
"selectEraser": {
|
||||
"title": "Selecionar Apagador",
|
||||
"desc": "Seleciona o apagador"
|
||||
},
|
||||
"decreaseBrushSize": {
|
||||
"title": "Diminuir Tamanho do Pincel",
|
||||
"desc": "Diminui o tamanho do pincel/apagador"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"desc": "Aumenta a opacidade do pincel",
|
||||
"title": "Aumentar Opacidade do Pincel"
|
||||
},
|
||||
"moveTool": {
|
||||
"title": "Ferramenta Mover",
|
||||
"desc": "Permite navegar pela tela"
|
||||
},
|
||||
"decreaseBrushOpacity": {
|
||||
"desc": "Diminui a opacidade do pincel",
|
||||
"title": "Diminuir Opacidade do Pincel"
|
||||
},
|
||||
"toggleSnap": {
|
||||
"title": "Ativar Encaixe",
|
||||
"desc": "Ativa Encaixar na Grade"
|
||||
},
|
||||
"quickToggleMove": {
|
||||
"title": "Ativar Mover Rapidamente",
|
||||
"desc": "Temporariamente ativa o modo Mover"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"title": "Ativar Camada",
|
||||
"desc": "Ativa a seleção de camada de máscara/base"
|
||||
},
|
||||
"clearMask": {
|
||||
"title": "Limpar Máscara",
|
||||
"desc": "Limpa toda a máscara"
|
||||
},
|
||||
"hideMask": {
|
||||
"title": "Esconder Máscara",
|
||||
"desc": "Esconde e Revela a máscara"
|
||||
},
|
||||
"mergeVisible": {
|
||||
"title": "Fundir Visível",
|
||||
"desc": "Fundir todas as camadas visíveis das telas"
|
||||
},
|
||||
"downloadImage": {
|
||||
"desc": "Descarregar a tela atual",
|
||||
"title": "Descarregar Imagem"
|
||||
},
|
||||
"undoStroke": {
|
||||
"title": "Desfazer Traço",
|
||||
"desc": "Desfaz um traço de pincel"
|
||||
},
|
||||
"redoStroke": {
|
||||
"title": "Refazer Traço",
|
||||
"desc": "Refaz o traço de pincel"
|
||||
},
|
||||
"keyboardShortcuts": "Atalhos de Teclado",
|
||||
"appHotkeys": "Atalhos do app",
|
||||
"invoke": {
|
||||
"title": "Invocar",
|
||||
"desc": "Gerar uma imagem"
|
||||
},
|
||||
"cancel": {
|
||||
"title": "Cancelar",
|
||||
"desc": "Cancelar geração de imagem"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"title": "Foco do Prompt",
|
||||
"desc": "Foco da área de texto do prompt"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"title": "Ativar Opções",
|
||||
"desc": "Abrir e fechar o painel de opções"
|
||||
},
|
||||
"pinOptions": {
|
||||
"title": "Fixar Opções",
|
||||
"desc": "Fixar o painel de opções"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "Fechar Painéis",
|
||||
"desc": "Fecha os painéis abertos"
|
||||
},
|
||||
"unifiedCanvasHotkeys": "Atalhos da Tela Unificada",
|
||||
"toggleGallery": {
|
||||
"title": "Ativar Galeria",
|
||||
"desc": "Abrir e fechar a gaveta da galeria"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "Definir Seed",
|
||||
"desc": "Usar seed da imagem atual"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "Definir Parâmetros",
|
||||
"desc": "Usar todos os parâmetros da imagem atual"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "Restaurar Rostos",
|
||||
"desc": "Restaurar a imagem atual"
|
||||
},
|
||||
"showInfo": {
|
||||
"title": "Mostrar Informações",
|
||||
"desc": "Mostrar metadados de informações da imagem atual"
|
||||
},
|
||||
"deleteImage": {
|
||||
"title": "Apagar Imagem",
|
||||
"desc": "Apaga a imagem atual"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "Aumentar Tamanho da Galeria de Imagem",
|
||||
"desc": "Aumenta o tamanho das thumbs na galeria"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "Aumentar Tamanho do Pincel",
|
||||
"desc": "Aumenta o tamanho do pincel/apagador"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "Preencher Caixa Delimitadora",
|
||||
"desc": "Preenche a caixa delimitadora com a cor do pincel"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"title": "Apagar Caixa Delimitadora",
|
||||
"desc": "Apaga a área da caixa delimitadora"
|
||||
},
|
||||
"colorPicker": {
|
||||
"title": "Selecionar Seletor de Cor",
|
||||
"desc": "Seleciona o seletor de cores"
|
||||
},
|
||||
"showHideBoundingBox": {
|
||||
"title": "Mostrar/Esconder Caixa Delimitadora",
|
||||
"desc": "Ativa a visibilidade da caixa delimitadora"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "Gravara Na Galeria",
|
||||
"desc": "Grava a tela atual na galeria"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "Copiar para a Área de Transferência",
|
||||
"desc": "Copia a tela atual para a área de transferência"
|
||||
},
|
||||
"resetView": {
|
||||
"title": "Resetar Visualização",
|
||||
"desc": "Reseta Visualização da Tela"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"title": "Imagem de Preparação Anterior",
|
||||
"desc": "Área de Imagem de Preparação Anterior"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"title": "Próxima Imagem de Preparação Anterior",
|
||||
"desc": "Próxima Área de Imagem de Preparação Anterior"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"title": "Aceitar Imagem de Preparação Anterior",
|
||||
"desc": "Aceitar Área de Imagem de Preparação Anterior"
|
||||
}
|
||||
},
|
||||
"modelManager": {
|
||||
"modelUpdated": "Modelo Atualizado",
|
||||
"description": "Descrição",
|
||||
@@ -227,7 +30,6 @@
|
||||
"convertToDiffusersHelpText6": "Deseja converter este modelo?",
|
||||
"alpha": "Alpha",
|
||||
"config": "Configuração",
|
||||
"v2_768": "v2 (768px)",
|
||||
"modelConverted": "Modelo Convertido",
|
||||
"manual": "Manual",
|
||||
"name": "Nome",
|
||||
@@ -241,7 +43,6 @@
|
||||
"convertToDiffusersHelpText1": "Este modelo será convertido ao formato 🧨 Diffusers.",
|
||||
"convertToDiffusersHelpText2": "Este processo irá substituir a sua entrada de Gestor de Modelos por uma versão Diffusers do mesmo modelo.",
|
||||
"convertToDiffusersHelpText3": "O seu ficheiro de ponto de verificação no disco NÃO será excluído ou modificado de forma alguma. Pode adicionar o seu ponto de verificação ao Gestor de modelos novamente, se desejar.",
|
||||
"v2_base": "v2 (512px)",
|
||||
"none": "nenhum",
|
||||
"modelManager": "Gerente de Modelo",
|
||||
"model": "Modelo",
|
||||
@@ -279,8 +80,6 @@
|
||||
"scaledWidth": "L Escalada",
|
||||
"scaledHeight": "A Escalada",
|
||||
"infillMethod": "Método de Preenchimento",
|
||||
"sendToImg2Img": "Mandar para Imagem Para Imagem",
|
||||
"sendToUnifiedCanvas": "Mandar para Tela Unificada",
|
||||
"copyImage": "Copiar imagem",
|
||||
"downloadImage": "Descarregar Imagem",
|
||||
"useSeed": "Usar Seed",
|
||||
@@ -289,7 +88,6 @@
|
||||
},
|
||||
"settings": {
|
||||
"confirmOnDelete": "Confirmar Antes de Apagar",
|
||||
"enableImageDebugging": "Ativar Depuração de Imagem",
|
||||
"resetWebUIDesc1": "Reiniciar a interface apenas reinicia o cache local do broswer para imagens e configurações lembradas. Não apaga nenhuma imagem do disco.",
|
||||
"models": "Modelos",
|
||||
"displayInProgress": "Mostrar Progresso de Imagens Em Andamento",
|
||||
@@ -299,80 +97,32 @@
|
||||
},
|
||||
"toast": {
|
||||
"uploadFailed": "Envio Falhou",
|
||||
"imageNotLoadedDesc": "Nenhuma imagem encontrada a enviar para o módulo de imagem para imagem",
|
||||
"imageCopied": "Imagem Copiada",
|
||||
"canvasMerged": "Tela Fundida",
|
||||
"sentToImageToImage": "Mandar Para Imagem Para Imagem",
|
||||
"sentToUnifiedCanvas": "Enviada para a Tela Unificada",
|
||||
"parametersNotSet": "Parâmetros Não Definidos",
|
||||
"metadataLoadFailed": "Falha ao tentar carregar metadados"
|
||||
},
|
||||
"tooltip": {
|
||||
"feature": {
|
||||
"prompt": "Este é o campo de prompt. O prompt inclui objetos de geração e termos estilísticos. Também pode adicionar peso (importância do token) no prompt, mas comandos e parâmetros de CLI não funcionarão.",
|
||||
"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.",
|
||||
"seed": "O valor da semente afeta o ruído inicial a partir do qual a imagem é formada. 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 ficheiros e acessadas pelo menu de contexto.",
|
||||
"upscale": "Use o ESRGAN para ampliar a imagem imediatamente após a geração.",
|
||||
"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."
|
||||
}
|
||||
},
|
||||
"unifiedCanvas": {
|
||||
"scaledBoundingBox": "Caixa Delimitadora Escalada",
|
||||
"boundingBoxPosition": "Posição da Caixa Delimitadora",
|
||||
"next": "Próximo",
|
||||
"accept": "Aceitar",
|
||||
"discardAll": "Descartar Todos",
|
||||
"base": "Base",
|
||||
"brush": "Pincel",
|
||||
"showIntermediates": "Mostrar Intermediários",
|
||||
"showGrid": "Mostrar Grade",
|
||||
"clearCanvasHistoryConfirm": "Tem certeza que quer limpar o histórico de tela?",
|
||||
"boundingBox": "Caixa Delimitadora",
|
||||
"canvasDimensions": "Dimensões da Tela",
|
||||
"canvasPosition": "Posição da Tela",
|
||||
"cursorPosition": "Posição do cursor",
|
||||
"previous": "Anterior",
|
||||
"layer": "Camada",
|
||||
"mask": "Máscara",
|
||||
"maskingOptions": "Opções de Mascaramento",
|
||||
"enableMask": "Ativar Máscara",
|
||||
"preserveMaskedArea": "Preservar Área da Máscara",
|
||||
"clearMask": "Limpar Máscara",
|
||||
"eraser": "Apagador",
|
||||
"fillBoundingBox": "Preencher Caixa Delimitadora",
|
||||
"eraseBoundingBox": "Apagar Caixa Delimitadora",
|
||||
"colorPicker": "Seletor de Cor",
|
||||
"brushOptions": "Opções de Pincel",
|
||||
"brushSize": "Tamanho",
|
||||
"move": "Mover",
|
||||
"resetView": "Resetar Visualização",
|
||||
"mergeVisible": "Fundir Visível",
|
||||
"saveToGallery": "Gravar na Galeria",
|
||||
"copyToClipboard": "Copiar para a Área de Transferência",
|
||||
"downloadAsImage": "Descarregar Como Imagem",
|
||||
"undo": "Desfazer",
|
||||
"redo": "Refazer",
|
||||
"clearCanvas": "Limpar Tela",
|
||||
"canvasSettings": "Configurações de Tela",
|
||||
"snapToGrid": "Encaixar na Grade",
|
||||
"darkenOutsideSelection": "Escurecer Seleção Externa",
|
||||
"autoSaveToGallery": "Gravar Automaticamente na Galeria",
|
||||
"saveBoxRegionOnly": "Gravar Apenas a Região da Caixa",
|
||||
"limitStrokesToBox": "Limitar Traços à Caixa",
|
||||
"showCanvasDebugInfo": "Mostrar Informações de Depuração daTela",
|
||||
"clearCanvasHistory": "Limpar o Histórico da Tela",
|
||||
"clearHistory": "Limpar Históprico",
|
||||
"clearCanvasHistoryMessage": "Limpar o histórico de tela deixa a sua tela atual intacta, mas limpa de forma irreversível o histórico de desfazer e refazer.",
|
||||
"activeLayer": "Camada Ativa",
|
||||
"canvasScale": "Escala da Tela"
|
||||
"parametersNotSet": "Parâmetros Não Definidos"
|
||||
},
|
||||
"accessibility": {
|
||||
"invokeProgressBar": "Invocar barra de progresso",
|
||||
"reset": "Repôr",
|
||||
"reset": "Reiniciar",
|
||||
"nextImage": "Próxima imagem",
|
||||
"showOptionsPanel": "Mostrar painel de opções",
|
||||
"uploadImage": "Enviar imagem",
|
||||
"previousImage": "Imagem anterior"
|
||||
"previousImage": "Imagem Anterior",
|
||||
"menu": "Menu",
|
||||
"about": "Sobre",
|
||||
"resetUI": "$t(accessibility.reset)UI",
|
||||
"createIssue": "Reportar Problema",
|
||||
"submitSupportTicket": "Submeter um ticket de Suporte",
|
||||
"mode": "Modo",
|
||||
"showGalleryPanel": "Mostrar Painel de Galeria"
|
||||
},
|
||||
"boards": {
|
||||
"selectedForAutoAdd": "Selecionado para Auto-Adicionar",
|
||||
"addBoard": "Adicionar Quadro",
|
||||
"addPrivateBoard": "Adicionar Quadro privado",
|
||||
"addSharedBoard": "Adicionar quadro Compartilhado",
|
||||
"boards": "Quadros",
|
||||
"autoAddBoard": "Auto-adicao de Quadro",
|
||||
"archiveBoard": "Arquivar Quadro",
|
||||
"archived": "Arquivado"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"reportBugLabel": "Relatar Bug",
|
||||
"settingsLabel": "Configurações",
|
||||
"img2img": "Imagem Para Imagem",
|
||||
"unifiedCanvas": "Tela Unificada",
|
||||
"nodes": "Nódulos",
|
||||
"upload": "Enviar",
|
||||
"load": "Carregar",
|
||||
@@ -19,204 +18,8 @@
|
||||
"galleryImageSize": "Tamanho da Imagem",
|
||||
"gallerySettings": "Configurações de Galeria",
|
||||
"autoSwitchNewImages": "Trocar para Novas Imagens Automaticamente",
|
||||
"loadMore": "Carregar Mais",
|
||||
"noImagesInGallery": "Sem Imagens na Galeria"
|
||||
},
|
||||
"hotkeys": {
|
||||
"keyboardShortcuts": "Atalhos de Teclado",
|
||||
"appHotkeys": "Atalhos do app",
|
||||
"generalHotkeys": "Atalhos Gerais",
|
||||
"galleryHotkeys": "Atalhos da Galeria",
|
||||
"unifiedCanvasHotkeys": "Atalhos da Tela Unificada",
|
||||
"invoke": {
|
||||
"title": "Invoke",
|
||||
"desc": "Gerar uma imagem"
|
||||
},
|
||||
"cancel": {
|
||||
"title": "Cancelar",
|
||||
"desc": "Cancelar geração de imagem"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"title": "Foco do Prompt",
|
||||
"desc": "Foco da área de texto do prompt"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"title": "Ativar Opções",
|
||||
"desc": "Abrir e fechar o painel de opções"
|
||||
},
|
||||
"pinOptions": {
|
||||
"title": "Fixar Opções",
|
||||
"desc": "Fixar o painel de opções"
|
||||
},
|
||||
"toggleGallery": {
|
||||
"title": "Ativar Galeria",
|
||||
"desc": "Abrir e fechar a gaveta da galeria"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"title": "Maximizar a Área de Trabalho",
|
||||
"desc": "Fechar painéis e maximixar área de trabalho"
|
||||
},
|
||||
"changeTabs": {
|
||||
"title": "Mudar Abas",
|
||||
"desc": "Trocar para outra área de trabalho"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"title": "Ativar Console",
|
||||
"desc": "Abrir e fechar console"
|
||||
},
|
||||
"setPrompt": {
|
||||
"title": "Definir Prompt",
|
||||
"desc": "Usar o prompt da imagem atual"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "Definir Seed",
|
||||
"desc": "Usar seed da imagem atual"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "Definir Parâmetros",
|
||||
"desc": "Usar todos os parâmetros da imagem atual"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "Restaurar Rostos",
|
||||
"desc": "Restaurar a imagem atual"
|
||||
},
|
||||
"showInfo": {
|
||||
"title": "Mostrar Informações",
|
||||
"desc": "Mostrar metadados de informações da imagem atual"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"title": "Mandar para Imagem Para Imagem",
|
||||
"desc": "Manda a imagem atual para Imagem Para Imagem"
|
||||
},
|
||||
"deleteImage": {
|
||||
"title": "Apagar Imagem",
|
||||
"desc": "Apaga a imagem atual"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "Fechar Painéis",
|
||||
"desc": "Fecha os painéis abertos"
|
||||
},
|
||||
"previousImage": {
|
||||
"title": "Imagem Anterior",
|
||||
"desc": "Mostra a imagem anterior na galeria"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "Próxima Imagem",
|
||||
"desc": "Mostra a próxima imagem na galeria"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "Aumentar Tamanho da Galeria de Imagem",
|
||||
"desc": "Aumenta o tamanho das thumbs na galeria"
|
||||
},
|
||||
"decreaseGalleryThumbSize": {
|
||||
"title": "Diminuir Tamanho da Galeria de Imagem",
|
||||
"desc": "Diminui o tamanho das thumbs na galeria"
|
||||
},
|
||||
"selectBrush": {
|
||||
"title": "Selecionar Pincel",
|
||||
"desc": "Seleciona o pincel"
|
||||
},
|
||||
"selectEraser": {
|
||||
"title": "Selecionar Apagador",
|
||||
"desc": "Seleciona o apagador"
|
||||
},
|
||||
"decreaseBrushSize": {
|
||||
"title": "Diminuir Tamanho do Pincel",
|
||||
"desc": "Diminui o tamanho do pincel/apagador"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "Aumentar Tamanho do Pincel",
|
||||
"desc": "Aumenta o tamanho do pincel/apagador"
|
||||
},
|
||||
"decreaseBrushOpacity": {
|
||||
"title": "Diminuir Opacidade do Pincel",
|
||||
"desc": "Diminui a opacidade do pincel"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"title": "Aumentar Opacidade do Pincel",
|
||||
"desc": "Aumenta a opacidade do pincel"
|
||||
},
|
||||
"moveTool": {
|
||||
"title": "Ferramenta Mover",
|
||||
"desc": "Permite navegar pela tela"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "Preencher Caixa Delimitadora",
|
||||
"desc": "Preenche a caixa delimitadora com a cor do pincel"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"title": "Apagar Caixa Delimitadora",
|
||||
"desc": "Apaga a área da caixa delimitadora"
|
||||
},
|
||||
"colorPicker": {
|
||||
"title": "Selecionar Seletor de Cor",
|
||||
"desc": "Seleciona o seletor de cores"
|
||||
},
|
||||
"toggleSnap": {
|
||||
"title": "Ativar Encaixe",
|
||||
"desc": "Ativa Encaixar na Grade"
|
||||
},
|
||||
"quickToggleMove": {
|
||||
"title": "Ativar Mover Rapidamente",
|
||||
"desc": "Temporariamente ativa o modo Mover"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"title": "Ativar Camada",
|
||||
"desc": "Ativa a seleção de camada de máscara/base"
|
||||
},
|
||||
"clearMask": {
|
||||
"title": "Limpar Máscara",
|
||||
"desc": "Limpa toda a máscara"
|
||||
},
|
||||
"hideMask": {
|
||||
"title": "Esconder Máscara",
|
||||
"desc": "Esconde e Revela a máscara"
|
||||
},
|
||||
"showHideBoundingBox": {
|
||||
"title": "Mostrar/Esconder Caixa Delimitadora",
|
||||
"desc": "Ativa a visibilidade da caixa delimitadora"
|
||||
},
|
||||
"mergeVisible": {
|
||||
"title": "Fundir Visível",
|
||||
"desc": "Fundir todas as camadas visíveis em tela"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "Salvara Na Galeria",
|
||||
"desc": "Salva a tela atual na galeria"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "Copiar para a Área de Transferência",
|
||||
"desc": "Copia a tela atual para a área de transferência"
|
||||
},
|
||||
"downloadImage": {
|
||||
"title": "Baixar Imagem",
|
||||
"desc": "Baixa a tela atual"
|
||||
},
|
||||
"undoStroke": {
|
||||
"title": "Desfazer Traço",
|
||||
"desc": "Desfaz um traço de pincel"
|
||||
},
|
||||
"redoStroke": {
|
||||
"title": "Refazer Traço",
|
||||
"desc": "Refaz o traço de pincel"
|
||||
},
|
||||
"resetView": {
|
||||
"title": "Resetar Visualização",
|
||||
"desc": "Reseta Visualização da Tela"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"title": "Imagem de Preparação Anterior",
|
||||
"desc": "Área de Imagem de Preparação Anterior"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"title": "Próxima Imagem de Preparação Anterior",
|
||||
"desc": "Próxima Área de Imagem de Preparação Anterior"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"title": "Aceitar Imagem de Preparação Anterior",
|
||||
"desc": "Aceitar Área de Imagem de Preparação Anterior"
|
||||
}
|
||||
},
|
||||
"modelManager": {
|
||||
"modelManager": "Gerente de Modelo",
|
||||
"model": "Modelo",
|
||||
@@ -271,8 +74,6 @@
|
||||
"scaledHeight": "A Escalada",
|
||||
"infillMethod": "Método de Preenchimento",
|
||||
"tileSize": "Tamanho do Ladrilho",
|
||||
"sendToImg2Img": "Mandar para Imagem Para Imagem",
|
||||
"sendToUnifiedCanvas": "Mandar para Tela Unificada",
|
||||
"downloadImage": "Baixar Imagem",
|
||||
"usePrompt": "Usar Prompt",
|
||||
"useSeed": "Usar Seed",
|
||||
@@ -288,7 +89,6 @@
|
||||
"models": "Modelos",
|
||||
"displayInProgress": "Mostrar Progresso de Imagens Em Andamento",
|
||||
"confirmOnDelete": "Confirmar Antes de Apagar",
|
||||
"enableImageDebugging": "Ativar Depuração de Imagem",
|
||||
"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.",
|
||||
"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.",
|
||||
@@ -297,71 +97,6 @@
|
||||
"toast": {
|
||||
"uploadFailed": "Envio Falhou",
|
||||
"imageCopied": "Imagem Copiada",
|
||||
"imageNotLoadedDesc": "Nenhuma imagem encontrar para mandar para o módulo de imagem para imagem",
|
||||
"canvasMerged": "Tela Fundida",
|
||||
"sentToImageToImage": "Mandar Para Imagem Para Imagem",
|
||||
"sentToUnifiedCanvas": "Enviada para a Tela Unificada",
|
||||
"parametersNotSet": "Parâmetros Não Definidos",
|
||||
"metadataLoadFailed": "Falha ao tentar carregar metadados"
|
||||
},
|
||||
"unifiedCanvas": {
|
||||
"layer": "Camada",
|
||||
"base": "Base",
|
||||
"mask": "Máscara",
|
||||
"maskingOptions": "Opções de Mascaramento",
|
||||
"enableMask": "Ativar Máscara",
|
||||
"preserveMaskedArea": "Preservar Área da Máscara",
|
||||
"clearMask": "Limpar Máscara",
|
||||
"brush": "Pincel",
|
||||
"eraser": "Apagador",
|
||||
"fillBoundingBox": "Preencher Caixa Delimitadora",
|
||||
"eraseBoundingBox": "Apagar Caixa Delimitadora",
|
||||
"colorPicker": "Seletor de Cor",
|
||||
"brushOptions": "Opções de Pincel",
|
||||
"brushSize": "Tamanho",
|
||||
"move": "Mover",
|
||||
"resetView": "Resetar Visualização",
|
||||
"mergeVisible": "Fundir Visível",
|
||||
"saveToGallery": "Salvar na Galeria",
|
||||
"copyToClipboard": "Copiar para a Área de Transferência",
|
||||
"downloadAsImage": "Baixar Como Imagem",
|
||||
"undo": "Desfazer",
|
||||
"redo": "Refazer",
|
||||
"clearCanvas": "Limpar Tela",
|
||||
"canvasSettings": "Configurações de Tela",
|
||||
"showIntermediates": "Mostrar Intermediários",
|
||||
"showGrid": "Mostrar Grade",
|
||||
"snapToGrid": "Encaixar na Grade",
|
||||
"darkenOutsideSelection": "Escurecer Seleção Externa",
|
||||
"autoSaveToGallery": "Salvar Automaticamente na Galeria",
|
||||
"saveBoxRegionOnly": "Salvar Apenas a Região da Caixa",
|
||||
"limitStrokesToBox": "Limitar Traços para a Caixa",
|
||||
"showCanvasDebugInfo": "Mostrar Informações de Depuração daTela",
|
||||
"clearCanvasHistory": "Limpar o Histórico da Tela",
|
||||
"clearHistory": "Limpar Históprico",
|
||||
"clearCanvasHistoryMessage": "Limpar o histórico de tela deixa sua tela atual intacta, mas limpa de forma irreversível o histórico de desfazer e refazer.",
|
||||
"clearCanvasHistoryConfirm": "Tem certeza que quer limpar o histórico de tela?",
|
||||
"activeLayer": "Camada Ativa",
|
||||
"canvasScale": "Escala da Tela",
|
||||
"boundingBox": "Caixa Delimitadora",
|
||||
"scaledBoundingBox": "Caixa Delimitadora Escalada",
|
||||
"boundingBoxPosition": "Posição da Caixa Delimitadora",
|
||||
"canvasDimensions": "Dimensões da Tela",
|
||||
"canvasPosition": "Posição da Tela",
|
||||
"cursorPosition": "Posição do cursor",
|
||||
"previous": "Anterior",
|
||||
"next": "Próximo",
|
||||
"accept": "Aceitar",
|
||||
"discardAll": "Descartar Todos"
|
||||
},
|
||||
"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.",
|
||||
"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."
|
||||
}
|
||||
"parametersNotSet": "Parâmetros Não Definidos"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,6 @@
|
||||
"githubLabel": "Github",
|
||||
"discordLabel": "Discord",
|
||||
"settingsLabel": "Inställningar",
|
||||
"unifiedCanvas": "Förenad kanvas",
|
||||
"upload": "Ladda upp",
|
||||
"cancel": "Avbryt",
|
||||
"accept": "Acceptera",
|
||||
@@ -29,135 +28,8 @@
|
||||
},
|
||||
"gallery": {
|
||||
"galleryImageSize": "Bildstorlek",
|
||||
"loadMore": "Ladda mer",
|
||||
"gallerySettings": "Galleriinställningar",
|
||||
"noImagesInGallery": "Inga bilder i galleriet",
|
||||
"autoSwitchNewImages": "Ändra automatiskt till nya bilder"
|
||||
},
|
||||
"hotkeys": {
|
||||
"generalHotkeys": "Allmänna snabbtangenter",
|
||||
"galleryHotkeys": "Gallerisnabbtangenter",
|
||||
"unifiedCanvasHotkeys": "Snabbtangenter för sammanslagskanvas",
|
||||
"invoke": {
|
||||
"title": "Anropa",
|
||||
"desc": "Genererar en bild"
|
||||
},
|
||||
"cancel": {
|
||||
"title": "Avbryt",
|
||||
"desc": "Avbryt bildgenerering"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"desc": "Fokusera området för promptinmatning",
|
||||
"title": "Fokusprompt"
|
||||
},
|
||||
"pinOptions": {
|
||||
"desc": "Nåla fast alternativpanelen",
|
||||
"title": "Nåla fast alternativ"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"title": "Växla inställningar",
|
||||
"desc": "Öppna och stäng alternativpanelen"
|
||||
},
|
||||
"toggleGallery": {
|
||||
"title": "Växla galleri",
|
||||
"desc": "Öppna eller stäng galleribyrån"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"title": "Maximera arbetsyta",
|
||||
"desc": "Stäng paneler och maximera arbetsyta"
|
||||
},
|
||||
"changeTabs": {
|
||||
"title": "Växla flik",
|
||||
"desc": "Byt till en annan arbetsyta"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"title": "Växla konsol",
|
||||
"desc": "Öppna och stäng konsol"
|
||||
},
|
||||
"setSeed": {
|
||||
"desc": "Använd seed för nuvarande bild",
|
||||
"title": "välj seed"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "Välj parametrar",
|
||||
"desc": "Använd alla parametrar från nuvarande bild"
|
||||
},
|
||||
"setPrompt": {
|
||||
"desc": "Använd prompt för nuvarande bild",
|
||||
"title": "Välj prompt"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "Återskapa ansikten",
|
||||
"desc": "Återskapa nuvarande bild"
|
||||
},
|
||||
"showInfo": {
|
||||
"title": "Visa info",
|
||||
"desc": "Visa metadata för nuvarande bild"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"title": "Skicka till Bild till bild",
|
||||
"desc": "Skicka nuvarande bild till Bild till bild"
|
||||
},
|
||||
"deleteImage": {
|
||||
"title": "Radera bild",
|
||||
"desc": "Radera nuvarande bild"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "Stäng paneler",
|
||||
"desc": "Stäng öppna paneler"
|
||||
},
|
||||
"previousImage": {
|
||||
"title": "Föregående bild",
|
||||
"desc": "Visa föregående bild"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "Nästa bild",
|
||||
"desc": "Visa nästa bild"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "Förstora galleriets bildstorlek",
|
||||
"desc": "Förstora miniatyrbildernas storlek"
|
||||
},
|
||||
"decreaseGalleryThumbSize": {
|
||||
"title": "Minska gelleriets bildstorlek",
|
||||
"desc": "Minska miniatyrbildernas storlek i galleriet"
|
||||
},
|
||||
"decreaseBrushSize": {
|
||||
"desc": "Förminska storleken på kanvas- pensel eller suddgummi",
|
||||
"title": "Minska penselstorlek"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "Öka penselstorlek",
|
||||
"desc": "Öka stoleken på kanvas- pensel eller suddgummi"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"title": "Öka penselns opacitet",
|
||||
"desc": "Öka opaciteten för kanvaspensel"
|
||||
},
|
||||
"decreaseBrushOpacity": {
|
||||
"desc": "Minska kanvaspenselns opacitet",
|
||||
"title": "Minska penselns opacitet"
|
||||
},
|
||||
"moveTool": {
|
||||
"title": "Flytta",
|
||||
"desc": "Tillåt kanvasnavigation"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "Fyll ram",
|
||||
"desc": "Fyller ramen med pensels färg"
|
||||
},
|
||||
"keyboardShortcuts": "Snabbtangenter",
|
||||
"appHotkeys": "Appsnabbtangenter",
|
||||
"selectBrush": {
|
||||
"desc": "Välj kanvaspensel",
|
||||
"title": "Välj pensel"
|
||||
},
|
||||
"selectEraser": {
|
||||
"desc": "Välj kanvassuddgummi",
|
||||
"title": "Välj suddgummi"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"title": "Ta bort ram"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
"mode": "Kip",
|
||||
"resetUI": "$t(accessibility.reset)Arayüz",
|
||||
"showGalleryPanel": "Galeri Panelini Göster",
|
||||
"loadMore": "Daha Getir",
|
||||
"createIssue": "Sorun Bildir"
|
||||
},
|
||||
"common": {
|
||||
@@ -26,7 +25,6 @@
|
||||
"linear": "Doğrusal",
|
||||
"nodes": "İş Akışı Düzenleyici",
|
||||
"postprocessing": "Rötuş",
|
||||
"unifiedCanvas": "Tuval",
|
||||
"batch": "Toplu İş Yöneticisi",
|
||||
"accept": "Onayla",
|
||||
"cancel": "Vazgeç",
|
||||
@@ -52,7 +50,6 @@
|
||||
"outpaint": "dışboyama",
|
||||
"outputs": "Çıktılar",
|
||||
"learnMore": "Bilgi Edin",
|
||||
"nodeEditor": "Çizge Düzenleyici",
|
||||
"save": "Kaydet",
|
||||
"random": "Rastgele",
|
||||
"simple": "Basit",
|
||||
@@ -132,85 +129,6 @@
|
||||
"changeBoard": "Panoyu Değiştir",
|
||||
"bottomMessage": "Bu panoyu ve görselleri silmek, bunları kullanan özelliklerin resetlemesine neden olacaktır."
|
||||
},
|
||||
"controlnet": {
|
||||
"balanced": "Dengeli",
|
||||
"contentShuffle": "İçerik Karıştırma",
|
||||
"contentShuffleDescription": "Görselin içeriğini karıştırır",
|
||||
"depthZoe": "Derinlik (Zoe)",
|
||||
"depthZoeDescription": "Zoe kullanarak derinlik haritası oluşturma",
|
||||
"resizeMode": "Boyutlandırma Kipi",
|
||||
"addControlNet": "$t(common.controlNet) Ekle",
|
||||
"addIPAdapter": "$t(common.ipAdapter) Ekle",
|
||||
"addT2IAdapter": "$t(common.t2iAdapter) Ekle",
|
||||
"colorMap": "Renk",
|
||||
"crop": "Kırpma",
|
||||
"delete": "Kaldır",
|
||||
"depthMidas": "Derinlik (Midas)",
|
||||
"depthMidasDescription": "Midas kullanarak derinlik haritası oluşturma",
|
||||
"detectResolution": "Çözünürlüğü Bul",
|
||||
"none": "Hiçbiri",
|
||||
"noneDescription": "Hiçbir işlem uygulanmamış",
|
||||
"selectModel": "Model seçin",
|
||||
"showAdvanced": "Gelişmiş Seçenekleri Göster",
|
||||
"canny": "Canny",
|
||||
"colorMapDescription": "Görselden renk haritası oluşturur",
|
||||
"processor": "İşlemci",
|
||||
"prompt": "İstem",
|
||||
"duplicate": "Kopyala",
|
||||
"large": "Büyük",
|
||||
"modelSize": "Model Boyutu",
|
||||
"resize": "Boyutlandır",
|
||||
"resizeSimple": "Boyutlandır (Basit)",
|
||||
"safe": "Güvenli",
|
||||
"small": "Küçük",
|
||||
"weight": "Etki",
|
||||
"cannyDescription": "Canny kenar algılama",
|
||||
"fill": "Doldur",
|
||||
"highThreshold": "Üst Eşik",
|
||||
"imageResolution": "Görsel Çözünürlüğü",
|
||||
"colorMapTileSize": "Döşeme Boyutu",
|
||||
"importImageFromCanvas": "Tuvaldeki Görseli Al",
|
||||
"importMaskFromCanvas": "Tuvalden Maskeyi İçe Aktar",
|
||||
"lowThreshold": "Alt Eşik",
|
||||
"base": "Taban",
|
||||
"depthAnythingDescription": "Depth Anything yöntemi ile derinlik haritası oluşturma",
|
||||
"controlAdapter_one": "Yönetim Aracı",
|
||||
"controlAdapter_other": "Yönetim Aracı",
|
||||
"beginEndStepPercent": "Başlangıç / Bitiş Yüzdesi",
|
||||
"control": "Yönetim",
|
||||
"controlnet": "{{number}}. $t(controlnet.controlAdapter_one) ($t(common.controlNet))",
|
||||
"amult": "a_mult",
|
||||
"hideAdvanced": "Gelişmiş Seçenekleri Gizle",
|
||||
"hed": "HED",
|
||||
"ip_adapter": "{{number}}. $t(controlnet.controlAdapter_one) ($t(common.ipAdapter))",
|
||||
"t2i_adapter": "{{number}}. $t(controlnet.controlAdapter_one) ($t(common.t2iAdapter))",
|
||||
"autoConfigure": "Aracı otomatik yapılandır",
|
||||
"bgth": "bg_th",
|
||||
"coarse": "İri",
|
||||
"controlMode": "Yönetim Kipi",
|
||||
"depthAnything": "Depth Anything",
|
||||
"hedDescription": "Holistically-Nested Edge Detection (Bütünsel Yuvalanmış Kenar Tespiti)",
|
||||
"lineartAnime": "Çizim (Anime)",
|
||||
"lineartAnimeDescription": "Anime stili çizim işleme",
|
||||
"minConfidence": "Özgüven Alt Limiti",
|
||||
"pidiDescription": "PIDI görsel işleme",
|
||||
"mediapipeFace": "Mediapipe Yüz",
|
||||
"megaControl": "Aşırı Yönetim",
|
||||
"mlsd": "M-LSD",
|
||||
"setControlImageDimensions": "Yönetim Görseli Boyutlarını En/Boydan Al",
|
||||
"pidi": "PIDI",
|
||||
"scribble": "çiziktirme",
|
||||
"mediapipeFaceDescription": "Mediapipe kullanarak yüz algılama",
|
||||
"saveControlImage": "Yönetim Görselini Kaydet",
|
||||
"w": "En",
|
||||
"lineartDescription": "Görseli çizime dönüştürür",
|
||||
"maxFaces": "Yüz Üst Limiti",
|
||||
"mlsdDescription": "Minimalist Line Segment Detector (Kolay Çizgi Parçası Algılama)",
|
||||
"normalBae": "Normal BAE",
|
||||
"normalBaeDescription": "Normal BAE işleme",
|
||||
"resetControlImage": "Yönetim Görselini Kaldır",
|
||||
"lineart": "Çizim"
|
||||
},
|
||||
"queue": {
|
||||
"resumeSucceeded": "İşlem Sürdürüldü",
|
||||
"openQueue": "Sırayı Göster",
|
||||
@@ -285,11 +203,9 @@
|
||||
"starImage": "Yıldız Koy",
|
||||
"download": "İndir",
|
||||
"deleteSelection": "Seçileni Sil",
|
||||
"problemDeletingImages": "Görsel Silmede Sorun",
|
||||
"featuresWillReset": "Bu görseli silerseniz, o özellikler resetlenecektir.",
|
||||
"noImageSelected": "Görsel Seçilmedi",
|
||||
"unstarImage": "Yıldızı Kaldır",
|
||||
"problemDeletingImagesDesc": "Bir ya da daha çok görsel silinemedi",
|
||||
"gallerySettings": "Galeri Düzeni",
|
||||
"image": "görsel",
|
||||
"galleryImageSize": "Görsel Boyutu",
|
||||
@@ -299,8 +215,6 @@
|
||||
"currentlyInUse": "Bu görsel şurada kullanımda:",
|
||||
"deleteImage_one": "Görseli Sil",
|
||||
"deleteImage_other": "",
|
||||
"loadMore": "Daha Getir",
|
||||
"setCurrentImage": "Çalışma Görseli Yap",
|
||||
"unableToLoad": "Galeri Yüklenemedi",
|
||||
"downloadSelection": "Seçileni İndir",
|
||||
"dropOrUpload": "$t(gallery.drop) ya da Yükle",
|
||||
@@ -320,225 +234,7 @@
|
||||
"hotkeys": {
|
||||
"noHotkeysFound": "Kısayol Tuşu Bulanamadı",
|
||||
"searchHotkeys": "Kısayol Tuşlarında Ara",
|
||||
"clearSearch": "Aramayı Sil",
|
||||
"colorPicker": {
|
||||
"title": "Renk Seçici",
|
||||
"desc": "Tuvalde renk seçiciye geçer"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"title": "Konsolu Aç-Kapat",
|
||||
"desc": "Konsolu aç-kapat"
|
||||
},
|
||||
"hideMask": {
|
||||
"desc": "Maskeyi gizle-göster",
|
||||
"title": "Maskeyi Gizle"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"title": "İsteme Odaklan",
|
||||
"desc": "Görsel istemi alanına odaklanır"
|
||||
},
|
||||
"keyboardShortcuts": "Kısayol Tuşları",
|
||||
"nextImage": {
|
||||
"title": "Sonraki Görsel",
|
||||
"desc": "Galerideki sonraki görseli göster"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"desc": "Panelleri kapatıp çalışma alanını genişlet",
|
||||
"title": "Çalışma Alanını Genişlet"
|
||||
},
|
||||
"pinOptions": {
|
||||
"desc": "Seçenekler panelini iğnele",
|
||||
"title": "Seçenekleri İğnele"
|
||||
},
|
||||
"nodesHotkeys": "Çizgeler",
|
||||
"quickToggleMove": {
|
||||
"desc": "Geçici olarak Kayma Aracına geçer",
|
||||
"title": "Geçici Kayma"
|
||||
},
|
||||
"showHideBoundingBox": {
|
||||
"title": "Sınırlayıcı Kutuyu Gizle/Göster",
|
||||
"desc": "Sınırlayıcı kutunun görünürlüğünü değiştir"
|
||||
},
|
||||
"showInfo": {
|
||||
"desc": "Seçili görselin üstverisini göster",
|
||||
"title": "Bilgileri Göster"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"desc": "Sonraki Görsel Parçayı Göster",
|
||||
"title": "Sonraki Görsel Parça"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"desc": "Geçiçi Görsel Parçasını Onayla",
|
||||
"title": "Geçiçi Görsel Parçasını Onayla"
|
||||
},
|
||||
"changeTabs": {
|
||||
"desc": "Çalışma alanını değiştir",
|
||||
"title": "Sekmeyi değiştir"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "Panelleri Kapat",
|
||||
"desc": "Açık panelleri kapat"
|
||||
},
|
||||
"decreaseBrushOpacity": {
|
||||
"title": "Fırça Saydamlığını Artır",
|
||||
"desc": "Tuval fırçasının saydamlığını artırır"
|
||||
},
|
||||
"clearMask": {
|
||||
"title": "Maskeyi Sil",
|
||||
"desc": "Tüm maskeyi sil"
|
||||
},
|
||||
"decreaseGalleryThumbSize": {
|
||||
"desc": "Galerideki küçük görsel boyutunu düşürür",
|
||||
"title": "Küçük Görsel Boyutunu Düşür"
|
||||
},
|
||||
"deleteImage": {
|
||||
"desc": "Seçili görseli sil",
|
||||
"title": "Görseli Sil"
|
||||
},
|
||||
"invoke": {
|
||||
"desc": "Görsel Oluştur",
|
||||
"title": "Invoke"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "Küçük Görsel Boyutunu Artır",
|
||||
"desc": "Galerideki küçük görsel boyutunu artırır"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "Değişkenleri Kullan",
|
||||
"desc": "Seçili görselin tüm değişkenlerini kullan"
|
||||
},
|
||||
"setPrompt": {
|
||||
"desc": "Seçili görselin istemini kullan",
|
||||
"title": "İstemi Kullan"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"desc": "Maske/Taban katmanları arasında geçiş yapar",
|
||||
"title": "Katmanı Gizle-Göster"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "Tohumu Kullan",
|
||||
"desc": "Seçili görselin tohumunu kullan"
|
||||
},
|
||||
"appHotkeys": "Uygulama",
|
||||
"cancel": {
|
||||
"desc": "Geçerli İşi Sil",
|
||||
"title": "Vazgeç"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"title": "Görselden Görsel'e Gönder",
|
||||
"desc": "Seçili görseli Görselden Görsel'e gönder"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "Sınırlayıcı Kutuyu Doldur",
|
||||
"desc": "Sınırlayıcı kutuyu fırçadaki renkle doldurur"
|
||||
},
|
||||
"moveTool": {
|
||||
"desc": "Tuvalde kaymayı sağlar",
|
||||
"title": "Kayma Aracı"
|
||||
},
|
||||
"redoStroke": {
|
||||
"desc": "Fırça vuruşunu yinele",
|
||||
"title": "Vuruşu Yinele"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"title": "Fırçanın Saydamlığını Düşür",
|
||||
"desc": "Tuval fırçasının saydamlığını düşürür"
|
||||
},
|
||||
"selectEraser": {
|
||||
"desc": "Tuval silgisini kullan",
|
||||
"title": "Silgiyi Kullan"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"desc": "Seçenekler panelini aç-kapat",
|
||||
"title": "Seçenekleri Aç-Kapat"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"desc": "Tuval içeriğini kopyala",
|
||||
"title": "Kopyala"
|
||||
},
|
||||
"galleryHotkeys": "Galeri",
|
||||
"generalHotkeys": "Genel",
|
||||
"mergeVisible": {
|
||||
"desc": "Tuvalin görünür tüm katmanlarını birleştir",
|
||||
"title": "Katmanları Birleştir"
|
||||
},
|
||||
"toggleGallery": {
|
||||
"title": "Galeriyi Aç-Kapat",
|
||||
"desc": "Galeri panelini aç-kapat"
|
||||
},
|
||||
"downloadImage": {
|
||||
"title": "Görseli İndir",
|
||||
"desc": "Tuval içeriğini indir"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"title": "Önceki Görsel Parça",
|
||||
"desc": "Önceki Görsel Parçayı Göster"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "Fırça Boyutunu Artır",
|
||||
"desc": "Tuval fırçasının/silgisinin boyutunu artırır"
|
||||
},
|
||||
"previousImage": {
|
||||
"desc": "Galerideki önceki görseli göster",
|
||||
"title": "Önceki Görsel"
|
||||
},
|
||||
"toggleOptionsAndGallery": {
|
||||
"title": "Seçenekleri ve Galeriyi Aç-Kapat",
|
||||
"desc": "Seçenekler ve galeri panellerini aç-kapat"
|
||||
},
|
||||
"toggleSnap": {
|
||||
"desc": "Kılavuza Uydur",
|
||||
"title": "Kılavuza Uydur"
|
||||
},
|
||||
"resetView": {
|
||||
"desc": "Tuval Görüşünü Resetle",
|
||||
"title": "Görüşü Resetle"
|
||||
},
|
||||
"cancelAndClear": {
|
||||
"desc": "Geçerli işi geri çek ve sıradaki tüm işleri sil",
|
||||
"title": "Vazgeç ve Sil"
|
||||
},
|
||||
"decreaseBrushSize": {
|
||||
"title": "Fırça Boyutunu Düşür",
|
||||
"desc": "Tuval fırçasının/silgisinin boyutunu düşürür"
|
||||
},
|
||||
"resetOptionsAndGallery": {
|
||||
"desc": "Seçenekler ve galeri panellerini resetler",
|
||||
"title": "Seçenekleri ve Galeriyi Resetle"
|
||||
},
|
||||
"remixImage": {
|
||||
"desc": "Seçili görselin tohumu hariç tüm değişkenlerini kullan",
|
||||
"title": "Benzerini Türet"
|
||||
},
|
||||
"undoStroke": {
|
||||
"title": "Vuruşu Geri Al",
|
||||
"desc": "Fırça vuruşunu geri al"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "Galeriye Gönder",
|
||||
"desc": "Tuval içeriğini galeriye gönder"
|
||||
},
|
||||
"unifiedCanvasHotkeys": "Tuval",
|
||||
"addNodes": {
|
||||
"desc": "Çizge ekleme menüsünü açar",
|
||||
"title": "Çizge Ekle"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"desc": "Sınırlayıcı kutunun içini boşaltır",
|
||||
"title": "Sınırlayıcı Kutuyu Boşalt"
|
||||
},
|
||||
"selectBrush": {
|
||||
"desc": "Tuval fırçasını kullan",
|
||||
"title": "Fırçayı Kullan"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "Yüzleri Onar",
|
||||
"desc": "Geçerli görseli onar"
|
||||
}
|
||||
},
|
||||
"unifiedCanvas": {
|
||||
"accept": "Onayla",
|
||||
"clearCanvasHistoryMessage": "Tuval geçmişini silmek tuvale dokunmaz, ancak yineleme ve geri alma geçmişini geri dönülemez bir biçimde siler."
|
||||
"clearSearch": "Aramayı Sil"
|
||||
},
|
||||
"nodes": {
|
||||
"unableToValidateWorkflow": "İş Akışı Doğrulanamadı",
|
||||
@@ -596,15 +292,9 @@
|
||||
"workflowSaved": "İş Akışı Kaydedildi"
|
||||
},
|
||||
"toast": {
|
||||
"problemDownloadingCanvasDesc": "Taban katman indirilemedi",
|
||||
"problemSavingMaskDesc": "Maske kaydedilemedi",
|
||||
"problemSavingCanvasDesc": "Taban katman kaydedilemedi",
|
||||
"problemRetrievingWorkflow": "İş Akışını Getirmede Sorun",
|
||||
"workflowDeleted": "İş Akışı Silindi",
|
||||
"loadedWithWarnings": "İş Akışı Yüklendi Ancak Uyarılar Var",
|
||||
"problemImportingMaskDesc": "Maske aktarılamadı",
|
||||
"problemMergingCanvasDesc": "Taban katman aktarılamadı",
|
||||
"problemCopyingCanvasDesc": "Taban katman aktarılamadı",
|
||||
"workflowLoaded": "İş Akışı Yüklendi",
|
||||
"problemDeletingWorkflow": "İş Akışını Silmede Sorun"
|
||||
},
|
||||
@@ -612,7 +302,6 @@
|
||||
"invoke": {
|
||||
"noPrompts": "İstem oluşturulmadı",
|
||||
"noModelSelected": "Model seçilmedi",
|
||||
"incompatibleBaseModelForControlAdapter": "{{number}}. yönetim aracı, ana model ile uyumlu değil.",
|
||||
"systemDisconnected": "Sistem bağlantısı kesildi",
|
||||
"invoke": "Invoke"
|
||||
},
|
||||
@@ -642,8 +331,6 @@
|
||||
"noiseThreshold": "Gürültü Eşiği",
|
||||
"seed": "Tohum",
|
||||
"imageActions": "Görsel İşlemleri",
|
||||
"sendToImg2Img": "Görselden Görsele Aktar",
|
||||
"sendToUnifiedCanvas": "Tuvale Aktar",
|
||||
"showOptionsPanel": "Yan Paneli Göster (O ya da T)",
|
||||
"shuffle": "Kar",
|
||||
"usePrompt": "İstemi Kullan",
|
||||
@@ -680,9 +367,7 @@
|
||||
"vaePrecision": "VAE Kesinliği",
|
||||
"convertToDiffusersHelpText6": "Bu modeli dönüştürmek istiyor musunuz?",
|
||||
"deleteMsg1": "Bu modeli InvokeAI'dan silmek istediğinize emin misiniz?",
|
||||
"modelSyncFailed": "Modeller Senkronize Edilemedi",
|
||||
"settings": "Seçenekler",
|
||||
"v2_768": "v2 (768pks)",
|
||||
"vae": "VAE",
|
||||
"width": "En",
|
||||
"delete": "Sil",
|
||||
@@ -705,22 +390,15 @@
|
||||
"deleteMsg2": "Model InvokeAI ana klasöründeyse bilgisayarınızdan silinir, bu klasör dışındaysa bilgisayarınızdan silinmeyecektir.",
|
||||
"load": "Yükle",
|
||||
"modelDeleteFailed": "Model kaldırılamadı",
|
||||
"modelsSynced": "Modeller Senkronize Edildi",
|
||||
"noModelSelected": "Model Seçilmedi",
|
||||
"predictionType": "Saptama Türü",
|
||||
"selectModel": "Model Seç",
|
||||
"v2_base": "v2 (512pks)",
|
||||
"modelConversionFailed": "Model Dönüşümü Başarısız",
|
||||
"modelConverted": "Model Dönüştürüldü",
|
||||
"description": "Tanım"
|
||||
},
|
||||
"dynamicPrompts": {
|
||||
"promptsWithCount_one": "{{count}} İstem",
|
||||
"promptsWithCount_other": "{{count}} İstem"
|
||||
},
|
||||
"models": {
|
||||
"addLora": "LoRA Ekle",
|
||||
"esrganModel": "ESRGAN Modeli",
|
||||
"defaultVAE": "Varsayılan VAE",
|
||||
"lora": "LoRA",
|
||||
"noModelsAvailable": "Model yok",
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"reportBugLabel": "Повідомити про помилку",
|
||||
"settingsLabel": "Налаштування",
|
||||
"img2img": "Зображення із зображення (img2img)",
|
||||
"unifiedCanvas": "Універсальне полотно",
|
||||
"nodes": "Вузли",
|
||||
"upload": "Завантажити",
|
||||
"load": "Завантажити",
|
||||
@@ -24,204 +23,8 @@
|
||||
"galleryImageSize": "Розмір зображень",
|
||||
"gallerySettings": "Налаштування галереї",
|
||||
"autoSwitchNewImages": "Автоматично вибирати нові",
|
||||
"loadMore": "Завантажити більше",
|
||||
"noImagesInGallery": "Зображень немає"
|
||||
},
|
||||
"hotkeys": {
|
||||
"keyboardShortcuts": "Клавіатурні скорочення",
|
||||
"appHotkeys": "Гарячі клавіші програми",
|
||||
"generalHotkeys": "Загальні гарячі клавіші",
|
||||
"galleryHotkeys": "Гарячі клавіші галереї",
|
||||
"unifiedCanvasHotkeys": "Гарячі клавіші універсального полотна",
|
||||
"invoke": {
|
||||
"title": "Invoke",
|
||||
"desc": "Згенерувати зображення"
|
||||
},
|
||||
"cancel": {
|
||||
"title": "Скасувати",
|
||||
"desc": "Скасувати генерацію зображення"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"title": "Переключитися на введення запиту",
|
||||
"desc": "Перемикання на область введення запиту"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"title": "Показати/приховати параметри",
|
||||
"desc": "Відкривати і закривати панель параметрів"
|
||||
},
|
||||
"pinOptions": {
|
||||
"title": "Закріпити параметри",
|
||||
"desc": "Закріпити панель параметрів"
|
||||
},
|
||||
"toggleGallery": {
|
||||
"title": "Показати галерею",
|
||||
"desc": "Відкривати і закривати скриньку галереї"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"title": "Максимізувати робочий простір",
|
||||
"desc": "Приховати панелі і максимізувати робочу область"
|
||||
},
|
||||
"changeTabs": {
|
||||
"title": "Переключити вкладку",
|
||||
"desc": "Переключитися на іншу робочу область"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"title": "Показати консоль",
|
||||
"desc": "Відкривати і закривати консоль"
|
||||
},
|
||||
"setPrompt": {
|
||||
"title": "Використовувати запит",
|
||||
"desc": "Використати запит із поточного зображення"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "Використовувати сід",
|
||||
"desc": "Використовувати сід поточного зображення"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "Використовувати всі параметри",
|
||||
"desc": "Використовувати всі параметри поточного зображення"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "Відновити обличчя",
|
||||
"desc": "Відновити обличчя на поточному зображенні"
|
||||
},
|
||||
"showInfo": {
|
||||
"title": "Показати метадані",
|
||||
"desc": "Показати метадані з поточного зображення"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"title": "Відправити в img2img",
|
||||
"desc": "Надіслати поточне зображення в Image To Image"
|
||||
},
|
||||
"deleteImage": {
|
||||
"title": "Видалити зображення",
|
||||
"desc": "Видалити поточне зображення"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "Закрити панелі",
|
||||
"desc": "Закриває відкриті панелі"
|
||||
},
|
||||
"previousImage": {
|
||||
"title": "Попереднє зображення",
|
||||
"desc": "Відображати попереднє зображення в галереї"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "Наступне зображення",
|
||||
"desc": "Відображення наступного зображення в галереї"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "Збільшити розмір мініатюр галереї",
|
||||
"desc": "Збільшує розмір мініатюр галереї"
|
||||
},
|
||||
"decreaseGalleryThumbSize": {
|
||||
"title": "Зменшує розмір мініатюр галереї",
|
||||
"desc": "Зменшує розмір мініатюр галереї"
|
||||
},
|
||||
"selectBrush": {
|
||||
"title": "Вибрати пензель",
|
||||
"desc": "Вибирає пензель для полотна"
|
||||
},
|
||||
"selectEraser": {
|
||||
"title": "Вибрати ластик",
|
||||
"desc": "Вибирає ластик для полотна"
|
||||
},
|
||||
"decreaseBrushSize": {
|
||||
"title": "Зменшити розмір пензля",
|
||||
"desc": "Зменшує розмір пензля/ластика полотна"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "Збільшити розмір пензля",
|
||||
"desc": "Збільшує розмір пензля/ластика полотна"
|
||||
},
|
||||
"decreaseBrushOpacity": {
|
||||
"title": "Зменшити непрозорість пензля",
|
||||
"desc": "Зменшує непрозорість пензля полотна"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"title": "Збільшити непрозорість пензля",
|
||||
"desc": "Збільшує непрозорість пензля полотна"
|
||||
},
|
||||
"moveTool": {
|
||||
"title": "Інструмент переміщення",
|
||||
"desc": "Дозволяє переміщатися по полотну"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "Заповнити обмежувальну рамку",
|
||||
"desc": "Заповнює обмежувальну рамку кольором пензля"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"title": "Стерти обмежувальну рамку",
|
||||
"desc": "Стирає область обмежувальної рамки"
|
||||
},
|
||||
"colorPicker": {
|
||||
"title": "Вибрати колір",
|
||||
"desc": "Вибирає засіб вибору кольору полотна"
|
||||
},
|
||||
"toggleSnap": {
|
||||
"title": "Увімкнути прив'язку",
|
||||
"desc": "Вмикає/вимикає прив'язку до сітки"
|
||||
},
|
||||
"quickToggleMove": {
|
||||
"title": "Швидке перемикання переміщення",
|
||||
"desc": "Тимчасово перемикає режим переміщення"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"title": "Переключити шар",
|
||||
"desc": "Перемикання маски/базового шару"
|
||||
},
|
||||
"clearMask": {
|
||||
"title": "Очистити маску",
|
||||
"desc": "Очистити всю маску"
|
||||
},
|
||||
"hideMask": {
|
||||
"title": "Приховати маску",
|
||||
"desc": "Приховує/показує маску"
|
||||
},
|
||||
"showHideBoundingBox": {
|
||||
"title": "Показати/приховати обмежувальну рамку",
|
||||
"desc": "Переключити видимість обмежувальної рамки"
|
||||
},
|
||||
"mergeVisible": {
|
||||
"title": "Об'єднати видимі",
|
||||
"desc": "Об'єднати всі видимі шари полотна"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "Зберегти в галерею",
|
||||
"desc": "Зберегти поточне полотно в галерею"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "Копіювати в буфер обміну",
|
||||
"desc": "Копіювати поточне полотно в буфер обміну"
|
||||
},
|
||||
"downloadImage": {
|
||||
"title": "Завантажити зображення",
|
||||
"desc": "Завантажити вміст полотна"
|
||||
},
|
||||
"undoStroke": {
|
||||
"title": "Скасувати пензель",
|
||||
"desc": "Скасувати мазок пензля"
|
||||
},
|
||||
"redoStroke": {
|
||||
"title": "Повторити мазок пензля",
|
||||
"desc": "Повторити мазок пензля"
|
||||
},
|
||||
"resetView": {
|
||||
"title": "Вид за замовчуванням",
|
||||
"desc": "Скинути вид полотна"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"title": "Попереднє зображення",
|
||||
"desc": "Попереднє зображення"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"title": "Наступне зображення",
|
||||
"desc": "Наступне зображення"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"title": "Прийняти зображення",
|
||||
"desc": "Прийняти поточне зображення"
|
||||
}
|
||||
},
|
||||
"modelManager": {
|
||||
"modelManager": "Менеджер моделей",
|
||||
"model": "Модель",
|
||||
@@ -249,8 +52,6 @@
|
||||
"convertToDiffusersHelpText3": "Файл моделі на диску НЕ буде видалено або змінено. Ви можете знову додати його в Model Manager, якщо потрібно.",
|
||||
"alpha": "Альфа",
|
||||
"repo_id": "ID репозиторію",
|
||||
"v2_base": "v2 (512px)",
|
||||
"v2_768": "v2 (768px)",
|
||||
"convertToDiffusersHelpText5": "Переконайтеся, що у вас достатньо місця на диску. Моделі зазвичай займають від 4 до 7 Гб.",
|
||||
"convertToDiffusersHelpText6": "Ви хочете перетворити цю модель?",
|
||||
"modelConverted": "Модель перетворено",
|
||||
@@ -279,8 +80,6 @@
|
||||
"scaledHeight": "Масштаб В",
|
||||
"infillMethod": "Засіб заповнення",
|
||||
"tileSize": "Розмір області",
|
||||
"sendToImg2Img": "Надіслати у img2img",
|
||||
"sendToUnifiedCanvas": "Надіслати на полотно",
|
||||
"downloadImage": "Завантажити",
|
||||
"usePrompt": "Використати запит",
|
||||
"useSeed": "Використати сід",
|
||||
@@ -296,7 +95,6 @@
|
||||
"models": "Моделі",
|
||||
"displayInProgress": "Показувати процес генерації",
|
||||
"confirmOnDelete": "Підтверджувати видалення",
|
||||
"enableImageDebugging": "Увімкнути налагодження",
|
||||
"resetWebUI": "Повернути початкові",
|
||||
"resetWebUIDesc1": "Скидання настройок веб-інтерфейсу видаляє лише локальний кеш браузера з вашими зображеннями та налаштуваннями. Це не призводить до видалення зображень з диску.",
|
||||
"resetWebUIDesc2": "Якщо зображення не відображаються в галереї або не працює ще щось, спробуйте скинути налаштування, перш ніж повідомляти про проблему на GitHub.",
|
||||
@@ -305,76 +103,11 @@
|
||||
"toast": {
|
||||
"uploadFailed": "Не вдалося завантажити",
|
||||
"imageCopied": "Зображення скопійоване",
|
||||
"imageNotLoadedDesc": "Не знайдено зображення для надсилання до img2img",
|
||||
"canvasMerged": "Полотно об'єднане",
|
||||
"sentToImageToImage": "Надіслати до img2img",
|
||||
"sentToUnifiedCanvas": "Надіслати на полотно",
|
||||
"parametersNotSet": "Параметри не задані",
|
||||
"metadataLoadFailed": "Не вдалося завантажити метадані",
|
||||
"serverError": "Помилка сервера",
|
||||
"connected": "Підключено до сервера",
|
||||
"canceled": "Обробку скасовано"
|
||||
},
|
||||
"tooltip": {
|
||||
"feature": {
|
||||
"prompt": "Це поле для тексту запиту, включаючи об'єкти генерації та стилістичні терміни. У запит можна включити і коефіцієнти ваги (значущості токена), але консольні команди та параметри не працюватимуть.",
|
||||
"gallery": "Тут відображаються генерації з папки outputs у міру їх появи.",
|
||||
"other": "Ці опції включають альтернативні режими обробки для Invoke. 'Безшовний узор' створить на виході узори, що повторюються. 'Висока роздільна здатність' - це генерація у два етапи за допомогою img2img: використовуйте це налаштування, коли хочете отримати цільне зображення більшого розміру без артефактів.",
|
||||
"seed": "Значення сіду впливає на початковий шум, з якого сформується зображення. Можна використовувати вже наявний сід із попередніх зображень. 'Поріг шуму' використовується для пом'якшення артефактів при високих значеннях CFG (спробуйте в діапазоні 0-10), а 'Перлін' - для додавання шуму Перліна в процесі генерації: обидва параметри служать для більшої варіативності результатів.",
|
||||
"upscale": "Використовуйте ESRGAN, щоб збільшити зображення відразу після генерації.",
|
||||
"boundingBox": "'Обмежуюча рамка' аналогічна налаштуванням 'Ширина' і 'Висота' для 'Зображення з тексту' або 'Зображення до зображення'. Буде оброблена тільки область у рамці."
|
||||
}
|
||||
},
|
||||
"unifiedCanvas": {
|
||||
"layer": "Шар",
|
||||
"base": "Базовий",
|
||||
"mask": "Маска",
|
||||
"maskingOptions": "Параметри маски",
|
||||
"enableMask": "Увiмкнути маску",
|
||||
"preserveMaskedArea": "Зберiгати замасковану область",
|
||||
"clearMask": "Очистити маску",
|
||||
"brush": "Пензель",
|
||||
"eraser": "Гумка",
|
||||
"fillBoundingBox": "Заповнити обмежуючу рамку",
|
||||
"eraseBoundingBox": "Стерти обмежуючу рамку",
|
||||
"colorPicker": "Пiпетка",
|
||||
"brushOptions": "Параметри пензля",
|
||||
"brushSize": "Розмiр",
|
||||
"move": "Перемiстити",
|
||||
"resetView": "Скинути вигляд",
|
||||
"mergeVisible": "Об'єднати видимi",
|
||||
"saveToGallery": "Зберегти до галереї",
|
||||
"copyToClipboard": "Копiювати до буферу обмiну",
|
||||
"downloadAsImage": "Завантажити як зображення",
|
||||
"undo": "Вiдмiнити",
|
||||
"redo": "Повторити",
|
||||
"clearCanvas": "Очистити полотно",
|
||||
"canvasSettings": "Налаштування полотна",
|
||||
"showIntermediates": "Показувати процес",
|
||||
"showGrid": "Показувати сiтку",
|
||||
"snapToGrid": "Прив'язати до сітки",
|
||||
"darkenOutsideSelection": "Затемнити полотно зовні",
|
||||
"autoSaveToGallery": "Автозбереження до галереї",
|
||||
"saveBoxRegionOnly": "Зберiгати тiльки видiлення",
|
||||
"limitStrokesToBox": "Обмежити штрихи виділенням",
|
||||
"showCanvasDebugInfo": "Показати дод. інформацію про полотно",
|
||||
"clearCanvasHistory": "Очистити iсторiю полотна",
|
||||
"clearHistory": "Очистити iсторiю",
|
||||
"clearCanvasHistoryMessage": "Очищення історії полотна залишає поточне полотно незайманим, але видаляє історію скасування та повтору.",
|
||||
"clearCanvasHistoryConfirm": "Ви впевнені, що хочете очистити історію полотна?",
|
||||
"activeLayer": "Активний шар",
|
||||
"canvasScale": "Масштаб полотна",
|
||||
"boundingBox": "Обмежуюча рамка",
|
||||
"scaledBoundingBox": "Масштабування рамки",
|
||||
"boundingBoxPosition": "Позиція обмежуючої рамки",
|
||||
"canvasDimensions": "Разміри полотна",
|
||||
"canvasPosition": "Розташування полотна",
|
||||
"cursorPosition": "Розташування курсора",
|
||||
"previous": "Попереднє",
|
||||
"next": "Наступне",
|
||||
"accept": "Приняти",
|
||||
"discardAll": "Відмінити все"
|
||||
},
|
||||
"accessibility": {
|
||||
"nextImage": "Наступне зображення",
|
||||
"invokeProgressBar": "Індикатор виконання",
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"reportBugLabel": "反馈错误",
|
||||
"settingsLabel": "设置",
|
||||
"img2img": "图生图",
|
||||
"unifiedCanvas": "统一画布",
|
||||
"nodes": "工作流",
|
||||
"upload": "上传",
|
||||
"load": "加载",
|
||||
@@ -26,7 +25,6 @@
|
||||
"batch": "批次管理器",
|
||||
"communityLabel": "社区",
|
||||
"modelManager": "模型管理器",
|
||||
"nodeEditor": "节点编辑器",
|
||||
"imageFailedToLoad": "无法加载图像",
|
||||
"learnMore": "了解更多",
|
||||
"advanced": "高级",
|
||||
@@ -68,12 +66,9 @@
|
||||
"or": "或",
|
||||
"aboutDesc": "使用 Invoke 工作?来看看:",
|
||||
"add": "添加",
|
||||
"loglevel": "日志级别",
|
||||
"copy": "复制",
|
||||
"localSystem": "本地系统",
|
||||
"aboutHeading": "掌握你的创造力",
|
||||
"comparing": "对比中",
|
||||
"comparingDesc": "正在对比两张图片",
|
||||
"enabled": "已启用",
|
||||
"disabled": "已禁用",
|
||||
"red": "红",
|
||||
@@ -81,12 +76,8 @@
|
||||
"positivePrompt": "正向提示词",
|
||||
"negativePrompt": "反向提示词",
|
||||
"selected": "选中的",
|
||||
"viewing": "查看",
|
||||
"viewingDesc": "在大型画廊视图中查看图片",
|
||||
"editing": "编辑中",
|
||||
"green": "绿",
|
||||
"blue": "蓝",
|
||||
"editingDesc": "在控制图层画布上编辑",
|
||||
"goTo": "前往",
|
||||
"dontShowMeThese": "请勿显示这些内容",
|
||||
"beta": "测试版",
|
||||
@@ -97,7 +88,6 @@
|
||||
"galleryImageSize": "预览大小",
|
||||
"gallerySettings": "预览设置",
|
||||
"autoSwitchNewImages": "自动切换到新图像",
|
||||
"loadMore": "加载更多",
|
||||
"noImagesInGallery": "无图像可用于显示",
|
||||
"deleteImage_other": "删除{{count}}张图片",
|
||||
"deleteImagePermanent": "删除的图片无法被恢复。",
|
||||
@@ -109,7 +99,6 @@
|
||||
"currentlyInUse": "该图像目前在以下功能中使用:",
|
||||
"copy": "复制",
|
||||
"download": "下载",
|
||||
"setCurrentImage": "设为当前图像",
|
||||
"downloadSelection": "下载所选内容",
|
||||
"noImageSelected": "无选中的图像",
|
||||
"deleteSelection": "删除所选内容",
|
||||
@@ -117,8 +106,6 @@
|
||||
"drop": "弃用",
|
||||
"dropOrUpload": "$t(gallery.drop) 或上传",
|
||||
"dropToUpload": "$t(gallery.drop) 以上传",
|
||||
"problemDeletingImagesDesc": "有一张或多张图像无法被删除",
|
||||
"problemDeletingImages": "删除图像时出现问题",
|
||||
"unstarImage": "取消收藏图像",
|
||||
"starImage": "收藏图像",
|
||||
"alwaysShowImageSizeBadge": "始终显示图像尺寸",
|
||||
@@ -133,11 +120,9 @@
|
||||
"viewerImage": "查看器图像",
|
||||
"compareImage": "对比图像",
|
||||
"openInViewer": "在查看器中打开",
|
||||
"selectAllOnBoard": "选择板块全部",
|
||||
"hover": "悬停",
|
||||
"selectAllOnPage": "选择本页全部",
|
||||
"swapImages": "交换图像",
|
||||
"compareOptions": "比较选项",
|
||||
"exitBoardSearch": "退出面板搜索",
|
||||
"exitSearch": "退出搜索",
|
||||
"oldestFirst": "最旧在前",
|
||||
@@ -158,231 +143,9 @@
|
||||
"go": "运行"
|
||||
},
|
||||
"hotkeys": {
|
||||
"keyboardShortcuts": "快捷键",
|
||||
"appHotkeys": "应用",
|
||||
"generalHotkeys": "一般",
|
||||
"galleryHotkeys": "图库",
|
||||
"unifiedCanvasHotkeys": "统一画布",
|
||||
"invoke": {
|
||||
"title": "Invoke",
|
||||
"desc": "生成图像"
|
||||
},
|
||||
"cancel": {
|
||||
"title": "取消",
|
||||
"desc": "取消当前队列项目"
|
||||
},
|
||||
"focusPrompt": {
|
||||
"title": "打开提示词框",
|
||||
"desc": "打开提示词文本框"
|
||||
},
|
||||
"toggleOptions": {
|
||||
"title": "切换选项卡",
|
||||
"desc": "打开或关闭选项浮窗"
|
||||
},
|
||||
"pinOptions": {
|
||||
"title": "常开选项卡",
|
||||
"desc": "保持选项浮窗常开"
|
||||
},
|
||||
"toggleGallery": {
|
||||
"title": "切换图库",
|
||||
"desc": "打开或关闭图库"
|
||||
},
|
||||
"maximizeWorkSpace": {
|
||||
"title": "工作区最大化",
|
||||
"desc": "关闭所有浮窗,将工作区域最大化"
|
||||
},
|
||||
"changeTabs": {
|
||||
"title": "切换选项卡",
|
||||
"desc": "切换到另一个工作区"
|
||||
},
|
||||
"consoleToggle": {
|
||||
"title": "切换命令行",
|
||||
"desc": "打开或关闭命令行"
|
||||
},
|
||||
"setPrompt": {
|
||||
"title": "使用当前提示词",
|
||||
"desc": "使用当前图像的提示词"
|
||||
},
|
||||
"setSeed": {
|
||||
"title": "使用种子",
|
||||
"desc": "使用当前图像的种子"
|
||||
},
|
||||
"setParameters": {
|
||||
"title": "使用当前参数",
|
||||
"desc": "使用当前图像的所有参数"
|
||||
},
|
||||
"restoreFaces": {
|
||||
"title": "面部修复",
|
||||
"desc": "对当前图像进行面部修复"
|
||||
},
|
||||
"showInfo": {
|
||||
"title": "显示信息",
|
||||
"desc": "显示当前图像的元数据"
|
||||
},
|
||||
"sendToImageToImage": {
|
||||
"title": "发送到图生图",
|
||||
"desc": "发送当前图像到图生图"
|
||||
},
|
||||
"deleteImage": {
|
||||
"title": "删除图像",
|
||||
"desc": "删除当前图像"
|
||||
},
|
||||
"closePanels": {
|
||||
"title": "关闭浮窗",
|
||||
"desc": "关闭目前打开的浮窗"
|
||||
},
|
||||
"previousImage": {
|
||||
"title": "上一张图像",
|
||||
"desc": "显示图库中的上一张图像"
|
||||
},
|
||||
"nextImage": {
|
||||
"title": "下一张图像",
|
||||
"desc": "显示图库中的下一张图像"
|
||||
},
|
||||
"increaseGalleryThumbSize": {
|
||||
"title": "增大预览尺寸",
|
||||
"desc": "增大图库中预览的尺寸"
|
||||
},
|
||||
"decreaseGalleryThumbSize": {
|
||||
"title": "缩小预览尺寸",
|
||||
"desc": "缩小图库中预览的尺寸"
|
||||
},
|
||||
"selectBrush": {
|
||||
"title": "选择刷子",
|
||||
"desc": "选择统一画布上的刷子"
|
||||
},
|
||||
"selectEraser": {
|
||||
"title": "选择橡皮擦",
|
||||
"desc": "选择统一画布上的橡皮擦"
|
||||
},
|
||||
"decreaseBrushSize": {
|
||||
"title": "减小刷子大小",
|
||||
"desc": "减小统一画布上的刷子或橡皮擦的大小"
|
||||
},
|
||||
"increaseBrushSize": {
|
||||
"title": "增大刷子大小",
|
||||
"desc": "增大统一画布上的刷子或橡皮擦的大小"
|
||||
},
|
||||
"decreaseBrushOpacity": {
|
||||
"title": "减小刷子不透明度",
|
||||
"desc": "减小统一画布上的刷子的不透明度"
|
||||
},
|
||||
"increaseBrushOpacity": {
|
||||
"title": "增大刷子不透明度",
|
||||
"desc": "增大统一画布上的刷子的不透明度"
|
||||
},
|
||||
"moveTool": {
|
||||
"title": "移动工具",
|
||||
"desc": "画布允许导航"
|
||||
},
|
||||
"fillBoundingBox": {
|
||||
"title": "填充选择区域",
|
||||
"desc": "在选择区域中填充刷子颜色"
|
||||
},
|
||||
"eraseBoundingBox": {
|
||||
"title": "擦除选择框",
|
||||
"desc": "将选择区域擦除"
|
||||
},
|
||||
"colorPicker": {
|
||||
"title": "选择颜色拾取工具",
|
||||
"desc": "选择画布颜色拾取工具"
|
||||
},
|
||||
"toggleSnap": {
|
||||
"title": "切换网格对齐",
|
||||
"desc": "打开或关闭网格对齐"
|
||||
},
|
||||
"quickToggleMove": {
|
||||
"title": "快速切换移动模式",
|
||||
"desc": "临时性地切换移动模式"
|
||||
},
|
||||
"toggleLayer": {
|
||||
"title": "切换图层",
|
||||
"desc": "切换遮罩/基础层的选择"
|
||||
},
|
||||
"clearMask": {
|
||||
"title": "清除遮罩",
|
||||
"desc": "清除整个遮罩"
|
||||
},
|
||||
"hideMask": {
|
||||
"title": "隐藏遮罩",
|
||||
"desc": "隐藏或显示遮罩"
|
||||
},
|
||||
"showHideBoundingBox": {
|
||||
"title": "显示/隐藏框选区",
|
||||
"desc": "切换框选区的的显示状态"
|
||||
},
|
||||
"mergeVisible": {
|
||||
"title": "合并可见层",
|
||||
"desc": "将画板上可见层合并"
|
||||
},
|
||||
"saveToGallery": {
|
||||
"title": "保存至图库",
|
||||
"desc": "将画布当前内容保存至图库"
|
||||
},
|
||||
"copyToClipboard": {
|
||||
"title": "复制到剪贴板",
|
||||
"desc": "将画板当前内容复制到剪贴板"
|
||||
},
|
||||
"downloadImage": {
|
||||
"title": "下载图像",
|
||||
"desc": "下载画板当前内容"
|
||||
},
|
||||
"undoStroke": {
|
||||
"title": "撤销画笔",
|
||||
"desc": "撤销上一笔刷子的动作"
|
||||
},
|
||||
"redoStroke": {
|
||||
"title": "重做画笔",
|
||||
"desc": "重做上一笔刷子的动作"
|
||||
},
|
||||
"resetView": {
|
||||
"title": "重置视图",
|
||||
"desc": "重置画布视图"
|
||||
},
|
||||
"previousStagingImage": {
|
||||
"title": "上一张暂存图像",
|
||||
"desc": "上一张暂存区中的图像"
|
||||
},
|
||||
"nextStagingImage": {
|
||||
"title": "下一张暂存图像",
|
||||
"desc": "下一张暂存区中的图像"
|
||||
},
|
||||
"acceptStagingImage": {
|
||||
"title": "接受暂存图像",
|
||||
"desc": "接受当前暂存区中的图像"
|
||||
},
|
||||
"nodesHotkeys": "节点",
|
||||
"addNodes": {
|
||||
"title": "添加节点",
|
||||
"desc": "打开添加节点菜单"
|
||||
},
|
||||
"cancelAndClear": {
|
||||
"desc": "取消当前队列项目并且清除所有待定项目",
|
||||
"title": "取消和清除"
|
||||
},
|
||||
"resetOptionsAndGallery": {
|
||||
"title": "重置选项和图库",
|
||||
"desc": "重置选项和图库面板"
|
||||
},
|
||||
"searchHotkeys": "检索快捷键",
|
||||
"noHotkeysFound": "未找到快捷键",
|
||||
"toggleOptionsAndGallery": {
|
||||
"desc": "打开和关闭选项和图库面板",
|
||||
"title": "开关选项和图库"
|
||||
},
|
||||
"clearSearch": "清除检索项",
|
||||
"toggleViewer": {
|
||||
"desc": "在当前标签页的图片查看模式和编辑工作区之间切换.",
|
||||
"title": "切换图片查看器"
|
||||
},
|
||||
"postProcess": {
|
||||
"desc": "使用选定的后期处理模型对当前图像进行处理",
|
||||
"title": "处理图像"
|
||||
},
|
||||
"remixImage": {
|
||||
"title": "重新混合图像",
|
||||
"desc": "使用当前图像的所有参数,但不包括随机种子"
|
||||
}
|
||||
"clearSearch": "清除检索项"
|
||||
},
|
||||
"modelManager": {
|
||||
"modelManager": "模型管理器",
|
||||
@@ -409,18 +172,14 @@
|
||||
"convertToDiffusersHelpText2": "这个过程会替换你的模型管理器的入口中相同 Diffusers 版本的模型。",
|
||||
"convertToDiffusersHelpText4": "这是一次性的处理过程。根据你电脑的配置不同耗时 30 - 60 秒。",
|
||||
"convertToDiffusersHelpText6": "你希望转换这个模型吗?",
|
||||
"v2_768": "v2 (768px)",
|
||||
"allModels": "全部模型",
|
||||
"convertToDiffusers": "转换为 Diffusers",
|
||||
"repo_id": "项目 ID",
|
||||
"modelConverted": "模型已转换",
|
||||
"convertToDiffusersHelpText3": "磁盘中放置在 InvokeAI 根文件夹的 checkpoint 文件会被删除. 若位于自定义目录, 则不会受影响.",
|
||||
"v2_base": "v2 (512px)",
|
||||
"convertToDiffusersHelpText5": "请确认你有足够的磁盘空间,模型大小通常在 2 GB - 7 GB 之间。",
|
||||
"convert": "转换",
|
||||
"none": "无",
|
||||
"modelsSynced": "模型已同步",
|
||||
"modelSyncFailed": "模型同步失败",
|
||||
"modelDeleteFailed": "模型删除失败",
|
||||
"selectModel": "选择模型",
|
||||
"settings": "设置",
|
||||
@@ -443,10 +202,8 @@
|
||||
"path": "路径",
|
||||
"pathToConfig": "配置路径",
|
||||
"cancel": "取消",
|
||||
"hfTokenUnableToVerify": "无法验证HuggingFace token",
|
||||
"install": "安装",
|
||||
"simpleModelPlaceholder": "本地文件或diffusers文件夹的URL或路径",
|
||||
"hfTokenInvalidErrorMessage": "无效或缺失的HuggingFace token.",
|
||||
"noModelsInstalledDesc1": "安装模型时使用",
|
||||
"inplaceInstallDesc": "安装模型时,不复制文件,直接从原位置加载。如果关闭此选项,模型文件将在安装过程中被复制到Invoke管理的模型文件夹中.",
|
||||
"installAll": "安装全部",
|
||||
@@ -464,10 +221,7 @@
|
||||
"pruneTooltip": "清理队列中已完成的导入任务",
|
||||
"urlOrLocalPath": "链接或本地路径",
|
||||
"localOnly": "仅本地",
|
||||
"hfTokenHelperText": "需要HuggingFace token才能使用Checkpoint模型。点击此处创建或获取您的token.",
|
||||
"huggingFaceHelper": "如果在此代码库中检测到多个模型,系统将提示您选择其中一个进行安装.",
|
||||
"hfTokenUnableToVerifyErrorMessage": "无法验证HuggingFace token.可能是网络问题所致.请稍后再试.",
|
||||
"hfTokenSaved": "HuggingFace token已保存",
|
||||
"imageEncoderModelId": "图像编码器模型ID",
|
||||
"modelImageUpdated": "模型图像已更新",
|
||||
"modelName": "模型名称",
|
||||
@@ -478,8 +232,6 @@
|
||||
"main": "主界面",
|
||||
"starterModels": "初始模型",
|
||||
"installQueue": "安装队列",
|
||||
"hfTokenInvalidErrorMessage2": "更新于其中 ",
|
||||
"hfTokenInvalid": "无效或缺失的HuggingFace token",
|
||||
"mainModelTriggerPhrases": "主模型触发词",
|
||||
"typePhraseHere": "在此输入触发词",
|
||||
"triggerPhrases": "触发词",
|
||||
@@ -519,8 +271,6 @@
|
||||
"scaledHeight": "缩放长度",
|
||||
"infillMethod": "填充方法",
|
||||
"tileSize": "方格尺寸",
|
||||
"sendToImg2Img": "发送到图生图",
|
||||
"sendToUnifiedCanvas": "发送到统一画布",
|
||||
"downloadImage": "下载图像",
|
||||
"usePrompt": "使用提示",
|
||||
"useSeed": "使用种子",
|
||||
@@ -545,30 +295,21 @@
|
||||
"noNodesInGraph": "节点图中无节点",
|
||||
"noModelSelected": "无已选中的模型",
|
||||
"invoke": "调用",
|
||||
"noInitialImageSelected": "无选中的初始图像",
|
||||
"missingInputForField": "{{nodeLabel}} -> {{fieldLabel}} 缺失输入",
|
||||
"systemDisconnected": "系统已断开连接",
|
||||
"missingNodeTemplate": "缺失节点模板",
|
||||
"missingFieldTemplate": "缺失模板",
|
||||
"addingImagesTo": "添加图像到",
|
||||
"noPrompts": "没有已生成的提示词",
|
||||
"noControlImageForControlAdapter": "有 #{{number}} 个 Control Adapter 缺失控制图像",
|
||||
"noModelForControlAdapter": "有 #{{number}} 个 Control Adapter 没有选择模型。",
|
||||
"incompatibleBaseModelForControlAdapter": "有 #{{number}} 个 Control Adapter 模型与主模型不兼容。",
|
||||
"layer": {
|
||||
"initialImageNoImageSelected": "未选择初始图像",
|
||||
"controlAdapterImageNotProcessed": "Control Adapter图像尚未处理",
|
||||
"ipAdapterNoModelSelected": "未选择IP adapter",
|
||||
"controlAdapterNoModelSelected": "未选择Control Adapter模型",
|
||||
"controlAdapterNoImageSelected": "未选择Control Adapter图像",
|
||||
"rgNoPromptsOrIPAdapters": "无文本提示或IP Adapters",
|
||||
"controlAdapterIncompatibleBaseModel": "Control Adapter的基础模型不兼容",
|
||||
"ipAdapterIncompatibleBaseModel": "IP Adapter的基础模型不兼容",
|
||||
"t2iAdapterIncompatibleDimensions": "T2I Adapter需要图像尺寸为{{multiple}}的倍数",
|
||||
"ipAdapterNoImageSelected": "未选择IP Adapter图像",
|
||||
"rgNoRegion": "未选择区域"
|
||||
},
|
||||
"imageNotProcessedForControlAdapter": "Control Adapter #{{number}} 的图像未处理"
|
||||
}
|
||||
},
|
||||
"patchmatchDownScaleSize": "缩小",
|
||||
"clipSkip": "CLIP 跳过层",
|
||||
@@ -584,18 +325,11 @@
|
||||
"swapDimensions": "交换尺寸",
|
||||
"aspect": "纵横",
|
||||
"setToOptimalSizeTooLarge": "$t(parameters.setToOptimalSize) (可能过大)",
|
||||
"globalNegativePromptPlaceholder": "全局反向提示词",
|
||||
"remixImage": "重新混合图像",
|
||||
"coherenceEdgeSize": "边缘尺寸",
|
||||
"postProcessing": "后处理(Shift + U)",
|
||||
"infillMosaicTileWidth": "瓦片宽度",
|
||||
"sendToUpscale": "发送到放大",
|
||||
"processImage": "处理图像",
|
||||
"globalPositivePromptPlaceholder": "全局正向提示词",
|
||||
"globalSettings": "全局设置",
|
||||
"infillMosaicTileHeight": "瓦片高度",
|
||||
"infillMosaicMinColor": "最小颜色",
|
||||
"infillMosaicMaxColor": "最大颜色",
|
||||
"infillColorValue": "填充颜色",
|
||||
"coherenceMinDenoise": "最小去噪"
|
||||
},
|
||||
@@ -603,7 +337,6 @@
|
||||
"models": "模型",
|
||||
"displayInProgress": "显示处理中的图像",
|
||||
"confirmOnDelete": "删除时确认",
|
||||
"enableImageDebugging": "开启图像调试",
|
||||
"resetWebUI": "重置网页界面",
|
||||
"resetWebUIDesc1": "重置网页只会重置浏览器中缓存的图像和设置,不会删除任何图像。",
|
||||
"resetWebUIDesc2": "如果图像没有显示在图库中,或者其他东西不工作,请在GitHub上提交问题之前尝试重置。",
|
||||
@@ -613,7 +346,6 @@
|
||||
"generation": "生成",
|
||||
"ui": "用户界面",
|
||||
"general": "通用",
|
||||
"shouldLogToConsole": "终端日志",
|
||||
"developer": "开发者",
|
||||
"beta": "Beta",
|
||||
"clearIntermediates": "清除中间产物",
|
||||
@@ -634,12 +366,7 @@
|
||||
"toast": {
|
||||
"uploadFailed": "上传失败",
|
||||
"imageCopied": "图像已复制",
|
||||
"imageNotLoadedDesc": "找不到图片",
|
||||
"canvasMerged": "画布已合并",
|
||||
"sentToImageToImage": "已发送到图生图",
|
||||
"sentToUnifiedCanvas": "已发送到统一画布",
|
||||
"parametersNotSet": "参数未恢复",
|
||||
"metadataLoadFailed": "加载元数据失败",
|
||||
"uploadFailedInvalidUploadDesc": "必须是单张的 PNG 或 JPEG 图片",
|
||||
"connected": "服务器连接",
|
||||
"parameterSet": "参数已恢复",
|
||||
@@ -648,37 +375,14 @@
|
||||
"canceled": "处理取消",
|
||||
"problemCopyingImage": "无法复制图像",
|
||||
"modelAddedSimple": "模型已加入队列",
|
||||
"imageSavingFailed": "图像保存失败",
|
||||
"canvasSentControlnetAssets": "画布已发送到 ControlNet & 素材",
|
||||
"problemCopyingCanvasDesc": "无法导出基础层",
|
||||
"loadedWithWarnings": "已加载带有警告的工作流",
|
||||
"setInitialImage": "设为初始图像",
|
||||
"canvasCopiedClipboard": "画布已复制到剪贴板",
|
||||
"setControlImage": "设为控制图像",
|
||||
"setNodeField": "设为节点字段",
|
||||
"problemSavingMask": "保存遮罩时出现问题",
|
||||
"problemSavingCanvasDesc": "无法导出基础层",
|
||||
"maskSavedAssets": "遮罩已保存到素材",
|
||||
"problemDownloadingCanvas": "下载画布时出现问题",
|
||||
"problemMergingCanvas": "合并画布时出现问题",
|
||||
"setCanvasInitialImage": "设定画布初始图像",
|
||||
"imageUploaded": "图像已上传",
|
||||
"addedToBoard": "已添加到面板",
|
||||
"workflowLoaded": "工作流已加载",
|
||||
"problemImportingMaskDesc": "无法导出遮罩",
|
||||
"problemCopyingCanvas": "复制画布时出现问题",
|
||||
"problemSavingCanvas": "保存画布时出现问题",
|
||||
"canvasDownloaded": "画布已下载",
|
||||
"problemMergingCanvasDesc": "无法导出基础层",
|
||||
"problemDownloadingCanvasDesc": "无法导出基础层",
|
||||
"problemSavingMaskDesc": "无法导出遮罩",
|
||||
"imageSaved": "图像已保存",
|
||||
"maskSentControlnetAssets": "遮罩已发送到 ControlNet & 素材",
|
||||
"canvasSavedGallery": "画布已保存到图库",
|
||||
"imageUploadFailed": "图像上传失败",
|
||||
"problemImportingMask": "导入遮罩时出现问题",
|
||||
"baseModelChangedCleared_other": "已清除或禁用{{count}}个不兼容的子模型",
|
||||
"setAsCanvasInitialImage": "设为画布初始图像",
|
||||
"invalidUpload": "无效的上传",
|
||||
"problemDeletingWorkflow": "删除工作流时出现问题",
|
||||
"workflowDeleted": "已删除工作流",
|
||||
@@ -687,14 +391,12 @@
|
||||
"problemDownloadingImage": "无法下载图像",
|
||||
"outOfMemoryError": "内存不足错误",
|
||||
"parameters": "参数",
|
||||
"resetInitialImage": "重置初始图像",
|
||||
"parameterNotSetDescWithMessage": "无法恢复 {{parameter}}: {{message}}",
|
||||
"parameterSetDesc": "已恢复 {{parameter}}",
|
||||
"parameterNotSetDesc": "无法恢复{{parameter}}",
|
||||
"sessionRef": "会话: {{sessionId}}",
|
||||
"somethingWentWrong": "出现错误",
|
||||
"prunedQueue": "已清理队列",
|
||||
"uploadInitialImage": "上传初始图像",
|
||||
"outOfMemoryErrorDesc": "您当前的生成设置已超出系统处理能力.请调整设置后再次尝试.",
|
||||
"parametersSet": "参数已恢复",
|
||||
"errorCopied": "错误信息已复制",
|
||||
@@ -702,68 +404,6 @@
|
||||
"importFailed": "导入失败",
|
||||
"importSuccessful": "导入成功"
|
||||
},
|
||||
"unifiedCanvas": {
|
||||
"layer": "图层",
|
||||
"base": "基础层",
|
||||
"mask": "遮罩",
|
||||
"maskingOptions": "遮罩选项",
|
||||
"enableMask": "启用遮罩",
|
||||
"preserveMaskedArea": "保留遮罩区域",
|
||||
"clearMask": "清除遮罩 (Shift+C)",
|
||||
"brush": "刷子",
|
||||
"eraser": "橡皮擦",
|
||||
"fillBoundingBox": "填充选择区域",
|
||||
"eraseBoundingBox": "取消选择区域",
|
||||
"colorPicker": "颜色提取",
|
||||
"brushOptions": "刷子选项",
|
||||
"brushSize": "大小",
|
||||
"move": "移动",
|
||||
"resetView": "重置视图",
|
||||
"mergeVisible": "合并可见层",
|
||||
"saveToGallery": "保存至图库",
|
||||
"copyToClipboard": "复制到剪贴板",
|
||||
"downloadAsImage": "下载图像",
|
||||
"undo": "撤销",
|
||||
"redo": "重做",
|
||||
"clearCanvas": "清除画布",
|
||||
"canvasSettings": "画布设置",
|
||||
"showIntermediates": "显示中间产物",
|
||||
"showGrid": "显示网格",
|
||||
"snapToGrid": "切换网格对齐",
|
||||
"darkenOutsideSelection": "暗化外部区域",
|
||||
"autoSaveToGallery": "自动保存至图库",
|
||||
"saveBoxRegionOnly": "只保存框内区域",
|
||||
"limitStrokesToBox": "限制画笔在框内",
|
||||
"showCanvasDebugInfo": "显示附加画布信息",
|
||||
"clearCanvasHistory": "清除画布历史",
|
||||
"clearHistory": "清除历史",
|
||||
"clearCanvasHistoryMessage": "清除画布历史不会影响当前画布,但会不可撤销地清除所有撤销/重做历史。",
|
||||
"clearCanvasHistoryConfirm": "确认清除所有画布历史?",
|
||||
"activeLayer": "活跃图层",
|
||||
"canvasScale": "画布缩放",
|
||||
"boundingBox": "选择区域",
|
||||
"scaledBoundingBox": "缩放选择区域",
|
||||
"boundingBoxPosition": "选择区域位置",
|
||||
"canvasDimensions": "画布长宽",
|
||||
"canvasPosition": "画布位置",
|
||||
"cursorPosition": "光标位置",
|
||||
"previous": "上一张",
|
||||
"next": "下一张",
|
||||
"accept": "接受",
|
||||
"discardAll": "放弃所有",
|
||||
"antialiasing": "抗锯齿",
|
||||
"showResultsOn": "显示结果 (开)",
|
||||
"showResultsOff": "显示结果 (关)",
|
||||
"saveMask": "保存 $t(unifiedCanvas.mask)",
|
||||
"coherenceModeBoxBlur": "盒子模糊",
|
||||
"showBoundingBox": "显示边界框",
|
||||
"coherenceModeGaussianBlur": "高斯模糊",
|
||||
"coherenceModeStaged": "分阶段",
|
||||
"hideBoundingBox": "隐藏边界框",
|
||||
"initialFitImageSize": "在拖放时调整图像大小以适配",
|
||||
"invertBrushSizeScrollDirection": "反转滚动操作以调整画笔大小",
|
||||
"discardCurrent": "放弃当前设置"
|
||||
},
|
||||
"accessibility": {
|
||||
"invokeProgressBar": "Invoke 进度条",
|
||||
"reset": "重置",
|
||||
@@ -773,23 +413,12 @@
|
||||
"showOptionsPanel": "显示侧栏浮窗",
|
||||
"menu": "菜单",
|
||||
"showGalleryPanel": "显示图库浮窗",
|
||||
"loadMore": "加载更多",
|
||||
"mode": "模式",
|
||||
"resetUI": "$t(accessibility.reset) UI",
|
||||
"createIssue": "创建问题",
|
||||
"about": "关于",
|
||||
"submitSupportTicket": "提交支持工单"
|
||||
},
|
||||
"tooltip": {
|
||||
"feature": {
|
||||
"prompt": "这是提示词区域。提示词包括生成对象和风格术语。您也可以在提示词中添加权重(Token 的重要性),但命令行命令和参数不起作用。",
|
||||
"upscale": "使用 ESRGAN 可以在图片生成后立即放大图片。",
|
||||
"boundingBox": "边界框的高和宽的设定对文生图和图生图模式是一样的,只有边界框中的区域会被处理。",
|
||||
"other": "这些选项将为 Invoke 启用替代处理模式。 \"无缝拼贴\" 将在输出中创建重复图案。\"高分辨率\" 是通过图生图进行两步生成:当您想要更大、更连贯且不带伪影的图像时,请使用此设置。这将比通常的文生图需要更长的时间。",
|
||||
"gallery": "图片库展示输出文件夹中的图片,设置和文件一起储存,可以通过内容菜单访问。",
|
||||
"seed": "种子值影响形成图像的初始噪声。您可以使用以前图像中已存在的种子。 “噪声阈值”用于减轻在高 CFG 等级(尝试 0 - 10 范围)下的伪像,并使用 Perlin 在生成过程中添加 Perlin 噪声:这两者都可以为您的输出添加变化。"
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"zoomInNodes": "放大",
|
||||
"loadWorkflow": "加载工作流",
|
||||
@@ -826,7 +455,6 @@
|
||||
"problemSettingTitle": "设定标题时出现问题",
|
||||
"noConnectionInProgress": "没有正在进行的连接",
|
||||
"workflowVersion": "版本",
|
||||
"noConnectionData": "无连接数据",
|
||||
"fieldTypesMustMatch": "类型必须匹配",
|
||||
"workflow": "工作流",
|
||||
"animatedEdgesHelp": "为选中边缘和其连接的选中节点的边缘添加动画",
|
||||
@@ -835,9 +463,7 @@
|
||||
"workflowTags": "标签",
|
||||
"fullyContainNodesHelp": "节点必须完全位于选择框中才能被选中",
|
||||
"workflowValidation": "工作流验证错误",
|
||||
"noMatchingNodes": "无相匹配的节点",
|
||||
"executionStateInProgress": "处理中",
|
||||
"noFieldType": "无字段类型",
|
||||
"executionStateError": "错误",
|
||||
"executionStateCompleted": "已完成",
|
||||
"workflowAuthor": "作者",
|
||||
@@ -927,95 +553,6 @@
|
||||
"boardAccessError": "无法找到面板 {{board_id}},正在恢复默认设置",
|
||||
"modelAccessError": "无法找到模型 {{key}},正在恢复默认设置"
|
||||
},
|
||||
"controlnet": {
|
||||
"resize": "直接缩放",
|
||||
"showAdvanced": "显示高级",
|
||||
"contentShuffleDescription": "随机打乱图像内容",
|
||||
"importImageFromCanvas": "从画布导入图像",
|
||||
"lineartDescription": "将图像转换为线稿",
|
||||
"importMaskFromCanvas": "从画布导入遮罩",
|
||||
"hideAdvanced": "隐藏高级",
|
||||
"resetControlImage": "重置控制图像",
|
||||
"beginEndStepPercent": "开始 / 结束步数百分比",
|
||||
"mlsdDescription": "简洁的分割线段(直线)检测器",
|
||||
"duplicate": "复制",
|
||||
"balanced": "平衡",
|
||||
"prompt": "Prompt (提示词控制)",
|
||||
"depthMidasDescription": "使用 Midas 生成深度图",
|
||||
"resizeMode": "缩放模式",
|
||||
"weight": "权重",
|
||||
"selectModel": "选择一个模型",
|
||||
"crop": "裁剪",
|
||||
"processor": "处理器",
|
||||
"none": "无",
|
||||
"detectResolution": "检测分辨率",
|
||||
"pidiDescription": "像素差分 (PIDI) 图像处理",
|
||||
"controlMode": "控制模式",
|
||||
"fill": "填充",
|
||||
"cannyDescription": "Canny 边缘检测",
|
||||
"colorMapDescription": "从图像生成一张颜色图",
|
||||
"imageResolution": "图像分辨率",
|
||||
"autoConfigure": "自动配置处理器",
|
||||
"normalBaeDescription": "法线 BAE 处理",
|
||||
"noneDescription": "不应用任何处理",
|
||||
"saveControlImage": "保存控制图像",
|
||||
"toggleControlNet": "开关此 ControlNet",
|
||||
"delete": "删除",
|
||||
"colorMapTileSize": "分块大小",
|
||||
"mediapipeFaceDescription": "使用 Mediapipe 检测面部",
|
||||
"depthZoeDescription": "使用 Zoe 生成深度图",
|
||||
"hedDescription": "整体嵌套边缘检测",
|
||||
"setControlImageDimensions": "复制尺寸到宽度/高度(为模型优化)",
|
||||
"amult": "角度倍率 (a_mult)",
|
||||
"bgth": "背景移除阈值 (bg_th)",
|
||||
"lineartAnimeDescription": "动漫风格线稿处理",
|
||||
"minConfidence": "最小置信度",
|
||||
"lowThreshold": "弱判断阈值",
|
||||
"highThreshold": "强判断阈值",
|
||||
"addT2IAdapter": "添加 $t(common.t2iAdapter)",
|
||||
"addControlNet": "添加 $t(common.controlNet)",
|
||||
"addIPAdapter": "添加 $t(common.ipAdapter)",
|
||||
"safe": "保守模式",
|
||||
"scribble": "草绘",
|
||||
"maxFaces": "最大面部数",
|
||||
"pidi": "PIDI",
|
||||
"normalBae": "Normal BAE",
|
||||
"hed": "HED",
|
||||
"contentShuffle": "Content Shuffle",
|
||||
"f": "F",
|
||||
"h": "H",
|
||||
"controlnet": "$t(controlnet.controlAdapter_one) #{{number}} ($t(common.controlNet))",
|
||||
"control": "Control (普通控制)",
|
||||
"coarse": "Coarse",
|
||||
"depthMidas": "Depth (Midas)",
|
||||
"w": "W",
|
||||
"ip_adapter": "$t(controlnet.controlAdapter_one) #{{number}} ($t(common.ipAdapter))",
|
||||
"mediapipeFace": "Mediapipe Face",
|
||||
"mlsd": "M-LSD",
|
||||
"lineart": "Lineart",
|
||||
"t2i_adapter": "$t(controlnet.controlAdapter_one) #{{number}} ($t(common.t2iAdapter))",
|
||||
"megaControl": "Mega Control (超级控制)",
|
||||
"depthZoe": "Depth (Zoe)",
|
||||
"colorMap": "Color",
|
||||
"controlAdapter_other": "Control Adapters",
|
||||
"lineartAnime": "Lineart Anime",
|
||||
"canny": "Canny",
|
||||
"resizeSimple": "缩放(简单)",
|
||||
"body": "身体",
|
||||
"ipAdapterMethod": "方法",
|
||||
"setControlImageDimensionsForce": "将尺寸复制到宽/高(忽略模型)",
|
||||
"depthAnythingDescription": "使用Depth Anything技术生成深度图",
|
||||
"selectCLIPVisionModel": "选择一个CLIP视觉模型",
|
||||
"small": "小",
|
||||
"full": "全部",
|
||||
"large": "大",
|
||||
"face": "脸",
|
||||
"style": "仅风格",
|
||||
"hands": "手",
|
||||
"composition": "仅构图",
|
||||
"modelSize": "模型尺寸",
|
||||
"dwOpenposeDescription": "使用DW Openpose进行人体姿态预估"
|
||||
},
|
||||
"queue": {
|
||||
"status": "状态",
|
||||
"cancelTooltip": "取消当前项目",
|
||||
@@ -1106,7 +643,6 @@
|
||||
"model": "模型",
|
||||
"noImageDetails": "未找到图像详细信息",
|
||||
"cfgScale": "CFG 等级",
|
||||
"initImage": "初始图像",
|
||||
"height": "高度",
|
||||
"noMetaData": "未找到元数据",
|
||||
"width": "宽度",
|
||||
@@ -1115,7 +651,6 @@
|
||||
"steps": "步数",
|
||||
"scheduler": "调度器",
|
||||
"seamless": "无缝",
|
||||
"fit": "图生图匹配",
|
||||
"recallParameters": "召回参数",
|
||||
"noRecallParameters": "未找到要召回的参数",
|
||||
"vae": "VAE",
|
||||
@@ -1134,7 +669,6 @@
|
||||
"selectModel": "选择一个模型",
|
||||
"noRefinerModelsInstalled": "无已安装的 SDXL Refiner 模型",
|
||||
"noLoRAsInstalled": "无已安装的 LoRA",
|
||||
"esrganModel": "ESRGAN 模型",
|
||||
"addLora": "添加 LoRA",
|
||||
"lora": "LoRA",
|
||||
"defaultVAE": "默认 VAE",
|
||||
@@ -1188,7 +722,6 @@
|
||||
},
|
||||
"maxPrompts": "最大提示词数",
|
||||
"dynamicPrompts": "动态提示词",
|
||||
"promptsWithCount_other": "{{count}} 个提示词",
|
||||
"promptsPreview": "提示词预览",
|
||||
"showDynamicPrompts": "显示动态提示词",
|
||||
"loading": "生成动态提示词中..."
|
||||
@@ -1608,27 +1141,19 @@
|
||||
"uploadWorkflow": "从文件中加载",
|
||||
"newWorkflowCreated": "已创建新的工作流",
|
||||
"name": "名称",
|
||||
"defaultWorkflows": "默认工作流",
|
||||
"created": "已创建",
|
||||
"ascending": "升序",
|
||||
"descending": "降序",
|
||||
"updated": "已更新",
|
||||
"userWorkflows": "我的工作流",
|
||||
"projectWorkflows": "项目工作流",
|
||||
"opened": "已打开",
|
||||
"noRecentWorkflows": "没有最近的工作流",
|
||||
"workflowCleared": "工作流已清除",
|
||||
"saveWorkflowToProject": "保存工作流到项目",
|
||||
"noWorkflows": "无工作流",
|
||||
"convertGraph": "转换图表",
|
||||
"loadWorkflow": "$t(common.load) 工作流",
|
||||
"noUserWorkflows": "没有用户工作流",
|
||||
"loadFromGraph": "从图表加载工作流",
|
||||
"autoLayout": "自动布局"
|
||||
},
|
||||
"app": {
|
||||
"storeNotInitialized": "商店尚未初始化"
|
||||
},
|
||||
"accordions": {
|
||||
"compositing": {
|
||||
"infillTab": "内补",
|
||||
@@ -1655,35 +1180,17 @@
|
||||
},
|
||||
"controlLayers": {
|
||||
"autoNegative": "自动反向",
|
||||
"opacityFilter": "透明度滤镜",
|
||||
"deleteAll": "删除所有",
|
||||
"moveForward": "向前移动",
|
||||
"layers_other": "层",
|
||||
"globalControlAdapterLayer": "全局 $t(controlnet.controlAdapter_one) $t(unifiedCanvas.layer)",
|
||||
"moveBackward": "向后移动",
|
||||
"regionalGuidance": "区域导向",
|
||||
"controlLayers": "控制层",
|
||||
"moveToBack": "移动到后面",
|
||||
"brushSize": "笔刷尺寸",
|
||||
"moveToFront": "移动到前面",
|
||||
"addLayer": "添加层",
|
||||
"deletePrompt": "删除提示词",
|
||||
"resetRegion": "重置区域",
|
||||
"debugLayers": "调试图层",
|
||||
"maskPreviewColor": "遮罩预览颜色",
|
||||
"addPositivePrompt": "添加 $t(common.positivePrompt)",
|
||||
"addNegativePrompt": "添加 $t(common.negativePrompt)",
|
||||
"addIPAdapter": "添加 $t(common.ipAdapter)",
|
||||
"globalIPAdapterLayer": "全局 $t(common.ipAdapter) $t(unifiedCanvas.layer)",
|
||||
"globalInitialImage": "全局初始图像",
|
||||
"noLayersAdded": "没有层被添加",
|
||||
"globalIPAdapter": "全局 $t(common.ipAdapter)",
|
||||
"resetProcessor": "重置处理器至默认值",
|
||||
"globalMaskOpacity": "全局遮罩透明度",
|
||||
"rectangle": "矩形",
|
||||
"opacity": "透明度",
|
||||
"clearProcessor": "清除处理器",
|
||||
"globalControlAdapter": "全局 $t(controlnet.controlAdapter_one)"
|
||||
"opacity": "透明度"
|
||||
},
|
||||
"ui": {
|
||||
"tabs": {
|
||||
@@ -1740,7 +1247,6 @@
|
||||
"searchByName": "按名称搜索",
|
||||
"shared": "已分享",
|
||||
"sharedTemplates": "已分享的模版",
|
||||
"templateActions": "模版操作",
|
||||
"templateDeleted": "提示模版已删除",
|
||||
"toggleViewMode": "切换显示模式",
|
||||
"uploadImage": "上传图像",
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
"githubLabel": "GitHub",
|
||||
"hotkeysLabel": "快捷鍵",
|
||||
"languagePickerLabel": "語言",
|
||||
"unifiedCanvas": "統一畫布",
|
||||
"cancel": "取消",
|
||||
"txt2img": "文字轉圖片",
|
||||
"controlNet": "ControlNet",
|
||||
@@ -40,7 +39,6 @@
|
||||
"nextImage": "下一張圖片",
|
||||
"previousImage": "上一張圖片",
|
||||
"menu": "選單",
|
||||
"loadMore": "載入更多",
|
||||
"about": "關於",
|
||||
"createIssue": "建立問題",
|
||||
"resetUI": "$t(accessibility.reset) 介面",
|
||||
@@ -77,15 +75,6 @@
|
||||
"options": "$t(accordions.advanced.title) 選項"
|
||||
}
|
||||
},
|
||||
"hotkeys": {
|
||||
"nodesHotkeys": "節點",
|
||||
"cancel": {
|
||||
"title": "取消"
|
||||
},
|
||||
"generalHotkeys": "一般",
|
||||
"keyboardShortcuts": "快捷鍵",
|
||||
"appHotkeys": "應用程式"
|
||||
},
|
||||
"modelManager": {
|
||||
"advanced": "進階",
|
||||
"allModels": "全部模型",
|
||||
@@ -110,23 +99,6 @@
|
||||
"vae": "VAE",
|
||||
"settings": "設定"
|
||||
},
|
||||
"controlnet": {
|
||||
"mlsd": "M-LSD",
|
||||
"canny": "Canny",
|
||||
"duplicate": "重複",
|
||||
"none": "無",
|
||||
"pidi": "PIDI",
|
||||
"h": "H",
|
||||
"balanced": "平衡",
|
||||
"crop": "裁切",
|
||||
"processor": "處理器",
|
||||
"control": "控制",
|
||||
"f": "F",
|
||||
"lineart": "線條藝術",
|
||||
"w": "W",
|
||||
"hed": "HED",
|
||||
"delete": "刪除"
|
||||
},
|
||||
"queue": {
|
||||
"queue": "佇列",
|
||||
"canceled": "已取消",
|
||||
@@ -190,18 +162,6 @@
|
||||
"heading": "步數"
|
||||
}
|
||||
},
|
||||
"unifiedCanvas": {
|
||||
"undo": "復原",
|
||||
"mask": "遮罩",
|
||||
"eraser": "橡皮擦",
|
||||
"antialiasing": "抗鋸齒",
|
||||
"redo": "重做",
|
||||
"layer": "圖層",
|
||||
"accept": "接受",
|
||||
"brush": "刷子",
|
||||
"move": "移動",
|
||||
"brushSize": "大小"
|
||||
},
|
||||
"nodes": {
|
||||
"workflowName": "名稱",
|
||||
"notes": "註釋",
|
||||
@@ -236,7 +196,6 @@
|
||||
"ui": {
|
||||
"tabs": {
|
||||
"models": "模型",
|
||||
"queueTab": "$t(ui.tabs.queue) $t(common.tab)",
|
||||
"queue": "佇列"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# Note: Must be run from invokeai/frontend/web/scripts directory
|
||||
#
|
||||
# After running the script, open `en.json` and check for empty objects (`{}`) and remove them manually.
|
||||
# Also, the script does not handle keys with underscores. They need to be checked manually.
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { Box, useGlobalModifiersInit } from '@invoke-ai/ui-library';
|
||||
import type { StudioDestination } from 'app/hooks/useHandleStudioDestination';
|
||||
import { useHandleStudioDestination } from 'app/hooks/useHandleStudioDestination';
|
||||
import { GlobalImageHotkeys } from 'app/components/GlobalImageHotkeys';
|
||||
import type { StudioInitAction } from 'app/hooks/useStudioInitAction';
|
||||
import { useStudioInitAction } from 'app/hooks/useStudioInitAction';
|
||||
import { useSyncQueueStatus } from 'app/hooks/useSyncQueueStatus';
|
||||
import { useLogger } from 'app/logging/useLogger';
|
||||
import { appStarted } from 'app/store/middleware/listenerMiddleware/listeners/appStarted';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import type { PartialAppConfig } from 'app/types/invokeai';
|
||||
import ImageUploadOverlay from 'common/components/ImageUploadOverlay';
|
||||
import { useScopeFocusWatcher } from 'common/hooks/interactionScopes';
|
||||
import { useFocusRegionWatcher } from 'common/hooks/focus';
|
||||
import { useClearStorage } from 'common/hooks/useClearStorage';
|
||||
import { useFullscreenDropzone } from 'common/hooks/useFullscreenDropzone';
|
||||
import { useGlobalHotkeys } from 'common/hooks/useGlobalHotkeys';
|
||||
@@ -18,12 +19,10 @@ import DeleteBoardModal from 'features/gallery/components/Boards/DeleteBoardModa
|
||||
import { useStarterModelsToast } from 'features/modelManagerV2/hooks/useStarterModelsToast';
|
||||
import { ClearQueueConfirmationsAlertDialog } from 'features/queue/components/ClearQueueConfirmationAlertDialog';
|
||||
import { StylePresetModal } from 'features/stylePresets/components/StylePresetForm/StylePresetModal';
|
||||
import { activeStylePresetIdChanged } from 'features/stylePresets/store/stylePresetSlice';
|
||||
import RefreshAfterResetModal from 'features/system/components/SettingsModal/RefreshAfterResetModal';
|
||||
import { configChanged } from 'features/system/store/configSlice';
|
||||
import { selectLanguage } from 'features/system/store/systemSelectors';
|
||||
import { AppContent } from 'features/ui/components/AppContent';
|
||||
import { useGetAndLoadLibraryWorkflow } from 'features/workflowLibrary/hooks/useGetAndLoadLibraryWorkflow';
|
||||
import { AnimatePresence } from 'framer-motion';
|
||||
import i18n from 'i18n';
|
||||
import { size } from 'lodash-es';
|
||||
@@ -33,28 +32,15 @@ import { useGetOpenAPISchemaQuery } from 'services/api/endpoints/appInfo';
|
||||
import { useSocketIO } from 'services/events/useSocketIO';
|
||||
|
||||
import AppErrorBoundaryFallback from './AppErrorBoundaryFallback';
|
||||
import PreselectedImage from './PreselectedImage';
|
||||
|
||||
const DEFAULT_CONFIG = {};
|
||||
|
||||
interface Props {
|
||||
config?: PartialAppConfig;
|
||||
selectedImage?: {
|
||||
imageName: string;
|
||||
action: 'sendToImg2Img' | 'sendToCanvas' | 'useAllParameters';
|
||||
};
|
||||
selectedWorkflowId?: string;
|
||||
selectedStylePresetId?: string;
|
||||
studioDestination?: StudioDestination;
|
||||
studioInitAction?: StudioInitAction;
|
||||
}
|
||||
|
||||
const App = ({
|
||||
config = DEFAULT_CONFIG,
|
||||
selectedImage,
|
||||
selectedWorkflowId,
|
||||
selectedStylePresetId,
|
||||
studioDestination,
|
||||
}: Props) => {
|
||||
const App = ({ config = DEFAULT_CONFIG, studioInitAction }: Props) => {
|
||||
const language = useAppSelector(selectLanguage);
|
||||
const logger = useLogger('system');
|
||||
const dispatch = useAppDispatch();
|
||||
@@ -66,8 +52,6 @@ const App = ({
|
||||
useGlobalHotkeys();
|
||||
useGetOpenAPISchemaQuery();
|
||||
|
||||
const handleStudioDestination = useHandleStudioDestination();
|
||||
|
||||
const { dropzone, isHandlingUpload, setIsHandlingUpload } = useFullscreenDropzone();
|
||||
|
||||
const handleReset = useCallback(() => {
|
||||
@@ -87,33 +71,14 @@ const App = ({
|
||||
}
|
||||
}, [dispatch, config, logger]);
|
||||
|
||||
const { getAndLoadWorkflow } = useGetAndLoadLibraryWorkflow();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedWorkflowId) {
|
||||
getAndLoadWorkflow(selectedWorkflowId);
|
||||
}
|
||||
}, [selectedWorkflowId, getAndLoadWorkflow]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedStylePresetId) {
|
||||
dispatch(activeStylePresetIdChanged(selectedStylePresetId));
|
||||
}
|
||||
}, [dispatch, selectedStylePresetId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (studioDestination) {
|
||||
handleStudioDestination(studioDestination);
|
||||
}
|
||||
}, [handleStudioDestination, studioDestination]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(appStarted());
|
||||
}, [dispatch]);
|
||||
|
||||
useStudioInitAction(studioInitAction);
|
||||
useStarterModelsToast();
|
||||
useSyncQueueStatus();
|
||||
useScopeFocusWatcher();
|
||||
useFocusRegionWatcher();
|
||||
|
||||
return (
|
||||
<ErrorBoundary onReset={handleReset} FallbackComponent={AppErrorBoundaryFallback}>
|
||||
@@ -138,9 +103,9 @@ const App = ({
|
||||
<DynamicPromptsModal />
|
||||
<StylePresetModal />
|
||||
<ClearQueueConfirmationsAlertDialog />
|
||||
<PreselectedImage selectedImage={selectedImage} />
|
||||
<RefreshAfterResetModal />
|
||||
<DeleteBoardModal />
|
||||
<GlobalImageHotkeys />
|
||||
</ErrorBoundary>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
import { skipToken } from '@reduxjs/toolkit/query';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { selectIsStaging } from 'features/controlLayers/store/canvasStagingAreaSlice';
|
||||
import { useImageActions } from 'features/gallery/hooks/useImageActions';
|
||||
import { selectLastSelectedImage } from 'features/gallery/store/gallerySelectors';
|
||||
import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData';
|
||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||
import { memo } from 'react';
|
||||
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
|
||||
import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
export const GlobalImageHotkeys = memo(() => {
|
||||
const lastSelectedImage = useAppSelector(selectLastSelectedImage);
|
||||
const { currentData: imageDTO } = useGetImageDTOQuery(lastSelectedImage?.image_name ?? skipToken);
|
||||
|
||||
if (!imageDTO) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <GlobalImageHotkeysInternal imageDTO={imageDTO} />;
|
||||
});
|
||||
|
||||
GlobalImageHotkeys.displayName = 'GlobalImageHotkeys';
|
||||
|
||||
const GlobalImageHotkeysInternal = memo(({ imageDTO }: { imageDTO: ImageDTO }) => {
|
||||
const isGalleryFocused = useIsRegionFocused('gallery');
|
||||
const isViewerFocused = useIsRegionFocused('viewer');
|
||||
const imageActions = useImageActions(imageDTO);
|
||||
const isStaging = useAppSelector(selectIsStaging);
|
||||
const isUpscalingEnabled = useFeatureStatus('upscaling');
|
||||
|
||||
useRegisteredHotkeys({
|
||||
id: 'loadWorkflow',
|
||||
category: 'viewer',
|
||||
callback: imageActions.loadWorkflow,
|
||||
options: { enabled: isGalleryFocused || isViewerFocused },
|
||||
dependencies: [imageActions.loadWorkflow, isGalleryFocused, isViewerFocused],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'recallAll',
|
||||
category: 'viewer',
|
||||
callback: imageActions.recallAll,
|
||||
options: { enabled: !isStaging && (isGalleryFocused || isViewerFocused) },
|
||||
dependencies: [imageActions.recallAll, isStaging, isGalleryFocused, isViewerFocused],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'recallSeed',
|
||||
category: 'viewer',
|
||||
callback: imageActions.recallSeed,
|
||||
options: { enabled: isGalleryFocused || isViewerFocused },
|
||||
dependencies: [imageActions.recallSeed, isGalleryFocused, isViewerFocused],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'recallPrompts',
|
||||
category: 'viewer',
|
||||
callback: imageActions.recallPrompts,
|
||||
options: { enabled: isGalleryFocused || isViewerFocused },
|
||||
dependencies: [imageActions.recallPrompts, isGalleryFocused, isViewerFocused],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'remix',
|
||||
category: 'viewer',
|
||||
callback: imageActions.remix,
|
||||
options: { enabled: isGalleryFocused || isViewerFocused },
|
||||
dependencies: [imageActions.remix, isGalleryFocused, isViewerFocused],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'useSize',
|
||||
category: 'viewer',
|
||||
callback: imageActions.recallSize,
|
||||
options: { enabled: !isStaging && (isGalleryFocused || isViewerFocused) },
|
||||
dependencies: [imageActions.recallSize, isStaging, isGalleryFocused, isViewerFocused],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'runPostprocessing',
|
||||
category: 'viewer',
|
||||
callback: imageActions.upscale,
|
||||
options: { enabled: isUpscalingEnabled && isViewerFocused },
|
||||
dependencies: [isUpscalingEnabled, imageDTO, isViewerFocused],
|
||||
});
|
||||
return null;
|
||||
});
|
||||
|
||||
GlobalImageHotkeysInternal.displayName = 'GlobalImageHotkeysInternal';
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'i18n';
|
||||
|
||||
import type { Middleware } from '@reduxjs/toolkit';
|
||||
import type { StudioDestination } from 'app/hooks/useHandleStudioDestination';
|
||||
import type { StudioInitAction } from 'app/hooks/useStudioInitAction';
|
||||
import { $authToken } from 'app/store/nanostores/authToken';
|
||||
import { $baseUrl } from 'app/store/nanostores/baseUrl';
|
||||
import { $customNavComponent } from 'app/store/nanostores/customNavComponent';
|
||||
@@ -40,13 +40,7 @@ interface Props extends PropsWithChildren {
|
||||
projectName?: string;
|
||||
projectUrl?: string;
|
||||
queueId?: string;
|
||||
selectedImage?: {
|
||||
imageName: string;
|
||||
action: 'sendToImg2Img' | 'sendToCanvas' | 'useAllParameters';
|
||||
};
|
||||
selectedWorkflowId?: string;
|
||||
selectedStylePresetId?: string;
|
||||
studioDestination?: StudioDestination;
|
||||
studioInitAction?: StudioInitAction;
|
||||
customStarUi?: CustomStarUi;
|
||||
socketOptions?: Partial<ManagerOptions & SocketOptions>;
|
||||
isDebugging?: boolean;
|
||||
@@ -65,10 +59,7 @@ const InvokeAIUI = ({
|
||||
projectName,
|
||||
projectUrl,
|
||||
queueId,
|
||||
selectedImage,
|
||||
selectedWorkflowId,
|
||||
selectedStylePresetId,
|
||||
studioDestination,
|
||||
studioInitAction,
|
||||
customStarUi,
|
||||
socketOptions,
|
||||
isDebugging = false,
|
||||
@@ -225,13 +216,7 @@ const InvokeAIUI = ({
|
||||
<React.Suspense fallback={<Loading />}>
|
||||
<ThemeLocaleProvider>
|
||||
<AppDndContext>
|
||||
<App
|
||||
config={config}
|
||||
selectedImage={selectedImage}
|
||||
selectedWorkflowId={selectedWorkflowId}
|
||||
selectedStylePresetId={selectedStylePresetId}
|
||||
studioDestination={studioDestination}
|
||||
/>
|
||||
<App config={config} studioInitAction={studioInitAction} />
|
||||
</AppDndContext>
|
||||
</ThemeLocaleProvider>
|
||||
</React.Suspense>
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import { usePreselectedImage } from 'features/parameters/hooks/usePreselectedImage';
|
||||
import { memo } from 'react';
|
||||
|
||||
type Props = {
|
||||
selectedImage?: {
|
||||
imageName: string;
|
||||
action: 'sendToImg2Img' | 'sendToCanvas' | 'useAllParameters';
|
||||
};
|
||||
};
|
||||
|
||||
const PreselectedImage = (props: Props) => {
|
||||
usePreselectedImage(props.selectedImage);
|
||||
return null;
|
||||
};
|
||||
|
||||
export default memo(PreselectedImage);
|
||||
@@ -1,64 +0,0 @@
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { settingsSendToCanvasChanged } from 'features/controlLayers/store/canvasSettingsSlice';
|
||||
import { useImageViewer } from 'features/gallery/components/ImageViewer/useImageViewer';
|
||||
import { $isMenuOpen } from 'features/stylePresets/store/isMenuOpen';
|
||||
import { setActiveTab } from 'features/ui/store/uiSlice';
|
||||
import { useWorkflowLibraryModal } from 'features/workflowLibrary/store/isWorkflowLibraryModalOpen';
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
export type StudioDestination =
|
||||
| 'generation'
|
||||
| 'canvas'
|
||||
| 'workflows'
|
||||
| 'upscaling'
|
||||
| 'viewAllWorkflows'
|
||||
| 'viewAllStylePresets';
|
||||
|
||||
export const useHandleStudioDestination = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { open: imageViewerOpen, close: imageViewerClose } = useImageViewer();
|
||||
const [initialized, setInitialized] = useState(false);
|
||||
|
||||
const workflowLibraryModal = useWorkflowLibraryModal();
|
||||
|
||||
const handleStudioDestination = useCallback(
|
||||
(destination: StudioDestination) => {
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
switch (destination) {
|
||||
case 'generation':
|
||||
dispatch(setActiveTab('canvas'));
|
||||
dispatch(settingsSendToCanvasChanged(false));
|
||||
imageViewerOpen();
|
||||
break;
|
||||
case 'canvas':
|
||||
dispatch(setActiveTab('canvas'));
|
||||
dispatch(settingsSendToCanvasChanged(true));
|
||||
imageViewerClose();
|
||||
break;
|
||||
case 'workflows':
|
||||
dispatch(setActiveTab('workflows'));
|
||||
break;
|
||||
case 'upscaling':
|
||||
dispatch(setActiveTab('upscaling'));
|
||||
break;
|
||||
case 'viewAllWorkflows':
|
||||
dispatch(setActiveTab('workflows'));
|
||||
workflowLibraryModal.setTrue();
|
||||
break;
|
||||
case 'viewAllStylePresets':
|
||||
dispatch(setActiveTab('canvas'));
|
||||
$isMenuOpen.set(true);
|
||||
break;
|
||||
default:
|
||||
dispatch(setActiveTab('canvas'));
|
||||
break;
|
||||
}
|
||||
setInitialized(true);
|
||||
},
|
||||
[dispatch, imageViewerOpen, imageViewerClose, workflowLibraryModal, initialized]
|
||||
);
|
||||
|
||||
return handleStudioDestination;
|
||||
};
|
||||
207
invokeai/frontend/web/src/app/hooks/useStudioInitAction.ts
Normal file
207
invokeai/frontend/web/src/app/hooks/useStudioInitAction.ts
Normal file
@@ -0,0 +1,207 @@
|
||||
import { useAppStore } from 'app/store/storeHooks';
|
||||
import { useAssertSingleton } from 'common/hooks/useAssertSingleton';
|
||||
import { withResultAsync } from 'common/util/result';
|
||||
import { canvasReset } from 'features/controlLayers/store/actions';
|
||||
import { settingsSendToCanvasChanged } from 'features/controlLayers/store/canvasSettingsSlice';
|
||||
import { rasterLayerAdded } from 'features/controlLayers/store/canvasSlice';
|
||||
import type { CanvasRasterLayerState } from 'features/controlLayers/store/types';
|
||||
import { imageDTOToImageObject } from 'features/controlLayers/store/util';
|
||||
import { $imageViewer } from 'features/gallery/components/ImageViewer/useImageViewer';
|
||||
import { sentImageToCanvas } from 'features/gallery/store/actions';
|
||||
import { parseAndRecallAllMetadata } from 'features/metadata/util/handlers';
|
||||
import { $isStylePresetsMenuOpen, activeStylePresetIdChanged } from 'features/stylePresets/store/stylePresetSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { setActiveTab } from 'features/ui/store/uiSlice';
|
||||
import { useGetAndLoadLibraryWorkflow } from 'features/workflowLibrary/hooks/useGetAndLoadLibraryWorkflow';
|
||||
import { $workflowLibraryModal } from 'features/workflowLibrary/store/isWorkflowLibraryModalOpen';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getImageDTO, getImageMetadata } from 'services/api/endpoints/images';
|
||||
import { getStylePreset } from 'services/api/endpoints/stylePresets';
|
||||
|
||||
type _StudioInitAction<T extends string, U> = { type: T; data: U };
|
||||
|
||||
type LoadWorkflowAction = _StudioInitAction<'loadWorkflow', { workflowId: string }>;
|
||||
type SelectStylePresetAction = _StudioInitAction<'selectStylePreset', { stylePresetId: string }>;
|
||||
type SendToCanvasAction = _StudioInitAction<'sendToCanvas', { imageName: string }>;
|
||||
type UseAllParametersAction = _StudioInitAction<'useAllParameters', { imageName: string }>;
|
||||
type StudioDestinationAction = _StudioInitAction<
|
||||
'goToDestination',
|
||||
{ destination: 'generation' | 'canvas' | 'workflows' | 'upscaling' | 'viewAllWorkflows' | 'viewAllStylePresets' }
|
||||
>;
|
||||
|
||||
export type StudioInitAction =
|
||||
| LoadWorkflowAction
|
||||
| SelectStylePresetAction
|
||||
| SendToCanvasAction
|
||||
| UseAllParametersAction
|
||||
| StudioDestinationAction;
|
||||
|
||||
/**
|
||||
* A hook that performs an action when the studio is initialized. This is useful for deep linking into the studio.
|
||||
*
|
||||
* The action is performed only once, when the hook is first run.
|
||||
*
|
||||
* In this hook, we prefer to use imperative APIs over hooks to avoid re-rendering the parent component. For example:
|
||||
* - Use `getImageDTO` helper instead of `useGetImageDTO`
|
||||
* - Usee the `$imageViewer` atom instead of `useImageViewer`
|
||||
*/
|
||||
export const useStudioInitAction = (action?: StudioInitAction) => {
|
||||
useAssertSingleton('useStudioInitAction');
|
||||
const { t } = useTranslation();
|
||||
// Use a ref to ensure that we only perform the action once
|
||||
const didInit = useRef(false);
|
||||
const store = useAppStore();
|
||||
const { getAndLoadWorkflow } = useGetAndLoadLibraryWorkflow();
|
||||
|
||||
const handleSendToCanvas = useCallback(
|
||||
async (imageName: string) => {
|
||||
// Try to the image DTO - use an imperative helper, rather than `useGetImageDTO`, so that we aren't re-rendering
|
||||
// the parent of this hook whenever the image name changes
|
||||
const getImageDTOResult = await withResultAsync(() => getImageDTO(imageName));
|
||||
if (getImageDTOResult.isErr()) {
|
||||
toast({
|
||||
title: t('toast.unableToLoadImage'),
|
||||
status: 'error',
|
||||
});
|
||||
return;
|
||||
}
|
||||
const imageDTO = getImageDTOResult.value;
|
||||
const imageObject = imageDTOToImageObject(imageDTO);
|
||||
const overrides: Partial<CanvasRasterLayerState> = {
|
||||
objects: [imageObject],
|
||||
};
|
||||
store.dispatch(canvasReset());
|
||||
store.dispatch(rasterLayerAdded({ overrides, isSelected: true }));
|
||||
store.dispatch(settingsSendToCanvasChanged(true));
|
||||
store.dispatch(setActiveTab('canvas'));
|
||||
store.dispatch(sentImageToCanvas());
|
||||
$imageViewer.set(false);
|
||||
toast({
|
||||
title: t('toast.sentToCanvas'),
|
||||
status: 'info',
|
||||
});
|
||||
},
|
||||
[store, t]
|
||||
);
|
||||
|
||||
const handleUseAllMetadata = useCallback(
|
||||
async (imageName: string) => {
|
||||
// Try to the image metadata - use an imperative helper, rather than `useGetImageMetadata`, so that we aren't
|
||||
// re-rendering the parent of this hook whenever the image name changes
|
||||
const getImageMetadataResult = await withResultAsync(() => getImageMetadata(imageName));
|
||||
if (getImageMetadataResult.isErr()) {
|
||||
toast({
|
||||
title: t('toast.unableToLoadImageMetadata'),
|
||||
status: 'error',
|
||||
});
|
||||
return;
|
||||
}
|
||||
const metadata = getImageMetadataResult.value;
|
||||
// This shows a toast
|
||||
parseAndRecallAllMetadata(metadata, true);
|
||||
store.dispatch(setActiveTab('canvas'));
|
||||
},
|
||||
[store, t]
|
||||
);
|
||||
|
||||
const handleLoadWorkflow = useCallback(
|
||||
(workflowId: string) => {
|
||||
// This shows a toast
|
||||
getAndLoadWorkflow(workflowId);
|
||||
store.dispatch(setActiveTab('workflows'));
|
||||
},
|
||||
[getAndLoadWorkflow, store]
|
||||
);
|
||||
|
||||
const handleSelectStylePreset = useCallback(
|
||||
async (stylePresetId: string) => {
|
||||
const getStylePresetResult = await withResultAsync(() => getStylePreset(stylePresetId));
|
||||
if (getStylePresetResult.isErr()) {
|
||||
toast({
|
||||
title: t('toast.unableToLoadStylePreset'),
|
||||
status: 'error',
|
||||
});
|
||||
return;
|
||||
}
|
||||
store.dispatch(activeStylePresetIdChanged(stylePresetId));
|
||||
store.dispatch(setActiveTab('canvas'));
|
||||
toast({
|
||||
title: t('toast.stylePresetLoaded'),
|
||||
status: 'info',
|
||||
});
|
||||
},
|
||||
[store, t]
|
||||
);
|
||||
|
||||
const handleGoToDestination = useCallback(
|
||||
(destination: StudioDestinationAction['data']['destination']) => {
|
||||
switch (destination) {
|
||||
case 'generation':
|
||||
// Go to the canvas tab, open the image viewer, and enable send-to-gallery mode
|
||||
store.dispatch(setActiveTab('canvas'));
|
||||
store.dispatch(settingsSendToCanvasChanged(false));
|
||||
$imageViewer.set(true);
|
||||
break;
|
||||
case 'canvas':
|
||||
// Go to the canvas tab, close the image viewer, and disable send-to-gallery mode
|
||||
store.dispatch(setActiveTab('canvas'));
|
||||
store.dispatch(settingsSendToCanvasChanged(true));
|
||||
$imageViewer.set(false);
|
||||
break;
|
||||
case 'workflows':
|
||||
// Go to the workflows tab
|
||||
store.dispatch(setActiveTab('workflows'));
|
||||
break;
|
||||
case 'upscaling':
|
||||
// Go to the upscaling tab
|
||||
store.dispatch(setActiveTab('upscaling'));
|
||||
break;
|
||||
case 'viewAllWorkflows':
|
||||
// Go to the workflows tab and open the workflow library modal
|
||||
store.dispatch(setActiveTab('workflows'));
|
||||
$workflowLibraryModal.set(true);
|
||||
break;
|
||||
case 'viewAllStylePresets':
|
||||
// Go to the canvas tab and open the style presets menu
|
||||
store.dispatch(setActiveTab('canvas'));
|
||||
$isStylePresetsMenuOpen.set(true);
|
||||
break;
|
||||
}
|
||||
},
|
||||
[store]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (didInit.current || !action) {
|
||||
return;
|
||||
}
|
||||
|
||||
didInit.current = true;
|
||||
|
||||
switch (action.type) {
|
||||
case 'loadWorkflow':
|
||||
handleLoadWorkflow(action.data.workflowId);
|
||||
break;
|
||||
case 'selectStylePreset':
|
||||
handleSelectStylePreset(action.data.stylePresetId);
|
||||
break;
|
||||
case 'sendToCanvas':
|
||||
handleSendToCanvas(action.data.imageName);
|
||||
break;
|
||||
case 'useAllParameters':
|
||||
handleUseAllMetadata(action.data.imageName);
|
||||
break;
|
||||
case 'goToDestination':
|
||||
handleGoToDestination(action.data.destination);
|
||||
break;
|
||||
}
|
||||
}, [
|
||||
handleSendToCanvas,
|
||||
handleUseAllMetadata,
|
||||
action,
|
||||
handleLoadWorkflow,
|
||||
handleSelectStylePreset,
|
||||
handleGoToDestination,
|
||||
]);
|
||||
};
|
||||
@@ -1,12 +1,7 @@
|
||||
import { isAnyOf } from '@reduxjs/toolkit';
|
||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||
import { selectListImagesQueryArgs } from 'features/gallery/store/gallerySelectors';
|
||||
import {
|
||||
boardIdSelected,
|
||||
galleryViewChanged,
|
||||
imageSelected,
|
||||
selectionChanged,
|
||||
} from 'features/gallery/store/gallerySlice';
|
||||
import { boardIdSelected, galleryViewChanged, imageSelected } from 'features/gallery/store/gallerySlice';
|
||||
import { imagesApi } from 'services/api/endpoints/images';
|
||||
|
||||
export const addBoardIdSelectedListener = (startAppListening: AppStartListening) => {
|
||||
@@ -20,8 +15,6 @@ export const addBoardIdSelectedListener = (startAppListening: AppStartListening)
|
||||
|
||||
const queryArgs = selectListImagesQueryArgs(state);
|
||||
|
||||
dispatch(selectionChanged([]));
|
||||
|
||||
// wait until the board has some images - maybe it already has some from a previous fetch
|
||||
// must use getState() to ensure we do not have stale state
|
||||
const isSuccess = await condition(
|
||||
|
||||
@@ -4,6 +4,7 @@ import { bboxSyncedToOptimalDimension } from 'features/controlLayers/store/canva
|
||||
import { selectIsStaging } from 'features/controlLayers/store/canvasStagingAreaSlice';
|
||||
import { loraDeleted } from 'features/controlLayers/store/lorasSlice';
|
||||
import { modelChanged, vaeSelected } from 'features/controlLayers/store/paramsSlice';
|
||||
import { selectBboxModelBase } from 'features/controlLayers/store/selectors';
|
||||
import { modelSelected } from 'features/parameters/store/actions';
|
||||
import { zParameterModel } from 'features/parameters/types/parameterSchemas';
|
||||
import { toast } from 'features/toast/toast';
|
||||
@@ -70,7 +71,8 @@ export const addModelSelectedListener = (startAppListening: AppStartListening) =
|
||||
}
|
||||
|
||||
dispatch(modelChanged({ model: newModel, previousModel: state.params.model }));
|
||||
if (!selectIsStaging(state)) {
|
||||
const modelBase = selectBboxModelBase(state);
|
||||
if (!selectIsStaging(state) && modelBase !== state.params.model?.base) {
|
||||
dispatch(bboxSyncedToOptimalDimension());
|
||||
}
|
||||
},
|
||||
|
||||
@@ -3,12 +3,10 @@ import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'
|
||||
import type { AppDispatch, RootState } from 'app/store/store';
|
||||
import type { SerializableObject } from 'common/types';
|
||||
import {
|
||||
bboxSyncedToOptimalDimension,
|
||||
controlLayerModelChanged,
|
||||
referenceImageIPAdapterModelChanged,
|
||||
rgIPAdapterModelChanged,
|
||||
} from 'features/controlLayers/store/canvasSlice';
|
||||
import { selectIsStaging } from 'features/controlLayers/store/canvasStagingAreaSlice';
|
||||
import { loraDeleted } from 'features/controlLayers/store/lorasSlice';
|
||||
import {
|
||||
clipEmbedModelSelected,
|
||||
@@ -20,10 +18,10 @@ import {
|
||||
} from 'features/controlLayers/store/paramsSlice';
|
||||
import { selectCanvasSlice } from 'features/controlLayers/store/selectors';
|
||||
import { getEntityIdentifier } from 'features/controlLayers/store/types';
|
||||
import { modelSelected } from 'features/parameters/store/actions';
|
||||
import { postProcessingModelChanged, upscaleModelChanged } from 'features/parameters/store/upscaleSlice';
|
||||
import {
|
||||
zParameterCLIPEmbedModel,
|
||||
zParameterModel,
|
||||
zParameterSpandrelImageToImageModel,
|
||||
zParameterT5EncoderModel,
|
||||
zParameterVAEModel,
|
||||
@@ -69,13 +67,12 @@ export const addModelsLoadedListener = (startAppListening: AppStartListening) =>
|
||||
const models = modelConfigsAdapterSelectors.selectAll(action.payload);
|
||||
|
||||
handleMainModels(models, state, dispatch, log);
|
||||
// Upscale models are also "main" models, but they have their own handling
|
||||
handleUpscalingModels(models, state, dispatch, log);
|
||||
handleRefinerModels(models, state, dispatch, log);
|
||||
handleVAEModels(models, state, dispatch, log);
|
||||
handleLoRAModels(models, state, dispatch, log);
|
||||
handleControlAdapterModels(models, state, dispatch, log);
|
||||
handleSpandrelImageToImageModels(models, state, dispatch, log);
|
||||
handlePostProcessingModel(models, state, dispatch, log);
|
||||
handleUpscaleModel(models, state, dispatch, log);
|
||||
handleIPAdapterModels(models, state, dispatch, log);
|
||||
handleT5EncoderModels(models, state, dispatch, log);
|
||||
handleCLIPEmbedModels(models, state, dispatch, log);
|
||||
@@ -120,10 +117,7 @@ const handleMainModels: ModelHandler = (models, state, dispatch, log) => {
|
||||
{ selectedMainModel, defaultModel },
|
||||
'No selected main model or selected main model is not available, selecting default model'
|
||||
);
|
||||
dispatch(modelChanged({ model: zParameterModel.parse(defaultModel), previousModel: selectedMainModel }));
|
||||
if (!selectIsStaging(state)) {
|
||||
dispatch(bboxSyncedToOptimalDimension());
|
||||
}
|
||||
dispatch(modelSelected(defaultModel));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -132,38 +126,7 @@ const handleMainModels: ModelHandler = (models, state, dispatch, log) => {
|
||||
{ selectedMainModel, firstModel },
|
||||
'No selected main model or selected main model is not available, selecting first available model'
|
||||
);
|
||||
dispatch(modelChanged({ model: zParameterModel.parse(firstModel), previousModel: selectedMainModel }));
|
||||
if (!selectIsStaging(state)) {
|
||||
dispatch(bboxSyncedToOptimalDimension());
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpscalingModels: ModelHandler = (models, state, dispatch, log) => {
|
||||
const selectedUpscaleModel = state.upscale.upscaleModel;
|
||||
const allUpscalingModels = models.filter(isNonRefinerMainModelConfig).sort((a) => (a.base === 'sdxl' ? -1 : 1));
|
||||
|
||||
const firstModel = allUpscalingModels[0] || null;
|
||||
|
||||
// If we have no models, we may need to clear the selected model
|
||||
if (!firstModel) {
|
||||
// Only clear the model if we have one currently selected
|
||||
if (selectedUpscaleModel !== null) {
|
||||
log.debug({ selectedUpscaleModel }, 'No upscaling models available, clearing');
|
||||
dispatch(upscaleModelChanged(null));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If the current model is available, we don't need to do anything
|
||||
if (allUpscalingModels.some((m) => m.key === selectedUpscaleModel?.key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug(
|
||||
{ selectedUpscaleModel, firstModel },
|
||||
'No selected upscaling model or selected upscaling model is not available, selecting first available model'
|
||||
);
|
||||
dispatch(upscaleModelChanged(zParameterModel.parse(firstModel)));
|
||||
dispatch(modelSelected(firstModel));
|
||||
};
|
||||
|
||||
const handleRefinerModels: ModelHandler = (models, state, dispatch, log) => {
|
||||
@@ -278,7 +241,7 @@ const handleIPAdapterModels: ModelHandler = (models, state, dispatch, log) => {
|
||||
});
|
||||
};
|
||||
|
||||
const handleSpandrelImageToImageModels: ModelHandler = (models, state, dispatch, log) => {
|
||||
const handlePostProcessingModel: ModelHandler = (models, state, dispatch, log) => {
|
||||
const selectedPostProcessingModel = state.upscale.postProcessingModel;
|
||||
const allSpandrelModels = models.filter(isSpandrelImageToImageModelConfig);
|
||||
|
||||
@@ -305,6 +268,33 @@ const handleSpandrelImageToImageModels: ModelHandler = (models, state, dispatch,
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpscaleModel: ModelHandler = (models, state, dispatch, log) => {
|
||||
const selectedUpscaleModel = state.upscale.upscaleModel;
|
||||
const allSpandrelModels = models.filter(isSpandrelImageToImageModelConfig);
|
||||
|
||||
// If the currently selected model is available, we don't need to do anything
|
||||
if (selectedUpscaleModel && allSpandrelModels.some((m) => m.key === selectedUpscaleModel.key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Else we should select the first available model
|
||||
const firstModel = allSpandrelModels[0] || null;
|
||||
if (firstModel) {
|
||||
log.debug(
|
||||
{ selectedUpscaleModel, firstModel },
|
||||
'No selected upscale model or selected upscale model is not available, selecting first available model'
|
||||
);
|
||||
dispatch(upscaleModelChanged(zParameterSpandrelImageToImageModel.parse(firstModel)));
|
||||
return;
|
||||
}
|
||||
|
||||
// No available models, we should clear the selected model - but only if we have one selected
|
||||
if (selectedUpscaleModel) {
|
||||
log.debug({ selectedUpscaleModel }, 'Selected upscale model is not available, clearing');
|
||||
dispatch(upscaleModelChanged(null));
|
||||
}
|
||||
};
|
||||
|
||||
const handleT5EncoderModels: ModelHandler = (models, state, dispatch, log) => {
|
||||
const selectedT5EncoderModel = state.params.t5EncoderModel;
|
||||
const t5EncoderModels = models.filter(isT5EncoderModelConfig);
|
||||
|
||||
@@ -4,6 +4,7 @@ import { selectIsStaging } from 'features/controlLayers/store/canvasStagingAreaS
|
||||
import {
|
||||
setCfgRescaleMultiplier,
|
||||
setCfgScale,
|
||||
setGuidance,
|
||||
setScheduler,
|
||||
setSteps,
|
||||
vaePrecisionChanged,
|
||||
@@ -13,6 +14,7 @@ import { setDefaultSettings } from 'features/parameters/store/actions';
|
||||
import {
|
||||
isParameterCFGRescaleMultiplier,
|
||||
isParameterCFGScale,
|
||||
isParameterGuidance,
|
||||
isParameterHeight,
|
||||
isParameterPrecision,
|
||||
isParameterScheduler,
|
||||
@@ -49,7 +51,7 @@ export const addSetDefaultSettingsListener = (startAppListening: AppStartListeni
|
||||
}
|
||||
|
||||
if (isNonRefinerMainModelConfig(modelConfig) && modelConfig.default_settings) {
|
||||
const { vae, vae_precision, cfg_scale, cfg_rescale_multiplier, steps, scheduler, width, height } =
|
||||
const { vae, vae_precision, cfg_scale, cfg_rescale_multiplier, steps, scheduler, width, height, guidance } =
|
||||
modelConfig.default_settings;
|
||||
|
||||
if (vae) {
|
||||
@@ -73,6 +75,12 @@ export const addSetDefaultSettingsListener = (startAppListening: AppStartListeni
|
||||
}
|
||||
}
|
||||
|
||||
if (guidance) {
|
||||
if (isParameterGuidance(guidance)) {
|
||||
dispatch(setGuidance(guidance));
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg_scale) {
|
||||
if (isParameterCFGScale(cfg_scale)) {
|
||||
dispatch(setCfgScale(cfg_scale));
|
||||
|
||||
182
invokeai/frontend/web/src/common/hooks/focus.ts
Normal file
182
invokeai/frontend/web/src/common/hooks/focus.ts
Normal file
@@ -0,0 +1,182 @@
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { logger } from 'app/logging/logger';
|
||||
import { useAssertSingleton } from 'common/hooks/useAssertSingleton';
|
||||
import type { Atom } from 'nanostores';
|
||||
import { atom, computed } from 'nanostores';
|
||||
import type { RefObject } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { objectKeys } from 'tsafe';
|
||||
|
||||
/**
|
||||
* We need to manage focus regions to conditionally enable hotkeys:
|
||||
* - Some hotkeys should only be enabled when a specific region is focused.
|
||||
* - Some hotkeys may conflict with other regions, so we need to disable them when a specific region is focused. For
|
||||
* example, `esc` is used to clear the gallery selection, but it is also used to cancel a filter or transform on the
|
||||
* canvas.
|
||||
*
|
||||
* To manage focus regions, we use a system of hooks and stores:
|
||||
* - `useFocusRegion` is a hook that registers an element as part of a focus region. When that element is focused, by
|
||||
* click or any other action, that region is set as the focused region. Optionally, focus can be set on mount. This
|
||||
* is useful for components like the image viewer.
|
||||
* - `useIsRegionFocused` is a hook that returns a boolean indicating if a specific region is focused.
|
||||
* - `useFocusRegionWatcher` is a hook that listens for focus events on the window. When an element is focused, it
|
||||
* checks if it is part of a focus region and sets that region as the focused region.
|
||||
*/
|
||||
|
||||
//
|
||||
|
||||
const log = logger('system');
|
||||
|
||||
/**
|
||||
* The names of the focus regions.
|
||||
*/
|
||||
type FocusRegionName = 'gallery' | 'layers' | 'canvas' | 'workflows' | 'viewer';
|
||||
|
||||
/**
|
||||
* A map of focus regions to the elements that are part of that region.
|
||||
*/
|
||||
const REGION_TARGETS: Record<FocusRegionName, Set<HTMLElement>> = {
|
||||
gallery: new Set<HTMLElement>(),
|
||||
layers: new Set<HTMLElement>(),
|
||||
canvas: new Set<HTMLElement>(),
|
||||
workflows: new Set<HTMLElement>(),
|
||||
viewer: new Set<HTMLElement>(),
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* The currently-focused region or `null` if no region is focused.
|
||||
*/
|
||||
const $focusedRegion = atom<FocusRegionName | null>(null);
|
||||
|
||||
/**
|
||||
* A map of focus regions to atoms that indicate if that region is focused.
|
||||
*/
|
||||
const FOCUS_REGIONS = objectKeys(REGION_TARGETS).reduce(
|
||||
(acc, region) => {
|
||||
acc[`$${region}`] = computed($focusedRegion, (focusedRegion) => focusedRegion === region);
|
||||
return acc;
|
||||
},
|
||||
{} as Record<`$${FocusRegionName}`, Atom<boolean>>
|
||||
);
|
||||
|
||||
/**
|
||||
* Sets the focused region, logging a trace level message.
|
||||
*/
|
||||
const setFocus = (region: FocusRegionName | null) => {
|
||||
$focusedRegion.set(region);
|
||||
log.trace(`Focus changed: ${region}`);
|
||||
};
|
||||
|
||||
type UseFocusRegionOptions = {
|
||||
focusOnMount?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Registers an element as part of a focus region. When that element is focused, by click or any other action, that
|
||||
* region is set as the focused region. Optionally, focus can be set on mount.
|
||||
*
|
||||
* On unmount, if the element is the last element in the region and the region is focused, the focused region is set to
|
||||
* `null`.
|
||||
*
|
||||
* @param region The focus region name.
|
||||
* @param ref The ref of the element to register.
|
||||
* @param options The options.
|
||||
*/
|
||||
export const useFocusRegion = (
|
||||
region: FocusRegionName,
|
||||
ref: RefObject<HTMLElement>,
|
||||
options?: UseFocusRegionOptions
|
||||
) => {
|
||||
useEffect(() => {
|
||||
if (!ref.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { focusOnMount = false } = { focusOnMount: false, ...options };
|
||||
|
||||
const element = ref.current;
|
||||
|
||||
REGION_TARGETS[region].add(element);
|
||||
|
||||
if (focusOnMount) {
|
||||
setFocus(region);
|
||||
}
|
||||
|
||||
return () => {
|
||||
REGION_TARGETS[region].delete(element);
|
||||
|
||||
if (REGION_TARGETS[region].size === 0 && $focusedRegion.get() === region) {
|
||||
setFocus(null);
|
||||
}
|
||||
};
|
||||
}, [options, ref, region]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a boolean indicating if a specific region is focused.
|
||||
* @param region The focus region name.
|
||||
*/
|
||||
export const useIsRegionFocused = (region: FocusRegionName) => {
|
||||
return useStore(FOCUS_REGIONS[`$${region}`]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Listens for focus events on the window. When an element is focused, it checks if it is part of a focus region and sets
|
||||
* that region as the focused region. The region corresponding to the deepest element is set.
|
||||
*/
|
||||
const onFocus = (_: FocusEvent) => {
|
||||
const activeElement = document.activeElement;
|
||||
if (!(activeElement instanceof HTMLElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const regionCandidates: { region: FocusRegionName; element: HTMLElement }[] = [];
|
||||
|
||||
for (const region of objectKeys(REGION_TARGETS)) {
|
||||
for (const element of REGION_TARGETS[region]) {
|
||||
if (element.contains(activeElement)) {
|
||||
regionCandidates.push({ region, element });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (regionCandidates.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sort by the shallowest element
|
||||
regionCandidates.sort((a, b) => {
|
||||
if (b.element.contains(a.element)) {
|
||||
return -1;
|
||||
}
|
||||
if (a.element.contains(b.element)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
// Set the region of the deepest element
|
||||
const focusedRegion = regionCandidates[0]?.region;
|
||||
|
||||
if (!focusedRegion) {
|
||||
log.warn('No focused region found');
|
||||
return;
|
||||
}
|
||||
|
||||
setFocus(focusedRegion);
|
||||
};
|
||||
|
||||
/**
|
||||
* Listens for focus events on the window. When an element is focused, it checks if it is part of a focus region and sets
|
||||
* that region as the focused region. This is a singleton.
|
||||
*/
|
||||
export const useFocusRegionWatcher = () => {
|
||||
useAssertSingleton('useFocusRegionWatcher');
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('focus', onFocus, { capture: true });
|
||||
return () => {
|
||||
window.removeEventListener('focus', onFocus, { capture: true });
|
||||
};
|
||||
}, []);
|
||||
};
|
||||
@@ -1,158 +0,0 @@
|
||||
import { logger } from 'app/logging/logger';
|
||||
import { useAssertSingleton } from 'common/hooks/useAssertSingleton';
|
||||
import { objectKeys } from 'common/util/objectKeys';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import type { Atom } from 'nanostores';
|
||||
import { atom, computed } from 'nanostores';
|
||||
import type { RefObject } from 'react';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
|
||||
const log = logger('system');
|
||||
|
||||
const _INTERACTION_SCOPES = ['gallery', 'canvas', 'stagingArea', 'workflows', 'imageViewer'] as const;
|
||||
|
||||
type InteractionScope = (typeof _INTERACTION_SCOPES)[number];
|
||||
|
||||
export const $activeScopes = atom<Set<InteractionScope>>(new Set());
|
||||
|
||||
type InteractionScopeData = {
|
||||
targets: Set<HTMLElement>;
|
||||
$isActive: Atom<boolean>;
|
||||
};
|
||||
|
||||
export const INTERACTION_SCOPES: Record<InteractionScope, InteractionScopeData> = _INTERACTION_SCOPES.reduce(
|
||||
(acc, region) => {
|
||||
acc[region] = {
|
||||
targets: new Set(),
|
||||
$isActive: computed($activeScopes, (activeScopes) => activeScopes.has(region)),
|
||||
};
|
||||
return acc;
|
||||
},
|
||||
{} as Record<InteractionScope, InteractionScopeData>
|
||||
);
|
||||
|
||||
const formatScopes = (interactionScopes: Set<InteractionScope>) => {
|
||||
if (interactionScopes.size === 0) {
|
||||
return 'none';
|
||||
}
|
||||
return Array.from(interactionScopes).join(', ');
|
||||
};
|
||||
|
||||
export const addScope = (scope: InteractionScope) => {
|
||||
const currentScopes = $activeScopes.get();
|
||||
if (currentScopes.has(scope)) {
|
||||
return;
|
||||
}
|
||||
const newScopes = new Set(currentScopes);
|
||||
newScopes.add(scope);
|
||||
$activeScopes.set(newScopes);
|
||||
log.trace(`Added scope ${scope}: ${formatScopes($activeScopes.get())}`);
|
||||
};
|
||||
|
||||
export const removeScope = (scope: InteractionScope) => {
|
||||
const currentScopes = $activeScopes.get();
|
||||
if (!currentScopes.has(scope)) {
|
||||
return;
|
||||
}
|
||||
const newScopes = new Set(currentScopes);
|
||||
newScopes.delete(scope);
|
||||
$activeScopes.set(newScopes);
|
||||
log.trace(`Removed scope ${scope}: ${formatScopes($activeScopes.get())}`);
|
||||
};
|
||||
|
||||
export const setScopes = (scopes: InteractionScope[]) => {
|
||||
const newScopes = new Set(scopes);
|
||||
$activeScopes.set(newScopes);
|
||||
log.trace(`Set scopes: ${formatScopes($activeScopes.get())}`);
|
||||
};
|
||||
|
||||
export const useScopeOnFocus = (scope: InteractionScope, ref: RefObject<HTMLElement>) => {
|
||||
useEffect(() => {
|
||||
const element = ref.current;
|
||||
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
INTERACTION_SCOPES[scope].targets.add(element);
|
||||
|
||||
return () => {
|
||||
INTERACTION_SCOPES[scope].targets.delete(element);
|
||||
};
|
||||
}, [ref, scope]);
|
||||
};
|
||||
|
||||
type UseScopeOnMountOptions = {
|
||||
mount?: boolean;
|
||||
unmount?: boolean;
|
||||
};
|
||||
|
||||
const defaultUseScopeOnMountOptions: UseScopeOnMountOptions = {
|
||||
mount: true,
|
||||
unmount: true,
|
||||
};
|
||||
|
||||
export const useScopeOnMount = (scope: InteractionScope, options?: UseScopeOnMountOptions) => {
|
||||
useEffect(() => {
|
||||
const { mount, unmount } = { ...defaultUseScopeOnMountOptions, ...options };
|
||||
|
||||
if (mount) {
|
||||
addScope(scope);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (unmount) {
|
||||
removeScope(scope);
|
||||
}
|
||||
};
|
||||
}, [options, scope]);
|
||||
};
|
||||
|
||||
export const useScopeImperativeApi = (scope: InteractionScope) => {
|
||||
const api = useMemo(() => {
|
||||
return {
|
||||
add: () => {
|
||||
addScope(scope);
|
||||
},
|
||||
remove: () => {
|
||||
removeScope(scope);
|
||||
},
|
||||
};
|
||||
}, [scope]);
|
||||
|
||||
return api;
|
||||
};
|
||||
|
||||
const handleFocusEvent = (_event: FocusEvent) => {
|
||||
const activeElement = document.activeElement;
|
||||
if (!(activeElement instanceof HTMLElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newActiveScopes = new Set<InteractionScope>();
|
||||
|
||||
for (const scope of objectKeys(INTERACTION_SCOPES)) {
|
||||
for (const element of INTERACTION_SCOPES[scope].targets) {
|
||||
if (element.contains(activeElement)) {
|
||||
newActiveScopes.add(scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const oldActiveScopes = $activeScopes.get();
|
||||
if (!isEqual(oldActiveScopes, newActiveScopes)) {
|
||||
$activeScopes.set(newActiveScopes);
|
||||
log.trace(`Scopes changed: ${formatScopes($activeScopes.get())}`);
|
||||
}
|
||||
};
|
||||
|
||||
export const useScopeFocusWatcher = () => {
|
||||
useAssertSingleton('useScopeFocusWatcher');
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('focus', handleFocusEvent, true);
|
||||
return () => {
|
||||
window.removeEventListener('focus', handleFocusEvent, true);
|
||||
};
|
||||
}, []);
|
||||
};
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { addScope, removeScope, setScopes } from 'common/hooks/interactionScopes';
|
||||
import { useClearQueue } from 'features/queue/components/ClearQueueConfirmationAlertDialog';
|
||||
import { useCancelCurrentQueueItem } from 'features/queue/hooks/useCancelCurrentQueueItem';
|
||||
import { useInvoke } from 'features/queue/hooks/useInvoke';
|
||||
@@ -71,8 +70,6 @@ export const useGlobalHotkeys = () => {
|
||||
category: 'app',
|
||||
callback: () => {
|
||||
dispatch(setActiveTab('canvas'));
|
||||
addScope('canvas');
|
||||
removeScope('workflows');
|
||||
},
|
||||
dependencies: [dispatch],
|
||||
});
|
||||
@@ -82,8 +79,6 @@ export const useGlobalHotkeys = () => {
|
||||
category: 'app',
|
||||
callback: () => {
|
||||
dispatch(setActiveTab('upscaling'));
|
||||
removeScope('canvas');
|
||||
removeScope('workflows');
|
||||
},
|
||||
dependencies: [dispatch],
|
||||
});
|
||||
@@ -93,8 +88,6 @@ export const useGlobalHotkeys = () => {
|
||||
category: 'app',
|
||||
callback: () => {
|
||||
dispatch(setActiveTab('workflows'));
|
||||
removeScope('canvas');
|
||||
addScope('workflows');
|
||||
},
|
||||
dependencies: [dispatch],
|
||||
});
|
||||
@@ -104,7 +97,6 @@ export const useGlobalHotkeys = () => {
|
||||
category: 'app',
|
||||
callback: () => {
|
||||
dispatch(setActiveTab('models'));
|
||||
setScopes([]);
|
||||
},
|
||||
options: {
|
||||
enabled: isModelManagerEnabled,
|
||||
@@ -117,7 +109,6 @@ export const useGlobalHotkeys = () => {
|
||||
category: 'app',
|
||||
callback: () => {
|
||||
dispatch(setActiveTab('queue'));
|
||||
setScopes([]);
|
||||
},
|
||||
dependencies: [dispatch, isModelManagerEnabled],
|
||||
});
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from 'features/controlLayers/store/ephemeral';
|
||||
import { useImageViewer } from 'features/gallery/components/ImageViewer/useImageViewer';
|
||||
import { useCurrentDestination } from 'features/queue/hooks/useCurrentDestination';
|
||||
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||
import { setActiveTab } from 'features/ui/store/uiSlice';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import type { PropsWithChildren, ReactNode } from 'react';
|
||||
@@ -30,13 +31,18 @@ const ActivateImageViewerButton = (props: PropsWithChildren) => {
|
||||
export const CanvasAlertsSendingToGallery = () => {
|
||||
const { t } = useTranslation();
|
||||
const destination = useCurrentDestination();
|
||||
const tab = useAppSelector(selectActiveTab);
|
||||
const isVisible = useMemo(() => {
|
||||
// This alert should only be visible when the destination is gallery and the tab is canvas
|
||||
if (tab !== 'canvas') {
|
||||
return false;
|
||||
}
|
||||
if (!destination) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return destination === 'gallery';
|
||||
}, [destination]);
|
||||
}, [destination, tab]);
|
||||
|
||||
return (
|
||||
<AlertWrapper
|
||||
@@ -68,7 +74,13 @@ export const CanvasAlertsSendingToCanvas = () => {
|
||||
const { t } = useTranslation();
|
||||
const destination = useCurrentDestination();
|
||||
const isStaging = useAppSelector(selectIsStaging);
|
||||
const tab = useAppSelector(selectActiveTab);
|
||||
const isVisible = useMemo(() => {
|
||||
// When we are on a non-canvas tab, and the current generation's destination is not the canvas, we don't show the alert
|
||||
// For example, on the workflows tab, when the destinatin is gallery, we don't show the alert
|
||||
if (tab !== 'canvas' && destination !== 'canvas') {
|
||||
return false;
|
||||
}
|
||||
if (isStaging) {
|
||||
return true;
|
||||
}
|
||||
@@ -78,7 +90,7 @@ export const CanvasAlertsSendingToCanvas = () => {
|
||||
}
|
||||
|
||||
return destination === 'canvas';
|
||||
}, [destination, isStaging]);
|
||||
}, [destination, isStaging, tab]);
|
||||
|
||||
return (
|
||||
<AlertWrapper
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
import { Divider, Flex } from '@invoke-ai/ui-library';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useFocusRegion } from 'common/hooks/focus';
|
||||
import { CanvasAddEntityButtons } from 'features/controlLayers/components/CanvasAddEntityButtons';
|
||||
import { CanvasEntityList } from 'features/controlLayers/components/CanvasEntityList/CanvasEntityList';
|
||||
import { EntityListSelectedEntityActionBar } from 'features/controlLayers/components/CanvasEntityList/EntityListSelectedEntityActionBar';
|
||||
import { CanvasManagerProviderGate } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
|
||||
import { selectHasEntities } from 'features/controlLayers/store/selectors';
|
||||
import { memo } from 'react';
|
||||
import { memo, useRef } from 'react';
|
||||
|
||||
export const CanvasLayersPanelContent = memo(() => {
|
||||
const hasEntities = useAppSelector(selectHasEntities);
|
||||
const layersPanelFocusRef = useRef<HTMLDivElement>(null);
|
||||
useFocusRegion('layers', layersPanelFocusRef);
|
||||
|
||||
return (
|
||||
<CanvasManagerProviderGate>
|
||||
<Flex flexDir="column" gap={2} w="full" h="full">
|
||||
<EntityListSelectedEntityActionBar />
|
||||
<Divider py={0} />
|
||||
{!hasEntities && <CanvasAddEntityButtons />}
|
||||
{hasEntities && <CanvasEntityList />}
|
||||
</Flex>
|
||||
</CanvasManagerProviderGate>
|
||||
<Flex ref={layersPanelFocusRef} flexDir="column" gap={2} w="full" h="full">
|
||||
<EntityListSelectedEntityActionBar />
|
||||
<Divider py={0} />
|
||||
{!hasEntities && <CanvasAddEntityButtons />}
|
||||
{hasEntities && <CanvasEntityList />}
|
||||
</Flex>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ContextMenu, Flex, MenuList } from '@invoke-ai/ui-library';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useScopeOnFocus } from 'common/hooks/interactionScopes';
|
||||
import { useFocusRegion } from 'common/hooks/focus';
|
||||
import { CanvasAlertsPreserveMask } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsPreserveMask';
|
||||
import { CanvasAlertsSelectedEntityStatus } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsSelectedEntityStatus';
|
||||
import { CanvasAlertsSendingToGallery } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsSendingTo';
|
||||
@@ -35,7 +35,7 @@ export const CanvasMainPanelContent = memo(() => {
|
||||
);
|
||||
}, []);
|
||||
|
||||
useScopeOnFocus('canvas', ref);
|
||||
useFocusRegion('canvas', ref);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
|
||||
@@ -2,8 +2,8 @@ import { useDndContext } from '@dnd-kit/core';
|
||||
import { Box, Button, Spacer, Tab, TabList, TabPanel, TabPanels, Tabs } from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useScopeOnFocus } from 'common/hooks/interactionScopes';
|
||||
import { CanvasLayersPanelContent } from 'features/controlLayers/components/CanvasLayersPanelContent';
|
||||
import { CanvasManagerProviderGate } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
|
||||
import {
|
||||
$canvasRightPanelTabIndex,
|
||||
selectCanvasRightPanelGalleryTab,
|
||||
@@ -18,9 +18,7 @@ import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const CanvasRightPanel = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const tabIndex = useStore($canvasRightPanelTabIndex);
|
||||
useScopeOnFocus('gallery', ref);
|
||||
const imageViewer = useImageViewer();
|
||||
const onClickViewerToggleButton = useCallback(() => {
|
||||
if ($canvasRightPanelTabIndex.get() !== 1) {
|
||||
@@ -46,7 +44,9 @@ export const CanvasRightPanel = memo(() => {
|
||||
</TabList>
|
||||
<TabPanels w="full" h="full">
|
||||
<TabPanel w="full" h="full" p={0} pt={3}>
|
||||
<CanvasLayersPanelContent />
|
||||
<CanvasManagerProviderGate>
|
||||
<CanvasLayersPanelContent />
|
||||
</CanvasManagerProviderGate>
|
||||
</TabPanel>
|
||||
<TabPanel w="full" h="full" p={0} pt={3}>
|
||||
<GalleryPanelContent />
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Button, ButtonGroup, Flex, FormControl, FormLabel, Heading, Spacer, Switch } from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { useFocusRegion, useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { FilterSettings } from 'features/controlLayers/components/Filters/FilterSettings';
|
||||
import { FilterTypeSelect } from 'features/controlLayers/components/Filters/FilterTypeSelect';
|
||||
import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
|
||||
@@ -14,118 +15,142 @@ import {
|
||||
} from 'features/controlLayers/store/canvasSettingsSlice';
|
||||
import type { FilterConfig } from 'features/controlLayers/store/filters';
|
||||
import { IMAGE_FILTERS } from 'features/controlLayers/store/filters';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData';
|
||||
import { memo, useCallback, useMemo, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiArrowsCounterClockwiseBold, PiCheckBold, PiShootingStarBold, PiXBold } from 'react-icons/pi';
|
||||
|
||||
const FilterBox = memo(({ adapter }: { adapter: CanvasEntityAdapterRasterLayer | CanvasEntityAdapterControlLayer }) => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const config = useStore(adapter.filterer.$filterConfig);
|
||||
const isProcessing = useStore(adapter.filterer.$isProcessing);
|
||||
const hasProcessed = useStore(adapter.filterer.$hasProcessed);
|
||||
const autoProcessFilter = useAppSelector(selectAutoProcessFilter);
|
||||
const isolatedFilteringPreview = useAppSelector(selectIsolatedFilteringPreview);
|
||||
const onChangeIsolatedPreview = useCallback(() => {
|
||||
dispatch(settingsIsolatedFilteringPreviewToggled());
|
||||
}, [dispatch]);
|
||||
const FilterContent = memo(
|
||||
({ adapter }: { adapter: CanvasEntityAdapterRasterLayer | CanvasEntityAdapterControlLayer }) => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
useFocusRegion('canvas', ref, { focusOnMount: true });
|
||||
|
||||
const onChangeFilterConfig = useCallback(
|
||||
(filterConfig: FilterConfig) => {
|
||||
adapter.filterer.$filterConfig.set(filterConfig);
|
||||
},
|
||||
[adapter.filterer.$filterConfig]
|
||||
);
|
||||
const config = useStore(adapter.filterer.$filterConfig);
|
||||
const isCanvasFocused = useIsRegionFocused('canvas');
|
||||
const isProcessing = useStore(adapter.filterer.$isProcessing);
|
||||
const hasProcessed = useStore(adapter.filterer.$hasProcessed);
|
||||
const autoProcessFilter = useAppSelector(selectAutoProcessFilter);
|
||||
const isolatedFilteringPreview = useAppSelector(selectIsolatedFilteringPreview);
|
||||
const onChangeIsolatedPreview = useCallback(() => {
|
||||
dispatch(settingsIsolatedFilteringPreviewToggled());
|
||||
}, [dispatch]);
|
||||
|
||||
const onChangeFilterType = useCallback(
|
||||
(filterType: FilterConfig['type']) => {
|
||||
adapter.filterer.$filterConfig.set(IMAGE_FILTERS[filterType].buildDefaults());
|
||||
},
|
||||
[adapter.filterer.$filterConfig]
|
||||
);
|
||||
const onChangeFilterConfig = useCallback(
|
||||
(filterConfig: FilterConfig) => {
|
||||
adapter.filterer.$filterConfig.set(filterConfig);
|
||||
},
|
||||
[adapter.filterer.$filterConfig]
|
||||
);
|
||||
|
||||
const onChangeAutoProcessFilter = useCallback(() => {
|
||||
dispatch(settingsAutoProcessFilterToggled());
|
||||
}, [dispatch]);
|
||||
const onChangeFilterType = useCallback(
|
||||
(filterType: FilterConfig['type']) => {
|
||||
adapter.filterer.$filterConfig.set(IMAGE_FILTERS[filterType].buildDefaults());
|
||||
},
|
||||
[adapter.filterer.$filterConfig]
|
||||
);
|
||||
|
||||
const isValid = useMemo(() => {
|
||||
return IMAGE_FILTERS[config.type].validateConfig?.(config as never) ?? true;
|
||||
}, [config]);
|
||||
const onChangeAutoProcessFilter = useCallback(() => {
|
||||
dispatch(settingsAutoProcessFilterToggled());
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
bg="base.800"
|
||||
borderRadius="base"
|
||||
p={4}
|
||||
flexDir="column"
|
||||
gap={4}
|
||||
w={420}
|
||||
h="auto"
|
||||
shadow="dark-lg"
|
||||
transitionProperty="height"
|
||||
transitionDuration="normal"
|
||||
>
|
||||
<Flex w="full" gap={4}>
|
||||
<Heading size="md" color="base.300" userSelect="none">
|
||||
{t('controlLayers.filter.filter')}
|
||||
</Heading>
|
||||
<Spacer />
|
||||
<FormControl w="min-content">
|
||||
<FormLabel m={0}>{t('controlLayers.filter.autoProcess')}</FormLabel>
|
||||
<Switch size="sm" isChecked={autoProcessFilter} onChange={onChangeAutoProcessFilter} />
|
||||
</FormControl>
|
||||
<FormControl w="min-content">
|
||||
<FormLabel m={0}>{t('controlLayers.settings.isolatedPreview')}</FormLabel>
|
||||
<Switch size="sm" isChecked={isolatedFilteringPreview} onChange={onChangeIsolatedPreview} />
|
||||
</FormControl>
|
||||
const isValid = useMemo(() => {
|
||||
return IMAGE_FILTERS[config.type].validateConfig?.(config as never) ?? true;
|
||||
}, [config]);
|
||||
|
||||
useRegisteredHotkeys({
|
||||
id: 'applyFilter',
|
||||
category: 'canvas',
|
||||
callback: adapter.filterer.apply,
|
||||
options: { enabled: !isProcessing && isCanvasFocused },
|
||||
dependencies: [adapter.filterer, isProcessing, isCanvasFocused],
|
||||
});
|
||||
|
||||
useRegisteredHotkeys({
|
||||
id: 'cancelFilter',
|
||||
category: 'canvas',
|
||||
callback: adapter.filterer.cancel,
|
||||
options: { enabled: !isProcessing && isCanvasFocused },
|
||||
dependencies: [adapter.filterer, isProcessing, isCanvasFocused],
|
||||
});
|
||||
|
||||
return (
|
||||
<Flex
|
||||
ref={ref}
|
||||
bg="base.800"
|
||||
borderRadius="base"
|
||||
p={4}
|
||||
flexDir="column"
|
||||
gap={4}
|
||||
w={420}
|
||||
h="auto"
|
||||
shadow="dark-lg"
|
||||
transitionProperty="height"
|
||||
transitionDuration="normal"
|
||||
>
|
||||
<Flex w="full" gap={4}>
|
||||
<Heading size="md" color="base.300" userSelect="none">
|
||||
{t('controlLayers.filter.filter')}
|
||||
</Heading>
|
||||
<Spacer />
|
||||
<FormControl w="min-content">
|
||||
<FormLabel m={0}>{t('controlLayers.filter.autoProcess')}</FormLabel>
|
||||
<Switch size="sm" isChecked={autoProcessFilter} onChange={onChangeAutoProcessFilter} />
|
||||
</FormControl>
|
||||
<FormControl w="min-content">
|
||||
<FormLabel m={0}>{t('controlLayers.settings.isolatedPreview')}</FormLabel>
|
||||
<Switch size="sm" isChecked={isolatedFilteringPreview} onChange={onChangeIsolatedPreview} />
|
||||
</FormControl>
|
||||
</Flex>
|
||||
<FilterTypeSelect filterType={config.type} onChange={onChangeFilterType} />
|
||||
<FilterSettings filterConfig={config} onChange={onChangeFilterConfig} />
|
||||
<ButtonGroup isAttached={false} size="sm" w="full">
|
||||
<Button
|
||||
variant="ghost"
|
||||
leftIcon={<PiShootingStarBold />}
|
||||
onClick={adapter.filterer.processImmediate}
|
||||
isLoading={isProcessing}
|
||||
loadingText={t('controlLayers.filter.process')}
|
||||
isDisabled={!isValid || autoProcessFilter}
|
||||
>
|
||||
{t('controlLayers.filter.process')}
|
||||
</Button>
|
||||
<Spacer />
|
||||
<Button
|
||||
leftIcon={<PiArrowsCounterClockwiseBold />}
|
||||
onClick={adapter.filterer.reset}
|
||||
isLoading={isProcessing}
|
||||
loadingText={t('controlLayers.filter.reset')}
|
||||
variant="ghost"
|
||||
>
|
||||
{t('controlLayers.filter.reset')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
leftIcon={<PiCheckBold />}
|
||||
onClick={adapter.filterer.apply}
|
||||
isLoading={isProcessing}
|
||||
loadingText={t('controlLayers.filter.apply')}
|
||||
isDisabled={!isValid || !hasProcessed}
|
||||
>
|
||||
{t('controlLayers.filter.apply')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
leftIcon={<PiXBold />}
|
||||
onClick={adapter.filterer.cancel}
|
||||
loadingText={t('controlLayers.filter.cancel')}
|
||||
>
|
||||
{t('controlLayers.filter.cancel')}
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</Flex>
|
||||
<FilterTypeSelect filterType={config.type} onChange={onChangeFilterType} />
|
||||
<FilterSettings filterConfig={config} onChange={onChangeFilterConfig} />
|
||||
<ButtonGroup isAttached={false} size="sm" w="full">
|
||||
<Button
|
||||
variant="ghost"
|
||||
leftIcon={<PiShootingStarBold />}
|
||||
onClick={adapter.filterer.processImmediate}
|
||||
isLoading={isProcessing}
|
||||
loadingText={t('controlLayers.filter.process')}
|
||||
isDisabled={!isValid || autoProcessFilter}
|
||||
>
|
||||
{t('controlLayers.filter.process')}
|
||||
</Button>
|
||||
<Spacer />
|
||||
<Button
|
||||
leftIcon={<PiArrowsCounterClockwiseBold />}
|
||||
onClick={adapter.filterer.reset}
|
||||
isLoading={isProcessing}
|
||||
loadingText={t('controlLayers.filter.reset')}
|
||||
variant="ghost"
|
||||
>
|
||||
{t('controlLayers.filter.reset')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
leftIcon={<PiCheckBold />}
|
||||
onClick={adapter.filterer.apply}
|
||||
isLoading={isProcessing}
|
||||
loadingText={t('controlLayers.filter.apply')}
|
||||
isDisabled={!isValid || !hasProcessed}
|
||||
>
|
||||
{t('controlLayers.filter.apply')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
leftIcon={<PiXBold />}
|
||||
onClick={adapter.filterer.cancel}
|
||||
loadingText={t('controlLayers.filter.cancel')}
|
||||
>
|
||||
{t('controlLayers.filter.cancel')}
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</Flex>
|
||||
);
|
||||
});
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
FilterBox.displayName = 'FilterBox';
|
||||
FilterContent.displayName = 'FilterContent';
|
||||
|
||||
export const Filter = () => {
|
||||
const canvasManager = useCanvasManager();
|
||||
@@ -134,7 +159,7 @@ export const Filter = () => {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <FilterBox adapter={adapter} />;
|
||||
return <FilterContent adapter={adapter} />;
|
||||
};
|
||||
|
||||
Filter.displayName = 'Filter';
|
||||
|
||||
@@ -26,7 +26,7 @@ export const CanvasSettingsInvertScrollCheckbox = memo(() => {
|
||||
);
|
||||
return (
|
||||
<FormControl w="full">
|
||||
<FormLabel flexGrow={1}>{t('unifiedCanvas.invertBrushSizeScrollDirection')}</FormLabel>
|
||||
<FormLabel flexGrow={1}>{t('controlLayers.settings.invertBrushSizeScrollDirection')}</FormLabel>
|
||||
<Checkbox isChecked={invertScrollForToolWidth} onChange={onChange} />
|
||||
</FormControl>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { ButtonGroup } from '@invoke-ai/ui-library';
|
||||
import { useScopeOnMount } from 'common/hooks/interactionScopes';
|
||||
import { StagingAreaToolbarAcceptButton } from 'features/controlLayers/components/StagingArea/StagingAreaToolbarAcceptButton';
|
||||
import { StagingAreaToolbarDiscardAllButton } from 'features/controlLayers/components/StagingArea/StagingAreaToolbarDiscardAllButton';
|
||||
import { StagingAreaToolbarDiscardSelectedButton } from 'features/controlLayers/components/StagingArea/StagingAreaToolbarDiscardSelectedButton';
|
||||
@@ -11,8 +10,6 @@ import { StagingAreaToolbarToggleShowResultsButton } from 'features/controlLayer
|
||||
import { memo } from 'react';
|
||||
|
||||
export const StagingAreaToolbar = memo(() => {
|
||||
useScopeOnMount('stagingArea');
|
||||
|
||||
return (
|
||||
<>
|
||||
<ButtonGroup borderRadius="base" shadow="dark-lg">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { IconButton } from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { INTERACTION_SCOPES } from 'common/hooks/interactionScopes';
|
||||
import { useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
|
||||
import { rasterLayerAdded } from 'features/controlLayers/store/canvasSlice';
|
||||
import {
|
||||
@@ -25,7 +25,7 @@ export const StagingAreaToolbarAcceptButton = memo(() => {
|
||||
const selectedEntityIdentifier = useAppSelector(selectSelectedEntityIdentifier);
|
||||
const imageCount = useAppSelector(selectImageCount);
|
||||
const shouldShowStagedImage = useStore(canvasManager.stagingArea.$shouldShowStagedImage);
|
||||
const isCanvasActive = useStore(INTERACTION_SCOPES.canvas.$isActive);
|
||||
const isCanvasFocused = useIsRegionFocused('canvas');
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -50,15 +50,15 @@ export const StagingAreaToolbarAcceptButton = memo(() => {
|
||||
acceptSelected,
|
||||
{
|
||||
preventDefault: true,
|
||||
enabled: isCanvasActive && shouldShowStagedImage && imageCount > 1,
|
||||
enabled: isCanvasFocused && shouldShowStagedImage && imageCount > 1,
|
||||
},
|
||||
[isCanvasActive, shouldShowStagedImage, imageCount]
|
||||
[isCanvasFocused, shouldShowStagedImage, imageCount]
|
||||
);
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
tooltip={`${t('unifiedCanvas.accept')} (Enter)`}
|
||||
aria-label={`${t('unifiedCanvas.accept')} (Enter)`}
|
||||
tooltip={`${t('common.accept')} (Enter)`}
|
||||
aria-label={`${t('common.accept')} (Enter)`}
|
||||
icon={<PiCheckBold />}
|
||||
onClick={acceptSelected}
|
||||
colorScheme="invokeBlue"
|
||||
|
||||
@@ -15,8 +15,8 @@ export const StagingAreaToolbarDiscardAllButton = memo(() => {
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
tooltip={`${t('unifiedCanvas.discardAll')} (Esc)`}
|
||||
aria-label={t('unifiedCanvas.discardAll')}
|
||||
tooltip={`${t('controlLayers.stagingArea.discardAll')} (Esc)`}
|
||||
aria-label={t('controlLayers.stagingArea.discardAll')}
|
||||
icon={<PiTrashSimpleBold />}
|
||||
onClick={discardAll}
|
||||
colorScheme="error"
|
||||
|
||||
@@ -32,8 +32,8 @@ export const StagingAreaToolbarDiscardSelectedButton = memo(() => {
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
tooltip={`${t('unifiedCanvas.discardCurrent')}`}
|
||||
aria-label={t('unifiedCanvas.discardCurrent')}
|
||||
tooltip={t('controlLayers.stagingArea.discard')}
|
||||
aria-label={t('controlLayers.stagingArea.discard')}
|
||||
icon={<PiXBold />}
|
||||
onClick={discardSelected}
|
||||
colorScheme="invokeBlue"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { IconButton } from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { INTERACTION_SCOPES } from 'common/hooks/interactionScopes';
|
||||
import { useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
|
||||
import {
|
||||
selectImageCount,
|
||||
@@ -17,7 +17,7 @@ export const StagingAreaToolbarNextButton = memo(() => {
|
||||
const canvasManager = useCanvasManager();
|
||||
const imageCount = useAppSelector(selectImageCount);
|
||||
const shouldShowStagedImage = useStore(canvasManager.stagingArea.$shouldShowStagedImage);
|
||||
const isCanvasActive = useStore(INTERACTION_SCOPES.canvas.$isActive);
|
||||
const isCanvasFocused = useIsRegionFocused('canvas');
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -30,15 +30,15 @@ export const StagingAreaToolbarNextButton = memo(() => {
|
||||
selectNext,
|
||||
{
|
||||
preventDefault: true,
|
||||
enabled: isCanvasActive && shouldShowStagedImage && imageCount > 1,
|
||||
enabled: isCanvasFocused && shouldShowStagedImage && imageCount > 1,
|
||||
},
|
||||
[isCanvasActive, shouldShowStagedImage, imageCount]
|
||||
[isCanvasFocused, shouldShowStagedImage, imageCount]
|
||||
);
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
tooltip={`${t('unifiedCanvas.next')} (Right)`}
|
||||
aria-label={`${t('unifiedCanvas.next')} (Right)`}
|
||||
tooltip={`${t('controlLayers.stagingArea.next')} (Right)`}
|
||||
aria-label={`${t('controlLayers.stagingArea.next')} (Right)`}
|
||||
icon={<PiArrowRightBold />}
|
||||
onClick={selectNext}
|
||||
colorScheme="invokeBlue"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { IconButton } from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { INTERACTION_SCOPES } from 'common/hooks/interactionScopes';
|
||||
import { useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
|
||||
import {
|
||||
selectImageCount,
|
||||
@@ -17,7 +17,7 @@ export const StagingAreaToolbarPrevButton = memo(() => {
|
||||
const canvasManager = useCanvasManager();
|
||||
const imageCount = useAppSelector(selectImageCount);
|
||||
const shouldShowStagedImage = useStore(canvasManager.stagingArea.$shouldShowStagedImage);
|
||||
const isCanvasActive = useStore(INTERACTION_SCOPES.canvas.$isActive);
|
||||
const isCanvasFocused = useIsRegionFocused('canvas');
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -30,15 +30,15 @@ export const StagingAreaToolbarPrevButton = memo(() => {
|
||||
selectPrev,
|
||||
{
|
||||
preventDefault: true,
|
||||
enabled: isCanvasActive && shouldShowStagedImage && imageCount > 1,
|
||||
enabled: isCanvasFocused && shouldShowStagedImage && imageCount > 1,
|
||||
},
|
||||
[isCanvasActive, shouldShowStagedImage, imageCount]
|
||||
[isCanvasFocused, shouldShowStagedImage, imageCount]
|
||||
);
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
tooltip={`${t('unifiedCanvas.previous')} (Left)`}
|
||||
aria-label={`${t('unifiedCanvas.previous')} (Left)`}
|
||||
tooltip={`${t('controlLayers.stagingArea.previous')} (Left)`}
|
||||
aria-label={`${t('controlLayers.stagingArea.previous')} (Left)`}
|
||||
icon={<PiArrowLeftBold />}
|
||||
onClick={selectPrev}
|
||||
colorScheme="invokeBlue"
|
||||
|
||||
@@ -37,8 +37,8 @@ export const StagingAreaToolbarSaveSelectedToGalleryButton = memo(() => {
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
tooltip={t('unifiedCanvas.saveToGallery')}
|
||||
aria-label={t('unifiedCanvas.saveToGallery')}
|
||||
tooltip={t('controlLayers.stagingArea.saveToGallery')}
|
||||
aria-label={t('controlLayers.stagingArea.saveToGallery')}
|
||||
icon={<PiFloppyDiskBold />}
|
||||
onClick={saveSelectedImageToGallery}
|
||||
colorScheme="invokeBlue"
|
||||
|
||||
@@ -17,8 +17,16 @@ export const StagingAreaToolbarToggleShowResultsButton = memo(() => {
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
tooltip={shouldShowStagedImage ? t('unifiedCanvas.showResultsOn') : t('unifiedCanvas.showResultsOff')}
|
||||
aria-label={shouldShowStagedImage ? t('unifiedCanvas.showResultsOn') : t('unifiedCanvas.showResultsOff')}
|
||||
tooltip={
|
||||
shouldShowStagedImage
|
||||
? t('controlLayers.stagingArea.showResultsOn')
|
||||
: t('controlLayers.stagingArea.showResultsOff')
|
||||
}
|
||||
aria-label={
|
||||
shouldShowStagedImage
|
||||
? t('controlLayers.stagingArea.showResultsOn')
|
||||
: t('controlLayers.stagingArea.showResultsOff')
|
||||
}
|
||||
data-alert={!shouldShowStagedImage}
|
||||
icon={shouldShowStagedImage ? <PiEyeBold /> : <PiEyeSlashBold />}
|
||||
onClick={toggleShowResults}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { IconButton } from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { INTERACTION_SCOPES } from 'common/hooks/interactionScopes';
|
||||
import { useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
|
||||
import { useImageViewer } from 'features/gallery/components/ImageViewer/useImageViewer';
|
||||
import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData';
|
||||
@@ -11,50 +10,50 @@ import { PiArrowsOutBold } from 'react-icons/pi';
|
||||
export const CanvasToolbarResetViewButton = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const canvasManager = useCanvasManager();
|
||||
const isCanvasActive = useStore(INTERACTION_SCOPES.canvas.$isActive);
|
||||
const isCanvasFocused = useIsRegionFocused('canvas');
|
||||
const imageViewer = useImageViewer();
|
||||
|
||||
useRegisteredHotkeys({
|
||||
id: 'fitLayersToCanvas',
|
||||
category: 'canvas',
|
||||
callback: canvasManager.stage.fitLayersToStage,
|
||||
options: { enabled: isCanvasActive && !imageViewer.isOpen, preventDefault: true },
|
||||
dependencies: [isCanvasActive, imageViewer.isOpen],
|
||||
options: { enabled: isCanvasFocused && !imageViewer.isOpen, preventDefault: true },
|
||||
dependencies: [isCanvasFocused, imageViewer.isOpen],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'fitBboxToCanvas',
|
||||
category: 'canvas',
|
||||
callback: canvasManager.stage.fitBboxToStage,
|
||||
options: { enabled: isCanvasActive && !imageViewer.isOpen, preventDefault: true },
|
||||
dependencies: [isCanvasActive, imageViewer.isOpen],
|
||||
options: { enabled: isCanvasFocused && !imageViewer.isOpen, preventDefault: true },
|
||||
dependencies: [isCanvasFocused, imageViewer.isOpen],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'setZoomTo100Percent',
|
||||
category: 'canvas',
|
||||
callback: () => canvasManager.stage.setScale(1),
|
||||
options: { enabled: isCanvasActive && !imageViewer.isOpen, preventDefault: true },
|
||||
dependencies: [isCanvasActive, imageViewer.isOpen],
|
||||
options: { enabled: isCanvasFocused && !imageViewer.isOpen, preventDefault: true },
|
||||
dependencies: [isCanvasFocused, imageViewer.isOpen],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'setZoomTo200Percent',
|
||||
category: 'canvas',
|
||||
callback: () => canvasManager.stage.setScale(2),
|
||||
options: { enabled: isCanvasActive && !imageViewer.isOpen, preventDefault: true },
|
||||
dependencies: [isCanvasActive, imageViewer.isOpen],
|
||||
options: { enabled: isCanvasFocused && !imageViewer.isOpen, preventDefault: true },
|
||||
dependencies: [isCanvasFocused, imageViewer.isOpen],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'setZoomTo400Percent',
|
||||
category: 'canvas',
|
||||
callback: () => canvasManager.stage.setScale(4),
|
||||
options: { enabled: isCanvasActive && !imageViewer.isOpen, preventDefault: true },
|
||||
dependencies: [isCanvasActive, imageViewer.isOpen],
|
||||
options: { enabled: isCanvasFocused && !imageViewer.isOpen, preventDefault: true },
|
||||
dependencies: [isCanvasFocused, imageViewer.isOpen],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'setZoomTo800Percent',
|
||||
category: 'canvas',
|
||||
callback: () => canvasManager.stage.setScale(8),
|
||||
options: { enabled: isCanvasActive && !imageViewer.isOpen, preventDefault: true },
|
||||
dependencies: [isCanvasActive, imageViewer.isOpen],
|
||||
options: { enabled: isCanvasFocused && !imageViewer.isOpen, preventDefault: true },
|
||||
dependencies: [isCanvasFocused, imageViewer.isOpen],
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,27 +1,49 @@
|
||||
import { Button, ButtonGroup, Flex, FormControl, FormLabel, Heading, Spacer, Switch } from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { useFocusRegion, useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
|
||||
import type { CanvasEntityAdapter } from 'features/controlLayers/konva/CanvasEntity/types';
|
||||
import {
|
||||
selectIsolatedTransformingPreview,
|
||||
settingsIsolatedTransformingPreviewToggled,
|
||||
} from 'features/controlLayers/store/canvasSettingsSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData';
|
||||
import { memo, useCallback, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiArrowsCounterClockwiseBold, PiArrowsOutBold, PiCheckBold, PiXBold } from 'react-icons/pi';
|
||||
|
||||
const TransformBox = memo(({ adapter }: { adapter: CanvasEntityAdapter }) => {
|
||||
const TransformContent = memo(({ adapter }: { adapter: CanvasEntityAdapter }) => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
useFocusRegion('canvas', ref, { focusOnMount: true });
|
||||
const isCanvasFocused = useIsRegionFocused('canvas');
|
||||
const isProcessing = useStore(adapter.transformer.$isProcessing);
|
||||
const isolatedTransformingPreview = useAppSelector(selectIsolatedTransformingPreview);
|
||||
const onChangeIsolatedPreview = useCallback(() => {
|
||||
dispatch(settingsIsolatedTransformingPreviewToggled());
|
||||
}, [dispatch]);
|
||||
|
||||
useRegisteredHotkeys({
|
||||
id: 'applyTransform',
|
||||
category: 'canvas',
|
||||
callback: adapter.transformer.applyTransform,
|
||||
options: { enabled: !isProcessing && isCanvasFocused },
|
||||
dependencies: [adapter.transformer, isProcessing, isCanvasFocused],
|
||||
});
|
||||
|
||||
useRegisteredHotkeys({
|
||||
id: 'cancelTransform',
|
||||
category: 'canvas',
|
||||
callback: adapter.transformer.stopTransform,
|
||||
options: { enabled: !isProcessing && isCanvasFocused },
|
||||
dependencies: [adapter.transformer, isProcessing, isCanvasFocused],
|
||||
});
|
||||
|
||||
return (
|
||||
<Flex
|
||||
ref={ref}
|
||||
bg="base.800"
|
||||
borderRadius="base"
|
||||
p={4}
|
||||
@@ -86,7 +108,7 @@ const TransformBox = memo(({ adapter }: { adapter: CanvasEntityAdapter }) => {
|
||||
);
|
||||
});
|
||||
|
||||
TransformBox.displayName = 'Transform';
|
||||
TransformContent.displayName = 'TransformContent';
|
||||
|
||||
export const Transform = () => {
|
||||
const canvasManager = useCanvasManager();
|
||||
@@ -96,5 +118,5 @@ export const Transform = () => {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <TransformBox adapter={adapter} />;
|
||||
return <TransformContent adapter={adapter} />;
|
||||
};
|
||||
|
||||
@@ -243,7 +243,7 @@ export class CanvasBboxModule extends CanvasModuleBase {
|
||||
onDragMove = () => {
|
||||
// The grid size here is the _position_ grid size, not the _dimension_ grid size - it is not constratined by the
|
||||
// currently-selected model.
|
||||
const gridSize = this.manager.stateApi.$ctrlKey.get() || this.manager.stateApi.$metaKey.get() ? 8 : 64;
|
||||
const gridSize = this.manager.stateApi.getGridSize();
|
||||
const bbox = this.manager.stateApi.getBbox();
|
||||
const bboxRect: Rect = {
|
||||
...bbox.rect,
|
||||
|
||||
@@ -1,8 +1,21 @@
|
||||
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
|
||||
import { CanvasModuleBase } from 'features/controlLayers/konva/CanvasModuleBase';
|
||||
import { getPrefixedId } from 'features/controlLayers/konva/util';
|
||||
import { selectCanvasSlice } from 'features/controlLayers/store/selectors';
|
||||
import { type CanvasState, getEntityIdentifier } from 'features/controlLayers/store/types';
|
||||
import {
|
||||
selectCanvasSlice,
|
||||
selectControlLayerEntities,
|
||||
selectInpaintMaskEntities,
|
||||
selectRasterLayerEntities,
|
||||
selectRegionalGuidanceEntities,
|
||||
} from 'features/controlLayers/store/selectors';
|
||||
import type {
|
||||
CanvasControlLayerState,
|
||||
CanvasInpaintMaskState,
|
||||
CanvasRasterLayerState,
|
||||
CanvasRegionalGuidanceState,
|
||||
CanvasState,
|
||||
} from 'features/controlLayers/store/types';
|
||||
import { getEntityIdentifier } from 'features/controlLayers/store/types';
|
||||
import type { Logger } from 'roarr';
|
||||
|
||||
export class CanvasEntityRendererModule extends CanvasModuleBase {
|
||||
@@ -25,62 +38,66 @@ export class CanvasEntityRendererModule extends CanvasModuleBase {
|
||||
|
||||
this.log.debug('Creating module');
|
||||
|
||||
this.subscriptions.add(this.manager.stateApi.createStoreSubscription(selectCanvasSlice, this.render));
|
||||
this.subscriptions.add(
|
||||
this.manager.stateApi.createStoreSubscription(selectRasterLayerEntities, this.createNewRasterLayers)
|
||||
);
|
||||
|
||||
this.subscriptions.add(
|
||||
this.manager.stateApi.createStoreSubscription(selectControlLayerEntities, this.createNewControlLayers)
|
||||
);
|
||||
|
||||
this.subscriptions.add(
|
||||
this.manager.stateApi.createStoreSubscription(selectInpaintMaskEntities, this.createNewInpaintMasks)
|
||||
);
|
||||
|
||||
this.subscriptions.add(
|
||||
this.manager.stateApi.createStoreSubscription(selectRegionalGuidanceEntities, this.createNewRegionalGuidance)
|
||||
);
|
||||
|
||||
this.subscriptions.add(this.manager.stateApi.createStoreSubscription(selectCanvasSlice, this.arrangeEntities));
|
||||
}
|
||||
|
||||
initialize = () => {
|
||||
this.log.debug('Initializing module');
|
||||
this.render(this.manager.stateApi.runSelector(selectCanvasSlice), null);
|
||||
this.createNewRasterLayers(this.manager.stateApi.runSelector(selectRasterLayerEntities));
|
||||
this.createNewControlLayers(this.manager.stateApi.runSelector(selectControlLayerEntities));
|
||||
this.createNewRegionalGuidance(this.manager.stateApi.runSelector(selectRegionalGuidanceEntities));
|
||||
this.createNewInpaintMasks(this.manager.stateApi.runSelector(selectInpaintMaskEntities));
|
||||
this.arrangeEntities(this.manager.stateApi.runSelector(selectCanvasSlice), null);
|
||||
};
|
||||
|
||||
render = async (state: CanvasState, prevState: CanvasState | null) => {
|
||||
await this.createNewRasterLayers(state, prevState);
|
||||
await this.createNewControlLayers(state, prevState);
|
||||
await this.createNewRegionalGuidance(state, prevState);
|
||||
await this.createNewInpaintMasks(state, prevState);
|
||||
this.arrangeEntities(state, prevState);
|
||||
};
|
||||
|
||||
createNewRasterLayers = async (state: CanvasState, prevState: CanvasState | null) => {
|
||||
if (!prevState || state.rasterLayers.entities !== prevState.rasterLayers.entities) {
|
||||
for (const entityState of state.rasterLayers.entities) {
|
||||
if (!this.manager.adapters.rasterLayers.has(entityState.id)) {
|
||||
const adapter = this.manager.createAdapter(getEntityIdentifier(entityState));
|
||||
await adapter.initialize();
|
||||
}
|
||||
createNewRasterLayers = (entities: CanvasRasterLayerState[]) => {
|
||||
for (const entityState of entities) {
|
||||
if (!this.manager.adapters.rasterLayers.has(entityState.id)) {
|
||||
const adapter = this.manager.createAdapter(getEntityIdentifier(entityState));
|
||||
adapter.initialize();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
createNewControlLayers = async (state: CanvasState, prevState: CanvasState | null) => {
|
||||
if (!prevState || state.controlLayers.entities !== prevState.controlLayers.entities) {
|
||||
for (const entityState of state.controlLayers.entities) {
|
||||
if (!this.manager.adapters.controlLayers.has(entityState.id)) {
|
||||
const adapter = this.manager.createAdapter(getEntityIdentifier(entityState));
|
||||
await adapter.initialize();
|
||||
}
|
||||
createNewControlLayers = (entities: CanvasControlLayerState[]) => {
|
||||
for (const entityState of entities) {
|
||||
if (!this.manager.adapters.controlLayers.has(entityState.id)) {
|
||||
const adapter = this.manager.createAdapter(getEntityIdentifier(entityState));
|
||||
adapter.initialize();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
createNewRegionalGuidance = async (state: CanvasState, prevState: CanvasState | null) => {
|
||||
if (!prevState || state.regionalGuidance.entities !== prevState.regionalGuidance.entities) {
|
||||
for (const entityState of state.regionalGuidance.entities) {
|
||||
if (!this.manager.adapters.regionMasks.has(entityState.id)) {
|
||||
const adapter = this.manager.createAdapter(getEntityIdentifier(entityState));
|
||||
await adapter.initialize();
|
||||
}
|
||||
createNewRegionalGuidance = (entities: CanvasRegionalGuidanceState[]) => {
|
||||
for (const entityState of entities) {
|
||||
if (!this.manager.adapters.regionMasks.has(entityState.id)) {
|
||||
const adapter = this.manager.createAdapter(getEntityIdentifier(entityState));
|
||||
adapter.initialize();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
createNewInpaintMasks = async (state: CanvasState, prevState: CanvasState | null) => {
|
||||
if (!prevState || state.inpaintMasks.entities !== prevState.inpaintMasks.entities) {
|
||||
for (const entityState of state.inpaintMasks.entities) {
|
||||
if (!this.manager.adapters.inpaintMasks.has(entityState.id)) {
|
||||
const adapter = this.manager.createAdapter(getEntityIdentifier(entityState));
|
||||
await adapter.initialize();
|
||||
}
|
||||
createNewInpaintMasks = (entities: CanvasInpaintMaskState[]) => {
|
||||
for (const entityState of entities) {
|
||||
if (!this.manager.adapters.inpaintMasks.has(entityState.id)) {
|
||||
const adapter = this.manager.createAdapter(getEntityIdentifier(entityState));
|
||||
adapter.initialize();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -62,6 +62,7 @@ export class CanvasStagingAreaModule extends CanvasModuleBase {
|
||||
initialize = () => {
|
||||
this.log.debug('Initializing module');
|
||||
this.render();
|
||||
this.$isStaging.set(this.manager.stateApi.runSelector(selectIsStaging));
|
||||
};
|
||||
|
||||
render = async () => {
|
||||
|
||||
@@ -235,6 +235,10 @@ export class CanvasStateApiModule extends CanvasModuleBase {
|
||||
}): Promise<ImageDTO> => {
|
||||
const { graph, outputNodeId, destination, prepend, timeout, signal } = arg;
|
||||
|
||||
if (!graph.hasNode(outputNodeId)) {
|
||||
throw new Error(`Graph does not contain node with id: ${outputNodeId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* We will use the origin to handle events from the graph. Ideally we'd just use the queue item's id, but there's a
|
||||
* race condition:
|
||||
@@ -281,6 +285,7 @@ export class CanvasStateApiModule extends CanvasModuleBase {
|
||||
if (event.origin !== origin) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore events that are not from the output node
|
||||
if (event.invocation_source_id !== outputNodeId) {
|
||||
return;
|
||||
@@ -321,14 +326,28 @@ export class CanvasStateApiModule extends CanvasModuleBase {
|
||||
return;
|
||||
}
|
||||
|
||||
// event.status is 'failed', 'canceled' or 'completed' - something has gone awry
|
||||
if (event.status === 'completed') {
|
||||
/**
|
||||
* The invocation_complete event should have been received before the queue item completed event, and the
|
||||
* event listeners are cleared in the invocation_complete handler. If we get here, it means we never got
|
||||
* the completion event for the output node! This should is a fail case.
|
||||
*
|
||||
* TODO(psyche): In the unexpected case where events are received out of order, this logic doesn't do what
|
||||
* we expect. If we got a queue item completed event before the output node completion event, we'd erroneously
|
||||
* triggers this error.
|
||||
*
|
||||
* For now, we'll just log a warning instead of rejecting the promise. This should be super rare anyways.
|
||||
*/
|
||||
// reject(new Error('Queue item completed without output node completion event'));
|
||||
this.log.warn('Queue item completed without output node completion event');
|
||||
return;
|
||||
}
|
||||
|
||||
// event.status is 'failed', 'canceled' - something has gone awry
|
||||
_clearTimeout();
|
||||
clearListeners();
|
||||
|
||||
if (event.status === 'completed') {
|
||||
// If we get a queue item completed event, that means we never got a completion event for the output node!
|
||||
reject(new Error('Queue item completed without output node completion event'));
|
||||
} else if (event.status === 'failed') {
|
||||
if (event.status === 'failed') {
|
||||
// We expect the event to have error details, but technically it's possible that it doesn't
|
||||
const { error_type, error_message, error_traceback } = event;
|
||||
if (error_type && error_message && error_traceback) {
|
||||
|
||||
@@ -171,6 +171,7 @@ export class CanvasToolModule extends CanvasModuleBase {
|
||||
const cursorPos = this.$cursorPos.get();
|
||||
const tool = this.$tool.get();
|
||||
const isFiltering = this.manager.stateApi.$isFiltering.get();
|
||||
const isStaging = this.manager.stagingArea.$isStaging.get();
|
||||
|
||||
const isDrawable =
|
||||
!!selectedEntity &&
|
||||
@@ -182,7 +183,7 @@ export class CanvasToolModule extends CanvasModuleBase {
|
||||
|
||||
stage.setIsDraggable(tool === 'view');
|
||||
|
||||
if (!cursorPos || renderedEntityCount === 0 || isFiltering) {
|
||||
if (!cursorPos || renderedEntityCount === 0 || isFiltering || isStaging) {
|
||||
// We can bail early if the mouse isn't over the stage or there are no layers
|
||||
this.konva.group.visible(false);
|
||||
} else {
|
||||
|
||||
@@ -86,7 +86,7 @@ const initialState: ParamsState = {
|
||||
img2imgStrength: 0.75,
|
||||
optimizedDenoisingEnabled: true,
|
||||
iterations: 1,
|
||||
scheduler: 'euler',
|
||||
scheduler: 'dpmpp_3m_k',
|
||||
seed: 0,
|
||||
shouldRandomizeSeed: true,
|
||||
steps: 30,
|
||||
|
||||
@@ -151,6 +151,14 @@ export function selectEntity<T extends CanvasEntityIdentifier>(
|
||||
return entity as Extract<CanvasEntityState, T>;
|
||||
}
|
||||
|
||||
export const selectRasterLayerEntities = createSelector(selectCanvasSlice, (canvas) => canvas.rasterLayers.entities);
|
||||
export const selectControlLayerEntities = createSelector(selectCanvasSlice, (canvas) => canvas.controlLayers.entities);
|
||||
export const selectInpaintMaskEntities = createSelector(selectCanvasSlice, (canvas) => canvas.inpaintMasks.entities);
|
||||
export const selectRegionalGuidanceEntities = createSelector(
|
||||
selectCanvasSlice,
|
||||
(canvas) => canvas.regionalGuidance.entities
|
||||
);
|
||||
|
||||
/**
|
||||
* Selected an entity from the canvas slice. If the entity is not found, an error is thrown.
|
||||
* Wrapper around {@link selectEntity}.
|
||||
@@ -338,6 +346,7 @@ export const selectAspectRatioValue = createSelector(selectCanvasSlice, (canvas)
|
||||
export const selectScaledSize = createSelector(selectBbox, (bbox) => bbox.scaledSize);
|
||||
export const selectScaleMethod = createSelector(selectBbox, (bbox) => bbox.scaleMethod);
|
||||
export const selectBboxRect = createSelector(selectBbox, (bbox) => bbox.rect);
|
||||
export const selectBboxModelBase = createSelector(selectBbox, (bbox) => bbox.modelBase);
|
||||
|
||||
export const selectCanvasMetadata = createSelector(
|
||||
selectCanvasSlice,
|
||||
|
||||
@@ -169,7 +169,7 @@ const GalleryBoard = ({ board, isSelected }: GalleryBoardProps) => {
|
||||
{board.archived && !editingDisclosure.isOpen && <Icon as={PiArchiveBold} fill="base.300" />}
|
||||
{!editingDisclosure.isOpen && <Text variant="subtext">{board.image_count}</Text>}
|
||||
|
||||
<IAIDroppable data={droppableData} dropLabel={t('unifiedCanvas.move')} />
|
||||
<IAIDroppable data={droppableData} dropLabel={t('gallery.move')} />
|
||||
</Flex>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
@@ -92,7 +92,7 @@ const NoBoardBoard = memo(({ isSelected }: Props) => {
|
||||
</Text>
|
||||
{autoAddBoardId === 'none' && <AutoAddBadge />}
|
||||
<Text variant="subtext">{imagesTotal}</Text>
|
||||
<IAIDroppable data={droppableData} dropLabel={t('unifiedCanvas.move')} />
|
||||
<IAIDroppable data={droppableData} dropLabel={t('gallery.move')} />
|
||||
</Flex>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Box, Button, Collapse, Divider, Flex, IconButton, useDisclosure } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { useScopeOnFocus } from 'common/hooks/interactionScopes';
|
||||
import { useFocusRegion } from 'common/hooks/focus';
|
||||
import { GalleryHeader } from 'features/gallery/components/GalleryHeader';
|
||||
import { selectBoardSearchText } from 'features/gallery/store/gallerySelectors';
|
||||
import { boardSearchTextChanged } from 'features/gallery/store/gallerySlice';
|
||||
@@ -25,17 +25,16 @@ const GalleryPanelContent = () => {
|
||||
const boardSearchText = useAppSelector(selectBoardSearchText);
|
||||
const dispatch = useAppDispatch();
|
||||
const boardSearchDisclosure = useDisclosure({ defaultIsOpen: !!boardSearchText.length });
|
||||
const panelGroupRef = useRef<ImperativePanelGroupHandle>(null);
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
useScopeOnFocus('gallery', ref);
|
||||
const imperativePanelGroupRef = useRef<ImperativePanelGroupHandle>(null);
|
||||
const galleryPanelFocusRef = useRef<HTMLDivElement>(null);
|
||||
useFocusRegion('gallery', galleryPanelFocusRef);
|
||||
|
||||
const boardsListPanelOptions = useMemo<UsePanelOptions>(
|
||||
() => ({
|
||||
id: 'boards-list-panel',
|
||||
unit: 'pixels',
|
||||
minSize: 128,
|
||||
defaultSize: 20,
|
||||
panelGroupRef,
|
||||
minSizePx: 128,
|
||||
defaultSizePx: 256,
|
||||
imperativePanelGroupRef,
|
||||
panelGroupDirection: 'vertical',
|
||||
}),
|
||||
[]
|
||||
@@ -51,7 +50,7 @@ const GalleryPanelContent = () => {
|
||||
}, [boardSearchText.length, boardSearchDisclosure, boardsListPanel, dispatch]);
|
||||
|
||||
return (
|
||||
<Flex ref={ref} position="relative" flexDirection="column" h="full" w="full" tabIndex={-1}>
|
||||
<Flex ref={galleryPanelFocusRef} position="relative" flexDirection="column" h="full" w="full" tabIndex={-1}>
|
||||
<Flex alignItems="center" w="full">
|
||||
<Flex w="25%">
|
||||
<Button
|
||||
@@ -81,7 +80,7 @@ const GalleryPanelContent = () => {
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
<PanelGroup ref={panelGroupRef} direction="vertical" autoSaveId="boards-list-panel">
|
||||
<PanelGroup ref={imperativePanelGroupRef} direction="vertical" autoSaveId="boards-list-panel">
|
||||
<Panel collapsible {...boardsListPanel.panelProps}>
|
||||
<Flex flexDir="column" w="full" h="full">
|
||||
<Collapse in={boardSearchDisclosure.isOpen} style={COLLAPSE_STYLES}>
|
||||
@@ -93,7 +92,7 @@ const GalleryPanelContent = () => {
|
||||
<BoardsListWrapper />
|
||||
</Flex>
|
||||
</Panel>
|
||||
<ResizeHandle id="gallery-panel-handle" orientation="horizontal" {...boardsListPanel.resizeHandleProps} />
|
||||
<ResizeHandle id="gallery-panel-handle" {...boardsListPanel.resizeHandleProps} />
|
||||
<Panel id="gallery-wrapper-panel" minSize={20}>
|
||||
<Gallery />
|
||||
</Panel>
|
||||
|
||||
@@ -11,7 +11,7 @@ import { PiFlowArrowBold } from 'react-icons/pi';
|
||||
export const ImageMenuItemLoadWorkflow = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const imageDTO = useImageDTOContext();
|
||||
const { getAndLoadEmbeddedWorkflow, getAndLoadEmbeddedWorkflowResult } = useGetAndLoadEmbeddedWorkflow({});
|
||||
const [getAndLoadEmbeddedWorkflow, { isLoading }] = useGetAndLoadEmbeddedWorkflow();
|
||||
const hasTemplates = useStore($hasTemplates);
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
@@ -20,7 +20,7 @@ export const ImageMenuItemLoadWorkflow = memo(() => {
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
icon={getAndLoadEmbeddedWorkflowResult.isLoading ? <SpinnerIcon /> : <PiFlowArrowBold />}
|
||||
icon={isLoading ? <SpinnerIcon /> : <PiFlowArrowBold />}
|
||||
onClickCapture={onClick}
|
||||
isDisabled={!imageDTO.has_workflow || !hasTemplates}
|
||||
>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { MenuItem } from '@invoke-ai/ui-library';
|
||||
import { SpinnerIcon } from 'features/gallery/components/ImageContextMenu/SpinnerIcon';
|
||||
import { useImageDTOContext } from 'features/gallery/contexts/ImageDTOContext';
|
||||
import { useImageActions } from 'features/gallery/hooks/useImageActions';
|
||||
import { memo } from 'react';
|
||||
@@ -16,53 +15,24 @@ export const ImageMenuItemMetadataRecallActions = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const imageDTO = useImageDTOContext();
|
||||
|
||||
const {
|
||||
recallAll,
|
||||
remix,
|
||||
recallSeed,
|
||||
recallPrompts,
|
||||
hasMetadata,
|
||||
hasSeed,
|
||||
hasPrompts,
|
||||
isLoadingMetadata,
|
||||
createAsPreset,
|
||||
} = useImageActions(imageDTO?.image_name);
|
||||
const { recallAll, remix, recallSeed, recallPrompts, hasMetadata, hasSeed, hasPrompts, createAsPreset } =
|
||||
useImageActions(imageDTO);
|
||||
|
||||
return (
|
||||
<>
|
||||
<MenuItem
|
||||
icon={isLoadingMetadata ? <SpinnerIcon /> : <PiArrowsCounterClockwiseBold />}
|
||||
onClickCapture={remix}
|
||||
isDisabled={isLoadingMetadata || !hasMetadata}
|
||||
>
|
||||
<MenuItem icon={<PiArrowsCounterClockwiseBold />} onClickCapture={remix} isDisabled={!hasMetadata}>
|
||||
{t('parameters.remixImage')}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon={isLoadingMetadata ? <SpinnerIcon /> : <PiQuotesBold />}
|
||||
onClickCapture={recallPrompts}
|
||||
isDisabled={isLoadingMetadata || !hasPrompts}
|
||||
>
|
||||
<MenuItem icon={<PiQuotesBold />} onClickCapture={recallPrompts} isDisabled={!hasPrompts}>
|
||||
{t('parameters.usePrompt')}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon={isLoadingMetadata ? <SpinnerIcon /> : <PiPlantBold />}
|
||||
onClickCapture={recallSeed}
|
||||
isDisabled={isLoadingMetadata || !hasSeed}
|
||||
>
|
||||
<MenuItem icon={<PiPlantBold />} onClickCapture={recallSeed} isDisabled={!hasSeed}>
|
||||
{t('parameters.useSeed')}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon={isLoadingMetadata ? <SpinnerIcon /> : <PiAsteriskBold />}
|
||||
onClickCapture={recallAll}
|
||||
isDisabled={isLoadingMetadata || !hasMetadata}
|
||||
>
|
||||
<MenuItem icon={<PiAsteriskBold />} onClickCapture={recallAll} isDisabled={!hasMetadata}>
|
||||
{t('parameters.useAll')}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon={isLoadingMetadata ? <SpinnerIcon /> : <PiPaintBrushBold />}
|
||||
onClickCapture={createAsPreset}
|
||||
isDisabled={isLoadingMetadata || !hasPrompts}
|
||||
>
|
||||
<MenuItem icon={<PiPaintBrushBold />} onClickCapture={createAsPreset} isDisabled={!hasPrompts}>
|
||||
{t('stylePresets.useForTemplate')}
|
||||
</MenuItem>
|
||||
</>
|
||||
|
||||
@@ -1,32 +1,18 @@
|
||||
import { Tag, TagCloseButton, TagLabel } from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { $activeScopes } from 'common/hooks/interactionScopes';
|
||||
import { useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { useGalleryImages } from 'features/gallery/hooks/useGalleryImages';
|
||||
import { selectionChanged } from 'features/gallery/store/gallerySlice';
|
||||
import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData';
|
||||
import { $isRightPanelOpen } from 'features/ui/store/uiSlice';
|
||||
import { computed } from 'nanostores';
|
||||
import { useCallback } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
const $isSelectAllEnabled = computed([$activeScopes, $isRightPanelOpen], (activeScopes, isGalleryPanelOpen) => {
|
||||
return activeScopes.has('gallery') && !activeScopes.has('workflows') && isGalleryPanelOpen;
|
||||
});
|
||||
|
||||
export const GallerySelectionCountTag = () => {
|
||||
export const GallerySelectionCountTag = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { selection } = useAppSelector((s) => s.gallery);
|
||||
const { t } = useTranslation();
|
||||
const { imageDTOs } = useGalleryImages();
|
||||
const isSelectAllEnabled = useStore($isSelectAllEnabled);
|
||||
|
||||
const onClearSelection = useCallback(() => {
|
||||
const firstImage = selection[0];
|
||||
if (firstImage) {
|
||||
dispatch(selectionChanged([firstImage]));
|
||||
}
|
||||
}, [dispatch, selection]);
|
||||
const isGalleryFocused = useIsRegionFocused('gallery');
|
||||
|
||||
const onSelectPage = useCallback(() => {
|
||||
dispatch(selectionChanged([...selection, ...imageDTOs]));
|
||||
@@ -36,22 +22,40 @@ export const GallerySelectionCountTag = () => {
|
||||
id: 'selectAllOnPage',
|
||||
category: 'gallery',
|
||||
callback: onSelectPage,
|
||||
options: { preventDefault: true, enabled: isSelectAllEnabled },
|
||||
dependencies: [onSelectPage, isSelectAllEnabled],
|
||||
});
|
||||
|
||||
useRegisteredHotkeys({
|
||||
id: 'clearSelection',
|
||||
category: 'gallery',
|
||||
callback: onClearSelection,
|
||||
options: { enabled: selection.length > 0 && isSelectAllEnabled },
|
||||
dependencies: [onClearSelection, selection, isSelectAllEnabled],
|
||||
options: { preventDefault: true, enabled: isGalleryFocused },
|
||||
dependencies: [onSelectPage, isGalleryFocused],
|
||||
});
|
||||
|
||||
if (selection.length <= 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <GallerySelectionCountTagContent selection={selection} />;
|
||||
});
|
||||
|
||||
GallerySelectionCountTag.displayName = 'GallerySelectionCountTag';
|
||||
|
||||
const GallerySelectionCountTagContent = memo(({ selection }: { selection: ImageDTO[] }) => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const isGalleryFocused = useIsRegionFocused('gallery');
|
||||
|
||||
const onClearSelection = useCallback(() => {
|
||||
const firstImage = selection[0];
|
||||
if (firstImage) {
|
||||
dispatch(selectionChanged([firstImage]));
|
||||
}
|
||||
}, [dispatch, selection]);
|
||||
|
||||
useRegisteredHotkeys({
|
||||
id: 'clearSelection',
|
||||
category: 'gallery',
|
||||
callback: onClearSelection,
|
||||
options: { enabled: selection.length > 0 && isGalleryFocused },
|
||||
dependencies: [onClearSelection, selection, isGalleryFocused],
|
||||
});
|
||||
|
||||
return (
|
||||
<Tag
|
||||
position="absolute"
|
||||
@@ -72,4 +76,6 @@ export const GallerySelectionCountTag = () => {
|
||||
<TagCloseButton onClick={onClearSelection} />
|
||||
</Tag>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
GallerySelectionCountTagContent.displayName = 'GallerySelectionCountTagContent';
|
||||
|
||||
@@ -1,24 +1,16 @@
|
||||
import { ButtonGroup, IconButton, Menu, MenuButton, MenuList } from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { skipToken } from '@reduxjs/toolkit/query';
|
||||
import { adHocPostProcessingRequested } from 'app/store/middleware/listenerMiddleware/listeners/addAdHocPostProcessingRequestedListener';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { INTERACTION_SCOPES } from 'common/hooks/interactionScopes';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { selectIsStaging } from 'features/controlLayers/store/canvasStagingAreaSlice';
|
||||
import { DeleteImageButton } from 'features/deleteImageModal/components/DeleteImageButton';
|
||||
import { imagesToDeleteSelected } from 'features/deleteImageModal/store/slice';
|
||||
import SingleSelectionMenuItems from 'features/gallery/components/ImageContextMenu/SingleSelectionMenuItems';
|
||||
import { useImageActions } from 'features/gallery/hooks/useImageActions';
|
||||
import { selectLastSelectedImage } from 'features/gallery/store/gallerySelectors';
|
||||
import { parseAndRecallImageDimensions } from 'features/metadata/util/handlers';
|
||||
import { $templates } from 'features/nodes/store/nodesSlice';
|
||||
import { $hasTemplates } from 'features/nodes/store/nodesSlice';
|
||||
import { PostProcessingPopover } from 'features/parameters/components/PostProcessing/PostProcessingPopover';
|
||||
import { useIsQueueMutationInProgress } from 'features/queue/hooks/useIsQueueMutationInProgress';
|
||||
import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData';
|
||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||
import { useGetAndLoadEmbeddedWorkflow } from 'features/workflowLibrary/hooks/useGetAndLoadEmbeddedWorkflow';
|
||||
import { size } from 'lodash-es';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
PiArrowsCounterClockwiseBold,
|
||||
@@ -30,109 +22,31 @@ import {
|
||||
PiRulerBold,
|
||||
} from 'react-icons/pi';
|
||||
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
|
||||
import { $isConnected, $progressImage } from 'services/events/stores';
|
||||
import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
const CurrentImageButtons = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const isConnected = useStore($isConnected);
|
||||
const isStaging = useAppSelector(selectIsStaging);
|
||||
const lastSelectedImage = useAppSelector(selectLastSelectedImage);
|
||||
const progressImage = useStore($progressImage);
|
||||
const shouldDisableToolbarButtons = useMemo(() => {
|
||||
return Boolean(progressImage) || !lastSelectedImage;
|
||||
}, [lastSelectedImage, progressImage]);
|
||||
const templates = useStore($templates);
|
||||
const isUpscalingEnabled = useFeatureStatus('upscaling');
|
||||
const isQueueMutationInProgress = useIsQueueMutationInProgress();
|
||||
const { t } = useTranslation();
|
||||
const isImageViewerActive = useStore(INTERACTION_SCOPES.imageViewer.$isActive);
|
||||
const { currentData: imageDTO } = useGetImageDTOQuery(lastSelectedImage?.image_name ?? skipToken);
|
||||
|
||||
const { recallAll, remix, recallSeed, recallPrompts, hasMetadata, hasSeed, hasPrompts, isLoadingMetadata } =
|
||||
useImageActions(lastSelectedImage?.image_name);
|
||||
if (!imageDTO) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { getAndLoadEmbeddedWorkflow, getAndLoadEmbeddedWorkflowResult } = useGetAndLoadEmbeddedWorkflow({});
|
||||
return <CurrentImageButtonsContent imageDTO={imageDTO} />;
|
||||
};
|
||||
|
||||
const handleLoadWorkflow = useCallback(() => {
|
||||
if (!lastSelectedImage || !lastSelectedImage.has_workflow) {
|
||||
return;
|
||||
}
|
||||
getAndLoadEmbeddedWorkflow(lastSelectedImage.image_name);
|
||||
}, [getAndLoadEmbeddedWorkflow, lastSelectedImage]);
|
||||
export default memo(CurrentImageButtons);
|
||||
|
||||
const handleUseSize = useCallback(() => {
|
||||
if (isStaging) {
|
||||
return;
|
||||
}
|
||||
parseAndRecallImageDimensions(lastSelectedImage);
|
||||
}, [isStaging, lastSelectedImage]);
|
||||
const handleClickUpscale = useCallback(() => {
|
||||
if (!imageDTO) {
|
||||
return;
|
||||
}
|
||||
dispatch(adHocPostProcessingRequested({ imageDTO }));
|
||||
}, [dispatch, imageDTO]);
|
||||
|
||||
const handleDelete = useCallback(() => {
|
||||
if (!imageDTO) {
|
||||
return;
|
||||
}
|
||||
dispatch(imagesToDeleteSelected([imageDTO]));
|
||||
}, [dispatch, imageDTO]);
|
||||
|
||||
useRegisteredHotkeys({
|
||||
id: 'loadWorkflow',
|
||||
category: 'viewer',
|
||||
callback: handleLoadWorkflow,
|
||||
options: { enabled: isImageViewerActive },
|
||||
dependencies: [handleLoadWorkflow, isImageViewerActive],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'recallAll',
|
||||
category: 'viewer',
|
||||
callback: recallAll,
|
||||
options: { enabled: isImageViewerActive },
|
||||
dependencies: [recallAll, isImageViewerActive],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'recallSeed',
|
||||
category: 'viewer',
|
||||
callback: recallSeed,
|
||||
options: { enabled: isImageViewerActive },
|
||||
dependencies: [recallSeed, isImageViewerActive],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'recallPrompts',
|
||||
category: 'viewer',
|
||||
callback: recallPrompts,
|
||||
options: { enabled: isImageViewerActive },
|
||||
dependencies: [recallPrompts, isImageViewerActive],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'remix',
|
||||
category: 'viewer',
|
||||
callback: remix,
|
||||
options: { enabled: isImageViewerActive },
|
||||
dependencies: [remix, isImageViewerActive],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'useSize',
|
||||
category: 'viewer',
|
||||
callback: handleUseSize,
|
||||
options: { enabled: isImageViewerActive },
|
||||
dependencies: [handleUseSize, isImageViewerActive],
|
||||
});
|
||||
useRegisteredHotkeys({
|
||||
id: 'runPostprocessing',
|
||||
category: 'viewer',
|
||||
callback: handleClickUpscale,
|
||||
options: { enabled: Boolean(isUpscalingEnabled && isImageViewerActive && isConnected) },
|
||||
dependencies: [isUpscalingEnabled, imageDTO, shouldDisableToolbarButtons, isConnected, isImageViewerActive],
|
||||
});
|
||||
const CurrentImageButtonsContent = memo(({ imageDTO }: { imageDTO: ImageDTO }) => {
|
||||
const { t } = useTranslation();
|
||||
const hasTemplates = useStore($hasTemplates);
|
||||
const imageActions = useImageActions(imageDTO);
|
||||
const isStaging = useAppSelector(selectIsStaging);
|
||||
const isUpscalingEnabled = useFeatureStatus('upscaling');
|
||||
|
||||
return (
|
||||
<>
|
||||
<ButtonGroup isDisabled={shouldDisableToolbarButtons}>
|
||||
<ButtonGroup>
|
||||
<Menu isLazy>
|
||||
<MenuButton
|
||||
as={IconButton}
|
||||
@@ -145,68 +59,62 @@ const CurrentImageButtons = () => {
|
||||
</Menu>
|
||||
</ButtonGroup>
|
||||
|
||||
<ButtonGroup isDisabled={shouldDisableToolbarButtons}>
|
||||
<ButtonGroup>
|
||||
<IconButton
|
||||
icon={<PiFlowArrowBold />}
|
||||
tooltip={`${t('nodes.loadWorkflow')} (W)`}
|
||||
aria-label={`${t('nodes.loadWorkflow')} (W)`}
|
||||
isDisabled={!imageDTO?.has_workflow || !size(templates)}
|
||||
onClick={handleLoadWorkflow}
|
||||
isLoading={getAndLoadEmbeddedWorkflowResult.isLoading}
|
||||
isDisabled={!imageActions.hasWorkflow || !hasTemplates}
|
||||
onClick={imageActions.loadWorkflow}
|
||||
/>
|
||||
<IconButton
|
||||
isLoading={isLoadingMetadata}
|
||||
icon={<PiArrowsCounterClockwiseBold />}
|
||||
tooltip={`${t('parameters.remixImage')} (R)`}
|
||||
aria-label={`${t('parameters.remixImage')} (R)`}
|
||||
isDisabled={!hasMetadata}
|
||||
onClick={remix}
|
||||
isDisabled={!imageActions.hasMetadata}
|
||||
onClick={imageActions.remix}
|
||||
/>
|
||||
<IconButton
|
||||
isLoading={isLoadingMetadata}
|
||||
icon={<PiQuotesBold />}
|
||||
tooltip={`${t('parameters.usePrompt')} (P)`}
|
||||
aria-label={`${t('parameters.usePrompt')} (P)`}
|
||||
isDisabled={!hasPrompts}
|
||||
onClick={recallPrompts}
|
||||
isDisabled={!imageActions.hasPrompts}
|
||||
onClick={imageActions.recallPrompts}
|
||||
/>
|
||||
<IconButton
|
||||
isLoading={isLoadingMetadata}
|
||||
icon={<PiPlantBold />}
|
||||
tooltip={`${t('parameters.useSeed')} (S)`}
|
||||
aria-label={`${t('parameters.useSeed')} (S)`}
|
||||
isDisabled={!hasSeed}
|
||||
onClick={recallSeed}
|
||||
isDisabled={!imageActions.hasSeed}
|
||||
onClick={imageActions.recallSeed}
|
||||
/>
|
||||
<IconButton
|
||||
isLoading={isLoadingMetadata}
|
||||
icon={<PiRulerBold />}
|
||||
tooltip={`${t('parameters.useSize')} (D)`}
|
||||
aria-label={`${t('parameters.useSize')} (D)`}
|
||||
onClick={handleUseSize}
|
||||
onClick={imageActions.recallSize}
|
||||
isDisabled={isStaging}
|
||||
/>
|
||||
<IconButton
|
||||
isLoading={isLoadingMetadata}
|
||||
icon={<PiAsteriskBold />}
|
||||
tooltip={`${t('parameters.useAll')} (A)`}
|
||||
aria-label={`${t('parameters.useAll')} (A)`}
|
||||
isDisabled={!hasMetadata}
|
||||
onClick={recallAll}
|
||||
isDisabled={!imageActions.hasMetadata}
|
||||
onClick={imageActions.recallAll}
|
||||
/>
|
||||
</ButtonGroup>
|
||||
|
||||
{isUpscalingEnabled && (
|
||||
<ButtonGroup isDisabled={isQueueMutationInProgress}>
|
||||
{isUpscalingEnabled && <PostProcessingPopover imageDTO={imageDTO} />}
|
||||
<ButtonGroup>
|
||||
<PostProcessingPopover imageDTO={imageDTO} />
|
||||
</ButtonGroup>
|
||||
)}
|
||||
|
||||
<ButtonGroup>
|
||||
<DeleteImageButton onClick={handleDelete} />
|
||||
<DeleteImageButton onClick={imageActions.delete} />
|
||||
</ButtonGroup>
|
||||
</>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default memo(CurrentImageButtons);
|
||||
CurrentImageButtonsContent.displayName = 'CurrentImageButtonsContent';
|
||||
|
||||
@@ -12,7 +12,7 @@ import type { AnimationProps } from 'framer-motion';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { memo, useCallback, useMemo, useRef, useState } from 'react';
|
||||
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
|
||||
import { $hasProgress, $isProgressFromCanvas } from 'services/events/stores';
|
||||
import { $hasProgressImage, $isProgressFromCanvas } from 'services/events/stores';
|
||||
|
||||
import { NoContentForViewer } from './NoContentForViewer';
|
||||
import ProgressImage from './ProgressImage';
|
||||
@@ -20,7 +20,7 @@ import ProgressImage from './ProgressImage';
|
||||
const CurrentImagePreview = () => {
|
||||
const shouldShowImageDetails = useAppSelector(selectShouldShowImageDetails);
|
||||
const imageName = useAppSelector(selectLastSelectedImageName);
|
||||
const hasDenoiseProgress = useStore($hasProgress);
|
||||
const hasProgressImage = useStore($hasProgressImage);
|
||||
const isProgressFromCanvas = useStore($isProgressFromCanvas);
|
||||
const shouldShowProgressInViewer = useAppSelector(selectShouldShowProgressInViewer);
|
||||
|
||||
@@ -59,7 +59,7 @@ const CurrentImagePreview = () => {
|
||||
justifyContent="center"
|
||||
position="relative"
|
||||
>
|
||||
{hasDenoiseProgress && !isProgressFromCanvas && shouldShowProgressInViewer ? (
|
||||
{hasProgressImage && !isProgressFromCanvas && shouldShowProgressInViewer ? (
|
||||
<ProgressImage />
|
||||
) : (
|
||||
<IAIDndImage
|
||||
|
||||
@@ -42,11 +42,7 @@ export const ImageComparisonSideBySide = memo(({ firstImage, secondImage }: Comp
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Panel>
|
||||
<ResizeHandle
|
||||
id="image-comparison-side-by-side-handle"
|
||||
onDoubleClick={onDoubleClickHandle}
|
||||
orientation="vertical"
|
||||
/>
|
||||
<ResizeHandle id="image-comparison-side-by-side-handle" onDoubleClick={onDoubleClickHandle} />
|
||||
|
||||
<Panel minSize={20}>
|
||||
<Flex position="relative" w="full" h="full" alignItems="center" justifyContent="center">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Box, Flex, IconButton } from '@invoke-ai/ui-library';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useScopeOnFocus, useScopeOnMount } from 'common/hooks/interactionScopes';
|
||||
import { useFocusRegion } from 'common/hooks/focus';
|
||||
import { useAssertSingleton } from 'common/hooks/useAssertSingleton';
|
||||
import { CanvasAlertsSendingToCanvas } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsSendingTo';
|
||||
import { CompareToolbar } from 'features/gallery/components/ImageViewer/CompareToolbar';
|
||||
@@ -10,7 +10,7 @@ import { ImageComparisonDroppable } from 'features/gallery/components/ImageViewe
|
||||
import { ViewerToolbar } from 'features/gallery/components/ImageViewer/ViewerToolbar';
|
||||
import { selectHasImageToCompare } from 'features/gallery/store/gallerySelectors';
|
||||
import type { ReactNode } from 'react';
|
||||
import { memo, useEffect, useRef } from 'react';
|
||||
import { memo, useRef } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiXBold } from 'react-icons/pi';
|
||||
@@ -22,17 +22,16 @@ type Props = {
|
||||
closeButton?: ReactNode;
|
||||
};
|
||||
|
||||
const useFocusRegionOptions = {
|
||||
focusOnMount: true,
|
||||
};
|
||||
|
||||
export const ImageViewer = memo(({ closeButton }: Props) => {
|
||||
useAssertSingleton('ImageViewer');
|
||||
const hasImageToCompare = useAppSelector(selectHasImageToCompare);
|
||||
const [containerRef, containerDims] = useMeasure<HTMLDivElement>();
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
useScopeOnFocus('imageViewer', ref);
|
||||
useScopeOnMount('imageViewer');
|
||||
|
||||
useEffect(() => {
|
||||
ref?.current?.focus();
|
||||
}, []);
|
||||
useFocusRegion('viewer', ref, useFocusRegionOptions);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
|
||||
@@ -27,7 +27,9 @@ import type { ImageDTO } from 'services/api/types';
|
||||
* TODO(psyche): Figure out a better way to do handle this...
|
||||
*/
|
||||
let didCloseImageViewer = false;
|
||||
const [useImageViewerState, $imageViewerState] = buildUseBoolean(true);
|
||||
const api = buildUseBoolean(true);
|
||||
const useImageViewerState = api[0];
|
||||
export const $imageViewer = api[1];
|
||||
|
||||
export const useImageViewer = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
@@ -54,7 +56,7 @@ export const useImageViewer = () => {
|
||||
open: imageViewerState.setTrue,
|
||||
close,
|
||||
toggle: imageViewerState.toggle,
|
||||
$state: $imageViewerState,
|
||||
$state: $imageViewer,
|
||||
openImageInViewer,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { $activeScopes, INTERACTION_SCOPES } from 'common/hooks/interactionScopes';
|
||||
import { useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { useAssertSingleton } from 'common/hooks/useAssertSingleton';
|
||||
import { $canvasRightPanelTab } from 'features/controlLayers/store/ephemeral';
|
||||
import { imagesToDeleteSelected } from 'features/deleteImageModal/store/slice';
|
||||
@@ -9,21 +9,9 @@ import { useGalleryPagination } from 'features/gallery/hooks/useGalleryPaginatio
|
||||
import { selectListImagesQueryArgs } from 'features/gallery/store/gallerySelectors';
|
||||
import { useRegisteredHotkeys } from 'features/system/components/HotkeysModal/useHotkeyData';
|
||||
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||
import { $isRightPanelOpen } from 'features/ui/store/uiSlice';
|
||||
import { computed } from 'nanostores';
|
||||
import { useMemo } from 'react';
|
||||
import { useListImagesQuery } from 'services/api/endpoints/images';
|
||||
|
||||
const $leftRightHotkeysEnabled = computed($activeScopes, (activeScopes) => {
|
||||
// The left and right hotkeys can be used when the gallery is focused and the canvas is not focused, OR when the image viewer is focused.
|
||||
return !activeScopes.has('canvas') || activeScopes.has('imageViewer');
|
||||
});
|
||||
|
||||
const $upDownHotkeysEnabled = computed([$activeScopes, $isRightPanelOpen], (activeScopes, isGalleryPanelOpen) => {
|
||||
// The up and down hotkeys can be used when the gallery is focused and the canvas is not focused, and the gallery panel is open.
|
||||
return !activeScopes.has('canvas') && isGalleryPanelOpen;
|
||||
});
|
||||
|
||||
/**
|
||||
* Registers gallery hotkeys. This hook is a singleton.
|
||||
*/
|
||||
@@ -34,11 +22,11 @@ export const useGalleryHotkeys = () => {
|
||||
const selection = useAppSelector((s) => s.gallery.selection);
|
||||
const queryArgs = useAppSelector(selectListImagesQueryArgs);
|
||||
const queryResult = useListImagesQuery(queryArgs);
|
||||
const leftRightHotkeysEnabled = useStore($leftRightHotkeysEnabled);
|
||||
const upDownHotkeysEnabled = useStore($upDownHotkeysEnabled);
|
||||
const canvasRightPanelTab = useStore($canvasRightPanelTab);
|
||||
const appTab = useAppSelector(selectActiveTab);
|
||||
const isWorkflowsScopeActive = useStore(INTERACTION_SCOPES.workflows.$isActive);
|
||||
const isWorkflowsFocused = useIsRegionFocused('workflows');
|
||||
const isGalleryFocused = useIsRegionFocused('gallery');
|
||||
const isImageViewerFocused = useIsRegionFocused('viewer');
|
||||
|
||||
// When we are on the canvas tab, we need to disable the delete hotkey when the user is focused on the layers tab in
|
||||
// the right hand panel, because the same hotkey is used to delete layers.
|
||||
@@ -70,14 +58,15 @@ export const useGalleryHotkeys = () => {
|
||||
}
|
||||
handleLeftImage(false);
|
||||
},
|
||||
options: { preventDefault: true, enabled: leftRightHotkeysEnabled },
|
||||
options: { preventDefault: true, enabled: isGalleryFocused || isImageViewerFocused },
|
||||
dependencies: [
|
||||
handleLeftImage,
|
||||
isOnFirstImageOfView,
|
||||
goPrev,
|
||||
isPrevEnabled,
|
||||
queryResult.isFetching,
|
||||
leftRightHotkeysEnabled,
|
||||
isGalleryFocused,
|
||||
isImageViewerFocused,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -93,14 +82,15 @@ export const useGalleryHotkeys = () => {
|
||||
handleRightImage(false);
|
||||
}
|
||||
},
|
||||
options: { preventDefault: true, enabled: leftRightHotkeysEnabled },
|
||||
options: { preventDefault: true, enabled: isGalleryFocused || isImageViewerFocused },
|
||||
dependencies: [
|
||||
isOnLastImageOfView,
|
||||
goNext,
|
||||
isNextEnabled,
|
||||
queryResult.isFetching,
|
||||
handleRightImage,
|
||||
leftRightHotkeysEnabled,
|
||||
isGalleryFocused,
|
||||
isImageViewerFocused,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -114,8 +104,8 @@ export const useGalleryHotkeys = () => {
|
||||
}
|
||||
handleUpImage(false);
|
||||
},
|
||||
options: { preventDefault: true, enabled: upDownHotkeysEnabled },
|
||||
dependencies: [handleUpImage, isOnFirstRow, goPrev, isPrevEnabled, queryResult.isFetching, upDownHotkeysEnabled],
|
||||
options: { preventDefault: true, enabled: isGalleryFocused },
|
||||
dependencies: [handleUpImage, isOnFirstRow, goPrev, isPrevEnabled, queryResult.isFetching, isGalleryFocused],
|
||||
});
|
||||
|
||||
useRegisteredHotkeys({
|
||||
@@ -128,8 +118,8 @@ export const useGalleryHotkeys = () => {
|
||||
}
|
||||
handleDownImage(false);
|
||||
},
|
||||
options: { preventDefault: true, enabled: upDownHotkeysEnabled },
|
||||
dependencies: [isOnLastRow, goNext, isNextEnabled, queryResult.isFetching, handleDownImage, upDownHotkeysEnabled],
|
||||
options: { preventDefault: true, enabled: isGalleryFocused },
|
||||
dependencies: [isOnLastRow, goNext, isNextEnabled, queryResult.isFetching, handleDownImage, isGalleryFocused],
|
||||
});
|
||||
|
||||
useRegisteredHotkeys({
|
||||
@@ -142,14 +132,15 @@ export const useGalleryHotkeys = () => {
|
||||
}
|
||||
handleLeftImage(true);
|
||||
},
|
||||
options: { preventDefault: true, enabled: leftRightHotkeysEnabled },
|
||||
options: { preventDefault: true, enabled: isGalleryFocused || isImageViewerFocused },
|
||||
dependencies: [
|
||||
handleLeftImage,
|
||||
isOnFirstImageOfView,
|
||||
goPrev,
|
||||
isPrevEnabled,
|
||||
queryResult.isFetching,
|
||||
leftRightHotkeysEnabled,
|
||||
isGalleryFocused,
|
||||
isImageViewerFocused,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -165,14 +156,15 @@ export const useGalleryHotkeys = () => {
|
||||
handleRightImage(true);
|
||||
}
|
||||
},
|
||||
options: { preventDefault: true, enabled: leftRightHotkeysEnabled },
|
||||
options: { preventDefault: true, enabled: isGalleryFocused || isImageViewerFocused },
|
||||
dependencies: [
|
||||
isOnLastImageOfView,
|
||||
goNext,
|
||||
isNextEnabled,
|
||||
queryResult.isFetching,
|
||||
handleRightImage,
|
||||
leftRightHotkeysEnabled,
|
||||
isGalleryFocused,
|
||||
isImageViewerFocused,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -186,8 +178,8 @@ export const useGalleryHotkeys = () => {
|
||||
}
|
||||
handleUpImage(true);
|
||||
},
|
||||
options: { preventDefault: true, enabled: upDownHotkeysEnabled },
|
||||
dependencies: [handleUpImage, isOnFirstRow, goPrev, isPrevEnabled, queryResult.isFetching, upDownHotkeysEnabled],
|
||||
options: { preventDefault: true, enabled: isGalleryFocused },
|
||||
dependencies: [handleUpImage, isOnFirstRow, goPrev, isPrevEnabled, queryResult.isFetching, isGalleryFocused],
|
||||
});
|
||||
|
||||
useRegisteredHotkeys({
|
||||
@@ -200,8 +192,8 @@ export const useGalleryHotkeys = () => {
|
||||
}
|
||||
handleDownImage(true);
|
||||
},
|
||||
options: { preventDefault: true, enabled: upDownHotkeysEnabled },
|
||||
dependencies: [isOnLastRow, goNext, isNextEnabled, queryResult.isFetching, handleDownImage, upDownHotkeysEnabled],
|
||||
options: { preventDefault: true, enabled: isGalleryFocused },
|
||||
dependencies: [isOnLastRow, goNext, isNextEnabled, queryResult.isFetching, handleDownImage, isGalleryFocused],
|
||||
});
|
||||
|
||||
useRegisteredHotkeys({
|
||||
@@ -213,7 +205,9 @@ export const useGalleryHotkeys = () => {
|
||||
}
|
||||
dispatch(imagesToDeleteSelected(selection));
|
||||
},
|
||||
options: { enabled: leftRightHotkeysEnabled && isDeleteEnabledByTab && !isWorkflowsScopeActive },
|
||||
dependencies: [leftRightHotkeysEnabled, isDeleteEnabledByTab, selection, isWorkflowsScopeActive],
|
||||
options: {
|
||||
enabled: (isGalleryFocused || isImageViewerFocused) && isDeleteEnabledByTab && !isWorkflowsFocused,
|
||||
},
|
||||
dependencies: [isWorkflowsFocused, isDeleteEnabledByTab, selection, isWorkflowsFocused],
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
import { skipToken } from '@reduxjs/toolkit/query';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { adHocPostProcessingRequested } from 'app/store/middleware/listenerMiddleware/listeners/addAdHocPostProcessingRequestedListener';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { selectIsStaging } from 'features/controlLayers/store/canvasStagingAreaSlice';
|
||||
import { handlers, parseAndRecallAllMetadata, parseAndRecallPrompts } from 'features/metadata/util/handlers';
|
||||
import { imagesToDeleteSelected } from 'features/deleteImageModal/store/slice';
|
||||
import {
|
||||
handlers,
|
||||
parseAndRecallAllMetadata,
|
||||
parseAndRecallImageDimensions,
|
||||
parseAndRecallPrompts,
|
||||
} from 'features/metadata/util/handlers';
|
||||
import { $hasTemplates } from 'features/nodes/store/nodesSlice';
|
||||
import { $stylePresetModalState } from 'features/stylePresets/store/stylePresetModal';
|
||||
import {
|
||||
activeStylePresetIdChanged,
|
||||
@@ -9,22 +17,23 @@ import {
|
||||
} from 'features/stylePresets/store/stylePresetSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||
import { useGetAndLoadEmbeddedWorkflow } from 'features/workflowLibrary/hooks/useGetAndLoadEmbeddedWorkflow';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
|
||||
import { useDebouncedMetadata } from 'services/api/hooks/useDebouncedMetadata';
|
||||
import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
export const useImageActions = (image_name?: string) => {
|
||||
export const useImageActions = (imageDTO: ImageDTO) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
const activeStylePresetId = useAppSelector(selectStylePresetActivePresetId);
|
||||
const isStaging = useAppSelector(selectIsStaging);
|
||||
const activeTabName = useAppSelector(selectActiveTab);
|
||||
const { metadata, isLoading: isLoadingMetadata } = useDebouncedMetadata(image_name);
|
||||
const { metadata } = useDebouncedMetadata(imageDTO.image_name);
|
||||
const [hasMetadata, setHasMetadata] = useState(false);
|
||||
const [hasSeed, setHasSeed] = useState(false);
|
||||
const [hasPrompts, setHasPrompts] = useState(false);
|
||||
const { data: imageDTO } = useGetImageDTOQuery(image_name ?? skipToken);
|
||||
const hasTemplates = useStore($hasTemplates);
|
||||
|
||||
useEffect(() => {
|
||||
const parseMetadata = async () => {
|
||||
@@ -68,66 +77,107 @@ export const useImageActions = (image_name?: string) => {
|
||||
}, [dispatch, activeStylePresetId, t]);
|
||||
|
||||
const recallAll = useCallback(() => {
|
||||
if (!metadata) {
|
||||
return;
|
||||
}
|
||||
parseAndRecallAllMetadata(metadata, activeTabName === 'canvas', isStaging ? ['width', 'height'] : []);
|
||||
clearStylePreset();
|
||||
}, [metadata, activeTabName, isStaging, clearStylePreset]);
|
||||
|
||||
const remix = useCallback(() => {
|
||||
if (!metadata) {
|
||||
return;
|
||||
}
|
||||
// Recalls all metadata parameters except seed
|
||||
parseAndRecallAllMetadata(metadata, activeTabName === 'canvas', ['seed']);
|
||||
clearStylePreset();
|
||||
}, [activeTabName, metadata, clearStylePreset]);
|
||||
|
||||
const recallSeed = useCallback(() => {
|
||||
if (!metadata) {
|
||||
return;
|
||||
}
|
||||
handlers.seed.parse(metadata).then((seed) => {
|
||||
handlers.seed.recall && handlers.seed.recall(seed, true);
|
||||
});
|
||||
}, [metadata]);
|
||||
|
||||
const recallPrompts = useCallback(() => {
|
||||
if (!metadata) {
|
||||
return;
|
||||
}
|
||||
parseAndRecallPrompts(metadata);
|
||||
clearStylePreset();
|
||||
}, [metadata, clearStylePreset]);
|
||||
|
||||
const createAsPreset = useCallback(async () => {
|
||||
if (image_name && metadata && imageDTO) {
|
||||
let positivePrompt;
|
||||
let negativePrompt;
|
||||
|
||||
try {
|
||||
positivePrompt = await handlers.positivePrompt.parse(metadata);
|
||||
} catch (error) {
|
||||
positivePrompt = '';
|
||||
}
|
||||
try {
|
||||
negativePrompt = await handlers.negativePrompt.parse(metadata);
|
||||
} catch (error) {
|
||||
negativePrompt = '';
|
||||
}
|
||||
|
||||
$stylePresetModalState.set({
|
||||
prefilledFormData: {
|
||||
name: '',
|
||||
positivePrompt,
|
||||
negativePrompt,
|
||||
imageUrl: imageDTO.image_url,
|
||||
type: 'user',
|
||||
},
|
||||
updatingStylePresetId: null,
|
||||
isModalOpen: true,
|
||||
});
|
||||
if (!metadata) {
|
||||
return;
|
||||
}
|
||||
}, [image_name, metadata, imageDTO]);
|
||||
let positivePrompt;
|
||||
let negativePrompt;
|
||||
|
||||
try {
|
||||
positivePrompt = await handlers.positivePrompt.parse(metadata);
|
||||
} catch (error) {
|
||||
positivePrompt = '';
|
||||
}
|
||||
try {
|
||||
negativePrompt = await handlers.negativePrompt.parse(metadata);
|
||||
} catch (error) {
|
||||
negativePrompt = '';
|
||||
}
|
||||
|
||||
$stylePresetModalState.set({
|
||||
prefilledFormData: {
|
||||
name: '',
|
||||
positivePrompt,
|
||||
negativePrompt,
|
||||
imageUrl: imageDTO.image_url,
|
||||
type: 'user',
|
||||
},
|
||||
updatingStylePresetId: null,
|
||||
isModalOpen: true,
|
||||
});
|
||||
}, [metadata, imageDTO]);
|
||||
|
||||
const [getAndLoadEmbeddedWorkflow] = useGetAndLoadEmbeddedWorkflow();
|
||||
|
||||
const loadWorkflow = useCallback(() => {
|
||||
if (!imageDTO.has_workflow || !hasTemplates) {
|
||||
return;
|
||||
}
|
||||
getAndLoadEmbeddedWorkflow(imageDTO.image_name);
|
||||
}, [getAndLoadEmbeddedWorkflow, hasTemplates, imageDTO.has_workflow, imageDTO.image_name]);
|
||||
|
||||
const recallSize = useCallback(() => {
|
||||
if (isStaging) {
|
||||
return;
|
||||
}
|
||||
parseAndRecallImageDimensions(imageDTO);
|
||||
}, [imageDTO, isStaging]);
|
||||
|
||||
const upscale = useCallback(() => {
|
||||
dispatch(adHocPostProcessingRequested({ imageDTO }));
|
||||
}, [dispatch, imageDTO]);
|
||||
|
||||
const _delete = useCallback(() => {
|
||||
dispatch(imagesToDeleteSelected([imageDTO]));
|
||||
}, [dispatch, imageDTO]);
|
||||
|
||||
return {
|
||||
hasMetadata,
|
||||
hasSeed,
|
||||
hasPrompts,
|
||||
recallAll,
|
||||
remix,
|
||||
recallSeed,
|
||||
recallPrompts,
|
||||
hasMetadata,
|
||||
hasSeed,
|
||||
hasPrompts,
|
||||
isLoadingMetadata,
|
||||
createAsPreset,
|
||||
loadWorkflow,
|
||||
hasWorkflow: imageDTO.has_workflow,
|
||||
recallSize,
|
||||
upscale,
|
||||
delete: _delete,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import type { PersistConfig, RootState } from 'app/store/store';
|
||||
import { uniqBy } from 'lodash-es';
|
||||
import { isEqual, uniqBy } from 'lodash-es';
|
||||
import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
import type { BoardId, ComparisonMode, GalleryState, GalleryView, OrderDir } from './types';
|
||||
@@ -32,10 +32,54 @@ export const gallerySlice = createSlice({
|
||||
initialState: initialGalleryState,
|
||||
reducers: {
|
||||
imageSelected: (state, action: PayloadAction<ImageDTO | null>) => {
|
||||
state.selection = action.payload ? [action.payload] : [];
|
||||
// Let's be efficient here and not update the selection unless it has actually changed. This helps to prevent
|
||||
// unnecessary re-renders of the gallery.
|
||||
|
||||
const selectedImage = action.payload;
|
||||
|
||||
// If we got `null`, clear the selection
|
||||
if (!selectedImage) {
|
||||
// But only if we have images selected
|
||||
if (state.selection.length > 0) {
|
||||
state.selection = [];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If we have multiple images selected, clear the selection and select the new image
|
||||
if (state.selection.length !== 1) {
|
||||
state.selection = [selectedImage];
|
||||
return;
|
||||
}
|
||||
|
||||
// If the selected image is different from the current selection, clear the selection and select the new image
|
||||
if (!isEqual(state.selection[0], selectedImage)) {
|
||||
state.selection = [selectedImage];
|
||||
return;
|
||||
}
|
||||
|
||||
// Else we have the same image selected, do nothing
|
||||
},
|
||||
selectionChanged: (state, action: PayloadAction<ImageDTO[]>) => {
|
||||
state.selection = uniqBy(action.payload, (i) => i.image_name);
|
||||
// Let's be efficient here and not update the selection unless it has actually changed. This helps to prevent
|
||||
// unnecessary re-renders of the gallery.
|
||||
|
||||
// Remove duplicates from the selection
|
||||
const newSelection = uniqBy(action.payload, (i) => i.image_name);
|
||||
|
||||
// If the new selection has a different length, update the selection
|
||||
if (newSelection.length !== state.selection.length) {
|
||||
state.selection = newSelection;
|
||||
return;
|
||||
}
|
||||
|
||||
// If the new selection is different, update the selection
|
||||
if (!isEqual(newSelection, state.selection)) {
|
||||
state.selection = newSelection;
|
||||
return;
|
||||
}
|
||||
|
||||
// Else we have the same selection, do nothing
|
||||
},
|
||||
imageToCompareChanged: (state, action: PayloadAction<ImageDTO | null>) => {
|
||||
state.imageToCompare = action.payload;
|
||||
|
||||
@@ -7,6 +7,7 @@ import type { MainModelConfig } from 'services/api/types';
|
||||
|
||||
const initialStatesSelector = createMemoizedSelector(selectConfigSlice, (config) => {
|
||||
const { steps, guidance, scheduler, cfgRescaleMultiplier, vaePrecision, width, height } = config.sd;
|
||||
const { guidance: fluxGuidance } = config.flux;
|
||||
|
||||
return {
|
||||
initialSteps: steps.initial,
|
||||
@@ -16,6 +17,7 @@ const initialStatesSelector = createMemoizedSelector(selectConfigSlice, (config)
|
||||
initialVaePrecision: vaePrecision,
|
||||
initialWidth: width.initial,
|
||||
initialHeight: height.initial,
|
||||
initialGuidance: fluxGuidance.initial,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -28,6 +30,7 @@ export const useMainModelDefaultSettings = (modelConfig: MainModelConfig) => {
|
||||
initialVaePrecision,
|
||||
initialWidth,
|
||||
initialHeight,
|
||||
initialGuidance,
|
||||
} = useAppSelector(initialStatesSelector);
|
||||
|
||||
const defaultSettingsDefaults = useMemo(() => {
|
||||
@@ -42,7 +45,7 @@ export const useMainModelDefaultSettings = (modelConfig: MainModelConfig) => {
|
||||
},
|
||||
scheduler: {
|
||||
isEnabled: !isNil(modelConfig?.default_settings?.scheduler),
|
||||
value: modelConfig?.default_settings?.scheduler || initialScheduler || 'euler',
|
||||
value: modelConfig?.default_settings?.scheduler || initialScheduler || 'dpmpp_3m_k',
|
||||
},
|
||||
steps: {
|
||||
isEnabled: !isNil(modelConfig?.default_settings?.steps),
|
||||
@@ -64,6 +67,10 @@ export const useMainModelDefaultSettings = (modelConfig: MainModelConfig) => {
|
||||
isEnabled: !isNil(modelConfig?.default_settings?.height),
|
||||
value: modelConfig?.default_settings?.height || initialHeight,
|
||||
},
|
||||
guidance: {
|
||||
isEnabled: !isNil(modelConfig?.default_settings?.guidance),
|
||||
value: modelConfig?.default_settings?.guidance || initialGuidance,
|
||||
},
|
||||
};
|
||||
}, [
|
||||
modelConfig,
|
||||
@@ -74,6 +81,7 @@ export const useMainModelDefaultSettings = (modelConfig: MainModelConfig) => {
|
||||
initialCfgRescaleMultiplier,
|
||||
initialWidth,
|
||||
initialHeight,
|
||||
initialGuidance,
|
||||
]);
|
||||
|
||||
return defaultSettingsDefaults;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Box, Flex, Heading, Tab, TabList, TabPanel, TabPanels, Tabs } from '@invoke-ai/ui-library';
|
||||
import { Box, Button, Flex, Heading, Tab, TabList, TabPanel, TabPanels, Tabs, Text } from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { StarterModelsForm } from 'features/modelManagerV2/subpanels/AddModelPanel/StarterModels/StarterModelsForm';
|
||||
import { atom } from 'nanostores';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiInfoBold } from 'react-icons/pi';
|
||||
|
||||
import { HuggingFaceForm } from './AddModelPanel/HuggingFaceFolder/HuggingFaceForm';
|
||||
import { InstallModelForm } from './AddModelPanel/InstallModelForm';
|
||||
@@ -19,9 +20,19 @@ export const InstallModels = memo(() => {
|
||||
$installModelsTab.set(index);
|
||||
}, []);
|
||||
|
||||
const onClickLearnMore = useCallback(() => {
|
||||
window.open('https://support.invoke.ai/support/solutions/articles/151000170961-supported-models');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Flex layerStyle="first" borderRadius="base" w="full" h="full" flexDir="column" gap={4}>
|
||||
<Heading fontSize="xl">{t('modelManager.addModel')}</Heading>
|
||||
<Flex alignItems="center" justifyContent="space-between">
|
||||
<Heading fontSize="xl">{t('modelManager.addModel')}</Heading>
|
||||
<Button alignItems="center" variant="link" leftIcon={<PiInfoBold />} onClick={onClickLearnMore}>
|
||||
<Text variant="subtext">{t('modelManager.learnMoreAboutSupportedModels')}</Text>
|
||||
</Button>
|
||||
</Flex>
|
||||
|
||||
<Tabs variant="collapse" height="50%" display="flex" flexDir="column" index={index} onChange={onChange}>
|
||||
<TabList>
|
||||
<Tab>{t('modelManager.urlOrLocalPath')}</Tab>
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
import { CompositeNumberInput, CompositeSlider, Flex, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { SettingToggle } from 'features/modelManagerV2/subpanels/ModelPanel/SettingToggle';
|
||||
import { selectGuidanceConfig } from 'features/system/store/configSlice';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import type { UseControllerProps } from 'react-hook-form';
|
||||
import { useController } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import type { MainModelDefaultSettingsFormData } from './MainModelDefaultSettings';
|
||||
|
||||
type DefaultGuidanceType = MainModelDefaultSettingsFormData['guidance'];
|
||||
|
||||
export const DefaultGuidance = memo((props: UseControllerProps<MainModelDefaultSettingsFormData>) => {
|
||||
const { field } = useController(props);
|
||||
|
||||
const config = useAppSelector(selectGuidanceConfig);
|
||||
const { t } = useTranslation();
|
||||
const marks = useMemo(
|
||||
() => [
|
||||
config.sliderMin,
|
||||
Math.floor(config.sliderMax - (config.sliderMax - config.sliderMin) / 2),
|
||||
config.sliderMax,
|
||||
],
|
||||
[config.sliderMax, config.sliderMin]
|
||||
);
|
||||
|
||||
const onChange = useCallback(
|
||||
(v: number) => {
|
||||
const updatedValue = {
|
||||
...(field.value as DefaultGuidanceType),
|
||||
value: v,
|
||||
};
|
||||
field.onChange(updatedValue);
|
||||
},
|
||||
[field]
|
||||
);
|
||||
|
||||
const value = useMemo(() => {
|
||||
return (field.value as DefaultGuidanceType).value;
|
||||
}, [field.value]);
|
||||
|
||||
const isDisabled = useMemo(() => {
|
||||
return !(field.value as DefaultGuidanceType).isEnabled;
|
||||
}, [field.value]);
|
||||
|
||||
return (
|
||||
<FormControl flexDir="column" gap={2} alignItems="flex-start">
|
||||
<Flex justifyContent="space-between" w="full">
|
||||
<InformationalPopover feature="paramGuidance">
|
||||
<FormLabel>{t('parameters.guidance')}</FormLabel>
|
||||
</InformationalPopover>
|
||||
<SettingToggle control={props.control} name="guidance" />
|
||||
</Flex>
|
||||
|
||||
<Flex w="full" gap={4}>
|
||||
<CompositeSlider
|
||||
value={value}
|
||||
min={config.sliderMin}
|
||||
max={config.sliderMax}
|
||||
step={config.coarseStep}
|
||||
fineStep={config.fineStep}
|
||||
onChange={onChange}
|
||||
marks={marks}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
<CompositeNumberInput
|
||||
value={value}
|
||||
min={config.numberInputMin}
|
||||
max={config.numberInputMax}
|
||||
step={config.coarseStep}
|
||||
fineStep={config.fineStep}
|
||||
onChange={onChange}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
</Flex>
|
||||
</FormControl>
|
||||
);
|
||||
});
|
||||
|
||||
DefaultGuidance.displayName = 'DefaultGuidance';
|
||||
@@ -17,6 +17,7 @@ import type { MainModelConfig } from 'services/api/types';
|
||||
|
||||
import { DefaultCfgRescaleMultiplier } from './DefaultCfgRescaleMultiplier';
|
||||
import { DefaultCfgScale } from './DefaultCfgScale';
|
||||
import { DefaultGuidance } from './DefaultGuidance';
|
||||
import { DefaultScheduler } from './DefaultScheduler';
|
||||
import { DefaultSteps } from './DefaultSteps';
|
||||
import { DefaultVae } from './DefaultVae';
|
||||
@@ -36,6 +37,7 @@ export type MainModelDefaultSettingsFormData = {
|
||||
cfgRescaleMultiplier: FormField<number>;
|
||||
width: FormField<number>;
|
||||
height: FormField<number>;
|
||||
guidance: FormField<number>;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
@@ -46,6 +48,10 @@ export const MainModelDefaultSettings = memo(({ modelConfig }: Props) => {
|
||||
const selectedModelKey = useAppSelector(selectSelectedModelKey);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const isFlux = useMemo(() => {
|
||||
return modelConfig.base === 'flux';
|
||||
}, [modelConfig]);
|
||||
|
||||
const defaultSettingsDefaults = useMainModelDefaultSettings(modelConfig);
|
||||
const optimalDimension = useMemo(() => {
|
||||
const modelBase = modelConfig?.base;
|
||||
@@ -72,6 +78,7 @@ export const MainModelDefaultSettings = memo(({ modelConfig }: Props) => {
|
||||
scheduler: data.scheduler.isEnabled ? data.scheduler.value : null,
|
||||
width: data.width.isEnabled ? data.width.value : null,
|
||||
height: data.height.isEnabled ? data.height.value : null,
|
||||
guidance: data.guidance.isEnabled ? data.guidance.value : null,
|
||||
};
|
||||
|
||||
updateModel({
|
||||
@@ -118,11 +125,12 @@ export const MainModelDefaultSettings = memo(({ modelConfig }: Props) => {
|
||||
|
||||
<SimpleGrid columns={2} gap={8}>
|
||||
<DefaultVae control={control} name="vae" />
|
||||
<DefaultVaePrecision control={control} name="vaePrecision" />
|
||||
<DefaultScheduler control={control} name="scheduler" />
|
||||
{!isFlux && <DefaultVaePrecision control={control} name="vaePrecision" />}
|
||||
{!isFlux && <DefaultScheduler control={control} name="scheduler" />}
|
||||
<DefaultSteps control={control} name="steps" />
|
||||
<DefaultCfgScale control={control} name="cfgScale" />
|
||||
<DefaultCfgRescaleMultiplier control={control} name="cfgRescaleMultiplier" />
|
||||
{isFlux && <DefaultGuidance control={control} name="guidance" />}
|
||||
{!isFlux && <DefaultCfgScale control={control} name="cfgScale" />}
|
||||
{!isFlux && <DefaultCfgRescaleMultiplier control={control} name="cfgRescaleMultiplier" />}
|
||||
<DefaultWidth control={control} optimalDimension={optimalDimension} />
|
||||
<DefaultHeight control={control} optimalDimension={optimalDimension} />
|
||||
</SimpleGrid>
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'reactflow/dist/style.css';
|
||||
|
||||
import { Flex } from '@invoke-ai/ui-library';
|
||||
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
|
||||
import { useScopeOnFocus } from 'common/hooks/interactionScopes';
|
||||
import { useFocusRegion } from 'common/hooks/focus';
|
||||
import { AddNodeCmdk } from 'features/nodes/components/flow/AddNodeCmdk/AddNodeCmdk';
|
||||
import TopPanel from 'features/nodes/components/flow/panels/TopPanel/TopPanel';
|
||||
import WorkflowEditorSettings from 'features/nodes/components/flow/panels/TopRightPanel/WorkflowEditorSettings';
|
||||
@@ -21,7 +21,7 @@ const NodeEditor = () => {
|
||||
const { data, isLoading } = useGetOpenAPISchemaQuery();
|
||||
const { t } = useTranslation();
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
useScopeOnFocus('workflows', ref);
|
||||
useFocusRegion('workflows', ref);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useGlobalMenuClose, useToken } from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppDispatch, useAppSelector, useAppStore } from 'app/store/storeHooks';
|
||||
import { INTERACTION_SCOPES, useScopeImperativeApi, useScopeOnFocus } from 'common/hooks/interactionScopes';
|
||||
import { useFocusRegion, useIsRegionFocused } from 'common/hooks/focus';
|
||||
import { useConnection } from 'features/nodes/hooks/useConnection';
|
||||
import { useCopyPaste } from 'features/nodes/hooks/useCopyPaste';
|
||||
import { useSyncExecutionState } from 'features/nodes/hooks/useExecutionState';
|
||||
@@ -89,9 +89,8 @@ export const Flow = memo(() => {
|
||||
const cancelConnection = useReactFlowStore(selectCancelConnection);
|
||||
const updateNodeInternals = useUpdateNodeInternals();
|
||||
const store = useAppStore();
|
||||
const isWorkflowsActive = useStore(INTERACTION_SCOPES.workflows.$isActive);
|
||||
const workflowsScopeApi = useScopeImperativeApi('workflows');
|
||||
useScopeOnFocus('workflows', flowWrapper);
|
||||
const isWorkflowsFocused = useIsRegionFocused('workflows');
|
||||
useFocusRegion('workflows', flowWrapper);
|
||||
|
||||
useWorkflowWatcher();
|
||||
useSyncExecutionState();
|
||||
@@ -129,8 +128,7 @@ export const Flow = memo(() => {
|
||||
const { onCloseGlobal } = useGlobalMenuClose();
|
||||
const handlePaneClick = useCallback(() => {
|
||||
onCloseGlobal();
|
||||
workflowsScopeApi.add();
|
||||
}, [onCloseGlobal, workflowsScopeApi]);
|
||||
}, [onCloseGlobal]);
|
||||
|
||||
const onInit: OnInit = useCallback((flow) => {
|
||||
$flow.set(flow);
|
||||
@@ -245,8 +243,8 @@ export const Flow = memo(() => {
|
||||
id: 'selectAll',
|
||||
category: 'workflows',
|
||||
callback: selectAll,
|
||||
options: { enabled: isWorkflowsActive, preventDefault: true },
|
||||
dependencies: [selectAll, isWorkflowsActive],
|
||||
options: { enabled: isWorkflowsFocused, preventDefault: true },
|
||||
dependencies: [selectAll, isWorkflowsFocused],
|
||||
});
|
||||
|
||||
useRegisteredHotkeys({
|
||||
@@ -319,8 +317,8 @@ export const Flow = memo(() => {
|
||||
id: 'deleteSelection',
|
||||
category: 'workflows',
|
||||
callback: deleteSelection,
|
||||
options: { preventDefault: true, enabled: isWorkflowsActive },
|
||||
dependencies: [deleteSelection, isWorkflowsActive],
|
||||
options: { preventDefault: true, enabled: isWorkflowsFocused },
|
||||
dependencies: [deleteSelection, isWorkflowsFocused],
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -51,7 +51,7 @@ const NodeEditorPanelGroup = () => {
|
||||
<Panel id="workflow" collapsible minSize={25}>
|
||||
<WorkflowPanel />
|
||||
</Panel>
|
||||
<ResizeHandle orientation="horizontal" onDoubleClick={handleDoubleClickHandle} />
|
||||
<ResizeHandle onDoubleClick={handleDoubleClickHandle} />
|
||||
<Panel id="inspector" collapsible minSize={25}>
|
||||
<InspectorPanel />
|
||||
</Panel>
|
||||
|
||||
@@ -8,7 +8,8 @@ export const addFLUXLoRAs = (
|
||||
state: RootState,
|
||||
g: Graph,
|
||||
denoise: Invocation<'flux_denoise'>,
|
||||
modelLoader: Invocation<'flux_model_loader'>
|
||||
modelLoader: Invocation<'flux_model_loader'>,
|
||||
fluxTextEncoder: Invocation<'flux_text_encoder'>
|
||||
): void => {
|
||||
const enabledLoRAs = state.loras.loras.filter((l) => l.isEnabled && l.model.base === 'flux');
|
||||
const loraCount = enabledLoRAs.length;
|
||||
@@ -20,7 +21,7 @@ export const addFLUXLoRAs = (
|
||||
const loraMetadata: S['LoRAMetadataField'][] = [];
|
||||
|
||||
// We will collect LoRAs into a single collection node, then pass them to the LoRA collection loader, which applies
|
||||
// each LoRA to the UNet and CLIP.
|
||||
// each LoRA to the transformer and text encoders.
|
||||
const loraCollector = g.addNode({
|
||||
id: getPrefixedId('lora_collector'),
|
||||
type: 'collect',
|
||||
@@ -33,10 +34,12 @@ export const addFLUXLoRAs = (
|
||||
g.addEdge(loraCollector, 'collection', loraCollectionLoader, 'loras');
|
||||
// Use model loader as transformer input
|
||||
g.addEdge(modelLoader, 'transformer', loraCollectionLoader, 'transformer');
|
||||
// Reroute transformer connections through the LoRA collection loader
|
||||
g.addEdge(modelLoader, 'clip', loraCollectionLoader, 'clip');
|
||||
// Reroute model connections through the LoRA collection loader
|
||||
g.deleteEdgesTo(denoise, ['transformer']);
|
||||
|
||||
g.deleteEdgesTo(fluxTextEncoder, ['clip']);
|
||||
g.addEdge(loraCollectionLoader, 'transformer', denoise, 'transformer');
|
||||
g.addEdge(loraCollectionLoader, 'clip', fluxTextEncoder, 'clip');
|
||||
|
||||
for (const lora of enabledLoRAs) {
|
||||
const { weight } = lora;
|
||||
|
||||
@@ -6,6 +6,7 @@ import { selectCanvasSettingsSlice } from 'features/controlLayers/store/canvasSe
|
||||
import { selectParamsSlice } from 'features/controlLayers/store/paramsSlice';
|
||||
import { selectCanvasMetadata, selectCanvasSlice } from 'features/controlLayers/store/selectors';
|
||||
import { fetchModelConfigWithTypeGuard } from 'features/metadata/util/modelFetchingHelpers';
|
||||
import { addFLUXLoRAs } from 'features/nodes/util/graph/generation/addFLUXLoRAs';
|
||||
import { addImageToImage } from 'features/nodes/util/graph/generation/addImageToImage';
|
||||
import { addInpaint } from 'features/nodes/util/graph/generation/addInpaint';
|
||||
import { addNSFWChecker } from 'features/nodes/util/graph/generation/addNSFWChecker';
|
||||
@@ -18,8 +19,6 @@ import type { Invocation } from 'services/api/types';
|
||||
import { isNonRefinerMainModelConfig } from 'services/api/types';
|
||||
import { assert } from 'tsafe';
|
||||
|
||||
import { addFLUXLoRAs } from './addFLUXLoRAs';
|
||||
|
||||
const log = logger('system');
|
||||
|
||||
export const buildFLUXGraph = async (
|
||||
@@ -78,7 +77,6 @@ export const buildFLUXGraph = async (
|
||||
guidance,
|
||||
num_steps: steps,
|
||||
seed,
|
||||
trajectory_guidance_strength: 0,
|
||||
denoising_start: 0,
|
||||
denoising_end: 1,
|
||||
width: scaledSize.width,
|
||||
@@ -97,12 +95,12 @@ export const buildFLUXGraph = async (
|
||||
g.addEdge(modelLoader, 'transformer', noise, 'transformer');
|
||||
g.addEdge(modelLoader, 'vae', l2i, 'vae');
|
||||
|
||||
addFLUXLoRAs(state, g, noise, modelLoader);
|
||||
|
||||
g.addEdge(modelLoader, 'clip', posCond, 'clip');
|
||||
g.addEdge(modelLoader, 't5_encoder', posCond, 't5_encoder');
|
||||
g.addEdge(modelLoader, 'max_seq_len', posCond, 't5_max_seq_len');
|
||||
|
||||
addFLUXLoRAs(state, g, noise, modelLoader, posCond);
|
||||
|
||||
g.addEdge(posCond, 'conditioning', noise, 'positive_text_conditioning');
|
||||
|
||||
g.addEdge(noise, 'latents', l2i, 'latents');
|
||||
@@ -124,7 +122,15 @@ export const buildFLUXGraph = async (
|
||||
clip_embed_model: clipEmbedModel,
|
||||
});
|
||||
|
||||
const denoisingValue = 1 - img2imgStrength;
|
||||
let denoisingStart: number;
|
||||
if (optimizedDenoisingEnabled) {
|
||||
// We rescale the img2imgStrength (with exponent 0.2) to effectively use the entire range [0, 1] and make the scale
|
||||
// more user-friendly for FLUX. Without this, most of the 'change' is concentrated in the high denoise strength
|
||||
// range (>0.9).
|
||||
denoisingStart = 1 - img2imgStrength ** 0.2;
|
||||
} else {
|
||||
denoisingStart = 1 - img2imgStrength;
|
||||
}
|
||||
|
||||
if (generationMode === 'txt2img') {
|
||||
canvasOutput = addTextToImage(g, l2i, originalSize, scaledSize);
|
||||
@@ -138,7 +144,7 @@ export const buildFLUXGraph = async (
|
||||
originalSize,
|
||||
scaledSize,
|
||||
bbox,
|
||||
denoisingValue,
|
||||
denoisingStart,
|
||||
false
|
||||
);
|
||||
} else if (generationMode === 'inpaint') {
|
||||
@@ -152,15 +158,9 @@ export const buildFLUXGraph = async (
|
||||
modelLoader,
|
||||
originalSize,
|
||||
scaledSize,
|
||||
denoisingValue,
|
||||
denoisingStart,
|
||||
false
|
||||
);
|
||||
if (optimizedDenoisingEnabled) {
|
||||
g.updateNode(noise, {
|
||||
denoising_start: 0,
|
||||
trajectory_guidance_strength: denoisingValue,
|
||||
});
|
||||
}
|
||||
} else if (generationMode === 'outpaint') {
|
||||
canvasOutput = await addOutpaint(
|
||||
state,
|
||||
@@ -172,7 +172,7 @@ export const buildFLUXGraph = async (
|
||||
modelLoader,
|
||||
originalSize,
|
||||
scaledSize,
|
||||
denoisingValue,
|
||||
denoisingStart,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ const FIELD_VALUE_FALLBACK_MAP: Record<StatefulFieldType['name'], FieldValue> =
|
||||
LoRAModelField: undefined,
|
||||
ModelIdentifierField: undefined,
|
||||
MainModelField: undefined,
|
||||
SchedulerField: 'euler',
|
||||
SchedulerField: 'dpmpp_3m_k',
|
||||
SDXLMainModelField: undefined,
|
||||
FluxMainModelField: undefined,
|
||||
SDXLRefinerModelField: undefined,
|
||||
|
||||
@@ -425,7 +425,7 @@ const buildSchedulerFieldInputTemplate: FieldInputTemplateBuilder<SchedulerField
|
||||
const template: SchedulerFieldInputTemplate = {
|
||||
...baseField,
|
||||
type: fieldType,
|
||||
default: schemaObject.default ?? 'euler',
|
||||
default: schemaObject.default ?? 'dpmpp_3m_k',
|
||||
};
|
||||
|
||||
return template;
|
||||
|
||||
@@ -26,7 +26,7 @@ export const ParamOptimizedDenoisingToggle = memo(() => {
|
||||
<FormControl w="min-content">
|
||||
<InformationalPopover feature="optimizedDenoising">
|
||||
<FormLabel m={0}>
|
||||
{t('parameters.optimizedInpainting')} ({t('settings.beta')})
|
||||
{t('parameters.optimizedImageToImage')} ({t('settings.beta')})
|
||||
</FormLabel>
|
||||
</InformationalPopover>
|
||||
<Switch isChecked={optimizedDenoisingEnabled} onChange={onChange} />
|
||||
|
||||
@@ -14,9 +14,9 @@ const ParamCanvasCoherenceMode = () => {
|
||||
|
||||
const options = useMemo<ComboboxOption[]>(
|
||||
() => [
|
||||
{ label: t('unifiedCanvas.coherenceModeGaussianBlur'), value: 'Gaussian Blur' },
|
||||
{ label: t('unifiedCanvas.coherenceModeBoxBlur'), value: 'Box Blur' },
|
||||
{ label: t('unifiedCanvas.coherenceModeStaged'), value: 'Staged' },
|
||||
{ label: t('parameters.gaussianBlur'), value: 'Gaussian Blur' },
|
||||
{ label: t('parameters.boxBlur'), value: 'Box Blur' },
|
||||
{ label: t('parameters.staged'), value: 'Staged' },
|
||||
],
|
||||
[t]
|
||||
);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user