diff --git a/__init__.py b/__init__.py index c090b0c..2a361fa 100644 --- a/__init__.py +++ b/__init__.py @@ -61,6 +61,8 @@ from .modules.providerSettings.alibabaProviderSettings import RunwareAlibabaProv from .modules.providerSettings.googleProviderSettings import RunwareGoogleProviderSettings from .modules.providerSettings.blackForestProviderSettings import RunwareBlackForestProviderSettings from .modules.providerSettings.xaiProviderSettings import RunwareXAIProviderSettings +from .modules.providerSettings.sourcefulProviderSettings import RunwareSourcefulProviderSettings +from .modules.providerSettings.sourcefulProviderSettingsFonts import RunwareSourcefulProviderSettingsFonts from .modules.ultralyticsInputs import RunwareUltralyticsInputs from .modules.providerSettings.syncSegment import RunwareSyncSegment from .modules.providerSettings.syncProviderSettings import RunwareSyncProviderSettings @@ -153,6 +155,8 @@ NODE_CLASS_MAPPINGS = { "Runware Google Provider Settings": RunwareGoogleProviderSettings, "Runware BlackForest Labs Provider Settings": RunwareBlackForestProviderSettings, "Runware xAI Provider Settings": RunwareXAIProviderSettings, + "Runware Sourceful Provider Settings": RunwareSourcefulProviderSettings, + "Runware Sourceful Provider Settings Fonts": RunwareSourcefulProviderSettingsFonts, "Runware Image Inference Ultralytics": RunwareUltralyticsInputs, "Runware Sync Segment": RunwareSyncSegment, "Runware Sync Provider Settings": RunwareSyncProviderSettings, diff --git a/clientlibs/main.js b/clientlibs/main.js index 329dc6f..4768d95 100644 --- a/clientlibs/main.js +++ b/clientlibs/main.js @@ -1,6 +1,6 @@ import { app } from "../../scripts/app.js"; import { api } from "../../scripts/api.js"; -import { promptEnhanceHandler, syncDimensionsNodeHandler, searchNodeHandler, APIKeyHandler, captionNodeHandler, mediaUUIDHandler, save3DFilepathHandler, videoTranscriptionHandler, videoOutputsHandler, handleCustomErrors, videoInferenceDimensionsHandler, videoModelSearchFilterHandler, audioModelSearchFilterHandler, useParameterToggleHandler, imageInferenceToggleHandler, upscalerToggleHandler, videoUpscalerToggleHandler, audioInferenceToggleHandler, acceleratorOptionsToggleHandler, bytedanceProviderSettingsToggleHandler, xaiProviderSettingsToggleHandler, viduProviderSettingsToggleHandler, ultralyticsProviderSettingsToggleHandler, openaiProviderSettingsToggleHandler, lightricksProviderSettingsToggleHandler, klingProviderSettingsToggleHandler, lumaProviderSettingsToggleHandler, briaProviderSettingsToggleHandler, pixverseProviderSettingsToggleHandler, alibabaProviderSettingsToggleHandler, mireloProviderSettingsToggleHandler, googleProviderSettingsToggleHandler, syncProviderSettingsToggleHandler, syncSegmentToggleHandler, settingsToggleHandler, audioInputToggleHandler, speechInputToggleHandler, briaProviderMaskToggleHandler, wanAnimateAdvancedFeatureSettingsToggleHandler, videoAdvancedFeatureInputsToggleHandler, audioInferenceInputsToggleHandler } from "./utils.js"; +import { promptEnhanceHandler, syncDimensionsNodeHandler, searchNodeHandler, APIKeyHandler, captionNodeHandler, mediaUUIDHandler, save3DFilepathHandler, videoTranscriptionHandler, videoOutputsHandler, handleCustomErrors, videoInferenceDimensionsHandler, videoModelSearchFilterHandler, audioModelSearchFilterHandler, useParameterToggleHandler, imageInferenceToggleHandler, upscalerToggleHandler, videoUpscalerToggleHandler, audioInferenceToggleHandler, acceleratorOptionsToggleHandler, bytedanceProviderSettingsToggleHandler, xaiProviderSettingsToggleHandler, viduProviderSettingsToggleHandler, sourcefulProviderSettingsToggleHandler, sourcefulProviderSettingsFontsToggleHandler, ultralyticsProviderSettingsToggleHandler, openaiProviderSettingsToggleHandler, lightricksProviderSettingsToggleHandler, klingProviderSettingsToggleHandler, lumaProviderSettingsToggleHandler, briaProviderSettingsToggleHandler, pixverseProviderSettingsToggleHandler, alibabaProviderSettingsToggleHandler, mireloProviderSettingsToggleHandler, googleProviderSettingsToggleHandler, syncProviderSettingsToggleHandler, syncSegmentToggleHandler, settingsToggleHandler, audioInputToggleHandler, speechInputToggleHandler, briaProviderMaskToggleHandler, wanAnimateAdvancedFeatureSettingsToggleHandler, videoAdvancedFeatureInputsToggleHandler, audioInferenceInputsToggleHandler } from "./utils.js"; import { RUNWARE_NODE_TYPES, RUNWARE_NODE_PROPS, SEARCH_TERMS } from "./types.js"; const nodeInitList = []; @@ -110,6 +110,10 @@ app.registerExtension({ syncSegmentToggleHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.VIDUPROVIDERSETTINGS) { viduProviderSettingsToggleHandler(node); + } else if(nodeClass === RUNWARE_NODE_TYPES.SOURCEFULPROVIDERSETTINGS) { + sourcefulProviderSettingsToggleHandler(node); + } else if(nodeClass === RUNWARE_NODE_TYPES.SOURCEFULPROVIDERSETTINGSFONTS) { + sourcefulProviderSettingsFontsToggleHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.SETTINGS) { settingsToggleHandler(node); } else if(nodeClass === RUNWARE_NODE_TYPES.AUDIOINPUT) { diff --git a/clientlibs/types.js b/clientlibs/types.js index a44232d..6a44812 100644 --- a/clientlibs/types.js +++ b/clientlibs/types.js @@ -107,6 +107,8 @@ const RUNWARE_NODE_TYPES = { ALIBABAPROVIDERSETTINGS: "Runware Alibaba Provider Settings", BLACKFORESTPROVIDERSETTINGS: "Runware BlackForest Labs Provider Settings", XAIPROVIDERSETTINGS: "Runware xAI Provider Settings", + SOURCEFULPROVIDERSETTINGS: "Runware Sourceful Provider Settings", + SOURCEFULPROVIDERSETTINGSFONTS: "Runware Sourceful Provider Settings Fonts", ULTRALYTICSINPUTS: "Runware Image Inference Ultralytics", GOOGLEPROVIDERSETTINGS: "Runware Google Provider Settings", SYNCSEGMENT: "Runware Sync Segment", @@ -370,6 +372,14 @@ const RUNWARE_NODE_PROPS = { bgColor: DEFAULT_BGCOLOR, colorModeOnly: true, }, + [RUNWARE_NODE_TYPES.SOURCEFULPROVIDERSETTINGS]: { + bgColor: DEFAULT_BGCOLOR, + colorModeOnly: true, + }, + [RUNWARE_NODE_TYPES.SOURCEFULPROVIDERSETTINGSFONTS]: { + bgColor: DEFAULT_BGCOLOR, + colorModeOnly: true, + }, [RUNWARE_NODE_TYPES.ULTRALYTICSINPUTS]: { bgColor: DEFAULT_BGCOLOR, colorModeOnly: true, diff --git a/clientlibs/utils.js b/clientlibs/utils.js index 1bd7454..bd69aa3 100644 --- a/clientlibs/utils.js +++ b/clientlibs/utils.js @@ -1449,6 +1449,110 @@ function viduProviderSettingsToggleHandler(viduNode) { } } +function sourcefulProviderSettingsToggleHandler(sourcefulNode) { + const useTransparencyWidget = sourcefulNode.widgets.find(w => w.name === "useTransparency"); + const transparencyWidget = sourcefulNode.widgets.find(w => w.name === "transparency"); + const useEnhancePromptWidget = sourcefulNode.widgets.find(w => w.name === "useEnhancePrompt"); + const enhancePromptWidget = sourcefulNode.widgets.find(w => w.name === "enhancePrompt"); + + function toggleWidgetState(useWidget, paramWidget, paramName) { + if (!useWidget || !paramWidget) return; + + function toggleEnabled() { + const enabled = useWidget.value === true; + + if (paramWidget.inputEl) { + paramWidget.inputEl.disabled = !enabled; + paramWidget.inputEl.style.opacity = enabled ? "1" : "0.5"; + paramWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed"; + paramWidget.inputEl.readOnly = !enabled; + } + paramWidget.disabled = !enabled; + + if (!paramWidget.inputEl) { + const nodeElement = sourcefulNode.htmlElements?.widgetsContainer || sourcefulNode.htmlElements; + if (nodeElement) { + const input = nodeElement.querySelector(`input[name="${paramName}"], textarea[name="${paramName}"], select[name="${paramName}"]`); + if (input) { + input.disabled = !enabled; + input.style.opacity = enabled ? "1" : "0.5"; + input.style.pointerEvents = enabled ? "auto" : "none"; + } + } + } + + sourcefulNode.setDirtyCanvas(true); + } + + appendWidgetCB(useWidget, () => { + setTimeout(toggleEnabled, 50); + }); + + setTimeout(toggleEnabled, 100); + } + + if (useTransparencyWidget && transparencyWidget) { + toggleWidgetState(useTransparencyWidget, transparencyWidget, "transparency"); + } + if (useEnhancePromptWidget && enhancePromptWidget) { + toggleWidgetState(useEnhancePromptWidget, enhancePromptWidget, "enhancePrompt"); + } +} + +function sourcefulProviderSettingsFontsToggleHandler(fontsNode) { + const useFont1Widget = fontsNode.widgets.find(w => w.name === "useFont1"); + const fontUrl1Widget = fontsNode.widgets.find(w => w.name === "fontUrl1"); + const text1Widget = fontsNode.widgets.find(w => w.name === "text1"); + const useFont2Widget = fontsNode.widgets.find(w => w.name === "useFont2"); + const fontUrl2Widget = fontsNode.widgets.find(w => w.name === "fontUrl2"); + const text2Widget = fontsNode.widgets.find(w => w.name === "text2"); + + function toggleFontGroup(useWidget, fontUrlWidget, textWidget, fontParamName, textParamName) { + if (!useWidget || !fontUrlWidget || !textWidget) return; + + function toggleEnabled() { + const enabled = useWidget.value === true; + + [fontUrlWidget, textWidget].forEach(paramWidget => { + if (paramWidget.inputEl) { + paramWidget.inputEl.disabled = !enabled; + paramWidget.inputEl.style.opacity = enabled ? "1" : "0.5"; + paramWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed"; + paramWidget.inputEl.readOnly = !enabled; + } + paramWidget.disabled = !enabled; + }); + + const nodeElement = fontsNode.htmlElements?.widgetsContainer || fontsNode.htmlElements; + if (nodeElement) { + [fontParamName, textParamName].forEach(paramName => { + const input = nodeElement.querySelector(`input[name="${paramName}"], textarea[name="${paramName}"]`); + if (input) { + input.disabled = !enabled; + input.style.opacity = enabled ? "1" : "0.5"; + input.style.pointerEvents = enabled ? "auto" : "none"; + } + }); + } + + fontsNode.setDirtyCanvas(true); + } + + appendWidgetCB(useWidget, () => { + setTimeout(toggleEnabled, 50); + }); + + setTimeout(toggleEnabled, 100); + } + + if (useFont1Widget && fontUrl1Widget && text1Widget) { + toggleFontGroup(useFont1Widget, fontUrl1Widget, text1Widget, "fontUrl1", "text1"); + } + if (useFont2Widget && fontUrl2Widget && text2Widget) { + toggleFontGroup(useFont2Widget, fontUrl2Widget, text2Widget, "fontUrl2", "text2"); + } +} + function openaiProviderSettingsToggleHandler(openaiNode) { // Find all "use" parameter widgets for OpenAI Provider Settings (these are COMBO widgets) const useBackgroundWidget = openaiNode.widgets.find(w => w.name === "useBackground"); @@ -3440,6 +3544,8 @@ export { bytedanceProviderSettingsToggleHandler, xaiProviderSettingsToggleHandler, viduProviderSettingsToggleHandler, + sourcefulProviderSettingsToggleHandler, + sourcefulProviderSettingsFontsToggleHandler, ultralyticsProviderSettingsToggleHandler, openaiProviderSettingsToggleHandler, lightricksProviderSettingsToggleHandler, diff --git a/modules/imageInference.py b/modules/imageInference.py index 4587eb0..e73f448 100644 --- a/modules/imageInference.py +++ b/modules/imageInference.py @@ -378,7 +378,7 @@ class txt2img: if isinstance(providerSettings, dict): # Check if providerSettings already has a provider key (e.g., {"alibaba": {...}}) if any(key in providerSettings for key in ["alibaba", "bytedance", "klingai", "openai", "pixverse", - "bria", "lightricks", "luma", "minimax", "runway", "vidu", "elevenlabs", "bfl", "xai"]): + "bria", "lightricks", "luma", "minimax", "runway", "vidu", "elevenlabs", "bfl", "xai", "sourceful"]): final_provider_settings = providerSettings else: # Otherwise, wrap with the extracted provider name diff --git a/modules/imageInferenceInputs.py b/modules/imageInferenceInputs.py index eb954a6..710e805 100644 --- a/modules/imageInferenceInputs.py +++ b/modules/imageInferenceInputs.py @@ -5,6 +5,7 @@ class imageInferenceInputs: """Image Inference Inputs node for configuring image generation inputs""" MAX_REFERENCE_IMAGES = 14 + MAX_SUPER_RESOLUTION_REFERENCE_IMAGES = 5 @classmethod def INPUT_TYPES(cls): @@ -27,6 +28,12 @@ class imageInferenceInputs: "default": "", }) + for i in range(1, cls.MAX_SUPER_RESOLUTION_REFERENCE_IMAGES + 1): + ordinal = rwUtils.getOrdinal(i) + optionalInputs[f"Super Resolution Reference Image {i}"] = ("IMAGE", { + "tooltip": f"Specifies {ordinal.capitalize()} Super Resolution Reference Image for the inputs.", + }) + return { "required": {}, "optional": optionalInputs @@ -54,6 +61,10 @@ class imageInferenceInputs: if len(references) > 0: inputs["referenceImages"] = references + super_resolution_refs = self._collectSuperResolutionReferences(kwargs) + if len(super_resolution_refs) > 0: + inputs["superResolutionReferenceImages"] = super_resolution_refs + return (inputs,) def _collectReferences(self, kwargs): @@ -91,3 +102,12 @@ class imageInferenceInputs: references.append(entry) return references + + def _collectSuperResolutionReferences(self, kwargs): + """Collect and convert super resolution reference images to list (same pattern as referenceImages)""" + images = [] + for i in range(1, self.MAX_SUPER_RESOLUTION_REFERENCE_IMAGES + 1): + image = kwargs.get(f"Super Resolution Reference Image {i}", None) + if image is not None: + images.append(rwUtils.convertTensor2IMG(image)) + return images diff --git a/modules/providerSettings/sourcefulProviderSettings.py b/modules/providerSettings/sourcefulProviderSettings.py new file mode 100644 index 0000000..068a314 --- /dev/null +++ b/modules/providerSettings/sourcefulProviderSettings.py @@ -0,0 +1,72 @@ +""" +Runware Sourceful Provider Settings Node +Provides Sourceful-specific settings for image generation (providerSettings.sourceful.*) +""" + +from typing import Dict, Any, List + + +class RunwareSourcefulProviderSettings: + """Runware Sourceful Provider Settings Node""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": {}, + "optional": { + "useTransparency": ("BOOLEAN", { + "tooltip": "Enable to include transparency parameter in API request", + "default": False, + }), + "transparency": ("BOOLEAN", { + "tooltip": "Transparency setting for image generation. Only used when 'Use Transparency' is enabled.", + "default": False, + }), + "useEnhancePrompt": ("BOOLEAN", { + "tooltip": "Enable to include enhancePrompt parameter in API request", + "default": False, + }), + "enhancePrompt": ("BOOLEAN", { + "tooltip": "When true, enhances the provided prompt. Only used when 'Use Enhance Prompt' is enabled.", + "default": True, + }), + "fontInputs": ("RUNWARESOURCEFULFONTINPUTS", { + "tooltip": "Connect Runware Sourceful Provider Settings Fonts node to provide font references (fontUrl and text). Up to 2 fonts.", + }), + } + } + + RETURN_TYPES = ("RUNWAREPROVIDERSETTINGS",) + RETURN_NAMES = ("providerSettings",) + FUNCTION = "create_provider_settings" + CATEGORY = "Runware/Provider Settings" + DESCRIPTION = "Configure Sourceful-specific provider settings for image generation: transparency, enhancePrompt, and font inputs." + + def create_provider_settings(self, **kwargs) -> tuple[Dict[str, Any]]: + """Create Sourceful provider settings""" + + useTransparency = kwargs.get("useTransparency", False) + transparency = kwargs.get("transparency", False) + useEnhancePrompt = kwargs.get("useEnhancePrompt", False) + enhancePrompt = kwargs.get("enhancePrompt", True) + font_inputs = kwargs.get("fontInputs", None) + + settings: Dict[str, Any] = {} + + if useTransparency: + settings["transparency"] = transparency + if useEnhancePrompt: + settings["enhancePrompt"] = enhancePrompt + if font_inputs is not None and isinstance(font_inputs, list) and len(font_inputs) > 0: + settings["fontInputs"] = font_inputs + + return (settings,) + + +NODE_CLASS_MAPPINGS = { + "RunwareSourcefulProviderSettings": RunwareSourcefulProviderSettings, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "RunwareSourcefulProviderSettings": "Runware Sourceful Provider Settings", +} diff --git a/modules/providerSettings/sourcefulProviderSettingsFonts.py b/modules/providerSettings/sourcefulProviderSettingsFonts.py new file mode 100644 index 0000000..30e0aef --- /dev/null +++ b/modules/providerSettings/sourcefulProviderSettingsFonts.py @@ -0,0 +1,76 @@ +""" +Runware Sourceful Provider Settings Fonts Node +Creates font inputs array for Sourceful provider (up to 2 font references with fontUrl and text). +""" + +from typing import Dict, List + + +class RunwareSourcefulProviderSettingsFonts: + """Runware Sourceful Provider Settings Fonts Node""" + + @classmethod + def INPUT_TYPES(cls): + return { + "required": {}, + "optional": { + "useFont1": ("BOOLEAN", { + "tooltip": "Enable to include first font reference in fontInputs array", + "default": False, + }), + "fontUrl1": ("STRING", { + "tooltip": "URL of the font file (e.g. .woff2). Only used when 'Use Font 1' is enabled.", + "default": "", + }), + "text1": ("STRING", { + "multiline": True, + "tooltip": "Text to render with the first font. Only used when 'Use Font 1' is enabled.", + "default": "", + }), + "useFont2": ("BOOLEAN", { + "tooltip": "Enable to include second font reference in fontInputs array", + "default": False, + }), + "fontUrl2": ("STRING", { + "tooltip": "URL of the font file (e.g. .woff2). Only used when 'Use Font 2' is enabled.", + "default": "", + }), + "text2": ("STRING", { + "multiline": True, + "tooltip": "Text to render with the second font. Only used when 'Use Font 2' is enabled.", + "default": "", + }), + } + } + + RETURN_TYPES = ("RUNWARESOURCEFULFONTINPUTS",) + RETURN_NAMES = ("Font Inputs",) + FUNCTION = "create_font_inputs" + CATEGORY = "Runware/Provider Settings" + DESCRIPTION = "Create font inputs for Sourceful provider. Up to 2 font references, each with font URL and text to render." + + def create_font_inputs(self, **kwargs) -> tuple[List[Dict[str, str]]]: + """Create font inputs array""" + font_inputs: List[Dict[str, str]] = [] + + for i in range(1, 3): + use_font = kwargs.get(f"useFont{i}", False) + if use_font: + font_url = (kwargs.get(f"fontUrl{i}", "") or "").strip() + text = (kwargs.get(f"text{i}", "") or "").strip() + if font_url and text: + font_inputs.append({ + "fontUrl": font_url, + "text": text, + }) + + return (font_inputs,) + + +NODE_CLASS_MAPPINGS = { + "RunwareSourcefulProviderSettingsFonts": RunwareSourcefulProviderSettingsFonts, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "RunwareSourcefulProviderSettingsFonts": "Runware Sourceful Provider Settings Fonts", +} diff --git a/workflows/Runware_Image_Inference_Riverflow2_provider_settings.json b/workflows/Runware_Image_Inference_Riverflow2_provider_settings.json new file mode 100644 index 0000000..d65c9a0 --- /dev/null +++ b/workflows/Runware_Image_Inference_Riverflow2_provider_settings.json @@ -0,0 +1 @@ +{"id":"5337d9ce-299f-4cf0-9e98-e48fd6333885","revision":0,"last_node_id":16,"last_link_id":24,"nodes":[{"id":14,"type":"Runware Save Image","pos":[725.7905883789062,472.79534912109375],"size":[270,294],"flags":{},"order":4,"mode":0,"inputs":[{"localized_name":"Images","name":"Images","type":"STRING","widget":{"name":"Images"},"link":22},{"localized_name":"filenamePrefix","name":"filenamePrefix","type":"STRING","widget":{"name":"filenamePrefix"},"link":null},{"localized_name":"saveImage","name":"saveImage","type":"BOOLEAN","widget":{"name":"saveImage"},"link":null}],"outputs":[],"properties":{"cnr_id":"ComfyUI-Runware","ver":"91646ada844167e36188b535ff60063735d10ca3","Node name for S&R":"Runware Save Image"},"widgets_values":["","ComfyUI",true],"bgcolor":"#5345bf"},{"id":4,"type":"Runware Model Search","pos":[-35.26217269897461,456.5984191894531],"size":[270,154],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"Model Search","name":"Model Search","type":"STRING","widget":{"name":"Model Search"},"link":null},{"localized_name":"Model Architecture","name":"Model Architecture","type":"COMBO","widget":{"name":"Model Architecture"},"link":null},{"localized_name":"ModelType","name":"ModelType","type":"COMBO","widget":{"name":"ModelType"},"link":null},{"localized_name":"ModelList","name":"ModelList","type":"COMBO","widget":{"name":"ModelList"},"link":null},{"localized_name":"Use Search Value","name":"Use Search Value","type":"BOOLEAN","widget":{"name":"Use Search Value"},"link":null}],"outputs":[{"localized_name":"Runware Model","name":"Runware Model","type":"RUNWAREMODEL","links":[17]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"47696ff476df65cc05e1adeb5a5d1d7b994650ae","Node name for S&R":"Runware Model Search"},"widgets_values":["sourceful:riverflow-2.0@pro","All","Base Model","sourceful:riverflow-2.0@pro (Riverflow 2.0 Pro 2.0)",true],"bgcolor":"#5345bf"},{"id":13,"type":"Runware Image Inference","pos":[274.27911376953125,443.8348388671875],"size":[400,1038],"flags":{},"order":3,"mode":0,"inputs":[{"localized_name":"Model","name":"Model","type":"RUNWAREMODEL","link":17},{"localized_name":"Accelerator","name":"Accelerator","shape":7,"type":"RUNWAREACCELERATOR","link":null},{"localized_name":"Lora","name":"Lora","shape":7,"type":"RUNWARELORA","link":null},{"localized_name":"Outpainting","name":"Outpainting","shape":7,"type":"RUNWAREOUTPAINT","link":null},{"localized_name":"IPAdapters","name":"IPAdapters","shape":7,"type":"RUNWAREIPAdapter","link":null},{"localized_name":"ControlNet","name":"ControlNet","shape":7,"type":"RUNWARECONTROLNET","link":null},{"localized_name":"Refiner","name":"Refiner","shape":7,"type":"RUNWAREREFINER","link":null},{"localized_name":"seedImage","name":"seedImage","shape":7,"type":"IMAGE","link":null},{"localized_name":"maskImage","name":"maskImage","shape":7,"type":"MASK","link":null},{"localized_name":"Embeddings","name":"Embeddings","shape":7,"type":"RUNWAREEMBEDDING","link":null},{"localized_name":"VAE","name":"VAE","shape":7,"type":"RUNWAREVAE","link":null},{"localized_name":"referenceImages","name":"referenceImages","shape":7,"type":"RUNWAREREFERENCEIMAGES","link":null},{"localized_name":"inputs","name":"inputs","shape":7,"type":"RUNWAREIMAGEINFERENCEINPUTS","link":null},{"localized_name":"providerSettings","name":"providerSettings","shape":7,"type":"RUNWAREPROVIDERSETTINGS","link":24},{"localized_name":"safetyInputs","name":"safetyInputs","shape":7,"type":"RUNWARESAFETYINPUTS","link":null},{"localized_name":"settings","name":"settings","shape":7,"type":"RUNWARESETTINGS","link":null},{"localized_name":"ultralytics","name":"ultralytics","shape":7,"type":"RUNWAREULTRALYTICSINPUTS","link":null},{"localized_name":"positivePrompt","name":"positivePrompt","type":"STRING","widget":{"name":"positivePrompt"},"link":null},{"localized_name":"negativePrompt","name":"negativePrompt","type":"STRING","widget":{"name":"negativePrompt"},"link":null},{"localized_name":"Multi Inference Mode","name":"Multi Inference Mode","type":"BOOLEAN","widget":{"name":"Multi Inference Mode"},"link":null},{"localized_name":"Prompt Weighting","name":"Prompt Weighting","type":"COMBO","widget":{"name":"Prompt Weighting"},"link":null},{"localized_name":"dimensions","name":"dimensions","type":"COMBO","widget":{"name":"dimensions"},"link":null},{"localized_name":"width","name":"width","type":"INT","widget":{"name":"width"},"link":null},{"localized_name":"height","name":"height","type":"INT","widget":{"name":"height"},"link":null},{"localized_name":"useResolution","name":"useResolution","type":"BOOLEAN","widget":{"name":"useResolution"},"link":null},{"localized_name":"resolution","name":"resolution","type":"COMBO","widget":{"name":"resolution"},"link":null},{"localized_name":"useSteps","name":"useSteps","type":"BOOLEAN","widget":{"name":"useSteps"},"link":null},{"localized_name":"steps","name":"steps","type":"INT","widget":{"name":"steps"},"link":null},{"localized_name":"useScheduler","name":"useScheduler","type":"BOOLEAN","widget":{"name":"useScheduler"},"link":null},{"localized_name":"scheduler","name":"scheduler","type":"COMBO","widget":{"name":"scheduler"},"link":null},{"localized_name":"useCFGScale","name":"useCFGScale","type":"BOOLEAN","widget":{"name":"useCFGScale"},"link":null},{"localized_name":"cfgScale","name":"cfgScale","type":"FLOAT","widget":{"name":"cfgScale"},"link":null},{"localized_name":"useSeed","name":"useSeed","type":"BOOLEAN","widget":{"name":"useSeed"},"link":null},{"localized_name":"seed","name":"seed","type":"INT","widget":{"name":"seed"},"link":null},{"localized_name":"useClipSkip","name":"useClipSkip","type":"BOOLEAN","widget":{"name":"useClipSkip"},"link":null},{"localized_name":"clipSkip","name":"clipSkip","type":"INT","widget":{"name":"clipSkip"},"link":null},{"localized_name":"strength","name":"strength","type":"FLOAT","widget":{"name":"strength"},"link":null},{"localized_name":"Mask Margin","name":"Mask Margin","type":"BOOLEAN","widget":{"name":"Mask Margin"},"link":null},{"localized_name":"maskMargin","name":"maskMargin","type":"INT","widget":{"name":"maskMargin"},"link":null},{"localized_name":"outputFormat","name":"outputFormat","type":"COMBO","widget":{"name":"outputFormat"},"link":null},{"localized_name":"batchSize","name":"batchSize","type":"INT","widget":{"name":"batchSize"},"link":null},{"localized_name":"acceleration","name":"acceleration","type":"COMBO","widget":{"name":"acceleration"},"link":null}],"outputs":[{"localized_name":"IMAGE","name":"IMAGE","type":"STRING","links":[22]},{"localized_name":"RW-Task","name":"RW-Task","type":"RUNWARETASK","links":[]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"bdc86e015971881247addb07bb8f22f7d85c0062","Node name for S&R":"Runware Image Inference"},"widgets_values":["Generate this image: Shot in a bold, high-saturation editorial food advertising style with harsh, direct flash lighting and vibrant color blocking. The image has tactile, punchy realism: textures are pronounced, with crisp shadows and high contrast defining each element. Imperfections are embraced: greasy glisten, salt crystals, crumbs, smeared sauce, and melted cheese stretching mid-motion. Colors are rich and slightly exaggerated. Reds are deep, yellows warm, and the background is a flat pop-art solid (hot red) with no gradients. Composition is tight and dynamic with a slight handheld feel. Subject: A double smashburger wrapped in thin white paper, cut in half and stacked so the cross-section faces the camera: lacy crisp edges on the patties, molten American cheese, glossy pickles, chopped onions, and a smear of mustard. A hand with a simple silver ring grips the top half mid-lift, pulling cheese strands. An orange Crush soda can (12 fl oz) with the distinctive Crush logo and orange slice graphic sits prominently next to the burger, with condensation droplets visible on the can surface. Loose fries spill into frame at the bottom edge, with visible salt and oil sheen. On-image copy (must be perfectly legible, uppercase, centered): \\\"THE LATE-NIGHT STACK\\\". Sub-line (smaller, letter-spaced, below): \\\"HOT. FAST. UNREASONABLE.\\\". Font: Kenia.","",false,"Disabled","Square HD (1024x1024)",1024,1024,false,"1k",false,4,false,"Default",false,6.5,false,215249455,"randomize",true,0,0.8,false,32,"WEBP",1,"none"],"bgcolor":"#5345bf"},{"id":15,"type":"Runware Sourceful Provider Settings","pos":[-85.43180847167969,685.6331176757812],"size":[329.4576110839844,130],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"fontInputs","name":"fontInputs","shape":7,"type":"RUNWARESOURCEFULFONTINPUTS","link":23},{"localized_name":"useTransparency","name":"useTransparency","shape":7,"type":"BOOLEAN","widget":{"name":"useTransparency"},"link":null},{"localized_name":"transparency","name":"transparency","shape":7,"type":"BOOLEAN","widget":{"name":"transparency"},"link":null},{"localized_name":"useEnhancePrompt","name":"useEnhancePrompt","shape":7,"type":"BOOLEAN","widget":{"name":"useEnhancePrompt"},"link":null},{"localized_name":"enhancePrompt","name":"enhancePrompt","shape":7,"type":"BOOLEAN","widget":{"name":"enhancePrompt"},"link":null}],"outputs":[{"localized_name":"providerSettings","name":"providerSettings","type":"RUNWAREPROVIDERSETTINGS","links":[24]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"40adf23c20d07a8cdbd82d67e06b90462af38603","Node name for S&R":"Runware Sourceful Provider Settings"},"widgets_values":[true,false,true,true],"bgcolor":"#5345bf"},{"id":16,"type":"Runware Sourceful Provider Settings Fonts","pos":[-166.60122680664062,878.9181518554688],"size":[400,238],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"useFont1","name":"useFont1","shape":7,"type":"BOOLEAN","widget":{"name":"useFont1"},"link":null},{"localized_name":"fontUrl1","name":"fontUrl1","shape":7,"type":"STRING","widget":{"name":"fontUrl1"},"link":null},{"localized_name":"text1","name":"text1","shape":7,"type":"STRING","widget":{"name":"text1"},"link":null},{"localized_name":"useFont2","name":"useFont2","shape":7,"type":"BOOLEAN","widget":{"name":"useFont2"},"link":null},{"localized_name":"fontUrl2","name":"fontUrl2","shape":7,"type":"STRING","widget":{"name":"fontUrl2"},"link":null},{"localized_name":"text2","name":"text2","shape":7,"type":"STRING","widget":{"name":"text2"},"link":null}],"outputs":[{"localized_name":"Font Inputs","name":"Font Inputs","type":"RUNWARESOURCEFULFONTINPUTS","links":[23]}],"properties":{"cnr_id":"ComfyUI-Runware","ver":"40adf23c20d07a8cdbd82d67e06b90462af38603","Node name for S&R":"Runware Sourceful Provider Settings Fonts"},"widgets_values":[true,"https://cdn.jsdelivr.net/fontsource/fonts/space-mono@latest/latin-400-normal.woff2","HE LATE-NIGHT STACK. HOT. FAST. UNREASONABLE.",false,"",""],"bgcolor":"#5345bf"}],"links":[[17,4,0,13,0,"RUNWAREMODEL"],[22,13,0,14,0,"STRING"],[23,16,0,15,0,"RUNWARESOURCEFULFONTINPUTS"],[24,15,0,13,13,"RUNWAREPROVIDERSETTINGS"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.6210486641221374,"offset":[759.5059021782826,-290.90335802801985]}},"version":0.4} \ No newline at end of file