toto10 commited on
Commit
6f24557
1 Parent(s): bf87c2a

e9f3000099baef4d6602519f3417f035ac4372bc76522d0d837800d2d2233d61

Browse files
Files changed (50) hide show
  1. html/svg/picture-in-picture-exit-line.svg +1 -0
  2. html/svg/play-line.svg +1 -0
  3. html/svg/pulse-line.svg +1 -0
  4. html/svg/question-answer-fill.svg +1 -0
  5. html/svg/question-answer-line.svg +1 -0
  6. html/svg/recycle-line.svg +1 -0
  7. html/svg/refresh-line.svg +1 -0
  8. html/svg/reply-fill.svg +1 -0
  9. html/svg/reply-line.svg +1 -0
  10. html/svg/restart-fill.svg +1 -0
  11. html/svg/rocket-fill.svg +13 -0
  12. html/svg/save-2-line.svg +1 -0
  13. html/svg/save-3-line.svg +1 -0
  14. html/svg/skip-forward-line.svg +1 -0
  15. html/svg/sort-asc.svg +1 -0
  16. html/svg/sort-desc.svg +1 -0
  17. html/svg/spotlight/arrow.svg +1 -0
  18. html/svg/spotlight/error.svg +1 -0
  19. html/svg/spotlight/pause.svg +1 -0
  20. html/svg/spotlight/pixel.gif +0 -0
  21. html/svg/spotlight/play.svg +1 -0
  22. html/svg/spotlight/preloader.svg +1 -0
  23. html/svg/spotlight/theme.svg +1 -0
  24. html/svg/stack-line.svg +1 -0
  25. html/svg/stop-line.svg +1 -0
  26. html/svg/t-box-fill.svg +1 -0
  27. html/svg/terminal-box-fill.svg +1 -0
  28. html/svg/terminal-box-line.svg +1 -0
  29. html/svg/zoom-in-line.svg +1 -0
  30. html/svg/zoom-out-line.svg +1 -0
  31. javascript/aspectRatioOverlay.js +112 -0
  32. javascript/badScaleChecker.js +108 -0
  33. javascript/contextMenus.js +177 -0
  34. javascript/dragdrop.js +109 -0
  35. javascript/edit-attention.js +121 -0
  36. javascript/edit-order.js +41 -0
  37. javascript/extensions.js +91 -0
  38. javascript/extraNetworks.js +579 -0
  39. javascript/generationParams.js +30 -0
  40. javascript/hints.js +202 -0
  41. javascript/hires_fix.js +19 -0
  42. javascript/imageMaskFix.js +339 -0
  43. javascript/imageviewer.js +242 -0
  44. javascript/imageviewerGamepad.js +63 -0
  45. javascript/localization.js +175 -0
  46. javascript/notification.js +47 -0
  47. javascript/profilerVisualization.js +153 -0
  48. javascript/progressbar.js +208 -0
  49. javascript/spotlight.js +13 -0
  50. javascript/textualInversion.js +14 -0
html/svg/picture-in-picture-exit-line.svg ADDED
html/svg/play-line.svg ADDED
html/svg/pulse-line.svg ADDED
html/svg/question-answer-fill.svg ADDED
html/svg/question-answer-line.svg ADDED
html/svg/recycle-line.svg ADDED
html/svg/refresh-line.svg ADDED
html/svg/reply-fill.svg ADDED
html/svg/reply-line.svg ADDED
html/svg/restart-fill.svg ADDED
html/svg/rocket-fill.svg ADDED
html/svg/save-2-line.svg ADDED
html/svg/save-3-line.svg ADDED
html/svg/skip-forward-line.svg ADDED
html/svg/sort-asc.svg ADDED
html/svg/sort-desc.svg ADDED
html/svg/spotlight/arrow.svg ADDED
html/svg/spotlight/error.svg ADDED
html/svg/spotlight/pause.svg ADDED
html/svg/spotlight/pixel.gif ADDED
html/svg/spotlight/play.svg ADDED
html/svg/spotlight/preloader.svg ADDED
html/svg/spotlight/theme.svg ADDED
html/svg/stack-line.svg ADDED
html/svg/stop-line.svg ADDED
html/svg/t-box-fill.svg ADDED
html/svg/terminal-box-fill.svg ADDED
html/svg/terminal-box-line.svg ADDED
html/svg/zoom-in-line.svg ADDED
html/svg/zoom-out-line.svg ADDED
javascript/aspectRatioOverlay.js ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ let currentWidth = null;
2
+ let currentHeight = null;
3
+ let arFrameTimeout = setTimeout(function() {}, 0);
4
+
5
+ function dimensionChange(e, is_width, is_height) {
6
+
7
+ if (is_width) {
8
+ currentWidth = e.target.value * 1.0;
9
+ }
10
+ if (is_height) {
11
+ currentHeight = e.target.value * 1.0;
12
+ }
13
+
14
+ var inImg2img = gradioApp().querySelector("#tab_img2img").style.display == "block";
15
+
16
+ if (!inImg2img) {
17
+ return;
18
+ }
19
+
20
+ var targetElement = null;
21
+
22
+ var tabIndex = get_tab_index('mode_img2img');
23
+ if (tabIndex == 0) { // img2img
24
+ targetElement = gradioApp().querySelector('#img2img_image div[data-testid=image] img');
25
+ } else if (tabIndex == 1) { //Sketch
26
+ targetElement = gradioApp().querySelector('#img2img_sketch div[data-testid=image] img');
27
+ } else if (tabIndex == 2) { // Inpaint
28
+ targetElement = gradioApp().querySelector('#img2maskimg div[data-testid=image] img');
29
+ } else if (tabIndex == 3) { // Inpaint sketch
30
+ targetElement = gradioApp().querySelector('#inpaint_sketch div[data-testid=image] img');
31
+ }
32
+
33
+
34
+ if (targetElement) {
35
+
36
+ var arPreviewRect = gradioApp().querySelector('#imageARPreview');
37
+ if (!arPreviewRect) {
38
+ arPreviewRect = document.createElement('div');
39
+ arPreviewRect.id = "imageARPreview";
40
+ gradioApp().appendChild(arPreviewRect);
41
+ }
42
+
43
+
44
+
45
+ var viewportOffset = targetElement.getBoundingClientRect();
46
+
47
+ var viewportscale = Math.min(targetElement.clientWidth / targetElement.naturalWidth, targetElement.clientHeight / targetElement.naturalHeight);
48
+
49
+ var scaledx = targetElement.naturalWidth * viewportscale;
50
+ var scaledy = targetElement.naturalHeight * viewportscale;
51
+
52
+ var cleintRectTop = (viewportOffset.top + window.scrollY);
53
+ var cleintRectLeft = (viewportOffset.left + window.scrollX);
54
+ var cleintRectCentreY = cleintRectTop + (targetElement.clientHeight / 2);
55
+ var cleintRectCentreX = cleintRectLeft + (targetElement.clientWidth / 2);
56
+
57
+ var arscale = Math.min(scaledx / currentWidth, scaledy / currentHeight);
58
+ var arscaledx = currentWidth * arscale;
59
+ var arscaledy = currentHeight * arscale;
60
+
61
+ var arRectTop = cleintRectCentreY - (arscaledy / 2);
62
+ var arRectLeft = cleintRectCentreX - (arscaledx / 2);
63
+ var arRectWidth = arscaledx;
64
+ var arRectHeight = arscaledy;
65
+
66
+ arPreviewRect.style.top = arRectTop + 'px';
67
+ arPreviewRect.style.left = arRectLeft + 'px';
68
+ arPreviewRect.style.width = arRectWidth + 'px';
69
+ arPreviewRect.style.height = arRectHeight + 'px';
70
+
71
+ clearTimeout(arFrameTimeout);
72
+ arFrameTimeout = setTimeout(function() {
73
+ arPreviewRect.style.display = 'none';
74
+ }, 2000);
75
+
76
+ arPreviewRect.style.display = 'block';
77
+
78
+ }
79
+
80
+ }
81
+
82
+
83
+ onAfterUiUpdate(function() {
84
+ var arPreviewRect = gradioApp().querySelector('#imageARPreview');
85
+ if (arPreviewRect) {
86
+ arPreviewRect.style.display = 'none';
87
+ }
88
+ var tabImg2img = gradioApp().querySelector("#tab_img2img");
89
+ if (tabImg2img) {
90
+ var inImg2img = tabImg2img.style.display == "block";
91
+ if (inImg2img) {
92
+ let inputs = gradioApp().querySelectorAll('input');
93
+ inputs.forEach(function(e) {
94
+ var is_width = e.parentElement.id == "img2img_width";
95
+ var is_height = e.parentElement.id == "img2img_height";
96
+
97
+ if ((is_width || is_height) && !e.classList.contains('scrollwatch')) {
98
+ e.addEventListener('input', function(e) {
99
+ dimensionChange(e, is_width, is_height);
100
+ });
101
+ e.classList.add('scrollwatch');
102
+ }
103
+ if (is_width) {
104
+ currentWidth = e.value * 1.0;
105
+ }
106
+ if (is_height) {
107
+ currentHeight = e.value * 1.0;
108
+ }
109
+ });
110
+ }
111
+ }
112
+ });
javascript/badScaleChecker.js ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function() {
2
+ var ignore = localStorage.getItem("bad-scale-ignore-it") == "ignore-it";
3
+
4
+ function getScale() {
5
+ var ratio = 0,
6
+ screen = window.screen,
7
+ ua = navigator.userAgent.toLowerCase();
8
+
9
+ if (window.devicePixelRatio !== undefined) {
10
+ ratio = window.devicePixelRatio;
11
+ } else if (~ua.indexOf('msie')) {
12
+ if (screen.deviceXDPI && screen.logicalXDPI) {
13
+ ratio = screen.deviceXDPI / screen.logicalXDPI;
14
+ }
15
+ } else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
16
+ ratio = window.outerWidth / window.innerWidth;
17
+ }
18
+
19
+ return ratio == 0 ? 0 : Math.round(ratio * 100);
20
+ }
21
+
22
+ var showing = false;
23
+
24
+ var div = document.createElement("div");
25
+ div.style.position = "fixed";
26
+ div.style.top = "0px";
27
+ div.style.left = "0px";
28
+ div.style.width = "100vw";
29
+ div.style.backgroundColor = "firebrick";
30
+ div.style.textAlign = "center";
31
+ div.style.zIndex = 99;
32
+
33
+ var b = document.createElement("b");
34
+ b.innerHTML = 'Bad Scale: ??% ';
35
+
36
+ div.appendChild(b);
37
+
38
+ var note1 = document.createElement("p");
39
+ note1.innerHTML = "Change your browser or your computer settings!";
40
+ note1.title = 'Just make sure "computer-scale" * "browser-scale" = 100% ,\n' +
41
+ "you can keep your computer-scale and only change this page's scale,\n" +
42
+ "for example: your computer-scale is 125%, just use [\"CTRL\"+\"-\"] to make your browser-scale of this page to 80%.";
43
+ div.appendChild(note1);
44
+
45
+ var note2 = document.createElement("p");
46
+ note2.innerHTML = " Otherwise, it will cause this page to not function properly!";
47
+ note2.title = "When you click \"Copy image to: [inpaint sketch]\" in some img2img's tab,\n" +
48
+ "if scale<100% the canvas will be invisible,\n" +
49
+ "else if scale>100% this page will take large amount of memory and CPU performance.";
50
+ div.appendChild(note2);
51
+
52
+ var btn = document.createElement("button");
53
+ btn.innerHTML = "Click here to ignore";
54
+
55
+ div.appendChild(btn);
56
+
57
+ function tryShowTopBar(scale) {
58
+ if (showing) return;
59
+
60
+ b.innerHTML = 'Bad Scale: ' + scale + '% ';
61
+
62
+ var updateScaleTimer = setInterval(function() {
63
+ var newScale = getScale();
64
+ b.innerHTML = 'Bad Scale: ' + newScale + '% ';
65
+ if (newScale == 100) {
66
+ var p = div.parentNode;
67
+ if (p != null) p.removeChild(div);
68
+ showing = false;
69
+ clearInterval(updateScaleTimer);
70
+ check();
71
+ }
72
+ }, 999);
73
+
74
+ btn.onclick = function() {
75
+ clearInterval(updateScaleTimer);
76
+ var p = div.parentNode;
77
+ if (p != null) p.removeChild(div);
78
+ ignore = true;
79
+ showing = false;
80
+ localStorage.setItem("bad-scale-ignore-it", "ignore-it");
81
+ };
82
+
83
+ document.body.appendChild(div);
84
+ }
85
+
86
+ function check() {
87
+ if (!ignore) {
88
+ var timer = setInterval(function() {
89
+ var scale = getScale();
90
+ if (scale != 100 && !ignore) {
91
+ tryShowTopBar(scale);
92
+ clearInterval(timer);
93
+ }
94
+ if (ignore) {
95
+ clearInterval(timer);
96
+ }
97
+ }, 999);
98
+ }
99
+ }
100
+
101
+ if (document.readyState != "complete") {
102
+ document.onreadystatechange = function() {
103
+ if (document.readyState != "complete") check();
104
+ };
105
+ } else {
106
+ check();
107
+ }
108
+ })();
javascript/contextMenus.js ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ var contextMenuInit = function() {
3
+ let eventListenerApplied = false;
4
+ let menuSpecs = new Map();
5
+
6
+ const uid = function() {
7
+ return Date.now().toString(36) + Math.random().toString(36).substring(2);
8
+ };
9
+
10
+ function showContextMenu(event, element, menuEntries) {
11
+ let posx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
12
+ let posy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
13
+
14
+ let oldMenu = gradioApp().querySelector('#context-menu');
15
+ if (oldMenu) {
16
+ oldMenu.remove();
17
+ }
18
+
19
+ let baseStyle = window.getComputedStyle(uiCurrentTab);
20
+
21
+ const contextMenu = document.createElement('nav');
22
+ contextMenu.id = "context-menu";
23
+ contextMenu.style.background = baseStyle.background;
24
+ contextMenu.style.color = baseStyle.color;
25
+ contextMenu.style.fontFamily = baseStyle.fontFamily;
26
+ contextMenu.style.top = posy + 'px';
27
+ contextMenu.style.left = posx + 'px';
28
+
29
+
30
+
31
+ const contextMenuList = document.createElement('ul');
32
+ contextMenuList.className = 'context-menu-items';
33
+ contextMenu.append(contextMenuList);
34
+
35
+ menuEntries.forEach(function(entry) {
36
+ let contextMenuEntry = document.createElement('a');
37
+ contextMenuEntry.innerHTML = entry['name'];
38
+ contextMenuEntry.addEventListener("click", function() {
39
+ entry['func']();
40
+ });
41
+ contextMenuList.append(contextMenuEntry);
42
+
43
+ });
44
+
45
+ gradioApp().appendChild(contextMenu);
46
+
47
+ let menuWidth = contextMenu.offsetWidth + 4;
48
+ let menuHeight = contextMenu.offsetHeight + 4;
49
+
50
+ let windowWidth = window.innerWidth;
51
+ let windowHeight = window.innerHeight;
52
+
53
+ if ((windowWidth - posx) < menuWidth) {
54
+ contextMenu.style.left = windowWidth - menuWidth + "px";
55
+ }
56
+
57
+ if ((windowHeight - posy) < menuHeight) {
58
+ contextMenu.style.top = windowHeight - menuHeight + "px";
59
+ }
60
+
61
+ }
62
+
63
+ function appendContextMenuOption(targetElementSelector, entryName, entryFunction) {
64
+
65
+ var currentItems = menuSpecs.get(targetElementSelector);
66
+
67
+ if (!currentItems) {
68
+ currentItems = [];
69
+ menuSpecs.set(targetElementSelector, currentItems);
70
+ }
71
+ let newItem = {
72
+ id: targetElementSelector + '_' + uid(),
73
+ name: entryName,
74
+ func: entryFunction,
75
+ isNew: true
76
+ };
77
+
78
+ currentItems.push(newItem);
79
+ return newItem['id'];
80
+ }
81
+
82
+ function removeContextMenuOption(uid) {
83
+ menuSpecs.forEach(function(v) {
84
+ let index = -1;
85
+ v.forEach(function(e, ei) {
86
+ if (e['id'] == uid) {
87
+ index = ei;
88
+ }
89
+ });
90
+ if (index >= 0) {
91
+ v.splice(index, 1);
92
+ }
93
+ });
94
+ }
95
+
96
+ function addContextMenuEventListener() {
97
+ if (eventListenerApplied) {
98
+ return;
99
+ }
100
+ gradioApp().addEventListener("click", function(e) {
101
+ if (!e.isTrusted) {
102
+ return;
103
+ }
104
+
105
+ let oldMenu = gradioApp().querySelector('#context-menu');
106
+ if (oldMenu) {
107
+ oldMenu.remove();
108
+ }
109
+ });
110
+ gradioApp().addEventListener("contextmenu", function(e) {
111
+ let oldMenu = gradioApp().querySelector('#context-menu');
112
+ if (oldMenu) {
113
+ oldMenu.remove();
114
+ }
115
+ menuSpecs.forEach(function(v, k) {
116
+ if (e.composedPath()[0].matches(k)) {
117
+ showContextMenu(e, e.composedPath()[0], v);
118
+ e.preventDefault();
119
+ }
120
+ });
121
+ });
122
+ eventListenerApplied = true;
123
+
124
+ }
125
+
126
+ return [appendContextMenuOption, removeContextMenuOption, addContextMenuEventListener];
127
+ };
128
+
129
+ var initResponse = contextMenuInit();
130
+ var appendContextMenuOption = initResponse[0];
131
+ var removeContextMenuOption = initResponse[1];
132
+ var addContextMenuEventListener = initResponse[2];
133
+
134
+ (function() {
135
+ //Start example Context Menu Items
136
+ let generateOnRepeat = function(genbuttonid, interruptbuttonid) {
137
+ let genbutton = gradioApp().querySelector(genbuttonid);
138
+ let interruptbutton = gradioApp().querySelector(interruptbuttonid);
139
+ if (!interruptbutton.offsetParent) {
140
+ genbutton.click();
141
+ }
142
+ clearInterval(window.generateOnRepeatInterval);
143
+ window.generateOnRepeatInterval = setInterval(function() {
144
+ if (!interruptbutton.offsetParent) {
145
+ genbutton.click();
146
+ }
147
+ },
148
+ 500);
149
+ };
150
+
151
+ let generateOnRepeat_txt2img = function() {
152
+ generateOnRepeat('#txt2img_generate', '#txt2img_interrupt');
153
+ };
154
+
155
+ let generateOnRepeat_img2img = function() {
156
+ generateOnRepeat('#img2img_generate', '#img2img_interrupt');
157
+ };
158
+
159
+ appendContextMenuOption('#txt2img_generate', 'Generate forever', generateOnRepeat_txt2img);
160
+ appendContextMenuOption('#txt2img_interrupt', 'Generate forever', generateOnRepeat_txt2img);
161
+ appendContextMenuOption('#img2img_generate', 'Generate forever', generateOnRepeat_img2img);
162
+ appendContextMenuOption('#img2img_interrupt', 'Generate forever', generateOnRepeat_img2img);
163
+
164
+ let cancelGenerateForever = function() {
165
+ clearInterval(window.generateOnRepeatInterval);
166
+ };
167
+
168
+ appendContextMenuOption('#txt2img_interrupt', 'Cancel generate forever', cancelGenerateForever);
169
+ appendContextMenuOption('#txt2img_generate', 'Cancel generate forever', cancelGenerateForever);
170
+ appendContextMenuOption('#img2img_interrupt', 'Cancel generate forever', cancelGenerateForever);
171
+ appendContextMenuOption('#img2img_generate', 'Cancel generate forever', cancelGenerateForever);
172
+
173
+ })();
174
+ //End example Context Menu Items
175
+
176
+ onAfterUiUpdate(addContextMenuEventListener);
177
+ */
javascript/dragdrop.js ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // allows drag-dropping files into gradio image elements, and also pasting images from clipboard
2
+
3
+ function isValidImageList(files) {
4
+ return (
5
+ files &&
6
+ files?.length === 1 &&
7
+ ["image/png", "image/gif", "image/jpeg"].includes(files[0].type)
8
+ );
9
+ }
10
+
11
+ function dropReplaceImage(imgWrap, files) {
12
+ if (!isValidImageList(files)) {
13
+ return;
14
+ }
15
+
16
+ const tmpFile = files[0];
17
+
18
+ imgWrap.querySelector('[aria-label="Clear"]')?.click();
19
+ const callback = () => {
20
+ const fileInput = imgWrap.querySelector('input[type="file"]');
21
+ if (fileInput) {
22
+ if (files.length === 0) {
23
+ files = new DataTransfer();
24
+ files.items.add(tmpFile);
25
+ fileInput.files = files.files;
26
+ } else {
27
+ fileInput.files = files;
28
+ }
29
+ fileInput.dispatchEvent(new Event("change"));
30
+ }
31
+ };
32
+
33
+ if (imgWrap.closest("#pnginfo_image")) {
34
+ // special treatment for PNG Info tab, wait for fetch request to finish
35
+ const oldFetch = window.fetch;
36
+ window.fetch = async (input, options) => {
37
+ const response = await oldFetch(input, options);
38
+ if ("api/predict/" === input) {
39
+ const content = await response.text();
40
+ window.fetch = oldFetch;
41
+ window.requestAnimationFrame(() => callback());
42
+ return new Response(content, {
43
+ status: response.status,
44
+ statusText: response.statusText,
45
+ headers: response.headers,
46
+ });
47
+ }
48
+ return response;
49
+ };
50
+ } else {
51
+ window.requestAnimationFrame(() => callback());
52
+ }
53
+ }
54
+
55
+ window.document.addEventListener("dragover", (e) => {
56
+ const target = e.composedPath()[0];
57
+ const imgWrap = target.closest('[data-testid="image"]');
58
+ if (
59
+ !imgWrap &&
60
+ target.placeholder &&
61
+ target.placeholder.indexOf("Prompt") == -1
62
+ ) {
63
+ return;
64
+ }
65
+ e.stopPropagation();
66
+ e.preventDefault();
67
+ e.dataTransfer.dropEffect = "copy";
68
+ });
69
+
70
+ window.document.addEventListener("drop", (e) => {
71
+ const target = e.composedPath()[0];
72
+ if (target.placeholder.indexOf("Prompt") == -1) {
73
+ return;
74
+ }
75
+ const imgWrap = target.closest('[data-testid="image"]');
76
+ if (!imgWrap) {
77
+ return;
78
+ }
79
+ e.stopPropagation();
80
+ e.preventDefault();
81
+ const files = e.dataTransfer.files;
82
+ dropReplaceImage(imgWrap, files);
83
+
84
+ });
85
+
86
+ window.addEventListener("paste", (e) => {
87
+ const files = e.clipboardData.files;
88
+ if (!isValidImageList(files)) {
89
+ return;
90
+ }
91
+
92
+ const visibleImageFields = [
93
+ ...gradioApp().querySelectorAll('[data-testid="image"]'),
94
+ ].filter((el) => uiElementIsVisible(el));
95
+ if (!visibleImageFields.length) {
96
+ return;
97
+ }
98
+
99
+ const firstFreeImageField = visibleImageFields.filter((el) =>
100
+ el.querySelector("input[type=file]")
101
+ )?.[0];
102
+
103
+ dropReplaceImage(
104
+ firstFreeImageField
105
+ ? firstFreeImageField
106
+ : visibleImageFields[visibleImageFields.length - 1],
107
+ files
108
+ );
109
+ });
javascript/edit-attention.js ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function keyupEditAttention(event) {
2
+ let target = event.originalTarget || event.composedPath()[0];
3
+ if (!target.matches("*:is([id*='_toprow'] [id*='_prompt'], .prompt) textarea")) return;
4
+ if (!(event.metaKey || event.ctrlKey)) return;
5
+
6
+ let isPlus = event.key == "ArrowUp";
7
+ let isMinus = event.key == "ArrowDown";
8
+ if (!isPlus && !isMinus) return;
9
+
10
+ let selectionStart = target.selectionStart;
11
+ let selectionEnd = target.selectionEnd;
12
+ let text = target.value;
13
+
14
+ function selectCurrentParenthesisBlock(OPEN, CLOSE) {
15
+ if (selectionStart !== selectionEnd) return false;
16
+
17
+ // Find opening parenthesis around current cursor
18
+ const before = text.substring(0, selectionStart);
19
+ let beforeParen = before.lastIndexOf(OPEN);
20
+ if (beforeParen == -1) return false;
21
+ let beforeParenClose = before.lastIndexOf(CLOSE);
22
+ while (beforeParenClose !== -1 && beforeParenClose > beforeParen) {
23
+ beforeParen = before.lastIndexOf(OPEN, beforeParen - 1);
24
+ beforeParenClose = before.lastIndexOf(CLOSE, beforeParenClose - 1);
25
+ }
26
+
27
+ // Find closing parenthesis around current cursor
28
+ const after = text.substring(selectionStart);
29
+ let afterParen = after.indexOf(CLOSE);
30
+ if (afterParen == -1) return false;
31
+ let afterParenOpen = after.indexOf(OPEN);
32
+ while (afterParenOpen !== -1 && afterParen > afterParenOpen) {
33
+ afterParen = after.indexOf(CLOSE, afterParen + 1);
34
+ afterParenOpen = after.indexOf(OPEN, afterParenOpen + 1);
35
+ }
36
+ if (beforeParen === -1 || afterParen === -1) return false;
37
+
38
+ // Set the selection to the text between the parenthesis
39
+ const parenContent = text.substring(beforeParen + 1, selectionStart + afterParen);
40
+ const lastColon = parenContent.lastIndexOf(":");
41
+ selectionStart = beforeParen + 1;
42
+ selectionEnd = selectionStart + lastColon;
43
+ target.setSelectionRange(selectionStart, selectionEnd);
44
+ return true;
45
+ }
46
+
47
+ function selectCurrentWord() {
48
+ if (selectionStart !== selectionEnd) return false;
49
+ const delimiters = opts.keyedit_delimiters + " \r\n\t";
50
+
51
+ // seek backward until to find beggining
52
+ while (!delimiters.includes(text[selectionStart - 1]) && selectionStart > 0) {
53
+ selectionStart--;
54
+ }
55
+
56
+ // seek forward to find end
57
+ while (!delimiters.includes(text[selectionEnd]) && selectionEnd < text.length) {
58
+ selectionEnd++;
59
+ }
60
+
61
+ target.setSelectionRange(selectionStart, selectionEnd);
62
+ return true;
63
+ }
64
+
65
+ // If the user hasn't selected anything, let's select their current parenthesis block or word
66
+ if (!selectCurrentParenthesisBlock('<', '>') && !selectCurrentParenthesisBlock('(', ')')) {
67
+ selectCurrentWord();
68
+ }
69
+
70
+ event.preventDefault();
71
+
72
+ var closeCharacter = ')';
73
+ var delta = opts.keyedit_precision_attention;
74
+
75
+ if (selectionStart > 0 && text[selectionStart - 1] == '<') {
76
+ closeCharacter = '>';
77
+ delta = opts.keyedit_precision_extra;
78
+ } else if (selectionStart == 0 || text[selectionStart - 1] != "(") {
79
+
80
+ // do not include spaces at the end
81
+ while (selectionEnd > selectionStart && text[selectionEnd - 1] == ' ') {
82
+ selectionEnd -= 1;
83
+ }
84
+ if (selectionStart == selectionEnd) {
85
+ return;
86
+ }
87
+
88
+ text = text.slice(0, selectionStart) + "(" + text.slice(selectionStart, selectionEnd) + ":1.0)" + text.slice(selectionEnd);
89
+
90
+ selectionStart += 1;
91
+ selectionEnd += 1;
92
+ }
93
+
94
+ var end = text.slice(selectionEnd + 1).indexOf(closeCharacter) + 1;
95
+ var weight = parseFloat(text.slice(selectionEnd + 1, selectionEnd + 1 + end));
96
+ if (isNaN(weight)) return;
97
+
98
+ weight += isPlus ? delta : -delta;
99
+ weight = parseFloat(weight.toPrecision(12));
100
+ if (String(weight).length == 1) weight += ".0";
101
+
102
+ if (closeCharacter == ')' && weight == 1) {
103
+ var endParenPos = text.substring(selectionEnd).indexOf(')');
104
+ text = text.slice(0, selectionStart - 1) + text.slice(selectionStart, selectionEnd) + text.slice(selectionEnd + endParenPos + 1);
105
+ selectionStart--;
106
+ selectionEnd--;
107
+ } else {
108
+ text = text.slice(0, selectionEnd + 1) + weight + text.slice(selectionEnd + end);
109
+ }
110
+
111
+ target.focus();
112
+ target.value = text;
113
+ target.selectionStart = selectionStart;
114
+ target.selectionEnd = selectionEnd;
115
+
116
+ updateInput(target);
117
+ }
118
+
119
+ addEventListener('keydown', (event) => {
120
+ keyupEditAttention(event);
121
+ });
javascript/edit-order.js ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* alt+left/right moves text in prompt */
2
+
3
+ function keyupEditOrder(event) {
4
+ if (!opts.keyedit_move) return;
5
+
6
+ let target = event.originalTarget || event.composedPath()[0];
7
+ if (!target.matches("*:is([id*='_toprow'] [id*='_prompt'], .prompt) textarea")) return;
8
+ if (!event.altKey) return;
9
+
10
+ let isLeft = event.key == "ArrowLeft";
11
+ let isRight = event.key == "ArrowRight";
12
+ if (!isLeft && !isRight) return;
13
+ event.preventDefault();
14
+
15
+ let selectionStart = target.selectionStart;
16
+ let selectionEnd = target.selectionEnd;
17
+ let text = target.value;
18
+ let items = text.split(",");
19
+ let indexStart = (text.slice(0, selectionStart).match(/,/g) || []).length;
20
+ let indexEnd = (text.slice(0, selectionEnd).match(/,/g) || []).length;
21
+ let range = indexEnd - indexStart + 1;
22
+
23
+ if (isLeft && indexStart > 0) {
24
+ items.splice(indexStart - 1, 0, ...items.splice(indexStart, range));
25
+ target.value = items.join();
26
+ target.selectionStart = items.slice(0, indexStart - 1).join().length + (indexStart == 1 ? 0 : 1);
27
+ target.selectionEnd = items.slice(0, indexEnd).join().length;
28
+ } else if (isRight && indexEnd < items.length - 1) {
29
+ items.splice(indexStart + 1, 0, ...items.splice(indexStart, range));
30
+ target.value = items.join();
31
+ target.selectionStart = items.slice(0, indexStart + 1).join().length + 1;
32
+ target.selectionEnd = items.slice(0, indexEnd + 2).join().length;
33
+ }
34
+
35
+ event.preventDefault();
36
+ updateInput(target);
37
+ }
38
+
39
+ addEventListener('keydown', (event) => {
40
+ keyupEditOrder(event);
41
+ });
javascript/extensions.js ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function extensions_apply(_disabled_list, _update_list, disable_all) {
2
+ var disable = [];
3
+ var update = [];
4
+
5
+ gradioApp().querySelectorAll('#extensions input[type="checkbox"]').forEach(function(x) {
6
+ if (x.name.startsWith("enable_") && !x.checked) {
7
+ disable.push(x.name.substring(7));
8
+ }
9
+
10
+ if (x.name.startsWith("update_") && x.checked) {
11
+ update.push(x.name.substring(7));
12
+ }
13
+ });
14
+
15
+ restart_reload();
16
+
17
+ return [JSON.stringify(disable), JSON.stringify(update), disable_all];
18
+ }
19
+
20
+ function extensions_check() {
21
+ var disable = [];
22
+
23
+ gradioApp().querySelectorAll('#extensions input[type="checkbox"]').forEach(function(x) {
24
+ if (x.name.startsWith("enable_") && !x.checked) {
25
+ disable.push(x.name.substring(7));
26
+ }
27
+ });
28
+
29
+ gradioApp().querySelectorAll('#extensions .extension_status').forEach(function(x) {
30
+ x.innerHTML = "Loading...";
31
+ });
32
+
33
+
34
+ var id = randomId();
35
+ requestProgress(id, gradioApp().getElementById('extensions_installed_top'), null, function() {
36
+
37
+ });
38
+
39
+ return [id, JSON.stringify(disable)];
40
+ }
41
+
42
+ function install_extension_from_index(button, url) {
43
+ button.disabled = "disabled";
44
+ button.value = "Installing...";
45
+
46
+ var textarea = gradioApp().querySelector('#extension_to_install textarea');
47
+ textarea.value = url;
48
+ updateInput(textarea);
49
+
50
+ gradioApp().querySelector('#install_extension_button').click();
51
+ }
52
+
53
+ function config_state_confirm_restore(_, config_state_name, config_restore_type) {
54
+ if (config_state_name == "Current") {
55
+ return [false, config_state_name, config_restore_type];
56
+ }
57
+ let restored = "";
58
+ if (config_restore_type == "extensions") {
59
+ restored = "all saved extension versions";
60
+ } else if (config_restore_type == "webui") {
61
+ restored = "the webui version";
62
+ } else {
63
+ restored = "the webui version and all saved extension versions";
64
+ }
65
+ let confirmed = confirm("Are you sure you want to restore from this state?\nThis will reset " + restored + ".");
66
+ if (confirmed) {
67
+ restart_reload();
68
+ gradioApp().querySelectorAll('#extensions .extension_status').forEach(function(x) {
69
+ x.innerHTML = "Loading...";
70
+ });
71
+ }
72
+ return [confirmed, config_state_name, config_restore_type];
73
+ }
74
+
75
+ function toggle_all_extensions(event) {
76
+ gradioApp().querySelectorAll('#extensions .extension_toggle').forEach(function(checkbox_el) {
77
+ checkbox_el.checked = event.target.checked;
78
+ });
79
+ }
80
+
81
+ function toggle_extension() {
82
+ let all_extensions_toggled = true;
83
+ for (const checkbox_el of gradioApp().querySelectorAll('#extensions .extension_toggle')) {
84
+ if (!checkbox_el.checked) {
85
+ all_extensions_toggled = false;
86
+ break;
87
+ }
88
+ }
89
+
90
+ gradioApp().querySelector('#extensions .all_extensions_toggle').checked = all_extensions_toggled;
91
+ }
javascript/extraNetworks.js ADDED
@@ -0,0 +1,579 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function setupExtraNetworksForTab(tabname) {
2
+ gradioApp()
3
+ .querySelector("#" + tabname + "_extra_tabs")
4
+ .classList.add("extra-networks");
5
+
6
+ let tabs = gradioApp().querySelector("#" + tabname + "_extra_tabs > div");
7
+ let search = gradioApp().querySelector("#" + tabname + "_extra_search textarea" );
8
+ let refresh = gradioApp().getElementById(tabname + "_extra_refresh");
9
+
10
+ //let sort = gradioApp().getElementById(tabname + '_extra_sort');
11
+ //let sortOrder = gradioApp().getElementById(tabname + '_extra_sortorder');
12
+
13
+ let clear = document.createElement("div");
14
+ clear.id = tabname + "_extra_clear";
15
+ clear.classList.add("token-remove", "remove-all", "svelte-a6vu2r", "hide");
16
+ clear.title = "Clear search";
17
+ clear.innerHTML =
18
+ '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></svg>';
19
+
20
+ search.classList.add("search");
21
+
22
+ tabs.appendChild(search);
23
+ tabs.appendChild(clear);
24
+ tabs.appendChild(refresh);
25
+
26
+ /*
27
+ sort.classList.add('sort');
28
+ sortOrder.classList.add('sortorder');
29
+ sort.dataset.sortkey = 'sortDefault';
30
+ tabs.appendChild(sort);
31
+ tabs.appendChild(sortOrder); */
32
+
33
+ clear.addEventListener("click", function (evt) {
34
+ search.value = "";
35
+ updateInput(search);
36
+ });
37
+
38
+ setTimeout(function () {
39
+ refresh.click();
40
+ }, 500);
41
+
42
+
43
+ setTimeout(extraNetworksApplyFilter[tabname], 1);
44
+
45
+ search.addEventListener("input", function (evt) {
46
+ searchTerm = search.value.toLowerCase();
47
+
48
+ gradioApp()
49
+ .querySelectorAll("#" + tabname + "_extra_tabs div.card")
50
+ .forEach(function (elem) {
51
+ let text =
52
+ elem.querySelector(".name").textContent.toLowerCase() +
53
+ " " +
54
+ elem.querySelector(".search_term").textContent.toLowerCase();
55
+ elem.parentElement.style.display =
56
+ text.indexOf(searchTerm) == -1 ? "none" : "";
57
+ });
58
+ });
59
+ }
60
+
61
+ function applyExtraNetworkFilter(tabname){
62
+ setTimeout(extraNetworksApplyFilter[tabname], 1);
63
+ }
64
+
65
+ var extraNetworksApplyFilter = {}
66
+ var activePromptTextarea = {};
67
+
68
+ function setupExtraNetworks() {
69
+ setupExtraNetworksForTab("txt2img");
70
+ setupExtraNetworksForTab("img2img");
71
+
72
+ function registerPrompt(tabname, id) {
73
+ var textarea = gradioApp().querySelector("#" + id + " > label > textarea");
74
+
75
+ if (!activePromptTextarea[tabname]) {
76
+ activePromptTextarea[tabname] = textarea;
77
+ }
78
+
79
+ textarea.addEventListener("focus", function () {
80
+ activePromptTextarea[tabname] = textarea;
81
+ });
82
+ }
83
+
84
+ registerPrompt("txt2img", "txt2img_prompt");
85
+ registerPrompt("txt2img", "txt2img_neg_prompt");
86
+ registerPrompt("img2img", "img2img_prompt");
87
+ registerPrompt("img2img", "img2img_neg_prompt");
88
+ }
89
+
90
+ onUiLoaded(setupExtraNetworks);
91
+
92
+ var re_extranet = /<([^:]+:[^:]+):[\d\.]+>/;
93
+ var re_extranet_g = /\s+<([^:]+:[^:]+):[\d\.]+>/g;
94
+
95
+ function tryToRemoveExtraNetworkFromPrompt(textarea, text) {
96
+ var m = text.match(re_extranet);
97
+ if (!m) return false;
98
+
99
+ var partToSearch = m[1];
100
+ var replaced = false;
101
+ var newTextareaText = textarea.value.replaceAll(
102
+ re_extranet_g,
103
+ function (found) {
104
+ m = found.match(re_extranet);
105
+ if (m[1] == partToSearch) {
106
+ replaced = true;
107
+ return "";
108
+ }
109
+ return found;
110
+ }
111
+ );
112
+
113
+ if (replaced) {
114
+ textarea.value = newTextareaText;
115
+ return true;
116
+ }
117
+
118
+ return false;
119
+ }
120
+
121
+ function cardClicked(tabname, textToAdd, allowNegativePrompt) {
122
+ var textarea = allowNegativePrompt
123
+ ? activePromptTextarea[tabname]
124
+ : gradioApp().querySelector("#" + tabname + "_prompt > label > textarea");
125
+
126
+ if (!tryToRemoveExtraNetworkFromPrompt(textarea, textToAdd)) {
127
+ textarea.value =
128
+ textarea.value + opts.extra_networks_add_text_separator + textToAdd;
129
+ }
130
+
131
+ updateInput(textarea);
132
+ }
133
+
134
+ function saveCardPreview(event, tabname, filename) {
135
+ var textarea = gradioApp().querySelector(
136
+ "#" + tabname + "_preview_filename > label > textarea"
137
+ );
138
+ var button = gradioApp().getElementById(tabname + "_save_preview");
139
+
140
+ textarea.value = filename;
141
+ updateInput(textarea);
142
+
143
+ button.click();
144
+
145
+ var search = gradioApp().querySelector(
146
+ "#" + tabname + "_extra_tabs textarea"
147
+ );
148
+
149
+ setTimeout(function () {
150
+ search.value = search.value.toLowerCase();
151
+ updateInput(search);
152
+ }, 1000);
153
+
154
+ event.stopPropagation();
155
+ event.preventDefault();
156
+ }
157
+
158
+ function extraNetworksSearchButton(tabs_id, event) {
159
+ var searchTextarea = gradioApp().querySelector(
160
+ "#" + tabs_id + " > div > textarea"
161
+ );
162
+ var button = event.target;
163
+ var text = button.classList.contains("search-all")
164
+ ? ""
165
+ : button.textContent.trim();
166
+ //text = event.target.selectedIndex == 0 ? "" : event.target.options[event.target.selectedIndex].text;
167
+
168
+ searchTextarea.value = text;
169
+ updateInput(searchTextarea);
170
+ }
171
+
172
+ var globalPopup = null;
173
+ var globalPopupInner = null;
174
+ function popup(contents) {
175
+ if (!globalPopup) {
176
+ globalPopup = document.createElement("div");
177
+ globalPopup.onclick = function () {
178
+ globalPopup.style.display = "none";
179
+ };
180
+ globalPopup.classList.add("global-popup");
181
+
182
+ var close = document.createElement("div");
183
+ close.classList.add("global-popup-close");
184
+ close.onclick = function () {
185
+ globalPopup.style.display = "none";
186
+ };
187
+ close.title = "Close";
188
+ globalPopup.appendChild(close);
189
+
190
+ globalPopupInner = document.createElement("div");
191
+ globalPopupInner.onclick = function (event) {
192
+ event.stopPropagation();
193
+ return false;
194
+ };
195
+ globalPopupInner.classList.add("global-popup-inner");
196
+ globalPopup.appendChild(globalPopupInner);
197
+
198
+ gradioApp().appendChild(globalPopup);
199
+ }
200
+
201
+ globalPopupInner.innerHTML = "";
202
+ globalPopupInner.appendChild(contents);
203
+
204
+ globalPopup.style.display = "flex";
205
+ }
206
+
207
+ function extraNetworksShowMetadata(text) {
208
+ var elem = document.createElement("pre");
209
+ elem.classList.add("popup-metadata");
210
+ elem.textContent = text;
211
+
212
+ popup(elem);
213
+ }
214
+
215
+ function requestGet(url, data, handler, errorHandler) {
216
+ var xhr = new XMLHttpRequest();
217
+ var args = Object.keys(data)
218
+ .map(function (k) {
219
+ return encodeURIComponent(k) + "=" + encodeURIComponent(data[k]);
220
+ })
221
+ .join("&");
222
+ xhr.open("GET", url + "?" + args, true);
223
+
224
+ xhr.onreadystatechange = function () {
225
+ if (xhr.readyState === 4) {
226
+ if (xhr.status === 200) {
227
+ try {
228
+ var js = JSON.parse(xhr.responseText);
229
+ handler(js);
230
+ } catch (error) {
231
+ console.error(error);
232
+ errorHandler();
233
+ }
234
+ } else {
235
+ errorHandler();
236
+ }
237
+ }
238
+ };
239
+ var js = JSON.stringify(data);
240
+ xhr.send(js);
241
+ }
242
+
243
+ function extraNetworksRequestMetadata(event, extraPage, cardName) {
244
+ var showError = function () {
245
+ extraNetworksShowMetadata("there was an error getting metadata");
246
+ };
247
+
248
+ requestGet(
249
+ "./sd_extra_networks/metadata",
250
+ { page: extraPage, item: cardName },
251
+ function (data) {
252
+ if (data && data.metadata) {
253
+ extraNetworksShowMetadata(data.metadata);
254
+ } else {
255
+ showError();
256
+ }
257
+ },
258
+ showError
259
+ );
260
+
261
+ event.stopPropagation();
262
+ }
263
+
264
+
265
+ /*
266
+ function setupExtraNetworksForTab(tabname) {
267
+ gradioApp().querySelector('#' + tabname + '_extra_tabs').classList.add('extra-networks');
268
+
269
+ var tabs = gradioApp().querySelector('#' + tabname + '_extra_tabs > div');
270
+ var search = gradioApp().querySelector('#' + tabname + '_extra_search textarea');
271
+ var sort = gradioApp().getElementById(tabname + '_extra_sort');
272
+ var sortOrder = gradioApp().getElementById(tabname + '_extra_sortorder');
273
+ var refresh = gradioApp().getElementById(tabname + '_extra_refresh');
274
+
275
+ search.classList.add('search');
276
+ sort.classList.add('sort');
277
+ sortOrder.classList.add('sortorder');
278
+ sort.dataset.sortkey = 'sortDefault';
279
+ tabs.appendChild(search);
280
+ tabs.appendChild(sort);
281
+ tabs.appendChild(sortOrder);
282
+ tabs.appendChild(refresh);
283
+
284
+ var applyFilter = function() {
285
+ var searchTerm = search.value.toLowerCase();
286
+
287
+ gradioApp().querySelectorAll('#' + tabname + '_extra_tabs div.card').forEach(function(elem) {
288
+ var searchOnly = elem.querySelector('.search_only');
289
+ var text = elem.querySelector('.name').textContent.toLowerCase() + " " + elem.querySelector('.search_term').textContent.toLowerCase();
290
+
291
+ var visible = text.indexOf(searchTerm) != -1;
292
+
293
+ if (searchOnly && searchTerm.length < 4) {
294
+ visible = false;
295
+ }
296
+
297
+ elem.style.display = visible ? "" : "none";
298
+ });
299
+ };
300
+
301
+ var applySort = function() {
302
+ var reverse = sortOrder.classList.contains("sortReverse");
303
+ var sortKey = sort.querySelector("input").value.toLowerCase().replace("sort", "").replaceAll(" ", "_").replace(/_+$/, "").trim();
304
+ sortKey = sortKey ? "sort" + sortKey.charAt(0).toUpperCase() + sortKey.slice(1) : "";
305
+ var sortKeyStore = sortKey ? sortKey + (reverse ? "Reverse" : "") : "";
306
+ if (!sortKey || sortKeyStore == sort.dataset.sortkey) {
307
+ return;
308
+ }
309
+
310
+ sort.dataset.sortkey = sortKeyStore;
311
+
312
+ var cards = gradioApp().querySelectorAll('#' + tabname + '_extra_tabs div.card');
313
+ cards.forEach(function(card) {
314
+ card.originalParentElement = card.parentElement;
315
+ });
316
+ var sortedCards = Array.from(cards);
317
+ sortedCards.sort(function(cardA, cardB) {
318
+ var a = cardA.dataset[sortKey];
319
+ var b = cardB.dataset[sortKey];
320
+ if (!isNaN(a) && !isNaN(b)) {
321
+ return parseInt(a) - parseInt(b);
322
+ }
323
+
324
+ return (a < b ? -1 : (a > b ? 1 : 0));
325
+ });
326
+ if (reverse) {
327
+ sortedCards.reverse();
328
+ }
329
+ cards.forEach(function(card) {
330
+ card.remove();
331
+ });
332
+ sortedCards.forEach(function(card) {
333
+ card.originalParentElement.appendChild(card);
334
+ });
335
+ };
336
+
337
+ search.addEventListener("input", applyFilter);
338
+ applyFilter();
339
+ ["change", "blur", "click"].forEach(function(evt) {
340
+ sort.querySelector("input").addEventListener(evt, applySort);
341
+ });
342
+ sortOrder.addEventListener("click", function() {
343
+ sortOrder.classList.toggle("sortReverse");
344
+ applySort();
345
+ });
346
+
347
+ extraNetworksApplyFilter[tabname] = applyFilter;
348
+ }
349
+
350
+ function applyExtraNetworkFilter(tabname) {
351
+ setTimeout(extraNetworksApplyFilter[tabname], 1);
352
+ }
353
+
354
+ var extraNetworksApplyFilter = {};
355
+ var activePromptTextarea = {};
356
+
357
+ function setupExtraNetworks() {
358
+ setupExtraNetworksForTab('txt2img');
359
+ setupExtraNetworksForTab('img2img');
360
+
361
+ function registerPrompt(tabname, id) {
362
+ var textarea = gradioApp().querySelector("#" + id + " > label > textarea");
363
+
364
+ if (!activePromptTextarea[tabname]) {
365
+ activePromptTextarea[tabname] = textarea;
366
+ }
367
+
368
+ textarea.addEventListener("focus", function() {
369
+ activePromptTextarea[tabname] = textarea;
370
+ });
371
+ }
372
+
373
+ registerPrompt('txt2img', 'txt2img_prompt');
374
+ registerPrompt('txt2img', 'txt2img_neg_prompt');
375
+ registerPrompt('img2img', 'img2img_prompt');
376
+ registerPrompt('img2img', 'img2img_neg_prompt');
377
+ }
378
+
379
+ onUiLoaded(setupExtraNetworks);
380
+
381
+ var re_extranet = /<([^:]+:[^:]+):[\d.]+>(.*)/;
382
+ var re_extranet_g = /\s+<([^:]+:[^:]+):[\d.]+>/g;
383
+
384
+ function tryToRemoveExtraNetworkFromPrompt(textarea, text) {
385
+ var m = text.match(re_extranet);
386
+ var replaced = false;
387
+ var newTextareaText;
388
+ if (m) {
389
+ var extraTextAfterNet = m[2];
390
+ var partToSearch = m[1];
391
+ var foundAtPosition = -1;
392
+ newTextareaText = textarea.value.replaceAll(re_extranet_g, function(found, net, pos) {
393
+ m = found.match(re_extranet);
394
+ if (m[1] == partToSearch) {
395
+ replaced = true;
396
+ foundAtPosition = pos;
397
+ return "";
398
+ }
399
+ return found;
400
+ });
401
+
402
+ if (foundAtPosition >= 0 && newTextareaText.substr(foundAtPosition, extraTextAfterNet.length) == extraTextAfterNet) {
403
+ newTextareaText = newTextareaText.substr(0, foundAtPosition) + newTextareaText.substr(foundAtPosition + extraTextAfterNet.length);
404
+ }
405
+ } else {
406
+ newTextareaText = textarea.value.replaceAll(new RegExp(text, "g"), function(found) {
407
+ if (found == text) {
408
+ replaced = true;
409
+ return "";
410
+ }
411
+ return found;
412
+ });
413
+ }
414
+
415
+ if (replaced) {
416
+ textarea.value = newTextareaText;
417
+ return true;
418
+ }
419
+
420
+ return false;
421
+ }
422
+
423
+ function cardClicked(tabname, textToAdd, allowNegativePrompt) {
424
+ var textarea = allowNegativePrompt ? activePromptTextarea[tabname] : gradioApp().querySelector("#" + tabname + "_prompt > label > textarea");
425
+
426
+ if (!tryToRemoveExtraNetworkFromPrompt(textarea, textToAdd)) {
427
+ textarea.value = textarea.value + opts.extra_networks_add_text_separator + textToAdd;
428
+ }
429
+
430
+ updateInput(textarea);
431
+ }
432
+
433
+ function saveCardPreview(event, tabname, filename) {
434
+ var textarea = gradioApp().querySelector("#" + tabname + '_preview_filename > label > textarea');
435
+ var button = gradioApp().getElementById(tabname + '_save_preview');
436
+
437
+ textarea.value = filename;
438
+ updateInput(textarea);
439
+
440
+ button.click();
441
+
442
+ event.stopPropagation();
443
+ event.preventDefault();
444
+ }
445
+
446
+ function extraNetworksSearchButton(tabs_id, event) {
447
+ var searchTextarea = gradioApp().querySelector("#" + tabs_id + ' > div > textarea');
448
+ var button = event.target;
449
+ var text = button.classList.contains("search-all") ? "" : button.textContent.trim();
450
+
451
+ searchTextarea.value = text;
452
+ updateInput(searchTextarea);
453
+ }
454
+
455
+ var globalPopup = null;
456
+ var globalPopupInner = null;
457
+ function closePopup() {
458
+ if (!globalPopup) return;
459
+
460
+ globalPopup.style.display = "none";
461
+ }
462
+ function popup(contents) {
463
+ if (!globalPopup) {
464
+ globalPopup = document.createElement('div');
465
+ globalPopup.onclick = closePopup;
466
+ globalPopup.classList.add('global-popup');
467
+
468
+ var close = document.createElement('div');
469
+ close.classList.add('global-popup-close');
470
+ close.onclick = closePopup;
471
+ close.title = "Close";
472
+ globalPopup.appendChild(close);
473
+
474
+ globalPopupInner = document.createElement('div');
475
+ globalPopupInner.onclick = function(event) {
476
+ event.stopPropagation(); return false;
477
+ };
478
+ globalPopupInner.classList.add('global-popup-inner');
479
+ globalPopup.appendChild(globalPopupInner);
480
+
481
+ gradioApp().querySelector('.main').appendChild(globalPopup);
482
+ }
483
+
484
+ globalPopupInner.innerHTML = '';
485
+ globalPopupInner.appendChild(contents);
486
+
487
+ globalPopup.style.display = "flex";
488
+ }
489
+
490
+ function extraNetworksShowMetadata(text) {
491
+ var elem = document.createElement('pre');
492
+ elem.classList.add('popup-metadata');
493
+ elem.textContent = text;
494
+
495
+ popup(elem);
496
+ }
497
+
498
+ function requestGet(url, data, handler, errorHandler) {
499
+ var xhr = new XMLHttpRequest();
500
+ var args = Object.keys(data).map(function(k) {
501
+ return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]);
502
+ }).join('&');
503
+ xhr.open("GET", url + "?" + args, true);
504
+
505
+ xhr.onreadystatechange = function() {
506
+ if (xhr.readyState === 4) {
507
+ if (xhr.status === 200) {
508
+ try {
509
+ var js = JSON.parse(xhr.responseText);
510
+ handler(js);
511
+ } catch (error) {
512
+ console.error(error);
513
+ errorHandler();
514
+ }
515
+ } else {
516
+ errorHandler();
517
+ }
518
+ }
519
+ };
520
+ var js = JSON.stringify(data);
521
+ xhr.send(js);
522
+ }
523
+
524
+ function extraNetworksRequestMetadata(event, extraPage, cardName) {
525
+ var showError = function() {
526
+ extraNetworksShowMetadata("there was an error getting metadata");
527
+ };
528
+
529
+ requestGet("./sd_extra_networks/metadata", {page: extraPage, item: cardName}, function(data) {
530
+ if (data && data.metadata) {
531
+ extraNetworksShowMetadata(data.metadata);
532
+ } else {
533
+ showError();
534
+ }
535
+ }, showError);
536
+
537
+ event.stopPropagation();
538
+ }
539
+
540
+ var extraPageUserMetadataEditors = {};
541
+
542
+ function extraNetworksEditUserMetadata(event, tabname, extraPage, cardName) {
543
+ var id = tabname + '_' + extraPage + '_edit_user_metadata';
544
+
545
+ var editor = extraPageUserMetadataEditors[id];
546
+ if (!editor) {
547
+ editor = {};
548
+ editor.page = gradioApp().getElementById(id);
549
+ editor.nameTextarea = gradioApp().querySelector("#" + id + "_name" + ' textarea');
550
+ editor.button = gradioApp().querySelector("#" + id + "_button");
551
+ extraPageUserMetadataEditors[id] = editor;
552
+ }
553
+
554
+ editor.nameTextarea.value = cardName;
555
+ updateInput(editor.nameTextarea);
556
+
557
+ editor.button.click();
558
+
559
+ popup(editor.page);
560
+
561
+ event.stopPropagation();
562
+ }
563
+
564
+ function extraNetworksRefreshSingleCard(page, tabname, name) {
565
+ requestGet("./sd_extra_networks/get-single-card", {page: page, tabname: tabname, name: name}, function(data) {
566
+ if (data && data.html) {
567
+ var card = gradioApp().querySelector('.card[data-name=' + JSON.stringify(name) + ']'); // likely using the wrong stringify function
568
+
569
+ var newDiv = document.createElement('DIV');
570
+ newDiv.innerHTML = data.html;
571
+ var newCard = newDiv.firstElementChild;
572
+
573
+ newCard.style = '';
574
+ card.parentElement.insertBefore(newCard, card);
575
+ card.parentElement.removeChild(card);
576
+ }
577
+ });
578
+ }
579
+ */
javascript/generationParams.js ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // attaches listeners to the txt2img and img2img galleries to update displayed generation param text when the image changes
2
+ let txt2img_gallery, img2img_gallery, modal = undefined;
3
+ onAfterUiUpdate(function() {
4
+ if (!txt2img_gallery) {
5
+ txt2img_gallery = attachGalleryListeners("txt2img");
6
+ }
7
+ if (!img2img_gallery) {
8
+ img2img_gallery = attachGalleryListeners("img2img");
9
+ }
10
+ });
11
+
12
+ let modalObserver = new MutationObserver(function(mutations) {
13
+ mutations.forEach(function(mutationRecord) {
14
+ let selectedTab = gradioApp().querySelector('#tabs div button.selected')?.innerText;
15
+ if (mutationRecord.target.style.display === 'none' && (selectedTab === 'txt2img' || selectedTab === 'img2img')) {
16
+ gradioApp().getElementById(selectedTab + "_generation_info_button")?.click();
17
+ }
18
+ });
19
+ });
20
+
21
+ function attachGalleryListeners(tab_name) {
22
+ var gallery = gradioApp().querySelector('#' + tab_name + '_gallery');
23
+ gallery?.addEventListener('click', () => gradioApp().getElementById(tab_name + "_generation_info_button").click());
24
+ gallery?.addEventListener('keydown', (e) => {
25
+ if (e.keyCode == 37 || e.keyCode == 39) { // left or right arrow
26
+ gradioApp().getElementById(tab_name + "_generation_info_button").click();
27
+ }
28
+ });
29
+ return gallery;
30
+ }
javascript/hints.js ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // mouseover tooltips for various UI elements
2
+
3
+ var titles = {
4
+ "Sampling steps": "How many times to improve the generated image iteratively; higher values take longer; very low values can produce bad results",
5
+ "Sampling method": "Which algorithm to use to produce the image",
6
+ "GFPGAN": "Restore low quality faces using GFPGAN neural network",
7
+ "Euler a": "Euler Ancestral - very creative, each can get a completely different picture depending on step count, setting steps higher than 30-40 does not help",
8
+ "DDIM": "Denoising Diffusion Implicit Models - best at inpainting",
9
+ "UniPC": "Unified Predictor-Corrector Framework for Fast Sampling of Diffusion Models",
10
+ "DPM adaptive": "Ignores step count - uses a number of steps determined by the CFG and resolution",
11
+
12
+ "\u{1F4D0}": "Auto detect size from img2img",
13
+ "Batch count": "How many batches of images to create (has no impact on generation performance or VRAM usage)",
14
+ "Batch size": "How many image to create in a single batch (increases generation performance at cost of higher VRAM usage)",
15
+ "CFG Scale": "Classifier Free Guidance Scale - how strongly the image should conform to prompt - lower values produce more creative results",
16
+ "Seed": "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result",
17
+ "\u{1f3b2}\ufe0f": "Set seed to -1, which will cause a new random number to be used every time",
18
+ "\u267b\ufe0f": "Reuse seed from last generation, mostly useful if it was randomized",
19
+ "\u2199\ufe0f": "Read generation parameters from prompt or last generation if prompt is empty into user interface.",
20
+ "\u{1f4c2}": "Open images output directory",
21
+ "\u{1f4be}": "Save style",
22
+ "\u{1f5d1}\ufe0f": "Clear prompt",
23
+ "\u{1f4cb}": "Apply selected styles to current prompt",
24
+ "\u{1f4d2}": "Paste available values into the field",
25
+ "\u{1f3b4}": "Show/hide extra networks",
26
+
27
+ "\u{1f5e8}": "Interogate Clip",
28
+ "\u{1f5ea}": "Interogate Deepbooru",
29
+ "\u{1F300}": "Restore progress",
30
+ "\u{267E}": "Toggle generate forever",
31
+
32
+
33
+ "Inpaint a part of image": "Draw a mask over an image, and the script will regenerate the masked area with content according to prompt",
34
+ "SD upscale": "Upscale image normally, split result into tiles, improve each tile using img2img, merge whole image back",
35
+
36
+ "Just resize": "Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.",
37
+ "Crop and resize": "Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out.",
38
+ "Resize and fill": "Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors.",
39
+
40
+ "Mask blur": "How much to blur the mask before processing, in pixels.",
41
+ "Masked content": "What to put inside the masked area before processing it with Stable Diffusion.",
42
+ "fill": "fill it with colors of the image",
43
+ "original": "keep whatever was there originally",
44
+ "latent noise": "fill it with latent space noise",
45
+ "latent nothing": "fill it with latent space zeroes",
46
+ "Inpaint at full resolution": "Upscale masked region to target resolution, do inpainting, downscale back and paste into original image",
47
+
48
+ "Denoising strength": "Determines how little respect the algorithm should have for image's content. At 0, nothing will change, and at 1 you'll get an unrelated image. With values below 1.0, processing will take less steps than the Sampling Steps slider specifies.",
49
+
50
+ "Skip": "Stop processing current image and continue processing.",
51
+ "Interrupt": "Stop processing images and return any results accumulated so far.",
52
+ "Save": "Write image to a directory (default - log/images) and generation parameters into csv file.",
53
+ "Zip": "Save as Zip",
54
+ "Send to txt2img": "Send to txt2img",
55
+ "Send to img2img": "Send to img2img",
56
+ "Send to inpaint": "Send to inpaint",
57
+ "Send to extras": "Send to extras",
58
+
59
+ "X values": "Separate values for X axis using commas.",
60
+ "Y values": "Separate values for Y axis using commas.",
61
+
62
+ "None": "Do not do anything special",
63
+ "Prompt matrix": "Separate prompts into parts using vertical pipe character (|) and the script will create a picture for every combination of them (except for the first part, which will be present in all combinations)",
64
+ "X/Y/Z plot": "Create grid(s) where images will have different parameters. Use inputs below to specify which parameters will be shared by columns and rows",
65
+ "Custom code": "Run Python code. Advanced user only. Must run program with --allow-code for this to work",
66
+
67
+ "Prompt S/R": "Separate a list of words with commas, and the first word will be used as a keyword: script will search for this word in the prompt, and replace it with others",
68
+ "Prompt order": "Separate a list of words with commas, and the script will make a variation of prompt with those words for their every possible order",
69
+
70
+ "Tiling": "Produce an image that can be tiled.",
71
+ "Tile overlap": "For SD upscale, how much overlap in pixels should there be between tiles. Tiles overlap so that when they are merged back into one picture, there is no clearly visible seam.",
72
+
73
+ "Variation seed": "Seed of a different picture to be mixed into the generation.",
74
+ "Variation strength": "How strong of a variation to produce. At 0, there will be no effect. At 1, you will get the complete picture with variation seed (except for ancestral samplers, where you will just get something).",
75
+ "Resize seed from height": "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution",
76
+ "Resize seed from width": "Make an attempt to produce a picture similar to what would have been produced with same seed at specified resolution",
77
+
78
+ "Interrogate": "Reconstruct prompt from existing image and put it into the prompt field.",
79
+
80
+ "Images filename pattern": "Use tags like [seed] and [date] to define how filenames for images are chosen. Leave empty for default.",
81
+ "Directory name pattern": "Use tags like [seed] and [date] to define how subdirectories for images and grids are chosen. Leave empty for default.",
82
+ "Max prompt words": "Set the maximum number of words to be used in the [prompt_words] option; ATTENTION: If the words are too long, they may exceed the maximum length of the file path that the system can handle",
83
+
84
+ "Loopback": "Performs img2img processing multiple times. Output images are used as input for the next loop.",
85
+ "Loops": "How many times to process an image. Each output is used as the input of the next loop. If set to 1, behavior will be as if this script were not used.",
86
+ "Final denoising strength": "The denoising strength for the final loop of each image in the batch.",
87
+ "Denoising strength curve": "The denoising curve controls the rate of denoising strength change each loop. Aggressive: Most of the change will happen towards the start of the loops. Linear: Change will be constant through all loops. Lazy: Most of the change will happen towards the end of the loops.",
88
+
89
+ "Style 1": "Style to apply; styles have components for both positive and negative prompts and apply to both",
90
+ "Style 2": "Style to apply; styles have components for both positive and negative prompts and apply to both",
91
+ "Apply style": "Insert selected styles into prompt fields",
92
+ "Create style": "Save current prompts as a style. If you add the token {prompt} to the text, the style uses that as a placeholder for your prompt when you use the style in the future.",
93
+
94
+ "Checkpoint name": "Loads weights from checkpoint before making images. You can either use hash or a part of filename (as seen in settings) for checkpoint name. Recommended to use with Y axis for less switching.",
95
+ "Inpainting conditioning mask strength": "Only applies to inpainting models. Determines how strongly to mask off the original image for inpainting and img2img. 1.0 means fully masked, which is the default behaviour. 0.0 means a fully unmasked conditioning. Lower values will help preserve the overall composition of the image, but will struggle with large changes.",
96
+
97
+ "Eta noise seed delta": "If this values is non-zero, it will be added to seed and used to initialize RNG for noises when using samplers with Eta. You can use this to produce even more variation of images, or you can use this to match images of other software if you know what you are doing.",
98
+
99
+ "Filename word regex": "This regular expression will be used extract words from filename, and they will be joined using the option below into label text used for training. Leave empty to keep filename text as it is.",
100
+ "Filename join string": "This string will be used to join split words into a single line if the option above is enabled.",
101
+
102
+ "Quicksettings list": "List of setting names, separated by commas, for settings that should go to the quick access bar at the top, rather than the usual setting tab. See modules/shared.py for setting names. Requires restarting to apply.",
103
+
104
+ "Weighted sum": "Result = A * (1 - M) + B * M",
105
+ "Add difference": "Result = A + (B - C) * M",
106
+ "No interpolation": "Result = A",
107
+
108
+ "Initialization text": "If the number of tokens is more than the number of vectors, some may be skipped.\nLeave the textbox empty to start with zeroed out vectors",
109
+ "Learning rate": "How fast should training go. Low values will take longer to train, high values may fail to converge (not generate accurate results) and/or may break the embedding (This has happened if you see Loss: nan in the training info textbox. If this happens, you need to manually restore your embedding from an older not-broken backup).\n\nYou can set a single numeric value, or multiple learning rates using the syntax:\n\n rate_1:max_steps_1, rate_2:max_steps_2, ...\n\nEG: 0.005:100, 1e-3:1000, 1e-5\n\nWill train with rate of 0.005 for first 100 steps, then 1e-3 until 1000 steps, then 1e-5 for all remaining steps.",
110
+
111
+ "Clip skip": "Early stopping parameter for CLIP model; 1 is stop at last layer as usual, 2 is stop at penultimate layer, etc.",
112
+
113
+ "Approx NN": "Cheap neural network approximation. Very fast compared to VAE, but produces pictures with 4 times smaller horizontal/vertical resolution and lower quality.",
114
+ "Approx cheap": "Very cheap approximation. Very fast compared to VAE, but produces pictures with 8 times smaller horizontal/vertical resolution and extremely low quality.",
115
+
116
+ "Hires. fix": "Use a two step process to partially create an image at smaller resolution, upscale, and then improve details in it without changing composition",
117
+ "Hires steps": "Number of sampling steps for upscaled picture. If 0, uses same as for original.",
118
+ "Upscale by": "Adjusts the size of the image by multiplying the original width and height by the selected value. Ignored if either Resize width to or Resize height to are non-zero.",
119
+ "Resize width to": "Resizes image to this width. If 0, width is inferred from either of two nearby sliders.",
120
+ "Resize height to": "Resizes image to this height. If 0, height is inferred from either of two nearby sliders.",
121
+ "Discard weights with matching name": "Regular expression; if weights's name matches it, the weights is not written to the resulting checkpoint. Use ^model_ema to discard EMA weights.",
122
+ "Extra networks tab order": "Comma-separated list of tab names; tabs listed here will appear in the extra networks UI first and in order listed.",
123
+ "Negative Guidance minimum sigma": "Skip negative prompt for steps where image is already mostly denoised; the higher this value, the more skips there will be; provides increased performance in exchange for minor quality reduction."
124
+ };
125
+
126
+ function updateTooltip(element) {
127
+ if (element.title) return; // already has a title
128
+
129
+ let text = element.textContent;
130
+ let tooltip = localization[titles[text]] || titles[text];
131
+
132
+ if (!tooltip) {
133
+ let value = element.value;
134
+ if (value) tooltip = localization[titles[value]] || titles[value];
135
+ }
136
+
137
+ if (!tooltip) {
138
+ // Gradio dropdown options have `data-value`.
139
+ let dataValue = element.dataset.value;
140
+ if (dataValue) tooltip = localization[titles[dataValue]] || titles[dataValue];
141
+ }
142
+
143
+ if (!tooltip) {
144
+ for (const c of element.classList) {
145
+ if (c in titles) {
146
+ tooltip = localization[titles[c]] || titles[c];
147
+ break;
148
+ }
149
+ }
150
+ }
151
+
152
+ if (tooltip) {
153
+ element.title = tooltip;
154
+ }
155
+ }
156
+
157
+ // Nodes to check for adding tooltips.
158
+ const tooltipCheckNodes = new Set();
159
+ // Timer for debouncing tooltip check.
160
+ let tooltipCheckTimer = null;
161
+
162
+ function processTooltipCheckNodes() {
163
+ for (const node of tooltipCheckNodes) {
164
+ updateTooltip(node);
165
+ }
166
+ tooltipCheckNodes.clear();
167
+ }
168
+
169
+ onUiUpdate(function(mutationRecords) {
170
+ for (const record of mutationRecords) {
171
+ if (record.type === "childList" && record.target.classList.contains("options")) {
172
+ // This smells like a Gradio dropdown menu having changed,
173
+ // so let's enqueue an update for the input element that shows the current value.
174
+ let wrap = record.target.parentNode;
175
+ let input = wrap?.querySelector("input");
176
+ if (input) {
177
+ input.title = ""; // So we'll even have a chance to update it.
178
+ tooltipCheckNodes.add(input);
179
+ }
180
+ }
181
+ for (const node of record.addedNodes) {
182
+ if (node.nodeType === Node.ELEMENT_NODE && !node.classList.contains("hide")) {
183
+ if (!node.title) {
184
+ if (
185
+ node.tagName === "SPAN" ||
186
+ node.tagName === "BUTTON" ||
187
+ node.tagName === "P" ||
188
+ node.tagName === "INPUT" ||
189
+ (node.tagName === "LI" && node.classList.contains("item")) // Gradio dropdown item
190
+ ) {
191
+ tooltipCheckNodes.add(node);
192
+ }
193
+ }
194
+ node.querySelectorAll('span, button, p').forEach(n => tooltipCheckNodes.add(n));
195
+ }
196
+ }
197
+ }
198
+ if (tooltipCheckNodes.size) {
199
+ clearTimeout(tooltipCheckTimer);
200
+ tooltipCheckTimer = setTimeout(processTooltipCheckNodes, 1000);
201
+ }
202
+ });
javascript/hires_fix.js ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function onCalcResolutionHires(enable, width, height, hr_scale, hr_resize_x, hr_resize_y) {
2
+ function setInactive(elem, inactive) {
3
+ elem.classList.toggle('inactive', !!inactive);
4
+ }
5
+
6
+ var hrUpscaleBy = gradioApp().getElementById('txt2img_hr_scale');
7
+ var hrResizeX = gradioApp().getElementById('txt2img_hr_resize_x');
8
+ var hrResizeY = gradioApp().getElementById('txt2img_hr_resize_y');
9
+
10
+ gradioApp().getElementById('txt2img_hires_fix_row2').style.display = opts.use_old_hires_fix_width_height ? "none" : "block";
11
+
12
+ setInactive(hrUpscaleBy, opts.use_old_hires_fix_width_height || hr_resize_x > 0 || hr_resize_y > 0);
13
+ setInactive(hrResizeX, opts.use_old_hires_fix_width_height || hr_resize_x == 0);
14
+ setInactive(hrResizeY, opts.use_old_hires_fix_width_height || hr_resize_y == 0);
15
+
16
+ setTimeout(function () {
17
+ return [enable, width, height, hr_scale, hr_resize_x, hr_resize_y];
18
+ }, 100);
19
+ }
javascript/imageMaskFix.js ADDED
@@ -0,0 +1,339 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * temporary fix for https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/668
3
+ * @see https://github.com/gradio-app/gradio/issues/1721
4
+ */
5
+
6
+ /*
7
+ window.addEventListener( 'resize', () => imageMaskResize());
8
+
9
+ function imageMaskResize() {
10
+ const canvases = gradioApp().querySelectorAll('#img2maskimg .touch-none canvas');
11
+ if (!canvases.length) {
12
+ window.removeEventListener('resize', imageMaskResize);
13
+ return;
14
+ }
15
+
16
+ const wrapper = canvases[0].closest('.touch-none');
17
+ const previewImage = wrapper.previousElementSibling;
18
+
19
+ if (!previewImage.complete) {
20
+ previewImage.addEventListener('load', imageMaskResize);
21
+ return;
22
+ }
23
+
24
+ const w = previewImage.width;
25
+ const h = previewImage.height;
26
+ const nw = previewImage.naturalWidth;
27
+ const nh = previewImage.naturalHeight;
28
+ const portrait = nh > nw;
29
+
30
+ const wW = Math.min(w, portrait ? h / nh * nw : w / nw * nw);
31
+ const wH = Math.min(h, portrait ? h / nh * nh : w / nw * nh);
32
+
33
+ wrapper.style.width = `${wW}px`;
34
+ wrapper.style.height = `${wH}px`;
35
+ wrapper.style.left = `0px`;
36
+ wrapper.style.top = `0px`;
37
+
38
+ canvases.forEach(c => {
39
+ c.style.width = c.style.height = '';
40
+ c.style.maxWidth = '100%';
41
+ c.style.maxHeight = '100%';
42
+ c.style.objectFit = 'contain';
43
+ });
44
+ }
45
+
46
+ onUiUpdate(() => imageMaskResize());
47
+ */
48
+
49
+ onUiLoaded(function () {
50
+ const color_box = '<input type="color">';
51
+ const brush_size = '<input type="range" min="0.75" max="110.0">';
52
+ let is_drawing = false;
53
+ let img_src = [];
54
+ let spl_instances = [];
55
+ let spl_pan_instances = [];
56
+ let img2img_tab_index = 0;
57
+ let intervalLastUIUpdate;
58
+ const container = gradioApp().querySelector(".gradio-container");
59
+ const observer = new MutationObserver(() =>
60
+ gradioApp()
61
+ .querySelectorAll('div[data-testid="image"]')
62
+ .forEach(function (elem, i) {
63
+ let img_parent = elem.parentElement.querySelector(
64
+ 'div[data-testid="image"] > div'
65
+ );
66
+ let img = img_parent.querySelector("img");
67
+ if (img) {
68
+ if (img_src[i] != img.src) {
69
+ let tool_buttons = img_parent.querySelectorAll("button");
70
+ //console.log(tool_buttons);
71
+ if (tool_buttons.length > 2) {
72
+ img_parent.style.visibility = "hidden";
73
+
74
+ if (intervalLastUIUpdate != null)
75
+ clearInterval(intervalLastUIUpdate);
76
+
77
+ intervalLastUIUpdate = setInterval(function () {
78
+ clearInterval(intervalLastUIUpdate);
79
+ img_parent.addEventListener("mouseup", function (e) {});
80
+
81
+ let spl_parent = elem.parentElement;
82
+ let spl;
83
+ let spl_pan;
84
+ let isPanning;
85
+ let splid;
86
+
87
+ if (spl_parent.className != "spl-pane") {
88
+ spl = new Spotlight();
89
+ spl.init(spl_parent, "-" + spl_parent.id);
90
+
91
+ spl.addControl("undo", spl_undo_handler);
92
+ spl_pan = spl.addControl("pan", spl_pan_handler);
93
+ spl.addControl("brush", spl_brush_handler, brush_size);
94
+ if (tool_buttons.length == 5) {
95
+ spl.addControl("color", spl_color_handler, color_box);
96
+ }
97
+ spl.addControl("clear", spl_clear_handler);
98
+
99
+ spl_instances[i] = spl;
100
+ spl_pan_instances[i] = spl_pan;
101
+ } else {
102
+ spl = spl_instances[i];
103
+ spl_pan = spl_pan_instances[i];
104
+ }
105
+
106
+ img_src[i] = img.src;
107
+ //console.log("NEWIMAGE");
108
+
109
+ function spl_undo_handler(e) {
110
+ tool_buttons[0].click();
111
+ }
112
+
113
+ function spl_clear_handler(e) {
114
+ tool_buttons[2].click();
115
+ spl.panzoom(false);
116
+ img_parent.classList.remove("no-point-events");
117
+ img_parent.parentElement.classList.remove("move");
118
+ document.removeEventListener("wheel", preventDefault, false);
119
+ setTimeout(function () {
120
+ spl.close(false, true);
121
+ img_parent.style.flexGrow = "1";
122
+ img_src[i] = "";
123
+ elem.style.transform = "none";
124
+ }, 500);
125
+ }
126
+
127
+ function spl_color_handler(e) {}
128
+ function spl_brush_handler(e) {}
129
+
130
+ function preventDefault(e) {
131
+ e = e || window.event;
132
+ if (e.preventDefault) {
133
+ e.preventDefault();
134
+ }
135
+ e.returnValue = false;
136
+ }
137
+
138
+ function pan_toggle(val, target) {
139
+ isPanning = val;
140
+ target.classList.toggle("on", isPanning);
141
+ spl.panzoom(val);
142
+
143
+ if (isPanning) {
144
+ img_parent.classList.add("no-point-events");
145
+ img_parent.parentElement.classList.add("move");
146
+ document.addEventListener("wheel", preventDefault, {
147
+ passive: false,
148
+ });
149
+ } else {
150
+ img_parent.classList.remove("no-point-events");
151
+ img_parent.parentElement.classList.remove("move");
152
+ document.removeEventListener(
153
+ "wheel",
154
+ preventDefault,
155
+ false
156
+ );
157
+ }
158
+ }
159
+
160
+ function spl_pan_handler(e) {
161
+ isPanning = !isPanning;
162
+ pan_toggle(isPanning, this);
163
+ }
164
+
165
+ function update_color(listener) {
166
+ let input_color = img_parent.querySelector(
167
+ "input[type='color']"
168
+ );
169
+ let spl =
170
+ img_parent.parentElement.parentElement.parentElement
171
+ .parentElement.parentElement;
172
+ let spl_color = spl.querySelector(
173
+ ".spl-color input[type='color']"
174
+ );
175
+ spl_color.value = input_color.value;
176
+
177
+ if (listener) {
178
+ spl_color.addEventListener("input", function (ev) {
179
+ input_color.value = ev.target.value;
180
+ updateInput(input_color);
181
+ pan_toggle(false, spl_pan);
182
+ });
183
+ }
184
+ }
185
+
186
+ function update_brush(listener) {
187
+ let input_range = img_parent.querySelector(
188
+ "input[type='range']"
189
+ );
190
+ let spl =
191
+ img_parent.parentElement.parentElement.parentElement
192
+ .parentElement.parentElement;
193
+ let spl_brush = spl.querySelector(
194
+ ".spl-brush input[type='range']"
195
+ );
196
+ spl_brush.value = input_range.value;
197
+
198
+ if (listener) {
199
+ spl_brush.addEventListener("input", function (ev) {
200
+ input_range.value = ev.target.value;
201
+ updateInput(input_range);
202
+ });
203
+ }
204
+ }
205
+
206
+ function init_drawing_tools() {
207
+ let input_color = img_parent.querySelector(
208
+ "input[type='color']"
209
+ );
210
+ if (!input_color) {
211
+ let tbcolor = img_parent.querySelector(
212
+ "button[aria-label='Select brush color']"
213
+ );
214
+ if (tbcolor) {
215
+ tbcolor.click();
216
+ setTimeout(function () {
217
+ update_color(true);
218
+ }, 100);
219
+ }
220
+ } else {
221
+ setTimeout(function () {
222
+ update_color(false);
223
+ }, 100);
224
+ }
225
+
226
+ let input_range = img_parent.querySelector(
227
+ "input[type='range']"
228
+ );
229
+ if (!input_range) {
230
+ let tbrange = img_parent.querySelector(
231
+ "button[aria-label='Use brush']"
232
+ );
233
+
234
+ if (tbrange) {
235
+ tbrange.click();
236
+ setTimeout(function () {
237
+ update_brush(true);
238
+ }, 100);
239
+ }
240
+ } else {
241
+ setTimeout(function () {
242
+ update_brush(false);
243
+ }, 100);
244
+ }
245
+ }
246
+
247
+ let w = img.naturalWidth;
248
+ let h = img.naturalHeight;
249
+ img_parent.style.width = `${w}px`;
250
+ img_parent.style.height = `${h}px`;
251
+
252
+ spl.show([
253
+ {
254
+ media: "node",
255
+ src: elem,
256
+ //autohide: true,
257
+ //control: ["pan","clear","undo","fullscreen","autofit","zoom-in","zoom-out","close"],
258
+ class: "relative",
259
+ },
260
+ ]);
261
+
262
+ img_parent.style.flexGrow = "0";
263
+ pan_toggle(false, spl_pan);
264
+ spl.panzoom(false);
265
+ setTimeout(function () {
266
+ init_drawing_tools();
267
+ }, 500);
268
+ img_parent.style.visibility = "visible";
269
+ }, 1000);
270
+ }
271
+ }
272
+ }
273
+ })
274
+ );
275
+ observer.observe(container, { childList: true, subtree: true });
276
+
277
+ /* gradioApp().querySelectorAll('#mode_img2img > .tabitem').forEach(function (tb, ti){
278
+ tb.querySelectorAll('[id^="img2img_copy_to_"] > button').forEach(function (btn, bi){
279
+
280
+ btn.addEventListener("click", function(e) {
281
+ console.log(ti + " > " + bi);
282
+ let src_canvas = tb.querySelector('[key="drawing"]');
283
+ if(src_canvas){
284
+ let dest_canvas = gradioApp().querySelector('#mode_img2img .tabitem:nth-child('+parseInt(bi+1)+') [key="drawing"]');
285
+ //let destCtx = dest_canvas.getContext('2d');
286
+ //destCtx.drawImage(src_canvas, 0, 0);
287
+ console.log(src_canvas);
288
+ console.log(dest_canvas);
289
+ }
290
+ })
291
+ })
292
+ })
293
+
294
+ */
295
+ });
296
+
297
+ /*
298
+ let intervalLastUIUpdate;
299
+ function onLastUIUpdate(){
300
+ clearInterval(intervalLastUIUpdate);
301
+ const img2img_tab = gradioApp().querySelector('#img2img_img2img_tab');
302
+ if(img2img_tab && selectedTabItemId=="tab_img2img"){
303
+ const current_img2img_tab_index = get_img2img_tab_index()[0];
304
+ //if(img2img_tab_index != current_img2img_tab_index){
305
+ console.log(current_img2img_tab_index);
306
+ if(current_img2img_tab_index > 3 || current_img2img_tab_index == 0) return;
307
+ img2img_tab_index = current_img2img_tab_index;
308
+ let tabid;
309
+
310
+ if(img2img_tab_index == 1){
311
+ tabid = "#img2img_img2img_sketch_tab";// #img2img_sketch";
312
+ }else if(img2img_tab_index == 2){
313
+ tabid = "#img2img_inpaint_tab";// #img2maskimg";
314
+ }else if(img2img_tab_index == 3){
315
+ tabid = "#img2img_inpaint_sketch_tab";// #inpaint_sketch";
316
+ }
317
+ //const parent_img2img_tab_img = gradioApp().querySelector('#mode_img2img > div:nth-child('+(img2img_tab_index+2)+') div[data-testid="image"] > div');
318
+ const parent_img2img_tab_img = gradioApp().querySelector('#mode_img2img '+tabid+' div[data-testid="image"] > div');
319
+ const img2img_tab_img = parent_img2img_tab_img.querySelector('img');
320
+ if(img2img_tab_img){
321
+ parent_img2img_tab_img.style.flexGrow = "0";
322
+ img2img_tab_img.onload = function() {
323
+ let w = this.naturalWidth;
324
+ let h = this.naturalHeight;
325
+ parent_img2img_tab_img.style.width = `${w}px`;
326
+ parent_img2img_tab_img.style.height = `${h}px`;
327
+ }
328
+ }else{
329
+ parent_img2img_tab_img.style.flexGrow = "1";
330
+ }
331
+ //}
332
+ }
333
+ }
334
+
335
+ onUiUpdate(function() {
336
+ if(intervalLastUIUpdate != null) clearInterval(intervalLastUIUpdate);
337
+ intervalLastUIUpdate = setInterval(onLastUIUpdate, 1000);
338
+ }) */
339
+
javascript/imageviewer.js ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //called from progressbar
2
+ function showGalleryImage() {
3
+ //need to clean up the old code
4
+ }
5
+
6
+ let like;
7
+ let tile;
8
+
9
+ let slide = 0;
10
+ let gallery = [];
11
+ let fullImg_src;
12
+ //let control = ["pan","undo","like","tile","page","fullscreen","autofit","zoom-in","zoom-out","clear","close","download","prev","next"];
13
+ let control = [
14
+ "like",
15
+ "tile",
16
+ "page",
17
+ "fullscreen",
18
+ "autofit",
19
+ "zoom-in",
20
+ "zoom-out",
21
+ "clear",
22
+ "close",
23
+ "download",
24
+ "prev",
25
+ "next",
26
+ ];
27
+
28
+ let img_browser;
29
+ let img_file_name;
30
+
31
+ let spl_pane;
32
+ let spl_zoom_out;
33
+ let spl_zoom_in;
34
+ let spotlight_gallery;
35
+
36
+ function tile_zoom_update(val) {
37
+ let current_tile_state_size = gallery[slide].tile_size;
38
+ current_tile_state_size += val * 5;
39
+ current_tile_state_size = Math.max(5, Math.min(100, current_tile_state_size));
40
+ spl_pane.style.setProperty("background-size", current_tile_state_size + "%");
41
+ gallery[slide].tile_size = current_tile_state_size;
42
+ }
43
+
44
+ function tile_wheel(event) {
45
+ let delta = event["deltaY"];
46
+ delta = (delta < 0 ? 1 : delta ? -1 : 0) * 0.5;
47
+ tile_zoom_update(delta);
48
+ }
49
+ function tile_zoom_in(event) {
50
+ tile_zoom_update(1);
51
+ }
52
+ function tile_zoom_out(event) {
53
+ tile_zoom_update(-1);
54
+ }
55
+
56
+ function removeTile() {
57
+ spl_pane.removeEventListener("wheel", tile_wheel);
58
+ spl_zoom_out.removeEventListener("click", tile_zoom_out);
59
+ spl_zoom_in.removeEventListener("click", tile_zoom_in);
60
+
61
+ spl_pane.classList.remove("hide");
62
+ spl_pane.style.setProperty("background-image", "none");
63
+ spotlight_gallery.zoom(0.0);
64
+ }
65
+
66
+ function addTile(spl_img) {
67
+ spl_pane.addEventListener("wheel", tile_wheel);
68
+ spl_zoom_out.addEventListener("click", tile_zoom_out);
69
+ spl_zoom_in.addEventListener("click", tile_zoom_in);
70
+
71
+ const current_tile_state_size = gallery[slide].tile_size;
72
+ spl_pane.classList.add("hide");
73
+ spl_pane.style.setProperty("background-position", "center");
74
+ spl_pane.style.setProperty("background-size", current_tile_state_size + "%");
75
+ if (spl_img) {
76
+ spl_pane.style.setProperty("background-image", `url(${spl_img.src})`);
77
+ }
78
+ }
79
+
80
+ function tile_handler(event) {
81
+ const current_tile_state = !gallery[slide].tile;
82
+ gallery[slide].tile = current_tile_state;
83
+
84
+ this.classList.toggle("on");
85
+
86
+ if (current_tile_state) {
87
+ const spl_img = gradioApp().querySelector("#spotlight-gal .spl-pane img");
88
+ addTile(spl_img);
89
+ } else {
90
+ removeTile();
91
+ }
92
+ }
93
+ function like_handler(event) {
94
+ const current_like_state = !gallery[slide].like;
95
+ gallery[slide].like = current_like_state;
96
+ this.classList.toggle("on");
97
+
98
+ if (current_like_state) {
99
+ // add to favorites ...
100
+ //img_file_name.value = gallery[slide].src;
101
+ //console.log(gallery[slide].src);
102
+ } else {
103
+ // remove from favorites ...
104
+ }
105
+ }
106
+
107
+ function createGallerySpotlight() {
108
+ //console.log("clicked");
109
+ slide = 0;
110
+ gallery = [];
111
+
112
+ gradioApp()
113
+ .querySelectorAll("#" + selectedTabItemId + " .thumbnails img")
114
+ .forEach(function (elem, i) {
115
+ elem.setAttribute("gal-id", i);
116
+ //if(fullImg_src == elem.src) slide = parseInt(i+1);
117
+ if (elem.parentElement.className.indexOf("selected") != -1)
118
+ slide = parseInt(i + 1);
119
+ //console.log(slide);
120
+ gallery[i] = {
121
+ src: elem.src,
122
+ title: "Seed:" + elem.src,
123
+ //description: "This is a description.",
124
+ like: false,
125
+ tile: false,
126
+ tile_size: 50,
127
+ };
128
+ });
129
+
130
+ const options = {
131
+ class: "sd-gallery",
132
+ index: slide,
133
+ //control: ["like","page","theme","fullscreen","autofit","zoom-in","zoom-out","close","download","play","prev","next"],
134
+ control: control,
135
+ //animation: animation,
136
+ onshow: function (index) {},
137
+ onchange: function (index, options) {
138
+ slide = index - 1;
139
+ tile.classList.toggle("on", gallery[slide].tile);
140
+ //if(img_browser){
141
+ like.classList.toggle("on", gallery[slide].like);
142
+
143
+ //}
144
+
145
+ spl_pane = gradioApp().querySelector(
146
+ "#spotlight-gal .spl-pane:nth-child(" + index + ")"
147
+ );
148
+ spl_zoom_out = gradioApp().querySelector("#spotlight-gal .spl-zoom-out");
149
+ spl_zoom_in = gradioApp().querySelector("#spotlight-gal .spl-zoom-in");
150
+
151
+ const current_tile_state = gallery[slide].tile;
152
+ if (current_tile_state) {
153
+ addTile();
154
+ } else {
155
+ removeTile();
156
+ }
157
+ },
158
+ onclose: function (index) {
159
+ gradioApp()
160
+ .querySelector(
161
+ "#" +
162
+ selectedTabItemId +
163
+ " .thumbnails .thumbnail-item:nth-child(" +
164
+ (slide + 1) +
165
+ ")"
166
+ )
167
+ .click();
168
+ },
169
+ };
170
+
171
+ //assign(options, modifier);
172
+
173
+ spotlight_gallery.show(gallery, options);
174
+ spotlight_gallery.panzoom(true);
175
+ }
176
+
177
+ function fullImg_click_handler(e) {
178
+ e.stopPropagation();
179
+ e.preventDefault();
180
+ createGallerySpotlight();
181
+ }
182
+
183
+ let intervalUiUpdateIViewer;
184
+ function onUiHeaderTabUpdate() {
185
+ if (intervalUiUpdateIViewer != null) clearInterval(intervalUiUpdateIViewer);
186
+ intervalUiUpdateIViewer = setInterval(onUiUpdateIViewer, 500);
187
+ }
188
+
189
+ let fullImg_preview;
190
+ function onUiUpdateIViewer() {
191
+ clearInterval(intervalUiUpdateIViewer);
192
+ //update_performant_inputs(selectedTabItemId);
193
+
194
+ //fullImg_preview = gradioApp().querySelector('#'+selectedTabItemId+' [id$="2img_results"] .modify-upload + img.w-full.object-contain');
195
+ fullImg_preview = gradioApp().querySelector(
196
+ "#" + selectedTabItemId + " .preview > img"
197
+ );
198
+ if (opts.js_modal_lightbox && fullImg_preview) {
199
+ fullImg_src = fullImg_preview.src;
200
+ fullImg_preview.removeEventListener("click", fullImg_click_handler);
201
+ fullImg_preview.addEventListener("click", fullImg_click_handler, true); //bubbling phase
202
+
203
+ /*
204
+ // this is an idea to integrate image browser extension seamlesly,
205
+ // without the need to change to the image browser tab extension users will be able to review images after generation
206
+ // and add them to favorites or delete the ones that don't like on the spot
207
+ const img_browser = gradioApp().querySelector('[id$="2img_images_history"]');
208
+ const tbname = selectedTabItemId.split("_")[1];
209
+ if(img_browser && tbname ==("txt2img" || "img2img")){
210
+ const images_history = gradioApp().querySelector('[id$="'+tbname+'_images_history"]');
211
+ const history_button_panel = images_history.querySelector('[id$="'+tbname+'_images_history_button_panel"]');
212
+ const labels = images_history.querySelectorAll('label.block span');
213
+ for(let i=0;i<labels.length;i++){
214
+ //console.log(labels[i].innerHTML)
215
+ if(labels[i].innerHTML == 'File Name'){
216
+ img_file_name = labels[i].parentElement.querySelector("textarea");
217
+ console.log(img_file_name.value);
218
+ break;
219
+ }
220
+ }
221
+ }
222
+ */
223
+ }
224
+ }
225
+
226
+ onUiUpdate(function () {
227
+ if (intervalUiUpdateIViewer != null) clearInterval(intervalUiUpdateIViewer);
228
+ intervalUiUpdateIViewer = setInterval(onUiUpdateIViewer, 500);
229
+
230
+ });
231
+
232
+ onUiLoaded(function () {
233
+ spotlight_gallery = new Spotlight();
234
+ spotlight_gallery.init(
235
+ gradioApp().querySelector(".gradio-container"),
236
+ "-gal"
237
+ );
238
+ tile = spotlight_gallery.addControl("tile", tile_handler);
239
+ like = spotlight_gallery.addControl("like", like_handler);
240
+ });
241
+
242
+ document.addEventListener("DOMContentLoaded", function () {});
javascript/imageviewerGamepad.js ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ let gamepads = [];
2
+
3
+ window.addEventListener('gamepadconnected', (e) => {
4
+ const index = e.gamepad.index;
5
+ let isWaiting = false;
6
+ gamepads[index] = setInterval(async() => {
7
+ if (!opts.js_modal_lightbox_gamepad || isWaiting) return;
8
+ const gamepad = navigator.getGamepads()[index];
9
+ const xValue = gamepad.axes[0];
10
+ if (xValue <= -0.3) {
11
+ modalPrevImage(e);
12
+ isWaiting = true;
13
+ } else if (xValue >= 0.3) {
14
+ modalNextImage(e);
15
+ isWaiting = true;
16
+ }
17
+ if (isWaiting) {
18
+ await sleepUntil(() => {
19
+ const xValue = navigator.getGamepads()[index].axes[0];
20
+ if (xValue < 0.3 && xValue > -0.3) {
21
+ return true;
22
+ }
23
+ }, opts.js_modal_lightbox_gamepad_repeat);
24
+ isWaiting = false;
25
+ }
26
+ }, 10);
27
+ });
28
+
29
+ window.addEventListener('gamepaddisconnected', (e) => {
30
+ clearInterval(gamepads[e.gamepad.index]);
31
+ });
32
+
33
+ /*
34
+ Primarily for vr controller type pointer devices.
35
+ I use the wheel event because there's currently no way to do it properly with web xr.
36
+ */
37
+ let isScrolling = false;
38
+ window.addEventListener('wheel', (e) => {
39
+ if (!opts.js_modal_lightbox_gamepad || isScrolling) return;
40
+ isScrolling = true;
41
+
42
+ if (e.deltaX <= -0.6) {
43
+ modalPrevImage(e);
44
+ } else if (e.deltaX >= 0.6) {
45
+ modalNextImage(e);
46
+ }
47
+
48
+ setTimeout(() => {
49
+ isScrolling = false;
50
+ }, opts.js_modal_lightbox_gamepad_repeat);
51
+ });
52
+
53
+ function sleepUntil(f, timeout) {
54
+ return new Promise((resolve) => {
55
+ const timeStart = new Date();
56
+ const wait = setInterval(function() {
57
+ if (f() || new Date() - timeStart > timeout) {
58
+ clearInterval(wait);
59
+ resolve();
60
+ }
61
+ }, 20);
62
+ });
63
+ }
javascript/localization.js ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // localization = {} -- the dict with translations is created by the backend
2
+
3
+ var ignore_ids_for_localization = {
4
+ setting_sd_hypernetwork: 'OPTION',
5
+ setting_sd_model_checkpoint: 'OPTION',
6
+ modelmerger_primary_model_name: 'OPTION',
7
+ modelmerger_secondary_model_name: 'OPTION',
8
+ modelmerger_tertiary_model_name: 'OPTION',
9
+ train_embedding: 'OPTION',
10
+ train_hypernetwork: 'OPTION',
11
+ txt2img_styles: 'OPTION',
12
+ img2img_styles: 'OPTION',
13
+ setting_random_artist_categories: 'SPAN',
14
+ setting_face_restoration_model: 'SPAN',
15
+ setting_realesrgan_enabled_models: 'SPAN',
16
+ extras_upscaler_1: 'SPAN',
17
+ extras_upscaler_2: 'SPAN',
18
+ };
19
+
20
+ var re_num = /^[.\d]+$/;
21
+ var re_emoji = /[\p{Extended_Pictographic}\u{1F3FB}-\u{1F3FF}\u{1F9B0}-\u{1F9B3}]/u;
22
+
23
+ var original_lines = {};
24
+ var translated_lines = {};
25
+
26
+ function hasLocalization() {
27
+ return window.localization && Object.keys(window.localization).length > 0;
28
+ }
29
+
30
+ function textNodesUnder(el) {
31
+ var n, a = [], walk = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null, false);
32
+ while ((n = walk.nextNode())) a.push(n);
33
+ return a;
34
+ }
35
+
36
+ function canBeTranslated(node, text) {
37
+ if (!text) return false;
38
+ if (!node.parentElement) return false;
39
+
40
+ var parentType = node.parentElement.nodeName;
41
+ if (parentType == 'SCRIPT' || parentType == 'STYLE' || parentType == 'TEXTAREA') return false;
42
+
43
+ if (parentType == 'OPTION' || parentType == 'SPAN') {
44
+ var pnode = node;
45
+ for (var level = 0; level < 4; level++) {
46
+ pnode = pnode.parentElement;
47
+ if (!pnode) break;
48
+
49
+ if (ignore_ids_for_localization[pnode.id] == parentType) return false;
50
+ }
51
+ }
52
+
53
+ if (re_num.test(text)) return false;
54
+ if (re_emoji.test(text)) return false;
55
+ return true;
56
+ }
57
+
58
+ function getTranslation(text) {
59
+ if (!text) return undefined;
60
+
61
+ if (translated_lines[text] === undefined) {
62
+ original_lines[text] = 1;
63
+ }
64
+
65
+ var tl = localization[text];
66
+ if (tl !== undefined) {
67
+ translated_lines[tl] = 1;
68
+ }
69
+
70
+ return tl;
71
+ }
72
+
73
+ function processTextNode(node) {
74
+ var text = node.textContent.trim();
75
+
76
+ if (!canBeTranslated(node, text)) return;
77
+
78
+ var tl = getTranslation(text);
79
+ if (tl !== undefined) {
80
+ node.textContent = tl;
81
+ }
82
+ }
83
+
84
+ function processNode(node) {
85
+ if (node.nodeType == 3) {
86
+ processTextNode(node);
87
+ return;
88
+ }
89
+
90
+ if (node.title) {
91
+ let tl = getTranslation(node.title);
92
+ if (tl !== undefined) {
93
+ node.title = tl;
94
+ }
95
+ }
96
+
97
+ if (node.placeholder) {
98
+ let tl = getTranslation(node.placeholder);
99
+ if (tl !== undefined) {
100
+ node.placeholder = tl;
101
+ }
102
+ }
103
+
104
+ textNodesUnder(node).forEach(function(node) {
105
+ processTextNode(node);
106
+ });
107
+ }
108
+
109
+ function dumpTranslations() {
110
+ if (!hasLocalization()) {
111
+ // If we don't have any localization,
112
+ // we will not have traversed the app to find
113
+ // original_lines, so do that now.
114
+ processNode(gradioApp());
115
+ }
116
+ var dumped = {};
117
+ if (localization.rtl) {
118
+ dumped.rtl = true;
119
+ }
120
+
121
+ for (const text in original_lines) {
122
+ if (dumped[text] !== undefined) continue;
123
+ dumped[text] = localization[text] || text;
124
+ }
125
+
126
+ return dumped;
127
+ }
128
+
129
+ function download_localization() {
130
+ var text = JSON.stringify(dumpTranslations(), null, 4);
131
+
132
+ var element = document.createElement('a');
133
+ element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
134
+ element.setAttribute('download', "localization.json");
135
+ element.style.display = 'none';
136
+ document.body.appendChild(element);
137
+
138
+ element.click();
139
+
140
+ document.body.removeChild(element);
141
+ }
142
+
143
+ document.addEventListener("DOMContentLoaded", function() {
144
+ if (!hasLocalization()) {
145
+ return;
146
+ }
147
+
148
+ onUiUpdate(function(m) {
149
+ m.forEach(function(mutation) {
150
+ mutation.addedNodes.forEach(function(node) {
151
+ processNode(node);
152
+ });
153
+ });
154
+ });
155
+
156
+ processNode(gradioApp());
157
+
158
+ if (localization.rtl) { // if the language is from right to left,
159
+ (new MutationObserver((mutations, observer) => { // wait for the style to load
160
+ mutations.forEach(mutation => {
161
+ mutation.addedNodes.forEach(node => {
162
+ if (node.tagName === 'STYLE') {
163
+ observer.disconnect();
164
+
165
+ for (const x of node.sheet.rules) { // find all rtl media rules
166
+ if (Array.from(x.media || []).includes('rtl')) {
167
+ x.media.appendMedium('all'); // enable them
168
+ }
169
+ }
170
+ }
171
+ });
172
+ });
173
+ })).observe(gradioApp(), {childList: true});
174
+ }
175
+ });
javascript/notification.js ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ let lastHeadImg = null;
2
+
3
+ let notificationButton = null;
4
+
5
+ onAfterUiUpdate(function() {
6
+ if (notificationButton == null) {
7
+ notificationButton = gradioApp().getElementById('request_notifications');
8
+
9
+ if (notificationButton != null) {
10
+ notificationButton.addEventListener('click', () => {
11
+ void Notification.requestPermission();
12
+ }, true);
13
+ }
14
+ }
15
+
16
+ const galleryPreviews = gradioApp().querySelectorAll('div[id^="tab_"][style*="display: block"] div[id$="_results"] .thumbnail-item > img');
17
+
18
+ if (galleryPreviews == null) return;
19
+
20
+ const headImg = galleryPreviews[0]?.src;
21
+
22
+ if (headImg == null || headImg == lastHeadImg) return;
23
+
24
+ lastHeadImg = headImg;
25
+
26
+ // play notification sound if available
27
+ gradioApp().querySelector('#audio_notification audio')?.play();
28
+
29
+ if (document.hasFocus()) return;
30
+
31
+ // Multiple copies of the images are in the DOM when one is selected. Dedup with a Set to get the real number generated.
32
+ const imgs = new Set(Array.from(galleryPreviews).map(img => img.src));
33
+
34
+ const notification = new Notification(
35
+ 'Stable Diffusion',
36
+ {
37
+ body: `Generated ${imgs.size > 1 ? imgs.size - opts.return_grid : 1} image${imgs.size > 1 ? 's' : ''}`,
38
+ icon: headImg,
39
+ image: headImg,
40
+ }
41
+ );
42
+
43
+ notification.onclick = function(_) {
44
+ parent.focus();
45
+ this.close();
46
+ };
47
+ });
javascript/profilerVisualization.js ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ function createRow(table, cellName, items) {
3
+ var tr = document.createElement('tr');
4
+ var res = [];
5
+
6
+ items.forEach(function(x, i) {
7
+ if (x === undefined) {
8
+ res.push(null);
9
+ return;
10
+ }
11
+
12
+ var td = document.createElement(cellName);
13
+ td.textContent = x;
14
+ tr.appendChild(td);
15
+ res.push(td);
16
+
17
+ var colspan = 1;
18
+ for (var n = i + 1; n < items.length; n++) {
19
+ if (items[n] !== undefined) {
20
+ break;
21
+ }
22
+
23
+ colspan += 1;
24
+ }
25
+
26
+ if (colspan > 1) {
27
+ td.colSpan = colspan;
28
+ }
29
+ });
30
+
31
+ table.appendChild(tr);
32
+
33
+ return res;
34
+ }
35
+
36
+ function showProfile(path, cutoff = 0.05) {
37
+ requestGet(path, {}, function(data) {
38
+ var table = document.createElement('table');
39
+ table.className = 'popup-table';
40
+
41
+ data.records['total'] = data.total;
42
+ var keys = Object.keys(data.records).sort(function(a, b) {
43
+ return data.records[b] - data.records[a];
44
+ });
45
+ var items = keys.map(function(x) {
46
+ return {key: x, parts: x.split('/'), time: data.records[x]};
47
+ });
48
+ var maxLength = items.reduce(function(a, b) {
49
+ return Math.max(a, b.parts.length);
50
+ }, 0);
51
+
52
+ var cols = createRow(table, 'th', ['record', 'seconds']);
53
+ cols[0].colSpan = maxLength;
54
+
55
+ function arraysEqual(a, b) {
56
+ return !(a < b || b < a);
57
+ }
58
+
59
+ var addLevel = function(level, parent, hide) {
60
+ var matching = items.filter(function(x) {
61
+ return x.parts[level] && !x.parts[level + 1] && arraysEqual(x.parts.slice(0, level), parent);
62
+ });
63
+ var sorted = matching.sort(function(a, b) {
64
+ return b.time - a.time;
65
+ });
66
+ var othersTime = 0;
67
+ var othersList = [];
68
+ var othersRows = [];
69
+ var childrenRows = [];
70
+ sorted.forEach(function(x) {
71
+ var visible = x.time >= cutoff && !hide;
72
+
73
+ var cells = [];
74
+ for (var i = 0; i < maxLength; i++) {
75
+ cells.push(x.parts[i]);
76
+ }
77
+ cells.push(x.time.toFixed(3));
78
+ var cols = createRow(table, 'td', cells);
79
+ for (i = 0; i < level; i++) {
80
+ cols[i].className = 'muted';
81
+ }
82
+
83
+ var tr = cols[0].parentNode;
84
+ if (!visible) {
85
+ tr.classList.add("hidden");
86
+ }
87
+
88
+ if (x.time >= cutoff) {
89
+ childrenRows.push(tr);
90
+ } else {
91
+ othersTime += x.time;
92
+ othersList.push(x.parts[level]);
93
+ othersRows.push(tr);
94
+ }
95
+
96
+ var children = addLevel(level + 1, parent.concat([x.parts[level]]), true);
97
+ if (children.length > 0) {
98
+ var cell = cols[level];
99
+ var onclick = function() {
100
+ cell.classList.remove("link");
101
+ cell.removeEventListener("click", onclick);
102
+ children.forEach(function(x) {
103
+ x.classList.remove("hidden");
104
+ });
105
+ };
106
+ cell.classList.add("link");
107
+ cell.addEventListener("click", onclick);
108
+ }
109
+ });
110
+
111
+ if (othersTime > 0) {
112
+ var cells = [];
113
+ for (var i = 0; i < maxLength; i++) {
114
+ cells.push(parent[i]);
115
+ }
116
+ cells.push(othersTime.toFixed(3));
117
+ cells[level] = 'others';
118
+ var cols = createRow(table, 'td', cells);
119
+ for (i = 0; i < level; i++) {
120
+ cols[i].className = 'muted';
121
+ }
122
+
123
+ var cell = cols[level];
124
+ var tr = cell.parentNode;
125
+ var onclick = function() {
126
+ tr.classList.add("hidden");
127
+ cell.classList.remove("link");
128
+ cell.removeEventListener("click", onclick);
129
+ othersRows.forEach(function(x) {
130
+ x.classList.remove("hidden");
131
+ });
132
+ };
133
+
134
+ cell.title = othersList.join(", ");
135
+ cell.classList.add("link");
136
+ cell.addEventListener("click", onclick);
137
+
138
+ if (hide) {
139
+ tr.classList.add("hidden");
140
+ }
141
+
142
+ childrenRows.push(tr);
143
+ }
144
+
145
+ return childrenRows;
146
+ };
147
+
148
+ addLevel(0, []);
149
+
150
+ popup(table);
151
+ });
152
+ }
153
+
javascript/progressbar.js ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // code related to showing and updating progressbar shown as the image is being made
2
+
3
+ function rememberGallerySelection() {
4
+
5
+ }
6
+
7
+ function getGallerySelectedIndex() {
8
+
9
+ }
10
+
11
+ function request(url, data, handler, errorHandler) {
12
+ var xhr = new XMLHttpRequest();
13
+ xhr.open("POST", url, true);
14
+ xhr.setRequestHeader("Content-Type", "application/json");
15
+ xhr.onreadystatechange = function() {
16
+ if (xhr.readyState === 4) {
17
+ if (xhr.status === 200) {
18
+ try {
19
+ var js = JSON.parse(xhr.responseText);
20
+ handler(js);
21
+ } catch (error) {
22
+ console.error(error);
23
+ errorHandler();
24
+ }
25
+ } else {
26
+ errorHandler();
27
+ }
28
+ }
29
+ };
30
+ var js = JSON.stringify(data);
31
+ xhr.send(js);
32
+ }
33
+
34
+ function pad2(x) {
35
+ return x < 10 ? '0' + x : x;
36
+ }
37
+
38
+ function formatTime(secs) {
39
+ if (secs > 3600) {
40
+ return pad2(Math.floor(secs / 60 / 60)) + ":" + pad2(Math.floor(secs / 60) % 60) + ":" + pad2(Math.floor(secs) % 60);
41
+ } else if (secs > 60) {
42
+ return pad2(Math.floor(secs / 60)) + ":" + pad2(Math.floor(secs) % 60);
43
+ } else {
44
+ return Math.floor(secs) + "s";
45
+ }
46
+ }
47
+
48
+ function setTitle(progress) {
49
+ var title = 'Stable Diffusion';
50
+
51
+ if (opts.show_progress_in_title && progress) {
52
+ title = '[' + progress.trim() + '] ' + title;
53
+ }
54
+
55
+ if (document.title != title) {
56
+ document.title = title;
57
+ }
58
+ }
59
+
60
+ function randomId() {
61
+ return "task(" + Math.random().toString(36).slice(2, 7) + Math.random().toString(36).slice(2, 7) + Math.random().toString(36).slice(2, 7) + ")";
62
+ }
63
+
64
+ // starts sending progress requests to "/internal/progress" uri, creating progressbar above progressbarContainer element and
65
+ // preview inside gallery element. Cleans up all created stuff when the task is over and calls atEnd.
66
+ // calls onProgress every time there is a progress update
67
+ function requestProgress(
68
+ id_task,
69
+ progressbarContainer,
70
+ gallery,
71
+ atEnd,
72
+ onProgress,
73
+ inactivityTimeout = 40
74
+ ) {
75
+ var dateStart = new Date();
76
+ var wasEverActive = false;
77
+ var parentProgressbar = progressbarContainer.parentNode;
78
+ var parentGallery = gallery ? gallery.parentNode : null;
79
+
80
+ var divProgress = document.createElement("div");
81
+ divProgress.className = "progressDiv";
82
+
83
+ divProgress.style.display = opts.show_progressbar ? "block" : "none";
84
+ var divInner = document.createElement("div");
85
+ divInner.className = "progress";
86
+
87
+ divProgress.appendChild(divInner);
88
+ parentProgressbar.insertBefore(divProgress, progressbarContainer);
89
+
90
+ if (parentGallery) {
91
+ var livePreview = gradioApp().querySelector(".livePreview");
92
+ if (!livePreview) {
93
+ livePreview = document.createElement("div");
94
+ livePreview.classList.add("livePreview", "init");
95
+ parentGallery.insertBefore(livePreview, gallery);
96
+ }
97
+ livePreview.classList.remove("dropPreview");
98
+ }
99
+
100
+ var removeProgressBar = function () {
101
+ setTitle("");
102
+ if (divProgress) {
103
+ parentProgressbar.removeChild(divProgress);
104
+ }
105
+
106
+ if (progressbarContainer.id == "txt2img_gallery_container") {
107
+ showSubmitButtons("txt2img", true);
108
+ } else if (progressbarContainer.id == "img2img_gallery_container") {
109
+ showSubmitButtons("img2img", true);
110
+ }
111
+ if (livePreview) {
112
+ if (parentGallery) parentGallery.removeChild(livePreview);
113
+ }
114
+ gradioApp()
115
+ .querySelectorAll("#tabs + div, #tabs + div > *:not(ul)")
116
+ .forEach(function (elem) {
117
+ elem.style.setProperty("display", "block", "important");
118
+ });
119
+ atEnd();
120
+ };
121
+
122
+ var fun = function (id_task, id_live_preview) {
123
+ request(
124
+ "./internal/progress",
125
+ { id_task: id_task, id_live_preview: id_live_preview },
126
+ function (res) {
127
+ if (res.completed) {
128
+ removeProgressBar();
129
+ return;
130
+ }
131
+
132
+ var rect = progressbarContainer.getBoundingClientRect();
133
+
134
+ if (rect.width) {
135
+ divProgress.style.width = rect.width + "px";
136
+ }
137
+
138
+ let progressText = "";
139
+
140
+ divInner.style.width = (res.progress || 0) * 100.0 + "%";
141
+ divInner.style.background = res.progress ? "" : "transparent";
142
+
143
+ if (res.progress > 0) {
144
+ progressText = ((res.progress || 0) * 100.0).toFixed(0) + "%";
145
+ }
146
+
147
+ if (res.eta) {
148
+ progressText += " ETA: " + formatTime(res.eta);
149
+ }
150
+
151
+ setTitle(progressText);
152
+
153
+ if (res.textinfo && res.textinfo.indexOf("\n") == -1) {
154
+ progressText = res.textinfo + " " + progressText;
155
+ }
156
+
157
+ divInner.textContent = progressText;
158
+
159
+ var elapsedFromStart = (new Date() - dateStart) / 1000;
160
+
161
+ if (res.active) wasEverActive = true;
162
+
163
+ if (!res.active && wasEverActive) {
164
+ removeProgressBar();
165
+ return;
166
+ }
167
+
168
+ if (
169
+ elapsedFromStart > inactivityTimeout &&
170
+ !res.queued &&
171
+ !res.active
172
+ ) {
173
+ removeProgressBar();
174
+ return;
175
+ }
176
+
177
+ if (res.live_preview && gallery) {
178
+
179
+ livePreview.classList.remove("init");
180
+
181
+ var img = new Image();
182
+ img.onload = function () {
183
+ img.width = img.naturalWidth;
184
+ img.height = img.naturalHeight;
185
+ livePreview.appendChild(img);
186
+ if (livePreview.childElementCount > 2) {
187
+ livePreview.removeChild(livePreview.firstElementChild);
188
+ }
189
+ };
190
+ img.src = res.live_preview;
191
+ }
192
+
193
+ if (onProgress) {
194
+ onProgress(res);
195
+ }
196
+
197
+ setTimeout(() => {
198
+ fun(id_task, res.id_live_preview);
199
+ }, opts.live_preview_refresh_period || 500);
200
+ },
201
+ function () {
202
+ removeProgressBar();
203
+ }
204
+ );
205
+ };
206
+
207
+ fun(id_task, 0);
208
+ }
javascript/spotlight.js ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Spotlight.js v0.7.8
3
+ * Copyright 2019-2021 Nextapps GmbH
4
+ * Author: Thomas Wilkerling
5
+ * Licence: Apache-2.0
6
+ * https://github.com/nextapps-de/spotlight
7
+ */
8
+ /*
9
+ this library was rewritten by anapnoe to work with https://github.com/anapnoe/stable-diffusion-webui-ux
10
+ it supports multi-instancing, enable-disable panzoom functionallity and input type tools
11
+ */
12
+
13
+ !function(e){"use strict";let t=function(t,i={}){this.controls=["info","theme","download","play","page","close","autofit","zoom-in","zoom-out","prev","next","fullscreen"],this.controls_default={page:1,close:1,autofit:1,"zoom-in":1,"zoom-out":1,prev:1,next:1,fullscreen:1},this.keycodes={BACKSPACE:8,ESCAPE:27,SPACEBAR:32,LEFT:37,RIGHT:39,UP:38,NUMBLOCK_PLUS:107,PLUS:187,DOWN:40,NUMBLOCK_MINUS:109,MINUS:189,INFO:73};let s=this;Object.assign||(Object.assign=function(e,t){let i=Object.keys(t);for(let s=0,o;s<i.length;s++)e[o=i[s]]=t[o];return e}),Element.prototype.closest||(Element.prototype.closest=function(e){e=e.substring(1);let t=this;for(;t&&1===t.nodeType;){if(t.classList.contains(e))return t;t=t.parentElement}return null}),this.addClass=(e,t)=>{s.toggleClass(e,t,!0)},this.removeClass=(e,t)=>{s.toggleClass(e,t)},this.toggleClass=(e,t,i)=>{e.classList[i?"add":"remove"](t)},this.hasClass=(e,t)=>e.classList.contains(t),this.setStyle=(e,t,i)=>{i=""+i,e["_s_"+t]!==i&&(e.style.setProperty(t,i),e["_s_"+t]=i)};let o=0;this.prepareStyle=(e,t)=>{t&&(s.setStyle(e,"transition","none"),t()),o||(o=e.clientTop&&0),t&&s.setStyle(e,"transition","")},this.setText=(e,t)=>{e.firstChild.nodeValue=t},this.getByClass=(e,t)=>(t||document).getElementsByClassName(e),this.getByTag=(e,t)=>(t||document).getElementsByTagName(e),this.addListener=(e,t,i,o)=>{s.toggleListener(!0,e,t,i,o)},this.removeListener=(e,t,i,o)=>{s.toggleListener(!1,e,t,i,o)},this.toggleListener=(e,t,i,s,o)=>{t[(e?"add":"remove")+"EventListener"](i,s,!o&&!1!==o||o)},this.cancelEvent=(e,t)=>{e.stopPropagation(),t&&e.preventDefault()},this.downloadImage=(e,t)=>{let i=s.createElement("a"),o=t.src;i.href=o,i.download=o.substring(o.lastIndexOf("/")+1),s.body.appendChild(i),i.click(),s.body.removeChild(i)},this.createElement=e=>document.createElement(e),this.toggleDisplay=(e,t)=>{s.setStyle(e,"display",t?"":"none")},this.toggleVisibility=(e,t)=>{s.setStyle(e,"visibility",t?"":"hidden")},this.toggleAnimation=(e,t)=>{s.setStyle(e,"transition",t?"":"none")},this.widget=this.createElement("div"),this.widget.innerHTML="<div class=spl-spinner></div><div class=spl-track><div class=spl-scene><div class=spl-pane></div></div></div><div class=spl-header><div class=spl-page> </div></div><div class=spl-progress></div><div class=spl-footer><div class=spl-title> </div><div class=spl-description> </div><div class=spl-button> </div></div><div class=spl-prev></div><div class=spl-next></div>",this.video_support={},this.tpl_video=this.createElement("video"),this.parse_src=(e,t,i,o)=>{let n,l;if("node"!==o){let a=Object.keys(i);for(let r=0,d;r<a.length;r++)if((d=a[r]).length>3&&0===d.indexOf("src")){if("video"===o){let p=s.video_support[d];if(p){if(p>0){n=i[d];break}}else if(s.tpl_video.canPlayType("video/"+d.substring(3).replace("-","").toLowerCase())){s.video_support[d]=1,n=i[d];break}else s.video_support[d]=-1}else{let c=parseInt(d.substring(4),10);if(c){let h=Math.abs(t-c);(!l||h<l)&&(l=h,n=i[d])}}}}return n||i.src||i.href||e.src||e.href},this.controls_dom={};let n=navigator.connection,l=e.devicePixelRatio||1;this.x,this.y,this.startX,this.startY,this.viewport_w,this.viewport_h,this.media_w,this.media_h,this.scale,this.is_down,this.dragged,this.slidable,this.toggle_autofit,this.toggle_theme,this.current_slide,this.slide_count,this.anchors,this.options,this.options_media,this.options_group,this.options_infinite,this.options_progress,this.options_onshow,this.options_onchange,this.options_onclose,this.options_fit,this.options_autohide,this.options_autoslide,this.options_theme,this.options_preload,this.options_href,this.options_click,this.options_class,this.delay,this.animation_scale,this.animation_fade,this.animation_slide,this.animation_custom,this.body,this.doc,this.panel,this.panes,this.media,this.media_next=this.createElement("img"),this.slider,this.header,this.footer,this.footer_visible=0,this.title,this.description,this.button,this.page_prev,this.page_next,this.maximize,this.page,this.player,this.progress,this.spinner,this.gallery,this.gallery_next,this.playing,this.hide,this.hide_cooldown,this.id="spotlight",this.prefix_request,this.prefix_exit,this.track,this.addListener(document,"click",this.dispatch),this.init=(e,t)=>{s.body||(s.id="spotlight"+t,s.widget.id="spotlight"+t,s.doc=document.body,s.body=e,s.slider=s.getOneByClass("scene"),s.header=s.getOneByClass("header"),s.footer=s.getOneByClass("footer"),s.title=s.getOneByClass("title"),s.description=s.getOneByClass("description"),s.button=s.getOneByClass("button"),s.page_prev=s.getOneByClass("prev"),s.page_next=s.getOneByClass("next"),s.page=s.getOneByClass("page"),s.progress=s.getOneByClass("progress"),s.spinner=s.getOneByClass("spinner"),s.panes=[s.getOneByClass("pane")],s.addControl("close",s.close),s.doc[s.prefix_request="requestFullscreen"]||s.doc[s.prefix_request="msRequestFullscreen"]||s.doc[s.prefix_request="webkitRequestFullscreen"]||s.doc[s.prefix_request="mozRequestFullscreen"]||(s.prefix_request=""),s.prefix_request?(s.prefix_exit=s.prefix_request.replace("request","exit").replace("mozRequest","mozCancel").replace("Request","Exit"),s.maximize=s.addControl("fullscreen",s.fullscreen)):s.controls.pop(),s.addControl("info",s.info),s.addControl("autofit",s.autofit),s.addControl("zoom-in",s.zoom_in),s.addControl("zoom-out",s.zoom_out),s.addControl("theme",s.theme),s.player=s.addControl("play",s.play),s.addControl("download",s.download),s.addListener(s.page_prev,"click",s.prev),s.addListener(s.page_next,"click",s.next),s.track=s.getOneByClass("track"),s.addListener(s.track,"mousedown",s.start),s.addListener(s.track,"mousemove",s.move),s.addListener(s.track,"mouseleave",s.end),s.addListener(s.track,"mouseup",s.end),s.addListener(s.track,"touchstart",s.start,{passive:!1}),s.addListener(s.track,"touchmove",s.move,{passive:!0}),s.addListener(s.track,"touchend",s.end),s.addListener(s.button,"click",function(){s.options_click?s.options_click(s.current_slide,s.options):s.options_href&&(location.href=s.options_href)}))},this.getOneByClass=e=>this.controls_dom[e]=this.getByClass("spl-"+e,this.widget)[0],this.addControl=(e,t,i="")=>{let o=s.createElement("div");return o.className="spl-"+e,o.innerHTML=i,s.addListener(o,"click",t),s.header.appendChild(o),s.controls_dom[e]=o},this.removeControl=e=>{let t=s.controls_dom[e];t&&(s.header.removeChild(t),s.controls_dom[e]=null)},this.dispatch=e=>{let t=e.target.closest(".spotlight");if(t){s.cancelEvent(e,!0);let i=t.closest(".spotlight-group");s.anchors=s.getByClass("spotlight",i);for(let o=0;o<s.anchors.length;o++)if(s.anchors[o]===t){s.options_group=i&&i.dataset,s.init_gallery(o+1);break}}},this.show=(e,t,i)=>{s.anchors=e,t&&(s.options_group=t,s.options_onshow=t.onshow,s.options_onchange=t.onchange,s.options_onclose=t.onclose,i=i||t.index),s.init_gallery(i)},this.panzoom=e=>{s.toggleListener(e,s.track,"wheel",s.wheel_listener,{passive:!1}),s.toggleListener(e,s.track,"mousedown",s.start),s.toggleListener(e,s.track,"mousemove",s.move),s.toggleListener(e,s.track,"mouseleave",s.end),s.toggleListener(e,s.track,"mouseup",s.end),s.toggleListener(e,s.track,"touchstart",s.start,{passive:!1}),s.toggleListener(e,s.track,"touchmove",s.move,{passive:!0}),s.toggleListener(e,s.track,"touchend",s.end)},this.init_gallery=e=>{if(s.slide_count=s.anchors.length,s.slide_count){s.body||s.init(),s.options_onshow&&s.options_onshow(e);let t=s.panes[0],i=t.parentElement;for(let o=s.panes.length;o<s.slide_count;o++){let n=t.cloneNode(!1);s.setStyle(n,"left",100*o+"%"),i.appendChild(n),s.panes[o]=n}s.panel||(s.body.appendChild(s.widget),s.update_widget_viewport()),s.current_slide=e||1,s.toggleAnimation(s.slider),s.setup_page(!0),s.prefix_request&&s.detect_fullscreen(),s.show_gallery()}},this.parse_option=(e,t)=>{let s=i[e];return void 0!==s?"false"!=(s=""+s)&&(s||t):t},this.apply_options=e=>{s.options={},s.options_group&&Object.assign(s.options,s.options_group),Object.assign(s.options,e.dataset||e),s.options_media=s.options.media,s.options_click=s.options.onclick,s.options_theme=s.options.theme,s.options_class=s.options.class,s.options_autohide=s.parse_option("autohide",!1),s.options_infinite=s.parse_option("infinite"),s.options_progress=s.parse_option("progress",!0),s.options_autoslide=s.parse_option("autoslide"),s.options_preload=s.parse_option("preload",!0),s.options_href=s.options.buttonHref,s.delay=s.options_autoslide&&parseFloat(s.options_autoslide)||7,s.toggle_theme||s.options_theme&&s.theme(s.options_theme),s.options_class&&s.addClass(s.widget,s.options_class),s.options_class&&s.prepareStyle(s.widget);let t=s.options.control;if(t){let i="string"==typeof t?t.split(","):t;for(let o=0;o<s.controls.length;o++)s.options[s.controls[o]]=!1;for(let n=0;n<i.length;n++){let l=i[n].trim();"zoom"===l?s.options["zoom-in"]=s.options["zoom-out"]=!0:s.options[l]=!0}}let a=s.options.animation;if(s.animation_scale=s.animation_fade=s.animation_slide=!a,s.animation_custom=!1,a){let r="string"==typeof a?a.split(","):a;for(let d=0;d<r.length;d++){let p=r[d].trim();"scale"===p?s.animation_scale=!0:"fade"===p?s.animation_fade=!0:"slide"===p?s.animation_slide=!0:p&&(s.animation_custom=p)}}s.options_fit=s.options.fit},this.prepare_animation=e=>{e?s.prepareStyle(s.media,s.prepare_animation):(s.toggleAnimation(s.slider,s.animation_slide),s.setStyle(s.media,"opacity",s.animation_fade?0:1),s.update_scroll(s.animation_scale&&.8),s.animation_custom&&s.addClass(s.media,s.animation_custom))},this.init_slide=e=>{if(s.panel=s.panes[e-1],s.media=s.panel.firstChild,s.current_slide=e,s.media)s.disable_autoresizer(),s.options_fit&&s.addClass(s.media,s.options_fit),s.prepare_animation(!0),s.animation_custom&&s.removeClass(s.media,s.animation_custom),s.animation_fade&&s.setStyle(s.media,"opacity",1),s.animation_scale&&s.setStyle(s.media,"transform",""),s.setStyle(s.media,"visibility","visible"),s.gallery_next&&(s.media_next.src=s.gallery_next),s.options_autoslide&&s.animate_bar(s.playing);else{let t=s.gallery.media;if(s.parse_option("spinner",!0),"node"===t){s.media=s.gallery.src,"string"==typeof s.media&&(s.media=gradioApp().querySelector(s.media)),s.media&&(s.media._root||(s.media._root=s.media.parentElement),s.update_media_viewport(),s.panel.appendChild(s.media),s.init_slide(e));return}s.toggle_spinner(s.options_spinner,!0),s.media=s.createElement("img"),s.media.onload=function(){s.media===s&&(s.media.onerror=null,s.toggle_spinner(s.options_spinner),s.init_slide(e),s.update_media_viewport())},s.media.src=s.gallery.src,s.panel.appendChild(s.media),s.media&&(s.options_spinner||s.setStyle(s.media,"visibility","visible"),s.media.onerror=function(){s.media===s&&(s.checkout(s.media),s.addClass(s.spinner,"error"),s.toggle_spinner(s.options_spinner))})}},this.toggle_spinner=(e,t)=>{e&&s.toggleClass(s.spinner,"spin",t)},this.has_fullscreen=()=>document.fullscreen||document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement,this.resize_listener=()=>{if(s.update_widget_viewport(),s.media&&s.update_media_viewport(),s.prefix_request){let e=s.has_fullscreen();s.toggleClass(s.maximize,"on",e),e||s.detect_fullscreen()}},this.detect_fullscreen=()=>{s.toggleDisplay(s.maximize,screen.availHeight-e.innerHeight>0)},this.update_widget_viewport=()=>{s.viewport_w=s.widget.clientWidth,s.viewport_h=s.widget.clientHeight},this.update_media_viewport=()=>{s.media_w=s.media.clientWidth,s.media_h=s.media.clientHeight},this.update_scroll=e=>{s.setStyle(s.media,"transform","translate(-50%, -50%) scale("+(e||s.scale)+")")},this.update_panel=(e,t)=>{s.setStyle(s.panel,"transform",e||t?"translate("+e+"px, "+t+"px)":"")},this.update_slider=(e,t,i)=>{t?s.prepareStyle(s.slider,function(){s.update_slider(e,!1,i)}):s.setStyle(s.slider,"transform","translateX("+(-(100*e)+(i||0))+"%)")},this.toggle_listener=t=>{s.toggleListener(t,e,"keydown",s.key_listener),s.toggleListener(t,e,"resize",s.resize_listener)},this.history_listener=e=>{s.panel&&e.state.spl&&s.close(!0)},this.key_listener=e=>{if(s.panel){let t=!1!==s.options["zoom-in"];switch(e.keyCode){case s.keycodes.BACKSPACE:t&&s.autofit();break;case s.keycodes.SPACEBAR:s.options_autoslide&&s.play();break;case s.keycodes.LEFT:s.prev();break;case s.keycodes.RIGHT:s.next();break;case s.keycodes.NUMBLOCK_PLUS:case s.keycodes.PLUS:t&&s.zoom_in();break;case s.keycodes.NUMBLOCK_MINUS:case s.keycodes.MINUS:t&&s.zoom_out();break;case s.keycodes.INFO:s.info()}}},this.wheel_listener=e=>{if(s.panel&&!1!==s.options["zoom-in"]){let t=e.deltaY;(t=(t<0?1:t?-1:0)*.5)<0?s.zoom_out():s.zoom_in()}},this.play=(e,t)=>{let i="boolean"==typeof e?e:!this.playing;!s.playing===i&&(s.playing=s.playing?clearTimeout(s.playing):1,s.toggleClass(s.player,"on",s.playing),t||s.animate_bar(s.playing))},this.animate_bar=e=>{s.options_progress&&(s.prepareStyle(s.progress,function(){s.setStyle(s.progress,"transition-duration",""),s.setStyle(s.progress,"transform","")}),e&&(s.setStyle(s.progress,"transition-duration",s.delay+"s"),s.setStyle(s.progress,"transform","translateX(0)"))),e&&(s.playing=setTimeout(s.next,1e3*s.delay))},this.autohide=()=>{s.options_autohide&&(s.hide_cooldown=Date.now()+2950,s.hide||(s.addClass(s.widget,"menu"),s.schedule(3e3)))},this.schedule=e=>{s.hide=setTimeout(function(){let e=Date.now();e>=s.hide_cooldown?(s.removeClass(s.widget,"menu"),s.hide=0):s.schedule(s.hide_cooldown-e)},e)},this.menu=e=>{"boolean"==typeof e&&(s.hide=e?s.hide:0),s.hide?(s.hide=clearTimeout(s.hide),s.removeClass(s.widget,"menu")):s.autohide()},this.start=e=>{s.cancelEvent(e,!0),s.is_down=!0,s.dragged=!1;let t=e.touches;t&&(t=t[0])&&(e=t),s.slidable=s.media_w*s.scale<=s.viewport_w,s.startX=e.pageX,s.startY=e.pageY,s.toggleAnimation(s.panel)},this.end=e=>{if(s.cancelEvent(e),s.is_down){if(s.dragged){if(s.slidable&&s.dragged){let t=s.x<-(s.viewport_w/7)&&(s.current_slide<s.slide_count||s.options_infinite),i=t||s.x>s.viewport_w/7&&(s.current_slide>1||s.options_infinite);(t||i)&&(s.update_slider(s.current_slide-1,!0,s.x/s.viewport_w*100),t&&s.next()||i&&s.prev()),s.x=0,s.update_panel()}s.toggleAnimation(s.panel,!0)}else s.menu();s.is_down=!1}},this.move=e=>{if(s.cancelEvent(e),s.is_down){let t=e.touches;t&&(t=t[0])&&(e=t);let i=(s.media_w*s.scale-s.viewport_w)/2;s.x-=s.startX-(s.startX=e.pageX),!s.slidable&&(s.x>i?s.x=i:s.x<-i&&(s.x=-i),s.media_h*s.scale>s.viewport_h&&(i=(s.media_h*s.scale-s.viewport_h)/2,s.y-=s.startY-(s.startY=e.pageY),s.y>i?s.y=i:s.y<-i&&(s.y=-i))),s.dragged=!0,s.update_panel(s.x,s.y)}else s.autohide()},this.fullscreen=e=>{let t=s.has_fullscreen();("boolean"!=typeof e||!!t!==e)&&(t?document[s.prefix_exit]():s.widget[s.prefix_request]())},this.theme=e=>{"string"!=typeof e&&(e=s.toggle_theme?"":s.options_theme||"white"),s.toggle_theme!==e&&(s.toggle_theme&&s.removeClass(s.widget,s.toggle_theme),e&&s.addClass(s.widget,e),s.toggle_theme=e)},this.autofit=e=>{"boolean"==typeof e&&(s.toggle_autofit=!e),s.toggle_autofit=1===s.scale&&!s.toggle_autofit,s.toggleClass(s.media,"autofit",s.toggle_autofit),s.setStyle(s.media,"transform",""),s.scale=1,s.x=0,s.y=0,s.update_media_viewport(),s.toggleAnimation(s.panel),s.update_panel()},this.zoom_in=e=>{let t=s.scale/.65;t<=50&&(s.disable_autoresizer(),s.x/=.65,s.y/=.65,s.update_panel(s.x,s.y),s.zoom(t))},this.zoom_out=e=>{let t=.65*s.scale;s.disable_autoresizer(),t>=1&&(1===t?s.x=s.y=0:(s.x*=.65,s.y*=.65),s.update_panel(s.x,s.y),s.zoom(t))},this.zoom=e=>{s.scale=e||1,s.update_scroll()},this.info=()=>{s.footer_visible=!s.footer_visible,s.toggleVisibility(s.footer,s.footer_visible)},this.disable_autoresizer=()=>{s.toggle_autofit&&s.autofit()},this.show_gallery=()=>{s.toggleAnimation(s.widget,!0),s.addClass(s.body,"hide-scrollbars"),s.addClass(s.widget,"show"),s.toggle_listener(!0),s.update_widget_viewport(),s.resize_listener(),s.autohide(),s.options_autoslide&&s.play(!0,!0)},this.download=()=>{s.downloadImage(s.body,s.media)},this.close=(e,t)=>{if(s.hasClass(s.body,"relative")&&!t){s.fullscreen(!1);return}t||setTimeout(function(){s.body.removeChild(s.widget),s.panel=s.media=s.gallery=s.options=s.options_group=s.anchors=s.options_onshow=s.options_onchange=s.options_onclose=s.options_click=null},200),s.removeClass(s.body,"hide-scrollbars"),s.removeClass(s.widget,"show"),s.fullscreen(!1),s.toggle_listener(),s.gallery_next&&(s.media_next.src=""),s.playing&&s.play(),s.media&&s.checkout(s.media),s.hide&&(s.hide=clearTimeout(s.hide)),s.toggle_theme&&s.theme(),s.options_class&&s.removeClass(s.widget,s.options_class),s.options_onclose&&s.options_onclose(),t&&(s.body.removeChild(s.widget),s.panel=s.media=s.gallery=s.options=s.options_group=s.anchors=s.options_onshow=s.options_onchange=s.options_onclose=s.options_click=null)},this.checkout=e=>{if(e._root)e._root.appendChild(e),e._root=null;else{let t=e.parentNode;t&&t.removeChild(e),e=e.src=e.onerror=""}},this.prev=e=>{if(e&&s.autohide(),s.slide_count>1){if(s.current_slide>1)return s.goto(s.current_slide-1);if(s.options_infinite)return s.update_slider(s.slide_count,!0),s.goto(s.slide_count)}},this.next=e=>{if(e&&s.autohide(),s.slide_count>1){if(s.current_slide<s.slide_count)return s.goto(s.current_slide+1);if(s.options_infinite)return s.update_slider(-1,!0),s.goto(1);s.playing&&s.play()}},this.goto=e=>{if(e!==s.current_slide){s.playing?(clearTimeout(s.playing),s.animate_bar()):s.autohide();let t=e>s.current_slide;return s.current_slide=e,s.setup_page(t),!0}},this.prepare=e=>{let t=s.anchors[s.current_slide-1];s.apply_options(t);let i=n&&n.downlink,o=Math.max(s.viewport_h,s.viewport_w)*l;i&&1200*i<o&&(o=1200*i);let a;if(s.gallery={media:s.options_media,src:s.parse_src(t,o,s.options,s.options_media),title:s.parse_option("title",t.alt||t.title||(a=t.firstElementChild)&&(a.alt||a.title))},s.gallery_next&&(s.media_next.src=s.gallery_next=""),s.options_preload&&e&&(t=s.anchors[s.current_slide])){let r=t.dataset||t,d=r.media;d&&"image"!==d||(s.gallery_next=s.parse_src(t,o,r,d))}for(let p=0;p<s.controls.length;p++){let c=s.controls[p];s.toggleDisplay(s.controls_dom[c],s.parse_option(c,s.controls_default[c]))}},this.setup_page=e=>{if(s.x=0,s.y=0,s.scale=1,s.media){if(s.media.onerror)s.checkout(s.media);else{let t=s.media;setTimeout(function(){t&&s.media!==t&&(s.checkout(t),t=null)},650),s.prepare_animation(),s.update_panel()}}s.footer&&s.toggleVisibility(s.footer,0),s.prepare(e),s.update_slider(s.current_slide-1),s.removeClass(s.spinner,"error"),s.init_slide(s.current_slide),s.toggleAnimation(s.panel),s.update_panel();let i=s.gallery.title,o=s.parse_option("description"),n=s.parse_option("button"),l=i||o||n;l&&(i&&s.setText(s.title,i),o&&s.setText(s.description,o),n&&s.setText(s.button,n),s.toggleDisplay(s.title,i),s.toggleDisplay(s.description,o),s.toggleDisplay(s.button,n),s.setStyle(s.footer,"transform","all"===s.options_autohide?"":"none")),s.options_autohide||s.addClass(s.widget,"menu"),s.toggleVisibility(s.footer,s.footer_visible&&l),s.toggleVisibility(s.page_prev,s.options_infinite||s.current_slide>1),s.toggleVisibility(s.page_next,s.options_infinite||s.current_slide<s.slide_count),s.setText(s.page,s.slide_count>1?s.current_slide+" / "+s.slide_count:""),s.options_onchange&&s.options_onchange(s.current_slide,s.options)}};"undefined"!=typeof module&&void 0!==module.exports?module.exports=t:e.Spotlight=t}(window);
javascript/textualInversion.js ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function start_training_textual_inversion() {
2
+ gradioApp().querySelector('#ti_error').innerHTML = '';
3
+
4
+ var id = randomId();
5
+ requestProgress(id, gradioApp().getElementById('ti_output'), gradioApp().getElementById('ti_gallery'), function() {}, function(progress) {
6
+ gradioApp().getElementById('ti_progress').innerHTML = progress.textinfo;
7
+ });
8
+
9
+ var res = Array.from(arguments);
10
+
11
+ res[0] = id;
12
+
13
+ return res;
14
+ }