Spaces:
Runtime error
Runtime error
File size: 19,681 Bytes
c19ca42 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 |
const activePromptTextarea = {};
let sortVal = 0;
// helpers
const requestGet = (url, data, handler) => {
const xhr = new XMLHttpRequest();
const args = Object.keys(data).map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(data[k])}`).join('&');
xhr.open('GET', `${url}?${args}`, true);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) handler(JSON.parse(xhr.responseText));
else console.error(`Request: url=${url} status=${xhr.status} err`);
}
};
xhr.send(JSON.stringify(data));
};
const getENActiveTab = () => {
if (gradioApp().getElementById('tab_txt2img').style.display === 'block') return 'txt2img';
if (gradioApp().getElementById('tab_img2img').style.display === 'block') return 'img2img';
if (gradioApp().getElementById('tab_control').style.display === 'block') return 'control';
return '';
};
const getENActivePage = () => {
const tabname = getENActiveTab();
const page = gradioApp().querySelector(`#${tabname}_extra_networks > .tabs > .tab-nav > .selected`);
const pageName = page ? page.innerText : '';
const btnApply = gradioApp().getElementById(`${tabname}_extra_apply`);
if (btnApply) btnApply.style.display = pageName === 'Style' ? 'inline-flex' : 'none';
return pageName;
};
const setENState = (state) => {
if (!state) return;
state.tab = getENActiveTab();
state.page = getENActivePage();
// log('setENState', state);
const el = gradioApp().querySelector(`#${state.tab}_extra_state > label > textarea`);
el.value = JSON.stringify(state);
updateInput(el);
};
// methods
function showCardDetails(event) {
console.log('showCardDetails', event);
const tabname = getENActiveTab();
const btn = gradioApp().getElementById(`${tabname}_extra_details_btn`);
btn.click();
event.stopPropagation();
event.preventDefault();
}
function getCardDetails(...args) {
const el = event?.target?.parentElement?.parentElement;
if (el?.classList?.contains('card')) setENState({ op: 'getCardDetails', item: el.dataset.name });
else setENState({ op: 'getCardDetails', item: null });
return [...args];
}
function readCardTags(el, tags) {
const replaceOutsideBrackets = (input, target, replacement) => input.split(/(<[^>]*>|\{[^}]*\})/g).map((part, i) => {
if (i % 2 === 0) return part.split(target).join(replacement); // Only replace in the parts that are not inside brackets (which are at even indices)
return part;
}).join('');
const clickTag = (e, tag) => {
e.preventDefault();
e.stopPropagation();
const textarea = activePromptTextarea[getENActiveTab()];
let new_prompt = textarea.value;
new_prompt = replaceOutsideBrackets(new_prompt, ` ${tag}`, ''); // try to remove tag
new_prompt = replaceOutsideBrackets(new_prompt, `${tag} `, '');
if (new_prompt === textarea.value) new_prompt += ` ${tag}`; // if not removed, then append it
textarea.value = new_prompt;
updateInput(textarea);
};
if (tags.length === 0) return;
const cardTags = tags.split('|');
if (!cardTags || cardTags.length === 0) return;
const tagsEl = el.getElementsByClassName('tags')[0];
if (!tagsEl?.children || tagsEl.children.length > 0) return;
for (const tag of cardTags) {
const span = document.createElement('span');
span.classList.add('tag');
span.textContent = tag;
span.onclick = (e) => clickTag(e, tag);
tagsEl.appendChild(span);
}
}
function readCardDescription(page, item) {
requestGet('/sd_extra_networks/description', { page, item }, (data) => {
const tabname = getENActiveTab();
const description = gradioApp().querySelector(`#${tabname}_description > label > textarea`);
description.value = data?.description?.trim() || '';
// description.focus();
updateInput(description);
setENState({ op: 'readCardDescription', page, item });
});
}
function getCardsForActivePage() {
const pagename = getENActivePage();
if (!pagename) return [];
const allCards = Array.from(gradioApp().querySelectorAll('.extra-network-cards > .card'));
const cards = allCards.filter((el) => el.dataset.page.toLowerCase().includes(pagename.toLowerCase()));
log('getCardsForActivePage', pagename, cards.length);
return allCards;
}
async function filterExtraNetworksForTab(searchTerm) {
let found = 0;
let items = 0;
const t0 = performance.now();
const pagename = getENActivePage();
if (!pagename) return;
const allPages = Array.from(gradioApp().querySelectorAll('.extra-network-cards'));
const pages = allPages.filter((el) => el.id.toLowerCase().includes(pagename.toLowerCase()));
for (const pg of pages) {
const cards = Array.from(pg.querySelectorAll('.card') || []);
// We will always have as many items as cards
items += cards.length;
// Reset the results to show all cards if the search term is empty
if (searchTerm === '') {
cards.forEach((elem) => {
elem.style.display = '';
});
} else {
// Do not account for case or whitespace
searchTerm = searchTerm.toLowerCase().trim();
// If the searchTerm starts with "r#", then we are using regex search
if (searchTerm.startsWith('r#')) {
searchTerm = searchTerm.substring(2);
// Insensitive regex search based on the searchTerm
// The regex can be invalid -> then it will error out of this function, so the timing log will be missing, instead the error will be logged to console
const re = new RegExp(searchTerm, 'i');
cards.forEach((elem) => {
// Construct the search text, which is the concatenation of all data elements with a prefix to make it unique
// This combined text allows to exclude search terms for example by using negative lookahead
if (re.test(`filename: ${elem.dataset.filename}|name: ${elem.dataset.name}|tags: ${elem.dataset.tags}`)) {
elem.style.display = '';
found += 1;
} else {
elem.style.display = 'none';
}
});
} else {
// If we are not using regex search, we still use an extended syntax to allow for searching for multiple keywords, or also excluding keywords
// Keywords are separated by |, and keywords that should be excluded are prefixed with -
const searchList = searchTerm.split('|').filter((s) => s !== '' && !s.startsWith('-')).map((s) => s.trim());
const excludeList = searchTerm.split('|').filter((s) => s !== '' && s.trim().startsWith('-')).map((s) => s.trim().substring(1).trim());
// In addition, both the searchList, and exclude List can be separated by &, which means that all keywords in the searchList must be present, and none of the excludeList
// So we construct an array of arrays, which we will then use to filter the cards
const searchListAll = searchList.map((s) => s.split('&').map((t) => t.trim()));
const excludeListAll = excludeList.map((s) => s.split('&').map((t) => t.trim()));
cards.forEach((elem) => {
let text = '';
if (elem.dataset.filename) text += `${elem.dataset.filename} `;
if (elem.dataset.name) text += `${elem.dataset.name} `;
if (elem.dataset.tags) text += `${elem.dataset.tags} `;
text = text.toLowerCase().replace('models--', 'diffusers').replaceAll('\\', '/');
if (
// In searchListAll we have a list of lists, in the sublist, every keyword must be present
// In the top level list, at least one sublist must be present
// In excludeListAll we have a list of lists, in the sublist, the keywords may not appear together
// In the top level list, none of the sublists must be present
searchListAll.some((sl) => sl.every((st) => text.includes(st))) && !excludeListAll.some((el) => el.every((et) => text.includes(et)))
) {
elem.style.display = '';
found += 1;
} else {
elem.style.display = 'none';
}
});
}
}
}
const t1 = performance.now();
if (searchTerm !== '') log(`filterExtraNetworks: text=${searchTerm} items=${items} match=${found} time=${Math.round(1000 * (t1 - t0)) / 1000000}`);
else log(`filterExtraNetworks: text=all items=${items} time=${Math.round(1000 * (t1 - t0)) / 1000000}`);
}
function tryToRemoveExtraNetworkFromPrompt(textarea, text) {
const re_extranet = /<([^:]+:[^:]+):[\d\.]+>/;
const re_extranet_g = /\s+<([^:]+:[^:]+):[\d\.]+>/g;
let m = text.match(re_extranet);
let replaced = false;
let newTextareaText;
if (m) {
const partToSearch = m[1];
newTextareaText = textarea.value.replaceAll(re_extranet_g, (found) => {
m = found.match(re_extranet);
if (m[1] === partToSearch) {
replaced = true;
return '';
}
return found;
});
} else {
newTextareaText = textarea.value.replaceAll(new RegExp(text, 'g'), (found) => {
if (found === text) {
replaced = true;
return '';
}
return found;
});
}
if (replaced) {
textarea.value = newTextareaText;
return true;
}
return false;
}
function sortExtraNetworks() {
const sortDesc = ['Name [A-Z]', 'Name [Z-A]', 'Date [Newest]', 'Date [Oldest]', 'Size [Largest]', 'Size [Smallest]'];
const pagename = getENActivePage();
if (!pagename) return 'sort error: unknown page';
const allPages = Array.from(gradioApp().querySelectorAll('.extra-network-cards'));
const pages = allPages.filter((el) => el.id.toLowerCase().includes(pagename.toLowerCase()));
let num = 0;
for (const pg of pages) {
const cards = Array.from(pg.querySelectorAll('.card') || []);
num = cards.length;
if (num === 0) return 'sort: no cards';
cards.sort((a, b) => { // eslint-disable-line no-loop-func
switch (sortVal) {
case 0: return a.dataset.name ? a.dataset.name.localeCompare(b.dataset.name) : 0;
case 1: return b.dataset.name ? b.dataset.name.localeCompare(a.dataset.name) : 0;
case 2: return a.dataset.mtime && !isNaN(a.dataset.mtime) ? parseFloat(b.dataset.mtime) - parseFloat(a.dataset.mtime) : 0;
case 3: return b.dataset.mtime && !isNaN(b.dataset.mtime) ? parseFloat(a.dataset.mtime) - parseFloat(b.dataset.mtime) : 0;
case 4: return a.dataset.size && !isNaN(a.dataset.size) ? parseFloat(b.dataset.size) - parseFloat(a.dataset.size) : 0;
case 5: return b.dataset.size && !isNaN(b.dataset.size) ? parseFloat(a.dataset.size) - parseFloat(b.dataset.size) : 0;
}
return 0;
});
for (const card of cards) pg.appendChild(card);
}
const desc = sortDesc[sortVal];
sortVal = (sortVal + 1) % sortDesc.length;
log('sortExtraNetworks', pagename, num, desc);
return `sort page ${pagename} cards ${num} by ${desc}`;
}
function refreshENInput(tabname) {
log('refreshExtraNetworks', tabname, gradioApp().querySelector(`#${tabname}_extra_networks textarea`)?.value);
gradioApp().querySelector(`#${tabname}_extra_networks textarea`)?.dispatchEvent(new Event('input'));
}
function cardClicked(textToAdd, allowNegativePrompt) {
const tabname = getENActiveTab();
const textarea = allowNegativePrompt ? activePromptTextarea[tabname] : gradioApp().querySelector(`#${tabname}_prompt > label > textarea`);
if (textarea.value.indexOf(textToAdd) !== -1) textarea.value = textarea.value.replace(textToAdd, '');
else textarea.value += textToAdd;
updateInput(textarea);
}
function extraNetworksSearchButton(event) {
const tabname = getENActiveTab();
const searchTextarea = gradioApp().querySelector(`#${tabname}_extra_search textarea`);
const button = event.target;
if (button.classList.contains('search-all')) {
searchTextarea.value = '';
} else {
searchTextarea.value = `${button.textContent.trim()}/`;
}
updateInput(searchTextarea);
}
let desiredStyle = '';
function selectStyle(name) {
desiredStyle = name;
const tabname = getENActiveTab();
const button = gradioApp().querySelector(`#${tabname}_styles_select`);
button.click();
}
function applyStyles(styles) {
let newStyles = [];
if (styles) newStyles = Array.isArray(styles) ? styles : [styles];
const index = newStyles.indexOf(desiredStyle);
if (index > -1) newStyles.splice(index, 1);
else newStyles.push(desiredStyle);
return newStyles.join('|');
}
function quickApplyStyle() {
const tabname = getENActiveTab();
const btnApply = gradioApp().getElementById(`${tabname}_extra_apply`);
if (btnApply) btnApply.click();
}
function quickSaveStyle() {
const tabname = getENActiveTab();
const btnSave = gradioApp().getElementById(`${tabname}_extra_quicksave`);
if (btnSave) btnSave.click();
}
let enDirty = false;
function closeDetailsEN(...args) {
// log('closeDetailsEN');
enDirty = true;
const tabname = getENActiveTab();
const btnClose = gradioApp().getElementById(`${tabname}_extra_details_close`);
if (btnClose) setTimeout(() => btnClose.click(), 100);
const btnRefresh = gradioApp().getElementById(`${tabname}_extra_refresh`);
if (btnRefresh && enDirty) setTimeout(() => btnRefresh.click(), 100);
return [...args];
}
function refeshDetailsEN(args) {
log(`refeshDetailsEN: ${enDirty}`);
const tabname = getENActiveTab();
const btnRefresh = gradioApp().getElementById(`${tabname}_extra_refresh`);
if (btnRefresh && enDirty) setTimeout(() => btnRefresh.click(), 100);
enDirty = false;
return args;
}
// refresh on en show
function refreshENpage() {
if (getCardsForActivePage().length === 0) {
log('refreshENpage');
const tabname = getENActiveTab();
const btnRefresh = gradioApp().getElementById(`${tabname}_extra_refresh`);
if (btnRefresh) btnRefresh.click();
}
}
// init
function setupExtraNetworksForTab(tabname) {
let tabs = gradioApp().querySelector(`#${tabname}_extra_tabs`);
if (tabs) tabs.classList.add('extra-networks');
const en = gradioApp().getElementById(`${tabname}_extra_networks`);
tabs = gradioApp().querySelector(`#${tabname}_extra_tabs > div`);
if (!tabs) return;
// buttons
const btnRefresh = gradioApp().getElementById(`${tabname}_extra_refresh`);
const btnScan = gradioApp().getElementById(`${tabname}_extra_scan`);
const btnSave = gradioApp().getElementById(`${tabname}_extra_save`);
const btnClose = gradioApp().getElementById(`${tabname}_extra_close`);
const btnSort = gradioApp().getElementById(`${tabname}_extra_sort`);
const btnView = gradioApp().getElementById(`${tabname}_extra_view`);
const btnModel = gradioApp().getElementById(`${tabname}_extra_model`);
const btnApply = gradioApp().getElementById(`${tabname}_extra_apply`);
const buttons = document.createElement('span');
buttons.classList.add('buttons');
if (btnRefresh) buttons.appendChild(btnRefresh);
if (btnModel) buttons.appendChild(btnModel);
if (btnApply) buttons.appendChild(btnApply);
if (btnScan) buttons.appendChild(btnScan);
if (btnSave) buttons.appendChild(btnSave);
if (btnSort) buttons.appendChild(btnSort);
if (btnView) buttons.appendChild(btnView);
if (btnClose) buttons.appendChild(btnClose);
btnModel.onclick = () => btnModel.classList.toggle('toolbutton-selected');
tabs.appendChild(buttons);
// details
const detailsImg = gradioApp().getElementById(`${tabname}_extra_details_img`);
const detailsClose = gradioApp().getElementById(`${tabname}_extra_details_close`);
if (detailsImg && detailsClose) {
detailsImg.title = 'Close details';
detailsImg.onclick = () => detailsClose.click();
}
// search and description
const div = document.createElement('div');
div.classList.add('second-line');
tabs.appendChild(div);
const txtSearch = gradioApp().querySelector(`#${tabname}_extra_search`);
const txtSearchValue = gradioApp().querySelector(`#${tabname}_extra_search textarea`);
const txtDescription = gradioApp().getElementById(`${tabname}_description`);
txtSearch.classList.add('search');
txtDescription.classList.add('description');
div.appendChild(txtSearch);
div.appendChild(txtDescription);
let searchTimer = null;
txtSearchValue.addEventListener('input', (evt) => {
if (searchTimer) clearTimeout(searchTimer);
searchTimer = setTimeout(async () => {
await filterExtraNetworksForTab(txtSearchValue.value.toLowerCase());
searchTimer = null;
}, 100);
});
// card hover
let hoverTimer = null;
let previousCard = null;
gradioApp().getElementById(`${tabname}_extra_tabs`).onmouseover = (e) => {
const el = e.target.closest('.card'); // bubble-up to card
if (!el || (el.title === previousCard)) return;
if (!hoverTimer) {
hoverTimer = setTimeout(() => {
readCardDescription(el.dataset.page, el.dataset.name);
readCardTags(el, el.dataset.tags);
previousCard = el.title;
}, 300);
}
el.onmouseout = () => {
clearTimeout(hoverTimer);
hoverTimer = null;
};
};
// en style
if (!en) return;
const intersectionObserver = new IntersectionObserver((entries) => {
for (const el of Array.from(gradioApp().querySelectorAll('.extra-networks-page'))) {
el.style.height = `${window.opts.extra_networks_height}vh`;
el.parentElement.style.width = '-webkit-fill-available';
}
if (entries[0].intersectionRatio > 0) {
refreshENpage();
if (window.opts.extra_networks_card_cover === 'cover') {
en.style.transition = '';
en.style.zIndex = 100;
en.style.top = '13em';
en.style.position = 'absolute';
en.style.right = 'unset';
en.style.width = 'unset';
en.style.height = 'unset';
gradioApp().getElementById(`${tabname}_settings`).parentNode.style.width = 'unset';
} else if (window.opts.extra_networks_card_cover === 'sidebar') {
en.style.zIndex = 100;
en.style.position = 'absolute';
en.style.right = '0';
en.style.top = '13em';
en.style.height = '-webkit-fill-available';
en.style.transition = 'width 0.3s ease';
en.style.width = `${window.opts.extra_networks_sidebar_width}vw`;
gradioApp().getElementById(`${tabname}_settings`).parentNode.style.width = `${100 - 2 - window.opts.extra_networks_sidebar_width}vw`;
} else {
en.style.transition = '';
en.style.zIndex = 0;
en.style.top = 0;
en.style.position = 'relative';
en.style.right = 'unset';
en.style.width = 'unset';
en.style.height = 'unset';
gradioApp().getElementById(`${tabname}_settings`).parentNode.style.width = 'unset';
}
} else {
if (window.opts.extra_networks_card_cover === 'sidebar') en.style.width = 0;
gradioApp().getElementById(`${tabname}_settings`).parentNode.style.width = 'unset';
}
});
intersectionObserver.observe(en); // monitor visibility of
}
async function setupExtraNetworks() {
setupExtraNetworksForTab('txt2img');
setupExtraNetworksForTab('img2img');
setupExtraNetworksForTab('control');
function registerPrompt(tabname, id) {
const textarea = gradioApp().querySelector(`#${id} > label > textarea`);
if (!textarea) return;
if (!activePromptTextarea[tabname]) activePromptTextarea[tabname] = textarea;
textarea.addEventListener('focus', () => { activePromptTextarea[tabname] = textarea; });
}
registerPrompt('txt2img', 'txt2img_prompt');
registerPrompt('txt2img', 'txt2img_neg_prompt');
registerPrompt('img2img', 'img2img_prompt');
registerPrompt('img2img', 'img2img_neg_prompt');
registerPrompt('control', 'control_prompt');
registerPrompt('control', 'control_neg_prompt');
log('initExtraNetworks');
}
onUiLoaded(setupExtraNetworks);
|