|
|
import { app } from "../../../scripts/app.js";
|
|
|
import { addMenuHandler } from "./common/utils.js";
|
|
|
import { addNode } from "./common/utils.js";
|
|
|
|
|
|
function createKSamplerEntry(node, samplerType, subNodeType = null, isSDXL = false) {
|
|
|
const samplerLabelMap = {
|
|
|
"Eff": "KSampler (Efficient)",
|
|
|
"Adv": "KSampler Adv. (Efficient)",
|
|
|
"SDXL": "KSampler SDXL (Eff.)"
|
|
|
};
|
|
|
|
|
|
const subNodeLabelMap = {
|
|
|
"XYPlot": "XY Plot",
|
|
|
"NoiseControl": "Noise Control Script",
|
|
|
"HiResFix": "HighRes-Fix Script",
|
|
|
"TiledUpscale": "Tiled Upscaler Script",
|
|
|
"AnimateDiff": "AnimateDiff Script"
|
|
|
};
|
|
|
|
|
|
const nicknameMap = {
|
|
|
"KSampler (Efficient)": "KSampler",
|
|
|
"KSampler Adv. (Efficient)": "KSampler(Adv)",
|
|
|
"KSampler SDXL (Eff.)": "KSampler",
|
|
|
"XY Plot": "XY Plot",
|
|
|
"Noise Control Script": "NoiseControl",
|
|
|
"HighRes-Fix Script": "HiResFix",
|
|
|
"Tiled Upscaler Script": "TiledUpscale",
|
|
|
"AnimateDiff Script": "AnimateDiff"
|
|
|
};
|
|
|
|
|
|
const kSamplerLabel = samplerLabelMap[samplerType];
|
|
|
const subNodeLabel = subNodeLabelMap[subNodeType];
|
|
|
|
|
|
const kSamplerNickname = nicknameMap[kSamplerLabel];
|
|
|
const subNodeNickname = nicknameMap[subNodeLabel];
|
|
|
|
|
|
const contentLabel = subNodeNickname ? `${kSamplerNickname} + ${subNodeNickname}` : kSamplerNickname;
|
|
|
|
|
|
return {
|
|
|
content: contentLabel,
|
|
|
callback: function() {
|
|
|
const kSamplerNode = addNode(kSamplerLabel, node, { shiftX: node.size[0] + 50 });
|
|
|
|
|
|
|
|
|
node.connect(0, kSamplerNode, 0);
|
|
|
node.connect(1, kSamplerNode, 1);
|
|
|
node.connect(2, kSamplerNode, 2);
|
|
|
|
|
|
|
|
|
if (!isSDXL) {
|
|
|
node.connect(3, kSamplerNode, 3);
|
|
|
node.connect(4, kSamplerNode, 4);
|
|
|
}
|
|
|
|
|
|
if (subNodeLabel) {
|
|
|
const subNode = addNode(subNodeLabel, node, { shiftX: 50, shiftY: node.size[1] + 50 });
|
|
|
const dependencyIndex = isSDXL ? 3 : 5;
|
|
|
node.connect(dependencyIndex, subNode, 0);
|
|
|
subNode.connect(0, kSamplerNode, dependencyIndex);
|
|
|
}
|
|
|
},
|
|
|
};
|
|
|
}
|
|
|
|
|
|
function createStackerNode(node, type) {
|
|
|
const stackerLabelMap = {
|
|
|
"LoRA": "LoRA Stacker",
|
|
|
"ControlNet": "Control Net Stacker"
|
|
|
};
|
|
|
|
|
|
const contentLabel = stackerLabelMap[type];
|
|
|
|
|
|
return {
|
|
|
content: contentLabel,
|
|
|
callback: function() {
|
|
|
const stackerNode = addNode(contentLabel, node);
|
|
|
|
|
|
|
|
|
const shiftX = -(stackerNode.size[0] + 25);
|
|
|
|
|
|
stackerNode.pos[0] += shiftX;
|
|
|
|
|
|
|
|
|
if (type === "ControlNet") {
|
|
|
stackerNode.pos[1] += 300;
|
|
|
}
|
|
|
|
|
|
|
|
|
if (type === "LoRA") {
|
|
|
stackerNode.connect(0, node, 0);
|
|
|
} else if (type === "ControlNet") {
|
|
|
stackerNode.connect(0, node, 1);
|
|
|
}
|
|
|
},
|
|
|
};
|
|
|
}
|
|
|
|
|
|
function createXYPlotNode(node, type) {
|
|
|
const contentLabel = "XY Plot";
|
|
|
|
|
|
return {
|
|
|
content: contentLabel,
|
|
|
callback: function() {
|
|
|
const xyPlotNode = addNode(contentLabel, node);
|
|
|
|
|
|
|
|
|
const centerXShift = (node.size[0] - xyPlotNode.size[0]) / 2;
|
|
|
xyPlotNode.pos[0] += centerXShift;
|
|
|
|
|
|
|
|
|
xyPlotNode.pos[1] += node.size[1] + 60;
|
|
|
|
|
|
|
|
|
if (type === "Efficient") {
|
|
|
node.connect(6, xyPlotNode, 0);
|
|
|
} else if (type === "SDXL") {
|
|
|
node.connect(3, xyPlotNode, 0);
|
|
|
}
|
|
|
},
|
|
|
};
|
|
|
}
|
|
|
|
|
|
function getMenuValues(type, node) {
|
|
|
const subNodeTypes = [null, "XYPlot", "NoiseControl", "HiResFix", "TiledUpscale", "AnimateDiff"];
|
|
|
const excludedSubNodeTypes = ["NoiseControl", "HiResFix", "TiledUpscale", "AnimateDiff"];
|
|
|
|
|
|
const menuValues = [];
|
|
|
|
|
|
|
|
|
menuValues.push(createStackerNode(node, "LoRA"));
|
|
|
menuValues.push(createStackerNode(node, "ControlNet"));
|
|
|
|
|
|
for (const subNodeType of subNodeTypes) {
|
|
|
|
|
|
if (!excludedSubNodeTypes.includes(subNodeType)) {
|
|
|
const menuEntry = createKSamplerEntry(node, type === "Efficient" ? "Eff" : "SDXL", subNodeType, type === "SDXL");
|
|
|
menuValues.push(menuEntry);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
menuValues.splice(3, 0, createXYPlotNode(node, type));
|
|
|
|
|
|
return menuValues;
|
|
|
}
|
|
|
|
|
|
function showAddLinkMenuCommon(value, options, e, menu, node, type) {
|
|
|
const values = getMenuValues(type, node);
|
|
|
new LiteGraph.ContextMenu(values, {
|
|
|
event: e,
|
|
|
callback: null,
|
|
|
parentMenu: menu,
|
|
|
node: node
|
|
|
});
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
|
|
|
app.registerExtension({
|
|
|
name: "efficiency.addLinks",
|
|
|
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
|
|
const linkTypes = {
|
|
|
"Efficient Loader": "Efficient",
|
|
|
"Eff. Loader SDXL": "SDXL"
|
|
|
};
|
|
|
|
|
|
const linkType = linkTypes[nodeData.name];
|
|
|
|
|
|
if (linkType) {
|
|
|
addMenuHandler(nodeType, function(insertOption) {
|
|
|
insertOption({
|
|
|
content: "⛓ Add link...",
|
|
|
has_submenu: true,
|
|
|
callback: (value, options, e, menu, node) => showAddLinkMenuCommon(value, options, e, menu, node, linkType)
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
},
|
|
|
});
|
|
|
|
|
|
|