|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function () { |
|
var FakeTextMetrics, |
|
proto, |
|
fontSetterNative, |
|
measureTextNative, |
|
fillTextNative, |
|
strokeTextNative; |
|
|
|
if ( |
|
!window.CanvasRenderingContext2D || |
|
!window.TextMetrics || |
|
!(proto = window.CanvasRenderingContext2D.prototype) || |
|
!proto.hasOwnProperty("font") || |
|
!proto.hasOwnProperty("mozTextStyle") || |
|
typeof proto.__lookupSetter__ !== "function" || |
|
!(fontSetterNative = proto.__lookupSetter__("font")) |
|
) { |
|
return; |
|
} |
|
|
|
proto.__defineSetter__("font", function (value) { |
|
try { |
|
return fontSetterNative.call(this, value); |
|
} catch (e) { |
|
if (e.name !== "NS_ERROR_FAILURE") { |
|
throw e; |
|
} |
|
} |
|
}); |
|
|
|
measureTextNative = proto.measureText; |
|
FakeTextMetrics = function () { |
|
this.width = 0; |
|
this.isFake = true; |
|
this.__proto__ = window.TextMetrics.prototype; |
|
}; |
|
proto.measureText = function ($0) { |
|
try { |
|
return measureTextNative.apply(this, arguments); |
|
} catch (e) { |
|
if (e.name !== "NS_ERROR_FAILURE") { |
|
throw e; |
|
} else { |
|
return new FakeTextMetrics(); |
|
} |
|
} |
|
}; |
|
|
|
fillTextNative = proto.fillText; |
|
proto.fillText = function ($0, $1, $2, $3) { |
|
try { |
|
fillTextNative.apply(this, arguments); |
|
} catch (e) { |
|
if (e.name !== "NS_ERROR_FAILURE") { |
|
throw e; |
|
} |
|
} |
|
}; |
|
|
|
strokeTextNative = proto.strokeText; |
|
proto.strokeText = function ($0, $1, $2, $3) { |
|
try { |
|
strokeTextNative.apply(this, arguments); |
|
} catch (e) { |
|
if (e.name !== "NS_ERROR_FAILURE") { |
|
throw e; |
|
} |
|
} |
|
}; |
|
})(); |
|
|
|
|
|
const urlParams = new URLSearchParams(window.location.search); |
|
|
|
window.onload = startup; |
|
|
|
var stableDiffusionData = { |
|
|
|
prompt: "", |
|
negative_prompt: "", |
|
seed: -1, |
|
cfg_scale: null, |
|
sampler_index: "DDIM", |
|
steps: null, |
|
denoising_strength: 1, |
|
mask_blur: 0, |
|
batch_size: null, |
|
width: 512, |
|
height: 512, |
|
n_iter: null, |
|
mask: "", |
|
init_images: [], |
|
inpaint_full_res: false, |
|
inpainting_fill: 1, |
|
outpainting_fill: 2, |
|
enable_hr: false, |
|
restore_faces: false, |
|
|
|
|
|
hr_scale: 2.0, |
|
hr_upscaler: "None", |
|
hr_second_pass_steps: 0, |
|
hr_resize_x: 0, |
|
hr_resize_y: 0, |
|
hr_square_aspect: false, |
|
styles: [], |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
var host = ""; |
|
var url = "/sdapi/v1/"; |
|
const basePixelCount = 64; |
|
var focused = true; |
|
let defaultScripts = {}; |
|
let userScripts = {}; |
|
|
|
function startup() { |
|
testHostConfiguration(); |
|
loadSettings(); |
|
|
|
const hostEl = document.getElementById("host"); |
|
testHostConnection().then((checkConnection) => { |
|
hostEl.onchange = () => { |
|
host = hostEl.value.endsWith("/") |
|
? hostEl.value.substring(0, hostEl.value.length - 1) |
|
: hostEl.value; |
|
hostEl.value = host; |
|
localStorage.setItem("openoutpaint/host", host); |
|
checkConnection(); |
|
}; |
|
}); |
|
|
|
drawBackground(); |
|
changeMaskBlur(); |
|
changeSmoothRendering(); |
|
changeSeed(); |
|
changeHiResFix(); |
|
changeHiResSquare(); |
|
changeRestoreFaces(); |
|
changeSyncCursorSize(); |
|
changeControlNetExtension(); |
|
changeControlNetReference(); |
|
checkFocus(); |
|
refreshScripts(); |
|
} |
|
|
|
function setFixedHost(h, changePromptMessage) { |
|
console.info(`[index] Fixed host to '${h}'`); |
|
const hostInput = document.getElementById("host"); |
|
host = h; |
|
hostInput.value = h; |
|
hostInput.readOnly = true; |
|
hostInput.style.cursor = "default"; |
|
hostInput.style.backgroundColor = "#ddd"; |
|
hostInput.addEventListener("dblclick", async () => { |
|
if (await notifications.dialog("Host is Locked", changePromptMessage)) { |
|
hostInput.style.backgroundColor = null; |
|
hostInput.style.cursor = null; |
|
hostInput.readOnly = false; |
|
hostInput.focus(); |
|
} |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
function testHostConfiguration() { |
|
|
|
|
|
|
|
const hostEl = document.getElementById("host"); |
|
hostEl.value = localStorage.getItem("openoutpaint/host"); |
|
|
|
const requestHost = (prompt, def = "http://127.0.0.1:7860") => { |
|
let value = null; |
|
|
|
if (!urlParams.has("noprompt")) value = window.prompt(prompt, def); |
|
if (value === null) value = def; |
|
|
|
value = value.endsWith("/") ? value.substring(0, value.length - 1) : value; |
|
host = value; |
|
hostEl.value = host; |
|
localStorage.setItem("openoutpaint/host", host); |
|
}; |
|
|
|
const current = localStorage.getItem("openoutpaint/host"); |
|
if (current) { |
|
if (!current.match(/^https?:\/\/[a-z0-9][a-z0-9.]+[a-z0-9](:[0-9]+)?$/i)) |
|
requestHost( |
|
"Host seems to be invalid! Please fix your host here:", |
|
current |
|
); |
|
else |
|
host = current.endsWith("/") |
|
? current.substring(0, current.length - 1) |
|
: current; |
|
} else { |
|
requestHost( |
|
"This seems to be the first time you are using openOutpaint! Please set your host here:" |
|
); |
|
} |
|
} |
|
|
|
async function testHostConnection() { |
|
class CheckInProgressError extends Error {} |
|
|
|
const connectionIndicator = document.getElementById( |
|
"connection-status-indicator" |
|
); |
|
|
|
let connectionStatus = false; |
|
let firstTimeOnline = true; |
|
|
|
const setConnectionStatus = (status) => { |
|
const connectionIndicatorText = document.getElementById( |
|
"connection-status-indicator-text" |
|
); |
|
|
|
const statuses = { |
|
online: () => { |
|
connectionIndicator.classList.add("online"); |
|
connectionIndicator.classList.remove( |
|
"webui-issue", |
|
"offline", |
|
"before", |
|
"server-error" |
|
); |
|
connectionIndicatorText.textContent = connectionIndicator.title = |
|
"Connected"; |
|
connectionStatus = true; |
|
}, |
|
error: () => { |
|
connectionIndicator.classList.add("server-error"); |
|
connectionIndicator.classList.remove( |
|
"online", |
|
"offline", |
|
"before", |
|
"webui-issue" |
|
); |
|
connectionIndicatorText.textContent = "Error"; |
|
connectionIndicator.title = |
|
"Server is online, but is returning an error response"; |
|
connectionStatus = false; |
|
}, |
|
corsissue: () => { |
|
connectionIndicator.classList.add("webui-issue"); |
|
connectionIndicator.classList.remove( |
|
"online", |
|
"offline", |
|
"before", |
|
"server-error" |
|
); |
|
connectionIndicatorText.textContent = "CORS"; |
|
connectionIndicator.title = |
|
"Server is online, but CORS is blocking our requests"; |
|
connectionStatus = false; |
|
}, |
|
apiissue: () => { |
|
connectionIndicator.classList.add("webui-issue"); |
|
connectionIndicator.classList.remove( |
|
"online", |
|
"offline", |
|
"before", |
|
"server-error" |
|
); |
|
connectionIndicatorText.textContent = "API"; |
|
connectionIndicator.title = |
|
"Server is online, but the API seems to be disabled"; |
|
connectionStatus = false; |
|
}, |
|
offline: () => { |
|
connectionIndicator.classList.add("offline"); |
|
connectionIndicator.classList.remove( |
|
"webui-issue", |
|
"online", |
|
"before", |
|
"server-error" |
|
); |
|
connectionIndicatorText.textContent = "Offline"; |
|
connectionIndicator.title = |
|
"Server seems to be offline. Please check the console for more information."; |
|
connectionStatus = false; |
|
}, |
|
before: () => { |
|
connectionIndicator.classList.add("before"); |
|
connectionIndicator.classList.remove( |
|
"webui-issue", |
|
"online", |
|
"offline", |
|
"server-error" |
|
); |
|
connectionIndicatorText.textContent = "Waiting"; |
|
connectionIndicator.title = "Waiting for check to complete."; |
|
connectionStatus = false; |
|
}, |
|
}; |
|
|
|
statuses[status] && |
|
(() => { |
|
statuses[status](); |
|
global.connection = status; |
|
})(); |
|
}; |
|
|
|
setConnectionStatus("before"); |
|
|
|
let checkInProgress = false; |
|
|
|
const checkConnection = async ( |
|
notify = false, |
|
simpleProgressStatus = false |
|
) => { |
|
const apiIssueResult = () => { |
|
setConnectionStatus("apiissue"); |
|
const message = `The host is online, but the API seems to be disabled.<br>Have you run the webui with the flag '--api', or is the flag '--gradio-debug' currently active?`; |
|
console.error(message); |
|
if (notify) |
|
notifications.notify(message, { |
|
type: NotificationType.ERROR, |
|
timeout: config.notificationTimeout * 2, |
|
}); |
|
}; |
|
|
|
const offlineResult = () => { |
|
setConnectionStatus("offline"); |
|
const message = `The connection with the host returned an error: ${response.status} - ${response.statusText}`; |
|
console.error(message); |
|
if (notify) |
|
notifications.notify(message, { |
|
type: NotificationType.ERROR, |
|
timeout: config.notificationTimeout * 2, |
|
}); |
|
}; |
|
if (checkInProgress) |
|
throw new CheckInProgressError( |
|
"Check is currently in progress, please try again" |
|
); |
|
checkInProgress = true; |
|
var url = document.getElementById("host").value + "/startup-events"; |
|
|
|
try { |
|
if (simpleProgressStatus) { |
|
const response = await fetch( |
|
document.getElementById("host").value + "/sdapi/v1/progress" |
|
); |
|
switch (response.status) { |
|
case 200: { |
|
setConnectionStatus("online"); |
|
break; |
|
} |
|
case 404: { |
|
apiIssueResult(); |
|
break; |
|
} |
|
default: { |
|
offlineResult(); |
|
} |
|
} |
|
} else { |
|
|
|
const response = await fetch( |
|
document.getElementById("host").value + "/sdapi/v1/options" |
|
); |
|
const optionsdata = await response.json(); |
|
if (optionsdata["use_scale_latent_for_hires_fix"]) { |
|
const message = `You are using an outdated version of A1111 webUI.<br>The HRfix options will not work until you update to at least commit ef27a18 or newer.<br>(https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/ef27a18b6b7cb1a8eebdc9b2e88d25baf2c2414d)<br>HRfix will fallback to half-resolution only.`; |
|
console.warn(message); |
|
if (notify) |
|
notifications.notify(message, { |
|
type: NotificationType.WARN, |
|
timeout: config.notificationTimeout * 4, |
|
}); |
|
|
|
document |
|
.querySelectorAll(".hrfix") |
|
.forEach((el) => (el.style.display = "none")); |
|
|
|
|
|
global.isOldHRFix = true; |
|
stableDiffusionData.enable_hr = false; |
|
} |
|
switch (response.status) { |
|
case 200: { |
|
setConnectionStatus("online"); |
|
|
|
if (firstTimeOnline) { |
|
getConfig(); |
|
getStyles(); |
|
getSamplers(); |
|
getUpscalers(); |
|
getModels(); |
|
extensions.getExtensions( |
|
controlNetModelAutoComplete, |
|
controlNetModuleAutoComplete, |
|
controlNetReferenceModuleAutoComplete |
|
); |
|
getLoras(); |
|
|
|
|
|
firstTimeOnline = false; |
|
} |
|
break; |
|
} |
|
case 404: { |
|
apiIssueResult(); |
|
break; |
|
} |
|
default: { |
|
offlineResult(); |
|
} |
|
} |
|
} |
|
} catch (e) { |
|
try { |
|
if (e instanceof DOMException) throw "offline"; |
|
|
|
await fetch(url, {mode: "no-cors"}); |
|
|
|
setConnectionStatus("corsissue"); |
|
const message = `CORS is blocking our requests. Try running the webui with the flag '--cors-allow-origins=${window.location.protocol}//${window.location.host}/'`; |
|
console.error(message); |
|
if (notify) |
|
notifications.notify(message, { |
|
type: NotificationType.ERROR, |
|
timeout: config.notificationTimeout * 2, |
|
}); |
|
} catch (e) { |
|
setConnectionStatus("offline"); |
|
const message = `The server seems to be offline. Is host '${ |
|
document.getElementById("host").value |
|
}' correct?`; |
|
console.error(message); |
|
if (notify) |
|
notifications.notify(message, { |
|
type: NotificationType.ERROR, |
|
timeout: config.notificationTimeout * 2, |
|
}); |
|
} |
|
} |
|
checkInProgress = false; |
|
return status; |
|
}; |
|
|
|
if (focused || firstTimeOnline) { |
|
await checkConnection(!urlParams.has("noprompt")); |
|
} |
|
|
|
|
|
connectionIndicator.onclick = async () => { |
|
try { |
|
await checkConnection(true); |
|
checked = true; |
|
} catch (e) { |
|
console.debug("Already refreshing"); |
|
} |
|
}; |
|
|
|
|
|
const checkAgain = () => { |
|
checkFocus(); |
|
if (focused || firstTimeOnline) { |
|
setTimeout( |
|
async () => { |
|
let simple = !firstTimeOnline; |
|
await checkConnection(false, simple); |
|
checkAgain(); |
|
}, |
|
connectionStatus ? 60000 : 5000 |
|
); |
|
} else { |
|
setTimeout(() => { |
|
checkAgain(); |
|
}, 60000); |
|
} |
|
}; |
|
|
|
checkAgain(); |
|
|
|
return () => { |
|
checkConnection().catch(() => {}); |
|
}; |
|
} |
|
|
|
function newImage(evt) { |
|
clearPaintedMask(); |
|
uil.layers.forEach(({layer}) => { |
|
commands.runCommand( |
|
"eraseImage", |
|
"Clear Canvas", |
|
{ |
|
...layer.bb, |
|
ctx: layer.ctx, |
|
}, |
|
{ |
|
extra: { |
|
log: `Cleared Canvas`, |
|
}, |
|
} |
|
); |
|
}); |
|
} |
|
|
|
function clearPaintedMask() { |
|
maskPaintLayer.clear(); |
|
} |
|
|
|
function march(bb, options = {}) { |
|
defaultOpt(options, { |
|
title: null, |
|
titleStyle: "#FFF5", |
|
style: "#FFFF", |
|
width: "2px", |
|
filter: null, |
|
}); |
|
|
|
const expanded = {...bb}; |
|
expanded.x--; |
|
expanded.y--; |
|
expanded.w += 2; |
|
expanded.h += 2; |
|
|
|
|
|
const layer = imageCollection.registerLayer(null, { |
|
bb: expanded, |
|
category: "display", |
|
}); |
|
layer.canvas.style.imageRendering = "pixelated"; |
|
let offset = 0; |
|
|
|
const interval = setInterval(() => { |
|
drawMarchingAnts(layer.ctx, bb, offset++, options); |
|
offset %= 12; |
|
}, 20); |
|
|
|
return () => { |
|
clearInterval(interval); |
|
imageCollection.deleteLayer(layer); |
|
}; |
|
} |
|
|
|
function drawMarchingAnts(ctx, bb, offset, options) { |
|
ctx.save(); |
|
|
|
ctx.clearRect(0, 0, bb.w + 2, bb.h + 2); |
|
|
|
|
|
if (bb.h > 40 && options.title) { |
|
ctx.font = `bold 20px Open Sans`; |
|
|
|
ctx.textAlign = "left"; |
|
ctx.fillStyle = options.titleStyle; |
|
ctx.fillText(options.title, 10, 30, bb.w); |
|
} |
|
|
|
ctx.strokeStyle = options.style; |
|
ctx.strokeWidth = options.width; |
|
ctx.filter = options.filter; |
|
ctx.setLineDash([4, 2]); |
|
ctx.lineDashOffset = -offset; |
|
ctx.strokeRect(1, 1, bb.w, bb.h); |
|
|
|
ctx.restore(); |
|
} |
|
|
|
const makeSlider = ( |
|
label, |
|
el, |
|
lsKey, |
|
min, |
|
max, |
|
step, |
|
defaultValue, |
|
textStep = null, |
|
valuecb = null |
|
) => { |
|
const local = lsKey && localStorage.getItem(`openoutpaint/${lsKey}`); |
|
const def = parseFloat(local === null ? defaultValue : local); |
|
let cb = (v) => { |
|
stableDiffusionData[lsKey] = v; |
|
if (lsKey) localStorage.setItem(`openoutpaint/${lsKey}`, v); |
|
}; |
|
if (valuecb) { |
|
cb = (v) => { |
|
valuecb(v); |
|
localStorage.setItem(`openoutpaint/${lsKey}`, v); |
|
}; |
|
} |
|
return createSlider(label, el, { |
|
valuecb: cb, |
|
min, |
|
max, |
|
step, |
|
defaultValue: def, |
|
textStep, |
|
}); |
|
}; |
|
|
|
let modelAutoComplete = createAutoComplete( |
|
"Model", |
|
document.getElementById("models-ac-select"), |
|
{}, |
|
document.getElementById("refreshModelsBtn"), |
|
"refreshable" |
|
); |
|
modelAutoComplete.onchange.on(({value}) => { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (value.toLowerCase().includes("inpainting")) |
|
document.querySelector( |
|
"#models-ac-select input.autocomplete-text" |
|
).style.backgroundColor = "#cfc"; |
|
else |
|
document.querySelector( |
|
"#models-ac-select input.autocomplete-text" |
|
).style.backgroundColor = "#fcc"; |
|
}); |
|
|
|
let loraAutoComplete = createAutoComplete( |
|
"LoRa", |
|
document.getElementById("lora-ac-select") |
|
); |
|
loraAutoComplete.onchange.on(({value}) => { |
|
|
|
let passVal = " <lora:" + value + ":1>"; |
|
let promptInput = document.getElementById("prompt"); |
|
promptInput.value += passVal; |
|
let promptThing = prompt; |
|
}); |
|
|
|
const samplerAutoComplete = createAutoComplete( |
|
"Sampler", |
|
document.getElementById("sampler-ac-select") |
|
); |
|
|
|
const upscalerAutoComplete = createAutoComplete( |
|
"Upscaler", |
|
document.getElementById("upscaler-ac-select") |
|
); |
|
|
|
const hrFixUpscalerAutoComplete = createAutoComplete( |
|
"HRfix Upscaler", |
|
document.getElementById("hrFixUpscaler") |
|
); |
|
|
|
let controlNetModelAutoComplete = createAutoComplete( |
|
"Inpaint Model", |
|
document.getElementById("controlNetModel-ac-select") |
|
); |
|
|
|
controlNetModelAutoComplete.onchange.on(({value}) => { |
|
extensions.selectedControlNetModel = value; |
|
}); |
|
|
|
let controlNetModuleAutoComplete = createAutoComplete( |
|
"Inpaint Preprocessor", |
|
document.getElementById("controlNetModule-ac-select") |
|
); |
|
|
|
controlNetModuleAutoComplete.onchange.on(({value}) => { |
|
extensions.selectedControlNetModule = value; |
|
}); |
|
|
|
let controlNetReferenceModuleAutoComplete = createAutoComplete( |
|
"Reference Preprocessor", |
|
document.getElementById("controlNetReferenceModule-ac-select") |
|
); |
|
|
|
controlNetReferenceModuleAutoComplete.onchange.on(({value}) => { |
|
extensions.selectedCNReferenceModule = value; |
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
hrFixUpscalerAutoComplete.onchange.on(({value}) => { |
|
stableDiffusionData.hr_upscaler = value; |
|
localStorage.setItem(`openoutpaint/hr_upscaler`, value); |
|
}); |
|
|
|
const resSlider = makeSlider( |
|
"Resolution", |
|
document.getElementById("resolution"), |
|
"resolution", |
|
128, |
|
2048, |
|
128, |
|
512, |
|
2, |
|
(v) => { |
|
stableDiffusionData.width = stableDiffusionData.height = v; |
|
|
|
toolbar.currentTool && |
|
toolbar.currentTool.redraw && |
|
toolbar.currentTool.redraw(); |
|
} |
|
); |
|
|
|
const refSlider = makeSlider( |
|
"Reference Fidelity", |
|
document.getElementById("controlNetReferenceFidelity"), |
|
"cn_reference_fidelity", |
|
0.0, |
|
1.0, |
|
0.1, |
|
0.5, |
|
0.01, |
|
(v) => { |
|
extensions.controlNetReferenceFidelity = v; |
|
|
|
toolbar.currentTool && |
|
toolbar.currentTool.redraw && |
|
toolbar.currentTool.redraw(); |
|
} |
|
); |
|
|
|
makeSlider( |
|
"CFG Scale", |
|
document.getElementById("cfgScale"), |
|
"cfg_scale", |
|
localStorage.getItem("openoutpaint/settings.min-cfg") || 1, |
|
localStorage.getItem("openoutpaint/settings.max-cfg") || 25, |
|
0.5, |
|
7.0, |
|
0.1 |
|
); |
|
makeSlider( |
|
"Batch Size", |
|
document.getElementById("batchSize"), |
|
"batch_size", |
|
1, |
|
8, |
|
1, |
|
2 |
|
); |
|
makeSlider( |
|
"Iterations", |
|
document.getElementById("batchCount"), |
|
"n_iter", |
|
1, |
|
8, |
|
1, |
|
2 |
|
); |
|
makeSlider( |
|
"Upscale X", |
|
document.getElementById("upscaleX"), |
|
"upscale_x", |
|
1.0, |
|
4.0, |
|
0.1, |
|
2.0, |
|
0.1 |
|
); |
|
|
|
makeSlider( |
|
"Steps", |
|
document.getElementById("steps"), |
|
"steps", |
|
1, |
|
localStorage.getItem("openoutpaint/settings.max-steps") || 70, |
|
5, |
|
30, |
|
1 |
|
); |
|
|
|
|
|
const hrFixScaleSlider = makeSlider( |
|
"HRfix Scale", |
|
document.getElementById("hrFixScale"), |
|
"hr_scale", |
|
1.0, |
|
4.0, |
|
0.1, |
|
2.0, |
|
0.1 |
|
); |
|
|
|
makeSlider( |
|
"HRfix Denoising", |
|
document.getElementById("hrDenoising"), |
|
"hr_denoising_strength", |
|
0.0, |
|
1.0, |
|
0.05, |
|
0.7, |
|
0.01 |
|
); |
|
|
|
const lockPxSlider = makeSlider( |
|
"HRfix Autoscale Lock Px.", |
|
document.getElementById("hrFixLockPx"), |
|
"hr_fix_lock_px", |
|
0, |
|
1024, |
|
256, |
|
0, |
|
1 |
|
); |
|
|
|
const hrStepsSlider = makeSlider( |
|
"HRfix Steps", |
|
document.getElementById("hrFixSteps"), |
|
"hr_second_pass_steps", |
|
0, |
|
localStorage.getItem("openoutpaint/settings.max-steps") || 70, |
|
5, |
|
0, |
|
1 |
|
); |
|
|
|
function changeMaskBlur() { |
|
stableDiffusionData.mask_blur = parseInt( |
|
document.getElementById("maskBlur").value |
|
); |
|
localStorage.setItem("openoutpaint/mask_blur", stableDiffusionData.mask_blur); |
|
} |
|
|
|
function changeSeed() { |
|
stableDiffusionData.seed = document.getElementById("seed").value; |
|
localStorage.setItem("openoutpaint/seed", stableDiffusionData.seed); |
|
} |
|
|
|
function changeHRFX() { |
|
stableDiffusionData.hr_resize_x = |
|
document.getElementById("hr_resize_x").value; |
|
} |
|
|
|
function changeHRFY() { |
|
stableDiffusionData.hr_resize_y = |
|
document.getElementById("hr_resize_y").value; |
|
} |
|
|
|
function changeDynamicPromptsExtension() { |
|
extensions.dynamicPromptsActive = |
|
document.getElementById("cbxDynPrompts").checked; |
|
} |
|
|
|
function changeControlNetExtension() { |
|
extensions.controlNetActive = |
|
document.getElementById("cbxControlNet").checked; |
|
if (extensions.controlNetActive) { |
|
document |
|
.querySelectorAll(".controlNetElement") |
|
.forEach((el) => el.classList.remove("invisible")); |
|
} else { |
|
document |
|
.querySelectorAll(".controlNetElement") |
|
.forEach((el) => el.classList.add("invisible")); |
|
} |
|
changeControlNetReference(); |
|
} |
|
|
|
function changeControlNetReference() { |
|
extensions.controlNetReferenceActive = document.getElementById( |
|
"cbxControlNetReferenceLayer" |
|
).checked; |
|
if (extensions.controlNetReferenceActive && extensions.controlNetActive) { |
|
document |
|
.querySelectorAll(".controlNetReferenceElement") |
|
.forEach((el) => el.classList.remove("invisible")); |
|
} else { |
|
document |
|
.querySelectorAll(".controlNetReferenceElement") |
|
.forEach((el) => el.classList.add("invisible")); |
|
} |
|
} |
|
|
|
function changeHiResFix() { |
|
stableDiffusionData.enable_hr = Boolean( |
|
document.getElementById("cbxHRFix").checked |
|
); |
|
localStorage.setItem("openoutpaint/enable_hr", stableDiffusionData.enable_hr); |
|
|
|
|
|
|
|
|
|
|
|
if (stableDiffusionData.enable_hr) { |
|
document |
|
.querySelectorAll(".hrfix") |
|
.forEach((el) => el.classList.remove("invisible")); |
|
} else { |
|
document |
|
.querySelectorAll(".hrfix") |
|
.forEach((el) => el.classList.add("invisible")); |
|
} |
|
} |
|
|
|
function changeHiResSquare() { |
|
stableDiffusionData.hr_square_aspect = Boolean( |
|
document.getElementById("cbxHRFSquare").checked |
|
); |
|
} |
|
|
|
function changeRestoreFaces() { |
|
stableDiffusionData.restore_faces = Boolean( |
|
document.getElementById("cbxRestoreFaces").checked |
|
); |
|
localStorage.setItem( |
|
"openoutpaint/restore_faces", |
|
stableDiffusionData.restore_faces |
|
); |
|
} |
|
|
|
function changeSyncCursorSize() { |
|
global.syncCursorSize = Boolean( |
|
document.getElementById("cbxSyncCursorSize").checked |
|
); |
|
localStorage.setItem("openoutpaint/sync_cursor_size", global.syncCursorSize); |
|
} |
|
|
|
function changeSmoothRendering() { |
|
const layers = document.getElementById("layer-render"); |
|
if (localStorage.getItem("openoutpaint/settings.smooth") === "true") { |
|
layers.classList.remove("pixelated"); |
|
} else { |
|
layers.classList.add("pixelated"); |
|
} |
|
} |
|
|
|
function isCanvasBlank(x, y, w, h, canvas) { |
|
return !canvas |
|
.getContext("2d") |
|
.getImageData(x, y, w, h) |
|
.data.some((channel) => channel !== 0); |
|
} |
|
|
|
function drawBackground() { |
|
{ |
|
|
|
const canvas = document.createElement("canvas"); |
|
canvas.width = config.gridSize * 2; |
|
canvas.height = config.gridSize * 2; |
|
|
|
const ctx = canvas.getContext("2d"); |
|
ctx.fillStyle = theme.grid.dark; |
|
ctx.fillRect(0, 0, canvas.width, canvas.height); |
|
ctx.fillStyle = theme.grid.light; |
|
ctx.fillRect(0, 0, config.gridSize, config.gridSize); |
|
ctx.fillRect( |
|
config.gridSize, |
|
config.gridSize, |
|
config.gridSize, |
|
config.gridSize |
|
); |
|
|
|
canvas.toBlob((blob) => { |
|
const url = window.URL.createObjectURL(blob); |
|
console.debug(url); |
|
bgLayer.canvas.style.backgroundImage = `url(${url})`; |
|
}); |
|
} |
|
} |
|
|
|
async function exportWorkspaceState() { |
|
return { |
|
defaultLayer: { |
|
id: uil.layerIndex.default.id, |
|
name: uil.layerIndex.default.name, |
|
}, |
|
bb: { |
|
x: imageCollection.bb.x, |
|
y: imageCollection.bb.y, |
|
w: imageCollection.bb.w, |
|
h: imageCollection.bb.h, |
|
}, |
|
history: await commands.export(), |
|
}; |
|
} |
|
|
|
async function importWorkspaceState(state) { |
|
|
|
await commands.clear(); |
|
|
|
|
|
const layer = uil.layerIndex.default; |
|
layer.deletable = true; |
|
|
|
await commands.runCommand( |
|
"addLayer", |
|
"Temporary Layer", |
|
{name: "Temporary Layer", key: "tmp"}, |
|
{recordHistory: false} |
|
); |
|
|
|
await commands.runCommand( |
|
"deleteLayer", |
|
"Deleted Layer", |
|
{ |
|
layer, |
|
}, |
|
{recordHistory: false} |
|
); |
|
|
|
await commands.runCommand( |
|
"addLayer", |
|
"Initial Layer Creation", |
|
{ |
|
id: state.defaultLayer.id, |
|
name: state.defaultLayer.name, |
|
key: "default", |
|
deletable: false, |
|
}, |
|
{recordHistory: false} |
|
); |
|
|
|
await commands.runCommand( |
|
"deleteLayer", |
|
"Deleted Layer", |
|
{ |
|
layer: uil.layerIndex.tmp, |
|
}, |
|
{recordHistory: false} |
|
); |
|
|
|
|
|
const sbb = new BoundingBox(state.bb); |
|
|
|
const bb = imageCollection.bb; |
|
let eleft = 0; |
|
if (bb.x > sbb.x) eleft = bb.x - sbb.x; |
|
let etop = 0; |
|
if (bb.y > sbb.y) etop = bb.y - sbb.y; |
|
|
|
let eright = 0; |
|
if (bb.tr.x < sbb.tr.x) eright = sbb.tr.x - bb.tr.x; |
|
let ebottom = 0; |
|
if (bb.br.y < sbb.br.y) ebottom = sbb.br.y - bb.br.y; |
|
|
|
imageCollection.expand(eleft, etop, eright, ebottom); |
|
|
|
|
|
for (const command of state.history) { |
|
await commands.import(command); |
|
} |
|
} |
|
|
|
async function saveWorkspaceToFile() { |
|
const workspace = await exportWorkspaceState(); |
|
|
|
const blob = new Blob([JSON.stringify(workspace)], { |
|
type: "application/json", |
|
}); |
|
|
|
const url = URL.createObjectURL(blob); |
|
var link = document.createElement("a"); |
|
link.href = url; |
|
link.download = `${new Date().toISOString()}_openOutpaint_workspace.json`; |
|
link.click(); |
|
} |
|
|
|
async function getUpscalers() { |
|
var url = document.getElementById("host").value + "/sdapi/v1/upscalers"; |
|
let upscalers = []; |
|
|
|
try { |
|
const response = await fetch(url, { |
|
method: "GET", |
|
headers: { |
|
Accept: "application/json", |
|
"Content-Type": "application/json", |
|
}, |
|
}); |
|
const data = await response.json(); |
|
for (var i = 0; i < data.length; i++) { |
|
if (data[i].name.includes("None")) { |
|
continue; |
|
} |
|
upscalers.push(data[i].name); |
|
} |
|
} catch (e) { |
|
console.warn("[index] Failed to fetch upscalers:"); |
|
console.warn(e); |
|
upscalers = [ |
|
"Lanczos", |
|
"Nearest", |
|
"LDSR", |
|
"SwinIR", |
|
"R-ESRGAN General 4xV3", |
|
"R-ESRGAN General WDN 4xV3", |
|
"R-ESRGAN AnimeVideo", |
|
"R-ESRGAN 4x+", |
|
"R-ESRGAN 4x+ Anime6B", |
|
"R-ESRGAN 2x+", |
|
]; |
|
} |
|
const upscalersPlusNone = [...upscalers]; |
|
upscalersPlusNone.unshift("None"); |
|
upscalersPlusNone.push("Latent"); |
|
upscalersPlusNone.push("Latent (antialiased)"); |
|
upscalersPlusNone.push("Latent (bicubic)"); |
|
upscalersPlusNone.push("Latent (bicubic, antialiased)"); |
|
upscalersPlusNone.push("Latent (nearest)"); |
|
|
|
upscalerAutoComplete.options = upscalers.map((u) => { |
|
return {name: u, value: u}; |
|
}); |
|
hrFixUpscalerAutoComplete.options = upscalersPlusNone.map((u) => { |
|
return {name: u, value: u}; |
|
}); |
|
|
|
upscalerAutoComplete.value = upscalers[0]; |
|
hrFixUpscalerAutoComplete.value = |
|
localStorage.getItem("openoutpaint/hr_upscaler") === null |
|
? "None" |
|
: localStorage.getItem("openoutpaint/hr_upscaler"); |
|
} |
|
|
|
async function getModels(refresh = false) { |
|
const url = document.getElementById("host").value + "/sdapi/v1/sd-models"; |
|
let opt = null; |
|
|
|
try { |
|
const response = await fetch(url); |
|
const data = await response.json(); |
|
|
|
opt = data.map((option) => ({ |
|
name: option.title, |
|
value: option.title, |
|
optionelcb: (el) => { |
|
if (option.title.toLowerCase().includes("inpainting")) |
|
el.classList.add("inpainting"); |
|
}, |
|
})); |
|
|
|
modelAutoComplete.options = opt; |
|
|
|
try { |
|
const optResponse = await fetch( |
|
document.getElementById("host").value + "/sdapi/v1/options" |
|
); |
|
const optData = await optResponse.json(); |
|
|
|
var model = optData.sd_model_checkpoint; |
|
|
|
|
|
if (model === undefined) { |
|
const modelHash = optData.sd_checkpoint_hash; |
|
const hashMap = data.map((option) => ({ |
|
hash: option.sha256, |
|
title: option.title, |
|
})); |
|
model = hashMap.find((option) => option.hash === modelHash).title; |
|
} |
|
console.log("Current model: " + model); |
|
if (modelAutoComplete.value !== model) modelAutoComplete.value = model; |
|
} catch (e) { |
|
console.warn("[index] Failed to fetch current model:"); |
|
console.warn(e); |
|
} |
|
} catch (e) { |
|
console.warn("[index] Failed to fetch models:"); |
|
console.warn(e); |
|
} |
|
|
|
if (!refresh) |
|
modelAutoComplete.onchange.on(async ({value}) => { |
|
console.log(`[index] Changing model to [${value}]`); |
|
const payload = { |
|
sd_model_checkpoint: value, |
|
}; |
|
const url = document.getElementById("host").value + "/sdapi/v1/options/"; |
|
try { |
|
await fetch(url, { |
|
method: "POST", |
|
headers: { |
|
"Content-Type": "application/json", |
|
}, |
|
body: JSON.stringify(payload), |
|
}); |
|
|
|
notifications.notify(`Model changed to [${value}]`, {type: "success"}); |
|
} catch (e) { |
|
console.warn("[index] Error changing model"); |
|
console.warn(e); |
|
|
|
notifications.notify( |
|
"Error changing model, please check console for additional information", |
|
{ |
|
type: NotificationType.ERROR, |
|
timeout: config.notificationTimeout * 2, |
|
} |
|
); |
|
} |
|
}); |
|
|
|
|
|
if (global.firstRun && !modelAutoComplete.value.includes("inpainting")) { |
|
const inpainting = opt.find(({name}) => name.includes("inpainting")); |
|
|
|
let message = |
|
"It seems this is your first time using openOutpaint. It is highly recommended that you switch to an inpainting model. \ |
|
These are highlighted as green in the model selector."; |
|
|
|
if (inpainting) { |
|
message += `<br><br>We have found the inpainting model<br><br> - ${inpainting.name}<br><br>available in the webui. Do you want to switch to it?`; |
|
if (await notifications.dialog("Automatic Model Switch", message)) { |
|
modelAutoComplete.value = inpainting.value; |
|
} |
|
} else { |
|
message += `<br><br>No inpainting model seems to be available in the webui. It is recommended that you download an inpainting model, or outpainting results may not be optimal.`; |
|
notifications.notify(message, { |
|
type: NotificationType.WARN, |
|
timeout: null, |
|
}); |
|
} |
|
} |
|
} |
|
|
|
async function getLoras() { |
|
var url = document.getElementById("host").value + "/sdapi/v1/loras"; |
|
let opt = null; |
|
|
|
try { |
|
const response = await fetch(url); |
|
const data = await response.json(); |
|
|
|
loraAutoComplete.options = data.map((lora) => ({ |
|
name: lora.name, |
|
value: lora.name, |
|
})); |
|
} catch (e) { |
|
console.warn("[index] Failed to fetch loras"); |
|
console.warn(e); |
|
} |
|
} |
|
|
|
async function getConfig() { |
|
var url = document.getElementById("host").value + "/sdapi/v1/options"; |
|
|
|
let message = |
|
"The following options for the AUTOMATIC1111's webui are not recommended to use with this software:"; |
|
|
|
try { |
|
const response = await fetch(url); |
|
|
|
const data = await response.json(); |
|
|
|
let wrong = false; |
|
|
|
|
|
|
|
if (data.img2img_color_correction) { |
|
message += "<br> - Image to Image Color Correction: false recommended"; |
|
wrong = true; |
|
} |
|
|
|
if (data.inpainting_mask_weight < 1.0) { |
|
message += `<br> - Inpainting Conditioning Mask Strength: 1.0 recommended`; |
|
wrong = true; |
|
} |
|
|
|
message += |
|
"<br><br>Should these values be changed to the recommended ones?"; |
|
|
|
if (!wrong) { |
|
console.info("[index] WebUI Settings set as recommended."); |
|
return; |
|
} |
|
|
|
console.info( |
|
"[index] WebUI Settings not set as recommended. Prompting for changing settings automatically." |
|
); |
|
|
|
if (!(await notifications.dialog("Recommended Settings", message))) return; |
|
|
|
try { |
|
await fetch(url, { |
|
method: "POST", |
|
headers: { |
|
"Content-Type": "application/json", |
|
}, |
|
body: JSON.stringify({ |
|
img2img_color_correction: false, |
|
inpainting_mask_weight: 1.0, |
|
}), |
|
}); |
|
} catch (e) { |
|
console.warn("[index] Failed to fetch WebUI Configuration"); |
|
console.warn(e); |
|
} |
|
} catch (e) { |
|
console.warn("[index] Failed to fetch WebUI Configuration"); |
|
console.warn(e); |
|
} |
|
} |
|
|
|
function changeStyles() { |
|
|
|
const styleSelectEl = document.getElementById("styleSelect"); |
|
const selected = Array.from(styleSelectEl.options).filter( |
|
(option) => option.selected |
|
); |
|
let selectedString = selected.map((option) => option.value); |
|
|
|
if (selectedString.find((selected) => selected === "None")) { |
|
selectedString = []; |
|
Array.from(styleSelectEl.options).forEach((option) => { |
|
if (option.value !== "None") option.selected = false; |
|
}); |
|
} |
|
|
|
localStorage.setItem( |
|
"openoutpaint/promptStyle", |
|
JSON.stringify(selectedString) |
|
); |
|
|
|
|
|
if (selectedString.length > 0) |
|
console.log(`[index] Changing styles to ${selectedString.join(", ")}`); |
|
else console.log(`[index] Clearing styles`); |
|
stableDiffusionData.styles = selectedString; |
|
} |
|
|
|
async function getSamplers() { |
|
var url = document.getElementById("host").value + "/sdapi/v1/samplers"; |
|
|
|
try { |
|
const response = await fetch(url); |
|
const data = await response.json(); |
|
|
|
samplerAutoComplete.onchange.on(({value}) => { |
|
stableDiffusionData.sampler_index = value; |
|
localStorage.setItem("openoutpaint/sampler", value); |
|
}); |
|
|
|
samplerAutoComplete.options = data.map((sampler) => ({ |
|
name: sampler.name, |
|
value: sampler.name, |
|
})); |
|
|
|
|
|
if (localStorage.getItem("openoutpaint/sampler") != null) { |
|
samplerAutoComplete.value = localStorage.getItem("openoutpaint/sampler"); |
|
} else { |
|
samplerAutoComplete.value = data[0].name; |
|
localStorage.setItem("openoutpaint/sampler", samplerAutoComplete.value); |
|
} |
|
stableDiffusionData.sampler_index = samplerAutoComplete.value; |
|
} catch (e) { |
|
console.warn("[index] Failed to fetch samplers"); |
|
console.warn(e); |
|
} |
|
} |
|
|
|
async function upscaleAndDownload() { |
|
|
|
|
|
|
|
var upscale_factor = localStorage.getItem("openoutpaint/upscale_x") |
|
? localStorage.getItem("openoutpaint/upscale_x") |
|
: 2; |
|
var upscaler = upscalerAutoComplete.value; |
|
var croppedCanvas = cropCanvas( |
|
uil.getVisible({ |
|
x: 0, |
|
y: 0, |
|
w: imageCollection.size.w, |
|
h: imageCollection.size.h, |
|
}) |
|
); |
|
if (croppedCanvas != null) { |
|
var url = |
|
document.getElementById("host").value + "/sdapi/v1/extra-single-image/"; |
|
var imgdata = croppedCanvas.canvas.toDataURL("image/png"); |
|
var data = { |
|
"resize-mode": 0, |
|
upscaling_resize: upscale_factor, |
|
upscaler_1: upscaler, |
|
image: imgdata, |
|
}; |
|
console.log(data); |
|
await fetch(url, { |
|
method: "POST", |
|
headers: { |
|
Accept: "application/json", |
|
"Content-Type": "application/json", |
|
}, |
|
body: JSON.stringify(data), |
|
}) |
|
.then((response) => response.json()) |
|
.then((data) => { |
|
console.log(data); |
|
var link = document.createElement("a"); |
|
link.download = |
|
new Date() |
|
.toISOString() |
|
.slice(0, 19) |
|
.replace("T", " ") |
|
.replace(":", " ") + |
|
" openOutpaint image upscaler_" + |
|
upscaler + |
|
"_x" + |
|
upscale_factor + |
|
".png"; |
|
link.href = "data:image/png;base64," + data["image"]; |
|
link.click(); |
|
}); |
|
} |
|
} |
|
|
|
function loadSettings() { |
|
|
|
var _mask_blur = |
|
localStorage.getItem("openoutpaint/mask_blur") == null |
|
? 0 |
|
: localStorage.getItem("openoutpaint/mask_blur"); |
|
var _seed = |
|
localStorage.getItem("openoutpaint/seed") == null |
|
? -1 |
|
: localStorage.getItem("openoutpaint/seed"); |
|
let _enable_hr = |
|
localStorage.getItem("openoutpaint/enable_hr") === null |
|
? false |
|
: localStorage.getItem("openoutpaint/enable_hr") === "true"; |
|
let _restore_faces = |
|
localStorage.getItem("openoutpaint/restore_faces") === null |
|
? false |
|
: localStorage.getItem("openoutpaint/restore_faces") === "true"; |
|
|
|
let _sync_cursor_size = |
|
localStorage.getItem("openoutpaint/sync_cursor_size") === null |
|
? true |
|
: localStorage.getItem("openoutpaint/sync_cursor_size") === "true"; |
|
|
|
let _hrfix_scale = |
|
localStorage.getItem("openoutpaint/hr_scale") === null |
|
? 2.0 |
|
: localStorage.getItem("openoutpaint/hr_scale"); |
|
|
|
let _hrfix_denoising = |
|
localStorage.getItem("openoutpaint/hr_denoising_strength") === null |
|
? 0.7 |
|
: localStorage.getItem("openoutpaint/hr_denoising_strength"); |
|
let _hrfix_lock_px = |
|
localStorage.getItem("openoutpaint/hr_fix_lock_px") === null |
|
? 0 |
|
: localStorage.getItem("openoutpaint/hr_fix_lock_px"); |
|
|
|
|
|
document.getElementById("maskBlur").value = Number(_mask_blur); |
|
document.getElementById("seed").value = Number(_seed); |
|
document.getElementById("cbxHRFix").checked = Boolean(_enable_hr); |
|
document.getElementById("cbxRestoreFaces").checked = Boolean(_restore_faces); |
|
document.getElementById("cbxSyncCursorSize").checked = |
|
Boolean(_sync_cursor_size); |
|
document.getElementById("hrFixScale").value = Number(_hrfix_scale); |
|
document.getElementById("hrDenoising").value = Number(_hrfix_denoising); |
|
document.getElementById("hrFixLockPx").value = Number(_hrfix_lock_px); |
|
} |
|
|
|
imageCollection.element.addEventListener( |
|
"wheel", |
|
(evn) => { |
|
evn.preventDefault(); |
|
}, |
|
{passive: false} |
|
); |
|
|
|
imageCollection.element.addEventListener( |
|
"contextmenu", |
|
(evn) => { |
|
evn.preventDefault(); |
|
}, |
|
{passive: false} |
|
); |
|
|
|
async function resetToDefaults() { |
|
if ( |
|
await notifications.dialog( |
|
"Clear Settings", |
|
"Are you sure you want to clear your settings?" |
|
) |
|
) { |
|
localStorage.clear(); |
|
} |
|
} |
|
|
|
document.addEventListener("visibilitychange", () => { |
|
checkFocus(); |
|
}); |
|
|
|
window.addEventListener("blur", () => { |
|
checkFocus(); |
|
}); |
|
|
|
window.addEventListener("focus", () => { |
|
checkFocus(); |
|
}); |
|
|
|
function checkFocus() { |
|
let hasFocus = document.hasFocus(); |
|
if (document.hidden || !hasFocus) { |
|
focused = false; |
|
} else { |
|
focused = true; |
|
} |
|
} |
|
|
|
function refreshScripts() { |
|
selector = document.getElementById("script-selector"); |
|
selector.innerHTML = ""; |
|
createBaseScriptOptions(); |
|
loadDefaultScripts(); |
|
|
|
} |
|
|
|
function createBaseScriptOptions() { |
|
selector = document.getElementById("script-selector"); |
|
var noScript = document.createElement("option"); |
|
noScript.id = "no_selected_script"; |
|
noScript.value = ""; |
|
noScript.innerHTML = "(disabled)"; |
|
selector.appendChild(noScript); |
|
var customScript = document.createElement("option"); |
|
customScript.id = "custom"; |
|
customScript.value = "custom"; |
|
customScript.innerHTML = "Custom"; |
|
selector.appendChild(customScript); |
|
} |
|
|
|
async function loadDefaultScripts() { |
|
selector = document.getElementById("script-selector"); |
|
const response = await fetch("./defaultscripts.json"); |
|
const json = await response.json(); |
|
for (const key in json.defaultScripts) { |
|
var opt = document.createElement("option"); |
|
opt.value = opt.innerHTML = key; |
|
selector.appendChild(opt); |
|
} |
|
defaultScripts = json; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function changeScript(event) { |
|
let enable = () => { |
|
scriptName.disabled = false; |
|
|
|
}; |
|
let disable = () => { |
|
scriptName.disabled = true; |
|
|
|
}; |
|
let selected = event.target.value; |
|
let scriptName = document.getElementById("script-name-input"); |
|
let scriptArgs = document.getElementById("script-args-input"); |
|
|
|
scriptName.value = selected; |
|
scriptArgs.title = ""; |
|
disable(); |
|
switch (selected) { |
|
case "custom": { |
|
let _script_name_input = |
|
localStorage.getItem("openoutpaint/script_name_input") === null |
|
? "" |
|
: localStorage.getItem("openoutpaint/script_name_input"); |
|
let _script_args_input = |
|
localStorage.getItem("openoutpaint/script_args_input") === null |
|
? "[]" |
|
: localStorage.getItem("openoutpaint/script_args_input"); |
|
scriptName.value = _script_name_input; |
|
scriptArgs.value = _script_args_input; |
|
scriptArgs.title = ""; |
|
enable(); |
|
break; |
|
} |
|
case "": { |
|
|
|
scriptArgs.value = ""; |
|
break; |
|
} |
|
default: { |
|
scriptName.value = selected; |
|
|
|
if (selected in defaultScripts.defaultScripts) { |
|
scriptArgs.value = defaultScripts.defaultScripts[selected].scriptValues; |
|
scriptArgs.title = defaultScripts.defaultScripts[selected].titleText; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function togglePix2PixImgCfg(value) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
function storeUserscriptVal(evt, type) { |
|
let currentScript = document.getElementById("script-selector").value; |
|
if (currentScript === "custom") { |
|
console.log(type); |
|
console.log(evt); |
|
let val = (currentScript = document.getElementById( |
|
"script-" + type + "-input" |
|
).value); |
|
|
|
localStorage.setItem("openoutpaint/script_" + type + "_input", val); |
|
} |
|
} |
|
|