Signed-off-by: Vladimir Mandic <mandic00@live.com>
This commit is contained in:
Vladimir Mandic
2026-09-14 13:57:08 +02:00
parent 516b9f4a45
commit 8691654bef
5 changed files with 119 additions and 86 deletions
+29 -29
View File
@@ -220,7 +220,7 @@ axis_options = [
AxisOption("[Model] Model", str, apply_checkpoint, cost=1.0, fmt=format_value_add_label, choices=lambda: sorted(sd_models.checkpoints_list)),
AxisOption("[Model] UNET", str, apply_unet, cost=0.8, choices=lambda: ['None'] + list(sd_unet.unet_dict)),
AxisOption("[Model] VAE", str, apply_vae, cost=0.6, choices=lambda: ['None'] + list(sd_vae.vae_dict)),
AxisOption("[Model] Refiner", str, apply_refiner, cost=0.8, fmt=format_value_add_label, choices=lambda: ['None'] + sorted(sd_models.checkpoints_list)),
AxisOption("[Model] Refiner", str, apply_refiner, cost=0.9, fmt=format_value_add_label, choices=lambda: ['None'] + sorted(sd_models.checkpoints_list)),
AxisOption("[Model] Text encoder", str, apply_te, cost=0.7, choices=shared_items.sd_te_items),
AxisOption("[Prompt] Search & replace", str, apply_prompt_primary, fmt=format_value_add_label),
AxisOption("[Prompt] Search & replace refine", str, apply_prompt_refine, fmt=format_value_add_label),
@@ -228,14 +228,14 @@ axis_options = [
AxisOption("[Prompt] Search & replace all", str, apply_prompt_all, fmt=format_value_add_label),
AxisOption("[Prompt] Prompt order", str_permutations, apply_order, fmt=format_value_join_list),
AxisOption("[Prompt] Prompt parser", str, apply_setting("prompt_attention"), choices=lambda: ["native", "compel", "xhinker", "a1111", "fixed"]),
AxisOption("[Network] LoRA", str, apply_lora, cost=0.5, choices=list_lora),
AxisOption("[Network] LoRA strength", float, apply_lora_strength, cost=0.6),
AxisOption("[Network] LoRA block weight", str, apply_lora_blocks, cost=0.6, fmt=format_value_trim, choices=list_lora_blocks),
AxisOption("[Network] LoRA stack mode", str, apply_setting("lora_stack_mode"), cost=0.6, choices=lambda: ["sum", "ties", "dare_ties", "dare_linear", "magnitude_prune", "klora", "estlora"]),
AxisOption("[Network] LoRA stack density", float, apply_setting("lora_stack_density"), cost=0.6),
AxisOption("[Network] LoRA stack ramp", float, apply_setting("lora_stack_alpha"), cost=0.6),
AxisOption("[Network] LoRA stack discrepancy", float, apply_setting("lora_stack_discrepancy"), cost=0.6),
AxisOption("[Network] LoRA force diffusers", bool, apply_setting("lora_force_diffusers"), cost=0.6, choices=lambda: [False, True]),
AxisOption("[Network] LoRA", str, apply_lora, cost=0.6, choices=list_lora),
AxisOption("[Network] LoRA strength", float, apply_lora_strength, cost=0.5),
AxisOption("[Network] LoRA block weight", str, apply_lora_blocks, cost=0.5, fmt=format_value_trim, choices=list_lora_blocks),
AxisOption("[Network] LoRA stack mode", str, apply_setting("lora_stack_mode"), cost=0.5, choices=lambda: ["sum", "ties", "dare_ties", "dare_linear", "magnitude_prune", "klora", "estlora"]),
AxisOption("[Network] LoRA stack density", float, apply_setting("lora_stack_density"), cost=0.5),
AxisOption("[Network] LoRA stack ramp", float, apply_setting("lora_stack_alpha"), cost=0.5),
AxisOption("[Network] LoRA stack discrepancy", float, apply_setting("lora_stack_discrepancy"), cost=0.5),
AxisOption("[Network] LoRA force diffusers", bool, apply_setting("lora_force_diffusers"), cost=0.65, choices=lambda: [False, True]),
AxisOption("[Network] Styles", str, apply_styles, choices=lambda: [s.name for s in shared.prompt_styles.styles.values()]),
AxisOption("[Param] Width", int, apply_field("width")),
AxisOption("[Param] Height", int, apply_field("height")),
@@ -270,7 +270,7 @@ axis_options = [
AxisOption("[Guidance] Start", float, apply_field("cfg_start")),
AxisOption("[Guidance] Stop", float, apply_field("cfg_stop")),
AxisOption("[Guidance] Image scale", float, apply_field("cfg_image")),
AxisOption("[Refine] Upscaler", str, apply_field("hr_upscaler"), cost=0.3, choices=lambda: [x.name for x in shared.sd_upscalers]),
AxisOption("[Refine] Upscaler", str, apply_field("hr_upscaler"), cost=0.4, choices=lambda: [x.name for x in shared.sd_upscalers]),
AxisOption("[Refine] Sampler", str, apply_hr_sampler_name, fmt=format_value_add_label, confirm=confirm_samplers, choices=lambda: [x.name for x in sd_samplers.visible_samplers()]),
AxisOption("[Refine] Denoising strength", float, apply_field("denoising_strength")),
AxisOption("[Refine] Hires steps", int, apply_field("hr_second_pass_steps")),
@@ -280,21 +280,21 @@ axis_options = [
AxisOption("[Postprocess] Context", str, apply_context, choices=lambda: ["Add with forward", "Remove with forward", "Add with backward", "Remove with backward"]),
AxisOption("[Postprocess] Detailer", bool, apply_detailer, fmt=format_bool, choices=lambda: [False, True]),
AxisOption("[Postprocess] Detailer strength", str, apply_field("detailer_strength")),
AxisOption("[Quant] SDNQ quant mode", str, apply_sdnq_quant, cost=0.9, fmt=format_value_add_label, choices=lambda: ['none'] + sorted(shared_items.sdnq_quant_modes)),
AxisOption("[Quant] SDNQ quant mode TE", str, apply_sdnq_quant_te, cost=0.9, fmt=format_value_add_label, choices=lambda: ['none'] + sorted(shared_items.sdnq_quant_modes)),
AxisOption("[Attention] Method", str, apply_setting('cross_attention_optimization'), cost=0.2, choices=shared_items.list_crossattention),
AxisOption("[Attention] Dispatcher", str, apply_attention_dispatcher, cost=0.2, choices=lambda: ['None'] + attention.list_dispatcher_backends()),
AxisOption("[Attention] SDNQ matmul", str, apply_attention('sdnq_attention_matmul_type'), cost=0.2, choices=lambda: list(shared_items.sdnq_matmul_modes)),
AxisOption("[Attention] SDNQ PV matmul", str, apply_attention('sdnq_attention_pv_matmul_type'), cost=0.2, choices=lambda: list(shared_items.sdnq_matmul_modes)),
AxisOption("[Attention] SDNQ smooth K", str, apply_attention('sdnq_attention_smooth_k'), cost=0.2, choices=lambda: ['False', 'True']),
AxisOption("[Attention] SDNQ hadamard", str, apply_attention('sdnq_attention_use_hadamard'), cost=0.2, choices=lambda: ['False', 'True']),
AxisOption("[Attention] SDNQ fp16 accumulation", str, apply_attention('sdnq_attention_use_fp16_accum'), cost=0.2, choices=lambda: ['False', 'True']),
AxisOption("[Sparse] Enabled", str, apply_attention('sparse_attention_enabled'), cost=0.2, choices=lambda: ['False', 'True']),
AxisOption("[Sparse] KV budget", int, apply_attention('sparse_attention_budget'), cost=0.2),
AxisOption("[Sparse] Minimum sequence", int, apply_attention('sparse_attention_min_tokens'), cost=0.2),
AxisOption("[Sparse] Dense steps", int, apply_attention('sparse_attention_schedule_steps'), cost=0.2),
AxisOption("[Sparse] Dense step bonus", int, apply_attention('sparse_attention_schedule_bump'), cost=0.2),
AxisOption("[Sparse] Shared heads", str, apply_attention('sparse_attention_head_shared'), cost=0.2, choices=lambda: ['False', 'True']),
AxisOption("[Quant] SDNQ quant mode", str, apply_sdnq_quant, cost=0.85, fmt=format_value_add_label, choices=lambda: ['none'] + sorted(shared_items.sdnq_quant_modes)),
AxisOption("[Quant] SDNQ quant mode TE", str, apply_sdnq_quant_te, cost=0.85, fmt=format_value_add_label, choices=lambda: ['none'] + sorted(shared_items.sdnq_quant_modes)),
AxisOption("[Attention] Method", str, apply_setting('cross_attention_optimization'), cost=0.4, choices=shared_items.list_crossattention),
AxisOption("[Attention] Dispatcher", str, apply_attention_dispatcher, cost=0.4, choices=lambda: ['None'] + attention.list_dispatcher_backends()),
AxisOption("[Attention] SDNQ matmul", str, apply_attention('sdnq_attention_matmul_type'), cost=0.4, choices=lambda: list(shared_items.sdnq_matmul_modes)),
AxisOption("[Attention] SDNQ PV matmul", str, apply_attention('sdnq_attention_pv_matmul_type'), cost=0.4, choices=lambda: list(shared_items.sdnq_matmul_modes)),
AxisOption("[Attention] SDNQ smooth K", str, apply_attention('sdnq_attention_smooth_k'), cost=0.4, choices=lambda: ['False', 'True']),
AxisOption("[Attention] SDNQ hadamard", str, apply_attention('sdnq_attention_use_hadamard'), cost=0.4, choices=lambda: ['False', 'True']),
AxisOption("[Attention] SDNQ fp16 accumulation", str, apply_attention('sdnq_attention_use_fp16_accum'), cost=0.4, choices=lambda: ['False', 'True']),
AxisOption("[Sparse] Enabled", str, apply_attention('sparse_attention_enabled'), cost=0.3, choices=lambda: ['False', 'True']),
AxisOption("[Sparse] KV budget", int, apply_attention('sparse_attention_budget'), cost=0.3),
AxisOption("[Sparse] Minimum sequence", int, apply_attention('sparse_attention_min_tokens'), cost=0.3),
AxisOption("[Sparse] Dense steps", int, apply_attention('sparse_attention_schedule_steps'), cost=0.3),
AxisOption("[Sparse] Dense step bonus", int, apply_attention('sparse_attention_schedule_bump'), cost=0.3),
AxisOption("[Sparse] Shared heads", str, apply_attention('sparse_attention_head_shared'), cost=0.3, choices=lambda: ['False', 'True']),
AxisOption("[HDR] Mode", int, apply_field("hdr_mode")),
AxisOption("[HDR] Brightness", float, apply_field("hdr_brightness")),
AxisOption("[HDR] Color", float, apply_field("hdr_color")),
@@ -311,13 +311,13 @@ axis_options = [
AxisOption("[FreeU] 2nd stage backbone factor", float, apply_setting('freeu_b2')),
AxisOption("[FreeU] 1st stage skip factor", float, apply_setting('freeu_s1')),
AxisOption("[FreeU] 2nd stage skip factor", float, apply_setting('freeu_s2')),
AxisOption("[IP adapter] Name", str, apply_field('ip_adapter_names'), cost=1.0, choices=lambda: list(ipadapter.ADAPTERS)),
AxisOption("[IP adapter] Name", str, apply_field('ip_adapter_names'), cost=0.6, choices=lambda: list(ipadapter.ADAPTERS)),
AxisOption("[IP adapter] Scale", float, apply_field('ip_adapter_scales')),
AxisOption("[IP adapter] Starts", float, apply_field('ip_adapter_starts')),
AxisOption("[IP adapter] Ends", float, apply_field('ip_adapter_ends')),
AxisOption("[Control] ControlNet", str, apply_control('controlnet'), cost=0.9, choices=lambda: list(controlnet.all_models)),
AxisOption("[Control] T2IAdapter", str, apply_control('t2i adapter'), cost=0.9, choices=lambda: list(t2iadapter.all_models)),
AxisOption("[Control] Processor", str, apply_control('processor'), cost=0.6, choices=lambda: processor.processors),
AxisOption("[Control] ControlNet", str, apply_control('controlnet'), cost=0.7, choices=lambda: list(controlnet.all_models)),
AxisOption("[Control] T2IAdapter", str, apply_control('t2i adapter'), cost=0.7, choices=lambda: list(t2iadapter.all_models)),
AxisOption("[Control] Processor", str, apply_control('processor'), cost=0.4, choices=lambda: processor.processors),
AxisOption("[Control] Strength", float, apply_control('control_strength')),
AxisOption("[Control] Start", float, apply_control('control_start')),
AxisOption("[Control] End", float, apply_control('control_end')),
+85 -54
View File
@@ -16241,6 +16241,8 @@ async function initStartup() {
onUiLoaded(initStartup);
onUiReady(() => log("uiReady"));
window.initStartup = initStartup;
window.addEventListener("pageshow", (evt) => log("pageShow", evt));
window.addEventListener("pagehide", (evt) => log("pageHide", evt));
// ui/extensions.ts
function extensions_apply(_extensionsDisabledList, _extensionsUpdateList, disableAll) {
@@ -16397,6 +16399,9 @@ var selectedType = [];
var selectedBase = [];
var selectedModelId = [];
var selectedVersionId = [];
var currentModel = null;
var precisionOrder = ["fp32", "bf16", "fp16", "fp8", "int8", "int4"];
var companionTypes = ["VAE", "Text Encoder"];
function clearModelDetails() {
const el2 = gradioApp().getElementById("model-details") || gradioApp().getElementById("civitai_models_output") || gradioApp().getElementById("models_outcome");
if (!el2) return;
@@ -16427,6 +16432,7 @@ var modelDetailsHTML = `
<th>Type</th>
<th>Base</th>
<th>File</th>
<th>Variant</th>
<th>Updated</th>
<th>Size</th>
<th>Availability</th>
@@ -16439,19 +16445,65 @@ var modelDetailsHTML = `
</table>
</div>
`;
var modelVersionsHTML = `
<tr>
<td>{url}</td>
<td>{name}</td>
<td>{type}</td>
<td>{base}</td>
<td>{file}</td>
<td>{mtime}</td>
<td>{size}</td>
<td>{availability}</td>
<td><div>{desc}</div></td>
</tr>
`;
function fileVariant(file) {
return file.metadata?.fp || file.metadata?.quantType || null;
}
function sortFiles(files) {
const isModel = (f) => f.type === "Model" || f.type === "Pruned Model";
const rank = (f) => {
const index = precisionOrder.indexOf((fileVariant(f) || "").toLowerCase());
return index < 0 ? precisionOrder.length : index;
};
return [...files].sort((a, b) => Number(isModel(b)) - Number(isModel(a)) || rank(a) - rank(b) || (b.size || 0) - (a.size || 0));
}
function insertNameSuffix(name, suffix) {
const dot = name.lastIndexOf(".");
return dot > 0 ? `${name.slice(0, dot)}-${suffix}${name.slice(dot)}` : `${name}-${suffix}`;
}
function fileSaveName(file, siblings) {
const tier1 = (f) => {
const variant = fileVariant(f);
return variant ? insertNameSuffix(f.name || "", variant) : f.name || "";
};
const tier2 = (f) => f.metadata?.size ? insertNameSuffix(tier1(f), f.metadata.size) : tier1(f);
const others = siblings.filter((s) => s.id !== file.id);
const name = tier1(file);
if (!others.some((s) => tier1(s) === name)) return name;
const sized = tier2(file);
if (!others.some((s) => tier2(s) === sized)) return sized;
return insertNameSuffix(name, String(file.id));
}
function escapeHTML(text) {
return text.replace(/[&<>"']/g, (c) => `&#${c.charCodeAt(0)};`);
}
function versionRows(version, divider) {
const files = sortFiles(version.files);
const entries = files.length > 0 ? files : [null];
const border = divider ? ' style="border-top: 1px solid var(--sd-panel-border-color, #555)"' : "";
const span = entries.length > 1 ? ` rowspan="${entries.length}"` : "";
const versionCell = (content) => `<td${span}${border}>${content}</td>`;
return entries.map((file, i) => {
const first = i === 0;
const cell = (content) => `<td${first ? border : ""}>${content}</td>`;
const link = file ? `<div class="link" onclick="startCivitFileDownload(${version.id}, ${file.id})"> \u{F01DA} </div>` : "";
const name = file ? `<a href="${escapeHTML(file.url || "")}" target="_blank" rel="noopener noreferrer">${escapeHTML(file.name || "unknown")}</a>${file.primary ? ' <span title="Primary file">\u2605</span>' : ""}` : "unknown";
const variant = file ? [fileVariant(file), file.metadata?.size].filter(Boolean).join(" \xB7 ") : "";
const size = file?.size ? `${(file.size / 1024 / 1024 / 1024).toFixed(2)} GB` : "unknown";
const cells = [
cell(link),
first ? versionCell(escapeHTML(version.name || "unknown")) : "",
cell(escapeHTML(file?.type || "unknown")),
first ? versionCell(escapeHTML(version.base || "unknown")) : "",
cell(name),
cell(escapeHTML(variant || "-")),
first ? versionCell(new Date(version.mtime).toLocaleDateString()) : "",
cell(size),
first ? versionCell(escapeHTML(version.availability || "unknown")) : "",
first ? versionCell(`<div>${version.desc || "no description available"}</div>`) : ""
];
return `<tr>${cells.join("")}</tr>`;
}).join("");
}
async function modelCardClick(id) {
log("modelCardClick id", id);
const el2 = gradioApp().getElementById("model-details") || gradioApp().getElementById("civitai_models_output") || gradioApp().getElementById("models_outcome");
@@ -16465,17 +16517,8 @@ async function modelCardClick(id) {
log("modelCardClick data", dataArray);
if (!dataArray || dataArray.length === 0) return;
const data = dataArray[0];
const versionsHTML = data.versions.map((v) => modelVersionsHTML.format({
url: `<div class="link" onclick="startCivitDownload('${v.files[0]?.url}', '${v.files[0]?.name}', '${data.type}', '${v.base || ""}', ${data.id}, ${v.id})"> \u{F01DA} </div>`,
name: v.name || "unknown",
type: v.files[0]?.type || "unknown",
base: v.base || "unknown",
mtime: new Date(v.mtime).toLocaleDateString(),
availability: v.availability || "unknown",
size: v.files[0]?.size ? `${(v.files[0].size / 1024 / 1024).toFixed(2)} MB` : "unknown",
file: `<a href=${v.files[0]?.url} target="_blank" rel="noopener noreferrer">${v.files[0]?.name || "unknown"}</a>`,
desc: v.desc || "no description available"
})).join("");
currentModel = data;
const versionsHTML = data.versions.map((v, i) => versionRows(v, i > 0)).join("");
const url2 = `<a href="${data.url}" target="_blank" rel="noopener noreferrer">${data.name || "unknown"}</a>`;
const creator = `<a href="https://civitai.com/user/${data.creator}" target="_blank" rel="noopener noreferrer">${data.creator || "unknown"}</a>`;
const images = data.versions.map((v) => v.images).flat().map((i) => i.url);
@@ -16495,41 +16538,29 @@ async function modelCardClick(id) {
el2.innerHTML = modelHTML;
}
window.modelCardClick = modelCardClick;
function startCivitDownload(url2, name, type, base, modelId, versionId) {
log("startCivitDownload", { url: url2, name, type, base, modelId, versionId });
selectedURL = [url2];
selectedName = [name];
selectedType = [type];
selectedBase = [base || ""];
selectedModelId = [modelId || 0];
selectedVersionId = [versionId || 0];
function queueFiles(model, queued) {
selectedURL = queued.map(({ file }) => file.url || "");
selectedName = queued.map(({ version, file }) => fileSaveName(file, version.files));
selectedType = queued.map(({ file }) => (companionTypes.includes(file.type || "") ? file.type : model.type) || "");
selectedBase = queued.map(({ version }) => version.base || "");
selectedModelId = queued.map(() => model.id || 0);
selectedVersionId = queued.map(({ version }) => version.id || 0);
const civitDownloadBtn = gradioApp().getElementById("civitai_download_btn");
if (civitDownloadBtn) civitDownloadBtn.click();
}
window.startCivitDownload = startCivitDownload;
function startCivitFileDownload(versionId, fileId) {
log("startCivitFileDownload", { versionId, fileId });
const version = currentModel?.versions.find((v) => v.id === versionId);
const file = version?.files.find((f) => f.id === fileId);
if (!currentModel || !version || !file) return;
queueFiles(currentModel, [{ version, file }]);
}
window.startCivitFileDownload = startCivitFileDownload;
function startCivitAllDownload(evt) {
log("startCivitAllDownload", evt);
const table = gradioApp().getElementById("model-versions-table");
if (!table) return;
const versions = table.querySelectorAll("tr");
selectedURL = [];
selectedName = [];
selectedType = [];
selectedBase = [];
selectedModelId = [];
selectedVersionId = [];
for (const version of versions) {
const parsed = version.querySelector("td:nth-child(1) div")?.getAttribute("onclick")?.match(/startCivitDownload\('([^']+)', '([^']+)', '([^']+)', '([^']*)', (\d+), (\d+)\)/);
if (!parsed || parsed.length < 7) continue;
selectedURL.push(parsed[1]);
selectedName.push(parsed[2]);
selectedType.push(parsed[3]);
selectedBase.push(parsed[4]);
selectedModelId.push(parseInt(parsed[5], 10));
selectedVersionId.push(parseInt(parsed[6], 10));
}
const civitDownloadBtn = gradioApp().getElementById("civitai_download_btn");
if (civitDownloadBtn) civitDownloadBtn.click();
if (!currentModel) return;
const queued = currentModel.versions.map((version) => ({ version, file: version.files.find((f) => f.primary) || version.files[0] })).filter((entry) => !!entry.file);
queueFiles(currentModel, queued);
}
window.startCivitAllDownload = startCivitAllDownload;
function downloadCivitModel(modelUrl, modelName, modelType, modelBase, mId, vId, modelPath, civitToken, innerHTML) {
+2 -2
View File
File diff suppressed because one or more lines are too long
+2
View File
@@ -133,6 +133,8 @@ onUiLoaded(initStartup);
onUiReady(() => log('uiReady'));
window.initStartup = initStartup;
window.addEventListener('pageshow', (evt) => log('pageShow', evt));
window.addEventListener('pagehide', (evt) => log('pageHide', evt));
// onAfterUiUpdate(() => log('evt onAfterUiUpdate'));
// onUiLoaded(() => log('evt onUiLoaded'));