Compare commits

..
8 Commits
Author SHA1 Message Date
Dr.Lt.Data bcbed07560 refactor: change type name NOISE to NOISE_IMAGE. 2024-12-20 14:58:38 +09:00
Dr.Lt.Data 685c5c0d00 Merge pull request #198 from stormwulfren/main
Zipped Prompts Parsing Enhancements
2024-12-19 18:43:45 +09:00
Ren Black 697f12fbdb Merge pull request #1 from stormwulfren/feat/zippedPromptsQoL
Enhance zipped prompt parsing
2024-12-18 13:12:10 +00:00
Ren Black e8817bc348 Enhance zipped prompt parsing
- Added 'count' to emits of LoadPromptsFromDir and LoadPromptsFromFile nodes. Represents the total number of extracted prompts in the batch.
- Modified regex pattern for prompt parsing to include an optional 'name' field. If 'name' is not present, the existing behaviour of using the filename is emitted instead. Additionally, 'positive', 'negative' and 'name' can be presented in arbitrary order.
2024-12-18 13:09:40 +00:00
Dr.Lt.Data 9c6065af6d feat: Is Cached (Inspire) node is added.
https://github.com/ltdrdata/ComfyUI-Inspire-Pack/issues/190#issuecomment-2507871877
2024-12-01 01:26:36 +09:00
Dr.Lt.Data 8db9411e94 FIXED: front compatibility fix
- selectors of wildcards, lbw, promptbuilder
2024-11-30 23:16:30 +09:00
Dr.Lt.Data 18f02d98b1 Merge pull request #189 from akuma/fix/warning-message-condition
Fix warning message condition and add info log
2024-11-25 23:24:27 +09:00
akuma cab499e30a Fix warning message condition and add info log
- Corrected the logic for displaying the "file not found" warning message.
- Added an info log message to indicate when the file is successfully found and loaded.
2024-11-25 18:38:38 +08:00
11 changed files with 320 additions and 194 deletions
+2
View File
@@ -2,6 +2,7 @@
This repository offers various extension nodes for ComfyUI. Nodes here have different characteristics compared to those in the ComfyUI Impact Pack. The Impact Pack has become too large now...
## Notice:
* v1.9.1 To avoid confusion with the `NOISE` type in core, the type name has been changed to `NOISE_IMAGE`.
* V0.73 The Variation Seed feature is added to Regional Prompt nodes, and it is only compatible with versions Impact Pack V5.10 and above.
* V0.69 incompatible with the outdated **ComfyUI IPAdapter Plus**. (A version dated March 24th or later is required.)
* V0.64 add sigma_factor to RegionalPrompt... nodes required Impact Pack V4.76 or later.
@@ -147,6 +148,7 @@ This repository offers various extension nodes for ComfyUI. Nodes here have diff
* When `key_opt` is empty, the `ckpt_name` is set as the cache key. The cache key output can be used for deletion purposes with Remove Back End.
* This node resolves the issue of reloading checkpoints during workflow switching.
* `Stable Cascade Checkpoint Loader (Inspire)`: This node provides a feature that allows you to load the `stage_b` and `stage_c` checkpoints of Stable Cascade at once, and it also provides a backend caching feature, optionally.
* `Is Cached (Inspire)`: Returns whether the cache exists.
### Conditioning - Nodes for conditionings
* `Concat Conditionings with Multiplier (Inspire)`: Concatenating an arbitrary number of Conditionings while applying a multiplier for each Conditioning. The multiplier depends on `comfy_PoP`, so [comfy_PoP](https://github.com/picturesonpictures/comfy_PoP) must be installed.
+1 -1
View File
@@ -7,7 +7,7 @@
import importlib
version_code = [1, 7]
version_code = [1, 9, 1]
version_str = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
print(f"### Loading: ComfyUI-Inspire-Pack ({version_str})")
+2 -2
View File
@@ -162,7 +162,7 @@ class KSamplerAdvanced_inspire:
"optional":
{
"variation_method": (["linear", "slerp"],),
"noise_opt": ("NOISE",),
"noise_opt": ("NOISE_IMAGE",),
"scheduler_func_opt": ("SCHEDULER_FUNC",),
}
}
@@ -253,7 +253,7 @@ class KSamplerAdvanced_inspire_pipe:
},
"optional":
{
"noise_opt": ("NOISE",),
"noise_opt": ("NOISE_IMAGE",),
"scheduler_func_opt": ("SCHEDULER_FUNC",),
}
}
+75 -2
View File
@@ -1,5 +1,6 @@
import json
import os
from .libs import common
import folder_paths
import nodes
@@ -478,6 +479,74 @@ class StableCascade_CheckpointLoader:
return b_model, b_vae, c_model, c_vae, clip_vision, clip, key_b, key_c
class IsCached:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"key": ("STRING", {"multiline": False}),
},
"hidden": {
"unique_id": "UNIQUE_ID"
}
}
RETURN_TYPES = ("BOOLEAN", )
FUNCTION = "doit"
CATEGORY = "InspirePack/Backend"
@staticmethod
def IS_CHANGED(key, unique_id):
return common.is_changed(unique_id, key in cache)
def doit(self, key, unique_id):
return (key in cache,)
# WIP: not properly working, yet
class CacheBridge:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"value": (any_typ,),
"mode": ("BOOLEAN", {"default": True, "label_off": "cached", "label_on": "passthrough"}),
},
"hidden": {
"unique_id": "UNIQUE_ID"
}
}
RETURN_TYPES = (any_typ, )
RETURN_NAMES = ("value",)
FUNCTION = "doit"
CATEGORY = "InspirePack/Backend"
@staticmethod
def IS_CHANGED(value, mode, unique_id):
if not mode and unique_id in common.changed_cache:
return common.not_changed_value(unique_id)
else:
return common.changed_value(unique_id)
def doit(self, value, mode, unique_id):
if not mode:
# cache mode
if unique_id not in common.changed_cache:
common.changed_cache[unique_id] = value
common.changed_count_cache[unique_id] = 0
return (common.changed_cache[unique_id],)
else:
common.changed_cache[unique_id] = value
common.changed_count_cache[unique_id] = 0
return (common.changed_cache[unique_id],)
NODE_CLASS_MAPPINGS = {
"CacheBackendData //Inspire": CacheBackendData,
"CacheBackendDataNumberKey //Inspire": CacheBackendDataNumberKey,
@@ -489,7 +558,9 @@ NODE_CLASS_MAPPINGS = {
"RemoveBackendDataNumberKey //Inspire": RemoveBackendDataNumberKey,
"ShowCachedInfo //Inspire": ShowCachedInfo,
"CheckpointLoaderSimpleShared //Inspire": CheckpointLoaderSimpleShared,
"StableCascade_CheckpointLoader //Inspire": StableCascade_CheckpointLoader
"StableCascade_CheckpointLoader //Inspire": StableCascade_CheckpointLoader,
"IsCached //Inspire": IsCached,
# "CacheBridge //Inspire": CacheBridge,
}
NODE_DISPLAY_NAME_MAPPINGS = {
@@ -503,5 +574,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"RemoveBackendDataNumberKey //Inspire": "Remove Backend Data [NumberKey] (Inspire)",
"ShowCachedInfo //Inspire": "Show Cached Info (Inspire)",
"CheckpointLoaderSimpleShared //Inspire": "Shared Checkpoint Loader (Inspire)",
"StableCascade_CheckpointLoader //Inspire": "Stable Cascade Checkpoint Loader (Inspire)"
"StableCascade_CheckpointLoader //Inspire": "Stable Cascade Checkpoint Loader (Inspire)",
"IsCached //Inspire": "Is Cached (Inspire)",
# "CacheBridge //Inspire": "Cache Bridge (Inspire)"
}
+17
View File
@@ -6,6 +6,7 @@ from enum import Enum
from . import prompt_support
from aiohttp import web
from . import backend_support
from .libs import common
max_seed = 2**32 - 1
@@ -354,6 +355,21 @@ def force_reset_useless_params(json_data):
return json_data
def clear_unused_node_changed_cache(json_data):
prompt = json_data['prompt']
unused = []
for x in common.changed_cache.keys():
if x not in prompt:
unused.append(x)
for x in unused:
del common.changed_cache[x]
del common.changed_count_cache[x]
return json_data
def onprompt(json_data):
prompt_support.list_counter_map = {}
@@ -367,6 +383,7 @@ def onprompt(json_data):
populate_wildcards(json_data)
force_reset_useless_params(json_data)
clear_unused_node_changed_cache(json_data)
return json_data
+27
View File
@@ -12,3 +12,30 @@ def impact_sampling(*args, **kwargs):
raise Exception(f"[ERROR] You need to install 'ComfyUI-Impact-Pack'")
return nodes.NODE_CLASS_MAPPINGS['RegionalSampler'].separated_sample(*args, **kwargs)
changed_count_cache = {}
changed_cache = {}
def changed_value(uid):
v = changed_count_cache.get(uid, 0)
changed_count_cache[uid] = v + 1
return v + 1
def not_changed_value(uid):
return changed_count_cache.get(uid, 0)
def is_changed(uid, value):
if uid not in changed_cache or changed_cache[uid] != value:
res = changed_value(uid)
else:
res = not_changed_value(uid)
changed_cache[uid] = value
print(f"keys: {changed_cache.keys()}")
return res
+32 -23
View File
@@ -63,7 +63,8 @@ class LoadPromptsFromDir:
}
}
RETURN_TYPES = ("ZIPPED_PROMPT",)
RETURN_TYPES = ("ZIPPED_PROMPT", "INT")
RETURN_NAMES = ("zipped_prompt", "count")
OUTPUT_IS_LIST = (True,)
FUNCTION = "doit"
@@ -125,20 +126,21 @@ class LoadPromptsFromDir:
prompt_list = re.split(r'\n\s*-+\s*\n', prompt_data)
for prompt in prompt_list:
pattern = r"positive:(.*?)(?:\n*|$)negative:(.*)"
pattern = r"^(?:(?:positive:(?P<positive>.*?)|negative:(?P<negative>.*?)|name:(?P<name>.*?))\n*)+$"
matches = re.search(pattern, prompt, re.DOTALL)
if matches:
positive_text = matches.group(1).strip()
negative_text = matches.group(2).strip()
result_tuple = (positive_text, negative_text, file_name)
positive_text = matches.group('positive').strip()
negative_text = matches.group('negative').strip()
name_text = matches.group('name').strip() if matches.group('name') else file_name
result_tuple = (positive_text, negative_text, name_text)
prompts.append(result_tuple)
else:
print(f"[WARN] LoadPromptsFromDir: invalid prompt format in '{file_name}'")
except Exception as e:
print(f"[ERROR] LoadPromptsFromDir: an error occurred while processing '{file_name}': {str(e)}\nNOTE: Only files with UTF-8 encoding are supported.")
return (prompts, )
return (prompts, len(prompts),)
class LoadPromptsFromFile:
@@ -166,7 +168,8 @@ class LoadPromptsFromFile:
}
}
RETURN_TYPES = ("ZIPPED_PROMPT",)
RETURN_TYPES = ("ZIPPED_PROMPT", "INT")
RETURN_NAMES = ("zipped_prompt", "count")
OUTPUT_IS_LIST = (True,)
FUNCTION = "doit"
@@ -208,12 +211,14 @@ class LoadPromptsFromFile:
matched_path = None
for d in folder_paths.get_folder_paths('inspire_prompts'):
matched_path = os.path.join(d, prompt_file)
if not os.path.exists(matched_path):
matched_path = None
else:
if os.path.exists(matched_path):
break
else:
matched_path = None
if matched_path:
print(f"[INFO] LoadPromptsFromFile: file found '{prompt_file}'")
else:
print(f"[WARN] LoadPromptsFromFile: file not found '{prompt_file}'")
prompts = []
@@ -226,22 +231,23 @@ class LoadPromptsFromFile:
prompt_list = re.split(r'\n\s*-+\s*\n', prompt_data)
pattern = r"positive:(.*?)(?:\n*|$)negative:(.*)"
pattern = r"^(?:(?:positive:(?P<positive>.*?)|negative:(?P<negative>.*?)|name:(?P<name>.*?))\n*)+$"
for p in prompt_list:
matches = re.search(pattern, p, re.DOTALL)
if matches:
positive_text = matches.group(1).strip()
negative_text = matches.group(2).strip()
result_tuple = (positive_text, negative_text, prompt_file)
positive_text = matches.group('positive').strip()
negative_text = matches.group('negative').strip()
name_text = matches.group('name').strip() if matches.group('name') else prompt_file
result_tuple = (positive_text, negative_text, name_text)
prompts.append(result_tuple)
else:
print(f"[WARN] LoadPromptsFromFile: invalid prompt format in '{prompt_file}'")
except Exception as e:
print(f"[ERROR] LoadPromptsFromFile: an error occurred while processing '{prompt_file}': {str(e)}\nNOTE: Only files with UTF-8 encoding are supported.")
return (prompts, )
return (prompts, len(prompts),)
class LoadSinglePromptFromFile:
@@ -286,6 +292,8 @@ class LoadSinglePromptFromFile:
prompt_path = None
if prompt_path:
print(f"[INFO] LoadSinglePromptFromFile: file found '{prompt_file}'")
else:
print(f"[WARN] LoadSinglePromptFromFile: file not found '{prompt_file}'")
prompts = []
@@ -302,13 +310,14 @@ class LoadSinglePromptFromFile:
except Exception:
prompt = prompt_list[-1]
pattern = r"positive:(.*?)(?:\n*|$)negative:(.*)"
pattern = r"^(?:(?:positive:(?P<positive>.*?)|negative:(?P<negative>.*?)|name:(?P<name>.*?))\n*)+$"
matches = re.search(pattern, prompt, re.DOTALL)
if matches:
positive_text = matches.group(1).strip()
negative_text = matches.group(2).strip()
result_tuple = (positive_text, negative_text, prompt_file)
positive_text = matches.group('positive').strip()
negative_text = matches.group('negative').strip()
name_text = matches.group('name').strip() if matches.group('name') else prompt_file
result_tuple = (positive_text, negative_text, name_text)
prompts.append(result_tuple)
else:
print(f"[WARN] LoadSinglePromptFromFile: invalid prompt format in '{prompt_file}'")
@@ -678,7 +687,7 @@ class SeedExplorer:
}
}
RETURN_TYPES = ("NOISE",)
RETURN_TYPES = ("NOISE_IMAGE",)
FUNCTION = "doit"
CATEGORY = "InspirePack/Prompt"
@@ -753,15 +762,15 @@ class CompositeNoise:
def INPUT_TYPES(s):
return {
"required": {
"destination": ("NOISE",),
"source": ("NOISE",),
"destination": ("NOISE_IMAGE",),
"source": ("NOISE_IMAGE",),
"mode": (["center", "left-top", "right-top", "left-bottom", "right-bottom", "xy"], ),
"x": ("INT", {"default": 0, "min": 0, "max": nodes.MAX_RESOLUTION, "step": 8}),
"y": ("INT", {"default": 0, "min": 0, "max": nodes.MAX_RESOLUTION, "step": 8}),
},
}
RETURN_TYPES = ("NOISE",)
RETURN_TYPES = ("NOISE_IMAGE",)
FUNCTION = "doit"
CATEGORY = "InspirePack/Prompt"
+4 -4
View File
@@ -460,7 +460,7 @@ class RegionalSeedExplorerMask:
"required": {
"mask": ("MASK",),
"noise": ("NOISE",),
"noise": ("NOISE_IMAGE",),
"seed_prompt": ("STRING", {"multiline": True, "dynamicPrompts": False, "pysssss.autocomplete": False}),
"enable_additional": ("BOOLEAN", {"default": True, "label_on": "true", "label_off": "false"}),
"additional_seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
@@ -471,7 +471,7 @@ class RegionalSeedExplorerMask:
{"variation_method": (["linear", "slerp"],), }
}
RETURN_TYPES = ("NOISE",)
RETURN_TYPES = ("NOISE_IMAGE",)
FUNCTION = "doit"
CATEGORY = "InspirePack/Regional"
@@ -517,7 +517,7 @@ class RegionalSeedExplorerColorMask:
"color_mask": ("IMAGE",),
"mask_color": ("STRING", {"multiline": False, "default": "#FFFFFF"}),
"noise": ("NOISE",),
"noise": ("NOISE_IMAGE",),
"seed_prompt": ("STRING", {"multiline": True, "dynamicPrompts": False, "pysssss.autocomplete": False}),
"enable_additional": ("BOOLEAN", {"default": True, "label_on": "true", "label_off": "false"}),
"additional_seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
@@ -528,7 +528,7 @@ class RegionalSeedExplorerColorMask:
{"variation_method": (["linear", "slerp"],), }
}
RETURN_TYPES = ("NOISE", "MASK")
RETURN_TYPES = ("NOISE_IMAGE", "MASK")
FUNCTION = "doit"
CATEGORY = "InspirePack/Regional"
+84 -86
View File
@@ -34,19 +34,17 @@ app.registerExtension({
node._value = "Preset";
node.widgets[preset_i].callback = (v, canvas, node, pos, e) => {
node.widgets[vector_i].value = node._value.split(':')[1];
if(node.widgets_values) {
node.widgets_values[vector_i] = node.widgets[preset_i].value;
}
}
Object.defineProperty(node.widgets[preset_i], "value", {
set: (value) => {
const stackTrace = new Error().stack;
if(stackTrace.includes('inner_value_change')) {
if(value != "Preset") {
node.widgets[vector_i].value = value.split(':')[1];
if(node.widgets_values) {
node.widgets_values[vector_i] = node.widgets[preset_i].value;
}
}
}
node._value = value;
if(value != "Preset")
node._value = value;
},
get: () => {
return node._value;
@@ -77,86 +75,86 @@ app.registerExtension({
let preset_i = 9;
let vector_i = 10;
node._value = "Preset";
Object.defineProperty(node.widgets[preset_i], "value", {
set: (value) => {
const stackTrace = new Error().stack;
if(stackTrace.includes('inner_value_change')) {
if(value != "Preset") {
if(!value.startsWith('@') && node.widgets[vector_i].value != "")
node.widgets[vector_i].value += "\n";
if(value.startsWith('@')) {
let spec = value.split(':')[1];
var n;
var sub_n = null;
var block = null;
if(isNaN(spec)) {
let sub_spec = spec.split(',');
node.widgets[preset_i].callback = (v, canvas, node, pos, e) => {
let value = node._value;
if(!value.startsWith('@') && node.widgets[vector_i].value != "")
node.widgets[vector_i].value += "\n";
if(value.startsWith('@')) {
let spec = value.split(':')[1];
var n;
var sub_n = null;
var block = null;
if(sub_spec.length != 3) {
node.widgets_values[vector_i] = '!! SPEC ERROR !!';
node._value = '';
return;
}
if(isNaN(spec)) {
let sub_spec = spec.split(',');
n = parseInt(sub_spec[0].trim());
sub_n = parseInt(sub_spec[1].trim());
block = parseInt(sub_spec[2].trim());
}
else {
n = parseInt(spec.trim());
}
node.widgets[vector_i].value = "";
if(sub_n == null) {
for(let i=1; i<=n; i++) {
var temp = "";
for(let j=1; j<=n; j++) {
if(temp!='')
temp += ',';
if(j==i)
temp += 'A';
else
temp += '0';
}
node.widgets[vector_i].value += `B${i}:${temp}\n`;
}
}
else {
for(let i=1; i<=sub_n; i++) {
var temp = "";
for(let j=1; j<=n; j++) {
if(temp!='')
temp += ',';
if(block!=j)
temp += '0';
else {
temp += ' ';
for(let k=1; k<=sub_n; k++) {
if(k==i)
temp += 'A ';
else
temp += '0 ';
}
}
}
node.widgets[vector_i].value += `B${block}.SUB${i}:${temp}\n`;
}
}
}
else {
node.widgets[vector_i].value += `${value}/${value.split(':')[0]}`;
}
if(node.widgets_values) {
node.widgets_values[vector_i] = node.widgets[preset_i].value;
}
}
if(sub_spec.length != 3) {
node.widgets_values[vector_i] = '!! SPEC ERROR !!';
node._value = '';
return;
}
node._value = value;
n = parseInt(sub_spec[0].trim());
sub_n = parseInt(sub_spec[1].trim());
block = parseInt(sub_spec[2].trim());
}
else {
n = parseInt(spec.trim());
}
node.widgets[vector_i].value = "";
if(sub_n == null) {
for(let i=1; i<=n; i++) {
var temp = "";
for(let j=1; j<=n; j++) {
if(temp!='')
temp += ',';
if(j==i)
temp += 'A';
else
temp += '0';
}
node.widgets[vector_i].value += `B${i}:${temp}\n`;
}
}
else {
for(let i=1; i<=sub_n; i++) {
var temp = "";
for(let j=1; j<=n; j++) {
if(temp!='')
temp += ',';
if(block!=j)
temp += '0';
else {
temp += ' ';
for(let k=1; k<=sub_n; k++) {
if(k==i)
temp += 'A ';
else
temp += '0 ';
}
}
}
node.widgets[vector_i].value += `B${block}.SUB${i}:${temp}\n`;
}
}
}
else {
node.widgets[vector_i].value += `${value}/${value.split(':')[0]}`;
}
if(node.widgets_values) {
node.widgets_values[vector_i] = node.widgets[preset_i].value;
}
}
Object.defineProperty(node.widgets[preset_i], "value", {
set: (value) => {
if(value != 'Preset')
node._value = value;
},
get: () => {
return node._value;
+75 -75
View File
@@ -42,35 +42,38 @@ app.registerExtension({
// lora selector, wildcard selector
let combo_id = 5;
Object.defineProperty(node.widgets[combo_id], "value", {
set: (value) => {
const stackTrace = new Error().stack;
if(stackTrace.includes('inner_value_change')) {
if(value != "Select the LoRA to add to the text") {
let lora_name = value;
if (lora_name.endsWith('.safetensors')) {
lora_name = lora_name.slice(0, -12);
}
// lora
node.widgets[combo_id].callback = (value, canvas, node, pos, e) => {
let lora_name = node._value;
if(lora_name.endsWith('.safetensors')) {
lora_name = lora_name.slice(0, -12);
}
wildcard_text_widget.value += `<lora:${lora_name}>`;
}
}
},
get: () => { return "Select the LoRA to add to the text"; }
});
wildcard_text_widget.value += `<lora:${lora_name}>`;
}
Object.defineProperty(node.widgets[combo_id], "value", {
set: (value) => {
if (value !== "Select the LoRA to add to the text")
node._value = value;
},
get: () => { return "Select the LoRA to add to the text"; }
});
// wildcard
node.widgets[combo_id+1].callback = (value, canvas, node, pos, e) => {
if(wildcard_text_widget.value != '')
wildcard_text_widget.value += ', '
wildcard_text_widget.value += node._wildcard_value;
}
Object.defineProperty(node.widgets[combo_id+1], "value", {
set: (value) => {
const stackTrace = new Error().stack;
if(stackTrace.includes('inner_value_change')) {
if(value != "Select the Wildcard to add to the text") {
if(wildcard_text_widget.value != '')
wildcard_text_widget.value += ', '
wildcard_text_widget.value += value;
}
}
},
if (value !== "Select the Wildcard to add to the text")
node._wildcard_value = value;
},
get: () => { return "Select the Wildcard to add to the text"; }
});
@@ -115,47 +118,46 @@ app.registerExtension({
// lora selector, wildcard selector
let combo_id = 5;
node.widgets[combo_id].callback = (value, canvas, node, pos, e) => {
let lora_name = node._lora_value;
if (lora_name.endsWith('.safetensors')) {
lora_name = lora_name.slice(0, -12);
}
if(direction_widget.value) {
pos_wildcard_text_widget.value += `<lora:${lora_name}>`;
}
else {
neg_wildcard_text_widget.value += `<lora:${lora_name}>`;
}
}
Object.defineProperty(node.widgets[combo_id], "value", {
set: (value) => {
const stackTrace = new Error().stack;
if(stackTrace.includes('inner_value_change')) {
if(value != "Select the LoRA to add to the text") {
let lora_name = value;
if (lora_name.endsWith('.safetensors')) {
lora_name = lora_name.slice(0, -12);
}
if(direction_widget.value) {
pos_wildcard_text_widget.value += `<lora:${lora_name}>`;
}
else {
neg_wildcard_text_widget.value += `<lora:${lora_name}>`;
}
}
}
if (value !== "Select the LoRA to add to the text")
node._lora_value = value;
},
get: () => { return "Select the LoRA to add to the text"; }
});
node.widgets[combo_id+1].callback = (value, canvas, node, pos, e) => {
let w = null;
if(direction_widget.value) {
w = pos_wildcard_text_widget;
}
else {
w = neg_wildcard_text_widget;
}
if(w.value != '')
w.value += ', '
w.value += node._wildcard_value;
}
Object.defineProperty(node.widgets[combo_id+1], "value", {
set: (value) => {
const stackTrace = new Error().stack;
if(stackTrace.includes('inner_value_change')) {
if(value != "Select the Wildcard to add to the text") {
let w = null;
if(direction_widget.value) {
w = pos_wildcard_text_widget;
}
else {
w = neg_wildcard_text_widget;
}
if(w.value != '')
w.value += ', '
w.value += value;
}
}
if (value !== "Select the Wildcard to add to the text")
node._wildcard_value = value;
},
get: () => { return "Select the Wildcard to add to the text"; }
});
@@ -205,24 +207,22 @@ app.registerExtension({
}
});
preset_widget.callback = (value, canvas, node, pos, e) => {
if(node.widgets[2].value) {
node.widgets[2].value += ', ';
}
const y = node._preset_value.split(':');
if(y.length == 2)
node.widgets[2].value += y[1].trim();
else
node.widgets[2].value += node._preset_value.trim();
}
Object.defineProperty(preset_widget, "value", {
set: (x) => {
const stackTrace = new Error().stack;
if(stackTrace.includes('inner_value_change')) {
if(node.widgets[2].value) {
node.widgets[2].value += ', ';
}
const y = x.split(':');
if(y.length == 2)
node.widgets[2].value += y[1].trim();
else
node.widgets[2].value += x.trim();
if(node.widgets_values) {
node.widgets_values[2] = node.widgets[2].values;
}
};
set: (value) => {
if (value !== "#PRESET")
node._preset_value = value;
},
get: () => { return '#PRESET'; }
});
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "comfyui-inspire-pack"
description = "This extension provides various nodes to support Lora Block Weight, Regional Nodes, Backend Cache, Prompt Utils, List Utils, Noise(Seed) Utils, ... and the Impact Pack."
version = "1.7"
version = "1.9.1"
license = { file = "LICENSE" }
dependencies = ["matplotlib", "cachetools"]