diff --git a/ui/plugins/ui/merge.plugin.js b/ui/plugins/ui/merge.plugin.js deleted file mode 100644 index 68884f79..00000000 --- a/ui/plugins/ui/merge.plugin.js +++ /dev/null @@ -1,373 +0,0 @@ -(function() { - "use strict" - - ///////////////////// Function section - function smoothstep(x) { - return x * x * (3 - 2 * x) - } - - function smootherstep(x) { - return x * x * x * (x * (x * 6 - 15) + 10) - } - - function smootheststep(x) { - let y = -20 * Math.pow(x, 7) - y += 70 * Math.pow(x, 6) - y -= 84 * Math.pow(x, 5) - y += 35 * Math.pow(x, 4) - return y - } - function getCurrentTime() { - const now = new Date(); - let hours = now.getHours(); - let minutes = now.getMinutes(); - let seconds = now.getSeconds(); - - hours = hours < 10 ? `0${hours}` : hours; - minutes = minutes < 10 ? `0${minutes}` : minutes; - seconds = seconds < 10 ? `0${seconds}` : seconds; - - return `${hours}:${minutes}:${seconds}`; - } - - function addLogMessage(message) { - const logContainer = document.getElementById('merge-log'); - logContainer.innerHTML += `${getCurrentTime()} ${message}
`; - - // Scroll to the bottom of the log - logContainer.scrollTop = logContainer.scrollHeight; - } - - function addLogSeparator() { - const logContainer = document.getElementById('merge-log'); - logContainer.innerHTML += '
' - - logContainer.scrollTop = logContainer.scrollHeight; - } - - function drawDiagram(fn) { - const canvas = document.getElementById('merge-canvas'); - canvas.width=canvas.width - const ctx = canvas.getContext('2d'); - - // Draw coordinate system - ctx.scale(1, -1); - ctx.translate(0, -canvas.height); - ctx.lineWidth = 1; - ctx.beginPath(); - - ctx.strokeStyle = 'white' - ctx.moveTo(0,0); ctx.lineTo(0,400); ctx.lineTo(400,400); ctx.lineTo(400,0); ctx.lineTo(0,0); ctx.lineTo(400,400); - ctx.stroke() - ctx.beginPath() - ctx.setLineDash([1,2]) - for (let i=40; i<400; i+=40) { - ctx.moveTo(0,i) - ctx.lineTo(400,i) - ctx.moveTo(i,0) - ctx.lineTo(i,400) - } - ctx.stroke() - ctx.beginPath() - ctx.setLineDash([]) - ctx.beginPath(); - ctx.strokeStyle = 'black' - ctx.lineWidth = 3; - // Plot function - const numSamples = 20; - for (let i = 0; i <= numSamples; i++) { - const x = i / numSamples; - const y = fn(x); - - const canvasX = x * 400; - const canvasY = y * 400; - - if (i === 0) { - ctx.moveTo(canvasX, canvasY); - } else { - ctx.lineTo(canvasX, canvasY); - } - } - ctx.stroke() - // Plot alpha values (yellow boxes) - let start = parseFloat( document.querySelector('#merge-start').value ) - let step = parseFloat( document.querySelector('#merge-step').value ) - let iterations = document.querySelector('#merge-count').value>>0 - ctx.beginPath() - ctx.fillStyle = "yellow" - for (let i=0; i< iterations; i++) { - const alpha = ( start + i * step ) / 100 - const x = alpha*400 - const y = fn(alpha) * 400 - if (x <= 400) { - ctx.rect(x-3,y-3,6,6) - ctx.fill() - } else { - ctx.strokeStyle = 'red' - ctx.moveTo(0,0); ctx.lineTo(0,400); ctx.lineTo(400,400); ctx.lineTo(400,0); ctx.lineTo(0,0); ctx.lineTo(400,400); - ctx.stroke() - addLogMessage('Warning: maximum ratio is ≥ 100%') - } - } - } - - function updateChart() { - let fn = (x) => x - switch (document.querySelector('#merge-interpolation').value) { - case 'SmoothStep': - fn = smoothstep - break - case 'SmootherStep': - fn = smootherstep - break - case 'SmoothestStep': - fn = smootheststep - break - } - drawDiagram(fn) - } - - /////////////////////// Tab implementation - document.querySelector('#tab-container')?.insertAdjacentHTML('beforeend', ` - - Merge models - - `) - - document.querySelector('#tab-content-wrapper')?.insertAdjacentHTML('beforeend', ` -
-
- Loading.. -
-
- `) - - const tabMerge = document.querySelector('#tab-merge') - if (tabMerge) { - linkTabContents(tabMerge) - } - const merge = document.querySelector('#merge') - if (!merge) { - // merge tab not found, dont exec plugin code. - return - } - - document.querySelector('body').insertAdjacentHTML('beforeend', ` - - `) - - merge.innerHTML = ` -
-
-

Batch merger

-

- -

- -

-
-
-
- - - - - - - - - - - - - - - -
- - - - - -
Number of models to create
% Smallest share of model A in the mix
% Share of model A added into the mix per step
Sigmoid function to be applied to the model share before mixing
Image generation uses fp16, so it's a good choice.
Use fp32 if you want to use the result models for more mixes
Base name of the output file.
Mix ratio and file suffix will be appended to this.
Use safetensors. It's the better format. Only use ckpt if you want to use
the models in legacy software not supporting saftensors.
- -
-
- -
-
` - - - /////////////////////// Event Listener - document.addEventListener('tabClick', (e) => { - if (e.detail.name == 'merge') { - console.log('Activate') - let modelList = stableDiffusionModelField.cloneNode(true) - modelList.id = "mergeModelA" - modelList.size = 8 - document.querySelector("#mergeModelA").replaceWith(modelList) - modelList = stableDiffusionModelField.cloneNode(true) - modelList.id = "mergeModelB" - modelList.size = 8 - document.querySelector("#mergeModelB").replaceWith(modelList) - updateChart() - } - }) - - document.querySelector('.merge-config').addEventListener('change', updateChart) - - document.querySelector('#merge-button').addEventListener('click', async function(e) { - // Build request template - let model0 = document.querySelector('#mergeModelA').value - let model1 = document.querySelector('#mergeModelB').value - let request = { model0: model0, model1: model1 } - request['use_fp16'] = document.querySelector('#merge-fp').value == 'fp16' - let iterations = document.querySelector('#merge-count').value>>0 - let start = parseFloat( document.querySelector('#merge-start').value ) - let step = parseFloat( document.querySelector('#merge-step').value ) - addLogMessage(`start = ${start}%`) - addLogMessage(`step = ${step}%`) - - if (start + iterations * (step-1) >= 100) { - addLogMessage('Aborting: maximum ratio is ≥ 100%') - addLogMessage('Reduce the number of steps or the step size') - addLogSeparator() - document.querySelector('#merge-count').focus() - return - } - - if (document.querySelector('#merge-filename').value == "") { - addLogMessage('Aborting: No output file name specified') - addLogSeparator() - document.querySelector('#merge-filename').focus() - return - } - - // Disable merge button - e.target.disabled=true - e.target.classList.add('disabled') - let cursor = $("body").css("cursor"); - let label = document.querySelector('#merge-button').innerHTML - $("body").css("cursor", "progress"); - document.querySelector('#merge-button').innerHTML = 'Merging models ...' - - addLogMessage("Merging models") - addLogMessage("Model A: "+model0) - addLogMessage("Model B: "+model1) - - // Batch main loop - for (let i=0; iDone. The models have been saved to your models/stable-diffusion folder.") - addLogSeparator() - // Re-enable merge button - $("body").css("cursor", cursor); - document.querySelector('#merge-button').innerHTML = label - e.target.disabled=false - e.target.classList.remove('disabled') - - // Update model list - stableDiffusionModelField.innerHTML = '' - vaeModelField.innerHTML = '' - hypernetworkModelField.innerHTML = '' - await getModels() - }) - -})()