Files
Runware-ComfyUI-Runware/clientlibs/utils.js
T

6244 lines
292 KiB
JavaScript

import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js";
import { DEFAULT_DIMENSIONS_LIST, DEFAULT_MODELS_ARCH_LIST, DEFAULT_CONTROLNET_CONDITIONING_LIST,
RUNWARE_NODE_TYPES, MODEL_TYPES_TERMS, MODEL_LIST_TERMS
} from "./types.js";
const TIMEOUT_RANGE = { min: 5, default: 90, max: 99 };
const OUTPUT_QUALITY_RANGE = { min: 20, default: 95, max: 99 };
const CACHE_SIZE_RANGE = { min: 30, default: 150, max: 4096 };
/** Must match `audioInferenceInputs.MAX_VIDEOS` in modules/audioInferenceInputs.py */
const AUDIO_INFERENCE_INPUTS_MAX_VIDEOS = 4;
/** Must match `audioInferenceInputs.MAX_AUDIOS` in modules/audioInferenceInputs.py */
const AUDIO_INFERENCE_INPUTS_MAX_AUDIOS = 4;
let openDialog = false;
let lastTimeout = false;
let lastOutputFormat = false;
let lastOutputQuality = false;
let lastEnableImagesCaching = null;
let lastMinImageCacheSize = false;
async function queryLocalAPI(endpoint, data) {
try {
const resp = await api.fetchApi(`/${endpoint}`, {
method: "POST",
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
});
return await resp.json();
} catch (err) {
return false;
}
}
const runwareLocalAPI = {
enhancePrompt: (userPrompt) => queryLocalAPI('promptEnhance', { userPrompt }),
setAPIKey: (apiKey) => queryLocalAPI('setAPIKey', { apiKey }),
setTimeout: (maxTimeout) => queryLocalAPI('setMaxTimeout', { maxTimeout }),
setOutputFormat: (outputFormat) => queryLocalAPI('setOutputFormat', { outputFormat }),
setOutputQuality: (outputQuality) => queryLocalAPI('setOutputQuality', { outputQuality }),
setEnableImagesCaching: (enableCaching) => queryLocalAPI('setEnableImagesCaching', { enableCaching }),
setMinImageCacheSize: (minCacheSize) => queryLocalAPI('setMinImageCacheSize', { minCacheSize }),
modelSearch: (modelQuery = "", modelArch = "all", modelType = "base", modelCat = "checkpoint", condtioning = "") =>
queryLocalAPI('modelSearch', { modelQuery, modelArch, modelType, modelCat, condtioning })
};
function mediaUUIDHandler(msgEvent) {
const mediaData = msgEvent.detail;
const mediaUUID = mediaData.mediaUUID;
const mediaNodeID = parseInt(mediaData.nodeID);
if(mediaData.success) {
const mediaNode = app.graph.getNodeById(mediaNodeID);
if(mediaNode !== null && mediaNode !== undefined) {
// Find the mediaUUID widget specifically
const mediaUUIDWidget = mediaNode.widgets.find(widget => widget.name === "mediaUUID");
if(mediaUUIDWidget) {
// Update both widget.value and inputEl.value for STRING widgets
if(mediaUUIDWidget.value !== undefined) {
mediaUUIDWidget.value = mediaUUID;
}
if(mediaUUIDWidget.inputEl) {
mediaUUIDWidget.inputEl.value = mediaUUID;
// Trigger change events to update the UI
mediaUUIDWidget.inputEl.dispatchEvent(new Event('input', { bubbles: true }));
mediaUUIDWidget.inputEl.dispatchEvent(new Event('change', { bubbles: true }));
}
}
}
}
return false;
}
function save3DFilepathHandler(msgEvent) {
const data = msgEvent.detail;
const filepath = data.filepath;
const nodeID = parseInt(data.nodeID, 10);
if (Number.isNaN(nodeID)) return false;
if(data.success && filepath) {
const node = app.graph.getNodeById(nodeID);
if(node !== null && node !== undefined) {
const filepathWidget = node.widgets.find(widget => widget.name === "filepath");
if(filepathWidget) {
if(filepathWidget.value !== undefined) {
filepathWidget.value = filepath;
}
if(filepathWidget.inputEl) {
filepathWidget.inputEl.value = filepath;
filepathWidget.inputEl.dispatchEvent(new Event('input', { bubbles: true }));
filepathWidget.inputEl.dispatchEvent(new Event('change', { bubbles: true }));
}
}
}
}
return false;
}
function captionNodeHandler(msgEvent) {
const captionData = msgEvent.detail;
const captionText = captionData.captionText;
const captionNodeID = parseInt(captionData.nodeID);
if(captionData.success) {
const captionNode = app.graph.getNodeById(captionNodeID);
if(captionNode !== null && captionNode !== undefined) {
// Find the imageCaption widget specifically
const imageCaptionWidget = captionNode.widgets.find(widget => widget.name === "imageCaption");
if(imageCaptionWidget && imageCaptionWidget.inputEl) {
imageCaptionWidget.inputEl.value = captionText;
}
}
}
return false;
}
function saveTextHandler(msgEvent) {
const data = msgEvent.detail;
const displayText = data.text;
const nodeID = parseInt(data.nodeID, 10);
if (!data.success || Number.isNaN(nodeID)) return false;
const node = app.graph.getNodeById(nodeID);
if (node === null || node === undefined) return false;
const widgetName = data.widgetName || "text";
const textWidget = node.widgets.find((w) => w.name === widgetName);
if (textWidget) {
if (textWidget.value !== undefined) {
textWidget.value = displayText;
}
if (textWidget.inputEl) {
textWidget.inputEl.value = displayText;
textWidget.inputEl.dispatchEvent(new Event("input", { bubbles: true }));
textWidget.inputEl.dispatchEvent(new Event("change", { bubbles: true }));
}
}
return false;
}
function videoTranscriptionHandler(msgEvent) {
const transcriptionData = msgEvent.detail;
const transcriptionText = transcriptionData.transcriptionText;
const transcriptionNodeID = parseInt(transcriptionData.nodeID);
if(transcriptionData.success) {
const transcriptionNode = app.graph.getNodeById(transcriptionNodeID);
if(transcriptionNode !== null && transcriptionNode !== undefined) {
// Find the prompt widget (where transcription is displayed)
const promptWidget = transcriptionNode.widgets.find(widget => widget.name === "prompt");
if(promptWidget && promptWidget.inputEl) {
promptWidget.inputEl.value = transcriptionText;
}
}
}
return false;
}
function videoOutputsHandler(msgEvent) {
const outputData = msgEvent.detail;
const draftId = outputData.draftId || "";
const videoId = outputData.videoId || "";
const nodeID = outputData.nodeID;
if(outputData.success && nodeID !== undefined && nodeID !== null) {
const nodeIdInt = typeof nodeID === 'string' ? parseInt(nodeID) : nodeID;
const outputNode = app.graph.getNodeById(nodeIdInt);
if(outputNode !== null && outputNode !== undefined) {
const draftIdWidget = outputNode.widgets.find(widget => widget.name === "draftId");
const videoIdWidget = outputNode.widgets.find(widget => widget.name === "videoId");
if(draftIdWidget) {
if(draftIdWidget.value !== undefined) draftIdWidget.value = draftId;
if(draftIdWidget.inputEl) {
draftIdWidget.inputEl.value = draftId;
draftIdWidget.inputEl.dispatchEvent(new Event('input', { bubbles: true }));
draftIdWidget.inputEl.dispatchEvent(new Event('change', { bubbles: true }));
}
}
if(videoIdWidget) {
if(videoIdWidget.value !== undefined) videoIdWidget.value = videoId;
if(videoIdWidget.inputEl) {
videoIdWidget.inputEl.value = videoId;
videoIdWidget.inputEl.dispatchEvent(new Event('input', { bubbles: true }));
videoIdWidget.inputEl.dispatchEvent(new Event('change', { bubbles: true }));
}
}
outputNode.setDirtyCanvas(true);
}
}
return false;
}
function notifyUser(message, type="info", title = "Runware", life = 4.5) {
app.extensionManager.toast.add({
severity: type, // 'info', 'success', 'warn', 'error' \\
summary: title,
detail: message,
life: Math.floor(life * 1000)
});
}
async function promptEnhanceHandler(e) {
if(e.ctrlKey && e.altKey && e.key.toLowerCase() === 'e') {
const userPrompt = e.target.value.trim();
if(userPrompt.length <= 1) {
notifyUser("Prompt Is Too Short!", "error", "Runware Prompt Enhancer");
return;
} else if(userPrompt.length > 300) {
notifyUser("Prompt Must Not Exceed 300 Characters!", "error", "Runware Prompt Enhancer");
return;
}
const enhanceResults = await runwareLocalAPI.enhancePrompt(userPrompt);
if(enhanceResults.success) {
e.target.value = enhanceResults.enhancedPrompt;
} else {
notifyUser(enhanceResults.error, "error", "Runware Prompt Enhancer");
}
}
}
function remNode(node) {
app.graph.remove(node);
app.graph.setDirtyCanvas(true,true);
}
async function APIKeyHandler(apiManagerNode) {
const widgets = apiManagerNode.widgets;
for(const widget of widgets) {
if(widget.name === "API Key") {
appendWidgetCB(widget, async function(...args) {
if(openDialog) return;
const apiKey = args[0].trim();
if(apiKey.length < 30) {
notifyUser("Invalid API Key Set, Please Try Again!", "error", "Runware API Manager");
return;
}
const setAPIKeyResults = await runwareLocalAPI.setAPIKey(apiKey);
if(setAPIKeyResults.success) {
remNode(apiManagerNode);
notifyUser("API Key Set Successfully!", "success", "Runware API Manager");
} else {
notifyUser(setAPIKeyResults.error, "error", "Runware API Manager");
}
});
} else if(widget.name === "Max Timeout") {
if(lastTimeout) widget.value = lastTimeout;
appendWidgetCB(widget, async function(...args) {
const maxTimeout = parseInt(args[0]);
if(isNaN(maxTimeout) || maxTimeout < TIMEOUT_RANGE.min || maxTimeout > TIMEOUT_RANGE.max) {
notifyUser(`Invalid Timeout Value! Must be between ${TIMEOUT_RANGE.min} and ${TIMEOUT_RANGE.max} seconds.`, "error", "Runware API Manager");
widget.value = lastTimeout || TIMEOUT_RANGE.default;
return;
}
const setTimeoutResults = await runwareLocalAPI.setTimeout(maxTimeout);
if(setTimeoutResults.success) {
notifyUser("Timeout Set Successfully!", "success", "Runware API Manager");
lastTimeout = maxTimeout;
} else {
widget.value = lastTimeout || TIMEOUT_RANGE.default;
notifyUser(setTimeoutResults.error, "error", "Runware API Manager");
}
});
} else if(widget.name === "Image Output Format") {
if(lastOutputFormat) widget.value = lastOutputFormat;
appendWidgetCB(widget, async function(...args) {
const outputFormat = args[0].trim().toUpperCase();
const setFormatResults = await runwareLocalAPI.setOutputFormat(outputFormat);
if(setFormatResults.success) {
notifyUser("Default Image Output Format Set Successfully!", "success", "Runware API Manager");
lastOutputFormat = outputFormat;
} else {
notifyUser(setFormatResults.error, "error", "Runware API Manager");
}
});
} else if(widget.name === "Image Output Quality") {
if(lastOutputQuality) widget.value = lastOutputQuality;
appendWidgetCB(widget, async function(...args) {
const outputQuality = parseInt(args[0]);
if(isNaN(outputQuality) || outputQuality < OUTPUT_QUALITY_RANGE.min || outputQuality > OUTPUT_QUALITY_RANGE.max) {
notifyUser(`Invalid Quality Value! Must be between ${OUTPUT_QUALITY_RANGE.min} and ${OUTPUT_QUALITY_RANGE.max}.`, "error", "Runware API Manager");
widget.value = lastOutputQuality || OUTPUT_QUALITY_RANGE.default;
return;
}
const setQualityResults = await runwareLocalAPI.setOutputQuality(outputQuality);
if(setQualityResults.success) {
notifyUser("Default Image Output Quality Set Successfully!", "success", "Runware API Manager");
lastOutputQuality = outputQuality;
} else {
widget.value = lastOutputQuality || OUTPUT_QUALITY_RANGE.default;
notifyUser(setQualityResults.error, "error", "Runware API Manager");
}
});
} else if(widget.name === "Enable Images Caching") {
if(lastEnableImagesCaching !== null) widget.value = lastEnableImagesCaching;
appendWidgetCB(widget, async function(...args) {
const enableCaching = args[0];
const setCachingResults = await runwareLocalAPI.setEnableImagesCaching(enableCaching);
if(setCachingResults.success) {
notifyUser("Image Caching Setting Updated Successfully!", "success", "Runware API Manager");
lastEnableImagesCaching = enableCaching;
} else {
widget.value = lastEnableImagesCaching;
notifyUser(setCachingResults.error, "error", "Runware API Manager");
}
});
} else if(widget.name === "Min Image Cache Size") {
if(lastMinImageCacheSize !== false) widget.value = lastMinImageCacheSize;
appendWidgetCB(widget, async function(...args) {
const minCacheSize = parseFloat(args[0]);
if(isNaN(minCacheSize) || minCacheSize < CACHE_SIZE_RANGE.min || minCacheSize > CACHE_SIZE_RANGE.max) {
notifyUser(`Invalid cache size! Must be between ${CACHE_SIZE_RANGE.min} KB and ${CACHE_SIZE_RANGE.max} KB.`, "error", "Runware API Manager");
widget.value = lastMinImageCacheSize || CACHE_SIZE_RANGE.default;
return;
}
const setCacheSizeResults = await runwareLocalAPI.setMinImageCacheSize(minCacheSize);
if(setCacheSizeResults.success) {
notifyUser("Minimum Image Cache Size Updated Successfully!", "success", "Runware API Manager");
lastMinImageCacheSize = minCacheSize;
} else {
widget.value = lastMinImageCacheSize || CACHE_SIZE_RANGE.default;
notifyUser(setCacheSizeResults.error, "error", "Runware API Manager");
}
});
}
}
}
function addTriggerWords(prompt, triggerWords) {
if (!triggerWords?.trim()) return prompt;
const cleanedTriggerWords = triggerWords
.trim()
.replace(/,\s*$/, '')
.split(',')
.map(word => word.trim())
.filter(word => word.length);
if (!prompt?.trim()) return cleanedTriggerWords.join(', ');
const wordsToAdd = cleanedTriggerWords.filter(word =>
!new RegExp(`\\b${word}\\b`, 'i').test(prompt)
);
return wordsToAdd.length
? `${prompt}${prompt.endsWith(',') ? ' ' : ', '}${wordsToAdd.join(', ')}`
: prompt;
}
function handleCustomErrors(errObj) {
const errData = errObj.detail;
const errCode = errData.errorCode;
if(errCode === 401 && !openDialog) {
const dialog = new comfyAPI.asyncDialog.ComfyAsyncDialog();
const htmlContent = `
<center>
<div style="padding: auto 200px; text-align: center;">
<h2>Runware Inference Error</h2>
<h4>Your API Key is Invalid Or Undefined. You Need To Update It.</h4>
<form method="POST" id="runwareAPIKey">
<input
id="apiKey"
type="text"
placeholder="Enter Your API Key ..." minlength="30" maxlength="48"
style="padding: 5px; min-width: 300px; text-align: center; margin-top: 10px;" required>
<div style="margin-top: 15px; display: flex; justify-content: center; gap: 10px;">
<button id="setAPIKeyBTN" style="padding: 8px 15px; background-color: #6c5ce7; color: #ccc;">Set Your API Key</button>
<button id="getAPIKeyBTN" style="padding: 8px 15px; background-color: #dfe6e9; color: #000;">Create New API Key</button>
</div>
</form>
</div>
</center>
`;
dialog.showModal(htmlContent).then(() => {
openDialog = false;
});
openDialog = true;
dialog.element.addEventListener('close', () => {
openDialog = false;
});
const runwareAPIForm = document.getElementById("runwareAPIKey");
const apiKeyInput = document.getElementById("apiKey");
const getAPIKeyBTN = document.getElementById("getAPIKeyBTN");
const setAPIKeyBTN = document.getElementById("setAPIKeyBTN");
getAPIKeyBTN.onclick = (e) => {
e.preventDefault();
window.open("https://my.runware.ai/keys?utm_source=comfyui&utm_medium=referral&utm_campaign=comfyui_api_key_creation", "_blank");
};
async function authUser(e) {
e.preventDefault();
e.stopPropagation();
const apiKey = apiKeyInput.value.trim();
if(apiKey.length < 30) {
runwareAPIForm.reportValidity();
return;
// notifyUser("Invalid API Key Set, Please Try Again!", "error", "Runware API Manager");
// return;
} else {
const setAPIKeyResults = await runwareLocalAPI.setAPIKey(apiKey);
if(setAPIKeyResults.success) {
dialog.close();
openDialog = false;
notifyUser("API Key Set Successfully!", "success", "Runware API Manager");
} else {
notifyUser(setAPIKeyResults.error, "error", "Runware API Manager");
}
}
};
setAPIKeyBTN.onclick = async (e) => {
authUser(e);
};
runwareAPIForm.onsubmit = async (e) => {
authUser(e);
};
}
}
function appendWidgetCB(node, newCB) {
const oldNodeCB = node.callback;
if(typeof oldNodeCB === "function") {
node.callback = function(...args) {
oldNodeCB?.apply(this, args);
newCB?.apply(this, args);
}
} else {
node.callback = newCB;
}
}
async function syncDimensionsNodeHandler(node, dimensionsWidget) {
const nodeWidgets = node.widgets;
let widthWidget = false, heightWidget = false;
for(const nodeWidget of nodeWidgets) {
const widgetName = nodeWidget.name;
const widgetType = nodeWidget.type;
if(widgetName === "width" && widgetType === "number") widthWidget = nodeWidget;
if(widgetName === "height" && widgetType === "number") heightWidget = nodeWidget;
}
appendWidgetCB(dimensionsWidget, function(...args) {
const chosenDimension = args[0];
if(chosenDimension === "Custom" || chosenDimension === "None") return;
const dimensionValue = DEFAULT_DIMENSIONS_LIST[chosenDimension];
if(!dimensionValue) return;
const [width, height] = dimensionValue.split("x");
widthWidget.callback(width, "customSetOperation");
heightWidget.callback(height, "customSetOperation");
});
if(widthWidget !== false) {
appendWidgetCB(widthWidget, function(...args) {
if(args[1] === "customSetOperation") return;
dimensionsWidget.value = "Custom";
});
}
if(heightWidget !== false) {
appendWidgetCB(heightWidget, function(...args) {
if(args[1] === "customSetOperation") return;
dimensionsWidget.value = "Custom";
});
}
}
const shortenAirCode = input => !input || !input.startsWith('urn:air:') ? input : input.match(/urn:air:.*?:.*?(civitai:\d+@\d+)$/)?.[1] || input;
async function searchNodeHandler(searchNode, searchInputWidget) {
const searchNodeWidgets = searchNode.widgets;
let modelArchWidget = false, modelTypeWidget = false, modelListWidget = false,
defaultWidgetValues = {}, triggerWordsList = {
"civitai:58390@62833": "", "civitai:82098@87153": "", "civitai:122359@135867": "",
"civitai:14171@16677": "mix4", "civitai:13941@16576": "", "civitai:25995@32988": "full body, chibi"
}, embeddingTriggerWordsList = {
"civitai:7808@9208": "easynegative", "civitai:4629@5637": "ng_deepnegative_v1_75t",
"civitai:56519@60938": "negative_hand", "civitai:72437@77169": "BadDream",
"civitai:11772@25820": "verybadimagenegative_v1.3", "civitai:71961@94057": "FastNegativeV2",
};
let isLora = false, isControlNet = false, isEmbedding = false, isVAE = false, modelTypeValue = false;
if(searchNode.comfyClass === RUNWARE_NODE_TYPES.LORASEARCH) isLora = true;
if(searchNode.comfyClass === RUNWARE_NODE_TYPES.CONTROLNET) isControlNet = true;
if(searchNode.comfyClass === RUNWARE_NODE_TYPES.EMBEDDING) isEmbedding = true;
if(searchNode.comfyClass === RUNWARE_NODE_TYPES.VAE) isVAE = true;
for(const searchWidget of searchNodeWidgets) {
const widgetName = searchWidget.name;
const widgetType = searchWidget.type;
if(widgetName === "Model Architecture" && widgetType === "combo") {
modelArchWidget = searchWidget;
defaultWidgetValues["modelArch"] = searchWidget.options.values;
}
if(MODEL_TYPES_TERMS.includes(widgetName) && widgetType === "combo") {
modelTypeWidget = searchWidget;
defaultWidgetValues["modelType"] = searchWidget.options.values;
}
if(MODEL_LIST_TERMS.includes(widgetName) && widgetType === "combo") {
modelListWidget = searchWidget;
defaultWidgetValues["modelList"] = searchWidget.options.values;
}
}
function resetValues() {
if(modelArchWidget) {
modelArchWidget.options.values = defaultWidgetValues["modelArch"];
modelArchWidget.value = defaultWidgetValues["modelArch"][0];
}
if(modelTypeWidget) {
modelTypeWidget.options.values = defaultWidgetValues["modelType"];
modelTypeWidget.value = defaultWidgetValues["modelType"][0];
}
if(modelListWidget) {
modelListWidget.options.values = defaultWidgetValues["modelList"];
modelListWidget.value = defaultWidgetValues["modelList"][0];
}
}
async function searchModels(exactQuery = null, returnOutput = false) {
let searchQuery;
if(exactQuery) {
searchQuery = exactQuery;
} else {
searchQuery = searchInputWidget.value.trim();
}
searchQuery = shortenAirCode(searchQuery);
const modelArchValue = DEFAULT_MODELS_ARCH_LIST[modelArchWidget.value];
if(isControlNet) {
modelTypeValue = DEFAULT_CONTROLNET_CONDITIONING_LIST[modelTypeWidget.value];
} else {
if(isEmbedding) {
modelTypeValue = "embeddings";
} else if(isVAE) {
modelTypeValue = "vae";
} else {
modelTypeValue = modelTypeWidget.value.toLowerCase().replace("model", "").trim();
}
}
let modelSearchResults = null;
if(isControlNet) {
modelSearchResults = await runwareLocalAPI.modelSearch(searchQuery, modelArchValue, "", "controlnet", modelTypeValue);
} else if(isLora || isEmbedding || isVAE) {
modelSearchResults = await runwareLocalAPI.modelSearch(searchQuery, modelArchValue, "", modelTypeValue);
} else {
modelSearchResults = await runwareLocalAPI.modelSearch(searchQuery, modelArchValue, modelTypeValue);
}
if(modelSearchResults.success) {
const modelListArray = [];
modelSearchResults.modelList.forEach(modelObj => {
if(isLora) triggerWordsList[modelObj.air] = modelObj.positiveTriggerWords?.trim() || false;
if(isEmbedding) embeddingTriggerWordsList[modelObj.air] = modelObj.positiveTriggerWords?.trim() || false;
modelListArray.push(`${modelObj.air} (${modelObj.name} ${modelObj.version})`);
});
if(exactQuery) {
const extraSearch = await searchModels(null, true);
if(extraSearch) {
const newModelList = [...new Set([...modelListArray, ...extraSearch])];
modelListWidget.options.values = newModelList;
return;
}
}
if(returnOutput) return modelListArray;
modelListWidget.options.values = modelListArray;
modelListWidget.value = modelListArray[0];
} else {
if(returnOutput) return false;
if(exactQuery) {
notifyUser("Failed To Load Workflow's Model List Value!", "error", "Runware Search");
return;
}
notifyUser(modelSearchResults.error, "error", "Runware Search");
}
}
function findTargetWidget(currentNode, targetWidgetName, depth = 1) {
try {
if(depth < 0) return false;
const nodeOutputs = currentNode.outputs;
if(nodeOutputs.length === 0) return false;
const outputLinks = nodeOutputs[0].links;
if(outputLinks.length === 0) return false;
for(const linkID of outputLinks) {
const linkInfo = app.graph.links[linkID];
const linkNodeID = linkInfo.target_id;
if(!linkNodeID) continue;
const targetNode = app.graph.getNodeById(linkNodeID);
let widgetFound = false;
if(targetNode.widgets !== undefined && targetNode.widgets.length > 0){
widgetFound = targetNode.widgets.find(widget => widget.name === targetWidgetName) || false;
}
if(widgetFound) {
return widgetFound;
} else {
return findTargetWidget(targetNode, targetWidgetName, depth - 1);
}
}
} catch(e) {
return false;
}
return false;
}
if(isLora) {
const runwareButton = document.createElement("button");
runwareButton.textContent = "Add Lora To Prompt";
runwareButton.style = "max-height: 50px; background-color: #333; color: #ccc;";
searchNode.addDOMWidget("addLora", "custom", runwareButton, {
selectOn: ['focus', 'click'],
});
runwareButton.addEventListener("click", async () => {
const chosenLora = modelListWidget.value.split(" ")[0];
if(!triggerWordsList.hasOwnProperty(chosenLora)) return;
const triggerWords = triggerWordsList[chosenLora];
if(triggerWords.length > 0) {
const positivePromptWidget = findTargetWidget(searchNode, "positivePrompt");
if(!positivePromptWidget) {
notifyUser("Lora Node Is Not Linked To Any Runware Inference Node!", "error", "Runware Lora Connector");
return;
}
const positivePromptWithTrigger = addTriggerWords(positivePromptWidget.value, triggerWords);
if(positivePromptWidget.value === positivePromptWithTrigger) {
notifyUser("Trigger Words Already Exists", "info", "Runware Lora Connector");
return;
}
positivePromptWidget.value = positivePromptWithTrigger;
notifyUser("Trigger Words Added Successfully!", "success", "Runware Lora Connector");
} else {
notifyUser("No Trigger Words Found For This Lora!", "warn", "Runware Lora Connector");
}
});
} else if(isEmbedding) {
const runwareButton = document.createElement("button");
runwareButton.textContent = "Add Embedding To Negative Prompt";
runwareButton.style = "max-height: 50px; background-color: #333; color: #ccc;";
searchNode.addDOMWidget("addEmbedding", "custom", runwareButton, {
selectOn: ['focus', 'click'],
});
runwareButton.addEventListener("click", async () => {
const chosenEmbedding = modelListWidget.value.split(" ")[0];
if (!embeddingTriggerWordsList.hasOwnProperty(chosenEmbedding)) return;
const triggerWords = embeddingTriggerWordsList[chosenEmbedding];
if(triggerWords.length > 0) {
const negativePromptWidget = findTargetWidget(searchNode, "negativePrompt");
if(!negativePromptWidget) {
notifyUser("Embedding Node Is Not Linked To Any Runware Inference Node!", "error", "Runware Embedding Connector");
return;
}
const negativePromptWithTrigger = addTriggerWords(negativePromptWidget.value, triggerWords);
if(negativePromptWidget.value === negativePromptWithTrigger) {
notifyUser("Trigger Words Already Exists", "info", "Runware Embedding Connector");
return;
}
negativePromptWidget.value = negativePromptWithTrigger;
notifyUser("Trigger Words Added Successfully!", "success", "Runware Embedding Connector");
} else {
notifyUser("No Trigger Words Found For This Embedding!", "warn", "Runware Embedding Connector");
}
});
}
appendWidgetCB(searchInputWidget, async function(...args) {
let searchQuery = args[0].trim();
const shortenSearchQuery = shortenAirCode(searchQuery);
if(searchQuery !== shortenSearchQuery) {
searchQuery = shortenSearchQuery;
searchInputWidget.value = searchQuery;
}
if(searchQuery.length === 0) {
resetValues();
} else if(searchQuery.length < 2) {
notifyUser("Invalid Search Value, Search Query must be at least 2 characters!", "error", "Runware Search");
return;
} else {
await searchModels();
}
});
appendWidgetCB(modelArchWidget, async function(...args) {
await searchModels();
});
if(!isVAE && !isEmbedding) {
appendWidgetCB(modelTypeWidget, async function(...args) {
await searchModels();
});
}
appendWidgetCB(searchNode, async function(...args) {
try {
let modelListValues = modelListWidget.options.values;
if(modelListValues.length <= 0) return;
modelListValues = modelListValues.map(model => model.split(" ")[0]);
const modelListCRValue = modelListWidget.value.split(" ")[0];
if(!modelListValues.includes(modelListCRValue)) {
searchModels(modelListCRValue);
}
} catch(e) {}
});
}
function toggleWidgetEnabled(widget, enabled, node) {
if (!widget || !widget.name) return;
// Use the same simple approach as videoInferenceDimensionsHandler
// Set widget disabled property
widget.disabled = !enabled;
// Disable/enable widgets using inputEl if available (same pattern as videoInferenceDimensionsHandler)
if (widget.inputEl) {
widget.inputEl.disabled = !enabled;
widget.inputEl.style.opacity = enabled ? "1" : "0.5";
widget.inputEl.style.cursor = enabled ? "text" : "not-allowed";
widget.inputEl.readOnly = !enabled;
}
// For combo/dropdown widgets, also try to disable the options element
if (widget.options && widget.options.element) {
widget.options.element.disabled = !enabled;
widget.options.element.style.opacity = enabled ? "1" : "0.5";
widget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
// Fallback: try to find inputs via DOM if inputEl is not available (same as videoInferenceDimensionsHandler)
if (!widget.inputEl && node) {
const nodeElement = node.htmlElements?.widgetsContainer || node.htmlElements;
if (nodeElement) {
const input = nodeElement.querySelector(`input[name="${widget.name}"], textarea[name="${widget.name}"], select[name="${widget.name}"]`);
if (input) {
input.disabled = !enabled;
input.style.opacity = enabled ? "1" : "0.5";
input.style.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
}
function videoUpscalerToggleHandler(videoUpscalerNode) {
if (!videoUpscalerNode?.widgets) return;
const useUpscaleFactorWidget = videoUpscalerNode.widgets.find(w => w && w.name === "useUpscaleFactor");
const upscaleFactorWidget = videoUpscalerNode.widgets.find(w => w && w.name === "upscaleFactor");
const useFpsWidget = videoUpscalerNode.widgets.find(w => w && w.name === "useFps");
const fpsWidget = videoUpscalerNode.widgets.find(w => w && w.name === "fps");
const useDimensionWidget = videoUpscalerNode.widgets.find(w => w && w.name === "useDimension");
const widthWidget = videoUpscalerNode.widgets.find(w => w && w.name === "width");
const heightWidget = videoUpscalerNode.widgets.find(w => w && w.name === "height");
function applyToggleState() {
if (useUpscaleFactorWidget && upscaleFactorWidget) {
const enabled = useUpscaleFactorWidget.value === true;
toggleWidgetEnabled(upscaleFactorWidget, enabled, videoUpscalerNode);
}
if (useFpsWidget && fpsWidget) {
const enabled = useFpsWidget.value === true;
toggleWidgetEnabled(fpsWidget, enabled, videoUpscalerNode);
}
if (useDimensionWidget && widthWidget && heightWidget) {
const enabled = useDimensionWidget.value === "custom";
toggleWidgetEnabled(widthWidget, enabled, videoUpscalerNode);
toggleWidgetEnabled(heightWidget, enabled, videoUpscalerNode);
}
videoUpscalerNode.setDirtyCanvas(true);
}
// Initialize state once widgets are rendered
setTimeout(applyToggleState, 100);
if (useUpscaleFactorWidget) {
appendWidgetCB(useUpscaleFactorWidget, () => {
setTimeout(applyToggleState, 50);
});
}
if (useFpsWidget) {
appendWidgetCB(useFpsWidget, () => {
setTimeout(applyToggleState, 50);
});
}
if (useDimensionWidget) {
appendWidgetCB(useDimensionWidget, () => {
setTimeout(applyToggleState, 50);
});
}
}
function useParameterToggleHandler(node) {
// Prevent double registration
if (node._useParameterToggleHandlerRegistered) return;
node._useParameterToggleHandlerRegistered = true;
// Define explicit mappings: "useParameterName" -> ["parameter1", "parameter2", ...]
const parameterMappings = {
// Image Inference
"useSteps": ["steps"],
"useSeed": ["seed"],
"useCFGScale": ["cfgScale"], // Image inference uses lowercase cfgScale
"useScheduler": ["scheduler"],
"useClipSkip": ["clipSkip"],
"useUpscaleFactor": ["upscaleFactor"],
// Video Inference
"useCustomDimensions": ["width", "height"], // Note: Also handled separately in videoInferenceDimensionsHandler
"useDuration": ["duration"],
"useFps": ["fps"],
"useSchedulers": ["scheduler"],
"useCFGScale": ["cfgScale"],
"useTtl": ["ttl"],
// useSteps and useSeed are same as image inference, handled by fallback
// Upscaler specific mappings (override for nodes that have CFGScale with capital C)
"usePrompts": ["positivePrompt", "negativePrompt"],
"useClarityParams": ["controlNetWeight", "strength", "scheduler"],
"useCCSRParams": ["colorFix", "tileDiffusion"],
"useLatentParams": ["clipSkip"],
// Audio Inference
"usePositivePrompt": ["positivePrompt"],
"useSeed": ["seed"],
"useSteps": ["steps"],
"useStrength": ["strength"],
// Accelerator Options
"useCacheDistance": ["cacheDistance"],
"useTeaCacheDistance": ["teaCacheDistance"],
"useDeepCacheOptions": ["deepCacheInterval", "deepCacheBranchId"],
"useCacheSteps": ["cacheStartStep", "cacheEndStep"],
"useCachePercentageSteps": ["cacheStartStepPercentage", "cacheEndStepPercentage"],
"useCacheMaxConsecutiveSteps": ["cacheMaxConsecutiveSteps"],
// Bytedance Provider Settings
"useCameraFixed": ["cameraFixed"],
"useMaxSequentialImages": ["maxSequentialImages"],
"useFastMode": ["fastMode"],
// OpenAI Provider Settings (these are dropdowns, not booleans, but handle them anyway)
"useBackground": ["background"],
"useStyle": ["style"],
// Mask Margin
"Mask Margin": ["maskMargin"],
};
// Node-specific overrides for parameters that have different names in different nodes
// Format: nodeClass -> { "useParam": ["param1", "param2"] }
const nodeSpecificMappings = {
// Upscaler uses CFGScale (capital C) instead of cfgScale
[RUNWARE_NODE_TYPES.UPSCALER]: {
"useCFGScale": ["CFGScale"],
},
// Audio Inference uses CFGScale (capital C)
[RUNWARE_NODE_TYPES.AUDIOINFERENCE]: {
"useCFGScale": ["CFGScale"],
},
};
// Wait for widgets to be ready
function initializeHandler() {
if (!node.widgets || node.widgets.length === 0) {
setTimeout(initializeHandler, 100);
return;
}
// Find all "use" widgets and their corresponding parameter widgets upfront (like videoInferenceDimensionsHandler does)
const togglePairs = [];
// Find all "use" widgets
node.widgets.forEach(widget => {
if (!widget || !widget.name) return;
const isUseWidget = widget.name.startsWith("use") && (widget.type === "BOOLEAN" || widget.type === "COMBO");
const isMaskMargin = widget.name === "Mask Margin" && widget.type === "BOOLEAN";
if (!isUseWidget && !isMaskMargin) return;
const useParamName = widget.name;
// Get corresponding parameters - check node-specific mappings first, then general mappings
let paramNames = [];
const nodeClass = node.comfyClass;
if (nodeClass && nodeSpecificMappings[nodeClass] && nodeSpecificMappings[nodeClass][useParamName]) {
paramNames = nodeSpecificMappings[nodeClass][useParamName];
} else {
paramNames = parameterMappings[useParamName] || [];
}
// Handle special case: remove "use" prefix and lowercase first letter
if (paramNames.length === 0) {
const paramName = useParamName.replace(/^use/, "").replace(/^[A-Z]/, (match) => match.toLowerCase());
paramNames = [paramName];
}
// Find the actual parameter widgets
const paramWidgets = [];
paramNames.forEach(paramName => {
const paramWidget = node.widgets.find(w => w && w.name === paramName);
if (paramWidget) {
paramWidgets.push(paramWidget);
} else {
// If mapped parameter doesn't exist, try fallback auto-detection
const fallbackParamName = useParamName.replace(/^use/, "").replace(/^[A-Z]/, (match) => match.toLowerCase());
if (fallbackParamName !== paramName) {
const fallbackWidget = node.widgets.find(w => w && w.name === fallbackParamName);
if (fallbackWidget) {
paramWidgets.push(fallbackWidget);
}
}
}
});
if (paramWidgets.length > 0) {
togglePairs.push({
useWidget: widget,
paramWidgets: paramWidgets
});
}
});
// Create toggle functions for each pair (like toggleDimensionsEnabled in videoInferenceDimensionsHandler)
togglePairs.forEach(pair => {
const { useWidget, paramWidgets } = pair;
function toggleEnabled() {
// Determine if enabled based on widget type
let enabled = false;
if (useWidget.type === "BOOLEAN") {
enabled = useWidget.value === true;
} else if (useWidget.type === "COMBO") {
enabled = useWidget.value === "enable" || useWidget.value === "Enable";
}
// Apply to each parameter widget (exactly like toggleDimensionsEnabled does)
paramWidgets.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;
// Fallback: try to find inputs via DOM if inputEl is not available
if (!paramWidget.inputEl) {
const nodeElement = node.htmlElements?.widgetsContainer || node.htmlElements;
if (nodeElement) {
const input = nodeElement.querySelector(`input[name="${paramWidget.name}"], textarea[name="${paramWidget.name}"], select[name="${paramWidget.name}"]`);
if (input) {
input.disabled = !enabled;
input.style.opacity = enabled ? "1" : "0.5";
input.style.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
});
node.setDirtyCanvas(true);
}
// Set up callback (exactly like videoInferenceDimensionsHandler does)
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
// Initial call to set initial state
setTimeout(toggleEnabled, 50);
});
}
// Start initialization
setTimeout(initializeHandler, 200);
}
function upscalerToggleHandler(upscalerNode) {
// Find all "use" parameter widgets for Upscaler
const useUpscaleFactorWidget = upscalerNode.widgets.find(w => w.name === "useUpscaleFactor");
const upscaleFactorWidget = upscalerNode.widgets.find(w => w.name === "upscaleFactor");
const useStepsWidget = upscalerNode.widgets.find(w => w.name === "useSteps");
const stepsWidget = upscalerNode.widgets.find(w => w.name === "steps");
const useSeedWidget = upscalerNode.widgets.find(w => w.name === "useSeed");
const seedWidget = upscalerNode.widgets.find(w => w.name === "seed");
const useCFGScaleWidget = upscalerNode.widgets.find(w => w.name === "useCFGScale");
const cfgScaleWidget = upscalerNode.widgets.find(w => w.name === "CFGScale");
const usePromptsWidget = upscalerNode.widgets.find(w => w.name === "usePrompts");
const positivePromptWidget = upscalerNode.widgets.find(w => w.name === "positivePrompt");
const negativePromptWidget = upscalerNode.widgets.find(w => w.name === "negativePrompt");
const useClarityParamsWidget = upscalerNode.widgets.find(w => w.name === "useClarityParams");
const controlNetWeightWidget = upscalerNode.widgets.find(w => w.name === "controlNetWeight");
const strengthWidget = upscalerNode.widgets.find(w => w.name === "strength");
const schedulerWidget = upscalerNode.widgets.find(w => w.name === "scheduler");
const useCCSRParamsWidget = upscalerNode.widgets.find(w => w.name === "useCCSRParams");
const colorFixWidget = upscalerNode.widgets.find(w => w.name === "colorFix");
const tileDiffusionWidget = upscalerNode.widgets.find(w => w.name === "tileDiffusion");
const useLatentParamsWidget = upscalerNode.widgets.find(w => w.name === "useLatentParams");
const clipSkipWidget = upscalerNode.widgets.find(w => w.name === "clipSkip");
// Helper function to toggle widget enabled state (exact same pattern)
function toggleWidgetState(useWidget, paramWidgets, paramNames) {
if (!useWidget || !paramWidgets || paramWidgets.length === 0) return;
function toggleEnabled() {
const enabled = useWidget.value === true;
// Apply to each parameter widget
paramWidgets.forEach((paramWidget, idx) => {
if (!paramWidget) return;
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;
// Fallback: try to find inputs via DOM if inputEl is not available
if (!paramWidget.inputEl) {
const nodeElement = upscalerNode.htmlElements?.widgetsContainer || upscalerNode.htmlElements;
if (nodeElement && paramNames[idx]) {
const input = nodeElement.querySelector(`input[name="${paramNames[idx]}"], textarea[name="${paramNames[idx]}"], select[name="${paramNames[idx]}"]`);
if (input) {
input.disabled = !enabled;
input.style.opacity = enabled ? "1" : "0.5";
input.style.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
});
upscalerNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
// Set up all toggle handlers
if (useUpscaleFactorWidget && upscaleFactorWidget) {
toggleWidgetState(useUpscaleFactorWidget, [upscaleFactorWidget], ["upscaleFactor"]);
}
if (useStepsWidget && stepsWidget) {
toggleWidgetState(useStepsWidget, [stepsWidget], ["steps"]);
}
if (useSeedWidget && seedWidget) {
toggleWidgetState(useSeedWidget, [seedWidget], ["seed"]);
}
if (useCFGScaleWidget && cfgScaleWidget) {
toggleWidgetState(useCFGScaleWidget, [cfgScaleWidget], ["CFGScale"]);
}
if (usePromptsWidget && positivePromptWidget && negativePromptWidget) {
toggleWidgetState(usePromptsWidget, [positivePromptWidget, negativePromptWidget], ["positivePrompt", "negativePrompt"]);
}
if (useClarityParamsWidget && controlNetWeightWidget && strengthWidget && schedulerWidget) {
toggleWidgetState(useClarityParamsWidget, [controlNetWeightWidget, strengthWidget, schedulerWidget], ["controlNetWeight", "strength", "scheduler"]);
}
if (useCCSRParamsWidget && colorFixWidget && tileDiffusionWidget) {
toggleWidgetState(useCCSRParamsWidget, [colorFixWidget, tileDiffusionWidget], ["colorFix", "tileDiffusion"]);
}
if (useLatentParamsWidget && clipSkipWidget) {
toggleWidgetState(useLatentParamsWidget, [clipSkipWidget], ["clipSkip"]);
}
const useTargetMegapixelsWidget = upscalerNode.widgets.find(w => w.name === "useTargetMegapixels");
const targetMegapixelsWidget = upscalerNode.widgets.find(w => w.name === "targetMegapixels");
if (useTargetMegapixelsWidget && targetMegapixelsWidget) {
toggleWidgetState(useTargetMegapixelsWidget, [targetMegapixelsWidget], ["targetMegapixels"]);
}
}
function imageUpscalerSettingsToggleHandler(settingsNode) {
const useEnhanceDetailsWidget = settingsNode.widgets.find(w => w.name === "useEnhanceDetails");
const enhanceDetailsWidget = settingsNode.widgets.find(w => w.name === "enhanceDetails");
const useRealismWidget = settingsNode.widgets.find(w => w.name === "useRealism");
const realismWidget = settingsNode.widgets.find(w => w.name === "realism");
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 ? "pointer" : "not-allowed";
}
paramWidget.disabled = !enabled;
if (!paramWidget.inputEl) {
const nodeElement = settingsNode.htmlElements?.widgetsContainer || settingsNode.htmlElements;
if (nodeElement && paramName) {
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.cursor = enabled ? "pointer" : "not-allowed";
}
}
}
settingsNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
if (useEnhanceDetailsWidget && enhanceDetailsWidget) {
toggleWidgetState(useEnhanceDetailsWidget, enhanceDetailsWidget, "enhanceDetails");
}
if (useRealismWidget && realismWidget) {
toggleWidgetState(useRealismWidget, realismWidget, "realism");
}
}
function audioInferenceToggleHandler(audioInferenceNode) {
// Find all "use" parameter widgets for Audio Inference
const usePositivePromptWidget = audioInferenceNode.widgets.find(w => w.name === "usePositivePrompt");
const positivePromptWidget = audioInferenceNode.widgets.find(w => w.name === "positivePrompt");
const useDurationWidget = audioInferenceNode.widgets.find(w => w.name === "useDuration");
const durationWidget = audioInferenceNode.widgets.find(w => w.name === "duration");
const useSampleRateWidget = audioInferenceNode.widgets.find(w => w.name === "useSampleRate");
const sampleRateWidget = audioInferenceNode.widgets.find(w => w.name === "sampleRate");
const useBitrateWidget = audioInferenceNode.widgets.find(w => w.name === "useBitrate");
const bitrateWidget = audioInferenceNode.widgets.find(w => w.name === "bitrate");
const useSeedWidget = audioInferenceNode.widgets.find(w => w.name === "useSeed");
const seedWidget = audioInferenceNode.widgets.find(w => w.name === "seed");
const useStepsWidget = audioInferenceNode.widgets.find(w => w.name === "useSteps");
const stepsWidget = audioInferenceNode.widgets.find(w => w.name === "steps");
const useStrengthWidget = audioInferenceNode.widgets.find(w => w.name === "useStrength");
const strengthWidget = audioInferenceNode.widgets.find(w => w.name === "strength");
const useCFGScaleWidget = audioInferenceNode.widgets.find(w => w.name === "useCFGScale");
const CFGScaleWidget = audioInferenceNode.widgets.find(w => w.name === "CFGScale");
const useChannelsWidget = audioInferenceNode.widgets.find(w => w.name === "useChannels");
const channelsWidget = audioInferenceNode.widgets.find(w => w.name === "channels");
// Helper function to toggle widget enabled state (exact same pattern)
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 = audioInferenceNode.htmlElements?.widgetsContainer || audioInferenceNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
audioInferenceNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
// Set up all toggle handlers
if (usePositivePromptWidget && positivePromptWidget) {
toggleWidgetState(usePositivePromptWidget, positivePromptWidget, "positivePrompt");
}
if (useDurationWidget && durationWidget) {
toggleWidgetState(useDurationWidget, durationWidget, "duration");
}
if (useSampleRateWidget && sampleRateWidget) {
toggleWidgetState(useSampleRateWidget, sampleRateWidget, "sampleRate");
}
if (useBitrateWidget && bitrateWidget) {
toggleWidgetState(useBitrateWidget, bitrateWidget, "bitrate");
}
if (useSeedWidget && seedWidget) {
toggleWidgetState(useSeedWidget, seedWidget, "seed");
}
if (useStepsWidget && stepsWidget) {
toggleWidgetState(useStepsWidget, stepsWidget, "steps");
}
if (useStrengthWidget && strengthWidget) {
toggleWidgetState(useStrengthWidget, strengthWidget, "strength");
}
if (useCFGScaleWidget && CFGScaleWidget) {
toggleWidgetState(useCFGScaleWidget, CFGScaleWidget, "CFGScale");
}
if (useChannelsWidget && channelsWidget) {
toggleWidgetState(useChannelsWidget, channelsWidget, "channels");
}
}
function audioSettingsToggleHandler(settingsNode) {
if (!settingsNode?.widgets) return;
const useTemperatureWidget = settingsNode.widgets.find(w => w && w.name === "useTemperature");
const temperatureWidget = settingsNode.widgets.find(w => w && w.name === "temperature");
const useAudioTemperatureWidget = settingsNode.widgets.find(w => w && w.name === "useAudioTemperature");
const audioTemperatureWidget = settingsNode.widgets.find(w => w && w.name === "audioTemperature");
const useTopKWidget = settingsNode.widgets.find(w => w && w.name === "useTopK");
const topKWidget = settingsNode.widgets.find(w => w && w.name === "topK");
const useIncludePrefixWidget = settingsNode.widgets.find(w => w && w.name === "useIncludePrefix");
const includePrefixWidget = settingsNode.widgets.find(w => w && w.name === "includePrefix");
const useLyricsWidget = settingsNode.widgets.find(w => w && w.name === "useLyrics");
const lyricsWidget = settingsNode.widgets.find(w => w && w.name === "lyrics");
const useInstrumentalWidget = settingsNode.widgets.find(w => w && w.name === "useInstrumental");
const instrumentalWidget = settingsNode.widgets.find(w => w && w.name === "instrumental");
const useLyricsOptimizerWidget = settingsNode.widgets.find(w => w && w.name === "useLyricsOptimizer");
const lyricsOptimizerWidget = settingsNode.widgets.find(w => w && w.name === "lyricsOptimizer");
const useGuidanceTypeWidget = settingsNode.widgets.find(w => w && w.name === "useGuidanceType");
const guidanceTypeWidget = settingsNode.widgets.find(w => w && w.name === "guidanceType");
const useLanguageBoostWidget = settingsNode.widgets.find(w => w && w.name === "useLanguageBoost");
const languageBoostWidget = settingsNode.widgets.find(w => w && w.name === "languageBoost");
const useTurboWidget = settingsNode.widgets.find(w => w && w.name === "useTurbo");
const turboWidget = settingsNode.widgets.find(w => w && w.name === "turbo");
const useTextNormalizationWidget = settingsNode.widgets.find(w => w && w.name === "useTextNormalization");
const textNormalizationWidget = settingsNode.widgets.find(w => w && w.name === "textNormalization");
const useBpmWidget = settingsNode.widgets.find(w => w && w.name === "useBpm");
const bpmWidget = settingsNode.widgets.find(w => w && w.name === "bpm");
const useKeyScaleWidget = settingsNode.widgets.find(w => w && w.name === "useKeyScale");
const keyScaleWidget = settingsNode.widgets.find(w => w && w.name === "keyScale");
const useTimeSignatureWidget = settingsNode.widgets.find(w => w && w.name === "useTimeSignature");
const timeSignatureWidget = settingsNode.widgets.find(w => w && w.name === "timeSignature");
const useVocalLanguageWidget = settingsNode.widgets.find(w => w && w.name === "useVocalLanguage");
const vocalLanguageWidget = settingsNode.widgets.find(w => w && w.name === "vocalLanguage");
const useCoverConditioningScaleWidget = settingsNode.widgets.find(w => w && w.name === "useCoverConditioningScale");
const coverConditioningScaleWidget = settingsNode.widgets.find(w => w && w.name === "coverConditioningScale");
const useRepaintingStartWidget = settingsNode.widgets.find(w => w && w.name === "useRepaintingStart");
const repaintingStartWidget = settingsNode.widgets.find(w => w && w.name === "repaintingStart");
const useRepaintingEndWidget = settingsNode.widgets.find(w => w && w.name === "useRepaintingEnd");
const repaintingEndWidget = settingsNode.widgets.find(w => w && w.name === "repaintingEnd");
const useXVectorOnlyWidget = settingsNode.widgets.find(w => w && w.name === "useXVectorOnly");
const xVectorOnlyWidget = settingsNode.widgets.find(w => w && w.name === "xVectorOnly");
const useMaxNewTokensWidget = settingsNode.widgets.find(w => w && w.name === "useMaxNewTokens");
const maxNewTokensWidget = settingsNode.widgets.find(w => w && w.name === "maxNewTokens");
const useTranscriptWidget = settingsNode.widgets.find(w => w && w.name === "useTranscript");
const transcriptWidget = settingsNode.widgets.find(w => w && w.name === "transcript");
const useCfgIntervalStartWidget = settingsNode.widgets.find(w => w && w.name === "useCfgIntervalStart");
const cfgIntervalStartWidget = settingsNode.widgets.find(w => w && w.name === "cfgIntervalStart");
const useCfgIntervalEndWidget = settingsNode.widgets.find(w => w && w.name === "useCfgIntervalEnd");
const cfgIntervalEndWidget = settingsNode.widgets.find(w => w && w.name === "cfgIntervalEnd");
const useNormalizeLoudnessWidget = settingsNode.widgets.find(w => w && w.name === "useNormalizeLoudness");
const normalizeLoudnessWidget = settingsNode.widgets.find(w => w && w.name === "normalizeLoudness");
const useTopPWidget = settingsNode.widgets.find(w => w && w.name === "useTopP");
const topPWidget = settingsNode.widgets.find(w => w && w.name === "topP");
const useChunkLengthWidget = settingsNode.widgets.find(w => w && w.name === "useChunkLength");
const chunkLengthWidget = settingsNode.widgets.find(w => w && w.name === "chunkLength");
const useMinChunkLengthWidget = settingsNode.widgets.find(w => w && w.name === "useMinChunkLength");
const minChunkLengthWidget = settingsNode.widgets.find(w => w && w.name === "minChunkLength");
const useNormalizeWidget = settingsNode.widgets.find(w => w && w.name === "useNormalize");
const normalizeWidget = settingsNode.widgets.find(w => w && w.name === "normalize");
const useLatencyWidget = settingsNode.widgets.find(w => w && w.name === "useLatency");
const latencyWidget = settingsNode.widgets.find(w => w && w.name === "latency");
const useMaxTokensWidget = settingsNode.widgets.find(w => w && w.name === "useMaxTokens");
const maxTokensWidget = settingsNode.widgets.find(w => w && w.name === "maxTokens");
const useRepetitionPenaltyWidget = settingsNode.widgets.find(w => w && w.name === "useRepetitionPenalty");
const repetitionPenaltyWidget = settingsNode.widgets.find(w => w && w.name === "repetitionPenalty");
const useConditionOnPreviousChunksWidget = settingsNode.widgets.find(w => w && w.name === "useConditionOnPreviousChunks");
const conditionOnPreviousChunksWidget = settingsNode.widgets.find(w => w && w.name === "conditionOnPreviousChunks");
const useEarlyStopThresholdWidget = settingsNode.widgets.find(w => w && w.name === "useEarlyStopThreshold");
const earlyStopThresholdWidget = settingsNode.widgets.find(w => w && w.name === "earlyStopThreshold");
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function applyState() {
const enabled = useWidget.value === true;
toggleWidgetEnabled(paramWidget, enabled, settingsNode);
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
settingsNode.setDirtyCanvas(true);
}
setTimeout(applyState, 100);
appendWidgetCB(useWidget, () => setTimeout(applyState, 50));
}
if (useTemperatureWidget && temperatureWidget) toggleWidgetState(useTemperatureWidget, temperatureWidget, "temperature");
if (useAudioTemperatureWidget && audioTemperatureWidget) toggleWidgetState(useAudioTemperatureWidget, audioTemperatureWidget, "audioTemperature");
if (useTopKWidget && topKWidget) toggleWidgetState(useTopKWidget, topKWidget, "topK");
if (useIncludePrefixWidget && includePrefixWidget) toggleWidgetState(useIncludePrefixWidget, includePrefixWidget, "includePrefix");
if (useLyricsWidget && lyricsWidget) toggleWidgetState(useLyricsWidget, lyricsWidget, "lyrics");
if (useInstrumentalWidget && instrumentalWidget) toggleWidgetState(useInstrumentalWidget, instrumentalWidget, "instrumental");
if (useLyricsOptimizerWidget && lyricsOptimizerWidget) toggleWidgetState(useLyricsOptimizerWidget, lyricsOptimizerWidget, "lyricsOptimizer");
if (useGuidanceTypeWidget && guidanceTypeWidget) toggleWidgetState(useGuidanceTypeWidget, guidanceTypeWidget, "guidanceType");
if (useLanguageBoostWidget && languageBoostWidget) toggleWidgetState(useLanguageBoostWidget, languageBoostWidget, "languageBoost");
if (useTurboWidget && turboWidget) toggleWidgetState(useTurboWidget, turboWidget, "turbo");
if (useTextNormalizationWidget && textNormalizationWidget) toggleWidgetState(useTextNormalizationWidget, textNormalizationWidget, "textNormalization");
if (useBpmWidget && bpmWidget) toggleWidgetState(useBpmWidget, bpmWidget, "bpm");
if (useKeyScaleWidget && keyScaleWidget) toggleWidgetState(useKeyScaleWidget, keyScaleWidget, "keyScale");
if (useTimeSignatureWidget && timeSignatureWidget) toggleWidgetState(useTimeSignatureWidget, timeSignatureWidget, "timeSignature");
if (useVocalLanguageWidget && vocalLanguageWidget) toggleWidgetState(useVocalLanguageWidget, vocalLanguageWidget, "vocalLanguage");
if (useCoverConditioningScaleWidget && coverConditioningScaleWidget) toggleWidgetState(useCoverConditioningScaleWidget, coverConditioningScaleWidget, "coverConditioningScale");
if (useRepaintingStartWidget && repaintingStartWidget) toggleWidgetState(useRepaintingStartWidget, repaintingStartWidget, "repaintingStart");
if (useRepaintingEndWidget && repaintingEndWidget) toggleWidgetState(useRepaintingEndWidget, repaintingEndWidget, "repaintingEnd");
if (useXVectorOnlyWidget && xVectorOnlyWidget) toggleWidgetState(useXVectorOnlyWidget, xVectorOnlyWidget, "xVectorOnly");
if (useMaxNewTokensWidget && maxNewTokensWidget) toggleWidgetState(useMaxNewTokensWidget, maxNewTokensWidget, "maxNewTokens");
if (useTranscriptWidget && transcriptWidget) toggleWidgetState(useTranscriptWidget, transcriptWidget, "transcript");
if (useCfgIntervalStartWidget && cfgIntervalStartWidget) toggleWidgetState(useCfgIntervalStartWidget, cfgIntervalStartWidget, "cfgIntervalStart");
if (useCfgIntervalEndWidget && cfgIntervalEndWidget) toggleWidgetState(useCfgIntervalEndWidget, cfgIntervalEndWidget, "cfgIntervalEnd");
if (useNormalizeLoudnessWidget && normalizeLoudnessWidget) toggleWidgetState(useNormalizeLoudnessWidget, normalizeLoudnessWidget, "normalizeLoudness");
if (useTopPWidget && topPWidget) toggleWidgetState(useTopPWidget, topPWidget, "topP");
if (useChunkLengthWidget && chunkLengthWidget) toggleWidgetState(useChunkLengthWidget, chunkLengthWidget, "chunkLength");
if (useMinChunkLengthWidget && minChunkLengthWidget) toggleWidgetState(useMinChunkLengthWidget, minChunkLengthWidget, "minChunkLength");
if (useNormalizeWidget && normalizeWidget) toggleWidgetState(useNormalizeWidget, normalizeWidget, "normalize");
if (useLatencyWidget && latencyWidget) toggleWidgetState(useLatencyWidget, latencyWidget, "latency");
if (useMaxTokensWidget && maxTokensWidget) toggleWidgetState(useMaxTokensWidget, maxTokensWidget, "maxTokens");
if (useRepetitionPenaltyWidget && repetitionPenaltyWidget) toggleWidgetState(useRepetitionPenaltyWidget, repetitionPenaltyWidget, "repetitionPenalty");
if (useConditionOnPreviousChunksWidget && conditionOnPreviousChunksWidget) toggleWidgetState(useConditionOnPreviousChunksWidget, conditionOnPreviousChunksWidget, "conditionOnPreviousChunks");
if (useEarlyStopThresholdWidget && earlyStopThresholdWidget) toggleWidgetState(useEarlyStopThresholdWidget, earlyStopThresholdWidget, "earlyStopThreshold");
}
function textInferenceSettingsToggleHandler(settingsNode) {
if (!settingsNode?.widgets) return;
const useSystemPromptWidget = settingsNode.widgets.find(w => w && w.name === "useSystemPrompt");
const systemWidget = settingsNode.widgets.find(w => w && (w.name === "systemPrompt" || w.name === "system"));
const useMaxTokensWidget = settingsNode.widgets.find(w => w && w.name === "useMaxTokens");
const maxTokensWidget = settingsNode.widgets.find(w => w && w.name === "maxTokens");
const useTemperatureWidget = settingsNode.widgets.find(w => w && w.name === "useTemperature");
const temperatureWidget = settingsNode.widgets.find(w => w && w.name === "temperature");
const useTopPWidget = settingsNode.widgets.find(w => w && w.name === "useTopP");
const topPWidget = settingsNode.widgets.find(w => w && w.name === "topP");
const useTopKWidget = settingsNode.widgets.find(w => w && w.name === "useTopK");
const topKWidget = settingsNode.widgets.find(w => w && w.name === "topK");
const useStopSequencesWidget = settingsNode.widgets.find(w => w && w.name === "useStopSequences");
const stopSequencesWidget = settingsNode.widgets.find(w => w && w.name === "stopSequences");
const usePresencePenaltyWidget = settingsNode.widgets.find(w => w && w.name === "usePresencePenalty");
const presencePenaltyWidget = settingsNode.widgets.find(w => w && w.name === "presencePenalty");
const useFrequencyPenaltyWidget = settingsNode.widgets.find(w => w && w.name === "useFrequencyPenalty");
const frequencyPenaltyWidget = settingsNode.widgets.find(w => w && w.name === "frequencyPenalty");
const useToolsWidget = settingsNode.widgets.find(w => w && w.name === "useTools");
const toolsWidget = settingsNode.widgets.find(w => w && w.name === "tools");
function toggleWidgetState(useWidget, paramWidget) {
if (!useWidget || !paramWidget) return;
function applyState() {
const enabled = useWidget.value === true;
toggleWidgetEnabled(paramWidget, enabled, settingsNode);
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
settingsNode.setDirtyCanvas(true);
}
setTimeout(applyState, 100);
appendWidgetCB(useWidget, () => setTimeout(applyState, 50));
}
if (useSystemPromptWidget && systemWidget) toggleWidgetState(useSystemPromptWidget, systemWidget);
if (useMaxTokensWidget && maxTokensWidget) toggleWidgetState(useMaxTokensWidget, maxTokensWidget);
if (useTemperatureWidget && temperatureWidget) toggleWidgetState(useTemperatureWidget, temperatureWidget);
if (useTopPWidget && topPWidget) toggleWidgetState(useTopPWidget, topPWidget);
if (useTopKWidget && topKWidget) toggleWidgetState(useTopKWidget, topKWidget);
if (useStopSequencesWidget && stopSequencesWidget) toggleWidgetState(useStopSequencesWidget, stopSequencesWidget);
if (usePresencePenaltyWidget && presencePenaltyWidget) toggleWidgetState(usePresencePenaltyWidget, presencePenaltyWidget);
if (useFrequencyPenaltyWidget && frequencyPenaltyWidget) toggleWidgetState(useFrequencyPenaltyWidget, frequencyPenaltyWidget);
if (useToolsWidget && toolsWidget) toggleWidgetState(useToolsWidget, toolsWidget);
}
function videoSettingsToggleHandler(settingsNode) {
if (!settingsNode?.widgets) return;
const useDraftWidget = settingsNode.widgets.find(w => w && w.name === "useDraft");
const draftWidget = settingsNode.widgets.find(w => w && w.name === "draft");
const useAudioWidget = settingsNode.widgets.find(w => w && w.name === "useAudio");
const audioWidget = settingsNode.widgets.find(w => w && w.name === "audio");
const usePreserveAudioWidget = settingsNode.widgets.find(w => w && w.name === "usePreserveAudio");
const preserveAudioWidget = settingsNode.widgets.find(w => w && w.name === "preserveAudio");
const useSourceAudioSyncWidget = settingsNode.widgets.find(w => w && w.name === "useSourceAudioSync");
const sourceAudioSyncWidget = settingsNode.widgets.find(w => w && w.name === "sourceAudioSync");
const useTurboWidget = settingsNode.widgets.find(w => w && w.name === "useTurbo");
const turboWidget = settingsNode.widgets.find(w => w && w.name === "turbo");
const useLoopWidget = settingsNode.widgets.find(w => w && w.name === "useLoop");
const loopWidget = settingsNode.widgets.find(w => w && w.name === "loop");
const useHdrWidget = settingsNode.widgets.find(w => w && w.name === "useHdr");
const hdrWidget = settingsNode.widgets.find(w => w && w.name === "hdr");
const useExrExportWidget = settingsNode.widgets.find(w => w && w.name === "useExrExport");
const exrExportWidget = settingsNode.widgets.find(w => w && w.name === "exrExport");
const useVoicePromptWidget = settingsNode.widgets.find(w => w && w.name === "useVoicePrompt");
const voicePromptWidget = settingsNode.widgets.find(w => w && w.name === "voicePrompt");
const useSafetyFilterWidget = settingsNode.widgets.find(w => w && w.name === "useSafetyFilter");
const safetyFilterWidget = settingsNode.widgets.find(w => w && w.name === "safetyFilter");
const usePromptUpsamplingWidget = settingsNode.widgets.find(w => w && w.name === "usePromptUpsampling");
const promptUpsamplingWidget = settingsNode.widgets.find(w => w && w.name === "promptUpsampling");
const useBackgroundColorWidget = settingsNode.widgets.find(w => w && w.name === "useBackgroundColor");
const backgroundColorWidget = settingsNode.widgets.find(w => w && w.name === "backgroundColor");
const useRemoveBackgroundWidget = settingsNode.widgets.find(w => w && w.name === "useRemoveBackground");
const removeBackgroundWidget = settingsNode.widgets.find(w => w && w.name === "removeBackground");
const useExpressivenessWidget = settingsNode.widgets.find(w => w && w.name === "useExpressiveness");
const expressivenessWidget = settingsNode.widgets.find(w => w && w.name === "expressiveness");
const useVoiceDescriptionWidget = settingsNode.widgets.find(w => w && w.name === "useVoiceDescription");
const voiceDescriptionWidget = settingsNode.widgets.find(w => w && w.name === "voiceDescription");
const useStyleWidget = settingsNode.widgets.find(w => w && w.name === "useStyle");
const styleWidget = settingsNode.widgets.find(w => w && w.name === "style");
const useThinkingWidget = settingsNode.widgets.find(w => w && w.name === "useThinking");
const thinkingWidget = settingsNode.widgets.find(w => w && w.name === "thinking");
const useMultiClipWidget = settingsNode.widgets.find(w => w && w.name === "useMultiClip");
const multiClipWidget = settingsNode.widgets.find(w => w && w.name === "multiClip");
const useShotTypeWidget = settingsNode.widgets.find(w => w && w.name === "useShotType");
const shotTypeWidget = settingsNode.widgets.find(w => w && w.name === "shotType");
const usePromptExtendWidget = settingsNode.widgets.find(w => w && w.name === "usePromptExtend");
const promptExtendWidget = settingsNode.widgets.find(w => w && w.name === "promptExtend");
const useSyncModeWidget = settingsNode.widgets.find(w => w && w.name === "useSyncMode");
const syncModeWidget = settingsNode.widgets.find(w => w && w.name === "syncMode");
const useModeWidget = settingsNode.widgets.find(w => w && w.name === "useMode");
const modeWidget = settingsNode.widgets.find(w => w && w.name === "mode");
const useEmotionWidget = settingsNode.widgets.find(w => w && w.name === "useEmotion");
const emotionWidget = settingsNode.widgets.find(w => w && w.name === "emotion");
const useTemperatureWidget = settingsNode.widgets.find(w => w && w.name === "useTemperature");
const temperatureWidget = settingsNode.widgets.find(w => w && w.name === "temperature");
const useOcclusionDetectionWidget = settingsNode.widgets.find(w => w && w.name === "useOcclusionDetection");
const occlusionDetectionWidget = settingsNode.widgets.find(w => w && w.name === "occlusionDetection");
const useKeyframeIdWidget = settingsNode.widgets.find(w => w && w.name === "useKeyframeId");
const keyframeIdWidget = settingsNode.widgets.find(w => w && w.name === "keyframeId");
const useFitWidget = settingsNode.widgets.find(w => w && w.name === "useFit");
const fitWidget = settingsNode.widgets.find(w => w && w.name === "fit");
const useCaptionWidget = settingsNode.widgets.find(w => w && w.name === "useCaption");
const captionWidget = settingsNode.widgets.find(w => w && w.name === "caption");
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function applyState() {
const enabled = useWidget.value === true;
toggleWidgetEnabled(paramWidget, enabled, settingsNode);
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
settingsNode.setDirtyCanvas(true);
}
setTimeout(applyState, 100);
appendWidgetCB(useWidget, () => setTimeout(applyState, 50));
}
if (useDraftWidget && draftWidget) toggleWidgetState(useDraftWidget, draftWidget, "draft");
if (useAudioWidget && audioWidget) toggleWidgetState(useAudioWidget, audioWidget, "audio");
if (usePreserveAudioWidget && preserveAudioWidget) toggleWidgetState(usePreserveAudioWidget, preserveAudioWidget, "preserveAudio");
if (useSourceAudioSyncWidget && sourceAudioSyncWidget) toggleWidgetState(useSourceAudioSyncWidget, sourceAudioSyncWidget, "sourceAudioSync");
if (useTurboWidget && turboWidget) toggleWidgetState(useTurboWidget, turboWidget, "turbo");
if (useLoopWidget && loopWidget) toggleWidgetState(useLoopWidget, loopWidget, "loop");
if (useHdrWidget && hdrWidget) toggleWidgetState(useHdrWidget, hdrWidget, "hdr");
if (useExrExportWidget && exrExportWidget) toggleWidgetState(useExrExportWidget, exrExportWidget, "exrExport");
if (useVoicePromptWidget && voicePromptWidget) toggleWidgetState(useVoicePromptWidget, voicePromptWidget, "voicePrompt");
if (useSafetyFilterWidget && safetyFilterWidget) toggleWidgetState(useSafetyFilterWidget, safetyFilterWidget, "safetyFilter");
if (usePromptUpsamplingWidget && promptUpsamplingWidget) toggleWidgetState(usePromptUpsamplingWidget, promptUpsamplingWidget, "promptUpsampling");
if (useBackgroundColorWidget && backgroundColorWidget) toggleWidgetState(useBackgroundColorWidget, backgroundColorWidget, "backgroundColor");
if (useRemoveBackgroundWidget && removeBackgroundWidget) toggleWidgetState(useRemoveBackgroundWidget, removeBackgroundWidget, "removeBackground");
if (useExpressivenessWidget && expressivenessWidget) toggleWidgetState(useExpressivenessWidget, expressivenessWidget, "expressiveness");
if (useVoiceDescriptionWidget && voiceDescriptionWidget) toggleWidgetState(useVoiceDescriptionWidget, voiceDescriptionWidget, "voiceDescription");
if (useStyleWidget && styleWidget) toggleWidgetState(useStyleWidget, styleWidget, "style");
if (useThinkingWidget && thinkingWidget) toggleWidgetState(useThinkingWidget, thinkingWidget, "thinking");
if (useMultiClipWidget && multiClipWidget) toggleWidgetState(useMultiClipWidget, multiClipWidget, "multiClip");
if (useShotTypeWidget && shotTypeWidget) toggleWidgetState(useShotTypeWidget, shotTypeWidget, "shotType");
if (usePromptExtendWidget && promptExtendWidget) toggleWidgetState(usePromptExtendWidget, promptExtendWidget, "promptExtend");
if (useSyncModeWidget && syncModeWidget) toggleWidgetState(useSyncModeWidget, syncModeWidget, "syncMode");
if (useModeWidget && modeWidget) toggleWidgetState(useModeWidget, modeWidget, "mode");
if (useEmotionWidget && emotionWidget) toggleWidgetState(useEmotionWidget, emotionWidget, "emotion");
if (useTemperatureWidget && temperatureWidget) toggleWidgetState(useTemperatureWidget, temperatureWidget, "temperature");
if (useOcclusionDetectionWidget && occlusionDetectionWidget) toggleWidgetState(useOcclusionDetectionWidget, occlusionDetectionWidget, "occlusionDetection");
if (useKeyframeIdWidget && keyframeIdWidget) toggleWidgetState(useKeyframeIdWidget, keyframeIdWidget, "keyframeId");
if (useFitWidget && fitWidget) toggleWidgetState(useFitWidget, fitWidget, "fit");
if (useCaptionWidget && captionWidget) toggleWidgetState(useCaptionWidget, captionWidget, "caption");
}
function videoInferenceSettingsTtsToggleHandler(node) {
if (!node?.widgets) return;
const useStabilityWidget = node.widgets.find(w => w && w.name === "useStability");
const stabilityWidget = node.widgets.find(w => w && w.name === "stability");
const useSimilarityBoostWidget = node.widgets.find(w => w && w.name === "useSimilarityBoost");
const similarityBoostWidget = node.widgets.find(w => w && w.name === "similarityBoost");
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function applyState() {
const enabled = useWidget.value === true;
toggleWidgetEnabled(paramWidget, enabled, node);
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
node.setDirtyCanvas(true);
}
setTimeout(applyState, 100);
appendWidgetCB(useWidget, () => setTimeout(applyState, 50));
}
if (useStabilityWidget && stabilityWidget) toggleWidgetState(useStabilityWidget, stabilityWidget, "stability");
if (useSimilarityBoostWidget && similarityBoostWidget) toggleWidgetState(useSimilarityBoostWidget, similarityBoostWidget, "similarityBoost");
}
function videoInferenceSettingsActiveSpeakerDetectionToggleHandler(node) {
if (!node?.widgets) return;
const useAutoDetectWidget = node.widgets.find(w => w && w.name === "useAutoDetect");
const autoDetectWidget = node.widgets.find(w => w && w.name === "autoDetect");
const useFrameNumberWidget = node.widgets.find(w => w && w.name === "useFrameNumber");
const frameNumberWidget = node.widgets.find(w => w && w.name === "frameNumber");
const useCoordinatesWidget = node.widgets.find(w => w && w.name === "useCoordinates");
const coordinateXWidget = node.widgets.find(w => w && w.name === "coordinateX");
const coordinateYWidget = node.widgets.find(w => w && w.name === "coordinateY");
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function applyState() {
const enabled = useWidget.value === true;
toggleWidgetEnabled(paramWidget, enabled, node);
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
node.setDirtyCanvas(true);
}
setTimeout(applyState, 100);
appendWidgetCB(useWidget, () => setTimeout(applyState, 50));
}
if (useAutoDetectWidget && autoDetectWidget) toggleWidgetState(useAutoDetectWidget, autoDetectWidget, "autoDetect");
if (useFrameNumberWidget && frameNumberWidget) toggleWidgetState(useFrameNumberWidget, frameNumberWidget, "frameNumber");
if (useCoordinatesWidget && coordinateXWidget) toggleWidgetState(useCoordinatesWidget, coordinateXWidget, "coordinateX");
if (useCoordinatesWidget && coordinateYWidget) toggleWidgetState(useCoordinatesWidget, coordinateYWidget, "coordinateY");
}
function videoInferenceSettingsActiveSpeakerBoundingBoxesToggleHandler(node) {
if (!node?.widgets) return;
const useBox1Widget = node.widgets.find(w => w && w.name === "useBox1");
const box1Widget = node.widgets.find(w => w && w.name === "box1");
const useBox2Widget = node.widgets.find(w => w && w.name === "useBox2");
const box2Widget = node.widgets.find(w => w && w.name === "box2");
const useBox3Widget = node.widgets.find(w => w && w.name === "useBox3");
const box3Widget = node.widgets.find(w => w && w.name === "box3");
const useBox4Widget = node.widgets.find(w => w && w.name === "useBox4");
const box4Widget = node.widgets.find(w => w && w.name === "box4");
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function applyState() {
const enabled = useWidget.value === true;
toggleWidgetEnabled(paramWidget, enabled, node);
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
node.setDirtyCanvas(true);
}
setTimeout(applyState, 100);
appendWidgetCB(useWidget, () => setTimeout(applyState, 50));
}
if (useBox1Widget && box1Widget) toggleWidgetState(useBox1Widget, box1Widget, "box1");
if (useBox2Widget && box2Widget) toggleWidgetState(useBox2Widget, box2Widget, "box2");
if (useBox3Widget && box3Widget) toggleWidgetState(useBox3Widget, box3Widget, "box3");
if (useBox4Widget && box4Widget) toggleWidgetState(useBox4Widget, box4Widget, "box4");
}
function videoInferenceSettingsSegmentsToggleHandler(node) {
if (!node?.widgets) return;
function byName(name) {
return node.widgets.find(w => w && w.name === name);
}
function togglePair(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function applyState() {
const enabled = useWidget.value === true;
toggleWidgetEnabled(paramWidget, enabled, node);
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
node.setDirtyCanvas(true);
}
setTimeout(applyState, 100);
appendWidgetCB(useWidget, () => setTimeout(applyState, 50));
}
function wireSegment(idx) {
const useSegment = byName(`useSegment${idx}`);
const start = byName(`segment${idx}StartTime`);
const end = byName(`segment${idx}EndTime`);
const audio = byName(`segment${idx}Audio`);
const useCrop = byName(`useSegment${idx}AudioCrop`);
const cropStart = byName(`segment${idx}AudioStartTime`);
const cropEnd = byName(`segment${idx}AudioEndTime`);
function toggleCropTimeWidget(paramWidget) {
if (!useSegment || !useCrop || !paramWidget) return;
function applyState() {
const enabled = useSegment.value === true && useCrop.value === true;
toggleWidgetEnabled(paramWidget, enabled, node);
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
node.setDirtyCanvas(true);
}
setTimeout(applyState, 100);
appendWidgetCB(useSegment, () => setTimeout(applyState, 50));
appendWidgetCB(useCrop, () => setTimeout(applyState, 50));
}
if (useSegment && start) togglePair(useSegment, start, `segment${idx}StartTime`);
if (useSegment && end) togglePair(useSegment, end, `segment${idx}EndTime`);
if (useSegment && audio) togglePair(useSegment, audio, `segment${idx}Audio`);
if (useSegment && useCrop) togglePair(useSegment, useCrop, `useSegment${idx}AudioCrop`);
if (cropStart) toggleCropTimeWidget(cropStart);
if (cropEnd) toggleCropTimeWidget(cropEnd);
}
wireSegment(1);
wireSegment(2);
wireSegment(3);
wireSegment(4);
}
function videoInferenceSettingsControlToggleHandler(node) {
if (!node?.widgets) return;
const useAutoControlsWidget = node.widgets.find(w => w && w.name === "useAutoControls");
const autoControlsWidget = node.widgets.find(w => w && w.name === "autoControls");
const useStrengthWidget = node.widgets.find(w => w && w.name === "useStrength");
const strengthWidget = node.widgets.find(w => w && w.name === "strength");
const useDepthBlurWidget = node.widgets.find(w => w && w.name === "useDepthBlur");
const depthBlurWidget = node.widgets.find(w => w && w.name === "depthBlur");
const useFaceWidget = node.widgets.find(w => w && w.name === "useFace");
const faceWidget = node.widgets.find(w => w && w.name === "face");
const useNormalsAugmentationWidget = node.widgets.find(w => w && w.name === "useNormalsAugmentation");
const normalsAugmentationWidget = node.widgets.find(w => w && w.name === "normalsAugmentation");
const usePoseStrengthWidget = node.widgets.find(w => w && w.name === "usePoseStrength");
const poseStrengthWidget = node.widgets.find(w => w && w.name === "poseStrength");
const useTrajectorySparsityWidget = node.widgets.find(w => w && w.name === "useTrajectorySparsity");
const trajectorySparsityWidget = node.widgets.find(w => w && w.name === "trajectorySparsity");
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function applyState() {
const enabled = useWidget.value === true;
toggleWidgetEnabled(paramWidget, enabled, node);
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
node.setDirtyCanvas(true);
}
setTimeout(applyState, 100);
appendWidgetCB(useWidget, () => setTimeout(applyState, 50));
}
if (useAutoControlsWidget && autoControlsWidget) toggleWidgetState(useAutoControlsWidget, autoControlsWidget, "autoControls");
if (useStrengthWidget && strengthWidget) toggleWidgetState(useStrengthWidget, strengthWidget, "strength");
if (useDepthBlurWidget && depthBlurWidget) toggleWidgetState(useDepthBlurWidget, depthBlurWidget, "depthBlur");
if (useFaceWidget && faceWidget) toggleWidgetState(useFaceWidget, faceWidget, "face");
if (useNormalsAugmentationWidget && normalsAugmentationWidget) toggleWidgetState(useNormalsAugmentationWidget, normalsAugmentationWidget, "normalsAugmentation");
if (usePoseStrengthWidget && poseStrengthWidget) toggleWidgetState(usePoseStrengthWidget, poseStrengthWidget, "poseStrength");
if (useTrajectorySparsityWidget && trajectorySparsityWidget) toggleWidgetState(useTrajectorySparsityWidget, trajectorySparsityWidget, "trajectorySparsity");
}
function audioInferenceSpeechToggleHandler(speechNode) {
if (!speechNode?.widgets) return;
const useVoiceWidget = speechNode.widgets.find(w => w && w.name === "useVoice");
const voiceWidget = speechNode.widgets.find(w => w && w.name === "voice");
const useSpeedWidget = speechNode.widgets.find(w => w && w.name === "useSpeed");
const speedWidget = speechNode.widgets.find(w => w && w.name === "speed");
const useVolumeWidget = speechNode.widgets.find(w => w && w.name === "useVolume");
const volumeWidget = speechNode.widgets.find(w => w && w.name === "volume");
const usePitchWidget = speechNode.widgets.find(w => w && w.name === "usePitch");
const pitchWidget = speechNode.widgets.find(w => w && w.name === "pitch");
const useEmotionWidget = speechNode.widgets.find(w => w && w.name === "useEmotion");
const emotionWidget = speechNode.widgets.find(w => w && w.name === "emotion");
const useToneWidget = speechNode.widgets.find(w => w && w.name === "useTone");
const toneWidget = speechNode.widgets.find(w => w && w.name === "tone");
const useLanguageWidget = speechNode.widgets.find(w => w && w.name === "useLanguage");
const languageWidget = speechNode.widgets.find(w => w && w.name === "language");
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function applyState() {
const enabled = useWidget.value === true;
toggleWidgetEnabled(paramWidget, enabled, speechNode);
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
speechNode.setDirtyCanvas(true);
}
setTimeout(applyState, 100);
appendWidgetCB(useWidget, () => setTimeout(applyState, 50));
}
if (useSpeedWidget && speedWidget) toggleWidgetState(useSpeedWidget, speedWidget, "speed");
if (useVolumeWidget && volumeWidget) toggleWidgetState(useVolumeWidget, volumeWidget, "volume");
if (usePitchWidget && pitchWidget) toggleWidgetState(usePitchWidget, pitchWidget, "pitch");
if (useEmotionWidget && emotionWidget) toggleWidgetState(useEmotionWidget, emotionWidget, "emotion");
if (useToneWidget && toneWidget) toggleWidgetState(useToneWidget, toneWidget, "tone");
if (useLanguageWidget && languageWidget) toggleWidgetState(useLanguageWidget, languageWidget, "language");
if (useVoiceWidget && voiceWidget) toggleWidgetState(useVoiceWidget, voiceWidget, "voice");
}
function acceleratorOptionsToggleHandler(acceleratorNode) {
// Find all "use" parameter widgets for Accelerator Options
const useCacheDistanceWidget = acceleratorNode.widgets.find(w => w.name === "useCacheDistance");
const cacheDistanceWidget = acceleratorNode.widgets.find(w => w.name === "cacheDistance");
const useTeaCacheDistanceWidget = acceleratorNode.widgets.find(w => w.name === "useTeaCacheDistance");
const teaCacheDistanceWidget = acceleratorNode.widgets.find(w => w.name === "teaCacheDistance");
const useDeepCacheOptionsWidget = acceleratorNode.widgets.find(w => w.name === "useDeepCacheOptions");
const deepCacheIntervalWidget = acceleratorNode.widgets.find(w => w.name === "deepCacheInterval");
const deepCacheBranchIdWidget = acceleratorNode.widgets.find(w => w.name === "deepCacheBranchId");
const useCacheStepsWidget = acceleratorNode.widgets.find(w => w.name === "useCacheSteps");
const cacheStartStepWidget = acceleratorNode.widgets.find(w => w.name === "cacheStartStep");
const cacheEndStepWidget = acceleratorNode.widgets.find(w => w.name === "cacheEndStep");
const useCachePercentageStepsWidget = acceleratorNode.widgets.find(w => w.name === "useCachePercentageSteps");
const cacheStartStepPercentageWidget = acceleratorNode.widgets.find(w => w.name === "cacheStartStepPercentage");
const cacheEndStepPercentageWidget = acceleratorNode.widgets.find(w => w.name === "cacheEndStepPercentage");
const useCacheMaxConsecutiveStepsWidget = acceleratorNode.widgets.find(w => w.name === "useCacheMaxConsecutiveSteps");
const cacheMaxConsecutiveStepsWidget = acceleratorNode.widgets.find(w => w.name === "cacheMaxConsecutiveSteps");
// Helper function to toggle widget enabled state (exact same pattern)
function toggleWidgetState(useWidget, paramWidgets, paramNames) {
if (!useWidget || !paramWidgets || paramWidgets.length === 0) return;
function toggleEnabled() {
const enabled = useWidget.value === true;
paramWidgets.forEach((paramWidget, idx) => {
if (!paramWidget) return;
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 = acceleratorNode.htmlElements?.widgetsContainer || acceleratorNode.htmlElements;
if (nodeElement && paramNames[idx]) {
const input = nodeElement.querySelector(`input[name="${paramNames[idx]}"], textarea[name="${paramNames[idx]}"], select[name="${paramNames[idx]}"]`);
if (input) {
input.disabled = !enabled;
input.style.opacity = enabled ? "1" : "0.5";
input.style.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
});
acceleratorNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
// Set up all toggle handlers
if (useCacheDistanceWidget && cacheDistanceWidget) {
toggleWidgetState(useCacheDistanceWidget, [cacheDistanceWidget], ["cacheDistance"]);
}
if (useTeaCacheDistanceWidget && teaCacheDistanceWidget) {
toggleWidgetState(useTeaCacheDistanceWidget, [teaCacheDistanceWidget], ["teaCacheDistance"]);
}
if (useDeepCacheOptionsWidget && deepCacheIntervalWidget && deepCacheBranchIdWidget) {
toggleWidgetState(useDeepCacheOptionsWidget, [deepCacheIntervalWidget, deepCacheBranchIdWidget], ["deepCacheInterval", "deepCacheBranchId"]);
}
if (useCacheStepsWidget && cacheStartStepWidget && cacheEndStepWidget) {
toggleWidgetState(useCacheStepsWidget, [cacheStartStepWidget, cacheEndStepWidget], ["cacheStartStep", "cacheEndStep"]);
}
if (useCachePercentageStepsWidget && cacheStartStepPercentageWidget && cacheEndStepPercentageWidget) {
toggleWidgetState(useCachePercentageStepsWidget, [cacheStartStepPercentageWidget, cacheEndStepPercentageWidget], ["cacheStartStepPercentage", "cacheEndStepPercentage"]);
}
if (useCacheMaxConsecutiveStepsWidget && cacheMaxConsecutiveStepsWidget) {
toggleWidgetState(useCacheMaxConsecutiveStepsWidget, [cacheMaxConsecutiveStepsWidget], ["cacheMaxConsecutiveSteps"]);
}
}
function bytedanceProviderSettingsToggleHandler(bytedanceNode) {
// Find all "use" parameter widgets for Bytedance Provider Settings
const useCameraFixedWidget = bytedanceNode.widgets.find(w => w.name === "useCameraFixed");
const cameraFixedWidget = bytedanceNode.widgets.find(w => w.name === "cameraFixed");
const useMaxSequentialImagesWidget = bytedanceNode.widgets.find(w => w.name === "useMaxSequentialImages");
const maxSequentialImagesWidget = bytedanceNode.widgets.find(w => w.name === "maxSequentialImages");
const useFastModeWidget = bytedanceNode.widgets.find(w => w.name === "useFastMode");
const fastModeWidget = bytedanceNode.widgets.find(w => w.name === "fastMode");
const useAudioWidget = bytedanceNode.widgets.find(w => w.name === "useAudio");
const audioWidget = bytedanceNode.widgets.find(w => w.name === "audio");
const useDraftWidget = bytedanceNode.widgets.find(w => w.name === "useDraft");
const draftWidget = bytedanceNode.widgets.find(w => w.name === "draft");
const useOptimizePromptModeWidget = bytedanceNode.widgets.find(w => w.name === "useOptimizePromptMode");
const optimizePromptModeWidget = bytedanceNode.widgets.find(w => w.name === "optimizePromptMode");
// Helper function to toggle widget enabled state (exact same pattern)
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.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
if (!paramWidget.inputEl) {
const nodeElement = bytedanceNode.htmlElements?.widgetsContainer || bytedanceNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
bytedanceNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
// Set up all toggle handlers
if (useCameraFixedWidget && cameraFixedWidget) {
toggleWidgetState(useCameraFixedWidget, cameraFixedWidget, "cameraFixed");
}
if (useMaxSequentialImagesWidget && maxSequentialImagesWidget) {
toggleWidgetState(useMaxSequentialImagesWidget, maxSequentialImagesWidget, "maxSequentialImages");
}
if (useFastModeWidget && fastModeWidget) {
toggleWidgetState(useFastModeWidget, fastModeWidget, "fastMode");
}
if (useAudioWidget && audioWidget) {
toggleWidgetState(useAudioWidget, audioWidget, "audio");
}
if (useDraftWidget && draftWidget) {
toggleWidgetState(useDraftWidget, draftWidget, "draft");
}
if (useOptimizePromptModeWidget && optimizePromptModeWidget) {
toggleWidgetState(useOptimizePromptModeWidget, optimizePromptModeWidget, "optimizePromptMode");
}
}
function ultralyticsProviderSettingsToggleHandler(ultralyticsNode) {
const useParamPairs = [
["useMaskBlur", "maskBlur"],
["useMaskPadding", "maskPadding"],
["useConfidence", "confidence"],
["usePositivePrompt", "positivePrompt"],
["useNegativePrompt", "negativePrompt"],
["useSteps", "steps"],
["useCFGScale", "CFGScale"],
["useStrength", "strength"],
["useInpaintSize", "inpaintSize"],
];
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.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
if (!paramWidget.inputEl) {
const nodeElement = ultralyticsNode.htmlElements?.widgetsContainer || ultralyticsNode.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";
}
}
}
ultralyticsNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
useParamPairs.forEach(([useName, paramName]) => {
const useWidget = ultralyticsNode.widgets.find(w => w.name === useName);
const paramWidget = ultralyticsNode.widgets.find(w => w.name === paramName);
if (useWidget && paramWidget) {
toggleWidgetState(useWidget, paramWidget, paramName);
}
});
}
function xaiProviderSettingsToggleHandler(xaiNode) {
const useQualityWidget = xaiNode.widgets.find(w => w.name === "useQuality");
const qualityWidget = xaiNode.widgets.find(w => w.name === "quality");
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.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
if (!paramWidget.inputEl) {
const nodeElement = xaiNode.htmlElements?.widgetsContainer || xaiNode.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";
}
}
}
xaiNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
if (useQualityWidget && qualityWidget) {
toggleWidgetState(useQualityWidget, qualityWidget, "quality");
}
}
function viduProviderSettingsToggleHandler(viduNode) {
const useAudioWidget = viduNode.widgets.find(w => w.name === "useAudio");
const audioWidget = viduNode.widgets.find(w => w.name === "audio");
const useBgmWidget = viduNode.widgets.find(w => w.name === "useBgm");
const bgmWidget = viduNode.widgets.find(w => w.name === "bgm");
const useStyleWidget = viduNode.widgets.find(w => w.name === "useStyle");
const styleWidget = viduNode.widgets.find(w => w.name === "style");
const useMovementAmplitudeWidget = viduNode.widgets.find(w => w.name === "useMovementAmplitude");
const movementAmplitudeWidget = viduNode.widgets.find(w => w.name === "movementAmplitude");
const useTemplateNameWidget = viduNode.widgets.find(w => w.name === "useTemplateName");
const templateNameWidget = viduNode.widgets.find(w => w.name === "templateName");
const useTemplateAreaWidget = viduNode.widgets.find(w => w.name === "useTemplateArea");
const templateAreaWidget = viduNode.widgets.find(w => w.name === "templateArea");
const useTemplateBeastWidget = viduNode.widgets.find(w => w.name === "useTemplateBeast");
const templateBeastWidget = viduNode.widgets.find(w => w.name === "templateBeast");
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 = viduNode.htmlElements?.widgetsContainer || viduNode.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";
}
}
}
viduNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
if (useAudioWidget && audioWidget) {
toggleWidgetState(useAudioWidget, audioWidget, "audio");
}
if (useBgmWidget && bgmWidget) {
toggleWidgetState(useBgmWidget, bgmWidget, "bgm");
}
if (useStyleWidget && styleWidget) {
toggleWidgetState(useStyleWidget, styleWidget, "style");
}
if (useMovementAmplitudeWidget && movementAmplitudeWidget) {
toggleWidgetState(useMovementAmplitudeWidget, movementAmplitudeWidget, "movementAmplitude");
}
if (useTemplateNameWidget && templateNameWidget) {
toggleWidgetState(useTemplateNameWidget, templateNameWidget, "templateName");
}
if (useTemplateAreaWidget && templateAreaWidget) {
toggleWidgetState(useTemplateAreaWidget, templateAreaWidget, "templateArea");
}
if (useTemplateBeastWidget && templateBeastWidget) {
toggleWidgetState(useTemplateBeastWidget, templateBeastWidget, "templateBeast");
}
}
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) {
if (!fontsNode?.widgets) return;
if (fontsNode._sourcefulProviderSettingsFontsToggleHandlerRegistered) return;
fontsNode._sourcefulProviderSettingsFontsToggleHandlerRegistered = true;
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);
}
for (let i = 1; i <= 2; i++) {
const useFontWidget = fontsNode.widgets.find(w => w && w.name === `useFont${i}`);
const fontUrlWidget = fontsNode.widgets.find(w => w && w.name === `fontUrl${i}`);
const textWidget = fontsNode.widgets.find(w => w && w.name === `text${i}`);
if (useFontWidget && fontUrlWidget && textWidget) {
toggleFontGroup(useFontWidget, fontUrlWidget, textWidget, `fontUrl${i}`, `text${i}`);
}
}
}
function threeDInferenceToggleHandler(node) {
const useSeedWidget = node.widgets.find(w => w && w.name === "useSeed");
const seedWidget = node.widgets.find(w => w && w.name === "seed");
const useOutputQualityWidget = node.widgets.find(w => w.name === "useOutputQuality");
const outputQualityWidget = node.widgets.find(w => w.name === "outputQuality");
if (useSeedWidget && seedWidget) {
function toggleSeed() {
const enabled = useSeedWidget.value === true;
toggleWidgetEnabled(seedWidget, enabled, node);
if (seedWidget.options && seedWidget.options.element) {
seedWidget.options.element.disabled = !enabled;
seedWidget.options.element.style.opacity = enabled ? "1" : "0.5";
seedWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
node.setDirtyCanvas(true);
}
setTimeout(toggleSeed, 100);
appendWidgetCB(useSeedWidget, () => setTimeout(toggleSeed, 50));
}
if (!useOutputQualityWidget || !outputQualityWidget) return;
function toggleEnabled() {
const enabled = useOutputQualityWidget.value === true;
toggleWidgetEnabled(outputQualityWidget, enabled, node);
node.setDirtyCanvas(true);
}
appendWidgetCB(useOutputQualityWidget, () => setTimeout(toggleEnabled, 50));
setTimeout(toggleEnabled, 100);
}
function threeDInferenceSettingsToggleHandler(node) {
const pairs = [
["useTextureSize", "textureSize"],
["useDecimationTarget", "decimationTarget"],
["useRemesh", "remesh"],
["useResolution", "resolution"],
["useImageAutoFix", "imageAutoFix"],
["useFaceLimit", "faceLimit"],
["useTexture", "texture"],
["usePbr", "pbr"],
["useTextureSeed", "textureSeed"],
["useTextureAlignment", "textureAlignment"],
["useTextureQuality", "textureQuality"],
["useAutoSize", "autoSize"],
["useOrientation", "orientation"],
["useQuad", "quad"],
["useCompress", "compress"],
["useSmartLowPoly", "smartLowPoly"],
["useGenerateParts", "generateParts"],
["useExportUv", "exportUv"],
["useGeometryQuality", "geometryQuality"],
["useOriginalAlpha", "originalAlpha"],
["useMaterial", "material"],
["useQuality", "quality"],
["usePolyCount", "polyCount"],
["useTaPose", "taPose"],
["useBoundingBox", "boundingBox"],
["useMeshMode", "meshMode"],
["useAddons", "addons"],
["useHdTexture", "hdTexture"],
["useMeshType", "meshType"],
["useTopology", "topology"],
["useDecimation", "decimation"],
["useSymmetry", "symmetry"],
["usePose", "pose"],
["useImageEnhancement", "imageEnhancement"],
["useRemoveLighting", "removeLighting"],
["useOrigin", "origin"],
["useModeration", "moderation"],
["useSavePreRemeshedModel", "savePreRemeshedModel"],
["useTexturePrompt", "texturePrompt"],
["useFaceCount", "faceCount"],
["useGenerateType", "generateType"],
["usePolygonType", "polygonType"],
["useGeometryOnly", "geometryOnly"],
["useRemeshBand", "remeshBand"],
["useRemeshProject", "remeshProject"],
["useTextureFormat", "textureFormat"],
["useAlphaMode", "alphaMode"],
];
pairs.forEach(([useName, paramName]) => {
const useW = node.widgets.find(w => w.name === useName);
const paramW = node.widgets.find(w => w.name === paramName);
if (!useW || !paramW) return;
function toggleEnabled() {
const enabled = useW.value === true;
toggleWidgetEnabled(paramW, enabled, node);
node.setDirtyCanvas(true);
}
appendWidgetCB(useW, () => setTimeout(toggleEnabled, 50));
setTimeout(toggleEnabled, 100);
});
}
function threeDInferenceSettingsLatToggleHandler(node) {
const pairs = [
["useGuidanceStrength", "guidanceStrength"],
["useGuidanceRescale", "guidanceRescale"],
["useSteps", "steps"],
["useRescaleT", "rescaleT"],
];
pairs.forEach(([useName, paramName]) => {
const useW = node.widgets.find(w => w.name === useName);
const paramW = node.widgets.find(w => w.name === paramName);
if (!useW || !paramW) return;
function toggleEnabled() {
const enabled = useW.value === true;
toggleWidgetEnabled(paramW, enabled, node);
node.setDirtyCanvas(true);
}
appendWidgetCB(useW, () => setTimeout(toggleEnabled, 50));
setTimeout(toggleEnabled, 100);
});
}
function threeDInferenceSettingsMeshClusterToggleHandler(node) {
const pairs = [
["useThresholdConeHalfAngleRad", "thresholdConeHalfAngleRad"],
["useRefineIterations", "refineIterations"],
["useGlobalIterations", "globalIterations"],
["useSmoothStrength", "smoothStrength"],
];
pairs.forEach(([useName, paramName]) => {
const useW = node.widgets.find(w => w.name === useName);
const paramW = node.widgets.find(w => w.name === paramName);
if (!useW || !paramW) return;
function toggleEnabled() {
const enabled = useW.value === true;
toggleWidgetEnabled(paramW, enabled, node);
node.setDirtyCanvas(true);
}
appendWidgetCB(useW, () => setTimeout(toggleEnabled, 50));
setTimeout(toggleEnabled, 100);
});
}
function threeDInferenceSettingsDracoCompressionToggleHandler(node) {
const pairs = [
["useEnabled", "enabled"],
["useLevel", "level"],
["useQuantizationPosition", "quantizationPosition"],
["useQuantizationNormal", "quantizationNormal"],
["useQuantizationTexCoord", "quantizationTexCoord"],
];
pairs.forEach(([useName, paramName]) => {
const useW = node.widgets.find(w => w.name === useName);
const paramW = node.widgets.find(w => w.name === paramName);
if (!useW || !paramW) return;
function toggleEnabled() {
const enabled = useW.value === true;
toggleWidgetEnabled(paramW, enabled, node);
node.setDirtyCanvas(true);
}
appendWidgetCB(useW, () => setTimeout(toggleEnabled, 50));
setTimeout(toggleEnabled, 100);
});
}
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");
const backgroundWidget = openaiNode.widgets.find(w => w.name === "background");
const useStyleWidget = openaiNode.widgets.find(w => w.name === "useStyle");
const styleWidget = openaiNode.widgets.find(w => w.name === "style");
// Helper function to toggle widget enabled state (exact same pattern, but handles COMBO)
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function toggleEnabled() {
// For COMBO widgets, check if value is "enable"
const enabled = useWidget.value === "enable" || useWidget.value === "Enable";
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;
}
// Handle dropdown widgets
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
paramWidget.disabled = !enabled;
if (!paramWidget.inputEl) {
const nodeElement = openaiNode.htmlElements?.widgetsContainer || openaiNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
openaiNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
// Set up all toggle handlers
if (useBackgroundWidget && backgroundWidget) {
toggleWidgetState(useBackgroundWidget, backgroundWidget, "background");
}
if (useStyleWidget && styleWidget) {
toggleWidgetState(useStyleWidget, styleWidget, "style");
}
}
function pixverseProviderSettingsToggleHandler(pixverseNode) {
// Find all "use" parameter widgets for Pixverse Provider Settings
const useEffectWidget = pixverseNode.widgets.find(w => w.name === "useEffect");
const effectWidget = pixverseNode.widgets.find(w => w.name === "effect");
const useCameraMovementWidget = pixverseNode.widgets.find(w => w.name === "useCameraMovement");
const cameraMovementWidget = pixverseNode.widgets.find(w => w.name === "cameraMovement");
const useStyleWidget = pixverseNode.widgets.find(w => w.name === "useStyle");
const styleWidget = pixverseNode.widgets.find(w => w.name === "style");
const useMotionModeWidget = pixverseNode.widgets.find(w => w.name === "useMotionMode");
const motionModeWidget = pixverseNode.widgets.find(w => w.name === "motionMode");
const useSoundEffectSwitchWidget = pixverseNode.widgets.find(w => w.name === "useSoundEffectSwitch");
const soundEffectSwitchWidget = pixverseNode.widgets.find(w => w.name === "soundEffectSwitch");
const useSoundEffectContentWidget = pixverseNode.widgets.find(w => w.name === "useSoundEffectContent");
const soundEffectContentWidget = pixverseNode.widgets.find(w => w.name === "soundEffectContent");
const useAudioWidget = pixverseNode.widgets.find(w => w.name === "useAudio");
const audioWidget = pixverseNode.widgets.find(w => w.name === "audio");
const useMultiClipWidget = pixverseNode.widgets.find(w => w.name === "useMultiClip");
const multiClipWidget = pixverseNode.widgets.find(w => w.name === "multiClip");
const useThinkingWidget = pixverseNode.widgets.find(w => w.name === "useThinking");
const thinkingWidget = pixverseNode.widgets.find(w => w.name === "thinking");
// Helper function to toggle widget enabled state (exact same pattern)
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;
}
// Handle dropdown widgets
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
paramWidget.disabled = !enabled;
if (!paramWidget.inputEl) {
const nodeElement = pixverseNode.htmlElements?.widgetsContainer || pixverseNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
pixverseNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
// Set up all toggle handlers
if (useEffectWidget && effectWidget) {
toggleWidgetState(useEffectWidget, effectWidget, "effect");
}
if (useCameraMovementWidget && cameraMovementWidget) {
toggleWidgetState(useCameraMovementWidget, cameraMovementWidget, "cameraMovement");
}
if (useStyleWidget && styleWidget) {
toggleWidgetState(useStyleWidget, styleWidget, "style");
}
if (useMotionModeWidget && motionModeWidget) {
toggleWidgetState(useMotionModeWidget, motionModeWidget, "motionMode");
}
if (useSoundEffectSwitchWidget && soundEffectSwitchWidget) {
toggleWidgetState(useSoundEffectSwitchWidget, soundEffectSwitchWidget, "soundEffectSwitch");
}
if (useSoundEffectContentWidget && soundEffectContentWidget) {
toggleWidgetState(useSoundEffectContentWidget, soundEffectContentWidget, "soundEffectContent");
}
if (useAudioWidget && audioWidget) {
toggleWidgetState(useAudioWidget, audioWidget, "audio");
}
if (useMultiClipWidget && multiClipWidget) {
toggleWidgetState(useMultiClipWidget, multiClipWidget, "multiClip");
}
if (useThinkingWidget && thinkingWidget) {
toggleWidgetState(useThinkingWidget, thinkingWidget, "thinking");
}
}
function lightricksProviderSettingsToggleHandler(lightricksNode) {
const useStartTimeWidget = lightricksNode.widgets.find(w => w.name === "useStartTime");
const startTimeWidget = lightricksNode.widgets.find(w => w.name === "startTime");
const useDurationWidget = lightricksNode.widgets.find(w => w.name === "useDuration");
const durationWidget = lightricksNode.widgets.find(w => w.name === "duration");
const useModeWidget = lightricksNode.widgets.find(w => w.name === "useMode");
const modeWidget = lightricksNode.widgets.find(w => w.name === "mode");
const useGenerateAudioWidget = lightricksNode.widgets.find(w => w.name === "useGenerateAudio");
const generateAudioWidget = lightricksNode.widgets.find(w => w.name === "generateAudio");
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;
}
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
paramWidget.disabled = !enabled;
if (!paramWidget.inputEl) {
const nodeElement = lightricksNode.htmlElements?.widgetsContainer || lightricksNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
lightricksNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
if (useStartTimeWidget && startTimeWidget) {
toggleWidgetState(useStartTimeWidget, startTimeWidget, "startTime");
}
if (useDurationWidget && durationWidget) {
toggleWidgetState(useDurationWidget, durationWidget, "duration");
}
if (useModeWidget && modeWidget) {
toggleWidgetState(useModeWidget, modeWidget, "mode");
}
if (useGenerateAudioWidget && generateAudioWidget) {
toggleWidgetState(useGenerateAudioWidget, generateAudioWidget, "generateAudio");
}
}
function imageInferenceToggleHandler(imageInferenceNode) {
// Find all "use" parameter widgets for Image Inference
const useStepsWidget = imageInferenceNode.widgets.find(w => w.name === "useSteps");
const stepsWidget = imageInferenceNode.widgets.find(w => w.name === "steps");
const useSeedWidget = imageInferenceNode.widgets.find(w => w.name === "useSeed");
const seedWidget = imageInferenceNode.widgets.find(w => w.name === "seed");
const useCFGScaleWidget = imageInferenceNode.widgets.find(w => w.name === "useCFGScale");
const cfgScaleWidget = imageInferenceNode.widgets.find(w => w.name === "cfgScale");
const useSchedulerWidget = imageInferenceNode.widgets.find(w => w.name === "useScheduler");
const schedulerWidget = imageInferenceNode.widgets.find(w => w.name === "scheduler");
const useClipSkipWidget = imageInferenceNode.widgets.find(w => w.name === "useClipSkip");
const clipSkipWidget = imageInferenceNode.widgets.find(w => w.name === "clipSkip");
const maskMarginWidget = imageInferenceNode.widgets.find(w => w.name === "Mask Margin");
const maskMarginValueWidget = imageInferenceNode.widgets.find(w => w.name === "maskMargin");
const useResolutionWidget = imageInferenceNode.widgets.find(w => w.name === "useResolution");
const resolutionWidget = imageInferenceNode.widgets.find(w => w.name === "resolution");
const useUpscaleFactorWidget = imageInferenceNode.widgets.find(w => w.name === "useUpscaleFactor");
const upscaleFactorWidget = imageInferenceNode.widgets.find(w => w.name === "upscaleFactor");
const dimensionsWidget = imageInferenceNode.widgets.find(w => w.name === "dimensions");
const widthWidget = imageInferenceNode.widgets.find(w => w.name === "width");
const heightWidget = imageInferenceNode.widgets.find(w => w.name === "height");
// Helper function to toggle widget enabled state (exact same pattern as videoInferenceDimensionsHandler)
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function toggleEnabled() {
const enabled = useWidget.value === true;
// Disable/enable widgets using inputEl if available (exact same pattern)
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;
}
// Also set widget property
paramWidget.disabled = !enabled;
// Fallback: try to find inputs via DOM if inputEl is not available
if (!paramWidget.inputEl) {
const nodeElement = imageInferenceNode.htmlElements?.widgetsContainer || imageInferenceNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
imageInferenceNode.setDirtyCanvas(true);
}
// Set up callback (exact same pattern as useCustomDimensions)
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
// Initial call to set initial state
setTimeout(toggleEnabled, 100);
}
// Set up all toggle handlers
if (useStepsWidget && stepsWidget) {
toggleWidgetState(useStepsWidget, stepsWidget, "steps");
}
if (useSeedWidget && seedWidget) {
toggleWidgetState(useSeedWidget, seedWidget, "seed");
}
if (useCFGScaleWidget && cfgScaleWidget) {
toggleWidgetState(useCFGScaleWidget, cfgScaleWidget, "cfgScale");
}
if (useSchedulerWidget && schedulerWidget) {
toggleWidgetState(useSchedulerWidget, schedulerWidget, "scheduler");
}
if (useClipSkipWidget && clipSkipWidget) {
toggleWidgetState(useClipSkipWidget, clipSkipWidget, "clipSkip");
}
// Handle Mask Margin (BOOLEAN widget)
if (maskMarginWidget && maskMarginValueWidget) {
toggleWidgetState(maskMarginWidget, maskMarginValueWidget, "maskMargin");
}
// Handle Resolution
if (useResolutionWidget && resolutionWidget) {
toggleWidgetState(useResolutionWidget, resolutionWidget, "resolution");
}
if (useUpscaleFactorWidget && upscaleFactorWidget) {
toggleWidgetState(useUpscaleFactorWidget, upscaleFactorWidget, "upscaleFactor");
}
// Handle Dimensions - disable width/height when dimensions is "None"
if (dimensionsWidget && widthWidget && heightWidget) {
function toggleDimensionsState() {
const dimensionsValue = dimensionsWidget.value;
const enabled = dimensionsValue !== "None";
// Toggle width widget
if (widthWidget.inputEl) {
widthWidget.inputEl.disabled = !enabled;
widthWidget.inputEl.style.opacity = enabled ? "1" : "0.5";
widthWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed";
widthWidget.inputEl.readOnly = !enabled;
}
widthWidget.disabled = !enabled;
// Toggle height widget
if (heightWidget.inputEl) {
heightWidget.inputEl.disabled = !enabled;
heightWidget.inputEl.style.opacity = enabled ? "1" : "0.5";
heightWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed";
heightWidget.inputEl.readOnly = !enabled;
}
heightWidget.disabled = !enabled;
// Fallback: try to find inputs via DOM if inputEl is not available
if (!widthWidget.inputEl || !heightWidget.inputEl) {
const nodeElement = imageInferenceNode.htmlElements?.widgetsContainer || imageInferenceNode.htmlElements;
if (nodeElement) {
const widthInput = nodeElement.querySelector(`input[name="width"]`);
const heightInput = nodeElement.querySelector(`input[name="height"]`);
if (widthInput) {
widthInput.disabled = !enabled;
widthInput.style.opacity = enabled ? "1" : "0.5";
widthInput.style.cursor = enabled ? "text" : "not-allowed";
widthInput.readOnly = !enabled;
}
if (heightInput) {
heightInput.disabled = !enabled;
heightInput.style.opacity = enabled ? "1" : "0.5";
heightInput.style.cursor = enabled ? "text" : "not-allowed";
heightInput.readOnly = !enabled;
}
}
}
imageInferenceNode.setDirtyCanvas(true);
}
appendWidgetCB(dimensionsWidget, () => {
setTimeout(toggleDimensionsState, 50);
});
setTimeout(toggleDimensionsState, 100);
}
}
function videoInferenceDimensionsHandler(videoInferenceNode) {
// Find "use" parameter widgets for Video Inference
const useDurationWidget = videoInferenceNode.widgets.find(w => w.name === "useDuration");
const durationWidget = videoInferenceNode.widgets.find(w => w.name === "duration");
const useFpsWidget = videoInferenceNode.widgets.find(w => w.name === "useFps");
const fpsWidget = videoInferenceNode.widgets.find(w => w.name === "fps");
const useSeedWidget = videoInferenceNode.widgets.find(w => w.name === "useSeed");
const seedWidget = videoInferenceNode.widgets.find(w => w.name === "seed");
const useStepsWidget = videoInferenceNode.widgets.find(w => w.name === "useSteps");
const stepsWidget = videoInferenceNode.widgets.find(w => w.name === "steps");
const useBatchSizeWidget = videoInferenceNode.widgets.find(w => w.name === "useBatchSize");
const batchSizeWidget = videoInferenceNode.widgets.find(w => w.name === "batchSize");
const useSchedulersWidget = videoInferenceNode.widgets.find(w => w.name === "useSchedulers");
const schedulerWidget = videoInferenceNode.widgets.find(w => w.name === "scheduler");
const useCFGScaleWidget = videoInferenceNode.widgets.find(w => w.name === "useCFGScale");
const cfgScaleWidget = videoInferenceNode.widgets.find(w => w.name === "cfgScale");
const useTtlWidget = videoInferenceNode.widgets.find(w => w.name === "useTtl");
const ttlWidget = videoInferenceNode.widgets.find(w => w.name === "ttl");
// Helper function to toggle widget enabled state
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function toggleEnabled() {
const enabled = useWidget.value === true;
// Disable/enable widgets using inputEl if available
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;
}
// Also set widget property
paramWidget.disabled = !enabled;
// Fallback: try to find inputs via DOM if inputEl is not available
if (!paramWidget.inputEl) {
const nodeElement = videoInferenceNode.htmlElements?.widgetsContainer || videoInferenceNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
videoInferenceNode.setDirtyCanvas(true);
}
// Set up callback
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
// Initial call to set initial state
setTimeout(toggleEnabled, 100);
}
// Set up all toggle handlers for "use" parameters
if (useDurationWidget && durationWidget) {
toggleWidgetState(useDurationWidget, durationWidget, "duration");
}
if (useFpsWidget && fpsWidget) {
toggleWidgetState(useFpsWidget, fpsWidget, "fps");
}
if (useSeedWidget && seedWidget) {
toggleWidgetState(useSeedWidget, seedWidget, "seed");
}
if (useStepsWidget && stepsWidget) {
toggleWidgetState(useStepsWidget, stepsWidget, "steps");
}
if (useBatchSizeWidget && batchSizeWidget) {
toggleWidgetState(useBatchSizeWidget, batchSizeWidget, "batchSize");
}
if (useSchedulersWidget && schedulerWidget) {
toggleWidgetState(useSchedulersWidget, schedulerWidget, "scheduler");
}
if (useCFGScaleWidget && cfgScaleWidget) {
toggleWidgetState(useCFGScaleWidget, cfgScaleWidget, "cfgScale");
}
if (useTtlWidget && ttlWidget) {
toggleWidgetState(useTtlWidget, ttlWidget, "ttl");
}
}
function videoModelSearchFilterHandler(videoModelSearchNode) {
const modelArchWidget = videoModelSearchNode.widgets.find(w => w.name === "Model Architecture");
const videoListWidget = videoModelSearchNode.widgets.find(w => w.name === "VideoList");
const widthWidget = videoModelSearchNode.widgets.find(w => w.name === "Width");
const heightWidget = videoModelSearchNode.widgets.find(w => w.name === "Height");
const useCustomDimensionsWidget = videoModelSearchNode.widgets.find(w => w.name === "useCustomDimensions");
const useResolutionWidget = videoModelSearchNode.widgets.find(w => w.name === "useResolution");
const resolutionWidget = videoModelSearchNode.widgets.find(w => w.name === "resolution");
if (!modelArchWidget || !videoListWidget) return;
const VIDEO_MODELS = {
"KlingAI": [
"klingai:1@2 (KlingAI V1.0 Pro)", "klingai:1@1 (KlingAI V1 Standard)",
"klingai:2@2 (KlingAI V1.5 Pro)", "klingai:2@1 (KlingAI V1.5 Standard)",
"klingai:3@1 (KlingAI V1.6 Standard)", "klingai:3@2 (KlingAI V1.6 Pro)",
"klingai:4@3 (KlingAI V2.1 Master)", "klingai:5@1 (KlingAI V2.1 Standard (I2V))",
"klingai:5@2 (KlingAI V2.1 Pro (I2V))", "klingai:5@3 (KlingAI V2.0 Master)",
"klingai:6@1 (KlingAI 2.5 Turbo Pro)",
"klingai:7@1 (KlingAI Lip-Sync)",
"klingai:kling@o1 (Kling VIDEO O1)",
"klingai:kling-video@2.6-pro (Kling VIDEO 2.6 Pro)",
"klingai:kling-video@3-pro (Kling VIDEO 3.0 Pro)",
"klingai:kling-video@3-standard (Kling VIDEO 3.0 Standard)",
"klingai:kling-video@3.0-turbo (Kling VIDEO 3.0 Turbo)",
"klingai:kling-video@3-4k (Kling VIDEO 3.0 4K)",
"klingai:kling-video@o3-pro (Kling VIDEO O3 Pro)",
"klingai:kling-video@o3-standard (Kling VIDEO O3 Standard)",
"klingai:kling-video@o3-4k (Kling VIDEO O3 4K)",
"klingai:avatar@2.0-standard (KlingAI Avatar 2.0 Standard)",
"klingai:avatar@2.0-pro (KlingAI Avatar 2.0 Pro)",
],
"Google": [
"google:2@0 (Veo 2.0)", "google:3@0 (Veo 3.0)", "google:3@1 (Veo 3.0 Fast)",
"google:3@2 (Veo 3.1)", "google:3@3 (Veo 3.1 Fast)",
"google:veo@3.1-lite (Veo 3.1 Lite)",
"google:gemini@omni-flash (Gemini Omni Flash)",
],
"Bytedance": [
"bytedance:2@1 (Seedance 1.0 Pro)", "bytedance:1@1 (Seedance 1.0 Lite)",
"bytedance:5@1 (OmniHuman 1)", "bytedance:5@2 (OmniHuman 1.5)",
"bytedance:seedance@1.5-pro (Seedance 1.5 Pro)",
"bytedance:seedance@2.0-fast (Seedance 2.0 Fast)",
"bytedance:seedance@2.0 (Seedance 2.0)",
"bytedance:seedance@2.0-mini (Seedance 2.0 Mini)",
],
"MiniMax": [
"minimax:1@1 (MiniMax 01 Base)", "minimax:2@1 (MiniMax 01 Director)",
"minimax:2@3 (MiniMax I2V 01 Live)", "minimax:3@1 (MiniMax 02 Hailuo)",
"minimax:4@1 (MiniMax Hailuo 2.3)", "minimax:4@2 (MiniMax Hailuo 2.3 Fast)",
],
"PixVerse": [
"pixverse:1@1 (PixVerse v3.5)", "pixverse:1@2 (PixVerse v4)",
"pixverse:1@3 (PixVerse v4.5)", "pixverse:1@5-fast (PixVerse v5 Fast)", "pixverse:1@6 (PixVerse v5.5)", "pixverse:1@7 (PixVerse v5.6)", "pixverse:1@8 (PixVerse v6)", "pixverse:lipsync@1 (PixVerse LipSync)", "pixverse:modify@0 (PixVerse Modify)",
],
"Vidu": [
"vidu:1@0 (Vidu Q1 Classic)", "vidu:1@1 (Vidu Q1)",
"vidu:1@5 (Vidu 1.5)", "vidu:2@0 (Vidu 2.0)",
"vidu:4@1 (Vidu Q3)",
"vidu:4@2 (Vidu Q3 Turbo)",
],
"Alibaba": [
"runware:200@1 (Wan 2.1 1.3B)", "runware:200@2 (Wan 2.1 14B)",
"runware:200@6 (Wan 2.2)",
"runware:200@8 (Wan 2.2 A14B Animate)",
"alibaba:wan@2.6 (Wan 2.6)",
"alibaba:wan@2.6-flash (Wan 2.6 Flash)",
"alibaba:wan@2.7 (Wan 2.7)",
"alibaba:happyhorse@1.0 (Alibaba Happy Horse 1.0)",
"alibaba:happyhorse@1.1 (Alibaba Happy Horse 1.1)",
],
"OpenAI": [
"openai:3@1 (OpenAI Sora 3.1)", "openai:3@0 (OpenAI Sora 3.0)",
],
"Lightricks": [
"lightricks:2@0 (LTX Fast)", "lightricks:2@1 (LTX Pro)",
"lightricks:3@1 (LTX-2 Retake)", "lightricks:ltx@2 (LTX-2)",
"lightricks:ltx@2.3 (LTX 2.3)", "lightricks:ltx@2.3-fast (LTX 2.3 Fast)",
"lightricks:ltx@2.3-open (LTX-2.3 Open)",
],
"Ovi": [
"runware:190@1 (Ovi)",
],
"Runway": [
"runway:aleph@2.0 (Runway Aleph 2.0)",
"runway:2@1 (Runway Aleph)",
"runway:1@1 (Runway Gen-4 Turbo)",
"runway:1@2 (Runway Gen-4.5)",
],
"Luma": [
"lumaai:1@1 (Luma Ray 1.6)",
"lumaai:2@1 (Luma Ray 2)",
"lumaai:2@2 (Luma Ray 2 Flash)",
"luma:ray@3.2 (Luma Ray 3.2)",
],
"Sync": [
"sync:lipsync-2@1 (Sync LipSync 2)",
"sync:lipsync-2-pro@1 (Sync LipSync 2 Pro)",
"sync:react-1@1 (Sync React-1)",
"sync:3@0 (Sync 3)",
],
"Bria": [
"bria:60@1 (Bria Video Eraser)",
],
"Creatify": [
"creatify:aurora@fast (Creatify Aurora Avatar Model API (720p))",
"creatify:aurora@0 (Creatify Aurora Avatar Model API (720p))",
],
"HeyGen": [
"heygen:avatar@4 (HeyGen Avatar IV)",
"heygen:video-agent@0 (HeyGen Video Agent)",
"heygen:avatar@5 (HeyGen Avatar V)",
],
"Hunyuan": [
"runware:hunyuanvideo@1.5 (HunyuanVideo-1.5)",
],
"Kandinsky": [
"runware:210@1 (Kandinsky 5.0 Lite)",
],
"xAI": [
"xai:grok-imagine@video-1.5 (Grok Imagine Video 1.5)",
"xai:grok-imagine@video-1.5-preview (Grok Imagine Video 1.5 Preview)",
"xai:grok-imagine@video (Grok Imagine Video)",
],
"VEED": [
"veed:fabric@1.0 (VEED Fabric 1.0)",
],
"Pruna": [
"prunaai:p-video@0 (P-Video)",
"prunaai:p-video@avatar (P-Video Avatar)",
"prunaai:p-video@animate (P-Video Animate)",
"prunaai:p-video@replace (P-Video Replace)",
],
"SkyReels": [
"skywork:skyreels@v4 (SkyReels V4)",
],
};
const MODEL_DIMENSIONS = {
"klingai:1@2": {"width": 1280, "height": 720},
"klingai:1@1": {"width": 1280, "height": 720},
"klingai:2@2": {"width": 1920, "height": 1080},
"klingai:2@1": {"width": 1280, "height": 720},
"klingai:3@1": {"width": 1280, "height": 720},
"klingai:3@2": {"width": 1920, "height": 1080},
"klingai:4@3": {"width": 1280, "height": 720},
"klingai:5@1": {"width": 1280, "height": 720},
"klingai:5@2": {"width": 1920, "height": 1080},
"klingai:5@3": {"width": 1920, "height": 1080},
"klingai:6@1": {"width": 1920, "height": 1080},
"klingai:7@1": {"width": 0, "height": 0},
"klingai:kling@o1": {"width": 1440, "height": 1440},
"klingai:kling-video@2.6-pro": {"width": 1920, "height": 1080},
"klingai:kling-video@3-pro": {"width": 1920, "height": 1080},
"klingai:kling-video@3-standard": {"width": 1920, "height": 1080},
"klingai:kling-video@3.0-turbo": {"width": 1920, "height": 1080},
"klingai:kling-video@3-4k": {"width": 3840, "height": 2160},
"klingai:kling-video@o3-pro": {"width": 1920, "height": 1080},
"klingai:kling-video@o3-standard": {"width": 1920, "height": 1080},
"klingai:kling-video@o3-4k": {"width": 3840, "height": 2160},
"klingai:avatar@2.0-standard": {"width": 0, "height": 0},
"klingai:avatar@2.0-pro": {"width": 0, "height": 0},
"google:2@0": {"width": 1280, "height": 720},
"google:3@0": {"width": 1280, "height": 720},
"google:3@1": {"width": 1280, "height": 720},
"google:3@2": {"width": 1280, "height": 720},
"google:3@3": {"width": 1280, "height": 720},
"google:veo@3.1-lite": {"width": 1280, "height": 720},
"google:gemini@omni-flash": {"width": 1280, "height": 720},
"bytedance:2@1": {"width": 864, "height": 480},
"bytedance:1@1": {"width": 864, "height": 480},
"bytedance:5@1": {"width": 1024, "height": 1024},
"bytedance:5@2": {"width": 1024, "height": 1024},
"bytedance:seedance@1.5-pro": {"width": 864, "height": 496},
"bytedance:seedance@2.0-fast": {"width": 864, "height": 496},
"bytedance:seedance@2.0": {"width": 864, "height": 496},
"bytedance:seedance@2.0-mini": {"width": 864, "height": 496},
"minimax:1@1": {"width": 1366, "height": 768},
"minimax:2@1": {"width": 1366, "height": 768},
"minimax:2@3": {"width": 1366, "height": 768},
"minimax:3@1": {"width": 1366, "height": 768},
"minimax:4@1": {"width": 1366, "height": 768},
"minimax:4@2": {"width": 1366, "height": 768},
"pixverse:1@1": {"width": 640, "height": 360},
"pixverse:1@2": {"width": 640, "height": 360},
"pixverse:1@3": {"width": 640, "height": 360},
"pixverse:1@5-fast": {"width": 640, "height": 360},
"pixverse:1@6": {"width": 640, "height": 360},
"pixverse:1@7": {"width": 640, "height": 360},
"pixverse:1@8": {"width": 640, "height": 360},
"pixverse:lipsync@1": {"width": 640, "height": 360},
"pixverse:modify@0": {"width": 640, "height": 360},
"vidu:1@0": {"width": 1920, "height": 1080},
"vidu:1@1": {"width": 1920, "height": 1080},
"vidu:1@5": {"width": 1920, "height": 1080},
"vidu:2@0": {"width": 1920, "height": 1080},
"vidu:4@1": {"width": 1920, "height": 1080},
"vidu:4@2": {"width": 1920, "height": 1080},
"runware:200@1": {"width": 853, "height": 480},
"runware:200@2": {"width": 853, "height": 480},
"runware:200@6": {"width": 1280, "height": 720},
"runware:200@8": {"width": 1104, "height": 832},
"alibaba:wan@2.6": {"width": 1280, "height": 720},
"alibaba:wan@2.6-flash": {"width": 1280, "height": 720},
"alibaba:wan@2.7": {"width": 1280, "height": 720},
"alibaba:happyhorse@1.0": {"width": 1280, "height": 720},
"alibaba:happyhorse@1.1": {"width": 1280, "height": 720},
"openai:3@1": {"width": 1280, "height": 720},
"openai:3@0": {"width": 1280, "height": 720},
"lightricks:2@0": {"width": 1920, "height": 1080},
"lightricks:2@1": {"width": 1920, "height": 1080},
"lightricks:3@1": {"width": 0, "height": 0},
"lightricks:ltx@2": {"width": 1024, "height": 1024},
"lightricks:ltx@2.3": {"width": 1920, "height": 1080},
"lightricks:ltx@2.3-fast": {"width": 1920, "height": 1080},
"lightricks:ltx@2.3-open": {"width": 1024, "height": 1024},
"runware:190@1": {"width": 0, "height": 0},
"runway:aleph@2.0": {"width": 0, "height": 0},
"runway:2@1": {"width": 1280, "height": 720},
"runway:1@1": {"width": 1280, "height": 720},
"runway:1@2": {"width": 1280, "height": 720},
"lumaai:1@1": {"width": 1080, "height": 720},
"lumaai:2@1": {"width": 1080, "height": 720},
"lumaai:2@2": {"width": 1080, "height": 720},
"luma:ray@3.2": {"width": 1280, "height": 720},
"sync:lipsync-2@1": {"width": 0, "height": 0},
"sync:lipsync-2-pro@1": {"width": 0, "height": 0},
"sync:react-1@1": {"width": 0, "height": 0},
"sync:3@0": {"width": 1280, "height": 720},
"bria:60@1": {"width": 1280, "height": 720},
"creatify:aurora@fast": {"width": 1280, "height": 720},
"creatify:aurora@0": {"width": 1280, "height": 720},
"runware:hunyuanvideo@1.5": {"width": 848, "height": 480},
"runware:210@1": {"width": 512, "height": 512},
"xai:grok-imagine@video-1.5": {"width": 480, "height": 480},
"xai:grok-imagine@video-1.5-preview": {"width": 480, "height": 480},
"xai:grok-imagine@video": {"width": 480, "height": 480},
"veed:fabric@1.0": {"width": 1280, "height": 720},
"prunaai:p-video@0": {"width": 1280, "height": 720},
"prunaai:p-video@avatar": {"width": 1280, "height": 720},
"prunaai:p-video@animate": {"width": 1280, "height": 720},
"prunaai:p-video@replace": {"width": 1280, "height": 720},
"heygen:avatar@4": {"width": 1280, "height": 720},
"heygen:video-agent@0": {"width": 1280, "height": 720},
"heygen:avatar@5": {"width": 1280, "height": 720},
"skywork:skyreels@v4": {"width": 1280, "height": 720},
};
const MODEL_RESOLUTIONS = {
"klingai:1@2": "720p",
"klingai:1@1": "720p",
"klingai:2@2": "1080p",
"klingai:2@1": "720p",
"klingai:3@1": "720p",
"klingai:3@2": "1080p",
"klingai:4@3": "720p",
"klingai:5@1": "720p",
"klingai:5@2": "1080p",
"klingai:5@3": "1080p",
"klingai:6@1": "1080p",
"klingai:7@1": null, // No resolution support
"klingai:kling@o1": null, // No standard resolution
"klingai:kling-video@2.6-pro": "1080p",
"klingai:kling-video@3-pro": "1080p",
"klingai:kling-video@3-standard": "1080p",
"klingai:kling-video@3.0-turbo": "1080p",
"klingai:kling-video@3-4k": null, // No 4K option in current resolution dropdown
"klingai:kling-video@o3-pro": "1080p",
"klingai:kling-video@o3-standard": "1080p",
"klingai:kling-video@o3-4k": null, // No 4K option in current resolution dropdown
"klingai:avatar@2.0-standard": null, // No resolution support
"klingai:avatar@2.0-pro": null, // No resolution support
"google:2@0": "720p",
"google:3@0": "720p",
"google:3@1": "720p",
"google:3@2": "720p",
"google:3@3": "720p",
"google:veo@3.1-lite": "720p",
"google:gemini@omni-flash": "720p",
"bytedance:2@1": "480p",
"bytedance:1@1": "480p",
"bytedance:5@1": null, // No resolution support
"bytedance:5@2": null, // No resolution support
"bytedance:seedance@1.5-pro": "480p",
"bytedance:seedance@2.0-fast": "480p",
"bytedance:seedance@2.0": "480p",
"bytedance:seedance@2.0-mini": "480p",
"minimax:1@1": "768p",
"minimax:2@1": "768p",
"minimax:2@3": "768p",
"minimax:3@1": "768p",
"minimax:4@1": "768p",
"minimax:4@2": "768p",
"pixverse:1@1": "360p",
"pixverse:1@2": "360p",
"pixverse:1@3": "360p",
"pixverse:1@5-fast": "360p",
"pixverse:1@6": "360p",
"pixverse:1@7": "360p",
"pixverse:1@8": "360p",
"pixverse:lipsync@1": "360p",
"pixverse:modify@0": "360p",
"vidu:1@0": "1080p",
"vidu:1@1": "1080p",
"vidu:1@5": "1080p",
"vidu:2@0": "1080p",
"vidu:4@1": "1080p",
"vidu:4@2": "1080p",
"runware:200@1": "480p",
"runware:200@2": "480p",
"runware:200@6": "720p",
"runware:200@8": "720p",
"alibaba:wan@2.6": "720p",
"alibaba:wan@2.6-flash": "720p",
"alibaba:wan@2.7": "720p",
"alibaba:happyhorse@1.0": "720p",
"alibaba:happyhorse@1.1": "720p",
"openai:3@1": "720p",
"openai:3@0": "720p",
"lightricks:2@0": "1080p",
"lightricks:2@1": "1080p",
"lightricks:3@1": null, // No resolution support
"lightricks:ltx@2": null, // No resolution support (fixed 1024x1024)
"lightricks:ltx@2.3": "1080p",
"lightricks:ltx@2.3-fast": "1080p",
"lightricks:ltx@2.3-open": null, // No resolution support (fixed 1024x1024)
"runware:190@1": null, // No resolution support
"runway:aleph@2.0": null, // Output ratio matches input video
"runway:2@1": "720p",
"runway:1@1": "720p",
"runway:1@2": "720p",
"lumaai:1@1": "720p",
"lumaai:2@1": "720p",
"lumaai:2@2": "720p",
"luma:ray@3.2": "720p",
"sync:lipsync-2@1": "720p",
"sync:lipsync-2-pro@1": "720p",
"sync:react-1@1": "720p",
"sync:3@0": "720p",
"bria:60@1": "720p",
"creatify:aurora@fast": "720p",
"creatify:aurora@0": "720p",
"runware:hunyuanvideo@1.5": "480p",
"runware:210@1": null, // No resolution support (fixed 512x512)
"xai:grok-imagine@video-1.5": "480p",
"xai:grok-imagine@video-1.5-preview": "480p",
"xai:grok-imagine@video": "480p",
"veed:fabric@1.0": "720p",
"prunaai:p-video@0": "720p",
"prunaai:p-video@avatar": "720p",
"prunaai:p-video@animate": "720p",
"prunaai:p-video@replace": "720p",
"heygen:avatar@4": "720p",
"heygen:video-agent@0": "720p",
"heygen:avatar@5": "720p",
"skywork:skyreels@v4": "720p",
};
const DEFAULT_DIMENSIONS = {"width": 1024, "height": 576};
function setWidthHeightEnabled(enabled) {
if (!widthWidget || !heightWidget) return;
[widthWidget, heightWidget].forEach(widget => {
widget.disabled = !enabled;
if (widget.inputEl) {
widget.inputEl.disabled = !enabled;
widget.inputEl.style.opacity = enabled ? "1" : "0.5";
widget.inputEl.style.cursor = enabled ? "text" : "not-allowed";
widget.inputEl.readOnly = !enabled;
}
});
}
function updateDimensions() {
if (!widthWidget || !heightWidget || !videoListWidget) return;
const selectedModel = videoListWidget.value;
if (!selectedModel) return;
const useCustomDimensionsValue = useCustomDimensionsWidget ? useCustomDimensionsWidget.value : "Model Default";
// Handle "Disabled" option - disable widgets and set to 0 (but Python will use None in dict)
if (useCustomDimensionsValue === "Disabled") {
setWidthHeightEnabled(false);
if (widthWidget.callback) widthWidget.callback(0, "customSetOperation");
widthWidget.value = 0;
if (heightWidget.callback) heightWidget.callback(0, "customSetOperation");
heightWidget.value = 0;
videoModelSearchNode.setDirtyCanvas(true);
return;
}
// Handle "Model Default" option - disable widgets and use model defaults
if (useCustomDimensionsValue === "Model Default") {
setWidthHeightEnabled(false);
} else if (useCustomDimensionsValue === "Custom") {
// Handle "Custom" option - enable widgets
setWidthHeightEnabled(true);
}
const modelCode = selectedModel.split(" (")[0];
const dims = MODEL_DIMENSIONS[modelCode] || DEFAULT_DIMENSIONS;
// Only update dimensions if "Model Default" is selected (widgets are disabled but we show the values)
if (useCustomDimensionsValue === "Model Default") {
if (dims.width === 0 && dims.height === 0) {
// Set to None when dimensions are 0,0
if (widthWidget.callback) widthWidget.callback(null, "customSetOperation");
if (heightWidget.callback) heightWidget.callback(null, "customSetOperation");
videoModelSearchNode.setDirtyCanvas(true);
} else if (dims.width !== 0 && dims.height !== 0) {
if (widthWidget.callback) widthWidget.callback(dims.width, "customSetOperation");
if (heightWidget.callback) heightWidget.callback(dims.height, "customSetOperation");
videoModelSearchNode.setDirtyCanvas(true);
}
}
// For "Custom" mode, don't update - let user set their own values
// For "Disabled" mode, already handled above (set to None and disabled)
// Update resolution based on selected model
if (resolutionWidget && useResolutionWidget) {
const modelCode = selectedModel.split(" (")[0];
const modelResolution = MODEL_RESOLUTIONS[modelCode];
// If model supports resolution
if (modelResolution !== null && modelResolution !== undefined) {
// Enable useResolution checkbox
if (useResolutionWidget.inputEl) {
useResolutionWidget.inputEl.disabled = false;
useResolutionWidget.inputEl.style.opacity = "1";
}
useResolutionWidget.disabled = false;
// Only update resolution value if useResolution is enabled
if (useResolutionWidget.value === true) {
// Set resolution value to model's default
if (resolutionWidget.callback) resolutionWidget.callback(modelResolution, "customSetOperation");
resolutionWidget.value = modelResolution;
}
} else {
// Model doesn't support resolution, disable useResolution checkbox and resolution dropdown
if (useResolutionWidget.callback) useResolutionWidget.callback(false, "customSetOperation");
useResolutionWidget.value = false;
// Disable useResolution checkbox
if (useResolutionWidget.inputEl) {
useResolutionWidget.inputEl.disabled = true;
useResolutionWidget.inputEl.style.opacity = "0.5";
}
useResolutionWidget.disabled = true;
// Disable resolution dropdown
if (resolutionWidget.inputEl) {
resolutionWidget.inputEl.disabled = true;
resolutionWidget.inputEl.style.opacity = "0.5";
resolutionWidget.inputEl.style.cursor = "not-allowed";
}
resolutionWidget.disabled = true;
}
videoModelSearchNode.setDirtyCanvas(true);
}
}
function filterModelList() {
const selectedArch = modelArchWidget.value;
const selectedArchNormalized = selectedArch === "Wan" ? "Alibaba" : selectedArch;
let filteredModels = [];
if (selectedArchNormalized === "All") {
Object.values(VIDEO_MODELS).forEach(models => filteredModels.push(...models));
} else if (VIDEO_MODELS[selectedArchNormalized]) {
filteredModels = VIDEO_MODELS[selectedArchNormalized];
}
if (filteredModels.length > 0) {
const currentValue = videoListWidget.value;
videoListWidget.options.values = filteredModels;
if (!filteredModels.includes(currentValue)) {
videoListWidget.value = filteredModels[0];
}
updateDimensions();
videoModelSearchNode.setDirtyCanvas(true);
}
}
appendWidgetCB(modelArchWidget, filterModelList);
if (videoListWidget) {
appendWidgetCB(videoListWidget, updateDimensions);
}
if (useCustomDimensionsWidget) {
appendWidgetCB(useCustomDimensionsWidget, () => {
updateDimensions();
});
}
// Handle useResolution toggle
if (useResolutionWidget && resolutionWidget) {
function toggleResolutionState() {
// Check if current model supports resolution
const selectedModel = videoListWidget ? videoListWidget.value : null;
if (!selectedModel) return;
const modelCode = selectedModel.split(" (")[0];
const modelResolution = MODEL_RESOLUTIONS[modelCode];
// Only enable resolution if model supports it and useResolution is enabled
const enabled = useResolutionWidget.value === true && modelResolution !== null && modelResolution !== undefined;
if (resolutionWidget.inputEl) {
resolutionWidget.inputEl.disabled = !enabled;
resolutionWidget.inputEl.style.opacity = enabled ? "1" : "0.5";
resolutionWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed";
}
resolutionWidget.disabled = !enabled;
// Fallback: try to find input via DOM if inputEl is not available
if (!resolutionWidget.inputEl) {
const nodeElement = videoModelSearchNode.htmlElements?.widgetsContainer || videoModelSearchNode.htmlElements;
if (nodeElement) {
const input = nodeElement.querySelector(`select[name="resolution"]`);
if (input) {
input.disabled = !enabled;
input.style.opacity = enabled ? "1" : "0.5";
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
videoModelSearchNode.setDirtyCanvas(true);
}
appendWidgetCB(useResolutionWidget, () => {
setTimeout(toggleResolutionState, 50);
});
// Also update when model changes
if (videoListWidget) {
appendWidgetCB(videoListWidget, () => {
setTimeout(toggleResolutionState, 50);
});
}
setTimeout(toggleResolutionState, 100);
}
filterModelList();
updateDimensions();
}
function textModelSearchFilterHandler(textModelSearchNode) {
const modelProviderWidget = textModelSearchNode.widgets.find(w => w.name === "Model Provider");
const textListWidget = textModelSearchNode.widgets.find(w => w.name === "TextList");
if (!modelProviderWidget || !textListWidget) return;
const TEXT_MODELS = {
"MiniMax": [
"minimax:m2.7@0 (MiniMax-M2.7)",
"minimax:m2.7@highspeed (MiniMax-M2.7 Highspeed)",
"minimax:m2.5@0 (MiniMax-M2.5)",
],
"OpenAI": [
"openai:gpt@5.4 (GPT-5.4)",
"openai:gpt@5.4-pro (GPT-5.4 Pro)",
"openai:gpt@5.4-mini (GPT-5.4 Mini)",
"openai:gpt@5.4-nano (GPT-5.4 Nano)",
],
"Anthropic": [
"anthropic:claude@opus-4.7 (Claude Opus 4.7)",
"anthropic:claude@sonnet-4.6 (Claude Sonnet 4.6)",
"anthropic:claude@haiku-4.5 (Claude Haiku 4.5)",
],
"Google": [
"google:gemini@3-flash (Gemini 3 Flash)",
],
"MoonshotAI": [
"moonshotai:kimi@k2.6 (Kimi K2.6)",
],
"Zai": [
"zai-glm-5-1 (ZAI GLM 5.1)",
],
};
function filterModelList() {
const selectedProvider = modelProviderWidget.value;
let filteredModels = [];
if (selectedProvider === "All") {
Object.values(TEXT_MODELS).forEach(models => filteredModels.push(...models));
} else if (TEXT_MODELS[selectedProvider]) {
filteredModels = TEXT_MODELS[selectedProvider];
}
if (filteredModels.length > 0) {
const currentValue = textListWidget.value;
textListWidget.options.values = filteredModels;
if (!filteredModels.includes(currentValue)) {
textListWidget.value = filteredModels[0];
}
textModelSearchNode.setDirtyCanvas(true);
}
}
appendWidgetCB(modelProviderWidget, filterModelList);
filterModelList();
}
function threeDModelSearchFilterHandler(threeDModelSearchNode) {
const modelArchWidget = threeDModelSearchNode.widgets.find(w => w.name === "Model Architecture");
const threeDListWidget = threeDModelSearchNode.widgets.find(w => w.name === "ThreeDList");
if (!modelArchWidget || !threeDListWidget) return;
const THREED_MODELS = {
"Tencent": [
"tencent:hunyuan-3d@3.1-pro (Tencent Hunyuan 3D 3.1 Pro)",
"tencent:hunyuan-3d@3.1-rapid (Tencent Hunyuan 3D 3.1 Rapid)",
],
"Meta": [
"meta:sam@3d (Meta SAM 3D)",
],
"Microsoft": [
"microsoft:trellis-2@4b (TRELLIS.2)",
],
"Tripo": [
"tripo:v3.1@0 (Tripo 3D v3.1)",
],
"Hyper3D": [
"hyper3d:rodin@gen-1 (Rodin Gen-1)",
"hyper3d:rodin@gen-2 (Rodin Gen-2)",
],
"Meshy": [
"meshy:meshy@6 (Meshy 6)",
],
};
function filterModelList() {
const selectedArch = modelArchWidget.value;
let filteredModels = [];
if (selectedArch === "All") {
Object.values(THREED_MODELS).forEach(models => filteredModels.push(...models));
} else if (THREED_MODELS[selectedArch]) {
filteredModels = THREED_MODELS[selectedArch];
}
if (filteredModels.length > 0) {
const currentValue = threeDListWidget.value;
threeDListWidget.options.values = filteredModels;
if (!filteredModels.includes(currentValue)) {
threeDListWidget.value = filteredModels[0];
}
threeDModelSearchNode.setDirtyCanvas(true);
}
}
appendWidgetCB(modelArchWidget, filterModelList);
filterModelList();
}
function audioModelSearchFilterHandler(audioModelSearchNode) {
const modelProviderWidget = audioModelSearchNode.widgets.find(w => w.name === "Model Provider");
const audioListWidget = audioModelSearchNode.widgets.find(w => w.name === "AudioList");
if (!modelProviderWidget || !audioListWidget) return;
const AUDIO_MODELS = {
"ElevenLabs": [
"elevenlabs:1@1 (ElevenLabs Multilingual v2)",
"elevenlabs:2@1 (ElevenLabs Multilingual v2 Turbo)",
"elevenlabs:3@1 (ElevenLabs Monolingual v1)",
],
"KlingAI": [
"klingai:8@1 (KlingAI Audio)",
],
"Mirelo": [
"mirelo:1@1 (Mirelo SFX 1.5)",
],
"Ace": [
"runware:ace-step@0 (ACE Step v1 3.5B)",
"runware:ace-step@v1.5-base (ACE-Step v1.5 Base)",
"runware:ace-step@v1.5-turbo (ACE-Step v1.5 Turbo)",
"runware:ace-step@v1.5-xl-base (ACE-Step v1.5 XL Base)",
"runware:ace-step@v1.5-xl-turbo (ACE-Step v1.5 XL Turbo)",
"runware:ace-step@v1.5-xl-sft (ACE-Step v1.5 XL SFT)",
],
"Alibaba": [
"alibaba:qwen@3-tts-1.7b-voicedesign (Qwen3 TTS 1.7B Voice Design)",
"alibaba:qwen@3-tts-1.7b-customvoice (Qwen3 TTS 1.7B Custom Voice)",
"alibaba:qwen@3-tts-1.7b-base (Qwen3 TTS 1.7B Base)",
],
"Bytedance": [
"bytedance:seed-audio@1.0 (Seed Audio 1.0)",
],
"Dia": [
"runware:dia@v1.0 (Dia 1.6B)",
"runware:dia2@2b (Dia2 2B)",
],
"xAI": [
"xai:voice@tts (xAI TTS)",
],
"MiniMax": [
"minimax:speech@2.8 (MiniMax Speech 2.8)",
"minimax:music@cover (MiniMax Music Cover)",
"minimax:music@2.6 (MiniMax Music 2.6)",
],
"Inworld": [
"inworld:tts@2 (Inworld Realtime TTS 2)",
"inworld:tts@1.5-mini (Inworld TTS-1.5 Mini)",
"inworld:tts@1.5-max (Inworld TTS-1.5 Max)",
],
"Google": [
"google:gemini@3.1-flash-tts (Gemini 3.1 Flash TTS)",
],
"Fish": [
"fishaudio:s2.1@pro (Fish Audio S2.1 Pro)",
],
};
function filterModelList() {
const selectedProvider = modelProviderWidget.value;
let filteredModels = [];
if (selectedProvider === "All") {
Object.values(AUDIO_MODELS).forEach(models => filteredModels.push(...models));
} else if (AUDIO_MODELS[selectedProvider]) {
filteredModels = AUDIO_MODELS[selectedProvider];
}
if (filteredModels.length > 0) {
const currentValue = audioListWidget.value;
audioListWidget.options.values = filteredModels;
if (!filteredModels.includes(currentValue)) {
audioListWidget.value = filteredModels[0];
}
audioModelSearchNode.setDirtyCanvas(true);
}
}
appendWidgetCB(modelProviderWidget, filterModelList);
filterModelList();
}
function vectorizeModelSearchFilterHandler(vectorizeNode) {
const modelArchWidget = vectorizeNode.widgets.find(w => w.name === "Model Architecture");
const vectorListWidget = vectorizeNode.widgets.find(w => w.name === "Vector Model List");
if (!modelArchWidget || !vectorListWidget) return;
const VECTORIZE_MODELS = {
"Recraft": [
"recraft:1@1 (Recraft 1)",
"recraft:v4-pro@vector (Recraft V4 Pro Vector)",
"recraft:v4@vector (Recraft V4 Vector)",
],
"Picsart": [
"picsart:1@1 (Picsart 1)",
],
};
function filterModelList() {
const selectedArch = modelArchWidget.value;
let filteredModels = [];
if (selectedArch === "All") {
Object.values(VECTORIZE_MODELS).forEach(models => filteredModels.push(...models));
} else if (VECTORIZE_MODELS[selectedArch]) {
filteredModels = VECTORIZE_MODELS[selectedArch];
}
if (filteredModels.length > 0) {
const currentValue = vectorListWidget.value;
vectorListWidget.options.values = filteredModels;
if (!filteredModels.includes(currentValue)) {
vectorListWidget.value = filteredModels[0];
}
vectorizeNode.setDirtyCanvas(true);
}
}
appendWidgetCB(modelArchWidget, filterModelList);
filterModelList();
}
function vectorizeToggleHandler(vectorizeNode) {
const usePositivePromptWidget = vectorizeNode.widgets.find(w => w.name === "Use positivePrompt");
const positivePromptWidget = vectorizeNode.widgets.find(w => w.name === "positivePrompt");
const dimensionsWidget = vectorizeNode.widgets.find(w => w.name === "dimensions");
const widthWidget = vectorizeNode.widgets.find(w => w.name === "width");
const heightWidget = vectorizeNode.widgets.find(w => w.name === "height");
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function applyState() {
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";
}
}
applyState();
appendWidgetCB(useWidget, applyState);
}
if (usePositivePromptWidget && positivePromptWidget) {
toggleWidgetState(usePositivePromptWidget, positivePromptWidget, "positivePrompt");
}
// Disable width/height when dimensions is "None" (same as image inference)
if (dimensionsWidget && widthWidget && heightWidget) {
function toggleDimensionsState() {
const dimensionsValue = dimensionsWidget.value;
const enabled = dimensionsValue !== "None";
if (widthWidget.inputEl) {
widthWidget.inputEl.disabled = !enabled;
widthWidget.inputEl.style.opacity = enabled ? "1" : "0.5";
widthWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed";
widthWidget.inputEl.readOnly = !enabled;
}
widthWidget.disabled = !enabled;
if (heightWidget.inputEl) {
heightWidget.inputEl.disabled = !enabled;
heightWidget.inputEl.style.opacity = enabled ? "1" : "0.5";
heightWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed";
heightWidget.inputEl.readOnly = !enabled;
}
heightWidget.disabled = !enabled;
vectorizeNode.setDirtyCanvas(true);
}
appendWidgetCB(dimensionsWidget, () => {
setTimeout(toggleDimensionsState, 50);
});
setTimeout(toggleDimensionsState, 100);
}
}
function klingProviderSettingsToggleHandler(klingNode) {
// Find all "use" parameter widgets for KlingAI Provider Settings (EXACT same pattern as imageInferenceToggleHandler)
const useCameraControlWidget = klingNode.widgets.find(w => w.name === "useCameraControl");
const cameraControlWidget = klingNode.widgets.find(w => w.name === "cameraControl");
const useSoundVolumeWidget = klingNode.widgets.find(w => w.name === "useSoundVolume");
const soundVolumeWidget = klingNode.widgets.find(w => w.name === "soundVolume");
const useOriginalAudioVolumeWidget = klingNode.widgets.find(w => w.name === "useOriginalAudioVolume");
const originalAudioVolumeWidget = klingNode.widgets.find(w => w.name === "originalAudioVolume");
const useSoundEffectPromptWidget = klingNode.widgets.find(w => w.name === "useSoundEffectPrompt");
const soundEffectPromptWidget = klingNode.widgets.find(w => w.name === "soundEffectPrompt");
const useBgmPromptWidget = klingNode.widgets.find(w => w.name === "useBgmPrompt");
const bgmPromptWidget = klingNode.widgets.find(w => w.name === "bgmPrompt");
const useAsmrModeWidget = klingNode.widgets.find(w => w.name === "useAsmrMode");
const asmrModeWidget = klingNode.widgets.find(w => w.name === "asmrMode");
const useKeepOriginalSoundWidget = klingNode.widgets.find(w => w.name === "useKeepOriginalSound");
const keepOriginalSoundWidget = klingNode.widgets.find(w => w.name === "keepOriginalSound");
const useSoundWidget = klingNode.widgets.find(w => w.name === "useSound");
const soundWidget = klingNode.widgets.find(w => w.name === "sound");
const useCharacterOrientationWidget = klingNode.widgets.find(w => w.name === "useCharacterOrientation");
const characterOrientationWidget = klingNode.widgets.find(w => w.name === "characterOrientation");
const useMultipromptWidget = klingNode.widgets.find(w => w.name === "useMultiprompt");
// Helper function to toggle widget enabled state (EXACT same pattern as imageInferenceToggleHandler)
// Callers guard with if (useX && xWidget) before invoking
function toggleWidgetState(useWidget, paramWidget, paramName) {
function toggleEnabled() {
const enabled = useWidget.value === true;
// Disable/enable widgets using inputEl if available (exact same pattern)
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;
}
// Also set widget property
paramWidget.disabled = !enabled;
// Fallback: try to find inputs via DOM if inputEl is not available
if (!paramWidget.inputEl) {
const nodeElement = klingNode.htmlElements?.widgetsContainer || klingNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
klingNode.setDirtyCanvas(true);
}
// Set up callback (exact same pattern as imageInferenceToggleHandler)
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
// Initial call to set initial state (exact same pattern)
setTimeout(toggleEnabled, 100);
}
// Set up all toggle handlers (exact same pattern as imageInferenceToggleHandler)
if (useCameraControlWidget && cameraControlWidget) {
toggleWidgetState(useCameraControlWidget, cameraControlWidget, "cameraControl");
}
if (useSoundVolumeWidget && soundVolumeWidget) {
toggleWidgetState(useSoundVolumeWidget, soundVolumeWidget, "soundVolume");
}
if (useOriginalAudioVolumeWidget && originalAudioVolumeWidget) {
toggleWidgetState(useOriginalAudioVolumeWidget, originalAudioVolumeWidget, "originalAudioVolume");
}
if (useSoundEffectPromptWidget && soundEffectPromptWidget) {
toggleWidgetState(useSoundEffectPromptWidget, soundEffectPromptWidget, "soundEffectPrompt");
}
if (useBgmPromptWidget && bgmPromptWidget) {
toggleWidgetState(useBgmPromptWidget, bgmPromptWidget, "bgmPrompt");
}
if (useAsmrModeWidget && asmrModeWidget) {
toggleWidgetState(useAsmrModeWidget, asmrModeWidget, "asmrMode");
}
if (useKeepOriginalSoundWidget && keepOriginalSoundWidget) {
toggleWidgetState(useKeepOriginalSoundWidget, keepOriginalSoundWidget, "keepOriginalSound");
}
if (useSoundWidget && soundWidget) {
toggleWidgetState(useSoundWidget, soundWidget, "sound");
}
if (useCharacterOrientationWidget && characterOrientationWidget) {
toggleWidgetState(useCharacterOrientationWidget, characterOrientationWidget, "characterOrientation");
}
// Toggle MultiPrompt Segment input slots when useMultiprompt changes
if (useMultipromptWidget) {
function toggleMultipromptInputs() {
const enabled = useMultipromptWidget.value === true;
klingNode.inputs?.forEach(inp => {
if (inp?.name?.startsWith("MultiPrompt Segment")) {
inp.disabled = !enabled;
if (inp.domElement) {
inp.domElement.style.opacity = enabled ? "1" : "0.4";
inp.domElement.style.pointerEvents = enabled ? "auto" : "none";
}
}
});
klingNode.setDirtyCanvas(true);
}
appendWidgetCB(useMultipromptWidget, () => setTimeout(toggleMultipromptInputs, 50));
setTimeout(toggleMultipromptInputs, 100);
}
}
function alibabaProviderSettingsToggleHandler(alibabaNode) {
// Find all "use" parameter widgets for Alibaba Provider Settings
const usePromptEnhancerWidget = alibabaNode.widgets.find(w => w.name === "usePromptEnhancer");
const promptEnhancerWidget = alibabaNode.widgets.find(w => w.name === "promptEnhancer");
const usePromptExtendWidget = alibabaNode.widgets.find(w => w.name === "usePromptExtend");
const promptExtendWidget = alibabaNode.widgets.find(w => w.name === "promptExtend");
const useAudioWidget = alibabaNode.widgets.find(w => w.name === "useAudio");
const audioWidget = alibabaNode.widgets.find(w => w.name === "audio");
const useShotTypeWidget = alibabaNode.widgets.find(w => w.name === "useShotType");
const shotTypeWidget = alibabaNode.widgets.find(w => w.name === "shotType");
// Helper function to toggle widget enabled state
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 = alibabaNode.htmlElements?.widgetsContainer || alibabaNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
alibabaNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
// Special handler for shotType - depends on both usePromptExtend AND promptExtend being true
function toggleShotTypeEnabled() {
if (!useShotTypeWidget || !shotTypeWidget || !usePromptExtendWidget || !promptExtendWidget) return;
const usePromptExtendEnabled = usePromptExtendWidget.value === true;
const promptExtendValue = promptExtendWidget.value === true;
const useShotTypeEnabled = useShotTypeWidget.value === true;
// shotType is enabled only if: useShotType is enabled AND usePromptExtend is enabled AND promptExtend is true
const enabled = useShotTypeEnabled && usePromptExtendEnabled && promptExtendValue;
if (shotTypeWidget.inputEl) {
shotTypeWidget.inputEl.disabled = !enabled;
shotTypeWidget.inputEl.style.opacity = enabled ? "1" : "0.5";
shotTypeWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed";
shotTypeWidget.inputEl.readOnly = !enabled;
}
shotTypeWidget.disabled = !enabled;
if (!shotTypeWidget.inputEl) {
const nodeElement = alibabaNode.htmlElements?.widgetsContainer || alibabaNode.htmlElements;
if (nodeElement) {
const input = nodeElement.querySelector(`input[name="shotType"], select[name="shotType"]`);
if (input) {
input.disabled = !enabled;
input.style.opacity = enabled ? "1" : "0.5";
input.style.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
alibabaNode.setDirtyCanvas(true);
}
// Set up toggle handlers
if (usePromptEnhancerWidget && promptEnhancerWidget) {
toggleWidgetState(usePromptEnhancerWidget, promptEnhancerWidget, "promptEnhancer");
}
if (usePromptExtendWidget && promptExtendWidget) {
toggleWidgetState(usePromptExtendWidget, promptExtendWidget, "promptExtend");
// Also listen to promptExtend value changes to update shotType
appendWidgetCB(promptExtendWidget, () => {
setTimeout(toggleShotTypeEnabled, 50);
});
}
if (useAudioWidget && audioWidget) {
toggleWidgetState(useAudioWidget, audioWidget, "audio");
}
if (useShotTypeWidget && shotTypeWidget) {
// Listen to useShotType changes
appendWidgetCB(useShotTypeWidget, () => {
setTimeout(toggleShotTypeEnabled, 50);
});
// Also listen to usePromptExtend changes
if (usePromptExtendWidget) {
appendWidgetCB(usePromptExtendWidget, () => {
setTimeout(toggleShotTypeEnabled, 50);
});
}
// Initial state
setTimeout(toggleShotTypeEnabled, 100);
}
}
function mireloProviderSettingsToggleHandler(mireloNode) {
// Find all "use" parameter widgets for Mirelo Provider Settings
const useStartOffsetWidget = mireloNode.widgets.find(w => w.name === "useStartOffset");
const startOffsetWidget = mireloNode.widgets.find(w => w.name === "startOffset");
// Helper function to toggle widget enabled state
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 = mireloNode.htmlElements?.widgetsContainer || mireloNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
mireloNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
// Set up toggle handler
if (useStartOffsetWidget && startOffsetWidget) {
toggleWidgetState(useStartOffsetWidget, startOffsetWidget, "startOffset");
}
}
function lumaProviderSettingsToggleHandler(lumaNode) {
// Find all "use" parameter widgets for Luma Provider Settings
const useLoopWidget = lumaNode.widgets.find(w => w.name === "useLoop");
const loopWidget = lumaNode.widgets.find(w => w.name === "loop");
const useConcept1Widget = lumaNode.widgets.find(w => w.name === "useConcept1");
const concept1Widget = lumaNode.widgets.find(w => w.name === "concept1");
const useConcept2Widget = lumaNode.widgets.find(w => w.name === "useConcept2");
const concept2Widget = lumaNode.widgets.find(w => w.name === "concept2");
const useConcept3Widget = lumaNode.widgets.find(w => w.name === "useConcept3");
const concept3Widget = lumaNode.widgets.find(w => w.name === "concept3");
const useConcept4Widget = lumaNode.widgets.find(w => w.name === "useConcept4");
const concept4Widget = lumaNode.widgets.find(w => w.name === "concept4");
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 = lumaNode.htmlElements?.widgetsContainer || lumaNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
lumaNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
if (useLoopWidget && loopWidget) {
toggleWidgetState(useLoopWidget, loopWidget, "loop");
}
if (useConcept1Widget && concept1Widget) {
toggleWidgetState(useConcept1Widget, concept1Widget, "concept1");
}
if (useConcept2Widget && concept2Widget) {
toggleWidgetState(useConcept2Widget, concept2Widget, "concept2");
}
if (useConcept3Widget && concept3Widget) {
toggleWidgetState(useConcept3Widget, concept3Widget, "concept3");
}
if (useConcept4Widget && concept4Widget) {
toggleWidgetState(useConcept4Widget, concept4Widget, "concept4");
}
}
function briaProviderSettingsToggleHandler(briaNode) {
// Find all "use" parameter widgets for Bria Provider Settings
const useMediumWidget = briaNode.widgets.find(w => w.name === "useMedium");
const mediumWidget = briaNode.widgets.find(w => w.name === "medium");
const usePromptEnhancementWidget = briaNode.widgets.find(w => w.name === "usePromptEnhancement");
const promptEnhancementWidget = briaNode.widgets.find(w => w.name === "promptEnhancement");
const useEnhanceImageWidget = briaNode.widgets.find(w => w.name === "useEnhanceImage");
const enhanceImageWidget = briaNode.widgets.find(w => w.name === "enhanceImage");
const usePromptContentModerationWidget = briaNode.widgets.find(w => w.name === "usePromptContentModeration");
const promptContentModerationWidget = briaNode.widgets.find(w => w.name === "promptContentModeration");
const useContentModerationWidget = briaNode.widgets.find(w => w.name === "useContentModeration");
const contentModerationWidget = briaNode.widgets.find(w => w.name === "contentModeration");
const useIpSignalWidget = briaNode.widgets.find(w => w.name === "useIpSignal");
const ipSignalWidget = briaNode.widgets.find(w => w.name === "ipSignal");
const usePreserveAlphaWidget = briaNode.widgets.find(w => w.name === "usePreserveAlpha");
const preserveAlphaWidget = briaNode.widgets.find(w => w.name === "preserveAlpha");
const useModeWidget = briaNode.widgets.find(w => w.name === "useMode");
const modeWidget = briaNode.widgets.find(w => w.name === "mode");
const useEnhanceReferenceImagesWidget = briaNode.widgets.find(w => w.name === "useEnhanceReferenceImages");
const enhanceReferenceImagesWidget = briaNode.widgets.find(w => w.name === "enhanceReferenceImages");
const useRefinePromptWidget = briaNode.widgets.find(w => w.name === "useRefinePrompt");
const refinePromptWidget = briaNode.widgets.find(w => w.name === "refinePrompt");
const useOriginalQualityWidget = briaNode.widgets.find(w => w.name === "useOriginalQuality");
const originalQualityWidget = briaNode.widgets.find(w => w.name === "originalQuality");
const useForceBackgroundDetectionWidget = briaNode.widgets.find(w => w.name === "useForceBackgroundDetection");
const forceBackgroundDetectionWidget = briaNode.widgets.find(w => w.name === "forceBackgroundDetection");
const useAutoTrimWidget = briaNode.widgets.find(w => w.name === "useAutoTrim");
const autoTrimWidget = briaNode.widgets.find(w => w.name === "autoTrim");
const usePreserveAudioWidget = briaNode.widgets.find(w => w.name === "usePreserveAudio");
const preserveAudioWidget = briaNode.widgets.find(w => w.name === "preserveAudio");
const useSeasonWidget = briaNode.widgets.find(w => w.name === "useSeason");
const seasonWidget = briaNode.widgets.find(w => w.name === "season");
const useEditWidget = briaNode.widgets.find(w => w.name === "useEdit");
const editWidget = briaNode.widgets.find(w => w.name === "edit");
const useColorWidget = briaNode.widgets.find(w => w.name === "useColor");
const colorWidget = briaNode.widgets.find(w => w.name === "color");
const useLightDirectionWidget = briaNode.widgets.find(w => w.name === "useLightDirection");
const lightDirectionWidget = briaNode.widgets.find(w => w.name === "lightDirection");
const useLightTypeWidget = briaNode.widgets.find(w => w.name === "useLightType");
const lightTypeWidget = briaNode.widgets.find(w => w.name === "lightType");
// Helper function to toggle widget enabled state (exact same pattern)
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function toggleEnabled() {
const enabled = useWidget.value === true;
// Disable/enable widgets using inputEl if available (exact same pattern)
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;
}
// Handle dropdown widgets (for medium and mode)
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
// Also set widget property
paramWidget.disabled = !enabled;
// Fallback: try to find inputs via DOM if inputEl is not available
if (!paramWidget.inputEl) {
const nodeElement = briaNode.htmlElements?.widgetsContainer || briaNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
briaNode.setDirtyCanvas(true);
}
// Set up callback (exact same pattern)
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
// Initial call to set initial state
setTimeout(toggleEnabled, 100);
}
// Set up all toggle handlers
if (useMediumWidget && mediumWidget) {
toggleWidgetState(useMediumWidget, mediumWidget, "medium");
}
if (usePromptEnhancementWidget && promptEnhancementWidget) {
toggleWidgetState(usePromptEnhancementWidget, promptEnhancementWidget, "promptEnhancement");
}
if (useEnhanceImageWidget && enhanceImageWidget) {
toggleWidgetState(useEnhanceImageWidget, enhanceImageWidget, "enhanceImage");
}
if (usePromptContentModerationWidget && promptContentModerationWidget) {
toggleWidgetState(usePromptContentModerationWidget, promptContentModerationWidget, "promptContentModeration");
}
if (useContentModerationWidget && contentModerationWidget) {
toggleWidgetState(useContentModerationWidget, contentModerationWidget, "contentModeration");
}
if (useIpSignalWidget && ipSignalWidget) {
toggleWidgetState(useIpSignalWidget, ipSignalWidget, "ipSignal");
}
if (usePreserveAlphaWidget && preserveAlphaWidget) {
toggleWidgetState(usePreserveAlphaWidget, preserveAlphaWidget, "preserveAlpha");
}
if (useModeWidget && modeWidget) {
toggleWidgetState(useModeWidget, modeWidget, "mode");
}
if (useEnhanceReferenceImagesWidget && enhanceReferenceImagesWidget) {
toggleWidgetState(useEnhanceReferenceImagesWidget, enhanceReferenceImagesWidget, "enhanceReferenceImages");
}
if (useRefinePromptWidget && refinePromptWidget) {
toggleWidgetState(useRefinePromptWidget, refinePromptWidget, "refinePrompt");
}
if (useOriginalQualityWidget && originalQualityWidget) {
toggleWidgetState(useOriginalQualityWidget, originalQualityWidget, "originalQuality");
}
if (useForceBackgroundDetectionWidget && forceBackgroundDetectionWidget) {
toggleWidgetState(useForceBackgroundDetectionWidget, forceBackgroundDetectionWidget, "forceBackgroundDetection");
}
if (useAutoTrimWidget && autoTrimWidget) {
toggleWidgetState(useAutoTrimWidget, autoTrimWidget, "autoTrim");
}
if (usePreserveAudioWidget && preserveAudioWidget) {
toggleWidgetState(usePreserveAudioWidget, preserveAudioWidget, "preserveAudio");
}
if (useSeasonWidget && seasonWidget) {
toggleWidgetState(useSeasonWidget, seasonWidget, "season");
}
if (useEditWidget && editWidget) {
toggleWidgetState(useEditWidget, editWidget, "edit");
}
if (useColorWidget && colorWidget) {
toggleWidgetState(useColorWidget, colorWidget, "color");
}
if (useLightDirectionWidget && lightDirectionWidget) {
toggleWidgetState(useLightDirectionWidget, lightDirectionWidget, "lightDirection");
}
if (useLightTypeWidget && lightTypeWidget) {
toggleWidgetState(useLightTypeWidget, lightTypeWidget, "lightType");
}
}
function audioInputToggleHandler(audioInputNode) {
// Find "use" parameter widget and "id" widget for Audio Input
const useIdWidget = audioInputNode.widgets.find(w => w.name === "useId");
const idWidget = audioInputNode.widgets.find(w => w.name === "id");
// Helper function to toggle widget enabled state
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function toggleEnabled() {
const enabled = useWidget.value === true;
// Disable/enable widgets using inputEl if available
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;
}
// Also set widget property
paramWidget.disabled = !enabled;
// Fallback: try to find inputs via DOM if inputEl is not available
if (!paramWidget.inputEl) {
const nodeElement = audioInputNode.htmlElements?.widgetsContainer || audioInputNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
audioInputNode.setDirtyCanvas(true);
}
// Set up callback
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
// Initial call to set initial state
setTimeout(toggleEnabled, 100);
}
// Set up toggle handler for "useId" parameter
if (useIdWidget && idWidget) {
toggleWidgetState(useIdWidget, idWidget, "id");
}
}
function speechInputToggleHandler(speechInputNode) {
// Find "use" parameter widget and "id" widget for Speech Input
const useIdWidget = speechInputNode.widgets.find(w => w.name === "useId");
const idWidget = speechInputNode.widgets.find(w => w.name === "id");
// Helper function to toggle widget enabled state
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function toggleEnabled() {
const enabled = useWidget.value === true;
// Disable/enable widgets using inputEl if available
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;
}
// Also set widget property
paramWidget.disabled = !enabled;
// Fallback: try to find inputs via DOM if inputEl is not available
if (!paramWidget.inputEl) {
const nodeElement = speechInputNode.htmlElements?.widgetsContainer || speechInputNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
speechInputNode.setDirtyCanvas(true);
}
// Set up callback
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
// Initial call to set initial state
setTimeout(toggleEnabled, 100);
}
// Set up toggle handler for "useId" parameter
if (useIdWidget && idWidget) {
toggleWidgetState(useIdWidget, idWidget, "id");
}
}
function briaProviderMaskToggleHandler(maskNode) {
// Helper function to toggle widget enabled state for multiple widgets
function toggleWidgetState(useWidget, paramWidgets, paramNames) {
if (!useWidget || !paramWidgets || paramWidgets.length === 0) return;
function toggleEnabled() {
const enabled = useWidget.value === true;
paramWidgets.forEach((paramWidget, idx) => {
if (!paramWidget) return;
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;
}
// Handle dropdown widgets (for Type fields)
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
paramWidget.disabled = !enabled;
// Fallback: try to find inputs via DOM if inputEl is not available
if (!paramWidget.inputEl && paramNames[idx]) {
const nodeElement = maskNode.htmlElements?.widgetsContainer || maskNode.htmlElements;
if (nodeElement) {
const input = nodeElement.querySelector(`input[name="${paramNames[idx]}"], textarea[name="${paramNames[idx]}"], select[name="${paramNames[idx]}"]`);
if (input) {
input.disabled = !enabled;
input.style.opacity = enabled ? "1" : "0.5";
input.style.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
});
maskNode.setDirtyCanvas(true);
}
// Set up callback
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
// Initial call to set initial state
setTimeout(toggleEnabled, 100);
}
// Set up toggle handlers for foreground, prompt, frameIndex
const useForegroundWidget = maskNode.widgets.find(w => w.name === "useForeground");
const foregroundWidget = maskNode.widgets.find(w => w.name === "foreground");
if (useForegroundWidget && foregroundWidget) {
toggleWidgetState(useForegroundWidget, [foregroundWidget], ["foreground"]);
}
const usePromptWidget = maskNode.widgets.find(w => w.name === "usePrompt");
const promptWidget = maskNode.widgets.find(w => w.name === "prompt");
if (usePromptWidget && promptWidget) {
toggleWidgetState(usePromptWidget, [promptWidget], ["prompt"]);
}
const useFrameIndexWidget = maskNode.widgets.find(w => w.name === "useFrameIndex");
const frameIndexWidget = maskNode.widgets.find(w => w.name === "frameIndex");
if (useFrameIndexWidget && frameIndexWidget) {
toggleWidgetState(useFrameIndexWidget, [frameIndexWidget], ["frameIndex"]);
}
// Set up toggle handlers for all 6 key points
for (let i = 1; i <= 6; i++) {
const useWidget = maskNode.widgets.find(w => w.name === `use_${i}`);
const xWidget = maskNode.widgets.find(w => w.name === `X${i}`);
const yWidget = maskNode.widgets.find(w => w.name === `Y${i}`);
const typeWidget = maskNode.widgets.find(w => w.name === `Type${i}`);
if (useWidget && xWidget && yWidget && typeWidget) {
toggleWidgetState(useWidget, [xWidget, yWidget, typeWidget], [`X${i}`, `Y${i}`, `Type${i}`]);
}
}
}
function wanAnimateAdvancedFeatureSettingsToggleHandler(wanAnimateNode) {
// Find widgets
const useModeWidget = wanAnimateNode.widgets.find(w => w.name === "useMode");
const modeWidget = wanAnimateNode.widgets.find(w => w.name === "mode");
const useRetargetPoseWidget = wanAnimateNode.widgets.find(w => w.name === "useRetargetPose");
const retargetPoseWidget = wanAnimateNode.widgets.find(w => w.name === "retargetPose");
const usePrevSegCondFramesWidget = wanAnimateNode.widgets.find(w => w.name === "usePrevSegCondFrames");
const prevSegCondFramesWidget = wanAnimateNode.widgets.find(w => w.name === "prevSegCondFrames");
// Helper function to toggle widget enabled state
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;
}
// Handle dropdown widgets (for mode field)
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
paramWidget.disabled = !enabled;
// Fallback: try to find inputs via DOM if inputEl is not available
if (!paramWidget.inputEl && paramName) {
const nodeElement = wanAnimateNode.htmlElements?.widgetsContainer || wanAnimateNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
wanAnimateNode.setDirtyCanvas(true);
}
// Set up callback
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
// Initial call to set initial state
setTimeout(toggleEnabled, 100);
}
// Set up toggle handler for mode
if (useModeWidget && modeWidget) {
toggleWidgetState(useModeWidget, modeWidget, "mode");
}
// Set up toggle handler for retargetPose (with mode dependency)
if (useRetargetPoseWidget && retargetPoseWidget) {
function toggleRetargetPoseEnabled() {
const useRetargetPoseEnabled = useRetargetPoseWidget.value === true;
const modeValue = modeWidget ? modeWidget.value : "animate";
// retargetPose is only supported for animate mode
const enabled = useRetargetPoseEnabled && modeValue === "animate";
if (retargetPoseWidget.inputEl) {
retargetPoseWidget.inputEl.disabled = !enabled;
retargetPoseWidget.inputEl.style.opacity = enabled ? "1" : "0.5";
retargetPoseWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed";
retargetPoseWidget.inputEl.readOnly = !enabled;
}
retargetPoseWidget.disabled = !enabled;
// Fallback: try to find inputs via DOM
if (!retargetPoseWidget.inputEl) {
const nodeElement = wanAnimateNode.htmlElements?.widgetsContainer || wanAnimateNode.htmlElements;
if (nodeElement) {
const input = nodeElement.querySelector(`input[name="retargetPose"], textarea[name="retargetPose"], select[name="retargetPose"]`);
if (input) {
input.disabled = !enabled;
input.style.opacity = enabled ? "1" : "0.5";
input.style.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
}
}
}
wanAnimateNode.setDirtyCanvas(true);
}
// Set up callback for useRetargetPose toggle
appendWidgetCB(useRetargetPoseWidget, () => {
setTimeout(toggleRetargetPoseEnabled, 50);
});
// Set up callback for mode change (to disable retargetPose when mode is "replace")
if (modeWidget) {
appendWidgetCB(modeWidget, () => {
setTimeout(toggleRetargetPoseEnabled, 50);
});
}
// Initial call to set initial state
setTimeout(toggleRetargetPoseEnabled, 100);
}
// Set up toggle handler for prevSegCondFrames
if (usePrevSegCondFramesWidget && prevSegCondFramesWidget) {
toggleWidgetState(usePrevSegCondFramesWidget, prevSegCondFramesWidget, "prevSegCondFrames");
}
}
function videoAdvancedFeatureInputsToggleHandler(advancedFeatureNode) {
// Helper function to toggle widget enabled state
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;
// Fallback: try to find inputs via DOM if inputEl is not available
if (!paramWidget.inputEl && paramName) {
const nodeElement = advancedFeatureNode.htmlElements?.widgetsContainer || advancedFeatureNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
}
}
}
advancedFeatureNode.setDirtyCanvas(true);
}
// Set up callback
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
// Initial call to set initial state
setTimeout(toggleEnabled, 100);
}
// Set up toggle handlers for each parameter
const useVideoCFGScaleWidget = advancedFeatureNode.widgets.find(w => w.name === "useVideoCFGScale");
const videoCFGScaleWidget = advancedFeatureNode.widgets.find(w => w.name === "videoCFGScale");
if (useVideoCFGScaleWidget && videoCFGScaleWidget) {
toggleWidgetState(useVideoCFGScaleWidget, videoCFGScaleWidget, "videoCFGScale");
}
const useAudioCFGScaleWidget = advancedFeatureNode.widgets.find(w => w.name === "useAudioCFGScale");
const audioCFGScaleWidget = advancedFeatureNode.widgets.find(w => w.name === "audioCFGScale");
if (useAudioCFGScaleWidget && audioCFGScaleWidget) {
toggleWidgetState(useAudioCFGScaleWidget, audioCFGScaleWidget, "audioCFGScale");
}
const useVideoNegativePromptWidget = advancedFeatureNode.widgets.find(w => w.name === "useVideoNegativePrompt");
const videoNegativePromptWidget = advancedFeatureNode.widgets.find(w => w.name === "videoNegativePrompt");
if (useVideoNegativePromptWidget && videoNegativePromptWidget) {
toggleWidgetState(useVideoNegativePromptWidget, videoNegativePromptWidget, "videoNegativePrompt");
}
const useAudioNegativePromptWidget = advancedFeatureNode.widgets.find(w => w.name === "useAudioNegativePrompt");
const audioNegativePromptWidget = advancedFeatureNode.widgets.find(w => w.name === "audioNegativePrompt");
if (useAudioNegativePromptWidget && audioNegativePromptWidget) {
toggleWidgetState(useAudioNegativePromptWidget, audioNegativePromptWidget, "audioNegativePrompt");
}
const useSlgLayerWidget = advancedFeatureNode.widgets.find(w => w.name === "useSlgLayer");
const slgLayerWidget = advancedFeatureNode.widgets.find(w => w.name === "slgLayer");
if (useSlgLayerWidget && slgLayerWidget) {
toggleWidgetState(useSlgLayerWidget, slgLayerWidget, "slgLayer");
}
}
function imageInferenceAdvancedFeaturesToggleHandler(advancedFeaturesNode) {
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 && paramName) {
const nodeElement = advancedFeaturesNode.htmlElements?.widgetsContainer || advancedFeaturesNode.htmlElements;
if (nodeElement) {
const input = nodeElement.querySelector(`input[name="${paramName}"], select[name="${paramName}"]`);
if (input) {
input.disabled = !enabled;
input.style.opacity = enabled ? "1" : "0.5";
input.style.cursor = enabled ? "text" : "not-allowed";
}
}
}
advancedFeaturesNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => setTimeout(toggleEnabled, 50));
setTimeout(toggleEnabled, 100);
}
const useLayerDiffuseWidget = advancedFeaturesNode.widgets.find(w => w.name === "useLayerDiffuse");
const layerDiffuseWidget = advancedFeaturesNode.widgets.find(w => w.name === "layerDiffuse");
if (useLayerDiffuseWidget && layerDiffuseWidget) toggleWidgetState(useLayerDiffuseWidget, layerDiffuseWidget, "layerDiffuse");
const useHiresFixWidget = advancedFeaturesNode.widgets.find(w => w.name === "useHiresFix");
const hiresFixWidget = advancedFeaturesNode.widgets.find(w => w.name === "hiresFix");
if (useHiresFixWidget && hiresFixWidget) toggleWidgetState(useHiresFixWidget, hiresFixWidget, "hiresFix");
}
function watermarkAdvancedFeatureToggleHandler(watermarkNode) {
if (!watermarkNode?.widgets) return;
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 && paramName) {
const nodeElement = watermarkNode.htmlElements?.widgetsContainer || watermarkNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
}
}
}
watermarkNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
const pairs = [
["useText", "text"],
["useImage", "image"],
["useDisplayPosition", "displayPosition"],
["useTiled", "tiled"],
["useOpacity", "opacity"],
["useFontColor", "fontColor"],
["useBgColor", "bgColor"],
];
for (const [useName, paramName] of pairs) {
const useWidget = watermarkNode.widgets.find(w => w.name === useName);
const paramWidget = watermarkNode.widgets.find(w => w.name === paramName);
if (useWidget && paramWidget) {
toggleWidgetState(useWidget, paramWidget, paramName);
}
}
}
function videoInferenceSpeechInputToggleHandler(speechInputNode) {
if (!speechInputNode?.widgets) return;
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 && paramName) {
const nodeElement = speechInputNode.htmlElements?.widgetsContainer || speechInputNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
}
}
}
speechInputNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
const pairs = [
["useVoice", "voice"],
["useText", "text"],
["useSpeed", "speed"],
["usePitch", "pitch"],
["useLanguage", "language"],
];
for (const [useName, paramName] of pairs) {
const useWidget = speechInputNode.widgets.find(w => w.name === useName);
const paramWidget = speechInputNode.widgets.find(w => w.name === paramName);
if (useWidget && paramWidget) {
toggleWidgetState(useWidget, paramWidget, paramName);
}
}
}
function regionalPromptingRegionsToggleHandler(regionsNode) {
if (!regionsNode?.widgets) return;
function toggleWidgetState(useWidget, paramWidgets, paramNames) {
if (!useWidget || !paramWidgets || paramWidgets.length === 0) return;
function toggleEnabled() {
const enabled = useWidget.value === true;
for (let i = 0; i < paramWidgets.length; i++) {
const paramWidget = paramWidgets[i];
const paramName = paramNames[i];
if (!paramWidget) continue;
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 && paramName) {
const nodeElement = regionsNode.htmlElements?.widgetsContainer || regionsNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
}
}
}
}
regionsNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
for (let idx = 1; idx <= 4; idx++) {
const useWidget = regionsNode.widgets.find(w => w.name === `useRegion${idx}`);
const promptWidget = regionsNode.widgets.find(w => w.name === `region${idx}Prompt`);
const x0Widget = regionsNode.widgets.find(w => w.name === `region${idx}_x0`);
const y0Widget = regionsNode.widgets.find(w => w.name === `region${idx}_y0`);
const x1Widget = regionsNode.widgets.find(w => w.name === `region${idx}_x1`);
const y1Widget = regionsNode.widgets.find(w => w.name === `region${idx}_y1`);
const paramWidgets = [promptWidget, x0Widget, y0Widget, x1Widget, y1Widget];
const paramNames = [
`region${idx}Prompt`,
`region${idx}_x0`,
`region${idx}_y0`,
`region${idx}_x1`,
`region${idx}_y1`,
];
if (useWidget) {
toggleWidgetState(useWidget, paramWidgets, paramNames);
}
}
}
function audioInferenceReferenceVoiceToggleHandler(referenceVoiceNode) {
if (!referenceVoiceNode?.widgets) return;
if (referenceVoiceNode._audioInferenceReferenceVoiceToggleHandlerRegistered) return;
referenceVoiceNode._audioInferenceReferenceVoiceToggleHandlerRegistered = true;
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function applyState() {
const enabled = useWidget.value === true;
toggleWidgetEnabled(paramWidget, enabled, referenceVoiceNode);
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
referenceVoiceNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => setTimeout(applyState, 50));
setTimeout(applyState, 100);
}
for (let i = 1; i <= 4; i++) {
const useReferenceVoiceWidget = referenceVoiceNode.widgets.find((w) => w && w.name === `useReferenceVoice${i}`);
const audioWidget = referenceVoiceNode.widgets.find((w) => w && w.name === `audio${i}`);
const textWidget = referenceVoiceNode.widgets.find((w) => w && w.name === `text${i}`);
if (useReferenceVoiceWidget && audioWidget) {
toggleWidgetState(useReferenceVoiceWidget, audioWidget, `audio${i}`);
}
if (useReferenceVoiceWidget && textWidget) {
toggleWidgetState(useReferenceVoiceWidget, textWidget, `text${i}`);
}
}
}
function audioInferenceInputsToggleHandler(audioInputsNode) {
if (!audioInputsNode?.widgets) return;
// Find widgets
const useAudioWidget = audioInputsNode.widgets.find(w => w && w.name === "useAudio");
const audioWidget = audioInputsNode.widgets.find(w => w && w.name === "Audio");
const useVideoWidget = audioInputsNode.widgets.find(w => w && w.name === "useVideo");
const videoWidget = audioInputsNode.widgets.find(w => w && w.name === "Video");
const useVideosWidget = audioInputsNode.widgets.find(w => w && w.name === "useVideos");
const useAudiosWidget = audioInputsNode.widgets.find(w => w && w.name === "useAudios");
const useReferenceAudiosWidget = audioInputsNode.widgets.find(w => w && w.name === "useReferenceAudios");
// Helper function to toggle widget enabled state
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;
// Fallback: try to find inputs via DOM if inputEl is not available
if (!paramWidget.inputEl && paramName) {
const nodeElement = audioInputsNode.htmlElements?.widgetsContainer || audioInputsNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
}
}
}
audioInputsNode.setDirtyCanvas(true);
}
// Set up callback
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
// Initial call to set initial state
setTimeout(toggleEnabled, 100);
}
// Set up toggle handler for single audio
if (useAudioWidget && audioWidget) {
toggleWidgetState(useAudioWidget, audioWidget, "Audio");
}
// Set up toggle handler for single video
if (useVideoWidget && videoWidget) {
toggleWidgetState(useVideoWidget, videoWidget, "Video");
}
// Set up toggle handlers for multiple audios (Audio1 … AudioN; N from widgets, fallback to AUDIO_INFERENCE_INPUTS_MAX_AUDIOS)
if (useAudiosWidget) {
function getAudioInferenceAudioSlotCount() {
let max = 0;
for (const w of audioInputsNode.widgets) {
if (!w?.name) continue;
const m = /^Audio(\d+)$/.exec(w.name);
if (m) max = Math.max(max, parseInt(m[1], 10));
}
return max > 0 ? max : AUDIO_INFERENCE_INPUTS_MAX_AUDIOS;
}
function toggleAudiosEnabled() {
const enabled = useAudiosWidget.value === true;
const slotCount = getAudioInferenceAudioSlotCount();
for (let i = 1; i <= slotCount; i++) {
const audioSlotWidget = audioInputsNode.widgets.find(w => w && w.name === `Audio${i}`);
if (audioSlotWidget) {
if (audioSlotWidget.inputEl) {
audioSlotWidget.inputEl.disabled = !enabled;
audioSlotWidget.inputEl.style.opacity = enabled ? "1" : "0.5";
audioSlotWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed";
audioSlotWidget.inputEl.readOnly = !enabled;
}
audioSlotWidget.disabled = !enabled;
if (!audioSlotWidget.inputEl) {
const nodeElement = audioInputsNode.htmlElements?.widgetsContainer || audioInputsNode.htmlElements;
if (nodeElement) {
const input = nodeElement.querySelector(`input[name="Audio${i}"], textarea[name="Audio${i}"], select[name="Audio${i}"]`);
if (input) {
input.disabled = !enabled;
input.style.opacity = enabled ? "1" : "0.5";
input.style.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
}
}
}
}
}
audioInputsNode.setDirtyCanvas(true);
}
appendWidgetCB(useAudiosWidget, () => {
setTimeout(toggleAudiosEnabled, 50);
});
setTimeout(toggleAudiosEnabled, 100);
}
// Set up toggle handlers for multiple videos (Video1 … VideoN; N from widgets, fallback to AUDIO_INFERENCE_INPUTS_MAX_VIDEOS)
if (useVideosWidget) {
function getAudioInferenceVideoSlotCount() {
let max = 0;
for (const w of audioInputsNode.widgets) {
if (!w?.name) continue;
const m = /^Video(\d+)$/.exec(w.name);
if (m) max = Math.max(max, parseInt(m[1], 10));
}
return max > 0 ? max : AUDIO_INFERENCE_INPUTS_MAX_VIDEOS;
}
function toggleVideosEnabled() {
const enabled = useVideosWidget.value === true;
const slotCount = getAudioInferenceVideoSlotCount();
for (let i = 1; i <= slotCount; i++) {
const videoWidget = audioInputsNode.widgets.find(w => w && w.name === `Video${i}`);
if (videoWidget) {
if (videoWidget.inputEl) {
videoWidget.inputEl.disabled = !enabled;
videoWidget.inputEl.style.opacity = enabled ? "1" : "0.5";
videoWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed";
videoWidget.inputEl.readOnly = !enabled;
}
videoWidget.disabled = !enabled;
// Fallback: try to find inputs via DOM
if (!videoWidget.inputEl) {
const nodeElement = audioInputsNode.htmlElements?.widgetsContainer || audioInputsNode.htmlElements;
if (nodeElement) {
const input = nodeElement.querySelector(`input[name="Video${i}"], textarea[name="Video${i}"], select[name="Video${i}"]`);
if (input) {
input.disabled = !enabled;
input.style.opacity = enabled ? "1" : "0.5";
input.style.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
}
}
}
}
}
audioInputsNode.setDirtyCanvas(true);
}
// Set up callback
appendWidgetCB(useVideosWidget, () => {
setTimeout(toggleVideosEnabled, 50);
});
// Initial call to set initial state
setTimeout(toggleVideosEnabled, 100);
}
// Set up toggle handlers for reference audios (Reference Audio 1 … N; N from widgets, fallback to 4)
if (useReferenceAudiosWidget) {
function getAudioInferenceReferenceAudioSlotCount() {
let max = 0;
for (const w of audioInputsNode.widgets) {
if (!w?.name) continue;
const m = /^Reference Audio (\d+)$/.exec(w.name);
if (m) max = Math.max(max, parseInt(m[1], 10));
}
return max > 0 ? max : 4;
}
function toggleReferenceAudiosEnabled() {
const enabled = useReferenceAudiosWidget.value === true;
const slotCount = getAudioInferenceReferenceAudioSlotCount();
for (let i = 1; i <= slotCount; i++) {
const refAudioWidget = audioInputsNode.widgets.find(w => w && w.name === `Reference Audio ${i}`);
if (refAudioWidget) {
if (refAudioWidget.inputEl) {
refAudioWidget.inputEl.disabled = !enabled;
refAudioWidget.inputEl.style.opacity = enabled ? "1" : "0.5";
refAudioWidget.inputEl.style.cursor = enabled ? "text" : "not-allowed";
refAudioWidget.inputEl.readOnly = !enabled;
}
refAudioWidget.disabled = !enabled;
if (!refAudioWidget.inputEl) {
const nodeElement = audioInputsNode.htmlElements?.widgetsContainer || audioInputsNode.htmlElements;
if (nodeElement) {
const input = nodeElement.querySelector(`input[name="Reference Audio ${i}"], textarea[name="Reference Audio ${i}"], select[name="Reference Audio ${i}"]`);
if (input) {
input.disabled = !enabled;
input.style.opacity = enabled ? "1" : "0.5";
input.style.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
}
}
}
}
}
audioInputsNode.setDirtyCanvas(true);
}
appendWidgetCB(useReferenceAudiosWidget, () => {
setTimeout(toggleReferenceAudiosEnabled, 50);
});
setTimeout(toggleReferenceAudiosEnabled, 100);
}
}
function audioInferenceSpeechVoicesToggleHandler(voicesNode) {
if (!voicesNode?.widgets) return;
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 = voicesNode.htmlElements?.widgetsContainer || voicesNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
voicesNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
for (let i = 1; i <= 4; i++) {
const useVoiceWidget = voicesNode.widgets.find((w) => w && w.name === `useVoice${i}`);
const speakerWidget = voicesNode.widgets.find((w) => w && w.name === `speaker${i}`);
const voiceWidget = voicesNode.widgets.find((w) => w && w.name === `voice${i}`);
if (useVoiceWidget && speakerWidget) {
toggleWidgetState(useVoiceWidget, speakerWidget, `speaker${i}`);
}
if (useVoiceWidget && voiceWidget) {
toggleWidgetState(useVoiceWidget, voiceWidget, `voice${i}`);
}
}
}
function videoInputsFrameToggleHandler(frameImagesNode) {
if (!frameImagesNode?.widgets) return;
if (frameImagesNode._videoInputsFrameToggleHandlerRegistered) return;
frameImagesNode._videoInputsFrameToggleHandlerRegistered = true;
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function toggleEnabled() {
const enabled = useWidget.value === true;
// FLOAT timestamp widgets: avoid '' on disabled slots (ComfyUI validation error)
if (!enabled && paramName && paramName.startsWith("timestamp")) {
if (paramWidget.value === "" || paramWidget.value == null) {
paramWidget.value = 0.0;
}
}
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;
}
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
paramWidget.disabled = !enabled;
if (!paramWidget.inputEl && paramName) {
const nodeElement = frameImagesNode.htmlElements?.widgetsContainer || frameImagesNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
frameImagesNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
function initializeHandler() {
if (!frameImagesNode.widgets || frameImagesNode.widgets.length === 0) {
setTimeout(initializeHandler, 100);
return;
}
for (let i = 1; i <= 4; i++) {
const useFrameWidget = frameImagesNode.widgets.find((w) => w && w.name === `useFrame${i}`);
const frameWidget = frameImagesNode.widgets.find((w) => w && w.name === `frame${i} position`);
const useTimestampWidget = frameImagesNode.widgets.find((w) => w && w.name === `useTimestamp${i}`);
const timestampWidget = frameImagesNode.widgets.find((w) => w && w.name === `timestamp${i}`);
if (useFrameWidget && frameWidget) {
toggleWidgetState(useFrameWidget, frameWidget, `frame${i} position`);
}
if (useTimestampWidget && timestampWidget) {
toggleWidgetState(useTimestampWidget, timestampWidget, `timestamp${i}`);
}
}
}
initializeHandler();
}
function referenceVideosToggleHandler(referenceVideosNode) {
if (!referenceVideosNode?.widgets) return;
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;
}
if (paramWidget.options && paramWidget.options.element) {
paramWidget.options.element.disabled = !enabled;
paramWidget.options.element.style.opacity = enabled ? "1" : "0.5";
paramWidget.options.element.style.pointerEvents = enabled ? "auto" : "none";
}
paramWidget.disabled = !enabled;
if (!paramWidget.inputEl && paramName) {
const nodeElement = referenceVideosNode.htmlElements?.widgetsContainer || referenceVideosNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
referenceVideosNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
for (let i = 1; i <= 4; i++) {
const useVideoWidget = referenceVideosNode.widgets.find((w) => w && w.name === `useVideo${i}`);
const videoWidget = referenceVideosNode.widgets.find((w) => w && w.name === `Video${i}`);
const tagWidget = referenceVideosNode.widgets.find((w) => w && w.name === `Tag${i}`);
const typeWidget = referenceVideosNode.widgets.find((w) => w && w.name === `Type${i}`);
if (useVideoWidget && videoWidget) {
toggleWidgetState(useVideoWidget, videoWidget, `Video${i}`);
}
if (useVideoWidget && tagWidget) {
toggleWidgetState(useVideoWidget, tagWidget, `Tag${i}`);
}
if (useVideoWidget && typeWidget) {
toggleWidgetState(useVideoWidget, typeWidget, `Type${i}`);
}
}
}
export {
notifyUser,
promptEnhanceHandler,
syncDimensionsNodeHandler,
searchNodeHandler,
mediaUUIDHandler,
save3DFilepathHandler,
captionNodeHandler,
saveTextHandler,
videoTranscriptionHandler,
videoOutputsHandler,
handleCustomErrors,
APIKeyHandler,
videoInferenceDimensionsHandler,
videoModelSearchFilterHandler,
threeDModelSearchFilterHandler,
audioModelSearchFilterHandler,
textModelSearchFilterHandler,
vectorizeModelSearchFilterHandler,
vectorizeToggleHandler,
useParameterToggleHandler,
imageInferenceToggleHandler,
imageInferenceAdvancedFeaturesToggleHandler,
watermarkAdvancedFeatureToggleHandler,
videoInferenceSpeechInputToggleHandler,
regionalPromptingRegionsToggleHandler,
upscalerToggleHandler,
imageUpscalerSettingsToggleHandler,
videoUpscalerToggleHandler,
audioInferenceToggleHandler,
audioInferenceSpeechToggleHandler,
audioSettingsToggleHandler,
textInferenceSettingsToggleHandler,
videoSettingsToggleHandler,
videoInferenceSettingsTtsToggleHandler,
videoInferenceSettingsActiveSpeakerDetectionToggleHandler,
videoInferenceSettingsActiveSpeakerBoundingBoxesToggleHandler,
videoInferenceSettingsSegmentsToggleHandler,
videoInferenceSettingsControlToggleHandler,
acceleratorOptionsToggleHandler,
bytedanceProviderSettingsToggleHandler,
xaiProviderSettingsToggleHandler,
viduProviderSettingsToggleHandler,
sourcefulProviderSettingsToggleHandler,
sourcefulProviderSettingsFontsToggleHandler,
threeDInferenceToggleHandler,
threeDInferenceSettingsToggleHandler,
threeDInferenceSettingsLatToggleHandler,
threeDInferenceSettingsMeshClusterToggleHandler,
threeDInferenceSettingsDracoCompressionToggleHandler,
ultralyticsProviderSettingsToggleHandler,
openaiProviderSettingsToggleHandler,
lightricksProviderSettingsToggleHandler,
klingProviderSettingsToggleHandler,
lumaProviderSettingsToggleHandler,
briaProviderSettingsToggleHandler,
pixverseProviderSettingsToggleHandler,
alibabaProviderSettingsToggleHandler,
mireloProviderSettingsToggleHandler,
googleProviderSettingsToggleHandler,
syncProviderSettingsToggleHandler,
syncSegmentToggleHandler,
settingsToggleHandler,
outpaintSettingsToggleHandler,
safetyInputsToggleHandler,
imageInferenceSettingsColorPaletteToggleHandler,
imageInferenceSettingsMoodboardsToggleHandler,
imageInferenceSettingsStructuredPromptToggleHandler,
imageInferenceSettingsPromptEnhanceToggleHandler,
imageInferenceSettingsScoringRubricToggleHandler,
audioInputToggleHandler,
speechInputToggleHandler,
briaProviderMaskToggleHandler,
wanAnimateAdvancedFeatureSettingsToggleHandler,
videoAdvancedFeatureInputsToggleHandler,
audioInferenceInputsToggleHandler,
audioInferenceReferenceVoiceToggleHandler,
audioInferenceSpeechVoicesToggleHandler,
videoInputsFrameToggleHandler,
referenceVideosToggleHandler,
};
function googleProviderSettingsToggleHandler(googleNode) {
// Find all "use" parameter widgets for Google Provider Settings
const useGenerateAudioWidget = googleNode.widgets.find(w => w && w.name === "useGenerateAudio");
const generateAudioWidget = googleNode.widgets.find(w => w && w.name === "generateAudio");
const useEnhancePromptWidget = googleNode.widgets.find(w => w && w.name === "useEnhancePrompt");
const enhancePromptWidget = googleNode.widgets.find(w => w && w.name === "enhancePrompt");
const useSearchWidget = googleNode.widgets.find(w => w && w.name === "useSearch");
const searchWidget = googleNode.widgets.find(w => w && w.name === "search");
const useResizeModeWidget = googleNode.widgets.find(w => w && w.name === "useResizeMode");
const resizeModeWidget = googleNode.widgets.find(w => w && w.name === "resizeMode");
// Helper function to toggle widget enabled state
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 = googleNode.htmlElements?.widgetsContainer || googleNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
googleNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
// Set up toggle handlers
if (useGenerateAudioWidget && generateAudioWidget) {
toggleWidgetState(useGenerateAudioWidget, generateAudioWidget, "generateAudio");
}
if (useEnhancePromptWidget && enhancePromptWidget) {
toggleWidgetState(useEnhancePromptWidget, enhancePromptWidget, "enhancePrompt");
}
if (useSearchWidget && searchWidget) {
toggleWidgetState(useSearchWidget, searchWidget, "search");
}
if (useResizeModeWidget && resizeModeWidget) {
toggleWidgetState(useResizeModeWidget, resizeModeWidget, "resizeMode");
}
}
function settingsToggleHandler(settingsNode) {
// Find all "use" parameter widgets for Settings
const useTemperatureWidget = settingsNode.widgets.find(w => w.name === "useTemperature");
const temperatureWidget = settingsNode.widgets.find(w => w.name === "temperature");
const useSystemPromptWidget = settingsNode.widgets.find(w => w.name === "useSystemPrompt");
const systemPromptWidget = settingsNode.widgets.find(w => w.name === "systemPrompt");
const useTopPWidget = settingsNode.widgets.find(w => w.name === "useTopP");
const topPWidget = settingsNode.widgets.find(w => w.name === "topP");
const useLayersWidget = settingsNode.widgets.find(w => w.name === "useLayers");
const layersWidget = settingsNode.widgets.find(w => w.name === "layers");
const useTrueCFGScaleWidget = settingsNode.widgets.find(w => w.name === "useTrueCFGScale");
const trueCFGScaleWidget = settingsNode.widgets.find(w => w.name === "trueCFGScale");
const useQualityWidget = settingsNode.widgets.find(w => w.name === "useQuality");
const qualityWidget = settingsNode.widgets.find(w => w.name === "quality");
const useBackgroundWidget = settingsNode.widgets.find(w => w.name === "useBackground");
const backgroundWidget = settingsNode.widgets.find(w => w.name === "background");
const useStyleWidget = settingsNode.widgets.find(w => w.name === "useStyle");
const styleWidget = settingsNode.widgets.find(w => w.name === "style");
const useSearchWidget = settingsNode.widgets.find(w => w.name === "useSearch");
const searchWidget = settingsNode.widgets.find(w => w.name === "search");
const usePromptExtendWidget = settingsNode.widgets.find(w => w.name === "usePromptExtend");
const promptExtendWidget = settingsNode.widgets.find(w => w.name === "promptExtend");
const useEditRegionsWidget = settingsNode.widgets.find(w => w.name === "useEditRegions");
const editRegionsWidget = settingsNode.widgets.find(w => w.name === "editRegions");
const useThinkingWidget = settingsNode.widgets.find(w => w.name === "useThinking");
const thinkingWidget = settingsNode.widgets.find(w => w.name === "thinking");
const useThinkingLevelWidget = settingsNode.widgets.find(w => w.name === "useThinkingLevel");
const thinkingLevelWidget = settingsNode.widgets.find(w => w.name === "thinkingLevel");
const useSequentialWidget = settingsNode.widgets.find(w => w.name === "useSequential");
const sequentialWidget = settingsNode.widgets.find(w => w.name === "sequential");
const useRenderingSpeedWidget = settingsNode.widgets.find(w => w.name === "useRenderingSpeed");
const renderingSpeedWidget = settingsNode.widgets.find(w => w.name === "renderingSpeed");
const useMagicPromptWidget = settingsNode.widgets.find(w => w.name === "useMagicPrompt");
const magicPromptWidget = settingsNode.widgets.find(w => w.name === "magicPrompt");
const useAutoCropWidget = settingsNode.widgets.find(w => w.name === "useAutoCrop");
const autoCropWidget = settingsNode.widgets.find(w => w.name === "autoCrop");
const useDilatePixelsWidget = settingsNode.widgets.find(w => w.name === "useDilatePixels");
const dilatePixelsWidget = settingsNode.widgets.find(w => w.name === "dilatePixels");
const useCreativityWidget = settingsNode.widgets.find(w => w.name === "useCreativity");
const creativityWidget = settingsNode.widgets.find(w => w.name === "creativity");
const useBackgroundModeWidget = settingsNode.widgets.find(w => w.name === "useBackgroundMode");
const backgroundModeWidget = settingsNode.widgets.find(w => w.name === "backgroundMode");
const useBackgroundColorWidget = settingsNode.widgets.find(w => w.name === "useBackgroundColor");
const backgroundColorWidget = settingsNode.widgets.find(w => w.name === "backgroundColor");
const useEnhancePromptWidget = settingsNode.widgets.find(w => w.name === "useEnhancePrompt");
const enhancePromptWidget = settingsNode.widgets.find(w => w.name === "enhancePrompt");
const useScoringPromptWidget = settingsNode.widgets.find(w => w.name === "useScoringPrompt");
const scoringPromptWidget = settingsNode.widgets.find(w => w.name === "scoringPrompt");
const useCopyrightDetectionWidget = settingsNode.widgets.find(w => w.name === "useCopyrightDetection");
const copyrightDetectionWidget = settingsNode.widgets.find(w => w.name === "copyrightDetection");
const usePreserveInputSizeWidget = settingsNode.widgets.find(w => w.name === "usePreserveInputSize");
const preserveInputSizeWidget = settingsNode.widgets.find(w => w.name === "preserveInputSize");
const useTurboWidget = settingsNode.widgets.find(w => w.name === "useTurbo");
const turboWidget = settingsNode.widgets.find(w => w.name === "turbo");
// Helper function to toggle widget enabled state
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 = settingsNode.htmlElements?.widgetsContainer || settingsNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
settingsNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
// Set up toggle handlers
if (useTemperatureWidget && temperatureWidget) {
toggleWidgetState(useTemperatureWidget, temperatureWidget, "temperature");
}
if (useSystemPromptWidget && systemPromptWidget) {
toggleWidgetState(useSystemPromptWidget, systemPromptWidget, "systemPrompt");
}
if (useTopPWidget && topPWidget) {
toggleWidgetState(useTopPWidget, topPWidget, "topP");
}
if (useLayersWidget && layersWidget) {
toggleWidgetState(useLayersWidget, layersWidget, "layers");
}
if (useTrueCFGScaleWidget && trueCFGScaleWidget) {
toggleWidgetState(useTrueCFGScaleWidget, trueCFGScaleWidget, "trueCFGScale");
}
if (useQualityWidget && qualityWidget) {
toggleWidgetState(useQualityWidget, qualityWidget, "quality");
}
if (useBackgroundWidget && backgroundWidget) {
toggleWidgetState(useBackgroundWidget, backgroundWidget, "background");
}
if (useStyleWidget && styleWidget) {
toggleWidgetState(useStyleWidget, styleWidget, "style");
}
if (useSearchWidget && searchWidget) {
toggleWidgetState(useSearchWidget, searchWidget, "search");
}
if (usePromptExtendWidget && promptExtendWidget) {
toggleWidgetState(usePromptExtendWidget, promptExtendWidget, "promptExtend");
}
if (useEditRegionsWidget && editRegionsWidget) {
toggleWidgetState(useEditRegionsWidget, editRegionsWidget, "editRegions");
}
if (useThinkingWidget && thinkingWidget) {
toggleWidgetState(useThinkingWidget, thinkingWidget, "thinking");
}
if (useThinkingLevelWidget && thinkingLevelWidget) {
toggleWidgetState(useThinkingLevelWidget, thinkingLevelWidget, "thinkingLevel");
}
if (useSequentialWidget && sequentialWidget) {
toggleWidgetState(useSequentialWidget, sequentialWidget, "sequential");
}
if (useRenderingSpeedWidget && renderingSpeedWidget) {
toggleWidgetState(useRenderingSpeedWidget, renderingSpeedWidget, "renderingSpeed");
}
if (useMagicPromptWidget && magicPromptWidget) {
toggleWidgetState(useMagicPromptWidget, magicPromptWidget, "magicPrompt");
}
if (useAutoCropWidget && autoCropWidget) {
toggleWidgetState(useAutoCropWidget, autoCropWidget, "autoCrop");
}
if (useDilatePixelsWidget && dilatePixelsWidget) {
toggleWidgetState(useDilatePixelsWidget, dilatePixelsWidget, "dilatePixels");
}
if (useCreativityWidget && creativityWidget) {
toggleWidgetState(useCreativityWidget, creativityWidget, "creativity");
}
if (useBackgroundModeWidget && backgroundModeWidget) {
toggleWidgetState(useBackgroundModeWidget, backgroundModeWidget, "backgroundMode");
}
if (useBackgroundColorWidget && backgroundColorWidget) {
toggleWidgetState(useBackgroundColorWidget, backgroundColorWidget, "backgroundColor");
}
if (useEnhancePromptWidget && enhancePromptWidget) {
toggleWidgetState(useEnhancePromptWidget, enhancePromptWidget, "enhancePrompt");
}
if (useScoringPromptWidget && scoringPromptWidget) {
toggleWidgetState(useScoringPromptWidget, scoringPromptWidget, "scoringPrompt");
}
if (useCopyrightDetectionWidget && copyrightDetectionWidget) {
toggleWidgetState(useCopyrightDetectionWidget, copyrightDetectionWidget, "copyrightDetection");
}
if (usePreserveInputSizeWidget && preserveInputSizeWidget) {
toggleWidgetState(usePreserveInputSizeWidget, preserveInputSizeWidget, "preserveInputSize");
}
if (useTurboWidget && turboWidget) {
toggleWidgetState(useTurboWidget, turboWidget, "turbo");
}
}
function outpaintSettingsToggleHandler(settingsNode) {
if (!settingsNode?.widgets) return;
const useTopWidget = settingsNode.widgets.find(w => w && w.name === "useTop");
const topWidget = settingsNode.widgets.find(w => w && w.name === "Top");
const useRightWidget = settingsNode.widgets.find(w => w && w.name === "useRight");
const rightWidget = settingsNode.widgets.find(w => w && w.name === "Right");
const useBottomWidget = settingsNode.widgets.find(w => w && w.name === "useBottom");
const bottomWidget = settingsNode.widgets.find(w => w && w.name === "Bottom");
const useLeftWidget = settingsNode.widgets.find(w => w && w.name === "useLeft");
const leftWidget = settingsNode.widgets.find(w => w && w.name === "Left");
const useBlurWidget = settingsNode.widgets.find(w => w && w.name === "useBlur");
const blurWidget = settingsNode.widgets.find(w => w && w.name === "Blur");
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 = settingsNode.htmlElements?.widgetsContainer || settingsNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
settingsNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
if (useTopWidget && topWidget) toggleWidgetState(useTopWidget, topWidget, "Top");
if (useRightWidget && rightWidget) toggleWidgetState(useRightWidget, rightWidget, "Right");
if (useBottomWidget && bottomWidget) toggleWidgetState(useBottomWidget, bottomWidget, "Bottom");
if (useLeftWidget && leftWidget) toggleWidgetState(useLeftWidget, leftWidget, "Left");
if (useBlurWidget && blurWidget) toggleWidgetState(useBlurWidget, blurWidget, "Blur");
}
function safetyInputsToggleHandler(safetyNode) {
const useModeWidget = safetyNode.widgets.find(w => w.name === "useMode");
const modeWidget = safetyNode.widgets.find(w => w.name === "mode");
const useToleranceWidget = safetyNode.widgets.find(w => w.name === "useTolerance");
const toleranceWidget = safetyNode.widgets.find(w => w.name === "tolerance");
const useCheckInputsWidget = safetyNode.widgets.find(w => w.name === "useCheckInputs");
const checkInputsWidget = safetyNode.widgets.find(w => w.name === "checkInputs");
const useCheckContentWidget = safetyNode.widgets.find(w => w.name === "useCheckContent");
const checkContentWidget = safetyNode.widgets.find(w => w.name === "checkContent");
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 = safetyNode.htmlElements?.widgetsContainer || safetyNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
safetyNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
if (useModeWidget && modeWidget) {
toggleWidgetState(useModeWidget, modeWidget, "mode");
}
if (useToleranceWidget && toleranceWidget) {
toggleWidgetState(useToleranceWidget, toleranceWidget, "tolerance");
}
if (useCheckInputsWidget && checkInputsWidget) {
toggleWidgetState(useCheckInputsWidget, checkInputsWidget, "checkInputs");
}
if (useCheckContentWidget && checkContentWidget) {
toggleWidgetState(useCheckContentWidget, checkContentWidget, "checkContent");
}
}
function imageInferenceSettingsColorPaletteToggleHandler(paletteNode) {
function applyParamState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
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 = paletteNode.htmlElements?.widgetsContainer || paletteNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
}
}
}
}
function bindSlot(i) {
const useW = paletteNode.widgets.find((w) => w.name === `use_${i}`);
const hexW = paletteNode.widgets.find((w) => w.name === `hex_${i}`);
const ratioW = paletteNode.widgets.find((w) => w.name === `ratio_${i}`);
if (!useW || !hexW || !ratioW) return;
function toggleSlot() {
applyParamState(useW, hexW, `hex_${i}`);
applyParamState(useW, ratioW, `ratio_${i}`);
paletteNode.setDirtyCanvas(true);
}
appendWidgetCB(useW, () => {
setTimeout(toggleSlot, 50);
});
setTimeout(toggleSlot, 100);
}
for (let i = 1; i <= 8; i++) {
bindSlot(i);
}
}
function imageInferenceSettingsPromptEnhanceToggleHandler(node) {
if (!node?.widgets) return;
const useTemperatureWidget = node.widgets.find((w) => w && w.name === "useTemperature");
const temperatureWidget = node.widgets.find((w) => w && w.name === "temperature");
const useTopPWidget = node.widgets.find((w) => w && w.name === "useTopP");
const topPWidget = node.widgets.find((w) => w && w.name === "topP");
const useEnabledWidget = node.widgets.find((w) => w && w.name === "useEnabled");
const enabledWidget = node.widgets.find((w) => w && w.name === "enabled");
function toggleWidgetState(useWidget, paramWidget) {
if (!useWidget || !paramWidget) return;
function toggleEnabled() {
toggleWidgetEnabled(paramWidget, useWidget.value === true, node);
node.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => setTimeout(toggleEnabled, 50));
setTimeout(toggleEnabled, 100);
}
if (useTemperatureWidget && temperatureWidget) {
toggleWidgetState(useTemperatureWidget, temperatureWidget);
}
if (useTopPWidget && topPWidget) {
toggleWidgetState(useTopPWidget, topPWidget);
}
if (useEnabledWidget && enabledWidget) {
toggleWidgetState(useEnabledWidget, enabledWidget);
}
}
function imageInferenceSettingsMoodboardsToggleHandler(moodboardsNode) {
if (!moodboardsNode?.widgets) return;
const useStrengthWidget = moodboardsNode.widgets.find((w) => w && w.name === "useStrength");
const strengthWidget = moodboardsNode.widgets.find((w) => w && w.name === "strength");
if (!useStrengthWidget || !strengthWidget) return;
function toggleStrengthState() {
const enabled = useStrengthWidget.value === true;
toggleWidgetEnabled(strengthWidget, enabled, moodboardsNode);
moodboardsNode.setDirtyCanvas(true);
}
appendWidgetCB(useStrengthWidget, () => {
setTimeout(toggleStrengthState, 50);
});
setTimeout(toggleStrengthState, 100);
}
function imageInferenceSettingsScoringRubricToggleHandler(rubricNode) {
if (!rubricNode?.widgets) return;
if (rubricNode._imageInferenceSettingsScoringRubricToggleHandlerRegistered) return;
rubricNode._imageInferenceSettingsScoringRubricToggleHandlerRegistered = true;
function toggleWidgetState(useWidget, paramWidgets, paramNames) {
if (!useWidget) return;
const widgets = Array.isArray(paramWidgets) ? paramWidgets : [paramWidgets];
const names = Array.isArray(paramNames) ? paramNames : [paramNames];
function toggleEnabled() {
const enabled = useWidget.value === true;
widgets.forEach((paramWidget, index) => {
if (!paramWidget) return;
toggleWidgetEnabled(paramWidget, enabled, rubricNode);
const paramName = names[index];
if (!paramWidget.inputEl && paramName) {
const nodeElement = rubricNode.htmlElements?.widgetsContainer || rubricNode.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";
}
}
}
});
rubricNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => setTimeout(toggleEnabled, 50));
setTimeout(toggleEnabled, 100);
}
const usePassingScoreWidget = rubricNode.widgets.find((w) => w && w.name === "usePassingScore");
const passingScoreWidget = rubricNode.widgets.find((w) => w && w.name === "passingScore");
if (usePassingScoreWidget && passingScoreWidget) {
toggleWidgetState(usePassingScoreWidget, passingScoreWidget, "passingScore");
}
for (let i = 1; i <= 5; i++) {
const useScoreGuidanceWidget = rubricNode.widgets.find((w) => w && w.name === `useScoreGuidance${i}`);
const scoreWidget = rubricNode.widgets.find((w) => w && w.name === `score${i}`);
const guidanceDescriptionWidget = rubricNode.widgets.find((w) => w && w.name === `guidanceDescription${i}`);
if (useScoreGuidanceWidget && (scoreWidget || guidanceDescriptionWidget)) {
toggleWidgetState(
useScoreGuidanceWidget,
[scoreWidget, guidanceDescriptionWidget].filter(Boolean),
[`score${i}`, `guidanceDescription${i}`]
);
}
}
}
function imageInferenceSettingsStructuredPromptToggleHandler(node) {
if (!node?.widgets) return;
function applyParamState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
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 = node.htmlElements?.widgetsContainer || node.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
}
}
}
}
function toggleWidgetState(useWidget, paramWidget, paramName) {
if (!useWidget || !paramWidget) return;
function toggleEnabled() {
applyParamState(useWidget, paramWidget, paramName);
node.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => setTimeout(toggleEnabled, 50));
setTimeout(toggleEnabled, 100);
}
const useStyleDescriptionWidget = node.widgets.find((w) => w && w.name === "useStyleDescription");
const styleDescriptionWidget = node.widgets.find((w) => w && w.name === "style_description");
if (useStyleDescriptionWidget && styleDescriptionWidget) {
toggleWidgetState(useStyleDescriptionWidget, styleDescriptionWidget, "style_description");
}
const useElementsJsonWidget = node.widgets.find((w) => w && w.name === "useElementsJson");
const elementsJsonWidget = node.widgets.find((w) => w && w.name === "elementsJson");
const elementSlotRefreshers = [];
if (useElementsJsonWidget && elementsJsonWidget) {
toggleWidgetState(useElementsJsonWidget, elementsJsonWidget, "elementsJson");
}
function bindElementSlot(i) {
const useW = node.widgets.find((w) => w && w.name === `use_element_${i}`);
const typeW = node.widgets.find((w) => w && w.name === `element_type_${i}`);
const descW = node.widgets.find((w) => w && w.name === `element_desc_${i}`);
const textW = node.widgets.find((w) => w && w.name === `element_text_${i}`);
const bboxW = node.widgets.find((w) => w && w.name === `element_bbox_${i}`);
const paletteW = node.widgets.find((w) => w && w.name === `element_color_palette_${i}`);
if (!useW) return;
function toggleSlot() {
const jsonMode = useElementsJsonWidget?.value === true;
toggleWidgetEnabled(useW, !jsonMode, node);
const enabled = !jsonMode && useW.value === true;
[typeW, descW, textW, bboxW, paletteW].forEach((w) => {
if (w) toggleWidgetEnabled(w, enabled, node);
});
node.setDirtyCanvas(true);
}
elementSlotRefreshers.push(toggleSlot);
appendWidgetCB(useW, () => setTimeout(toggleSlot, 50));
setTimeout(toggleSlot, 100);
}
for (let i = 1; i <= 8; i++) {
bindElementSlot(i);
}
if (useElementsJsonWidget) {
function refreshElementSlotsForJsonMode() {
elementSlotRefreshers.forEach((refresh) => refresh());
node.setDirtyCanvas(true);
}
appendWidgetCB(useElementsJsonWidget, () => setTimeout(refreshElementSlotsForJsonMode, 50));
setTimeout(refreshElementSlotsForJsonMode, 100);
}
}
function syncProviderSettingsToggleHandler(syncNode) {
// Find all "use" parameter widgets for Sync Provider Settings
const useEditRegionWidget = syncNode.widgets.find(w => w.name === "useEditRegion");
const editRegionWidget = syncNode.widgets.find(w => w.name === "editRegion");
const useEmotionPromptWidget = syncNode.widgets.find(w => w.name === "useEmotionPrompt");
const emotionPromptWidget = syncNode.widgets.find(w => w.name === "emotionPrompt");
const useTemperatureWidget = syncNode.widgets.find(w => w.name === "useTemperature");
const temperatureWidget = syncNode.widgets.find(w => w.name === "temperature");
const useActiveSpeakerDetectionWidget = syncNode.widgets.find(w => w.name === "useActiveSpeakerDetection");
const activeSpeakerDetectionWidget = syncNode.widgets.find(w => w.name === "activeSpeakerDetection");
const useOcclusionDetectionEnabledWidget = syncNode.widgets.find(w => w.name === "useOcclusionDetectionEnabled");
const occlusionDetectionEnabledWidget = syncNode.widgets.find(w => w.name === "occlusionDetectionEnabled");
// Helper function to toggle widget enabled state
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 = syncNode.htmlElements?.widgetsContainer || syncNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
syncNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
// Set up toggle handlers
if (useEditRegionWidget && editRegionWidget) {
toggleWidgetState(useEditRegionWidget, editRegionWidget, "editRegion");
}
if (useEmotionPromptWidget && emotionPromptWidget) {
toggleWidgetState(useEmotionPromptWidget, emotionPromptWidget, "emotionPrompt");
}
if (useTemperatureWidget && temperatureWidget) {
toggleWidgetState(useTemperatureWidget, temperatureWidget, "temperature");
}
if (useActiveSpeakerDetectionWidget && activeSpeakerDetectionWidget) {
toggleWidgetState(useActiveSpeakerDetectionWidget, activeSpeakerDetectionWidget, "activeSpeakerDetection");
}
if (useOcclusionDetectionEnabledWidget && occlusionDetectionEnabledWidget) {
toggleWidgetState(useOcclusionDetectionEnabledWidget, occlusionDetectionEnabledWidget, "occlusionDetectionEnabled");
}
}
function syncSegmentToggleHandler(syncSegmentNode) {
// Find all "use" parameter widgets for Sync Segment
const useAudioStartTimeWidget = syncSegmentNode.widgets.find(w => w.name === "useAudioStartTime");
const audioStartTimeWidget = syncSegmentNode.widgets.find(w => w.name === "audioStartTime");
const useAudioEndTimeWidget = syncSegmentNode.widgets.find(w => w.name === "useAudioEndTime");
const audioEndTimeWidget = syncSegmentNode.widgets.find(w => w.name === "audioEndTime");
// Helper function to toggle widget enabled state
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 = syncSegmentNode.htmlElements?.widgetsContainer || syncSegmentNode.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.cursor = enabled ? "text" : "not-allowed";
input.readOnly = !enabled;
if (input.tagName === "SELECT") {
input.style.pointerEvents = enabled ? "auto" : "none";
}
}
}
}
syncSegmentNode.setDirtyCanvas(true);
}
appendWidgetCB(useWidget, () => {
setTimeout(toggleEnabled, 50);
});
setTimeout(toggleEnabled, 100);
}
// Set up toggle handlers
if (useAudioStartTimeWidget && audioStartTimeWidget) {
toggleWidgetState(useAudioStartTimeWidget, audioStartTimeWidget, "audioStartTime");
}
if (useAudioEndTimeWidget && audioEndTimeWidget) {
toggleWidgetState(useAudioEndTimeWidget, audioEndTimeWidget, "audioEndTime");
}
}