diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 16f70ff..9b232a7 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -2,7 +2,21 @@ "permissions": { "allow": [ "Bash(Get-ChildItem -Path \"d:\\\\My Actual Documents\\\\Projects\\\\Code\\\\PyProjects\\\\mb_gui\" -Recurse -File)", - "Bash(Select-Object FullName)" + "Bash(Select-Object FullName)", + "Bash(python mbq_parser.py \"images/straight_gen_monkeys.png\")", + "Bash(python mbq_parser.py \"images/disc_fix_00006_.png\")", + "Bash(python mbq_parser.py \"images/controlnet_i2i_tableLady_00004_.png\")", + "Bash(del screenshot.png screenshot_loaded.png screenshot_with_image.png)", + "Bash(find \"d:/My Actual Documents/Projects/Code/PyProjects/mb_gui\" -name \"ComfyUI_00101_betterHand.png\" 2>/dev/null; find \"d:/My Actual Documents\" -name \"ComfyUI_00101_betterHand.png\" 2>/dev/null | head -5)", + "Read(//d/My Actual Documents/**)", + "Bash(find / -name \"ComfyUI_00101_betterHand.png\" 2>/dev/null | head -5)", + "Read(//d//**)", + "Bash(python mbq_parser.py \"images/redux_1_00002_.png\")", + "Bash(python dump_png_text_chunks.py \"images/redux_1_00002_.png\")", + "Bash(python -c ' *)", + "Bash(Get-ChildItem -Path \"d:\\\\My Actual Documents\\\\Projects\\\\Code\\\\PyProjects\\\\mb_gui\" -Filter \"*.py\")", + "Bash(Select-Object -ExpandProperty Name)", + "Bash(Sort-Object)" ] } } diff --git a/CLAUDE.md b/CLAUDE.md index 6e50956..a9051cc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,25 +22,21 @@ too complex and was the root cause of prior pain — ignore it entirely. | File | Role | |------|------| -| `mbq_layout.py` | Main `MetaViewApp` window — PySide6 QMainWindow, UI layout | +| `mbq_browser.py` | Main `MetaViewApp` window — PySide6 QMainWindow, UI layout, menus | | `mbq_logic.py` | `MetaViewLogicMixin` — image navigation, metadata display, file dialog | | `mbq_functions.py` | `ImageFolder`, `ImageCanvas` (QGraphicsView), `WorkflowCache` | -| `mbq_parser.py` | `digest_workflow()` — PNG chunk extraction + ComfyUI prompt graph traversal | -| `mbq_metadata.py` | `ImageMetadata` dataclass — unified structure for all extracted fields | -| `mbq_nodes.py` | Static ComfyUI node registry (Jan 2025 snapshot) — used by CLI tools only | +| `mbq_parser.py` | `get_png_metadata()` — PNG chunk extraction + ComfyUI prompt graph traversal | +| `mbq_nodes.py` | Static ComfyUI node registry (Jan 2025 snapshot) — reference only | | `dump_png_text_chunks.py` | CLI: dump raw PNG text chunks for debugging | -| `mbq_audit_current_logic.py` | CLI: audit parser decisions on a batch of PNGs | -| `mbq_dump_testset.py` | CLI: generate metadata reports from a test image set | ## Architecture ``` -MetaViewApp (mbq_layout.py) +MetaViewApp (mbq_browser.py) ├─ MetaViewLogicMixin (mbq_logic.py) - │ └─ digest_workflow() ← mbq_parser.py - │ └─ ImageMetadata ← mbq_metadata.py + │ └─ get_png_metadata() ← mbq_parser.py ├─ ImageCanvas, ImageFolder, WorkflowCache (mbq_functions.py) - └─ [mbq_nodes.py — CLI audit tools only, not used by the GUI] + └─ [mbq_nodes.py — reference only, not used by the GUI] ``` ## PNG chunk format @@ -74,13 +70,17 @@ prompt graph (KSampler, CheckpointLoaderSimple, CLIPTextEncode, etc.). ``` # Run the GUI -python mbq_layout.py +python mbq_browser.py + +# Open directly to an image or folder +python mbq_browser.py path/to/image.png +python mbq_browser.py path/to/folder # Inspect raw chunks in a PNG before debugging the parser python dump_png_text_chunks.py -# Batch-audit parser decisions against a folder of test images -python mbq_audit_current_logic.py +# Pretty-print parsed metadata (what the GUI sees) +python mbq_parser.py ``` No formal test runner exists. Test images are stored under `project_docs/`. diff --git a/images/ComfyUI_00101_betterHand.png b/images/ComfyUI_00101_betterHand.png new file mode 100644 index 0000000..6e52e31 Binary files /dev/null and b/images/ComfyUI_00101_betterHand.png differ diff --git a/images/Flux2_dev_00001_.png b/images/Flux2_dev_00001_.png new file mode 100644 index 0000000..8e1333e Binary files /dev/null and b/images/Flux2_dev_00001_.png differ diff --git a/mbq_layout.py b/mbq_browser.py similarity index 55% rename from mbq_layout.py rename to mbq_browser.py index c45136f..f693b13 100644 --- a/mbq_layout.py +++ b/mbq_browser.py @@ -2,43 +2,56 @@ from PySide6.QtWidgets import ( QApplication, QMainWindow, QWidget, QFrame, QGroupBox, QVBoxLayout, QHBoxLayout, QGridLayout, QLabel, QPushButton, - QScrollArea, QTextEdit, + QScrollArea, QTextEdit, QMessageBox, QFileDialog, ) -from PySide6.QtGui import QAction -from mbq_functions import ImageCanvas -from PySide6.QtCore import Qt, QTimer, QEvent +from PySide6.QtGui import QAction, QDesktopServices +from PySide6.QtCore import Qt, QTimer, QEvent, QUrl +from mbq_functions import ImageCanvas, WorkflowCache from mbq_parser import get_png_metadata -from mbq_functions import WorkflowCache from mbq_logic import MetaViewLogicMixin - import sys +class StatusBulb(QLabel): + _COLORS = {"on": "#44cc44", "warn": "#c8823a", "off": "#2a2a2a"} + + def __init__(self, tooltip_name, parent=None): + super().__init__(parent) + self._name = tooltip_name + self.setFixedSize(14, 14) + self._state = "off" + self._apply() + + def set_state(self, state: str): + if state != self._state: + self._state = state + self._apply() + + def _apply(self): + c = self._COLORS[self._state] + self.setStyleSheet(f"background:{c}; border-radius:7px; border:1px solid #555;") + self.setToolTip(f"{self._name}: {'ON' if self._state != 'off' else 'OFF'}") class MetaViewApp(MetaViewLogicMixin, QMainWindow): - # Now inherits from both QMainWindow and our logic mixin def __init__(self): super().__init__() - self.setWindowTitle("Image Viewer GL Layout") + self.setWindowTitle("MBQ — Meta Browser") self.workflow_cache = WorkflowCache(max_size=50) - # --- 4:3 Optimized Window Size --- - # Calculate for 1024x768 image + UI elements - self.resize(1400, 900) # Wider window to accommodate right sidebar - + self.resize(1400, 900) + self.folder_model = None self.image_cache = {} self.thumb_cache = {} self.cache_size = 5 - # --- Design reference sizes for 4:3 --- - self.design_canvas_w = 1024 # Target image width - self.design_canvas_h = 768 # Target image height - self.design_thumb_w = 120 # Thumbnail width - self.design_thumb_h = 90 # Thumbnail height (4:3) - + self.design_canvas_w = 1024 + self.design_canvas_h = 768 + self.design_thumb_w = 120 + self.design_thumb_h = 90 + self.scale_factor = 1.0 # ---- Central Widget ---- @@ -50,59 +63,56 @@ class MetaViewApp(MetaViewLogicMixin, QMainWindow): self.main_layout.setContentsMargins(10, 20, 10, 20) self.main_layout.setSpacing(10) - # Column weights - center area for image, right for metadata - self.main_layout.setColumnStretch(0, 0) # left aesthetic spacer (fixed) - self.main_layout.setColumnStretch(1, 3) # center image area (main content) - self.main_layout.setColumnStretch(2, 1) # right metadata panel (~1/4 width) - self.main_layout.setRowStretch(0, 1) # main row expands + self.main_layout.setColumnStretch(0, 0) + self.main_layout.setColumnStretch(1, 3) + self.main_layout.setColumnStretch(2, 1) + self.main_layout.setRowStretch(0, 1) - # --- Left Spacer (Aesthetic) --- + # --- Left Spacer --- self.left_spacer = QFrame() - self.left_spacer.setFixedWidth(40) # Small fixed width spacer + self.left_spacer.setFixedWidth(40) self.left_spacer.setStyleSheet("background: transparent;") self.main_layout.addWidget(self.left_spacer, 0, 0) # --- Center Image Area --- self.center_group = QGroupBox("Image View") self.center_group.setStyleSheet(""" - QGroupBox { - border: 2px solid #333333; - border-radius: 4px; - margin-top: 10px; - } - QGroupBox::title { - subcontrol-origin: margin; - subcontrol-position: top left; - left: 10px; - padding: 0 5px 0 5px; - background: palette(window); + QGroupBox { + border: 2px solid #333333; + border-radius: 4px; + margin-top: 10px; + } + QGroupBox::title { + subcontrol-origin: margin; + subcontrol-position: top left; + left: 10px; + padding: 0 5px 0 5px; + background: palette(window); } """) - + self.main_layout.addWidget(self.center_group, 0, 1) center_layout = QGridLayout(self.center_group) - center_layout.setRowStretch(0, 5) # image view (most space) - center_layout.setRowStretch(1, 1) # filmstrip - center_layout.setRowStretch(2, 0) # buttons + center_layout.setRowStretch(0, 5) + center_layout.setRowStretch(1, 1) + center_layout.setRowStretch(2, 0) center_layout.setColumnStretch(0, 1) # ---- Image Canvas ---- self.image_view = ImageCanvas() self.image_view.fileDropped.connect(self.load_image_from_path) - self.image_view.setMinimumSize(800, 600) # 4:3 minimum + self.image_view.setMinimumSize(800, 600) center_layout.addWidget(self.image_view, 0, 0) # ---- Filmstrip Frame ---- self.filmstrip_frame = QFrame() filmstrip_layout = QVBoxLayout(self.filmstrip_frame) - # Top separator sep = QFrame() sep.setFrameShape(QFrame.HLine) sep.setStyleSheet("color: #252222;") filmstrip_layout.addWidget(sep) - # Thumbnail scroller self.thumb_scroll_area = QScrollArea() self.thumb_scroll_area.setWidgetResizable(True) self.thumb_scroll_area.setMinimumHeight(100) @@ -110,12 +120,13 @@ class MetaViewApp(MetaViewLogicMixin, QMainWindow): self.thumb_layout = QHBoxLayout(self.thumb_container) self.thumb_scroll_area.setWidget(self.thumb_container) filmstrip_layout.addWidget(self.thumb_scroll_area) - + center_layout.addWidget(self.filmstrip_frame, 1, 0) # ---- Button Frame ---- self.button_frame = QFrame() btn_layout = QHBoxLayout(self.button_frame) + btn_layout.setContentsMargins(0, 2, 0, 2) next_btn = QPushButton("Next Image") prev_btn = QPushButton("Previous Image") @@ -125,12 +136,40 @@ class MetaViewApp(MetaViewLogicMixin, QMainWindow): btn_layout.addWidget(prev_btn) btn_layout.addWidget(open_btn) + # ---- Status Bulbs ---- + btn_layout.addStretch() + + bulb_style = "color: #888; font-size: 10px;" + + self.bulb_zoom = StatusBulb("Zoom Lock") + zoom_lbl = QLabel("Zoom") + zoom_lbl.setStyleSheet(bulb_style) + zoom_group = QHBoxLayout() + zoom_group.setSpacing(4) + zoom_group.addWidget(self.bulb_zoom) + zoom_group.addWidget(zoom_lbl) + btn_layout.addLayout(zoom_group) + + self.bulb_wedge = StatusBulb("Wedge node") + wedge_lbl = QLabel("Wedge") + wedge_lbl.setStyleSheet(bulb_style) + wedge_group = QHBoxLayout() + wedge_group.setSpacing(4) + wedge_group.addWidget(self.bulb_wedge) + wedge_group.addWidget(wedge_lbl) + btn_layout.addLayout(wedge_group) + + self.bulb_uncomfy = StatusBulb("UnComfy") + uncomfy_lbl = QLabel("UnComfy") + uncomfy_lbl.setStyleSheet(bulb_style) + uncomfy_group = QHBoxLayout() + uncomfy_group.setSpacing(4) + uncomfy_group.addWidget(self.bulb_uncomfy) + uncomfy_group.addWidget(uncomfy_lbl) + btn_layout.addLayout(uncomfy_group) + center_layout.addWidget(self.button_frame, 2, 0) - - - - # --- Right Metadata Panel --- self.right_metadata = QGroupBox("Metadata") self.right_metadata.setMinimumWidth(300) @@ -146,7 +185,6 @@ class MetaViewApp(MetaViewLogicMixin, QMainWindow): lbl.setStyleSheet(label_style) return lbl - # --- File Info (compact grid) --- self.file_name_label = style_label(QLabel("File:")) self.file_dim_label = style_label(QLabel("Dimensions:")) self.file_size_label = style_label(QLabel("Size:")) @@ -181,7 +219,6 @@ class MetaViewApp(MetaViewLogicMixin, QMainWindow): sep.setStyleSheet("color: #333;") metadata_vbox.addWidget(sep) - # --- Primary node display (tier 1 + tier 2) --- mono_style = "font-family: 'Courier New', 'Consolas', monospace; font-size: 9pt;" self.primary_display = QTextEdit() self.primary_display.setReadOnly(True) @@ -189,7 +226,6 @@ class MetaViewApp(MetaViewLogicMixin, QMainWindow): self.primary_display.setStyleSheet(mono_style) metadata_vbox.addWidget(self.primary_display, stretch=1) - # --- Tier 3 toggle + display --- self.tier3_btn = QPushButton("▶ plumbing") self.tier3_btn.setStyleSheet("text-align: left; padding: 2px 6px; font-size: 10px;") self.tier3_btn.setVisible(False) @@ -207,52 +243,95 @@ class MetaViewApp(MetaViewLogicMixin, QMainWindow): self.primary_display.installEventFilter(self) self.tier3_display.installEventFilter(self) - # --- Copy button --- copy_btn = QPushButton("Copy Metadata") metadata_vbox.addWidget(copy_btn) - # Add panel to main layout self.main_layout.addWidget(self.right_metadata, 0, 2) + # ---- Menu Bar ---- + menu_bar = self.menuBar() + # File + file_menu = menu_bar.addMenu("File") + file_menu.addAction("Open Image", self.open_image_file) + file_menu.addAction("Open Path", self.open_folder) + file_menu.addSeparator() + file_menu.addAction("Exit", QApplication.instance().quit) - # ---- View Menu ---- - view_menu = self.menuBar().addMenu("View") + # Edit + edit_menu = menu_bar.addMenu("Edit") + edit_menu.addAction("Copy Image", self._copy_image) + edit_menu.addAction("Copy Workflow", self._copy_workflow) + + # View + view_menu = menu_bar.addMenu("View") self._lock_zoom_action = QAction("Lock Zoom", self, checkable=True, shortcut="Z") - self._lock_zoom_action.toggled.connect(lambda checked: setattr(self.image_view, "zoom_locked", checked)) + self._lock_zoom_action.toggled.connect(self._on_zoom_lock_toggled) view_menu.addAction(self._lock_zoom_action) + view_menu.addAction("Reset Zoom", self.image_view.reset_zoom) + view_menu.addSeparator() + self._freeze_scroll_action = QAction("Freeze Scroll", self, checkable=True, shortcut="S") + view_menu.addAction(self._freeze_scroll_action) + + # About + about_menu = menu_bar.addMenu("About") + about_menu.addAction("About MBQ…", self._show_about) + about_menu.addAction("Help", self._open_help) # ---- Connect Signals ---- open_btn.clicked.connect(self.open_image_file) next_btn.clicked.connect(self.show_next_image) prev_btn.clicked.connect(self.show_prev_image) + copy_btn.clicked.connect(self._copy_workflow) - # Initialize after UI is built QTimer.singleShot(100, self.initialize_scale) - - - # Install event filter on THIS window only self.installEventFilter(self) - def copy_metadata_to_clipboard(): - lines = [ - f"File: {self.file_name_value.text()}", - f"Dimensions: {self.file_dim_value.text()}", - f"Size: {self.file_size_value.text()}", - f"Modified: {self.file_mod_value.text()}", - "", - self.primary_display.toPlainText(), - ] - t3 = self.tier3_display.toPlainText() - if t3: - lines += ["", "--- plumbing ---", t3] - QApplication.clipboard().setText("\n".join(lines)) + # ---- Menu handlers ---- + def open_folder(self): + folder = QFileDialog.getExistingDirectory(self, "Open Folder") + if folder: + self.load_folder_from_path(folder) - copy_btn.clicked.connect(copy_metadata_to_clipboard) + def _on_zoom_lock_toggled(self, checked: bool): + self.image_view.zoom_locked = checked + self.bulb_zoom.set_state("on" if checked else "off") + def _copy_image(self): + if self.image_view.image_item: + QApplication.clipboard().setPixmap(self.image_view.image_item.pixmap()) + + def _copy_workflow(self): + lines = [ + f"File: {self.file_name_value.text()}", + f"Dimensions: {self.file_dim_value.text()}", + f"Size: {self.file_size_value.text()}", + f"Modified: {self.file_mod_value.text()}", + "", + self.primary_display.toPlainText(), + ] + t3 = self.tier3_display.toPlainText() + if t3: + lines += ["", "--- plumbing ---", t3] + QApplication.clipboard().setText("\n".join(lines)) + + def _show_about(self): + QMessageBox.about( + self, + "About MBQ", + "MBQ — Meta Browser Qt\n" + "PySide6 image viewer for ComfyUI PNGs.\n\n" + "Reads ComfyUI prompt metadata from PNG text chunks\n" + "and displays generation parameters in a side panel.", + ) + + def _open_help(self): + # TODO: replace with actual repo URL + QDesktopServices.openUrl(QUrl("https://github.com/YOUR_REPO")) + + # ---- Event filter ---- - def eventFilter(self, obj, event): if event.type() == QEvent.Wheel: if obj in (self.primary_display, self.tier3_display): @@ -266,6 +345,8 @@ class MetaViewApp(MetaViewLogicMixin, QMainWindow): return True return super().eventFilter(obj, event) + # ---- Cache helpers ---- + def get_workflow_data(self, file_path): return self.workflow_cache.get(file_path, get_png_metadata) @@ -281,5 +362,6 @@ if __name__ == "__main__": import os if os.path.isfile(sys.argv[1]): QTimer.singleShot(0, lambda: window.load_image_from_path(sys.argv[1])) + elif os.path.isdir(sys.argv[1]): + QTimer.singleShot(0, lambda: window.load_folder_from_path(sys.argv[1])) sys.exit(app.exec()) - diff --git a/mbq_functions.py b/mbq_functions.py index d8cafc5..0fdd4ee 100644 --- a/mbq_functions.py +++ b/mbq_functions.py @@ -244,6 +244,10 @@ class ImageCanvas(QGraphicsView): def load_image_from_pixmap(self, pixmap: QPixmap): self._show_pixmap(pixmap) + def reset_zoom(self): + if self.image_item: + self.fitInView(self.image_item.boundingRect(), Qt.KeepAspectRatio) + # formerly workflow_cache.py diff --git a/mbq_logic.py b/mbq_logic.py index 70ff3b3..09a319d 100644 --- a/mbq_logic.py +++ b/mbq_logic.py @@ -2,7 +2,7 @@ import html as _html import os import re -from PySide6.QtCore import Qt +from PySide6.QtCore import Qt, QTimer from PySide6.QtGui import QPixmap, QPainter from PySide6.QtWidgets import QFileDialog, QLabel from mbq_functions import ImageFolder @@ -108,11 +108,16 @@ class MetaViewLogicMixin: md = self.get_workflow_data(file_info["path"]) prefixes = md.get("saveimage_prefixes", []) if md else [] - if md and prefixes and _is_preview_save(file_info["name"], prefixes): + is_preview = bool(md and prefixes and _is_preview_save(file_info["name"], prefixes)) + if is_preview: self.file_name_value.setStyleSheet("color: #c8823a;") # amber — possible preview save else: self.file_name_value.setStyleSheet("") + # Save scroll position if freeze is active + freeze = getattr(self._freeze_scroll_action, 'isChecked', lambda: False)() + saved_scroll = self.primary_display.verticalScrollBar().value() if freeze else None + # Always reset tier 3 to collapsed on image change self.tier3_display.setVisible(False) @@ -121,18 +126,32 @@ class MetaViewLogicMixin: primary_html = _build_display_text(t1 + t2) if primary_html: self.primary_display.setHtml(primary_html) + if saved_scroll is not None: + QTimer.singleShot(0, lambda v=saved_scroll: self.primary_display.verticalScrollBar().setValue(v)) else: self.primary_display.setPlainText("(no ComfyUI params in this image)") self.tier3_display.setHtml(_build_display_text(t3)) self._tier3_count = len(t3) self.tier3_btn.setText(f"▶ plumbing ({self._tier3_count} nodes)") self.tier3_btn.setVisible(self._tier3_count > 0) + + # Bulbs + self.bulb_uncomfy.set_state("warn" if is_preview else "off") + has_wedge = any( + "wedge" in n["class_type"].lower() or "wedge" in n["title"].lower() + for n in t1 + t2 + t3 + ) + self.bulb_wedge.set_state("on" if has_wedge else "off") else: self.primary_display.setPlainText("(no ComfyUI metadata)") self.tier3_display.setPlainText("") self._tier3_count = 0 self.tier3_btn.setVisible(False) + # Bulbs + self.bulb_uncomfy.set_state("warn") + self.bulb_wedge.set_state("off") + def toggle_tier3(self): visible = not self.tier3_display.isVisible() self.tier3_display.setVisible(visible) @@ -148,6 +167,17 @@ class MetaViewLogicMixin: self.populate_filmstrip() self.preload_adjacent_images() + def load_folder_from_path(self, folder_path): + self.folder_model = ImageFolder(folder_path) + self.image_cache.clear() + self.thumb_cache.clear() + current = self.folder_model.current() + if current: + self.display_image(current["path"]) + self.update_metadata(current) + self.populate_filmstrip() + self.preload_adjacent_images() + def load_image_from_path(self, file_path): folder = os.path.dirname(file_path) self.folder_model = ImageFolder(folder, start_file=file_path) diff --git a/node_unify.py b/node_unify.py deleted file mode 100644 index 2c6a59d..0000000 --- a/node_unify.py +++ /dev/null @@ -1,124 +0,0 @@ -# node_unify.py -# Unified prompt/workflow merge with correct Comfy alignment rules. - -import unicodedata - - -def normalize_value(v): - if v is None or v == "None": - return None - - if isinstance(v, bool): - return v - - if isinstance(v, (int, float)): - return float(v) - - if isinstance(v, list): - return [normalize_value(x) for x in v] - - if isinstance(v, dict): - return {k: normalize_value(val) for k, val in v.items()} - - if isinstance(v, str): - s = v.strip() - s = unicodedata.normalize("NFKC", s) - s = s.replace("\r\n", "\n").replace("\r", "\n") - - try: - return float(s) - except: - return s - - s = str(v).strip() - s = unicodedata.normalize("NFKC", s) - s = s.replace("\r\n", "\n").replace("\r", "\n") - return s - - -def values_equivalent(a, b): - return normalize_value(a) == normalize_value(b) - - -def unify_prompt_and_workflow(prompt_json, workflow_json): - prompt_nodes = {} - if prompt_json: - for k, v in prompt_json.items(): - if isinstance(v, dict): - try: - prompt_nodes[int(k)] = v - except: - pass - - workflow_nodes = {} - if workflow_json and "nodes" in workflow_json: - for n in workflow_json["nodes"]: - nid = n.get("id") - if isinstance(nid, int): - workflow_nodes[nid] = n - - all_ids = set(prompt_nodes.keys()) | set(workflow_nodes.keys()) - unified = {} - - for nid in sorted(all_ids): - pnode = prompt_nodes.get(nid) - wnode = workflow_nodes.get(nid) - - if pnode and "class_type" in pnode: - ntype = pnode["class_type"] - elif pnode and "type" in pnode: - ntype = pnode["type"] - elif wnode and "type" in wnode: - ntype = wnode["type"] - else: - ntype = "Unknown" - - params = {} - - # PROMPT LITERAL INPUTS (skip links) - prompt_literal_values = [] - prompt_literal_keys = [] - - if pnode and "inputs" in pnode: - for key, val in pnode["inputs"].items(): - # Link input → skip (not a literal) - if isinstance(val, list) and len(val) == 2 and isinstance(val[0], str): - continue - - params[key] = val - prompt_literal_keys.append(key) - prompt_literal_values.append(val) - - # WORKFLOW WIDGETS - w_values = wnode.get("widgets_values", []) if wnode else [] - - # --- Smart synchronization between prompt literal inputs and workflow widget values --- - skip_indices = set() - i = 0 # index for prompt literal values - j = 0 # index for workflow values - - while i < len(prompt_literal_values) and j < len(w_values): - - if values_equivalent(prompt_literal_values[i], w_values[j]): - # They match → skip this workflow param (no param#) - skip_indices.add(j) - i += 1 - j += 1 - else: - # They do NOT match → workflow has an extra value here - # Mark this as param#, but DO NOT advance prompt index - j += 1 - - # After loop, all remaining workflow values are extras → include as paramN - for idx, val in enumerate(w_values): - if idx not in skip_indices: - params[f"param{idx}"] = val - - - unified[nid] = { - "id": nid, - "type": ntype, - "params": params - } - - return unified diff --git a/prompt_chunk_samples.txt b/prompt_chunk_samples.txt new file mode 100644 index 0000000..197ecb4 --- /dev/null +++ b/prompt_chunk_samples.txt @@ -0,0 +1,1493 @@ +====================================================================== +FILE: straight_gen_monkeys.png +====================================================================== +{ + "5": { + "inputs": { + "width": 1024, + "height": 1024, + "batch_size": 6 + }, + "class_type": "EmptyLatentImage", + "_meta": { + "title": "Empty Latent Image" + } + }, + "8": { + "inputs": { + "samples": [ + "13", + 0 + ], + "vae": [ + "10", + 0 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "9": { + "inputs": { + "filename_prefix": "gend/monkeyvine/monkeyvine_ref", + "images": [ + "8", + 0 + ] + }, + "class_type": "SaveImage", + "_meta": { + "title": "Save Image" + } + }, + "10": { + "inputs": { + "vae_name": "ae.safetensors" + }, + "class_type": "VAELoader", + "_meta": { + "title": "Load VAE" + } + }, + "11": { + "inputs": { + "clip_name1": "t5xxl_fp16.safetensors", + "clip_name2": "clip_l.safetensors", + "type": "flux", + "device": "default" + }, + "class_type": "DualCLIPLoader", + "_meta": { + "title": "DualCLIPLoader" + } + }, + "12": { + "inputs": { + "unet_name": "pixelwave_flux1_dev_bf16_03.safetensors", + "weight_dtype": "default" + }, + "class_type": "UNETLoader", + "_meta": { + "title": "Load Diffusion Model" + } + }, + "13": { + "inputs": { + "noise": [ + "25", + 0 + ], + "guider": [ + "22", + 0 + ], + "sampler": [ + "16", + 0 + ], + "sigmas": [ + "17", + 0 + ], + "latent_image": [ + "5", + 0 + ] + }, + "class_type": "SamplerCustomAdvanced", + "_meta": { + "title": "SamplerCustomAdvanced" + } + }, + "16": { + "inputs": { + "sampler_name": "dpmpp_2m" + }, + "class_type": "KSamplerSelect", + "_meta": { + "title": "KSamplerSelect" + } + }, + "17": { + "inputs": { + "scheduler": "sgm_uniform", + "steps": 23, + "denoise": 1.0, + "model": [ + "12", + 0 + ] + }, + "class_type": "BasicScheduler", + "_meta": { + "title": "BasicScheduler" + } + }, + "22": { + "inputs": { + "model": [ + "12", + 0 + ], + "conditioning": [ + "26", + 0 + ] + }, + "class_type": "BasicGuider", + "_meta": { + "title": "BasicGuider" + } + }, + "25": { + "inputs": { + "noise_seed": 583741017171973 + }, + "class_type": "RandomNoise", + "_meta": { + "title": "RandomNoise" + } + }, + "26": { + "inputs": { + "clip_l": "summer, realistic, lush", + "t5xxl": " photograph of a cedar fence in a N American back yard, a bushy, flowering vine grows out of the ground and climbs up the fence, vine spreads out a few feet to either side of the top of the fence, there are about a dozen medium-sized monkeys on the vine and fence, some monkeys hanging, some monkeys sitting", + "guidance": 5.0, + "speak_and_recognation": { + "__value__": [ + false, + true + ] + }, + "clip": [ + "11", + 0 + ] + }, + "class_type": "CLIPTextEncodeFlux", + "_meta": { + "title": "CLIPTextEncodeFlux" + } + } +} + +====================================================================== +FILE: disc_fix_00006_.png +====================================================================== +{ + "1": { + "inputs": { + "seed": 506728175275987, + "steps": 30, + "cfg": 1.0, + "sampler_name": "euler", + "scheduler": "beta", + "denoise": 1.0, + "model": [ + "11", + 0 + ], + "positive": [ + "10", + 0 + ], + "negative": [ + "10", + 1 + ], + "latent_image": [ + "10", + 2 + ] + }, + "class_type": "KSampler", + "_meta": { + "title": "KSampler" + } + }, + "2": { + "inputs": { + "samples": [ + "1", + 0 + ], + "vae": [ + "8", + 0 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "3": { + "inputs": { + "filename_prefix": "procd/disc_fix", + "images": [ + "13", + 0 + ] + }, + "class_type": "SaveImage", + "_meta": { + "title": "Save Image" + } + }, + "4": { + "inputs": { + "image": "clipspace/clipspace-mask-3930874.8000000003.png [input]", + "upload": "image" + }, + "class_type": "LoadImage", + "_meta": { + "title": "Load Image For Inpaint" + }, + "is_changed": [ + "02ea58ec5591e1186065c0afac323cfb726d0fc02fcddaed35d614dea01631c0" + ] + }, + "5": { + "inputs": { + "text": "she was beautiful when she was young, long hair, large chest, cute eyes, puffy lips, but spent her life in hostess bars and nightclubs. now she is thirty and as she looks into the camera her face tells the story of her wild youth, She is wearing revealing bright yellow swimwear, a gold necklace hangs just above ample cleavage. Sitting next to her is her younger friend, cuter and busty, shorter hair and a tighter bright green bikini, she has a naughty wicked smile.", + "clip": [ + "9", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Positive Prompt)" + } + }, + "6": { + "inputs": { + "guidance": 25.0, + "conditioning": [ + "5", + 0 + ] + }, + "class_type": "FluxGuidance", + "_meta": { + "title": "FluxGuidance" + } + }, + "7": { + "inputs": { + "unet_name": "flux1-fill-dev.safetensors", + "weight_dtype": "default" + }, + "class_type": "UNETLoader", + "_meta": { + "title": "Load Diffusion Model" + } + }, + "8": { + "inputs": { + "vae_name": "ae.safetensors" + }, + "class_type": "VAELoader", + "_meta": { + "title": "Load VAE" + } + }, + "9": { + "inputs": { + "clip_name1": "clip_l.safetensors", + "clip_name2": "t5xxl_fp16.safetensors", + "type": "flux", + "device": "default" + }, + "class_type": "DualCLIPLoader", + "_meta": { + "title": "DualCLIPLoader" + } + }, + "10": { + "inputs": { + "noise_mask": false, + "positive": [ + "6", + 0 + ], + "negative": [ + "17", + 0 + ], + "vae": [ + "8", + 0 + ], + "pixels": [ + "12", + 1 + ], + "mask": [ + "12", + 2 + ] + }, + "class_type": "InpaintModelConditioning", + "_meta": { + "title": "InpaintModelConditioning" + } + }, + "11": { + "inputs": { + "model": [ + "7", + 0 + ] + }, + "class_type": "DifferentialDiffusion", + "_meta": { + "title": "Differential Diffusion" + } + }, + "12": { + "inputs": { + "context_expand_pixels": 20, + "context_expand_factor": 1.0, + "fill_mask_holes": true, + "blur_mask_pixels": 16.0, + "invert_mask": false, + "blend_pixels": 32.0, + "rescale_algorithm": "bicubic", + "mode": "forced size", + "force_width": 1024, + "force_height": 1024, + "rescale_factor": 1.0, + "min_width": 768, + "min_height": 768, + "max_width": 1024, + "max_height": 1024, + "padding": 64, + "image": [ + "4", + 0 + ], + "mask": [ + "4", + 1 + ], + "optional_context_mask": [ + "20", + 1 + ] + }, + "class_type": "InpaintCrop", + "_meta": { + "title": "\u2702\ufe0f Inpaint Crop" + } + }, + "13": { + "inputs": { + "rescale_algorithm": "bislerp", + "stitch": [ + "12", + 0 + ], + "inpainted_image": [ + "2", + 0 + ] + }, + "class_type": "InpaintStitch", + "_meta": { + "title": "\u2702\ufe0f Inpaint Stitch" + } + }, + "17": { + "inputs": { + "text": "", + "clip": [ + "9", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Negative Prompt)" + } + }, + "19": { + "inputs": { + "rgthree_comparer": { + "images": [ + { + "name": "A", + "selected": true, + "url": "/api/view?filename=rgthree.compare._temp_lipgx_00015_.png&type=temp&subfolder=&rand=0.4340572918453691" + }, + { + "name": "B", + "selected": true, + "url": "/api/view?filename=rgthree.compare._temp_lipgx_00016_.png&type=temp&subfolder=&rand=0.5994150191872023" + } + ] + }, + "image_a": [ + "4", + 0 + ], + "image_b": [ + "13", + 0 + ] + }, + "class_type": "Image Comparer (rgthree)", + "_meta": { + "title": "Image Comparer (rgthree)" + } + }, + "20": { + "inputs": { + "image": "clipspace/clipspace-mask-16580118.299999999.png [input]", + "upload": "image" + }, + "class_type": "LoadImage", + "_meta": { + "title": "Load Image" + }, + "is_changed": [ + "e8fbba0268d891bbb3329222ecd52b5cd04f6f68ee2038b8e6db7c63c7576f1b" + ] + } +} + +====================================================================== +FILE: redux_1_00002_.png +====================================================================== +{ + "6": { + "inputs": { + "text": "mysterious sultry woman named Alice23. this is a photograph of the time Alice23 came over to welcome our back yard when we moved in, when Alice23 brought wine and treats, we were sitting on the patio in the garden, she was irresistible, so full of desire.", + "speak_and_recognation": { + "__value__": [ + false, + true + ] + }, + "clip": [ + "11", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Positive Prompt)" + } + }, + "8": { + "inputs": { + "samples": [ + "13", + 0 + ], + "vae": [ + "10", + 0 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "9": { + "inputs": { + "filename_prefix": "gend/patio/redux_1", + "images": [ + "8", + 0 + ] + }, + "class_type": "SaveImage", + "_meta": { + "title": "Save Image" + } + }, + "10": { + "inputs": { + "vae_name": "ae.safetensors" + }, + "class_type": "VAELoader", + "_meta": { + "title": "Load VAE" + } + }, + "11": { + "inputs": { + "clip_name1": "t5xxl_fp16.safetensors", + "clip_name2": "clip_l.safetensors", + "type": "flux", + "device": "default" + }, + "class_type": "DualCLIPLoader", + "_meta": { + "title": "DualCLIPLoader" + } + }, + "12": { + "inputs": { + "unet_name": "pixelwave_flux1_dev_bf16_03.safetensors", + "weight_dtype": "default" + }, + "class_type": "UNETLoader", + "_meta": { + "title": "Load Diffusion Model" + } + }, + "13": { + "inputs": { + "noise": [ + "25", + 0 + ], + "guider": [ + "22", + 0 + ], + "sampler": [ + "16", + 0 + ], + "sigmas": [ + "17", + 0 + ], + "latent_image": [ + "27", + 0 + ] + }, + "class_type": "SamplerCustomAdvanced", + "_meta": { + "title": "SamplerCustomAdvanced" + } + }, + "16": { + "inputs": { + "sampler_name": "euler" + }, + "class_type": "KSamplerSelect", + "_meta": { + "title": "KSamplerSelect" + } + }, + "17": { + "inputs": { + "scheduler": "simple", + "steps": 20, + "denoise": 1.0, + "model": [ + "30", + 0 + ] + }, + "class_type": "BasicScheduler", + "_meta": { + "title": "BasicScheduler" + } + }, + "22": { + "inputs": { + "model": [ + "30", + 0 + ], + "conditioning": [ + "41", + 0 + ] + }, + "class_type": "BasicGuider", + "_meta": { + "title": "BasicGuider" + } + }, + "25": { + "inputs": { + "noise_seed": 162089893908859 + }, + "class_type": "RandomNoise", + "_meta": { + "title": "RandomNoise" + } + }, + "26": { + "inputs": { + "guidance": 4.0, + "conditioning": [ + "6", + 0 + ] + }, + "class_type": "FluxGuidance", + "_meta": { + "title": "FluxGuidance" + } + }, + "27": { + "inputs": { + "width": 1024, + "height": 960, + "batch_size": 4 + }, + "class_type": "EmptySD3LatentImage", + "_meta": { + "title": "EmptySD3LatentImage" + } + }, + "30": { + "inputs": { + "max_shift": 1.15, + "base_shift": 0.5, + "width": 1024, + "height": 960, + "model": [ + "12", + 0 + ] + }, + "class_type": "ModelSamplingFlux", + "_meta": { + "title": "ModelSamplingFlux" + } + }, + "38": { + "inputs": { + "clip_name": "sigclip_vision_patch14_384.safetensors" + }, + "class_type": "CLIPVisionLoader", + "_meta": { + "title": "Load CLIP Vision" + } + }, + "39": { + "inputs": { + "crop": "none", + "clip_vision": [ + "38", + 0 + ], + "image": [ + "40", + 0 + ] + }, + "class_type": "CLIPVisionEncode", + "_meta": { + "title": "CLIP Vision Encode" + } + }, + "40": { + "inputs": { + "image": "alice_35_00010_.png" + }, + "class_type": "LoadImage", + "_meta": { + "title": "Load Image" + }, + "is_changed": [ + "094fa8c02f1afc382ae9191f2e13d99118e2d5f08cef57bc139f0d9fe5f66b71" + ] + }, + "41": { + "inputs": { + "strength": 0.8500000000000002, + "strength_type": "multiply", + "conditioning": [ + "26", + 0 + ], + "style_model": [ + "42", + 0 + ], + "clip_vision_output": [ + "39", + 0 + ] + }, + "class_type": "StyleModelApply", + "_meta": { + "title": "Apply Style Model" + } + }, + "42": { + "inputs": { + "style_model_name": "flux1-redux-dev.safetensors" + }, + "class_type": "StyleModelLoader", + "_meta": { + "title": "Load Style Model" + } + } +} + +====================================================================== +FILE: controlnet_i2i_tableLady_00004_.png +====================================================================== +{ + "5": { + "inputs": { + "width": 1024, + "height": 544, + "batch_size": 3 + }, + "class_type": "EmptyLatentImage", + "_meta": { + "title": "Empty Latent Image" + } + }, + "8": { + "inputs": { + "samples": [ + "37", + 0 + ], + "vae": [ + "10", + 0 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "9": { + "inputs": { + "filename_prefix": "gend/flux_practice/controlnet_tableLady", + "images": [ + "8", + 0 + ] + }, + "class_type": "SaveImage", + "_meta": { + "title": "Save Image" + } + }, + "10": { + "inputs": { + "vae_name": "ae.safetensors" + }, + "class_type": "VAELoader", + "_meta": { + "title": "Load VAE" + } + }, + "11": { + "inputs": { + "clip_name1": "t5xxl_fp16.safetensors", + "clip_name2": "ViT-L-14-TEXT-detail-improved-hiT-GmP-TE-only-HF.safetensors", + "type": "flux", + "device": "default" + }, + "class_type": "DualCLIPLoader", + "_meta": { + "title": "DualCLIPLoader" + } + }, + "12": { + "inputs": { + "unet_name": "pixelwave_flux1_dev_bf16_03.safetensors", + "weight_dtype": "default" + }, + "class_type": "UNETLoader", + "_meta": { + "title": "Load Diffusion Model" + } + }, + "16": { + "inputs": { + "sampler_name": "dpmpp_2m" + }, + "class_type": "KSamplerSelect", + "_meta": { + "title": "KSamplerSelect" + } + }, + "17": { + "inputs": { + "scheduler": "sgm_uniform", + "steps": 33, + "denoise": 1, + "model": [ + "12", + 0 + ] + }, + "class_type": "BasicScheduler", + "_meta": { + "title": "BasicScheduler" + } + }, + "22": { + "inputs": { + "model": [ + "12", + 0 + ], + "conditioning": [ + "26", + 0 + ] + }, + "class_type": "BasicGuider", + "_meta": { + "title": "BasicGuider" + } + }, + "25": { + "inputs": { + "noise_seed": 206640685800676 + }, + "class_type": "RandomNoise", + "_meta": { + "title": "RandomNoise" + } + }, + "26": { + "inputs": { + "clip_l": "POV shot. We are outside in a tropical setting, looking across a faded wood table at an Asian Philippine woman. This is a portrait of former glory, she used to be beautiful when she was young, but spent her life in hostess bars. Now she is forty five years old, a few pounds heavier and the scars of her past life evident as she looks into the camera her face tells the story of her wild and overindulgent youth. to the right of frame a cigarette sits horizontally in a gold metal ashtray, smoke tendril rising up smoothly then breaking apart.\n", + "t5xxl": "tags: film photography portrait, dark day, light rain, dour mood, stormy weather, sad, mournful, pensive, heavy make-up, smoke tendril rising up smoothly then breaking apart, saturated tropical island colors.\n", + "guidance": 4.5, + "speak_and_recognation": { + "__value__": [ + false, + true + ] + }, + "clip": [ + "11", + 0 + ] + }, + "class_type": "CLIPTextEncodeFlux", + "_meta": { + "title": "CLIPTextEncodeFlux" + } + }, + "35": { + "inputs": { + "strength": 0.37000000000000005, + "start_percent": 0.0, + "end_percent": 0.6950000000000002, + "positive": [ + "26", + 0 + ], + "negative": [ + "36", + 0 + ], + "control_net": [ + "38", + 0 + ], + "image": [ + "41", + 0 + ], + "vae": [ + "39", + 0 + ] + }, + "class_type": "ControlNetApplyAdvanced", + "_meta": { + "title": "Apply ControlNet" + } + }, + "36": { + "inputs": { + "text": "", + "speak_and_recognation": { + "__value__": [ + false, + true + ] + }, + "clip": [ + "11", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "37": { + "inputs": { + "seed": 1072580640823242, + "steps": 25, + "cfg": 1.0, + "sampler_name": "dpmpp_2m", + "scheduler": "sgm_uniform", + "denoise": 0.3600000000000001, + "model": [ + "12", + 0 + ], + "positive": [ + "35", + 0 + ], + "negative": [ + "35", + 1 + ], + "latent_image": [ + "46", + 0 + ] + }, + "class_type": "KSampler", + "_meta": { + "title": "KSampler" + } + }, + "38": { + "inputs": { + "control_net_name": "flux.1-dev_controlnet_union.safetensors" + }, + "class_type": "ControlNetLoader", + "_meta": { + "title": "Load ControlNet Model" + } + }, + "39": { + "inputs": { + "vae_name": "ae.safetensors" + }, + "class_type": "VAELoader", + "_meta": { + "title": "Load VAE" + } + }, + "40": { + "inputs": { + "image": "pixelwave_00042_.png" + }, + "class_type": "LoadImage", + "_meta": { + "title": "Load Image" + }, + "is_changed": [ + "d8fd5802fe399b48163f5724863057d7ce12c2503522b85f889706c2a71fc713" + ] + }, + "41": { + "inputs": { + "preprocessor": "DepthAnythingV2Preprocessor", + "resolution": 768, + "image": [ + "40", + 0 + ] + }, + "class_type": "AIO_Preprocessor", + "_meta": { + "title": "AIO Aux Preprocessor" + } + }, + "42": { + "inputs": { + "images": [ + "41", + 0 + ] + }, + "class_type": "PreviewImage", + "_meta": { + "title": "Preview Image" + } + }, + "44": { + "inputs": { + "width": 1024, + "height": 768, + "batch_size": 1 + }, + "class_type": "EmptyLatentImage", + "_meta": { + "title": "Empty Latent Image" + } + }, + "45": { + "inputs": { + "image": "pixelwave_00042_.png" + }, + "class_type": "LoadImage", + "_meta": { + "title": "Load Image" + }, + "is_changed": [ + "d8fd5802fe399b48163f5724863057d7ce12c2503522b85f889706c2a71fc713" + ] + }, + "46": { + "inputs": { + "pixels": [ + "45", + 0 + ], + "vae": [ + "39", + 0 + ] + }, + "class_type": "VAEEncode", + "_meta": { + "title": "VAE Encode" + } + }, + "47": { + "inputs": { + "rgthree_comparer": { + "images": [ + { + "name": "A", + "selected": true, + "url": "/api/view?filename=rgthree.compare._temp_cgqux_00003_.png&type=temp&subfolder=&rand=0.5164693888047022" + }, + { + "name": "B", + "selected": true, + "url": "/api/view?filename=rgthree.compare._temp_cgqux_00004_.png&type=temp&subfolder=&rand=0.6139242934037267" + } + ] + }, + "image_a": [ + "8", + 0 + ], + "image_b": [ + "40", + 0 + ] + }, + "class_type": "Image Comparer (rgthree)", + "_meta": { + "title": "Image Comparer (rgthree)" + } + } +} + +====================================================================== +FILE: dual_controlnet_anime_sd35.png +====================================================================== +{ + "7": { + "inputs": { + "text": "(hands), text, error, cropped, (worst quality:1.2), (low quality:1.2), normal quality, (jpeg artifacts:1.3), signature, watermark, username, blurry, artist name, monochrome, sketch, censorship, censor, (copyright:1.2), extra legs, (forehead mark) (depth of field) (emotionless) (penis)", + "speak_and_recognation": { + "__value__": [ + false, + true + ] + }, + "clip": [ + "38", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "8": { + "inputs": { + "samples": [ + "39", + 0 + ], + "vae": [ + "31", + 2 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "9": { + "inputs": { + "filename_prefix": "gend/tests/sd35_dual__controlnets", + "images": [ + "8", + 0 + ] + }, + "class_type": "SaveImage", + "_meta": { + "title": "Save Image" + } + }, + "20": { + "inputs": { + "image": "farm_bg.png" + }, + "class_type": "LoadImage", + "_meta": { + "title": "Load Image" + }, + "is_changed": [ + "fc768c73dcc7a70011065a49f874f9adbcf45f97eda526b32570ccc7b4e71e5c" + ] + }, + "21": { + "inputs": { + "image": "pose_present.png" + }, + "class_type": "LoadImage", + "_meta": { + "title": "Load Image" + }, + "is_changed": [ + "8e0e54ef33bc82437f8841c33a2afb15e16b90173c3d7b37a3617db82684fc39" + ] + }, + "24": { + "inputs": { + "text": "(solo) anime girl cartoon realistic (flat chest:0.9), (fennec ears:1.0) (fox ears:1.0), (messy hair) blonde hair, blue eyes, standing, serafuku sweater, (brick house) (scenery lush landscape) (sun clouds) sky, mountains,\n\n", + "speak_and_recognation": { + "__value__": [ + false, + true + ] + }, + "clip": [ + "38", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "26": { + "inputs": { + "control_net_name": "sd3.5_large_controlnet_depth.safetensors" + }, + "class_type": "ControlNetLoader", + "_meta": { + "title": "Load ControlNet Model" + } + }, + "27": { + "inputs": { + "control_net_name": "sd3.5_large_controlnet_canny.safetensors" + }, + "class_type": "ControlNetLoader", + "_meta": { + "title": "Load ControlNet Model" + } + }, + "31": { + "inputs": { + "ckpt_name": "sd3.5_large.safetensors" + }, + "class_type": "CheckpointLoaderSimple", + "_meta": { + "title": "Load Checkpoint" + } + }, + "35": { + "inputs": { + "width": 768, + "height": 768, + "batch_size": 1 + }, + "class_type": "EmptySD3LatentImage", + "_meta": { + "title": "EmptySD3LatentImage" + } + }, + "38": { + "inputs": { + "clip_name1": "clip_g.safetensors", + "clip_name2": "clip_l.safetensors", + "clip_name3": "t5xxl_fp8_e4m3fn.safetensors" + }, + "class_type": "TripleCLIPLoader", + "_meta": { + "title": "TripleCLIPLoader" + } + }, + "39": { + "inputs": { + "seed": 840133775034047, + "steps": 33, + "cfg": 4.0, + "sampler_name": "dpmpp_2m", + "scheduler": "sgm_uniform", + "denoise": 1.0, + "model": [ + "31", + 0 + ], + "positive": [ + "47", + 0 + ], + "negative": [ + "47", + 1 + ], + "latent_image": [ + "35", + 0 + ] + }, + "class_type": "KSampler", + "_meta": { + "title": "KSampler" + } + }, + "47": { + "inputs": { + "strength": 0.53, + "start_percent": 0.0, + "end_percent": 0.893, + "positive": [ + "24", + 0 + ], + "negative": [ + "7", + 0 + ], + "control_net": [ + "26", + 0 + ], + "vae": [ + "31", + 2 + ], + "image": [ + "20", + 0 + ] + }, + "class_type": "ControlNetApplySD3", + "_meta": { + "title": "Apply Controlnet with VAE" + } + }, + "48": { + "inputs": { + "images": [ + "8", + 0 + ] + }, + "class_type": "PreviewImage", + "_meta": { + "title": "Preview Image" + } + }, + "50": { + "inputs": { + "preprocessor": "DepthAnythingPreprocessor", + "resolution": 512, + "image": [ + "20", + 0 + ] + }, + "class_type": "AIO_Preprocessor", + "_meta": { + "title": "AIO Aux Preprocessor" + } + }, + "51": { + "inputs": { + "images": [ + "50", + 0 + ] + }, + "class_type": "PreviewImage", + "_meta": { + "title": "Preview Image" + } + } +} + +====================================================================== +FILE: long_prompt.0001.png +====================================================================== +{ + "5": { + "inputs": { + "width": 1536, + "height": 1024, + "batch_size": 4 + }, + "class_type": "EmptyLatentImage", + "_meta": { + "title": "Empty Latent Image" + } + }, + "6": { + "inputs": { + "text": "against a background grimy run down futuristic Los Angeles, four girls early twenties stand against a wall on a corner in the rain, two asian two white, their heavy makeup is heavy smudged and running, they have been at a rave, decadent dance party, wearing bright colored shiny neo punk clothes, glowing illuminated jewelry, LED phosphorescent glow in the dark accessories, a subtle thin layer of yellow glitter around their eyes. one girl is holding an e-cigarette pen in one hand looking at camera, she is exhaling from her mouth a cloud of magic fairy dust smoke, the smoke cloud is big red and orange filled with bright yellow sparkling particles. The other girl has already exhaled a similar cloud, we see just the remnants of the cloud dissipating away from her, cinematic still, digital film camera,\ntags: Medium close up, low light, night shot, BMD pocket 6K cinema camera, high ISO, sensor noise, glowing shiny immature colors, sneaky private mood, depravity", + "clip": [ + "11", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "8": { + "inputs": { + "samples": [ + "13", + 0 + ], + "vae": [ + "10", + 0 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "9": { + "inputs": { + "filename_prefix": "WIP/more-groupies", + "images": [ + "8", + 0 + ] + }, + "class_type": "SaveImage", + "_meta": { + "title": "Save Image" + } + }, + "10": { + "inputs": { + "vae_name": "FLUX.safetensors" + }, + "class_type": "VAELoader", + "_meta": { + "title": "Load VAE" + } + }, + "11": { + "inputs": { + "clip_name1": "clip_l.safetensors", + "clip_name2": "t5xxl_fp16.safetensors", + "type": "flux" + }, + "class_type": "DualCLIPLoader", + "_meta": { + "title": "DualCLIPLoader" + } + }, + "12": { + "inputs": { + "unet_name": "pixelwave_flux1_dev_bf16_03.safetensors", + "weight_dtype": "default" + }, + "class_type": "UNETLoader", + "_meta": { + "title": "Load Diffusion Model" + } + }, + "13": { + "inputs": { + "noise": [ + "25", + 0 + ], + "guider": [ + "22", + 0 + ], + "sampler": [ + "16", + 0 + ], + "sigmas": [ + "17", + 0 + ], + "latent_image": [ + "5", + 0 + ] + }, + "class_type": "SamplerCustomAdvanced", + "_meta": { + "title": "SamplerCustomAdvanced" + } + }, + "16": { + "inputs": { + "sampler_name": "euler" + }, + "class_type": "KSamplerSelect", + "_meta": { + "title": "KSamplerSelect" + } + }, + "17": { + "inputs": { + "scheduler": "simple", + "steps": 20, + "denoise": 1.0, + "model": [ + "12", + 0 + ] + }, + "class_type": "BasicScheduler", + "_meta": { + "title": "BasicScheduler" + } + }, + "22": { + "inputs": { + "model": [ + "12", + 0 + ], + "conditioning": [ + "6", + 0 + ] + }, + "class_type": "BasicGuider", + "_meta": { + "title": "BasicGuider" + } + }, + "25": { + "inputs": { + "noise_seed": 845373432002232 + }, + "class_type": "RandomNoise", + "_meta": { + "title": "RandomNoise" + } + } +}