Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c7c98a965 | ||
|
|
dc2eb75b85 | ||
|
|
fa34efe3bd | ||
|
|
5cbaa9e07c | ||
|
|
c7427375ee | ||
|
|
22d1241a50 | ||
|
|
f04229b84d | ||
|
|
f067ad15d1 | ||
|
|
483004dd1d | ||
|
|
00a5d08103 | ||
|
|
d043997d30 |
2
.github/workflows/stable-release.yml
vendored
2
.github/workflows/stable-release.yml
vendored
@@ -12,7 +12,7 @@ on:
|
||||
description: 'CUDA version'
|
||||
required: true
|
||||
type: string
|
||||
default: "121"
|
||||
default: "124"
|
||||
python_minor:
|
||||
description: 'Python minor version'
|
||||
required: true
|
||||
|
||||
@@ -94,6 +94,8 @@ Workflow examples can be found on the [Examples page](https://comfyanonymous.git
|
||||
| Alt + `+` | Canvas Zoom in |
|
||||
| Alt + `-` | Canvas Zoom out |
|
||||
| Ctrl + Shift + LMB + Vertical drag | Canvas Zoom in/out |
|
||||
| P | Pin/Unpin selected nodes |
|
||||
| Ctrl + G | Group selected nodes |
|
||||
| Q | Toggle visibility of the queue |
|
||||
| H | Toggle visibility of history |
|
||||
| R | Refresh graph |
|
||||
|
||||
@@ -92,6 +92,8 @@ class LatentPreviewMethod(enum.Enum):
|
||||
|
||||
parser.add_argument("--preview-method", type=LatentPreviewMethod, default=LatentPreviewMethod.NoPreviews, help="Default preview method for sampler nodes.", action=EnumAction)
|
||||
|
||||
parser.add_argument("--preview-size", type=int, default=512, help="Sets the maximum preview size for sampler nodes.")
|
||||
|
||||
cache_group = parser.add_mutually_exclusive_group()
|
||||
cache_group.add_argument("--cache-classic", action="store_true", help="Use the old style (aggressive) caching.")
|
||||
cache_group.add_argument("--cache-lru", type=int, default=0, help="Use LRU caching with a maximum of N node results cached. May use more RAM/VRAM.")
|
||||
|
||||
@@ -430,9 +430,9 @@ def load_controlnet_hunyuandit(controlnet_data):
|
||||
control = ControlNet(control_model, compression_ratio=1, latent_format=latent_format, load_device=load_device, manual_cast_dtype=manual_cast_dtype, extra_conds=extra_conds, strength_type=StrengthType.CONSTANT)
|
||||
return control
|
||||
|
||||
def load_controlnet_flux_xlabs(sd):
|
||||
def load_controlnet_flux_xlabs_mistoline(sd, mistoline=False):
|
||||
model_config, operations, load_device, unet_dtype, manual_cast_dtype, offload_device = controlnet_config(sd)
|
||||
control_model = comfy.ldm.flux.controlnet.ControlNetFlux(operations=operations, device=offload_device, dtype=unet_dtype, **model_config.unet_config)
|
||||
control_model = comfy.ldm.flux.controlnet.ControlNetFlux(mistoline=mistoline, operations=operations, device=offload_device, dtype=unet_dtype, **model_config.unet_config)
|
||||
control_model = controlnet_load_state_dict(control_model, sd)
|
||||
extra_conds = ['y', 'guidance']
|
||||
control = ControlNet(control_model, load_device=load_device, manual_cast_dtype=manual_cast_dtype, extra_conds=extra_conds)
|
||||
@@ -457,6 +457,10 @@ def load_controlnet_flux_instantx(sd):
|
||||
control = ControlNet(control_model, compression_ratio=1, latent_format=latent_format, load_device=load_device, manual_cast_dtype=manual_cast_dtype, extra_conds=extra_conds)
|
||||
return control
|
||||
|
||||
def convert_mistoline(sd):
|
||||
return comfy.utils.state_dict_prefix_replace(sd, {"single_controlnet_blocks.": "controlnet_single_blocks."})
|
||||
|
||||
|
||||
def load_controlnet(ckpt_path, model=None):
|
||||
controlnet_data = comfy.utils.load_torch_file(ckpt_path, safe_load=True)
|
||||
if 'after_proj_list.18.bias' in controlnet_data.keys(): #Hunyuan DiT
|
||||
@@ -518,13 +522,15 @@ def load_controlnet(ckpt_path, model=None):
|
||||
if len(leftover_keys) > 0:
|
||||
logging.warning("leftover keys: {}".format(leftover_keys))
|
||||
controlnet_data = new_sd
|
||||
elif "controlnet_blocks.0.weight" in controlnet_data: #SD3 diffusers format
|
||||
elif "controlnet_blocks.0.weight" in controlnet_data:
|
||||
if "double_blocks.0.img_attn.norm.key_norm.scale" in controlnet_data:
|
||||
return load_controlnet_flux_xlabs(controlnet_data)
|
||||
return load_controlnet_flux_xlabs_mistoline(controlnet_data)
|
||||
elif "pos_embed_input.proj.weight" in controlnet_data:
|
||||
return load_controlnet_mmdit(controlnet_data)
|
||||
return load_controlnet_mmdit(controlnet_data) #SD3 diffusers controlnet
|
||||
elif "controlnet_x_embedder.weight" in controlnet_data:
|
||||
return load_controlnet_flux_instantx(controlnet_data)
|
||||
elif "controlnet_blocks.0.linear.weight" in controlnet_data: #mistoline flux
|
||||
return load_controlnet_flux_xlabs_mistoline(convert_mistoline(controlnet_data), mistoline=True)
|
||||
|
||||
pth_key = 'control_model.zero_convs.0.0.weight'
|
||||
pth = False
|
||||
|
||||
@@ -41,9 +41,8 @@ def manual_stochastic_round_to_float8(x, dtype, generator=None):
|
||||
(2.0 ** (exponent - EXPONENT_BIAS)) * (1.0 + abs_x),
|
||||
(2.0 ** (-EXPONENT_BIAS + 1)) * abs_x
|
||||
)
|
||||
del abs_x
|
||||
|
||||
return sign.to(dtype=dtype)
|
||||
return sign
|
||||
|
||||
|
||||
|
||||
@@ -57,6 +56,11 @@ def stochastic_rounding(value, dtype, seed=0):
|
||||
if dtype == torch.float8_e4m3fn or dtype == torch.float8_e5m2:
|
||||
generator = torch.Generator(device=value.device)
|
||||
generator.manual_seed(seed)
|
||||
return manual_stochastic_round_to_float8(value, dtype, generator=generator)
|
||||
output = torch.empty_like(value, dtype=dtype)
|
||||
num_slices = max(1, (value.numel() / (4096 * 4096)))
|
||||
slice_size = max(1, round(value.shape[0] / num_slices))
|
||||
for i in range(0, value.shape[0], slice_size):
|
||||
output[i:i+slice_size].copy_(manual_stochastic_round_to_float8(value[i:i+slice_size], dtype, generator=generator))
|
||||
return output
|
||||
|
||||
return value.to(dtype=dtype)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#Original code can be found on: https://github.com/XLabs-AI/x-flux/blob/main/src/flux/controlnet.py
|
||||
#modified to support different types of flux controlnets
|
||||
|
||||
import torch
|
||||
import math
|
||||
@@ -12,22 +13,65 @@ from .layers import (DoubleStreamBlock, EmbedND, LastLayer,
|
||||
from .model import Flux
|
||||
import comfy.ldm.common_dit
|
||||
|
||||
class MistolineCondDownsamplBlock(nn.Module):
|
||||
def __init__(self, dtype=None, device=None, operations=None):
|
||||
super().__init__()
|
||||
self.encoder = nn.Sequential(
|
||||
operations.Conv2d(3, 16, 3, padding=1, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 1, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, stride=2, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, stride=2, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, stride=2, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 1, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device)
|
||||
)
|
||||
|
||||
def forward(self, x):
|
||||
return self.encoder(x)
|
||||
|
||||
class MistolineControlnetBlock(nn.Module):
|
||||
def __init__(self, hidden_size, dtype=None, device=None, operations=None):
|
||||
super().__init__()
|
||||
self.linear = operations.Linear(hidden_size, hidden_size, dtype=dtype, device=device)
|
||||
self.act = nn.SiLU()
|
||||
|
||||
def forward(self, x):
|
||||
return self.act(self.linear(x))
|
||||
|
||||
|
||||
class ControlNetFlux(Flux):
|
||||
def __init__(self, latent_input=False, num_union_modes=0, image_model=None, dtype=None, device=None, operations=None, **kwargs):
|
||||
def __init__(self, latent_input=False, num_union_modes=0, mistoline=False, image_model=None, dtype=None, device=None, operations=None, **kwargs):
|
||||
super().__init__(final_layer=False, dtype=dtype, device=device, operations=operations, **kwargs)
|
||||
|
||||
self.main_model_double = 19
|
||||
self.main_model_single = 38
|
||||
|
||||
self.mistoline = mistoline
|
||||
# add ControlNet blocks
|
||||
if self.mistoline:
|
||||
control_block = lambda : MistolineControlnetBlock(self.hidden_size, dtype=dtype, device=device, operations=operations)
|
||||
else:
|
||||
control_block = lambda : operations.Linear(self.hidden_size, self.hidden_size, dtype=dtype, device=device)
|
||||
|
||||
self.controlnet_blocks = nn.ModuleList([])
|
||||
for _ in range(self.params.depth):
|
||||
controlnet_block = operations.Linear(self.hidden_size, self.hidden_size, dtype=dtype, device=device)
|
||||
self.controlnet_blocks.append(controlnet_block)
|
||||
self.controlnet_blocks.append(control_block())
|
||||
|
||||
self.controlnet_single_blocks = nn.ModuleList([])
|
||||
for _ in range(self.params.depth_single_blocks):
|
||||
self.controlnet_single_blocks.append(operations.Linear(self.hidden_size, self.hidden_size, dtype=dtype, device=device))
|
||||
self.controlnet_single_blocks.append(control_block())
|
||||
|
||||
self.num_union_modes = num_union_modes
|
||||
self.controlnet_mode_embedder = None
|
||||
@@ -38,23 +82,26 @@ class ControlNetFlux(Flux):
|
||||
self.latent_input = latent_input
|
||||
self.pos_embed_input = operations.Linear(self.in_channels, self.hidden_size, bias=True, dtype=dtype, device=device)
|
||||
if not self.latent_input:
|
||||
self.input_hint_block = nn.Sequential(
|
||||
operations.Conv2d(3, 16, 3, padding=1, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, stride=2, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, stride=2, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, stride=2, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device)
|
||||
)
|
||||
if self.mistoline:
|
||||
self.input_cond_block = MistolineCondDownsamplBlock(dtype=dtype, device=device, operations=operations)
|
||||
else:
|
||||
self.input_hint_block = nn.Sequential(
|
||||
operations.Conv2d(3, 16, 3, padding=1, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, stride=2, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, stride=2, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, stride=2, dtype=dtype, device=device),
|
||||
nn.SiLU(),
|
||||
operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device)
|
||||
)
|
||||
|
||||
def forward_orig(
|
||||
self,
|
||||
@@ -73,9 +120,6 @@ class ControlNetFlux(Flux):
|
||||
|
||||
# running on sequences img
|
||||
img = self.img_in(img)
|
||||
if not self.latent_input:
|
||||
controlnet_cond = self.input_hint_block(controlnet_cond)
|
||||
controlnet_cond = rearrange(controlnet_cond, "b c (h ph) (w pw) -> b (h w) (c ph pw)", ph=2, pw=2)
|
||||
|
||||
controlnet_cond = self.pos_embed_input(controlnet_cond)
|
||||
img = img + controlnet_cond
|
||||
@@ -131,9 +175,14 @@ class ControlNetFlux(Flux):
|
||||
patch_size = 2
|
||||
if self.latent_input:
|
||||
hint = comfy.ldm.common_dit.pad_to_patch_size(hint, (patch_size, patch_size))
|
||||
hint = rearrange(hint, "b c (h ph) (w pw) -> b (h w) (c ph pw)", ph=patch_size, pw=patch_size)
|
||||
elif self.mistoline:
|
||||
hint = hint * 2.0 - 1.0
|
||||
hint = self.input_cond_block(hint)
|
||||
else:
|
||||
hint = hint * 2.0 - 1.0
|
||||
hint = self.input_hint_block(hint)
|
||||
|
||||
hint = rearrange(hint, "b c (h ph) (w pw) -> b (h w) (c ph pw)", ph=patch_size, pw=patch_size)
|
||||
|
||||
bs, c, h, w = x.shape
|
||||
x = comfy.ldm.common_dit.pad_to_patch_size(x, (patch_size, patch_size))
|
||||
|
||||
@@ -842,6 +842,11 @@ class UNetModel(nn.Module):
|
||||
t_emb = timestep_embedding(timesteps, self.model_channels, repeat_only=False).to(x.dtype)
|
||||
emb = self.time_embed(t_emb)
|
||||
|
||||
if "emb_patch" in transformer_patches:
|
||||
patch = transformer_patches["emb_patch"]
|
||||
for p in patch:
|
||||
emb = p(emb, self.model_channels, transformer_options)
|
||||
|
||||
if self.num_classes is not None:
|
||||
assert y.shape[0] == x.shape[0]
|
||||
emb = emb + self.label_emb(y)
|
||||
|
||||
@@ -324,6 +324,7 @@ def model_lora_keys_unet(model, key_map={}):
|
||||
to = diffusers_keys[k]
|
||||
key_map["transformer.{}".format(k[:-len(".weight")])] = to #simpletrainer and probably regular diffusers flux lora format
|
||||
key_map["lycoris_{}".format(k[:-len(".weight")].replace(".", "_"))] = to #simpletrainer lycoris
|
||||
key_map["lora_transformer_{}".format(k[:-len(".weight")].replace(".", "_"))] = to #onetrainer
|
||||
|
||||
return key_map
|
||||
|
||||
@@ -527,20 +528,40 @@ def calculate_weight(patches, weight, key, intermediate_dtype=torch.float32):
|
||||
except Exception as e:
|
||||
logging.error("ERROR {} {} {}".format(patch_type, key, e))
|
||||
elif patch_type == "glora":
|
||||
if v[4] is not None:
|
||||
alpha = v[4] / v[0].shape[0]
|
||||
else:
|
||||
alpha = 1.0
|
||||
|
||||
dora_scale = v[5]
|
||||
|
||||
old_glora = False
|
||||
if v[3].shape[1] == v[2].shape[0] == v[0].shape[0] == v[1].shape[1]:
|
||||
rank = v[0].shape[0]
|
||||
old_glora = True
|
||||
|
||||
if v[3].shape[0] == v[2].shape[1] == v[0].shape[1] == v[1].shape[0]:
|
||||
if old_glora and v[1].shape[0] == weight.shape[0] and weight.shape[0] == weight.shape[1]:
|
||||
pass
|
||||
else:
|
||||
old_glora = False
|
||||
rank = v[1].shape[0]
|
||||
|
||||
a1 = comfy.model_management.cast_to_device(v[0].flatten(start_dim=1), weight.device, intermediate_dtype)
|
||||
a2 = comfy.model_management.cast_to_device(v[1].flatten(start_dim=1), weight.device, intermediate_dtype)
|
||||
b1 = comfy.model_management.cast_to_device(v[2].flatten(start_dim=1), weight.device, intermediate_dtype)
|
||||
b2 = comfy.model_management.cast_to_device(v[3].flatten(start_dim=1), weight.device, intermediate_dtype)
|
||||
|
||||
if v[4] is not None:
|
||||
alpha = v[4] / rank
|
||||
else:
|
||||
alpha = 1.0
|
||||
|
||||
try:
|
||||
lora_diff = (torch.mm(b2, b1) + torch.mm(torch.mm(weight.flatten(start_dim=1).to(dtype=intermediate_dtype), a2), a1)).reshape(weight.shape)
|
||||
if old_glora:
|
||||
lora_diff = (torch.mm(b2, b1) + torch.mm(torch.mm(weight.flatten(start_dim=1).to(dtype=intermediate_dtype), a2), a1)).reshape(weight.shape) #old lycoris glora
|
||||
else:
|
||||
if weight.dim() > 2:
|
||||
lora_diff = torch.einsum("o i ..., i j -> o j ...", torch.einsum("o i ..., i j -> o j ...", weight.to(dtype=intermediate_dtype), a1), a2).reshape(weight.shape)
|
||||
else:
|
||||
lora_diff = torch.mm(torch.mm(weight.to(dtype=intermediate_dtype), a1), a2).reshape(weight.shape)
|
||||
lora_diff += torch.mm(b1, b2).reshape(weight.shape)
|
||||
|
||||
if dora_scale is not None:
|
||||
weight = function(weight_decompose(dora_scale, weight, lora_diff, alpha, strength, intermediate_dtype))
|
||||
else:
|
||||
|
||||
@@ -426,7 +426,7 @@ def free_memory(memory_required, device, keep_loaded=[]):
|
||||
shift_model = current_loaded_models[i]
|
||||
if shift_model.device == device:
|
||||
if shift_model not in keep_loaded:
|
||||
can_unload.append((sys.getrefcount(shift_model.model), shift_model.model_memory(), i))
|
||||
can_unload.append((-shift_model.model_offloaded_memory(), sys.getrefcount(shift_model.model), shift_model.model_memory(), i))
|
||||
shift_model.currently_used = False
|
||||
|
||||
for x in sorted(can_unload):
|
||||
|
||||
@@ -98,7 +98,7 @@ class CacheKeySetInputSignature(CacheKeySet):
|
||||
class_type = node["class_type"]
|
||||
class_def = nodes.NODE_CLASS_MAPPINGS[class_type]
|
||||
signature = [class_type, self.is_changed_cache.get(node_id)]
|
||||
if self.include_node_id_in_input() or (hasattr(class_def, "NOT_IDEMPOTENT") and class_def.NOT_IDEMPOTENT):
|
||||
if self.include_node_id_in_input() or (hasattr(class_def, "NOT_IDEMPOTENT") and class_def.NOT_IDEMPOTENT) or "UNIQUE_ID" in class_def.INPUT_TYPES().get("hidden", {}).values():
|
||||
signature.append(node_id)
|
||||
inputs = node["inputs"]
|
||||
for key in sorted(inputs.keys()):
|
||||
|
||||
91
comfy_extras/nodes_lora_extract.py
Normal file
91
comfy_extras/nodes_lora_extract.py
Normal file
@@ -0,0 +1,91 @@
|
||||
import torch
|
||||
import comfy.model_management
|
||||
import comfy.utils
|
||||
import folder_paths
|
||||
import os
|
||||
import logging
|
||||
|
||||
CLAMP_QUANTILE = 0.99
|
||||
|
||||
def extract_lora(diff, rank):
|
||||
conv2d = (len(diff.shape) == 4)
|
||||
kernel_size = None if not conv2d else diff.size()[2:4]
|
||||
conv2d_3x3 = conv2d and kernel_size != (1, 1)
|
||||
out_dim, in_dim = diff.size()[0:2]
|
||||
rank = min(rank, in_dim, out_dim)
|
||||
|
||||
if conv2d:
|
||||
if conv2d_3x3:
|
||||
diff = diff.flatten(start_dim=1)
|
||||
else:
|
||||
diff = diff.squeeze()
|
||||
|
||||
|
||||
U, S, Vh = torch.linalg.svd(diff.float())
|
||||
U = U[:, :rank]
|
||||
S = S[:rank]
|
||||
U = U @ torch.diag(S)
|
||||
Vh = Vh[:rank, :]
|
||||
|
||||
dist = torch.cat([U.flatten(), Vh.flatten()])
|
||||
hi_val = torch.quantile(dist, CLAMP_QUANTILE)
|
||||
low_val = -hi_val
|
||||
|
||||
U = U.clamp(low_val, hi_val)
|
||||
Vh = Vh.clamp(low_val, hi_val)
|
||||
if conv2d:
|
||||
U = U.reshape(out_dim, rank, 1, 1)
|
||||
Vh = Vh.reshape(rank, in_dim, kernel_size[0], kernel_size[1])
|
||||
return (U, Vh)
|
||||
|
||||
class LoraSave:
|
||||
def __init__(self):
|
||||
self.output_dir = folder_paths.get_output_directory()
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {"required": {"filename_prefix": ("STRING", {"default": "loras/ComfyUI_extracted_lora"}),
|
||||
"rank": ("INT", {"default": 8, "min": 1, "max": 1024, "step": 1}),
|
||||
},
|
||||
"optional": {"model_diff": ("MODEL",),},
|
||||
}
|
||||
RETURN_TYPES = ()
|
||||
FUNCTION = "save"
|
||||
OUTPUT_NODE = True
|
||||
|
||||
CATEGORY = "_for_testing"
|
||||
|
||||
def save(self, filename_prefix, rank, model_diff=None):
|
||||
if model_diff is None:
|
||||
return {}
|
||||
|
||||
full_output_folder, filename, counter, subfolder, filename_prefix = folder_paths.get_save_image_path(filename_prefix, self.output_dir)
|
||||
|
||||
output_sd = {}
|
||||
prefix_key = "diffusion_model."
|
||||
stored = set()
|
||||
|
||||
comfy.model_management.load_models_gpu([model_diff], force_patch_weights=True)
|
||||
sd = model_diff.model_state_dict(filter_prefix=prefix_key)
|
||||
|
||||
for k in sd:
|
||||
if k.endswith(".weight"):
|
||||
weight_diff = sd[k]
|
||||
if weight_diff.ndim < 2:
|
||||
continue
|
||||
try:
|
||||
out = extract_lora(weight_diff, rank)
|
||||
output_sd["{}.lora_up.weight".format(k[:-7])] = out[0].contiguous().half().cpu()
|
||||
output_sd["{}.lora_down.weight".format(k[:-7])] = out[1].contiguous().half().cpu()
|
||||
except:
|
||||
logging.warning("Could not generate lora weights for key {}, is the weight difference a zero?".format(k))
|
||||
|
||||
output_checkpoint = f"{filename}_{counter:05}_.safetensors"
|
||||
output_checkpoint = os.path.join(full_output_folder, output_checkpoint)
|
||||
|
||||
comfy.utils.save_torch_file(output_sd, output_checkpoint, metadata=None)
|
||||
return {}
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"LoraSave": LoraSave
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import folder_paths
|
||||
import comfy.utils
|
||||
import logging
|
||||
|
||||
MAX_PREVIEW_RESOLUTION = 512
|
||||
MAX_PREVIEW_RESOLUTION = args.preview_size
|
||||
|
||||
def preview_to_image(latent_image):
|
||||
latents_ubyte = (((latent_image + 1.0) / 2.0).clamp(0, 1) # change scale from -1..1 to 0..1
|
||||
|
||||
1
main.py
1
main.py
@@ -247,6 +247,7 @@ if __name__ == "__main__":
|
||||
folder_paths.add_model_folder_path("clip", os.path.join(folder_paths.get_output_directory(), "clip"))
|
||||
folder_paths.add_model_folder_path("vae", os.path.join(folder_paths.get_output_directory(), "vae"))
|
||||
folder_paths.add_model_folder_path("diffusion_models", os.path.join(folder_paths.get_output_directory(), "diffusion_models"))
|
||||
folder_paths.add_model_folder_path("loras", os.path.join(folder_paths.get_output_directory(), "loras"))
|
||||
|
||||
if args.input_directory:
|
||||
input_dir = os.path.abspath(args.input_directory)
|
||||
|
||||
1
nodes.py
1
nodes.py
@@ -2101,6 +2101,7 @@ def init_builtin_extra_nodes():
|
||||
"nodes_controlnet.py",
|
||||
"nodes_hunyuan.py",
|
||||
"nodes_flux.py",
|
||||
"nodes_lora_extract.py",
|
||||
]
|
||||
|
||||
import_failed = []
|
||||
|
||||
1
web/assets/index-BD-Ia1C4.js.map
generated
vendored
1
web/assets/index-BD-Ia1C4.js.map
generated
vendored
File diff suppressed because one or more lines are too long
0
web/assets/index-DjWyclij.css → web/assets/index-BRhY6FpL.css
generated
vendored
0
web/assets/index-DjWyclij.css → web/assets/index-BRhY6FpL.css
generated
vendored
10
web/assets/index-BD-Ia1C4.js → web/assets/index-CrROdkG4.js
generated
vendored
10
web/assets/index-BD-Ia1C4.js → web/assets/index-CrROdkG4.js
generated
vendored
@@ -1,6 +1,6 @@
|
||||
var __defProp = Object.defineProperty;
|
||||
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||
import { C as ComfyDialog, $ as $el, a as ComfyApp, b as app, L as LGraphCanvas, c as LiteGraph, d as LGraphNode, e as applyTextReplacements, f as ComfyWidgets, g as addValueControlWidgets, D as DraggableList, h as api, u as useToastStore, i as LGraphGroup } from "./index-CI3N807S.js";
|
||||
import { C as ComfyDialog, $ as $el, a as ComfyApp, b as app, L as LGraphCanvas, c as LiteGraph, d as LGraphNode, e as applyTextReplacements, f as ComfyWidgets, g as addValueControlWidgets, D as DraggableList, h as api, i as LGraphGroup, u as useToastStore } from "./index-Dfv2aLsq.js";
|
||||
class ClipspaceDialog extends ComfyDialog {
|
||||
static {
|
||||
__name(this, "ClipspaceDialog");
|
||||
@@ -3650,7 +3650,7 @@ app.registerExtension({
|
||||
content: "Add Group For Selected Nodes",
|
||||
disabled: !Object.keys(app.canvas.selected_nodes || {}).length,
|
||||
callback: /* @__PURE__ */ __name(() => {
|
||||
var group2 = new LiteGraph.LGraphGroup();
|
||||
const group2 = new LGraphGroup();
|
||||
addNodesToGroup(group2, this.selected_nodes);
|
||||
app.canvas.graph.add(group2);
|
||||
this.graph.change();
|
||||
@@ -5088,7 +5088,7 @@ app.registerExtension({
|
||||
data = JSON.parse(data);
|
||||
const nodeIds = Object.keys(app.canvas.selected_nodes);
|
||||
for (let i = 0; i < nodeIds.length; i++) {
|
||||
const node = app.graph.getNodeById(Number.parseInt(nodeIds[i]));
|
||||
const node = app.graph.getNodeById(nodeIds[i]);
|
||||
const nodeData = node?.constructor.nodeData;
|
||||
let groupData = GroupNodeHandler.getGroupData(node);
|
||||
if (groupData) {
|
||||
@@ -5955,7 +5955,7 @@ app.registerExtension({
|
||||
},
|
||||
onNodeOutputsUpdated(nodeOutputs) {
|
||||
for (const [nodeId, output] of Object.entries(nodeOutputs)) {
|
||||
const node = app.graph.getNodeById(Number.parseInt(nodeId));
|
||||
const node = app.graph.getNodeById(nodeId);
|
||||
if ("audio" in output) {
|
||||
const audioUIWidget = node.widgets.find(
|
||||
(w) => w.name === "audioUI"
|
||||
@@ -6026,4 +6026,4 @@ app.registerExtension({
|
||||
};
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=index-BD-Ia1C4.js.map
|
||||
//# sourceMappingURL=index-CrROdkG4.js.map
|
||||
1
web/assets/index-CrROdkG4.js.map
generated
vendored
Normal file
1
web/assets/index-CrROdkG4.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
15027
web/assets/index-CI3N807S.js → web/assets/index-Dfv2aLsq.js
generated
vendored
15027
web/assets/index-CI3N807S.js → web/assets/index-Dfv2aLsq.js
generated
vendored
File diff suppressed because one or more lines are too long
2
web/assets/index-CI3N807S.js.map → web/assets/index-Dfv2aLsq.js.map
generated
vendored
2
web/assets/index-CI3N807S.js.map → web/assets/index-Dfv2aLsq.js.map
generated
vendored
File diff suppressed because one or more lines are too long
144
web/assets/index-_5czGnTA.css → web/assets/index-W4jP-SrU.css
generated
vendored
144
web/assets/index-_5czGnTA.css → web/assets/index-W4jP-SrU.css
generated
vendored
@@ -1475,21 +1475,21 @@
|
||||
width: 5rem !important;
|
||||
}
|
||||
|
||||
.info-chip[data-v-25bd5f50] {
|
||||
.info-chip[data-v-ffbfdf57] {
|
||||
background: transparent;
|
||||
}
|
||||
.setting-item[data-v-25bd5f50] {
|
||||
.setting-item[data-v-ffbfdf57] {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.setting-label[data-v-25bd5f50] {
|
||||
.setting-label[data-v-ffbfdf57] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
}
|
||||
.setting-input[data-v-25bd5f50] {
|
||||
.setting-input[data-v-ffbfdf57] {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
@@ -1497,19 +1497,19 @@
|
||||
}
|
||||
|
||||
/* Ensure PrimeVue components take full width of their container */
|
||||
.setting-input[data-v-25bd5f50] .p-inputtext,
|
||||
.setting-input[data-v-25bd5f50] .input-slider,
|
||||
.setting-input[data-v-25bd5f50] .p-select,
|
||||
.setting-input[data-v-25bd5f50] .p-togglebutton {
|
||||
.setting-input[data-v-ffbfdf57] .p-inputtext,
|
||||
.setting-input[data-v-ffbfdf57] .input-slider,
|
||||
.setting-input[data-v-ffbfdf57] .p-select,
|
||||
.setting-input[data-v-ffbfdf57] .p-togglebutton {
|
||||
width: 100%;
|
||||
max-width: 200px;
|
||||
}
|
||||
.setting-input[data-v-25bd5f50] .p-inputtext {
|
||||
.setting-input[data-v-ffbfdf57] .p-inputtext {
|
||||
max-width: unset;
|
||||
}
|
||||
|
||||
/* Special case for ToggleSwitch to align it to the right */
|
||||
.setting-input[data-v-25bd5f50] .p-toggleswitch {
|
||||
.setting-input[data-v-ffbfdf57] .p-toggleswitch {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
@@ -1655,21 +1655,21 @@
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.comfy-error-report[data-v-12539d86] {
|
||||
.comfy-error-report[data-v-a103fd62] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
.action-container[data-v-12539d86] {
|
||||
.action-container[data-v-a103fd62] {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.wrapper-pre[data-v-12539d86] {
|
||||
.wrapper-pre[data-v-a103fd62] {
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.no-results-placeholder[data-v-12539d86] {
|
||||
.no-results-placeholder[data-v-a103fd62] {
|
||||
padding-top: 0;
|
||||
}
|
||||
.lds-ring {
|
||||
@@ -3158,7 +3158,7 @@ body {
|
||||
overflow: hidden;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
background-color: var(--bg-color);
|
||||
background: var(--bg-color) var(--bg-img);
|
||||
color: var(--fg-color);
|
||||
min-height: -webkit-fill-available;
|
||||
max-height: -webkit-fill-available;
|
||||
@@ -3833,17 +3833,19 @@ audio.comfy-audio.empty-audio-widget {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.node-title-editor[data-v-77799b26] {
|
||||
.group-title-editor.node-title-editor[data-v-f0cbabc5] {
|
||||
z-index: 9999;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
[data-v-77799b26] .editable-text {
|
||||
[data-v-f0cbabc5] .editable-text {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
[data-v-77799b26] .editable-text input {
|
||||
[data-v-f0cbabc5] .editable-text input {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* Override the default font size */
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.side-bar-button-icon {
|
||||
@@ -4086,26 +4088,26 @@ audio.comfy-audio.empty-audio-widget {
|
||||
color: var(--error-text);
|
||||
}
|
||||
|
||||
.comfy-vue-node-search-container[data-v-077af1a9] {
|
||||
.comfy-vue-node-search-container[data-v-d28bffc4] {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-width: 24rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.comfy-vue-node-search-container[data-v-077af1a9] * {
|
||||
.comfy-vue-node-search-container[data-v-d28bffc4] * {
|
||||
pointer-events: auto;
|
||||
}
|
||||
.comfy-vue-node-preview-container[data-v-077af1a9] {
|
||||
.comfy-vue-node-preview-container[data-v-d28bffc4] {
|
||||
position: absolute;
|
||||
left: -350px;
|
||||
top: 50px;
|
||||
}
|
||||
.comfy-vue-node-search-box[data-v-077af1a9] {
|
||||
.comfy-vue-node-search-box[data-v-d28bffc4] {
|
||||
z-index: 10;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.option-container[data-v-077af1a9] {
|
||||
.option-container[data-v-d28bffc4] {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
@@ -4117,12 +4119,12 @@ audio.comfy-audio.empty-audio-widget {
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
.option-display-name[data-v-077af1a9] {
|
||||
.option-display-name[data-v-d28bffc4] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-weight: 600;
|
||||
}
|
||||
.option-category[data-v-077af1a9] {
|
||||
.option-category[data-v-d28bffc4] {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 0.875rem;
|
||||
@@ -4133,7 +4135,7 @@ audio.comfy-audio.empty-audio-widget {
|
||||
/* Keeps the text on a single line by default */
|
||||
white-space: nowrap;
|
||||
}
|
||||
[data-v-077af1a9] .highlight {
|
||||
[data-v-d28bffc4] .highlight {
|
||||
background-color: var(--p-primary-color);
|
||||
color: var(--p-primary-contrast-color);
|
||||
font-weight: bold;
|
||||
@@ -4141,10 +4143,10 @@ audio.comfy-audio.empty-audio-widget {
|
||||
padding: 0rem 0.125rem;
|
||||
margin: -0.125rem 0.125rem;
|
||||
}
|
||||
._filter-button[data-v-077af1a9] {
|
||||
._filter-button[data-v-d28bffc4] {
|
||||
z-index: 10;
|
||||
}
|
||||
._dialog[data-v-077af1a9] {
|
||||
._dialog[data-v-d28bffc4] {
|
||||
min-width: 24rem;
|
||||
}
|
||||
|
||||
@@ -4353,28 +4355,60 @@ img.galleria-image {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.node-tree-leaf[data-v-adf5f221] {
|
||||
.tree-node[data-v-d4b7b060] {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.node-content[data-v-adf5f221] {
|
||||
.leaf-count-badge[data-v-d4b7b060] {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
.node-content[data-v-d4b7b060] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.node-label[data-v-adf5f221] {
|
||||
.leaf-label[data-v-d4b7b060] {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
.bookmark-button[data-v-adf5f221] {
|
||||
width: unset;
|
||||
padding: 0.25rem;
|
||||
[data-v-d4b7b060] .editable-text span {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.node-tree-folder[data-v-f2d72e9b] {
|
||||
[data-v-9d3310b9] .tree-explorer-node-label {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: var(--p-tree-node-gap);
|
||||
flex-grow: 1;
|
||||
}
|
||||
/*
|
||||
* The following styles are necessary to avoid layout shift when dragging nodes over folders.
|
||||
* By setting the position to relative on the parent and using an absolutely positioned pseudo-element,
|
||||
* we can create a visual indicator for the drop target without affecting the layout of other elements.
|
||||
*/
|
||||
[data-v-9d3310b9] .p-tree-node-content:has(.tree-folder) {
|
||||
position: relative;
|
||||
}
|
||||
[data-v-9d3310b9] .p-tree-node-content:has(.tree-folder.can-drop)::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border: 1px solid var(--p-content-color);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.node-lib-node-container[data-v-3238e135] {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
.bookmark-button[data-v-3238e135] {
|
||||
width: unset;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.p-selectbutton .p-button[data-v-91077f2a] {
|
||||
@@ -4394,45 +4428,33 @@ img.galleria-image {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.node-lib-tree-node-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: var(--p-tree-node-gap);
|
||||
flex-grow: 1;
|
||||
}
|
||||
.node-lib-filter-popup {
|
||||
margin-left: -13px;
|
||||
}
|
||||
|
||||
[data-v-87967891] .node-lib-search-box {
|
||||
[data-v-85688f44] .node-lib-search-box {
|
||||
margin-left: 1rem;
|
||||
margin-right: 1rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
[data-v-87967891] .comfy-vue-side-bar-body {
|
||||
[data-v-85688f44] .comfy-vue-side-bar-body {
|
||||
background: var(--p-tree-background);
|
||||
}
|
||||
|
||||
/*
|
||||
* The following styles are necessary to avoid layout shift when dragging nodes over folders.
|
||||
* By setting the position to relative on the parent and using an absolutely positioned pseudo-element,
|
||||
* we can create a visual indicator for the drop target without affecting the layout of other elements.
|
||||
*/
|
||||
[data-v-87967891] .p-tree-node-content:has(.node-tree-folder) {
|
||||
position: relative;
|
||||
[data-v-85688f44] .node-lib-bookmark-tree-explorer {
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
[data-v-87967891] .p-tree-node-content:has(.node-tree-folder.can-drop)::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border: 1px solid var(--p-content-color);
|
||||
pointer-events: none;
|
||||
[data-v-85688f44] .node-lib-tree-explorer {
|
||||
padding-top: 2px;
|
||||
}
|
||||
[data-v-85688f44] .p-divider {
|
||||
margin: var(--comfy-tree-explorer-item-padding) 0px;
|
||||
}
|
||||
|
||||
.spinner[data-v-8616e7a1] {
|
||||
.p-tree-node-content {
|
||||
padding: var(--comfy-tree-explorer-item-padding) !important;
|
||||
}
|
||||
|
||||
.spinner[data-v-75e4840f] {
|
||||
position: absolute;
|
||||
inset: 0px;
|
||||
display: flex;
|
||||
0
web/assets/userSelection-BGzn1LuN.css → web/assets/userSelection-CF-ymHZW.css
generated
vendored
0
web/assets/userSelection-BGzn1LuN.css → web/assets/userSelection-CF-ymHZW.css
generated
vendored
4
web/assets/userSelection-CyXKCVy3.js → web/assets/userSelection-DSpF-zVD.js
generated
vendored
4
web/assets/userSelection-CyXKCVy3.js → web/assets/userSelection-DSpF-zVD.js
generated
vendored
@@ -1,6 +1,6 @@
|
||||
var __defProp = Object.defineProperty;
|
||||
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||
import { j as createSpinner, h as api, $ as $el } from "./index-CI3N807S.js";
|
||||
import { j as createSpinner, h as api, $ as $el } from "./index-Dfv2aLsq.js";
|
||||
class UserSelectionScreen {
|
||||
static {
|
||||
__name(this, "UserSelectionScreen");
|
||||
@@ -117,4 +117,4 @@ window.comfyAPI.userSelection.UserSelectionScreen = UserSelectionScreen;
|
||||
export {
|
||||
UserSelectionScreen
|
||||
};
|
||||
//# sourceMappingURL=userSelection-CyXKCVy3.js.map
|
||||
//# sourceMappingURL=userSelection-DSpF-zVD.js.map
|
||||
2
web/assets/userSelection-CyXKCVy3.js.map → web/assets/userSelection-DSpF-zVD.js.map
generated
vendored
2
web/assets/userSelection-CyXKCVy3.js.map → web/assets/userSelection-DSpF-zVD.js.map
generated
vendored
File diff suppressed because one or more lines are too long
BIN
web/dist.zip
vendored
Normal file
BIN
web/dist.zip
vendored
Normal file
Binary file not shown.
2
web/extensions/core/clipspace.js
vendored
2
web/extensions/core/clipspace.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for extensions\core\clipspace.ts
|
||||
// Shim for extensions/core/clipspace.ts
|
||||
export const ClipspaceDialog = window.comfyAPI.clipspace.ClipspaceDialog;
|
||||
|
||||
2
web/extensions/core/groupNode.js
vendored
2
web/extensions/core/groupNode.js
vendored
@@ -1,3 +1,3 @@
|
||||
// Shim for extensions\core\groupNode.ts
|
||||
// Shim for extensions/core/groupNode.ts
|
||||
export const GroupNodeConfig = window.comfyAPI.groupNode.GroupNodeConfig;
|
||||
export const GroupNodeHandler = window.comfyAPI.groupNode.GroupNodeHandler;
|
||||
|
||||
2
web/extensions/core/groupNodeManage.js
vendored
2
web/extensions/core/groupNodeManage.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for extensions\core\groupNodeManage.ts
|
||||
// Shim for extensions/core/groupNodeManage.ts
|
||||
export const ManageGroupDialog = window.comfyAPI.groupNodeManage.ManageGroupDialog;
|
||||
|
||||
2
web/extensions/core/widgetInputs.js
vendored
2
web/extensions/core/widgetInputs.js
vendored
@@ -1,4 +1,4 @@
|
||||
// Shim for extensions\core\widgetInputs.ts
|
||||
// Shim for extensions/core/widgetInputs.ts
|
||||
export const getWidgetConfig = window.comfyAPI.widgetInputs.getWidgetConfig;
|
||||
export const setWidgetConfig = window.comfyAPI.widgetInputs.setWidgetConfig;
|
||||
export const mergeIfValid = window.comfyAPI.widgetInputs.mergeIfValid;
|
||||
|
||||
100
web/index.html
vendored
100
web/index.html
vendored
@@ -1,50 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>ComfyUI</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||
<!-- Browser Test Fonts -->
|
||||
<!-- <link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Color+Emoji&family=Roboto+Mono:ital,wght@0,100..700;1,100..700&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* {
|
||||
font-family: 'Roboto Mono', 'Noto Color Emoji';
|
||||
}
|
||||
</style> -->
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="user.css" />
|
||||
<link rel="stylesheet" type="text/css" href="materialdesignicons.min.css" />
|
||||
<script type="module" crossorigin src="./assets/index-CI3N807S.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-_5czGnTA.css">
|
||||
</head>
|
||||
<body class="litegraph">
|
||||
<div id="vue-app"></div>
|
||||
<div id="comfy-user-selection" class="comfy-user-selection" style="display: none;">
|
||||
<main class="comfy-user-selection-inner">
|
||||
<h1>ComfyUI</h1>
|
||||
<form>
|
||||
<section>
|
||||
<label>New user:
|
||||
<input placeholder="Enter a username" />
|
||||
</label>
|
||||
</section>
|
||||
<div class="comfy-user-existing">
|
||||
<span class="or-separator">OR</span>
|
||||
<section>
|
||||
<label>
|
||||
Existing user:
|
||||
<select>
|
||||
<option hidden disabled selected value> Select a user </option>
|
||||
</select>
|
||||
</label>
|
||||
</section>
|
||||
</div>
|
||||
<footer>
|
||||
<span class="comfy-user-error"> </span>
|
||||
<button class="comfy-btn comfy-user-button-next">Next</button>
|
||||
</footer>
|
||||
</form>
|
||||
</main>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>ComfyUI</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||
<!-- Browser Test Fonts -->
|
||||
<!-- <link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Color+Emoji&family=Roboto+Mono:ital,wght@0,100..700;1,100..700&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* {
|
||||
font-family: 'Roboto Mono', 'Noto Color Emoji';
|
||||
}
|
||||
</style> -->
|
||||
<link rel="stylesheet" type="text/css" href="user.css" />
|
||||
<link rel="stylesheet" type="text/css" href="materialdesignicons.min.css" />
|
||||
<script type="module" crossorigin src="./assets/index-Dfv2aLsq.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-W4jP-SrU.css">
|
||||
</head>
|
||||
<body class="litegraph">
|
||||
<div id="vue-app"></div>
|
||||
<div id="comfy-user-selection" class="comfy-user-selection" style="display: none;">
|
||||
<main class="comfy-user-selection-inner">
|
||||
<h1>ComfyUI</h1>
|
||||
<form>
|
||||
<section>
|
||||
<label>New user:
|
||||
<input placeholder="Enter a username" />
|
||||
</label>
|
||||
</section>
|
||||
<div class="comfy-user-existing">
|
||||
<span class="or-separator">OR</span>
|
||||
<section>
|
||||
<label>
|
||||
Existing user:
|
||||
<select>
|
||||
<option hidden disabled selected value> Select a user </option>
|
||||
</select>
|
||||
</label>
|
||||
</section>
|
||||
</div>
|
||||
<footer>
|
||||
<span class="comfy-user-error"> </span>
|
||||
<button class="comfy-btn comfy-user-button-next">Next</button>
|
||||
</footer>
|
||||
</form>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
2
web/scripts/api.js
vendored
2
web/scripts/api.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\api.ts
|
||||
// Shim for scripts/api.ts
|
||||
export const api = window.comfyAPI.api.api;
|
||||
|
||||
2
web/scripts/app.js
vendored
2
web/scripts/app.js
vendored
@@ -1,4 +1,4 @@
|
||||
// Shim for scripts\app.ts
|
||||
// Shim for scripts/app.ts
|
||||
export const ANIM_PREVIEW_WIDGET = window.comfyAPI.app.ANIM_PREVIEW_WIDGET;
|
||||
export const ComfyApp = window.comfyAPI.app.ComfyApp;
|
||||
export const app = window.comfyAPI.app.app;
|
||||
|
||||
2
web/scripts/changeTracker.js
vendored
2
web/scripts/changeTracker.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\changeTracker.ts
|
||||
// Shim for scripts/changeTracker.ts
|
||||
export const ChangeTracker = window.comfyAPI.changeTracker.ChangeTracker;
|
||||
|
||||
2
web/scripts/defaultGraph.js
vendored
2
web/scripts/defaultGraph.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\defaultGraph.ts
|
||||
// Shim for scripts/defaultGraph.ts
|
||||
export const defaultGraph = window.comfyAPI.defaultGraph.defaultGraph;
|
||||
|
||||
2
web/scripts/domWidget.js
vendored
2
web/scripts/domWidget.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\domWidget.ts
|
||||
// Shim for scripts/domWidget.ts
|
||||
export const addDomClippingSetting = window.comfyAPI.domWidget.addDomClippingSetting;
|
||||
|
||||
2
web/scripts/logging.js
vendored
2
web/scripts/logging.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\logging.ts
|
||||
// Shim for scripts/logging.ts
|
||||
export const ComfyLogging = window.comfyAPI.logging.ComfyLogging;
|
||||
|
||||
2
web/scripts/metadata/flac.js
vendored
2
web/scripts/metadata/flac.js
vendored
@@ -1,3 +1,3 @@
|
||||
// Shim for scripts\metadata\flac.ts
|
||||
// Shim for scripts/metadata/flac.ts
|
||||
export const getFromFlacBuffer = window.comfyAPI.flac.getFromFlacBuffer;
|
||||
export const getFromFlacFile = window.comfyAPI.flac.getFromFlacFile;
|
||||
|
||||
2
web/scripts/metadata/png.js
vendored
2
web/scripts/metadata/png.js
vendored
@@ -1,3 +1,3 @@
|
||||
// Shim for scripts\metadata\png.ts
|
||||
// Shim for scripts/metadata/png.ts
|
||||
export const getFromPngBuffer = window.comfyAPI.png.getFromPngBuffer;
|
||||
export const getFromPngFile = window.comfyAPI.png.getFromPngFile;
|
||||
|
||||
2
web/scripts/pnginfo.js
vendored
2
web/scripts/pnginfo.js
vendored
@@ -1,4 +1,4 @@
|
||||
// Shim for scripts\pnginfo.ts
|
||||
// Shim for scripts/pnginfo.ts
|
||||
export const getPngMetadata = window.comfyAPI.pnginfo.getPngMetadata;
|
||||
export const getFlacMetadata = window.comfyAPI.pnginfo.getFlacMetadata;
|
||||
export const getWebpMetadata = window.comfyAPI.pnginfo.getWebpMetadata;
|
||||
|
||||
2
web/scripts/ui.js
vendored
2
web/scripts/ui.js
vendored
@@ -1,4 +1,4 @@
|
||||
// Shim for scripts\ui.ts
|
||||
// Shim for scripts/ui.ts
|
||||
export const ComfyDialog = window.comfyAPI.ui.ComfyDialog;
|
||||
export const $el = window.comfyAPI.ui.$el;
|
||||
export const ComfyUI = window.comfyAPI.ui.ComfyUI;
|
||||
|
||||
2
web/scripts/ui/components/asyncDialog.js
vendored
2
web/scripts/ui/components/asyncDialog.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\ui\components\asyncDialog.ts
|
||||
// Shim for scripts/ui/components/asyncDialog.ts
|
||||
export const ComfyAsyncDialog = window.comfyAPI.asyncDialog.ComfyAsyncDialog;
|
||||
|
||||
2
web/scripts/ui/components/button.js
vendored
2
web/scripts/ui/components/button.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\ui\components\button.ts
|
||||
// Shim for scripts/ui/components/button.ts
|
||||
export const ComfyButton = window.comfyAPI.button.ComfyButton;
|
||||
|
||||
2
web/scripts/ui/components/buttonGroup.js
vendored
2
web/scripts/ui/components/buttonGroup.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\ui\components\buttonGroup.ts
|
||||
// Shim for scripts/ui/components/buttonGroup.ts
|
||||
export const ComfyButtonGroup = window.comfyAPI.buttonGroup.ComfyButtonGroup;
|
||||
|
||||
2
web/scripts/ui/components/popup.js
vendored
2
web/scripts/ui/components/popup.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\ui\components\popup.ts
|
||||
// Shim for scripts/ui/components/popup.ts
|
||||
export const ComfyPopup = window.comfyAPI.popup.ComfyPopup;
|
||||
|
||||
2
web/scripts/ui/components/splitButton.js
vendored
2
web/scripts/ui/components/splitButton.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\ui\components\splitButton.ts
|
||||
// Shim for scripts/ui/components/splitButton.ts
|
||||
export const ComfySplitButton = window.comfyAPI.splitButton.ComfySplitButton;
|
||||
|
||||
2
web/scripts/ui/dialog.js
vendored
2
web/scripts/ui/dialog.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\ui\dialog.ts
|
||||
// Shim for scripts/ui/dialog.ts
|
||||
export const ComfyDialog = window.comfyAPI.dialog.ComfyDialog;
|
||||
|
||||
2
web/scripts/ui/draggableList.js
vendored
2
web/scripts/ui/draggableList.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\ui\draggableList.ts
|
||||
// Shim for scripts/ui/draggableList.ts
|
||||
export const DraggableList = window.comfyAPI.draggableList.DraggableList;
|
||||
|
||||
2
web/scripts/ui/imagePreview.js
vendored
2
web/scripts/ui/imagePreview.js
vendored
@@ -1,3 +1,3 @@
|
||||
// Shim for scripts\ui\imagePreview.ts
|
||||
// Shim for scripts/ui/imagePreview.ts
|
||||
export const calculateImageGrid = window.comfyAPI.imagePreview.calculateImageGrid;
|
||||
export const createImageHost = window.comfyAPI.imagePreview.createImageHost;
|
||||
|
||||
2
web/scripts/ui/menu/index.js
vendored
2
web/scripts/ui/menu/index.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\ui\menu\index.ts
|
||||
// Shim for scripts/ui/menu/index.ts
|
||||
export const ComfyAppMenu = window.comfyAPI.index.ComfyAppMenu;
|
||||
|
||||
2
web/scripts/ui/menu/interruptButton.js
vendored
2
web/scripts/ui/menu/interruptButton.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\ui\menu\interruptButton.ts
|
||||
// Shim for scripts/ui/menu/interruptButton.ts
|
||||
export const getInterruptButton = window.comfyAPI.interruptButton.getInterruptButton;
|
||||
|
||||
2
web/scripts/ui/menu/queueButton.js
vendored
2
web/scripts/ui/menu/queueButton.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\ui\menu\queueButton.ts
|
||||
// Shim for scripts/ui/menu/queueButton.ts
|
||||
export const ComfyQueueButton = window.comfyAPI.queueButton.ComfyQueueButton;
|
||||
|
||||
2
web/scripts/ui/menu/queueOptions.js
vendored
2
web/scripts/ui/menu/queueOptions.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\ui\menu\queueOptions.ts
|
||||
// Shim for scripts/ui/menu/queueOptions.ts
|
||||
export const ComfyQueueOptions = window.comfyAPI.queueOptions.ComfyQueueOptions;
|
||||
|
||||
2
web/scripts/ui/menu/workflows.js
vendored
2
web/scripts/ui/menu/workflows.js
vendored
@@ -1,3 +1,3 @@
|
||||
// Shim for scripts\ui\menu\workflows.ts
|
||||
// Shim for scripts/ui/menu/workflows.ts
|
||||
export const ComfyWorkflowsMenu = window.comfyAPI.workflows.ComfyWorkflowsMenu;
|
||||
export const ComfyWorkflowsContent = window.comfyAPI.workflows.ComfyWorkflowsContent;
|
||||
|
||||
2
web/scripts/ui/settings.js
vendored
2
web/scripts/ui/settings.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\ui\settings.ts
|
||||
// Shim for scripts/ui/settings.ts
|
||||
export const ComfySettingsDialog = window.comfyAPI.settings.ComfySettingsDialog;
|
||||
|
||||
2
web/scripts/ui/spinner.js
vendored
2
web/scripts/ui/spinner.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\ui\spinner.ts
|
||||
// Shim for scripts/ui/spinner.ts
|
||||
export const createSpinner = window.comfyAPI.spinner.createSpinner;
|
||||
|
||||
2
web/scripts/ui/toggleSwitch.js
vendored
2
web/scripts/ui/toggleSwitch.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\ui\toggleSwitch.ts
|
||||
// Shim for scripts/ui/toggleSwitch.ts
|
||||
export const toggleSwitch = window.comfyAPI.toggleSwitch.toggleSwitch;
|
||||
|
||||
2
web/scripts/ui/userSelection.js
vendored
2
web/scripts/ui/userSelection.js
vendored
@@ -1,2 +1,2 @@
|
||||
// Shim for scripts\ui\userSelection.ts
|
||||
// Shim for scripts/ui/userSelection.ts
|
||||
export const UserSelectionScreen = window.comfyAPI.userSelection.UserSelectionScreen;
|
||||
|
||||
2
web/scripts/ui/utils.js
vendored
2
web/scripts/ui/utils.js
vendored
@@ -1,3 +1,3 @@
|
||||
// Shim for scripts\ui\utils.ts
|
||||
// Shim for scripts/ui/utils.ts
|
||||
export const applyClasses = window.comfyAPI.utils.applyClasses;
|
||||
export const toggleElement = window.comfyAPI.utils.toggleElement;
|
||||
|
||||
2
web/scripts/utils.js
vendored
2
web/scripts/utils.js
vendored
@@ -1,4 +1,4 @@
|
||||
// Shim for scripts\utils.ts
|
||||
// Shim for scripts/utils.ts
|
||||
export const clone = window.comfyAPI.utils.clone;
|
||||
export const applyTextReplacements = window.comfyAPI.utils.applyTextReplacements;
|
||||
export const addStylesheet = window.comfyAPI.utils.addStylesheet;
|
||||
|
||||
2
web/scripts/widgets.js
vendored
2
web/scripts/widgets.js
vendored
@@ -1,4 +1,4 @@
|
||||
// Shim for scripts\widgets.ts
|
||||
// Shim for scripts/widgets.ts
|
||||
export const updateControlWidgetLabel = window.comfyAPI.widgets.updateControlWidgetLabel;
|
||||
export const addValueControlWidget = window.comfyAPI.widgets.addValueControlWidget;
|
||||
export const addValueControlWidgets = window.comfyAPI.widgets.addValueControlWidgets;
|
||||
|
||||
2
web/scripts/workflows.js
vendored
2
web/scripts/workflows.js
vendored
@@ -1,4 +1,4 @@
|
||||
// Shim for scripts\workflows.ts
|
||||
// Shim for scripts/workflows.ts
|
||||
export const trimJsonExt = window.comfyAPI.workflows.trimJsonExt;
|
||||
export const ComfyWorkflowManager = window.comfyAPI.workflows.ComfyWorkflowManager;
|
||||
export const ComfyWorkflow = window.comfyAPI.workflows.ComfyWorkflow;
|
||||
|
||||
Reference in New Issue
Block a user