diff --git a/invokeai/app/services/shared/graph.py b/invokeai/app/services/shared/graph.py
index fd31448ea4..3ea67a5291 100644
--- a/invokeai/app/services/shared/graph.py
+++ b/invokeai/app/services/shared/graph.py
@@ -123,6 +123,23 @@ def is_any(t: Any) -> bool:
return t == Any or Any in get_args(t)
+def extract_collection_item_types(t: Any) -> set[Any]:
+ """Extracts list item types from a collection annotation, including unions containing list branches."""
+ if is_any(t):
+ return {Any}
+
+ if get_origin(t) is list:
+ return {arg for arg in get_args(t) if arg != NoneType}
+
+ item_types: set[Any] = set()
+ for arg in get_args(t):
+ if is_any(arg):
+ item_types.add(Any)
+ elif get_origin(arg) is list:
+ item_types.update(item_arg for item_arg in get_args(arg) if item_arg != NoneType)
+ return item_types
+
+
def are_connection_types_compatible(from_type: Any, to_type: Any) -> bool:
if not from_type or not to_type:
return False
@@ -280,7 +297,7 @@ class CollectInvocationOutput(BaseInvocationOutput):
)
-@invocation("collect", version="1.0.0")
+@invocation("collect", version="1.1.0")
class CollectInvocation(BaseInvocation):
"""Collects values into a collection"""
@@ -292,7 +309,10 @@ class CollectInvocation(BaseInvocation):
input=Input.Connection,
)
collection: list[Any] = InputField(
- description="The collection, will be provided on execution", default=[], ui_hidden=True
+ description="An optional collection to append to",
+ default=[],
+ ui_type=UIType._Collection,
+ input=Input.Connection,
)
def invoke(self, context: InvocationContext) -> CollectInvocationOutput:
@@ -520,7 +540,9 @@ class Graph(BaseModel):
# Validate that an edge to this node+field doesn't already exist
input_edges = self._get_input_edges(edge.destination.node_id, edge.destination.field)
- if len(input_edges) > 0 and not isinstance(to_node, CollectInvocation):
+ if len(input_edges) > 0 and (
+ not isinstance(to_node, CollectInvocation) or edge.destination.field != ITEM_FIELD
+ ):
raise InvalidEdgeError(f"Edge already exists ({edge})")
# Validate that no cycles would be created
@@ -546,8 +568,10 @@ class Graph(BaseModel):
raise InvalidEdgeError(f"Iterator output type does not match iterator input type ({edge}): {err}")
# Validate if collector input type matches output type (if this edge results in both being set)
- if isinstance(to_node, CollectInvocation) and edge.destination.field == ITEM_FIELD:
- err = self._is_collector_connection_valid(edge.destination.node_id, new_input=edge.source)
+ if isinstance(to_node, CollectInvocation) and edge.destination.field in (ITEM_FIELD, COLLECTION_FIELD):
+ err = self._is_collector_connection_valid(
+ edge.destination.node_id, new_input=edge.source, new_input_field=edge.destination.field
+ )
if err is not None:
raise InvalidEdgeError(f"Collector output type does not match collector input type ({edge}): {err}")
@@ -676,76 +700,152 @@ class Graph(BaseModel):
# Collector input type must match all iterator output types
if isinstance(input_node, CollectInvocation):
- collector_inputs = self._get_input_edges(input_node.id, ITEM_FIELD)
- if len(collector_inputs) == 0:
- return "Iterator input collector must have at least one item input edge"
-
- # Traverse the graph to find the first collector input edge. Collectors validate that their collection
- # inputs are all of the same type, so we can use the first input edge to determine the collector's type
- first_collector_input_edge = collector_inputs[0]
- first_collector_input_type = get_output_field_type(
- self.get_node(first_collector_input_edge.source.node_id), first_collector_input_edge.source.field
- )
- resolved_collector_type = (
- first_collector_input_type
- if get_origin(first_collector_input_type) is None
- else get_args(first_collector_input_type)
- )
- if not all((are_connection_types_compatible(resolved_collector_type, t) for t in output_field_types)):
+ input_root_type = self._get_collector_input_root_type(input_node.id)
+ if input_root_type is None:
+ return "Iterator input collector must have at least one item or collection input edge"
+ if not all((are_connection_types_compatible(input_root_type, t) for t in output_field_types)):
return "Iterator collection type must match all iterator output types"
return None
+ def _resolve_collector_input_types(self, node_id: str, visited: Optional[set[str]] = None) -> set[Any]:
+ """Resolves possible item types for a collector's inputs, recursively following chained collectors."""
+ visited = visited or set()
+ if node_id in visited:
+ return set()
+ visited.add(node_id)
+
+ input_types: set[Any] = set()
+
+ for edge in self._get_input_edges(node_id, ITEM_FIELD):
+ input_field_type = get_output_field_type(self.get_node(edge.source.node_id), edge.source.field)
+ resolved_types = [input_field_type] if get_origin(input_field_type) is None else get_args(input_field_type)
+ input_types.update(t for t in resolved_types if t != NoneType)
+
+ for edge in self._get_input_edges(node_id, COLLECTION_FIELD):
+ source_node = self.get_node(edge.source.node_id)
+ if isinstance(source_node, CollectInvocation) and edge.source.field == COLLECTION_FIELD:
+ input_types.update(self._resolve_collector_input_types(source_node.id, visited.copy()))
+ continue
+
+ input_field_type = get_output_field_type(source_node, edge.source.field)
+ input_types.update(extract_collection_item_types(input_field_type))
+
+ return input_types
+
+ def _get_collector_input_root_type(self, node_id: str) -> Any | None:
+ input_types = self._resolve_collector_input_types(node_id)
+ non_any_input_types = {t for t in input_types if t != Any}
+ if len(non_any_input_types) == 0 and Any in input_types:
+ return Any
+ if len(non_any_input_types) == 0:
+ return None
+
+ type_tree = nx.DiGraph()
+ type_tree.add_nodes_from(non_any_input_types)
+ type_tree.add_edges_from([e for e in itertools.permutations(non_any_input_types, 2) if issubclass(e[1], e[0])])
+ type_degrees = type_tree.in_degree(type_tree.nodes)
+ root_types = [t[0] for t in type_degrees if t[1] == 0] # type: ignore
+ if len(root_types) != 1:
+ return Any
+ return root_types[0]
+
def _is_collector_connection_valid(
self,
node_id: str,
new_input: Optional[EdgeConnection] = None,
+ new_input_field: Optional[str] = None,
new_output: Optional[EdgeConnection] = None,
) -> str | None:
- inputs = [e.source for e in self._get_input_edges(node_id, ITEM_FIELD)]
+ item_inputs = [e.source for e in self._get_input_edges(node_id, ITEM_FIELD)]
+ collection_inputs = [e.source for e in self._get_input_edges(node_id, COLLECTION_FIELD)]
outputs = [e.destination for e in self._get_output_edges(node_id, COLLECTION_FIELD)]
if new_input is not None:
- inputs.append(new_input)
+ field = new_input_field or ITEM_FIELD
+ if field == ITEM_FIELD:
+ item_inputs.append(new_input)
+ elif field == COLLECTION_FIELD:
+ collection_inputs.append(new_input)
if new_output is not None:
outputs.append(new_output)
- # Get input and output fields (the fields linked to the iterator's input/output)
- input_field_types = [get_output_field_type(self.get_node(e.node_id), e.field) for e in inputs]
+ if len(item_inputs) == 0 and len(collection_inputs) == 0:
+ return "Collector must have at least one item or collection input edge"
+
+ # Get input and output fields (the fields linked to the collector's input/output)
+ item_input_field_types = [get_output_field_type(self.get_node(e.node_id), e.field) for e in item_inputs]
+ collection_input_field_types = [
+ get_output_field_type(self.get_node(e.node_id), e.field) for e in collection_inputs
+ ]
output_field_types = [get_input_field_type(self.get_node(e.node_id), e.field) for e in outputs]
+ if not all((is_list_or_contains_list(t) or is_any(t) for t in collection_input_field_types)):
+ return "Collector collection input must be a collection"
+
# Validate that all inputs are derived from or match a single type
input_field_types = {
resolved_type
- for input_field_type in input_field_types
+ for input_field_type in item_input_field_types
for resolved_type in (
[input_field_type] if get_origin(input_field_type) is None else get_args(input_field_type)
)
if resolved_type != NoneType
} # Get unique types
+
+ for input_conn, input_field_type in zip(collection_inputs, collection_input_field_types, strict=False):
+ source_node = self.get_node(input_conn.node_id)
+ if isinstance(source_node, CollectInvocation) and input_conn.field == COLLECTION_FIELD:
+ input_field_types.update(self._resolve_collector_input_types(source_node.id))
+ continue
+ input_field_types.update(extract_collection_item_types(input_field_type))
+
+ non_any_input_field_types = {t for t in input_field_types if t != Any}
type_tree = nx.DiGraph()
- type_tree.add_nodes_from(input_field_types)
- type_tree.add_edges_from([e for e in itertools.permutations(input_field_types, 2) if issubclass(e[1], e[0])])
+ type_tree.add_nodes_from(non_any_input_field_types)
+ type_tree.add_edges_from(
+ [e for e in itertools.permutations(non_any_input_field_types, 2) if issubclass(e[1], e[0])]
+ )
type_degrees = type_tree.in_degree(type_tree.nodes)
- if sum((t[1] == 0 for t in type_degrees)) != 1: # type: ignore
+ root_types = [t[0] for t in type_degrees if t[1] == 0] # type: ignore
+ if len(root_types) > 1:
return "Collector input collection items must be of a single type"
- # Get the input root type
- input_root_type = next(t[0] for t in type_degrees if t[1] == 0) # type: ignore
+ # Get the input root type (if known)
+ input_root_type = root_types[0] if len(root_types) == 1 else None
# Verify that all outputs are lists
if not all(is_list_or_contains_list(t) or is_any(t) for t in output_field_types):
return "Collector output must connect to a collection input"
# Verify that all outputs match the input type (are a base class or the same class)
- if not all(
- is_any(t)
- or is_union_subtype(input_root_type, get_args(t)[0])
- or issubclass(input_root_type, get_args(t)[0])
- for t in output_field_types
- ):
+ if input_root_type is not None:
+ if not all(
+ is_any(t)
+ or is_union_subtype(input_root_type, get_args(t)[0])
+ or issubclass(input_root_type, get_args(t)[0])
+ for t in output_field_types
+ ):
+ return "Collector outputs must connect to a collection input with a matching type"
+ elif any(not is_any(t) and get_args(t)[0] != Any for t in output_field_types):
return "Collector outputs must connect to a collection input with a matching type"
+ # If this collector outputs to another collector's collection input, validate against the downstream
+ # collector's resolved input type (if available).
+ for output in outputs:
+ output_node = self.get_node(output.node_id)
+ if not isinstance(output_node, CollectInvocation) or output.field != COLLECTION_FIELD:
+ continue
+ output_root_type = self._get_collector_input_root_type(output_node.id)
+ if output_root_type is None:
+ continue
+ if input_root_type is None:
+ if output_root_type != Any:
+ return "Collector outputs must connect to a collection input with a matching type"
+ continue
+ if not are_connection_types_compatible(input_root_type, output_root_type):
+ return "Collector outputs must connect to a collection input with a matching type"
+
return None
def nx_graph(self) -> nx.DiGraph:
@@ -1211,8 +1311,19 @@ class GraphExecutionState(BaseModel):
if isinstance(node, CollectInvocation):
item_edges = [e for e in input_edges if e.destination.field == ITEM_FIELD]
item_edges.sort(key=lambda e: (self._get_iteration_path(e.source.node_id), e.source.node_id))
+ collection_edges = [e for e in input_edges if e.destination.field == COLLECTION_FIELD]
+ collection_edges.sort(key=lambda e: (self._get_iteration_path(e.source.node_id), e.source.node_id))
- output_collection = [copydeep(getattr(self.results[e.source.node_id], e.source.field)) for e in item_edges]
+ output_collection = []
+ for edge in collection_edges:
+ source_value = copydeep(getattr(self.results[edge.source.node_id], edge.source.field))
+ if isinstance(source_value, list):
+ output_collection.extend(source_value)
+ else:
+ output_collection.append(source_value)
+ output_collection.extend(
+ copydeep(getattr(self.results[e.source.node_id], e.source.field)) for e in item_edges
+ )
node.collection = output_collection
else:
for edge in input_edges:
diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json
index db515785f3..4686ad070e 100644
--- a/invokeai/frontend/web/public/locales/en.json
+++ b/invokeai/frontend/web/public/locales/en.json
@@ -3144,9 +3144,9 @@
"whatsNew": {
"whatsNewInInvoke": "What's New in Invoke",
"items": [
- "FLUX.2 Klein Support: InvokeAI now supports the new FLUX.2 Klein models (4B and 9B variants) with GGUF, FP8, and Diffusers formats. Features include txt2img, img2img, inpainting, and outpainting. See 'Starter Models' to get started.",
- "DyPE support for FLUX models improves high-resolution (>1536 px up to 4K) images. Go to the 'Advanced Options' section to activate.",
- "Z-Image Turbo diversity: Active 'Seed Variance Enhancer' under 'Advanced Options' to add diversitiy to your ZiT gens."
+ "Multi-user mode supports multiple isolated users on the same server.",
+ "Enhanced support for Z-Image and FLUX.2 Models.",
+ "Multiple user interface enhancements and new canvas features."
],
"takeUserSurvey": "ð£ Let us know how you like InvokeAI. Take our User Experience Survey!",
"readReleaseNotes": "Read Release Notes",
diff --git a/invokeai/frontend/web/public/locales/it.json b/invokeai/frontend/web/public/locales/it.json
index 7a6dafe4c7..cafd91d2a4 100644
--- a/invokeai/frontend/web/public/locales/it.json
+++ b/invokeai/frontend/web/public/locales/it.json
@@ -2639,7 +2639,7 @@
"desc": "Seleziona un singolo oggetto di destinazione. Una volta completata la selezione, fai clic su Applica per eliminare tutto ciò che si trova al di fuori dell'area selezionata, oppure salva la selezione come nuovo livello.",
"visualModeDesc": "La modalità visiva utilizza input di tipo riquadro e punto per selezionare un oggetto.",
"visualMode1": "Fai clic e trascina per disegnare un riquadro attorno all'oggetto che desideri selezionare. Puoi ottenere risultati migliori disegnando il riquadro un po' più grande o più piccolo dell'oggetto.",
- "visualMode2": "Fare clic per aggiungere un punto di iinclusionei verde oppure fare clic tenendo premuto Maiusc per aggiungere un punto di iesclusionei rosso per indicare al modello cosa includere o escludere.",
+ "visualMode2": "Fai clic per aggiungere un punto verde includi oppure fai clic tenendo premuto il tasto Maiusc per aggiungere un punto rosso escludi per indicare al modello cosa includere o escludere.",
"visualMode3": "I punti possono essere utilizzati per perfezionare una selezione di caselle oppure in modo indipendente.",
"promptModeDesc": "La modalità Prompt utilizza l'input di testo per selezionare un oggetto.",
"promptMode1": "Digitare una breve descrizione dell'oggetto che si desidera selezionare.",
@@ -3089,7 +3089,8 @@
"passwordsDoNotMatch": "Le password non corrispondono",
"createAccount": "Crea un account amministratore",
"creatingAccount": "Impostazione in corso...",
- "setupFailed": "Installazione non riuscita. Riprova."
+ "setupFailed": "Installazione non riuscita. Riprova.",
+ "passwordHelperRelaxed": "Inserisci una password qualsiasi (verrà visualizzata la sua robustezza)"
},
"userMenu": "Menu utente",
"logout": "Esci",
diff --git a/invokeai/frontend/web/public/locales/ja.json b/invokeai/frontend/web/public/locales/ja.json
index 291b34cafa..7acf6c98ca 100644
--- a/invokeai/frontend/web/public/locales/ja.json
+++ b/invokeai/frontend/web/public/locales/ja.json
@@ -8,7 +8,7 @@
"back": "æ»ã",
"statusDisconnected": "åææž",
"cancel": "ãã£ã³ã»ã«",
- "accept": "åæ",
+ "accept": "確å®",
"img2img": "img2img",
"loading": "ããŒãäž",
"githubLabel": "Github",
@@ -33,9 +33,9 @@
"batch": "ããããããŒãžã£ãŒ",
"advanced": "é«åºŠ",
"created": "äœææž",
- "green": "ç·",
- "blue": "é",
- "alpha": "ã¢ã«ãã¡",
+ "green": "G",
+ "blue": "B",
+ "alpha": "α",
"outpaint": "outpaint",
"unknown": "äžæ",
"updated": "æŽæ°æž",
@@ -44,7 +44,7 @@
"copyError": "$t(gallery.copy) ãšã©ãŒ",
"data": "ããŒã¿",
"template": "ãã³ãã¬ãŒã",
- "red": "èµ€",
+ "red": "R",
"or": "ãŸãã¯",
"checkpoint": "Checkpoint",
"direction": "æ¹å",
@@ -194,7 +194,7 @@
"assets": "ã¢ã»ãã",
"useForPromptGeneration": "ããã³ããçæã«äœ¿çšãã",
"jump": "ãžã£ã³ã",
- "noImagesInGallery": "ãã£ã¹ãã¬ã€ã«ç»åããããŸãã",
+ "noImagesInGallery": "衚瀺ããç»åããããŸãã",
"unableToLoad": "ã®ã£ã©ãªãŒãèªã¿èŸŒããŸãã",
"selectAnImageToCompare": "æ¯èŒããç»åãéžæ",
"openViewer": "ãã¥ãŒã¢ãŒãéã",
@@ -211,7 +211,7 @@
},
"useSize": {
"title": "ãµã€ãºã䜿çš",
- "desc": "çŸç»åã®ãµã€ãºãbboxãµã€ãºãšããŠäœ¿çšãã."
+ "desc": "çŸç»åã®ãµã€ãºãããŠã³ãã£ã³ã°ããã¯ã¹ã®ãµã€ãºãšããŠäœ¿çšãã."
},
"recallPrompts": {
"title": "ããã³ãããå䜿çš",
@@ -366,8 +366,8 @@
"desc": "ç©åœ¢ããŒã«ãéžæããŸãã"
},
"settings": {
- "behavior": "è¡å",
- "display": "ãã£ã¹ãã¬ã€",
+ "behavior": "æå",
+ "display": "衚瀺",
"grid": "ã°ãªãã",
"debug": "ãããã°"
},
@@ -388,25 +388,25 @@
"desc": "éžæããã€ã³ãã€ã³ã ãã¹ã¯ãå転ããå察ã®éæåºŠãæã€æ°ãããã¹ã¯ãäœæããŸãã"
},
"fitBboxToLayers": {
- "title": "Bboxãã¬ã€ã€ãŒã«åããã",
- "desc": "衚瀺ã¬ã€ã€ãŒã«åãããŠçæå¢çããã¯ã¹ãèªåçã«èª¿æŽããŸã"
+ "title": "ããŠã³ãã£ã³ã°ããã¯ã¹ãã¬ã€ã€ãŒçŸ€ã«åããã",
+ "desc": "衚瀺ãããŠããã¬ã€ã€ãŒã«åãããŠçæããŠã³ãã£ã³ã°ããã¯ã¹ãèªåçã«èª¿æŽããŸã"
},
"fitBboxToMasks": {
- "title": "Bboxããã¹ã¯ã«ãã£ããããã",
- "desc": "ç®ã«èŠããã€ã³ãã€ã³ããã¹ã¯ã«åãããŠçæå¢çããã¯ã¹ãèªåçã«èª¿æŽããŸã"
+ "title": "ããŠã³ãã£ã³ã°ããã¯ã¹ããã¹ã¯ã«ãã£ããããã",
+ "desc": "å¯èŠã®ã€ã³ãã€ã³ããã¹ã¯ã«åãããŠçæããŠã³ãã£ã³ã°ããã¯ã¹ãèªåçã«èª¿æŽããŸã"
},
"toggleBbox": {
- "title": "Bboxã®è¡šç€º/é衚瀺ãåãæ¿ãã",
- "desc": "çæå¢çããã¯ã¹ãé衚瀺ãŸãã¯è¡šç€ºãã"
+ "title": "ããŠã³ãã£ã³ã°ããã¯ã¹ã®è¡šç€º/é衚瀺ãåãæ¿ãã",
+ "desc": "çæããŠã³ãã£ã³ã°ããã¯ã¹ãé衚瀺ãŸãã¯è¡šç€ºãã"
},
"applySegmentAnything": {
- "title": "äœã§ãã»ã°ã¡ã³ãåãé©çšãã",
- "desc": "çŸåšã®ãäœã§ãã»ã°ã¡ã³ãããã¹ã¯ãé©çšããŸãã",
+ "title": "Segment Anythingãé©çšãã",
+ "desc": "çŸåšã®Segment Anythingãã¹ã¯ãé©çšããŸãã",
"key": "å
¥å"
},
"cancelSegmentAnything": {
"title": "ã»ã°ã¡ã³ãããã£ã³ã»ã«",
- "desc": "çŸåšã®ãäœã§ãã»ã°ã¡ã³ããæäœããã£ã³ã»ã«ããŸãã",
+ "desc": "çŸåšã®Segment Anythingæäœããã£ã³ã»ã«ããŸãã",
"key": "ãšã¹ã±ãŒã"
}
},
@@ -468,8 +468,8 @@
"title": "ãã£ã³ãã¹ã¿ããéžæ"
},
"selectUpscalingTab": {
- "desc": "ã¢ããã¹ã±ãŒãªã³ã°ã¿ããéžæããŸãã",
- "title": "ã¢ããã¹ã±ãŒãªã³ã°ã¿ããéžæ"
+ "desc": "ã¢ããã¹ã±ãŒã«ã¿ããéžæããŸãã",
+ "title": "ã¢ããã¹ã±ãŒã«ã¿ããéžæ"
},
"toggleRightPanel": {
"desc": "å³ããã«ã衚瀺ãŸãã¯é衚瀺ã",
@@ -504,7 +504,7 @@
"desc": "ã«ãŒãœã«ãããžãã£ãããã³ããæ¬ã«ç§»åããŸãã"
},
"promptHistoryPrev": {
- "title": "å±¥æŽã®åã®ããã³ãã",
+ "title": "ãã¹ããªãŒã®ä»¥åã®ããã³ãã",
"desc": "ããã³ããã«ãã©ãŒã«ã¹ãããå Žåã¯ãå±¥æŽå
ã®åã®ïŒå€ãïŒããã³ããã«ç§»åããŸãã"
},
"promptHistoryNext": {
@@ -636,9 +636,9 @@
"controlLora": "ã³ã³ãããŒã«LoRA",
"triggerPhrases": "ããªã¬ãŒãã¬ãŒãº",
"t5Encoder": "T5ãšã³ã³ãŒããŒ",
- "textualInversions": "ããã¹ãå転",
+ "textualInversions": "Textual Inversions",
"fluxRedux": "FLUX ãªããã¯ã¹",
- "installQueue": "ãã¥ãŒãã€ã³ã¹ããŒã«",
+ "installQueue": "ã€ã³ã¹ããŒã«é²æç¶æ³",
"noMatchingModels": "ãããããã¢ãã«ããããŸãã",
"noDefaultSettings": "ãã®ã¢ãã«ã«ã¯æ§æãããããã©ã«ãèšå®ããããŸãã.ããã©ã«ãèšå®ã远å ããããã«ã¢ãã«ãããŒãžã£ãŒã«ã¢ã¯ã»ã¹ããŠãã ãã.",
"usingDefaultSettings": "ã¢ãã«ã®ããã©ã«ãèšå®ã䜿çšãã",
@@ -651,7 +651,7 @@
"main": "ã¡ã€ã³",
"defaultSettings": "ããã©ã«ãèšå®",
"deleteModelImage": "ã¢ãã«ç»åãåé€",
- "hfTokenInvalid": "ãã®ã³ã°ãã§ã€ã¹ããŒã¯ã³ãç¡å¹ãŸãã¯èŠã€ãããŸãã",
+ "hfTokenInvalid": "HuggingFaceããŒã¯ã³ãç¡å¹ãŸãã¯èŠã€ãããŸãã",
"hfForbiddenErrorMessage": "ãªããžããªã«ã¢ã¯ã»ã¹ããããšãå§ããŸã.ææè
ã¯ããŠã³ããŒãã«ãããå©çšèŠçŽãžã®åæãèŠæ±ããå ŽåããããŸã.",
"noModelsInstalled": "ã€ã³ã¹ããŒã«ãããŠããã¢ãã«ããããŸãã",
"pathToConfig": "èšå®ãžã®ãã¹",
@@ -665,8 +665,8 @@
"installRepo": "ãªããžããªãã€ã³ã¹ããŒã«",
"localOnly": "ããŒã«ã«ã®ã¿",
"huggingFaceHelper": "ããã€ãã®ã¢ãã«ããã®ãªããžããªã§èŠã€ãã£ãå ŽåïŒ1ã€ãéžæããŠã€ã³ã¹ããŒã«ããããã«æ±ããããŸã.",
- "hfTokenInvalidErrorMessage": "ãã®ã³ã°ãã§ã€ã¹ããŒã¯ã³ãç¡å¹ãŸãã¯èŠã€ãããŸãã.",
- "hfTokenRequired": "æå¹ãªãã®ã³ã°ãã§ã€ã¹ããŒã¯ã³ãå¿
èŠãªã¢ãã«ãããŠã³ããŒãããããšããŠããŸã.",
+ "hfTokenInvalidErrorMessage": "HuggingFaceããŒã¯ã³ãç¡å¹ãŸãã¯èŠã€ãããŸããã",
+ "hfTokenRequired": "æå¹ãªHuggingFaceããŒã¯ã³ãå¿
èŠãªã¢ãã«ãããŠã³ããŒãããããšããŠããŸãã",
"hfTokenInvalidErrorMessage2": "æŽæ°ããŠãã ãã ",
"modelImageDeleted": "ã¢ãã«ç»ååé€",
"repoVariant": "ãªããžããªããªã¢ã³ã",
@@ -679,17 +679,17 @@
"urlOrLocalPath": "URLãããŒã«ã«ãã¹",
"clipLEmbed": "ã¯ãªãã-L åã蟌ã¿",
"defaultSettingsSaved": "ããã©ã«ãèšå®ãä¿åããŸãã",
- "hfTokenUnableToVerify": "ãã®ã³ã°ãã§ã€ã¹ããŒã¯ã³ã確èªã§ããŸãã",
- "hfForbidden": "ãã®ãã®ã³ã°ãã§ã€ã¹ã¢ãã«ã«ã¢ã¯ã»ã¹ã§ããŸãã",
- "hfTokenLabel": "ãã®ã³ã°ãã§ã€ã¹ããŒã¯ã³(ããã€ãã®ã¢ãã«ã«å¿
èŠ)",
+ "hfTokenUnableToVerify": "HuggingFaceããŒã¯ã³ã確èªã§ããŸãã",
+ "hfForbidden": "ãã®HuggingFaceã¢ãã«ã«ã¢ã¯ã»ã¹ã§ããŸãã",
+ "hfTokenLabel": "HuggingFaceããŒã¯ã³(ããã€ãã®ã¢ãã«ã«å¿
èŠ)",
"noModelSelected": "ã¢ãã«ãéžæãããŠããŸãã",
"prune": "é€å»",
- "hfTokenHelperText": "ããã€ãã®ã¢ãã«ã«ãã®ã³ã°ãã§ã€ã¹ããŒã¯ã³ãå¿
èŠã§ã.ãããã¯ãªãã¯ããŠããªãã®ããŒã¯ã³ãäœæããŠãã ãã.",
+ "hfTokenHelperText": "ããã€ãã®ã¢ãã«ã«HuggingFaceããŒã¯ã³ãå¿
èŠã§ãããããã¯ãªãã¯ããŠããªãã®ããŒã¯ã³ãäœæããŠãã ããã",
"starterBundleHelpText": "ã¡ã€ã³ã¢ãã«ïŒã³ã³ãããŒã«ãããïŒIPã¢ããã¿ãŒãªã©ïŒããŒã¹ã¢ãã«ããå§ããã®ã«å¿
èŠãªãã¹ãŠã®ã¢ãã«ãç°¡åã«ã€ã³ã¹ããŒã«ã§ããŸã.ãã³ãã«ãéžæãããšïŒãã§ã«ã€ã³ã¹ããŒã«ãããŠããã¢ãã«ã¯ã¹ããããããŸã.",
"inplaceInstallDesc": "ãã¡ã€ã«ãç§»åããã«ã¢ãã«ãã€ã³ã¹ããŒã«ããŸã.ãã®ã¢ãã«ã䜿ã£ããšããå
ã®å ŽæããããŒããããŸã.å©çšã§ããªãå Žåãã¢ãã«ãã¡ã€ã«ã¯Invoke管çã¢ãã«ãã£ã¬ã¯ããªã«ã€ã³ã¹ããŒã«ããŠããéã«ç§»åãããŸãã",
- "hfTokenUnableToVerifyErrorMessage": "ãã®ã³ã°ãã§ã€ã¹ããŒã¯ã³ã確èªã§ããŸãã.ãããã¯ãŒã¯ã«ãããšã©ãŒã®å¯èœæ§ããããŸã.åŸã»ã©ãã©ã€ããŠãã ãã.",
+ "hfTokenUnableToVerifyErrorMessage": "HuggingFaceããŒã¯ã³ã確èªã§ããŸããããããã¯ãŒã¯ã«ãããšã©ãŒã®å¯èœæ§ããããŸããåŸã»ã©ãã©ã€ããŠãã ããã",
"restoreDefaultSettings": "ã¯ãªãã¯ãããšã¢ãã«ã®ããã©ã«ãèšå®ã䜿çšãããŸã.",
- "hfTokenSaved": "ãã®ã³ã°ãã§ã€ã¹ããŒã¯ã³ãä¿åããŸãã",
+ "hfTokenSaved": "HuggingFaceããŒã¯ã³ãä¿åããŸãã",
"imageEncoderModelId": "ç»åãšã³ã³ãŒããŒã¢ãã«ID",
"includesNModels": "{{n}}åã®ã¢ãã«ãšãããã®äŸåé¢ä¿ãå«ã¿ãŸãã",
"learnMoreAboutSupportedModels": "ç§ãã¡ã®ãµããŒãããŠããã¢ãã«ã«ã€ããŠæŽã«åŠã¶",
@@ -711,7 +711,7 @@
"modelPickerFallbackNoModelsInstalled2": "ã¢ãã«ãããŒãžã£ãŒ ã«ã¢ã¯ã»ã¹ããŠã¢ãã«ãã€ã³ã¹ããŒã«ããŠãã ãã.",
"modelPickerFallbackNoModelsInstalled": "ã¢ãã«ãã€ã³ã¹ããŒã«ãããŠããŸãã.",
"manageModels": "ã¢ãã«ç®¡ç",
- "hfTokenReset": "ãã®ã³ã°ãã§ã€ã¹ããŒã¯ã³ãªã»ãã",
+ "hfTokenReset": "HuggingFaceããŒã¯ã³ããªã»ãã",
"relatedModels": "é¢é£ã®ããã¢ãã«",
"installedModelsCount": "{{total}} ã¢ãã«ã®ãã¡ {{installed}} åãã€ã³ã¹ããŒã«ãããŠããŸãã",
"allNModelsInstalled": "{{count}} åã®ã¢ãã«ããã¹ãŠã€ã³ã¹ããŒã«ãããŠããŸã",
@@ -719,7 +719,7 @@
"nAlreadyInstalled": "{{count}} åãã§ã«ã€ã³ã¹ããŒã«ãããŠããŸã",
"bundleAlreadyInstalled": "ãã³ãã«ããã§ã«ã€ã³ã¹ããŒã«ãããŠããŸã",
"bundleAlreadyInstalledDesc": "{{bundleName}} ãã³ãã«å
ã®ãã¹ãŠã®ã¢ãã«ã¯ãã§ã«ã€ã³ã¹ããŒã«ãããŠããŸãã",
- "launchpadTab": "ã©ã³ãããã",
+ "launchpadTab": "ããŒã³ãããã",
"launchpad": {
"welcome": "ã¢ãã«ãããžã¡ã³ããžãããã",
"description": "Invoke ãã©ãããã©ãŒã ã®ã»ãšãã©ã®æ©èœãå©çšããã«ã¯ãã¢ãã«ã®ã€ã³ã¹ããŒã«ãå¿
èŠã§ããæåã€ã³ã¹ããŒã«ãªãã·ã§ã³ããéžæããããå³éžãããã¹ã¿ãŒã¿ãŒã¢ãã«ãã芧ãã ããã",
@@ -742,7 +742,10 @@
"installBundleMsg2": "ãã®ãã³ãã«ã§ã¯ã次㮠{{count}} ã¢ãã«ãã€ã³ã¹ããŒã«ãããŸã:",
"ipAdapters": "IPã¢ããã¿ãŒ",
"showOnlyRelatedModels": "é¢é£ããŠãã",
- "starterModelsInModelManager": "ã¹ã¿ãŒã¿ãŒã¢ãã«ã¯ã¢ãã«ãããŒãžã£ãŒã«ãããŸã"
+ "starterModelsInModelManager": "ã¹ã¿ãŒã¿ãŒã¢ãã«ã¯ã¢ãã«ãããŒãžã£ãŒã«ãããŸã",
+ "actions": "äžæ¬æäœ",
+ "selectAll": "å
šãŠéžæ",
+ "deselectAll": "å
šãŠéžæè§£é€"
},
"parameters": {
"images": "ç»å",
@@ -752,7 +755,7 @@
"seed": "ã·ãŒãå€",
"shuffle": "ã·ã£ããã«",
"strength": "匷床",
- "upscaling": "ã¢ããã¹ã±ãŒãªã³ã°",
+ "upscaling": "ã¢ããã¹ã±ãŒã«",
"scale": "ã¹ã±ãŒã«",
"scaleBeforeProcessing": "åŠçåã®ã¹ã±ãŒã«",
"scaledWidth": "å¹
ã®ã¹ã±ãŒã«",
@@ -794,10 +797,10 @@
"systemDisconnected": "ã·ã¹ãã ãåæãããŸãã",
"canvasIsTransforming": "ãã£ã³ãã¹ãããžãŒç¶æ
(倿)",
"canvasIsRasterizing": "ãã£ã³ãã¹ãããžãŒç¶æ
(ã©ã¹ã¿ã©ã€ãº)",
- "modelIncompatibleBboxHeight": "Bboxã®é«ãã¯{{height}}ã§ããïŒ{{model}}ã¯{{multiple}}ã®åæ°ãå¿
èŠã§ã",
- "modelIncompatibleScaledBboxHeight": "bboxã®é«ãã¯{{height}}ã§ããïŒ{{model}}ã¯{{multiple}}ã®åæ°ãå¿
èŠã§ã",
- "modelIncompatibleBboxWidth": "Bboxã®å¹
ã¯{{width}}ã§ãã, {{model}}ã¯{{multiple}}ã®åæ°ãå¿
èŠã§ã",
- "modelIncompatibleScaledBboxWidth": "bboxã®å¹
ã¯{{width}}ã§ããïŒ{{model}}ã¯{{multiple}}ã®åæ°ãå¿
èŠã§ã",
+ "modelIncompatibleBboxHeight": "ããŠã³ãã£ã³ã°ããã¯ã¹ã®é«ãã¯{{height}}ã§ããïŒ{{model}}ã¯{{multiple}}ã®åæ°ãå¿
èŠã§ã",
+ "modelIncompatibleScaledBboxHeight": "ããŠã³ãã£ã³ã°ããã¯ã¹ã®é«ãã¯{{height}}ã§ããïŒ{{model}}ã¯{{multiple}}ã®åæ°ãå¿
èŠã§ã",
+ "modelIncompatibleBboxWidth": "ããŠã³ãã£ã³ã°ããã¯ã¹ã®å¹
ã¯{{width}}ã§ãã, {{model}}ã¯{{multiple}}ã®åæ°ãå¿
èŠã§ã",
+ "modelIncompatibleScaledBboxWidth": "ããŠã³ãã£ã³ã°ããã¯ã¹ã®å¹
ã¯{{width}}ã§ããïŒ{{model}}ã¯{{multiple}}ã®åæ°ãå¿
èŠã§ã",
"canvasIsSelectingObject": "ãã£ã³ãã¹ãããžãŒç¶æ
(ãªããžã§ã¯ãã®éžæ)",
"noFLUXVAEModelSelected": "FLUXçæã«VAEã¢ãã«ãéžæãããŠããŸãã",
"noT5EncoderModelSelected": "FLUXçæã«T5ãšã³ã³ãŒãã¢ãã«ãéžæãããŠããŸãã",
@@ -806,10 +809,10 @@
"promptExpansionResultPending": "ããã³ããæ¡åŒµçµæãåãå
¥ãããç Žæ£ããŠãã ãã",
"emptyBatches": "空ã®ããã",
"noStartingFrameImage": "éå§ãã¬ãŒã ç»åããããŸãã",
- "fluxModelIncompatibleBboxWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16)ãbboxã®å¹
ã¯{{width}}ã§ã",
- "fluxModelIncompatibleBboxHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16)ãbboxã®é«ãã¯{{height}}ã§ã",
- "fluxModelIncompatibleScaledBboxWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16)ãã¹ã±ãŒã«ãããbboxã®å¹
ã¯{{width}}ã§ã",
- "fluxModelIncompatibleScaledBboxHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16)ãã¹ã±ãŒã«ããã bbox ã®é«ã㯠{{height}} ã§ã",
+ "fluxModelIncompatibleBboxWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16)ãããŠã³ãã£ã³ã°ããã¯ã¹ã®å¹
ã¯{{width}}ã§ã",
+ "fluxModelIncompatibleBboxHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16)ãããŠã³ãã£ã³ã°ããã¯ã¹ã®é«ãã¯{{height}}ã§ã",
+ "fluxModelIncompatibleScaledBboxWidth": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16)ãã¹ã±ãŒã«ãããããŠã³ãã£ã³ã°ããã¯ã¹ã®å¹
ã¯{{width}}ã§ã",
+ "fluxModelIncompatibleScaledBboxHeight": "$t(parameters.invoke.fluxRequiresDimensionsToBeMultipleOf16)ãã¹ã±ãŒã«ãããããŠã³ãã£ã³ã°ããã¯ã¹ã®é«ã㯠{{height}} ã§ã",
"incompatibleLoRAs": "äºææ§ã®ãªã LoRA ã远å ãããŸãã"
},
"aspect": "瞊暪æ¯",
@@ -818,7 +821,7 @@
"sendToUpscale": "ã¢ããã¹ã±ãŒã©ãŒã«è»¢é",
"useSize": "ãµã€ãºã䜿çš",
"postProcessing": "ãã¹ãããã»ã¹ (Shift + U)",
- "denoisingStrength": "ãã€ãºé€å»åŒ·åºŠ",
+ "denoisingStrength": "é€å»ãã€ãºåŒ·åºŠ",
"recallMetadata": "ã¡ã¿ããŒã¿ãå䜿çš",
"copyImage": "ç»åãã³ããŒ",
"positivePromptPlaceholder": "ããžãã£ãããã³ãã",
@@ -834,7 +837,7 @@
"imageFit": "åæç»åãåºåãµã€ãºã«åããã",
"setToOptimalSizeTooLarge": "$t(parameters.setToOptimalSize) (ãããã倧ããããŸã)",
"coherenceEdgeSize": "ãšããžãµã€ãº",
- "swapDimensions": "ã¹ã¯ããæ¬¡å
",
+ "swapDimensions": "瞊暪ãµã€ãºãå
¥ãæ¿ã",
"controlNetControlMode": "å¶åŸ¡ã¢ãŒã",
"infillColorValue": "å¡ãã€ã¶ãè²",
"coherenceMinDenoise": "æå°ãã€ãºé€å»",
@@ -845,7 +848,7 @@
"infillMethod": "å
å¡«æ³",
"patchmatchDownScaleSize": "ããŠã³ã¹ã±ãŒã«",
"boxBlur": "ããã¯ã¹ãŒãã",
- "remixImage": "ãªããã¯ã¹ç»å",
+ "remixImage": "ç»åããªããã¯ã¹",
"processImage": "ããã»ã¹ç»å",
"useCpuNoise": "CPUãã€ãºã®äœ¿çš",
"staged": "ã¹ããŒãž",
@@ -997,8 +1000,8 @@
"noVisibleMasksDesc": "å°ãªããšã1ã€ã®ã€ã³ãã€ã³ããã¹ã¯ãäœæãŸãã¯æå¹ã«ããŠå転ããŸã",
"noInpaintMaskSelected": "ã€ã³ãã€ã³ããã¹ã¯ãéžæãããŠããŸãã",
"noInpaintMaskSelectedDesc": "å転ããã€ã³ãã€ã³ããã¹ã¯ãéžæ",
- "invalidBbox": "ç¡å¹ãªå¢çããã¯ã¹",
- "invalidBboxDesc": "å¢çããã¯ã¹ã«æå¹ãªå¯žæ³ããããŸãã"
+ "invalidBbox": "ç¡å¹ãªããŠã³ãã£ã³ã°ããã¯ã¹",
+ "invalidBboxDesc": "ããŠã³ãã£ã³ã°ããã¯ã¹ã®å¯žæ³ãæå¹ã§ã¯ãããŸãã"
},
"accessibility": {
"invokeProgressBar": "鲿ããŒ",
@@ -1179,7 +1182,7 @@
"cannotConnectInputToInput": "å
¥åããå
¥åã«ã¯æ¥ç¶ã§ããŸãã",
"cannotConnectOutputToOutput": "åºåããåºåã«ã¯æ¥ç¶ã§ããŸãã",
"cannotConnectToSelf": "èªèº«ã®ããŒãã«ã¯æ¥ç¶ã§ããŸãã",
- "colorCodeEdges": "ã«ã©ãŒã³ãŒããšããž",
+ "colorCodeEdges": "ãšããžã®ã«ã©ãŒå",
"loadingNodes": "ããŒããèªã¿èŸŒã¿äž...",
"scheduler": "ã¹ã±ãžã¥ãŒã©ãŒ",
"version": "ããŒãžã§ã³",
@@ -1197,7 +1200,7 @@
"enum": "Enum",
"arithmeticSequence": "çå·®æ°å",
"linearDistribution": "ç·åœ¢ååž",
- "animatedEdges": "ã¢ãã¡ãŒã·ã§ã³ãšããž",
+ "animatedEdges": "ãšããžã®ã¢ãã¡ãŒã·ã§ã³",
"uniformRandomDistribution": "äžæ§ã©ã³ãã ååž",
"noBatchGroup": "ã°ã«ãŒããªã",
"parseString": "æååã®è§£æ",
@@ -1232,7 +1235,7 @@
"unableToUpdateNode": "ããŒãã¢ããããŒã倱æ:ããŒã {{node}} ã®ã¿ã€ã {{type}} (åé€ãåçæãå¿
èŠãããããŸãã)",
"deletedInvalidEdge": "ç¡å¹ãªãšããžãåé€ããŸãã{{source}} -> {{target}}",
"collectionFieldType": "{{name}} (ã³ã¬ã¯ã·ã§ã³)",
- "colorCodeEdgesHelp": "æ¥ç¶ããããã£ãŒã«ãã«ããã«ã©ãŒã³ãŒããšããž",
+ "colorCodeEdgesHelp": "æ¥ç¶ããããã£ãŒã«ãçš®ããšã«ãšããžãã«ã©ãŒå",
"showEdgeLabelsHelp": "ãšããžã®ã©ãã«ãè¡šç€ºïŒæ¥ç¶ãããŠããããŒãã瀺ã",
"sourceNodeFieldDoesNotExist": "ç¡å¹ãªãšããž:ãœãŒã¹/ã¢ãŠãããããã£ãŒã«ã{{node}}.{{field}}ãååšããŸãã",
"deletedMissingNodeFieldFormElement": "äžè¶³ããŠãããã©ãŒã ãã£ãŒã«ããåé€ããŸãã: ããŒã {{nodeId}} ãã£ãŒã«ã {{fieldName}}",
@@ -1602,13 +1605,13 @@
"compositingMaskAdjustments": {
"heading": "ãã¹ã¯èª¿æŽ",
"paragraphs": [
- "ãã¹ã¯ã調æŽãã."
+ "ãã¹ã¯ã調æŽãã"
]
},
"compositingCoherenceMinDenoise": {
"paragraphs": [
- "ã³ããŒã¬ã³ã¹ã¢ãŒãã®æå°ãã€ãºé€å»åŒ·åºŠ",
- "ã€ã³ãã€ã³ãã£ã³ã°ãŸãã¯ã¢ãŠããã€ã³ãã£ã³ã°æã®ã³ããŒã¬ã³ã¹é åã®æå°ãã€ãºé€å»åŒ·åºŠ"
+ "ã³ããŒã¬ã³ã¹ã¢ãŒãã®æå°é€å»ãã€ãºåŒ·åºŠ",
+ "ã€ã³ãã€ã³ãã»ã¢ãŠããã€ã³ãæã®ã³ããŒã¬ã³ã¹é åã®æå°é€å»ãã€ãºåŒ·åºŠ"
],
"heading": "æå°ãã€ãºé€å»"
},
@@ -1691,7 +1694,7 @@
"ããšãã°, ããã³ããã 5 ã€ããå Žå, åç»åã¯åãã·ãŒãã䜿çšããŸã.",
"ãç»åããšãã§ã¯, ç»åããšã«åºæã®ã·ãŒãå€ã䜿çšãããŸã. ããã«ãããããå€ãã®ããªãšãŒã·ã§ã³ãåŸãããŸã."
],
- "heading": "ã·ãŒãè¡å"
+ "heading": "ã·ãŒãã®æå"
},
"imageFit": {
"paragraphs": [
@@ -1730,7 +1733,7 @@
"optimizedDenoising": {
"heading": "ã€ã¡ãŒãžtoã€ã¡ãŒãžã®æé©å",
"paragraphs": [
- "ãã€ã¡ãŒãžtoã€ã¡ãŒãžãæé©åããæå¹ã«ãããšãFluxã¢ãã«ãçšããç»åé倿ããã³ã€ã³ãã€ã³ãã£ã³ã°å€æã«ãããŠãããæ®µéçãªãã€ãºé€å»åŒ·åºŠã¹ã±ãŒã«ãé©çšãããŸãããã®èšå®ã«ãããç»åã«é©çšãããå€åéãå¶åŸ¡ããèœåãåäžããŸãããæšæºã®ãã€ãºé€å»åŒ·åºŠã¹ã±ãŒã«ã䜿çšãããå Žåã¯ãªãã«ããããšãã§ããŸãããã®èšå®ã¯çŸåšèª¿æŽäžã§ãããŒã¿çã§ãã"
+ "ãã€ã¡ãŒãžtoã€ã¡ãŒãžãæé©åããæå¹ã«ãããšãFluxã¢ãã«ãçšããç»åé倿ããã³ã€ã³ãã€ã³ã倿ã«ãããŠãããæ®µéçãªé€å»ãã€ãºåŒ·åºŠã¹ã±ãŒã«ãé©çšãããŸãããã®èšå®ã«ãããç»åã«é©çšãããå€åéãå¶åŸ¡ããèœåãåäžããŸãããæšæºã®é€å»ãã€ãºåŒ·åºŠã¹ã±ãŒã«ã䜿çšãããå Žåã¯ãªãã«ããããšãã§ããŸãããã®èšå®ã¯çŸåšèª¿æŽäžã§ãããŒã¿çã§ãã"
]
},
"refinerPositiveAestheticScore": {
@@ -1756,8 +1759,8 @@
"refinerModel": {
"heading": "ãªãã¡ã€ããŒã¢ãã«",
"paragraphs": [
- "çæããã»ã¹ã®ç²Ÿè£œéšåã§äœ¿çšãããã¢ãã«ã",
- "äžä»£ã¢ãã«ã«äŒŒãŠããŸãã"
+ "çæããã»ã¹ã®ãªãã¡ã€ããŒéšåã§äœ¿çšãããã¢ãã«ã",
+ "çæã¢ãã«ã«äŒŒãŠããŸãã"
]
},
"refinerCfgScale": {
@@ -1833,7 +1836,7 @@
"tileOverlap": {
"heading": "ã¿ã€ã«ãªãŒããŒã©ãã",
"paragraphs": [
- "ã¢ããã¹ã±ãŒãªã³ã°æã®é£æ¥ããã¿ã€ã«ã®éãªãå
·åãå¶åŸ¡ããŸããéãªãå
·åã®å€ã倧ãããããšã¿ã€ã«éã®ç¶ãç®ãèŠãã«ãããªããŸãããã¡ã¢ãªäœ¿çšéã¯å¢å ããŸãã",
+ "ã¢ããã¹ã±ãŒã«æã®é£æ¥ããã¿ã€ã«ã®éãªãå
·åãå¶åŸ¡ããŸããéãªãå
·åã®å€ã倧ãããããšã¿ã€ã«éã®ç¶ãç®ãèŠãã«ãããªããŸãããã¡ã¢ãªäœ¿çšéã¯å¢å ããŸãã",
"ããã©ã«ãå€ã® 128 ã¯ã»ãšãã©ã®å Žåã«é©ããŠããŸãããç¹å®ã®ããŒãºãã¡ã¢ãªã®å¶çŽã«åºã¥ããŠèª¿æŽã§ããŸãã"
]
}
@@ -1881,8 +1884,8 @@
"resultTitle": "ããã³ããæ¡åŒµå®äº",
"resultSubtitle": "æ¡åŒµããã³ããã®åŠçæ¹æ³ãéžæããŸã:",
"insert": "æ¿å
¥",
- "noPromptHistory": "ããã³ããå±¥æŽãèšé²ãããŠããŸããã",
- "noMatchingPrompts": "å±¥æŽã«ãããããããã³ããããããŸããã",
+ "noPromptHistory": "ããã³ãããã¹ããªãŒãèšé²ãããŠããŸããã",
+ "noMatchingPrompts": "ãããããããã³ããããã¹ããªãŒã«ãããŸããã",
"toSwitchBetweenPrompts": "ããã³ãããåãæ¿ããŸãã"
},
"ui": {
@@ -1894,7 +1897,7 @@
"gallery": "ã®ã£ã©ãªãŒ",
"workflowsTab": "$t(ui.tabs.workflows) $t(common.tab)",
"modelsTab": "$t(ui.tabs.models) $t(common.tab)",
- "upscaling": "ã¢ããã¹ã±ãŒãªã³ã°",
+ "upscaling": "ã¢ããã¹ã±ãŒã«",
"upscalingTab": "$t(ui.tabs.upscaling) $t(common.tab)",
"generate": "çæ"
},
@@ -1904,7 +1907,7 @@
"scale": "ã¹ã±ãŒã«",
"helpText": {
"promptAdvice": "ã¢ããã¹ã±ãŒã«ããéã¯ãåªäœãšã¹ã¿ã€ã«ã説æããããã³ããã䜿çšããŠãã ãããç»åå
ã®å
·äœçãªã³ã³ãã³ãã®è©³çްã説æããããšã¯é¿ããŠãã ããã",
- "styleAdvice": "ã¢ããã¹ã±ãŒãªã³ã°ã¯ãç»åã®å
šäœçãªã¹ã¿ã€ã«ã«æé©ã§ãã"
+ "styleAdvice": "ã¢ããã¹ã±ãŒã«ã¯ãç»åã®å
šäœçãªã¹ã¿ã€ã«ã«æé©ã§ãã"
},
"uploadImage": {
"title": "ã¢ããã¹ã±ãŒã«çšã®ç»åãã¢ããããŒããã",
@@ -1957,19 +1960,19 @@
"browseAndLoadWorkflows": "æ¢åã®ã¯ãŒã¯ãããŒãåç
§ããŠèªã¿èŸŒã",
"addStyleRef": {
"title": "ã¹ã¿ã€ã«åç
§ã远å ãã",
- "description": "ç»åã远å ããŠå€èгã転éããŸãã"
+ "description": "å€èгãåç
§ããããã®ç»åã远å ããŸãããã"
},
"editImage": {
"title": "ç»åãç·šé",
- "description": "çµã蟌ãããã«ç»åã远å ããŸãã"
+ "description": "ãªãã¡ã€ã³ããç»åã远å ããŸãããã"
},
"generateFromText": {
"title": "ããã¹ãããçæ",
- "description": "ããã³ãããå
¥åããŠåŒã³åºããŸãã"
+ "description": "ããã³ãããå
¥åããŠçæããŸãããã"
},
"useALayoutImage": {
"title": "ã¬ã€ã¢ãŠãç»åã䜿çš",
- "description": "æ§æãå¶åŸ¡ããããã«ç»åã远å ããŸãã"
+ "description": "æ§å³ãå¶åŸ¡ããããã®ç»åã远å ããŸãããã"
},
"generate": {
"canvasCalloutTitle": "ç»åãããã«çްããå¶åŸ¡ãç·šéãå埩ãããã§ãã?",
@@ -1997,13 +2000,13 @@
"canvasGroup": "ãã£ã³ãã¹",
"saveToGalleryGroup": "ã®ã£ã©ãªãŒã«ä¿å",
"saveCanvasToGallery": "ãã£ã³ãã¹ãã®ã£ã©ãªãŒã«ä¿å",
- "saveBboxToGallery": "Bããã¯ã¹ãã®ã£ã©ãªãŒã«ä¿å",
+ "saveBboxToGallery": "ããŠã³ãã£ã³ã°ããã¯ã¹ãã®ã£ã©ãªãŒã«ä¿å",
"newControlLayer": "æ°èŠã³ã³ãããŒã«ã¬ã€ã€ãŒ",
"newRasterLayer": "æ°èŠã©ã¹ã¿ãŒã¬ã€ã€ãŒ",
"newInpaintMask": "æ°èŠã€ã³ãã€ã³ããã¹ã¯",
"copyToClipboard": "ã¯ãªããããŒãã«ã³ããŒ",
"copyCanvasToClipboard": "ãã£ã³ãã¹ãã¯ãªããããŒãã«ã³ããŒ",
- "copyBboxToClipboard": "Bããã¯ã¹ãã¯ãªããããŒãã«ã³ããŒ",
+ "copyBboxToClipboard": "ããŠã³ãã£ã³ã°ããã¯ã¹ãã¯ãªããããŒãã«ã³ããŒ",
"newResizedControlLayer": "æ°ãããµã€ãºå€æŽãããã³ã³ãããŒã«ã¬ã€ã€ãŒ"
},
"regionalGuidance": "é åã¬ã€ãã³ã¹",
@@ -2030,7 +2033,7 @@
"rectangle": "ç©åœ¢",
"move": "ç§»å",
"eraser": "æ¶ããŽã ",
- "bbox": "Bbox",
+ "bbox": "ããŠã³ãã£ã³ã°ããã¯ã¹",
"view": "ãã¥ãŒ"
},
"saveCanvasToGallery": "ãã£ã³ãã¹ãã®ã£ã©ãªãŒã«ä¿å",
@@ -2064,7 +2067,7 @@
"label": "ã°ãªããã«ã¹ããã"
},
"preserveMask": {
- "label": "ãã¹ã¯ãããé åãä¿æ",
+ "label": "ãã¹ã¯ãããé åãä¿è·",
"alert": "ãã¹ã¯ãããé åã®ä¿å"
},
"isolatedStagingPreview": "åé¢ãããã¹ããŒãžã³ã°ãã¬ãã¥ãŒ",
@@ -2072,10 +2075,10 @@
"isolatedLayerPreview": "åé¢ãããã¬ã€ã€ãŒã®ãã¬ãã¥ãŒ",
"isolatedLayerPreviewDesc": "ãã£ã«ã¿ãªã³ã°ã倿ãªã©ã®æäœãå®è¡ãããšãã«ããã®ã¬ã€ã€ãŒã®ã¿ã衚瀺ãããã©ããã",
"invertBrushSizeScrollDirection": "ãã©ã·ãµã€ãºã®ã¹ã¯ããŒã«å転",
- "pressureSensitivity": "å§åæåºŠ",
+ "pressureSensitivity": "çå§æ€ç¥",
"saveAllImagesToGallery": {
- "label": "ã®ã£ã©ãªãŒã«æ°ããçæãéã",
- "alert": "ãã£ã³ãã¹ãçµç±ãããã®ã£ã©ãªãŒã«æ°ããçæãéã蟌ã"
+ "label": "ã®ã£ã©ãªãŒã«æ°ããçæç»åãéã",
+ "alert": "ãã£ã³ãã¹ãçµç±ãããã®ã£ã©ãªãŒã«æ°ããçæãéã"
}
},
"filter": {
@@ -2093,14 +2096,14 @@
"cancel": "ãã£ã³ã»ã«",
"filters": "ãã£ã«ã¿ãŒ",
"filterType": "ãã£ã«ã¿ãŒã¿ã€ã",
- "autoProcess": "ãªãŒãããã»ã¹",
+ "autoProcess": "èªåã§å®è¡",
"process": "ããã»ã¹",
- "advanced": "ã¢ããã³ã¹ã",
+ "advanced": "詳现èšå®",
"processingLayerWith": "{{type}} ãã£ã«ã¿ãŒã䜿çšããåŠçã¬ã€ã€ãŒã",
"forMoreControl": "ããã«çްããå¶åŸ¡ããã«ã¯ã以äžã®ã詳现èšå®ããã¯ãªãã¯ããŠãã ããã",
"canny_edge_detection": {
- "label": "ãã£ããŒãšããžæ€åº",
- "description": "Canny ãšããžæ€åºã¢ã«ãŽãªãºã ã䜿çšããŠãéžæããã¬ã€ã€ãŒãããšããž ããããçæããŸãã",
+ "label": "ãšããžæ€åºïŒCannyïŒ",
+ "description": "Canny ãšããžæ€åºã¢ã«ãŽãªãºã ã䜿çšããŠãéžæããã¬ã€ã€ãŒããç·ç»ãçæããŸãã",
"low_threshold": "äœéŸå€",
"high_threshold": "é«éŸå€"
},
@@ -2115,8 +2118,8 @@
"scale_factor": "ã¹ã±ãŒã«ä¿æ°"
},
"depth_anything_depth_estimation": {
- "label": "ããã¹ãšãã·ã³ã°",
- "description": "ããã¹ãšãã·ã³ã°ã¢ãã«ã䜿çšããŠãéžæããã¬ã€ã€ãŒããæ·±åºŠããããçæããŸãã",
+ "label": "深床æœåºïŒDepth AnythingïŒ",
+ "description": "Depth Anthingã¢ãã«ã䜿çšããŠãéžæããã¬ã€ã€ãŒããæ·±åºŠããããçæããŸãã",
"model_size": "ã¢ãã«ãµã€ãº",
"model_size_small": "ã¹ã¢ãŒã«",
"model_size_small_v2": "ã¹ã¢ãŒã«v2",
@@ -2124,50 +2127,50 @@
"model_size_large": "ã©ãŒãž"
},
"dw_openpose_detection": {
- "label": "DW ãªãŒãã³ããŒãºæ€åº",
+ "label": "ããŒãºæ€åºïŒDW OpenposeïŒ",
"description": "DW Openpose ã¢ãã«ã䜿çšããŠãéžæããã¬ã€ã€ãŒå
ã®äººéã®ããŒãºãæ€åºããŸãã",
"draw_hands": "æãæã",
"draw_face": "é¡ãæã",
"draw_body": "äœãæã"
},
"hed_edge_detection": {
- "label": "HEDãšããžæ€åº",
- "description": "HED ãšããžæ€åºã¢ãã«ã䜿çšããŠãéžæããã¬ã€ã€ãŒãããšããž ããããçæããŸãã",
+ "label": "ãšããžæ€åºïŒHEDïŒ",
+ "description": "HED ãšããžæ€åºã¢ãã«ã䜿çšããŠãéžæããã¬ã€ã€ãŒããç·ç»ãçæããŸãã",
"scribble": "èœæžã"
},
"lineart_anime_edge_detection": {
- "label": "ç·ç»ã¢ãã¡ã®ãšããžæ€åº",
- "description": "ç·ç»ã¢ãã¡ãšããžæ€åºã¢ãã«ã䜿çšããŠãéžæããã¬ã€ã€ãŒãããšããž ããããçæããŸãã"
+ "label": "ãšããžæ€åºïŒLineart AnimeïŒ",
+ "description": "Lineart Animeãšããžæ€åºã¢ãã«ã䜿çšããŠãéžæããã¬ã€ã€ãŒããç·ç»ãçæããŸãã"
},
"lineart_edge_detection": {
- "label": "ç·ç»ãšããžæ€åº",
- "description": "ç·ç»ãšããžæ€åºã¢ãã«ã䜿çšããŠãéžæããã¬ã€ã€ãŒãããšããž ããããçæããŸãã",
- "coarse": "ç²ã"
+ "label": "ãšããžæ€åºïŒLineartïŒ",
+ "description": "Linartãšããžæ€åºã¢ãã«ã䜿çšããŠãéžæããã¬ã€ã€ãŒããç·ç»ãçæããŸãã",
+ "coarse": "ç²ã"
},
"mediapipe_face_detection": {
- "label": "ã¡ãã£ã¢ãã€ã顿€åº",
- "description": "ã¡ãã£ã¢ãã€ã顿€åºã¢ãã«ã䜿çšããŠãéžæããã¬ã€ã€ãŒå
ã®é¡ãæ€åºããŸãã",
- "max_faces": "ããã¯ã¹ãã§ã€ã¹",
+ "label": "顿€åºïŒMediaPipeïŒ",
+ "description": "MediaPipe顿€åºã¢ãã«ã䜿çšããŠãéžæããã¬ã€ã€ãŒå
ã®é¡ãæ€åºããŸãã",
+ "max_faces": "æå€§é¡æ°",
"min_confidence": "æå°ä¿¡é ŒåºŠ"
},
"mlsd_detection": {
- "label": "ç·åæ€åº",
- "description": "MLSD ç·åæ€åºã¢ãã«ã䜿çšããŠãéžæããã¬ã€ã€ãŒããç·åããããçæããŸãã",
+ "label": "çŽç·æ€åºïŒMLSDïŒ",
+ "description": "MLSD ç·åæ€åºã¢ãã«ã䜿çšããŠãéžæããã¬ã€ã€ãŒããçŽç·éšåãæœåºããŸãã",
"score_threshold": "ã¹ã³ã¢éŸå€",
"distance_threshold": "è·é¢éŸå€"
},
"normal_map": {
- "label": "ããŒãã«ããã",
+ "label": "ããŒãã«ãããæšå®",
"description": "éžæããã¬ã€ã€ãŒããããŒãã«ããããçæããŸãã"
},
"pidi_edge_detection": {
- "label": "PiDiNetãšããžæ€åº",
- "description": "PiDiNet ãšããžæ€åºã¢ãã«ã䜿çšããŠãéžæããã¬ã€ã€ãŒãããšããž ããããçæããŸãã",
+ "label": "ãšããžæ€åºïŒPiDiNetïŒ",
+ "description": "PiDiNet ãšããžæ€åºã¢ãã«ã䜿çšããŠãéžæããã¬ã€ã€ãŒããç·ç»ãçæããŸãã",
"scribble": "èœæžã",
"quantize_edges": "ãšããžãéååãã"
},
"img_blur": {
- "label": "ç»åããŒãã",
+ "label": "ãŒãã",
"description": "éžæããã¬ã€ã€ãŒããŒãããŸãã",
"blur_type": "ãŒããã®çš®é¡",
"blur_radius": "ååŸ",
@@ -2175,7 +2178,7 @@
"box_type": "ããã¯ã¹"
},
"img_noise": {
- "label": "ãã€ãºç»å",
+ "label": "ãã€ãº",
"description": "éžæããã¬ã€ã€ãŒã«ãã€ãºã远å ããŸãã",
"noise_type": "ãã€ãºã®çš®é¡",
"noise_amount": "ç·èš",
@@ -2219,26 +2222,26 @@
"newGlobalReferenceImageError": "ã°ããŒãã«åç
§ã€ã¡ãŒãžã®äœæäžã«åé¡ãçºçããŸãã",
"newRegionalReferenceImageOk": "å°ååç
§ç»åã®äœæ",
"newRegionalReferenceImageError": "å°ååç
§ç»åã®äœæäžã«åé¡ãçºçããŸãã",
- "newControlLayerOk": "å¶åŸ¡ã¬ã€ã€ãŒã®äœæ",
+ "newControlLayerOk": "äœæãããã³ã³ãããŒã«ã¬ã€ã€ãŒ",
"newControlLayerError": "å¶åŸ¡å±€ã®äœæäžã«åé¡ãçºçããŸãã",
"newRasterLayerOk": "ã©ã¹ã¿ãŒã¬ã€ã€ãŒãäœæããŸãã",
"newRasterLayerError": "ã©ã¹ã¿ãŒã¬ã€ã€ãŒã®äœæäžã«åé¡ãçºçããŸãã",
- "pullBboxIntoLayerOk": "Bbox ãã¬ã€ã€ãŒã«ãã«",
- "pullBboxIntoLayerError": "BBox ãã¬ã€ã€ãŒã«ãã«ããéã«åé¡ãçºçããŸãã",
- "pullBboxIntoReferenceImageOk": "Bbox ã ReferenceImage ã«ãã«ãããŸãã",
- "pullBboxIntoReferenceImageError": "BBox ã ReferenceImage ã«ãã«ããéã«åé¡ãçºçããŸãã",
+ "pullBboxIntoLayerOk": "ããŠã³ãã£ã³ã°ããã¯ã¹ãã¬ã€ã€ãŒã«",
+ "pullBboxIntoLayerError": "ããŠã³ãã£ã³ã°ããã¯ã¹ãã¬ã€ã€ãŒã«ããéã«åé¡ãçºçããŸãã",
+ "pullBboxIntoReferenceImageOk": "ããŠã³ãã£ã³ã°ããã¯ã¹ãåç
§ç»åã«ãããŸãã",
+ "pullBboxIntoReferenceImageError": "ããŠã³ãã£ã³ã°ããã¯ã¹ãåç
§ç»åã«ããéã«åé¡ãçºçããŸãã",
"regionIsEmpty": "éžæããé åã¯ç©ºã§ã",
"mergeVisible": "ããŒãžãå¯èŠå",
"mergeVisibleOk": "ããŒãžãããã¬ã€ã€ãŒ",
"mergeVisibleError": "ã¬ã€ã€ãŒã®çµåãšã©ãŒ",
"mergingLayers": "ã¬ã€ã€ãŒã®ããŒãž",
"clearHistory": "å±¥æŽãã¯ãªã¢",
- "bboxOverlay": "BboxãªãŒããŒã¬ã€ã衚瀺",
+ "bboxOverlay": "ããŠã³ãã£ã³ã°ããã¯ã¹ã®ãªãŒããŒã¬ã€ã衚瀺",
"ruleOfThirds": "äžå岿³ã衚瀺",
"newSession": "æ°ããã»ãã·ã§ã³",
"clearCaches": "ãã£ãã·ã¥ãã¯ãªã¢",
"recalculateRects": "é·æ¹åœ¢ãåèšç®ãã",
- "clipToBbox": "ã¹ãããŒã¯ãBboxã«ã¯ãªãã",
+ "clipToBbox": "ã¹ãããŒã¯ãããŠã³ãã£ã³ã°ããã¯ã¹å
ã«å¶é",
"outputOnlyMaskedRegions": "çæãããé åã®ã¿ãåºåãã",
"width": "å¹
",
"autoNegative": "ãªãŒããã¬ãã£ã",
@@ -2284,13 +2287,13 @@
"pasteTo": "貌ãä»ãå
",
"pasteToAssets": "ã¢ã»ãã",
"pasteToAssetsDesc": "ã¢ã»ããã«è²Œãä»ã",
- "pasteToBbox": "Bããã¯ã¹",
- "pasteToBboxDesc": "æ°ããã¬ã€ã€ãŒïŒBboxå
ïŒ",
+ "pasteToBbox": "ããŠã³ãã£ã³ã°ããã¯ã¹",
+ "pasteToBboxDesc": "æ°ããã¬ã€ã€ãŒïŒããŠã³ãã£ã³ã°ããã¯ã¹å
ïŒ",
"pasteToCanvas": "ãã£ã³ãã¹",
"pasteToCanvasDesc": "æ°ããã¬ã€ã€ãŒïŒãã£ã³ãã¹å
ïŒ",
- "transparency": "éææ§",
- "enableTransparencyEffect": "éæå¹æãæå¹ã«ãã",
- "disableTransparencyEffect": "éæå¹æãç¡å¹ã«ãã",
+ "transparency": "éé衚瀺",
+ "enableTransparencyEffect": "éé衚瀺ãæå¹ã«ãã",
+ "disableTransparencyEffect": "éé衚瀺ãç¡å¹ã«ãã",
"hidingType": "{{type}} ãé衚瀺",
"showingType": "{{type}}ã衚瀺",
"showNonRasterLayers": "éã©ã¹ã¿ãŒã¬ã€ã€ãŒã衚瀺 (Shift+H)",
@@ -2301,24 +2304,24 @@
"unlocked": "ããã¯è§£é€",
"deleteSelected": "éžæé
ç®ãåé€",
"replaceLayer": "ã¬ã€ã€ãŒã®çœ®ãæã",
- "pullBboxIntoLayer": "Bboxãã¬ã€ã€ãŒã«åŒã蟌ã",
- "pullBboxIntoReferenceImage": "Bboxãåç
§ç»åã«åã蟌ã",
+ "pullBboxIntoLayer": "ããŠã³ãã£ã³ã°ããã¯ã¹ãã¬ã€ã€ãŒã«",
+ "pullBboxIntoReferenceImage": "ããŠã³ãã£ã³ã°ããã¯ã¹ãåç
§ç»åã«",
"showProgressOnCanvas": "ãã£ã³ãã¹ã«é²æç¶æ³ã衚瀺",
"useImage": "ç»åã䜿ã",
"negativePrompt": "ãã¬ãã£ãããã³ãã",
"beginEndStepPercentShort": "éå§/çµäº %",
- "resetCanvasLayers": "ãã£ã³ãã¹ã¬ã€ã€ãŒããªã»ãã",
+ "resetCanvasLayers": "ãã£ã³ãã¹ãšã¬ã€ã€ãŒããªã»ãã",
"resetGenerationSettings": "çæèšå®ããªã»ãã",
- "controlLayerEmptyState": "ç»åãã¢ããããŒããã®ã£ã©ãªãŒãããã®ã¬ã€ã€ãŒã«ç»åããã©ãã°ãå¢çããã¯ã¹ããã®ã¬ã€ã€ãŒã«ãã«ããŸãã¯ãã£ã³ãã¹ã«æç»ããŠéå§ããŸãã",
- "referenceImageEmptyStateWithCanvasOptions": "éå§ããã«ã¯ãç»åãã¢ããããŒãããããã®ã£ã©ãªãŒãããã®åç
§ç»åã«ç»åããã©ãã°ããããå¢çããã¯ã¹ããã®åç
§ç»åã«åŒã蟌ã¿ãŸãã",
+ "controlLayerEmptyState": "ç»åãã¢ããããŒããã®ã£ã©ãªãŒãããã®ã¬ã€ã€ãŒã«ç»åããã©ãã°ãããŠã³ãã£ã³ã°ããã¯ã¹ããã®ã¬ã€ã€ãŒã«ããããŸãã¯ãã£ã³ãã¹ã«æç»ããŠéå§ããŸãã",
+ "referenceImageEmptyStateWithCanvasOptions": "éå§ããã«ã¯ãç»åãã¢ããããŒãããããã®ã£ã©ãªãŒãããã®åç
§ç»åã«ç»åããã©ãã°ããããããŠã³ãã£ã³ã°ããã¯ã¹ããã®åç
§ç»åã«ããŸãã",
"referenceImageEmptyState": "éå§ããã«ã¯ãç»åãã¢ããããŒãããããã®ã£ã©ãªãŒãããã®åç
§ç»åã«ç»åããã©ãã°ããŸãã",
"imageNoise": "ç»åãã€ãº",
"denoiseLimit": "ãã€ãºé€å»å¶é",
"warnings": {
"problemsFound": "åé¡ãèŠã€ãããŸãã",
"unsupportedModel": "éžæããããŒã¹ã¢ãã«ã§ã¯ã¬ã€ã€ãŒããµããŒããããŠããŸãã",
- "controlAdapterNoModelSelected": "å¶åŸ¡ã¬ã€ã€ãŒã¢ãã«ãéžæãããŠããŸãã",
- "controlAdapterIncompatibleBaseModel": "äºææ§ã®ãªãå¶åŸ¡ã¬ã€ã€ãŒããŒã¹ã¢ãã«",
+ "controlAdapterNoModelSelected": "ã³ã³ãããŒã«ã¬ã€ã€ãŒã®ã¢ãã«ãéžæãããŠããŸãã",
+ "controlAdapterIncompatibleBaseModel": "ã³ã³ãããŒã«ã¬ã€ã€ãŒã®ããŒã¹ã¢ãã«ã«äºææ§ããããŸãã",
"controlAdapterNoControl": "ã³ã³ãããŒã«ãéžæ/æç»ãããŠããŸãã",
"ipAdapterNoModelSelected": "åç
§ç»åã¢ãã«ãéžæãããŠããŸãã",
"ipAdapterIncompatibleBaseModel": "äºææ§ã®ãªãåç
§ç»åããŒã¹ã¢ãã«",
@@ -2329,7 +2332,7 @@
"rgAutoNegativeNotSupported": "éžæããããŒã¹ã¢ãã«ã§ã¯èªååŠå®ã¯ãµããŒããããŠããŸãã",
"rgNoRegion": "é åãæç»ãããŠããŸãã",
"fluxFillIncompatibleWithControlLoRA": "ã³ã³ãããŒã«LoRAã¯FLUX Fillãšäºææ§ããããŸãã",
- "bboxHidden": "å¢çããã¯ã¹ã¯é衚瀺ã§ãïŒShift+O ã§åãæ¿ããŸãïŒ"
+ "bboxHidden": "ããŠã³ãã£ã³ã°ããã¯ã¹ã¯é衚瀺ã§ãïŒShift+O ã§åãæ¿ãïŒ"
},
"errors": {
"unableToFindImage": "ç»åãèŠã€ãããŸãã",
@@ -2370,7 +2373,7 @@
},
"selectObject": {
"selectObject": "ãªããžã§ã¯ããéžæ",
- "pointType": "ãã€ã³ãã¿ã€ã",
+ "pointType": "ç¹ã¿ã€ã",
"invertSelection": "éžæç¯å²ãå転",
"include": "å«ã",
"exclude": "é€å€",
@@ -2384,7 +2387,7 @@
"dragToMove": "ãã€ã³ãããã©ãã°ããŠç§»åããŸã",
"clickToRemove": "ãã€ã³ããã¯ãªãã¯ããŠåé€ããŸã",
"desc": "察象ãªããžã§ã¯ãã1ã€éžæããŸããéžæãå®äºããããé©çš ãã¯ãªãã¯ããŠéžæç¯å²å€ã®ãã¹ãŠãåé€ããããéžæç¯å²ãæ°ããã¬ã€ã€ãŒãšããŠä¿åããŸãã",
- "visualModeDesc": "ããžã¥ã¢ã« ã¢ãŒãã§ã¯ãããã¯ã¹ãšãã€ã³ãã®å
¥åã䜿çšããŠãªããžã§ã¯ããéžæããŸãã",
+ "visualModeDesc": "ããžã¥ã¢ã« ã¢ãŒãã§ã¯ãããã¯ã¹ãšç¹ã®å
¥åã䜿çšããŠãªããžã§ã¯ããéžæããŸãã",
"visualMode1": "ã¯ãªãã¯ïŒãã©ãã°ããŠãéžæããããªããžã§ã¯ãã®åšå²ã«ããã¯ã¹ãæããŸãããªããžã§ã¯ãããå°ã倧ãããå°ããããã¯ã¹ãæããšãããè¯ãçµæãåŸãããå ŽåããããŸãã",
"visualMode2": "ã¯ãªãã¯ããŠç·ã® include ãã€ã³ãã远å ããããShift ããŒãæŒããªããã¯ãªãã¯ããŠèµ€ã® exclude ãã€ã³ãã远å ããã¢ãã«ã«å«ããå
容ãšé€å€ããå
容ãæç€ºããŸãã",
"visualMode3": "ãã€ã³ãã¯ãããã¯ã¹ã®éžæãçµã蟌ãããã«äœ¿çšããããšããç¬ç«ããŠäœ¿çšããããšãã§ããŸãã",
@@ -2392,13 +2395,13 @@
"promptMode1": "éžæãããªããžã§ã¯ãã®ç°¡åãªèª¬æãå
¥åããŸãã",
"promptMode2": "è€éãªèª¬æãè€æ°ã®ãªããžã§ã¯ããé¿ããç°¡åãªèšèã䜿çšããŠãã ããã",
"model": "ã¢ãã«",
- "segmentAnything1": "äœã§ãã»ã°ã¡ã³ã1",
- "segmentAnything2": "äœã§ãã»ã°ã¡ã³ã2",
+ "segmentAnything1": "Segment Anything 1",
+ "segmentAnything2": "Segment Anything 2",
"prompt": "ããã³ããéžæ"
},
"HUD": {
- "bbox": "Bããã¯ã¹",
- "scaledBbox": "ã¹ã±ãŒã«ãããBããã¯ã¹",
+ "bbox": "ããŠã³ãã£ã³ã°ããã¯ã¹",
+ "scaledBbox": "ã¹ã±ãŒã«ãããããŠã³ãã£ã³ã°ããã¯ã¹",
"entityStatus": {
"isFiltering": "{{title}} ã¯ãã£ã«ã¿ãªã³ã°äžã§ã",
"isTransforming": "{{title}}ã¯å€åããŠããŸã",
@@ -2418,20 +2421,20 @@
"showResultsOn": "çµæã衚瀺",
"showResultsOff": "çµæãé ã"
},
- "fitBboxToMasks": "Bboxããã¹ã¯ã«ãã£ããããã",
+ "fitBboxToMasks": "ããŠã³ãã£ã³ã°ããã¯ã¹ããã¹ã¯ã«ãã£ããããã",
"addAdjustments": "調æŽã远å ",
"removeAdjustments": "調æŽãåé€",
"adjustments": {
"simple": "ã·ã³ãã«",
- "curves": "æ²ç·",
+ "curves": "ã«ãŒã",
"heading": "調æŽ",
"expand": "調æŽãæ¡åŒµ",
"collapse": "æãããã¿èª¿æŽ",
"brightness": "èŒåºŠ",
"contrast": "ã³ã³ãã©ã¹ã",
- "saturation": "飜å",
- "temperature": "枩床",
- "tint": "è²åã",
+ "saturation": "圩床",
+ "temperature": "è²æž©åºŠ",
+ "tint": "è²çž",
"sharpness": "ã·ã£ãŒããã¹",
"finish": "çµäº",
"reset": "ãªã»ãã",
@@ -2475,7 +2478,8 @@
"off": "ãªã",
"switchOnStart": "éå§æ",
"switchOnFinish": "çµäºæ"
- }
+ },
+ "extractRegion": "é åãæœåº"
},
"stylePresets": {
"clearTemplateSelection": "éžæãããã³ãã¬ãŒããã¯ãªã¢",
@@ -2541,18 +2545,18 @@
"missingUpscaleInitialImage": "ã¢ããã¹ã±ãŒã«çšã®åæç»åããããŸãã",
"missingUpscaleModel": "ã¢ããã¹ã±ãŒã«ã¢ãã«ããããŸãã",
"missingTileControlNetModel": "æå¹ãªã¿ã€ã« ã³ã³ãããŒã«ãããã¢ãã«ãã€ã³ã¹ããŒã«ãããŠããŸãã",
- "incompatibleBaseModel": "ã¢ããã¹ã±ãŒãªã³ã°ã«ãµããŒããããŠããªãã¡ã€ã³ã¢ãã«ã¢ãŒããã¯ãã£ã§ã",
- "incompatibleBaseModelDesc": "ã¢ããã¹ã±ãŒãªã³ã°ã¯SD1.5ããã³SDXLã¢ãŒããã¯ãã£ã¢ãã«ã§ã®ã¿ãµããŒããããŠããŸããã¢ããã¹ã±ãŒãªã³ã°ãæå¹ã«ããã«ã¯ãã¡ã€ã³ã¢ãã«ã倿ŽããŠãã ããã",
+ "incompatibleBaseModel": "ã¢ããã¹ã±ãŒã«ã«ãµããŒããããŠããªãã¡ã€ã³ã¢ãã«ã¢ãŒããã¯ãã£ã§ã",
+ "incompatibleBaseModelDesc": "ã¢ããã¹ã±ãŒã«ã¯SD1.5ããã³SDXLã¢ãŒããã¯ãã£ã¢ãã«ã§ã®ã¿ãµããŒããããŠããŸããã¢ããã¹ã±ãŒã«ãæå¹ã«ããã«ã¯ãã¡ã€ã³ã¢ãã«ã倿ŽããŠãã ããã",
"tileControl": "ã¿ã€ã«ã³ã³ãããŒã«",
"tileSize": "ã¿ã€ã«ãµã€ãº",
"tileOverlap": "ã¿ã€ã«ãªãŒããŒã©ãã"
},
"sdxl": {
- "denoisingStrength": "ãã€ãºé€å»åŒ·åºŠ",
+ "denoisingStrength": "é€å»ãã€ãºåŒ·åºŠ",
"scheduler": "ã¹ã±ãžã¥ãŒã©ãŒ",
"loading": "ããŒãäž...",
"steps": "ã¹ããã",
- "refiner": "Refiner",
+ "refiner": "ãªãã¡ã€ããŒ",
"noModelsAvailable": "å©çšã§ããã¢ãã«ããããŸãã",
"cfgScale": "CFGã¹ã±ãŒã«",
"posAestheticScore": "ããžãã£ãçŸçã¹ã³ã¢",
@@ -2594,7 +2598,7 @@
"builder": "ãã©ãŒã ãã«ããŒ",
"text": "ããã¹ã",
"row": "è¡",
- "multiLine": "ãã«ãã©ã€ã³",
+ "multiLine": "ããã¹ã(è€æ°è¡)",
"resetAllNodeFields": "ãã¹ãŠã®ããŒããã£ãŒã«ãããªã»ãã",
"slider": "ã¹ã©ã€ããŒ",
"layout": "ã¬ã€ã¢ãŠã",
@@ -2604,7 +2608,7 @@
"component": "ã³ã³ããŒãã³ã",
"textPlaceholder": "空ã®ããã¹ã",
"addOption": "ãªãã·ã§ã³ã远å ",
- "singleLine": "åç·",
+ "singleLine": "ããã¹ã",
"numberInput": "æ°å€å
¥å",
"column": "å",
"container": "ã³ã³ãã",
@@ -2682,7 +2686,7 @@
"delete": "åé€",
"loadMore": "ãã£ãšèªã¿èŸŒã",
"saveWorkflowToProject": "ã¯ãŒã¯ãããŒããããžã§ã¯ãã«ä¿å",
- "created": "äœæãããŸãã",
+ "created": "äœæé ",
"workflowEditorMenu": "ã¯ãŒã¯ãããŒãšãã£ã¿ãŒã¡ãã¥ãŒ",
"recentlyOpened": "æè¿éãã",
"opened": "ãªãŒãã³",
@@ -2736,9 +2740,9 @@
"seedBehaviour": {
"label": "ã·ãŒãã®æå",
"perPromptLabel": "ç»åããšã®ã·ãŒã",
- "perIterationLabel": "ããŠã¬ãŒã·ã§ã³ããšã®ã·ãŒã",
+ "perIterationLabel": "ã€ãã¬ãŒã·ã§ã³ããšã®ã·ãŒã",
"perPromptDesc": "ããããã®ç»åã«è¶³ããŠå¥ã®ã·ãŒãã䜿ã",
- "perIterationDesc": "ããããã®ããŠã¬ãŒã·ã§ã³ã«å¥ã®ã·ãŒãã䜿ã"
+ "perIterationDesc": "ããããã®ã€ãã¬ãŒã·ã§ã³ã«å¥ã®ã·ãŒãã䜿ã"
},
"showDynamicPrompts": "ãã€ãããã¯ããã³ããã衚瀺ãã",
"dynamicPrompts": "ãã€ãããã¯ããã³ãã",
@@ -2758,7 +2762,7 @@
"whatsNewInInvoke": "Invokeã®æ°æ©èœ",
"items": [
"ãªããžã§ã¯ãã®éžæ v2: ãã€ã³ãããã³ããã¯ã¹å
¥åãŸãã¯ããã¹ã ããã³ããã«ãããªããžã§ã¯ãéžæãæ¹åãããŸããã",
- "ã©ã¹ã¿ãŒ ã¬ã€ã€ãŒã®èª¿æŽ: ã¬ã€ã€ãŒã®æãããã³ã³ãã©ã¹ããåœ©åºŠãæ²ç·ãªã©ãç°¡åã«èª¿æŽã§ããŸãã"
+ "ã©ã¹ã¿ãŒ ã¬ã€ã€ãŒã®èª¿æŽ: ã¬ã€ã€ãŒã®æåºŠãã³ã³ãã©ã¹ãã圩床ãã«ãŒããªã©ãç°¡åã«èª¿æŽã§ããŸãã"
],
"readReleaseNotes": "ãªãªãŒã¹ããŒããèªã",
"watchRecentReleaseVideos": "æè¿ã®ãªãªãŒã¹ãããªãèŠã",
diff --git a/invokeai/frontend/web/src/features/nodes/store/util/getCollectItemType.test.ts b/invokeai/frontend/web/src/features/nodes/store/util/getCollectItemType.test.ts
index 8adc013ab9..fb4d7ee48c 100644
--- a/invokeai/frontend/web/src/features/nodes/store/util/getCollectItemType.test.ts
+++ b/invokeai/frontend/web/src/features/nodes/store/util/getCollectItemType.test.ts
@@ -41,4 +41,14 @@ describe(getCollectItemType.name, () => {
const result = getCollectItemType({ add: addWithoutOutputValue, collect }, [n2, n1], [e1], n1.id);
expect(result).toBeNull();
});
+
+ it('should return the upstream collect item type for chained collects', () => {
+ const n1 = buildNode(collect);
+ const n2 = buildNode(collect);
+ const n3 = buildNode(add);
+ const e1 = buildEdge(n3.id, 'value', n1.id, 'item');
+ const e2 = buildEdge(n1.id, 'collection', n2.id, 'collection');
+ const result = getCollectItemType(templates, [n1, n2, n3], [e1, e2], n2.id);
+ expect(result).toEqual({ name: 'IntegerField', cardinality: 'SINGLE', batch: false });
+ });
});
diff --git a/invokeai/frontend/web/src/features/nodes/store/util/getCollectItemType.ts b/invokeai/frontend/web/src/features/nodes/store/util/getCollectItemType.ts
index 9fb2795ae8..35ec20220e 100644
--- a/invokeai/frontend/web/src/features/nodes/store/util/getCollectItemType.ts
+++ b/invokeai/frontend/web/src/features/nodes/store/util/getCollectItemType.ts
@@ -2,6 +2,16 @@ import type { Templates } from 'features/nodes/store/types';
import type { FieldType } from 'features/nodes/types/field';
import type { AnyEdge, AnyNode } from 'features/nodes/types/invocation';
+const toItemType = (fieldType: FieldType): FieldType | null => {
+ if (fieldType.name === 'CollectionField') {
+ return null;
+ }
+ if (fieldType.cardinality === 'COLLECTION' || fieldType.cardinality === 'SINGLE_OR_COLLECTION') {
+ return { ...fieldType, cardinality: 'SINGLE' };
+ }
+ return fieldType;
+};
+
/**
* Given a collect node, return the type of the items it collects. The graph is traversed to find the first node and
* field connected to the collector's `item` input. The field type of that field is returned, else null if there is no
@@ -18,21 +28,56 @@ export const getCollectItemType = (
edges: AnyEdge[],
nodeId: string
): FieldType | null => {
- const firstEdgeToCollect = edges.find((edge) => edge.target === nodeId && edge.targetHandle === 'item');
- if (!firstEdgeToCollect?.sourceHandle) {
+ const getCollectItemTypeInternal = (currentNodeId: string, visited: Set): FieldType | null => {
+ if (visited.has(currentNodeId)) {
+ return null;
+ }
+ visited.add(currentNodeId);
+
+ const firstItemEdgeToCollect = edges.find((edge) => edge.target === currentNodeId && edge.targetHandle === 'item');
+ if (firstItemEdgeToCollect?.sourceHandle) {
+ const node = nodes.find((n) => n.id === firstItemEdgeToCollect.source);
+ if (!node) {
+ return null;
+ }
+ const template = templates[node.data.type];
+ if (!template) {
+ return null;
+ }
+ const fieldTemplate = template.outputs[firstItemEdgeToCollect.sourceHandle];
+ if (!fieldTemplate) {
+ return null;
+ }
+ return toItemType(fieldTemplate.type);
+ }
+
+ const firstCollectionEdgeToCollect = edges.find(
+ (edge) => edge.target === currentNodeId && edge.targetHandle === 'collection'
+ );
+ if (!firstCollectionEdgeToCollect?.sourceHandle) {
+ return null;
+ }
+ const sourceNode = nodes.find((n) => n.id === firstCollectionEdgeToCollect.source);
+ if (!sourceNode) {
+ return null;
+ }
+ if (sourceNode.data.type === 'collect' && firstCollectionEdgeToCollect.sourceHandle === 'collection') {
+ return getCollectItemTypeInternal(sourceNode.id, visited);
+ }
+ const sourceTemplate = templates[sourceNode.data.type];
+ if (!sourceTemplate) {
+ return null;
+ }
+ const sourceFieldTemplate = sourceTemplate.outputs[firstCollectionEdgeToCollect.sourceHandle];
+ if (!sourceFieldTemplate) {
+ return null;
+ }
+ return toItemType(sourceFieldTemplate.type);
+ };
+
+ const itemType = getCollectItemTypeInternal(nodeId, new Set());
+ if (!itemType) {
return null;
}
- const node = nodes.find((n) => n.id === firstEdgeToCollect.source);
- if (!node) {
- return null;
- }
- const template = templates[node.data.type];
- if (!template) {
- return null;
- }
- const fieldTemplate = template.outputs[firstEdgeToCollect.sourceHandle];
- if (!fieldTemplate) {
- return null;
- }
- return fieldTemplate.type;
+ return itemType;
};
diff --git a/invokeai/frontend/web/src/features/nodes/store/util/testUtils.ts b/invokeai/frontend/web/src/features/nodes/store/util/testUtils.ts
index 7442561984..1eb445beaf 100644
--- a/invokeai/frontend/web/src/features/nodes/store/util/testUtils.ts
+++ b/invokeai/frontend/web/src/features/nodes/store/util/testUtils.ts
@@ -133,11 +133,27 @@ export const sub: InvocationTemplate = {
export const collect: InvocationTemplate = {
title: 'Collect',
type: 'collect',
- version: '1.0.0',
+ version: '1.1.0',
tags: [],
description: 'Collects values into a collection',
outputType: 'collect_output',
inputs: {
+ collection: {
+ name: 'collection',
+ title: 'Collection',
+ required: false,
+ default: undefined,
+ description: 'An optional collection to append to',
+ fieldKind: 'input',
+ input: 'connection',
+ ui_hidden: false,
+ ui_type: 'CollectionField' as const,
+ type: {
+ name: 'CollectionField' as const,
+ cardinality: 'COLLECTION',
+ batch: false,
+ },
+ },
item: {
name: 'item',
title: 'Collection Item',
@@ -1162,13 +1178,12 @@ export const schema = {
items: {},
type: 'array',
title: 'Collection',
- description: 'The collection, will be provided on execution',
- default: [],
+ description: 'An optional collection to append to',
field_kind: 'input',
- input: 'any',
- orig_default: [],
+ input: 'connection',
orig_required: false,
- ui_hidden: true,
+ ui_hidden: false,
+ ui_type: 'CollectionField',
},
type: {
type: 'string',
@@ -1185,7 +1200,7 @@ export const schema = {
node_pack: 'invokeai',
description: 'Collects values into a collection',
classification: 'stable',
- version: '1.0.0',
+ version: '1.1.0',
output: {
$ref: '#/components/schemas/CollectInvocationOutput',
},
diff --git a/invokeai/frontend/web/src/features/nodes/store/util/validateConnection.test.ts b/invokeai/frontend/web/src/features/nodes/store/util/validateConnection.test.ts
index 4108f57c07..947d8745f0 100644
--- a/invokeai/frontend/web/src/features/nodes/store/util/validateConnection.test.ts
+++ b/invokeai/frontend/web/src/features/nodes/store/util/validateConnection.test.ts
@@ -122,6 +122,52 @@ describe(validateConnection.name, () => {
expect(r).toEqual(null);
});
+ it('should accept chaining collect collection output to collect collection input', () => {
+ const n1 = buildNode(collect);
+ const n2 = buildNode(collect);
+ const nodes = [n1, n2];
+ const c = { source: n1.id, sourceHandle: 'collection', target: n2.id, targetHandle: 'collection' };
+ const r = validateConnection(c, nodes, [], templates, null);
+ expect(r).toEqual(null);
+ });
+
+ it('should reject multiple connections to collect collection input', () => {
+ const n1 = buildNode(collect);
+ const n2 = buildNode(collect);
+ const n3 = buildNode(collect);
+ const nodes = [n1, n2, n3];
+ const e1 = buildEdge(n1.id, 'collection', n2.id, 'collection');
+ const c = { source: n3.id, sourceHandle: 'collection', target: n2.id, targetHandle: 'collection' };
+ const r = validateConnection(c, nodes, [e1], templates, null);
+ expect(r).toEqual('nodes.inputMayOnlyHaveOneConnection');
+ });
+
+ it('should reject mismatched item connection when collect is typed via chained collection', () => {
+ const n1 = buildNode(add);
+ const n2 = buildNode(collect);
+ const n3 = buildNode(collect);
+ const n4 = buildNode(main_model_loader);
+ const nodes = [n1, n2, n3, n4];
+ const e1 = buildEdge(n1.id, 'value', n2.id, 'item');
+ const e2 = buildEdge(n2.id, 'collection', n3.id, 'collection');
+ const c = { source: n4.id, sourceHandle: 'vae', target: n3.id, targetHandle: 'item' };
+ const r = validateConnection(c, nodes, [e1, e2], templates, null);
+ expect(r).toEqual('nodes.cannotMixAndMatchCollectionItemTypes');
+ });
+
+ it('should reject chaining collection-to-collection for differently typed collects', () => {
+ const n1 = buildNode(add);
+ const n2 = buildNode(img_resize);
+ const n3 = buildNode(collect);
+ const n4 = buildNode(collect);
+ const nodes = [n1, n2, n3, n4];
+ const e1 = buildEdge(n1.id, 'value', n3.id, 'item');
+ const e2 = buildEdge(n2.id, 'image', n4.id, 'item');
+ const c = { source: n3.id, sourceHandle: 'collection', target: n4.id, targetHandle: 'collection' };
+ const r = validateConnection(c, nodes, [e1, e2], templates, null);
+ expect(r).toEqual('nodes.cannotMixAndMatchCollectionItemTypes');
+ });
+
it('should reject connections to target field that is already connected', () => {
const n1 = buildNode(add);
const n2 = buildNode(add);
diff --git a/invokeai/frontend/web/src/features/nodes/store/util/validateConnection.ts b/invokeai/frontend/web/src/features/nodes/store/util/validateConnection.ts
index aaeb10edfd..9024a16f42 100644
--- a/invokeai/frontend/web/src/features/nodes/store/util/validateConnection.ts
+++ b/invokeai/frontend/web/src/features/nodes/store/util/validateConnection.ts
@@ -108,6 +108,24 @@ export const validateConnection: ValidateConnectionFunc = (
}
}
+ if (
+ sourceNode.data.type === 'collect' &&
+ c.sourceHandle === 'collection' &&
+ targetNode.data.type === 'collect' &&
+ c.targetHandle === 'collection'
+ ) {
+ // Chained collect nodes should preserve a single item type when both ends are already typed.
+ const sourceCollectItemType = getCollectItemType(templates, nodes, edges, sourceNode.id);
+ const targetCollectItemType = getCollectItemType(templates, nodes, edges, targetNode.id);
+ if (
+ sourceCollectItemType &&
+ targetCollectItemType &&
+ !areTypesEqual(sourceCollectItemType, targetCollectItemType)
+ ) {
+ return 'nodes.cannotMixAndMatchCollectionItemTypes';
+ }
+ }
+
if (filteredEdges.find(getTargetEqualityPredicate(c))) {
// CollectionItemField inputs can have multiple input connections
if (targetFieldTemplate.type.name !== 'CollectionItemField') {
diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/generation/buildFLUXGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/generation/buildFLUXGraph.ts
index db7cba5961..ba27e5dbf6 100644
--- a/invokeai/frontend/web/src/features/nodes/util/graph/generation/buildFLUXGraph.ts
+++ b/invokeai/frontend/web/src/features/nodes/util/graph/generation/buildFLUXGraph.ts
@@ -271,10 +271,7 @@ export const buildFLUXGraph = async (arg: GraphBuilderArg): Promise getGlobalReferenceImageWarnings(entity, model).length === 0);
if (validFlux2RefImageConfigs.length > 0) {
- const flux2KontextCollect = g.addNode({
- type: 'collect',
- id: getPrefixedId('flux2_kontext_collect'),
- });
+ let prevCollect: Invocation<'collect'> | null = null;
for (const { config } of validFlux2RefImageConfigs) {
// FLUX.2 uses the same flux_kontext node - it just packages the image
const kontextConditioning = g.addNode({
@@ -282,9 +279,18 @@ export const buildFLUXGraph = async (arg: GraphBuilderArg): Promise(value: T): T => JSON.parse(JSON.stringify(value)) as T;
+
describe('parseSchema', () => {
it('should parse the schema', () => {
const parsed = parseSchema(schema);
- expect(parsed).toEqual(templates);
+ expect(stripUndefinedDeep(parsed)).toEqual(stripUndefinedDeep(templates));
});
it('should omit denied nodes', () => {
const parsed = parseSchema(schema, undefined, ['add']);
- expect(parsed).toEqual(omit(templates, 'add'));
+ expect(stripUndefinedDeep(parsed)).toEqual(stripUndefinedDeep(omit(templates, 'add')));
});
it('should include only allowed nodes', () => {
const parsed = parseSchema(schema, ['add']);
- expect(parsed).toEqual(pick(templates, 'add'));
+ expect(stripUndefinedDeep(parsed)).toEqual(stripUndefinedDeep(pick(templates, 'add')));
});
});
diff --git a/invokeai/frontend/web/src/features/nodes/util/schema/parseSchema.ts b/invokeai/frontend/web/src/features/nodes/util/schema/parseSchema.ts
index 1371db1568..57cd9943c5 100644
--- a/invokeai/frontend/web/src/features/nodes/util/schema/parseSchema.ts
+++ b/invokeai/frontend/web/src/features/nodes/util/schema/parseSchema.ts
@@ -39,9 +39,6 @@ const isReservedInputField = (nodeType: string, fieldName: string) => {
if (RESERVED_INPUT_FIELD_NAMES.includes(fieldName)) {
return true;
}
- if (nodeType === 'collect' && fieldName === 'collection') {
- return true;
- }
if (nodeType === 'iterate' && fieldName === 'index') {
return true;
}
diff --git a/invokeai/frontend/web/src/services/api/schema.ts b/invokeai/frontend/web/src/services/api/schema.ts
index 7574a841b0..67e1c31221 100644
--- a/invokeai/frontend/web/src/services/api/schema.ts
+++ b/invokeai/frontend/web/src/services/api/schema.ts
@@ -5040,7 +5040,7 @@ export type components = {
item?: unknown | null;
/**
* Collection
- * @description The collection, will be provided on execution
+ * @description An optional collection to append to
* @default []
*/
collection?: unknown[];
diff --git a/invokeai/version/invokeai_version.py b/invokeai/version/invokeai_version.py
index 0f32252c28..9bf32e7d0b 100644
--- a/invokeai/version/invokeai_version.py
+++ b/invokeai/version/invokeai_version.py
@@ -1 +1 @@
-__version__ = "6.11.1.post1"
+__version__ = "6.12.0.post1"
diff --git a/tests/test_node_graph.py b/tests/test_node_graph.py
index 160dc96d85..4f3b262204 100644
--- a/tests/test_node_graph.py
+++ b/tests/test_node_graph.py
@@ -40,6 +40,7 @@ from tests.test_nodes import (
PromptTestInvocation,
PromptTestInvocationOutput,
TextToImageTestInvocation,
+ UnionCollectionTestInvocation,
get_single_output_from_session,
run_session_with_mock_context,
)
@@ -337,6 +338,100 @@ def test_graph_collector_invalid_with_non_list_output():
g.add_edge(e3)
+def test_graph_collector_can_chain_collection_input():
+ g = Graph()
+ n1 = PromptCollectionTestInvocation(id="1", collection=["Banana", "Sushi"])
+ n2 = PromptTestInvocation(id="2", prompt="Ramen")
+ n3 = CollectInvocation(id="3")
+ g.add_node(n1)
+ g.add_node(n2)
+ g.add_node(n3)
+
+ g.add_edge(create_edge("1", "collection", "3", "collection"))
+ g.add_edge(create_edge("2", "prompt", "3", "item"))
+
+ session = GraphExecutionState(graph=g)
+ run_session_with_mock_context(session)
+ output = get_single_output_from_session(session, n3.id)
+
+ assert isinstance(output, CollectInvocationOutput)
+ assert output.collection == ["Banana", "Sushi", "Ramen"]
+
+
+def test_graph_collector_chain_rejects_mismatched_item_type():
+ g = Graph()
+ n1 = PromptCollectionTestInvocation(id="1", collection=["Banana", "Sushi"])
+ n2 = IntegerInvocation(id="2", value=7)
+ n3 = CollectInvocation(id="3")
+ g.add_node(n1)
+ g.add_node(n2)
+ g.add_node(n3)
+
+ g.add_edge(create_edge("1", "collection", "3", "collection"))
+ with pytest.raises(InvalidEdgeError):
+ g.add_edge(create_edge("2", "value", "3", "item"))
+
+
+def test_graph_iterator_accepts_collector_chained_collection_input():
+ g = Graph()
+ n1 = PromptTestInvocation(id="1", prompt="Banana")
+ n2 = CollectInvocation(id="2")
+ n3 = CollectInvocation(id="3")
+ n4 = IterateInvocation(id="4")
+ n5 = PromptTestInvocation(id="5")
+ g.add_node(n1)
+ g.add_node(n2)
+ g.add_node(n3)
+ g.add_node(n4)
+ g.add_node(n5)
+
+ g.add_edge(create_edge("1", "prompt", "2", "item"))
+ g.add_edge(create_edge("2", "collection", "3", "collection"))
+ g.add_edge(create_edge("3", "collection", "4", "collection"))
+ g.add_edge(create_edge("4", "item", "5", "prompt"))
+
+ session = GraphExecutionState(graph=g)
+ run_session_with_mock_context(session)
+
+ output = get_single_output_from_session(session, n5.id)
+ assert isinstance(output, PromptTestInvocationOutput)
+ assert output.prompt == "Banana"
+
+
+def test_graph_collector_chain_rejects_upstream_mismatch_added_late():
+ g = Graph()
+ n1 = CollectInvocation(id="1")
+ n2 = CollectInvocation(id="2")
+ n3 = PromptTestInvocation(id="3", prompt="typed-as-string")
+ n4 = ColorInvocation(id="4")
+ g.add_node(n1)
+ g.add_node(n2)
+ g.add_node(n3)
+ g.add_node(n4)
+
+ # Connect chain first while n1 is still untyped.
+ g.add_edge(create_edge("1", "collection", "2", "collection"))
+ # Constrain downstream collector to strings.
+ g.add_edge(create_edge("3", "prompt", "2", "item"))
+ # Now adding an incompatible type to the upstream collector must fail.
+ with pytest.raises(InvalidEdgeError):
+ g.add_edge(create_edge("4", "color", "1", "item"))
+
+
+def test_graph_collector_rejects_mismatched_item_with_union_collection_input():
+ g = Graph()
+ n1 = UnionCollectionTestInvocation(id="1")
+ n2 = CollectInvocation(id="2")
+ n3 = ColorInvocation(id="3")
+ g.add_node(n1)
+ g.add_node(n2)
+ g.add_node(n3)
+
+ g.add_edge(create_edge("1", "value", "2", "collection"))
+ with pytest.raises(InvalidEdgeError):
+ g.add_edge(create_edge("3", "color", "2", "item"))
+
+
def test_graph_connects_iterator():
g = Graph()
n1 = ListPassThroughInvocation(id="1")
@@ -712,6 +807,24 @@ def test_iterate_accepts_collection():
g.add_edge(e3)
+def test_iterate_accepts_collection_from_any_only_collector():
+ g = Graph()
+ n1 = AnyTypeTestInvocation(id="1")
+ n2 = CollectInvocation(id="2")
+ n3 = IterateInvocation(id="3")
+ n4 = AnyTypeTestInvocation(id="4")
+ g.add_node(n1)
+ g.add_node(n2)
+ g.add_node(n3)
+ g.add_node(n4)
+ e1 = create_edge(n1.id, "value", n2.id, "item")
+ e2 = create_edge(n2.id, "collection", n3.id, "collection")
+ e3 = create_edge(n3.id, "item", n4.id, "value")
+ g.add_edge(e1)
+ g.add_edge(e2)
+ g.add_edge(e3)
+
+
def test_iterate_validates_collection_inputs_against_iterator_outputs():
g = Graph()
n1 = IntegerInvocation(id="1", value=1)
diff --git a/tests/test_nodes.py b/tests/test_nodes.py
index 04ea5126f0..6e8d25a603 100644
--- a/tests/test_nodes.py
+++ b/tests/test_nodes.py
@@ -107,6 +107,19 @@ class PolymorphicStringTestInvocation(BaseInvocation):
return PromptCollectionTestInvocationOutput(collection=self.value)
+@invocation_output("test_union_collection_output")
+class UnionCollectionTestInvocationOutput(BaseInvocationOutput):
+ value: Union[str, list[str], None] = OutputField(default=None)
+
+
+@invocation("test_union_collection", version="1.0.0")
+class UnionCollectionTestInvocation(BaseInvocation):
+ value: Union[str, list[str], None] = InputField(default=None)
+
+ def invoke(self, context: InvocationContext) -> UnionCollectionTestInvocationOutput:
+ return UnionCollectionTestInvocationOutput(value=self.value)
+
+
# Importing these must happen after test invocations are defined or they won't register
from invokeai.app.services.events.events_base import EventServiceBase # noqa: E402
from invokeai.app.services.shared.graph import Edge, EdgeConnection, GraphExecutionState # noqa: E402