goroman

Untitled

May 21st, 2024
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 77.63 KB | None | 0 0
  1. // ==UserScript==
  2. // @name Bing AI SLOP
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.6.1
  5. // @description Auto Slop
  6. // @author (You)s
  7. // @match https://www.bing.com/images/create*
  8. // @run-at document-end
  9. // @grant GM_addStyle
  10. // @grant GM_download
  11. // @grant unsafeWindow
  12. // ==/UserScript==
  13.  
  14. // --- Guide ---
  15. // Request = alternative generate button.
  16. //
  17. // U(ltra) = do 3 requests at once
  18. // B(oost) = boost mode
  19. // S(low) = slow mode (saves boosts)
  20. // - Slow mode takes the time needed as you were out of Boosts
  21. // - Note it still counts on your daily request limit
  22. //
  23. // Download All = will download all not earlier downloaded images, except the deleted ones
  24. //
  25. // Auto-Download = automatically triggers 'Download All' after the Request is ready
  26. //
  27. // INF = auto click is enabled and won't stop even after an image is successfully generated.
  28. // ON = auto click if dogged
  29. // OFF = auto click disabled
  30. //
  31. // L(andscape) = automatic request landscape version of the generated image
  32. // OFF = disabled
  33. //
  34. // Slider 10 to 70s = Refresh time in seconds during a request
  35. // - When out of Boosts, set a shorter time to check if a request is ready more frequent
  36. //
  37.  
  38. // --- Settings ---
  39. // File name
  40. var file_name_format = 'timestamp'; // 'timestamp', 'prompt' or 'timestamp+prompt'
  41. var file_name_length = 80; // Max 170
  42. var file_img_type = 'jpg';
  43.  
  44. // Audio (May not work with browsers with anti-autoplay rules)
  45. var audio_enabled = true; // Enable audio notifications (true = enabled, false = disabled)
  46. var audio_done_link = 'https://bigsoundbank.com/UPLOAD/ogg/1111.ogg'; // Url to a sound that plays when the request is sucessfully done and the tab/window is idle. (Only in 'ON' mode)
  47. var audio_error_link = 'https://bigsoundbank.com/UPLOAD/mp3/2061.mp3'; // Url to a sound that plays when error notification occurs. (Only in 'INF' mode)
  48. var audio_debug_link = 'https://bigsoundbank.com/UPLOAD/ogg/0477.ogg'; // Url to a sound that plays when debug notification. (Only in debug mode, can be ignored)
  49. var audio_volume = 0.3; // 0.0 to 1.0
  50.  
  51. // Options
  52. var auto_login = true; // Try re-login when session is lost (true = enabled, false = disabled)
  53. var hide_loader_image = true; // Hide the "loader image" while making a request
  54. var remove_related_content = true; // Remove the related content from the web shown under the detail view of the image (true = enabled, false = disabled)
  55. var auto_delete_sets = 50; // When you reach this number of sets in Recent list, the oldest set will be automatically deleted. (You can still revive it by clicking the show deleted toggle.)
  56. var max_stored_sets = 200; // When you reach this number of temporary locally stored sets, the oldest set will be automatically removed. (You can not revive it)
  57.  
  58. var debug = false; // Debug mode (for developers)
  59.  
  60. // -------------
  61.  
  62. function elementBanner(doc) { return doc.getElementById('giscope'); } // banner with input prompt bar
  63. function elementSearchBox(doc) { return doc.getElementById('sb_form_q'); } // input prompt bar ("search box")
  64. function elementTokenBalance(doc) { return doc.getElementById('token_bal'); } // token balance
  65. function elementCreateButton(doc) { return doc.getElementById('create_btn_c'); } // create button when doing requests
  66. function elementPatiance(doc) { return doc.querySelector('#gilen_c.gi_nb.gi_nb_r.show_n'); }; // patiance pop-up appearing after a wile during request
  67. function elementPreviewContainer(doc) { return doc.getElementById('girrcc'); } // preview images container
  68. function elementPreviewGrids(doc) { return doc.getElementsByClassName('girrgrid'); } // cells containing preview images
  69. function elementPreviewLinks(doc) { return doc.querySelectorAll('a.girr_set'); } // all preview cells containing the request result links
  70. function elementPreviewImage(doc) { return doc.querySelector('#girrcc'); } // first image element
  71. function elementShareButton(doc) { return doc.getElementsByClassName('action share rm nofocus')[0]; }
  72. function elementLoaderImage(doc) { return doc.getElementById('giloadc'); }
  73. function elementDetailsImage(doc) { return doc.getElementById('detailMeta'); }
  74.  
  75. function isWorking(doc) { let btn = elementCreateButton(doc); return btn ? btn.classList.contains('ellipsis') : false; }
  76. function isLoggedOut(doc) { let btn = elementCreateButton(doc); return btn ? btn.classList.contains('land_login_create') : false; }
  77.  
  78. function isDogged(doc) { let div = doc.getElementById('girer'); return div ? div.classList.contains('blocked_bd') : false; } // "Unsafe image content detected"
  79. function isContent(doc) { let div = doc.getElementById('girer'); return div ? div.getElementsByClassName('gi_btn_s').length: false } // "Content warning"
  80.  
  81. function isPanda(doc) { // "We're sorry — we've run into an issue."
  82. let div = doc.getElementById("girer");
  83. if (!div) return false;
  84. let img = div.getElementsByClassName('gil_err_img rms_img');
  85. if (!img.length) return false;
  86. if (!('src' in img[0])) return false;
  87. let splits = img[0].src.split('/');
  88. let fileName = splits[splits.length - 1];
  89. if (fileName == '6su9d9mQOs47jDoNH2YyzqVpyzU.jpg') { return true; }
  90. return false;
  91. }
  92.  
  93. function isRobot(doc) { // "There was a problem creating your images"
  94. let div = doc.getElementById("girer");
  95. if (!div) return false;
  96. let img = div.getElementsByClassName('gil_err_img rms_img');
  97. if (!img.length) return false;
  98. if (!('src' in img[0])) return false;
  99. let splits = img[0].src.split('/');
  100. let fileName = splits[splits.length - 1];
  101. if (fileName == 'kLOji6rqeUcntDWPg9Jj-mZqSq4.jpg') { return true; }
  102. return false;
  103. }
  104.  
  105. function isLimit(doc) { // "You can't submit any more prompts"
  106. let div = doc.getElementById("girer");
  107. if (!div) return false;
  108. let img = div.getElementsByClassName('gil_err_img block_icon rms_img');
  109. if (img.length) { return true; }
  110. return false;
  111. }
  112.  
  113. let playAudio = (function() {
  114. var timeOut = null;
  115. return function(type, time) {
  116. let link = audio_done_link;
  117. if (type == 'error') { link = audio_error_link; }
  118. if (type == 'debug') { link = audio_debug_link; }
  119. if (audio_enabled && link) {
  120. let audio = new Audio(link);
  121. audio.volume = audio_volume;
  122. timeOut = setTimeout(function() { audio.play(); }, time || 0);
  123. if (time) {
  124. let abort = function() {
  125. clearTimeout(timeOut);
  126. document.body.removeEventListener('mousemove', abort);
  127. document.body.removeEventListener('scroll', abort);
  128. document.body.removeEventListener('keydown', abort);
  129. document.body.removeEventListener('click', abort);
  130. document.body.removeEventListener('touchstart', abort);
  131. };
  132. document.body.addEventListener('mousemove', abort);
  133. document.body.addEventListener('scroll', abort);
  134. document.body.addEventListener('keydown', abort);
  135. document.body.addEventListener('click', abort);
  136. document.body.addEventListener('touchstart', abort);
  137. }
  138. }
  139. }
  140. })();
  141.  
  142. function sleep(ms) {
  143. return new Promise(resolve => setTimeout(resolve, ms));
  144. }
  145.  
  146. async function wait(cond, timeOut) {
  147. let time = new Date();
  148. while (!cond()) {
  149. if (timeOut && (new Date() - time) > timeOut) { return false; }
  150. await sleep(50);
  151. }
  152. return true;
  153. }
  154.  
  155. class Storage {
  156. constructor(name, initValue) {
  157. this.name = name + GM_info.script.version.split('.').join('');
  158. if (initValue != undefined && localStorage.getItem(this.name) === null) {
  159. localStorage.setItem(this.name, JSON.stringify(initValue));
  160. return;
  161. }
  162. }
  163. get value() {
  164. return JSON.parse(localStorage.getItem(this.name));
  165. }
  166. set value(value) {
  167. if (value === undefined) { return; }
  168. localStorage.setItem(this.name, JSON.stringify(value));
  169. }
  170. }
  171.  
  172. function createElementFromHTML(htmlString) {
  173. var div = document.createElement('div');
  174. div.innerHTML = htmlString.trim();
  175. return div.firstChild;
  176. }
  177.  
  178. function getTimeStamp(date) {
  179. let year = date.getFullYear();
  180. let month = (date.getMonth() + 1).toString().padStart(2, '0');
  181. let day = date.getDate().toString().padStart(2, '0');
  182. let hours = date.getHours().toString().padStart(2, '0');
  183. let minutes = date.getMinutes().toString().padStart(2, '0');
  184. let seconds = date.getSeconds().toString().padStart(2, '0');
  185. let dateTime = year + '-' + month + '-' + day + ' ' + hours + '_' + minutes + '_' + seconds;
  186. return dateTime;
  187. }
  188.  
  189. function inIframe() {
  190. try { return window.self !== window.top; }
  191. catch (e) { return true; }
  192. }
  193.  
  194. function insertBefore(referenceNode, newNode) {
  195. referenceNode.parentNode.insertBefore(newNode, referenceNode);
  196. }
  197.  
  198. function insertAfter(referenceNode, newNode) {
  199. referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
  200. }
  201.  
  202. function getId(href) {
  203. if (href.includes('create?q')) {
  204. let search = href.split('?')[1];
  205. let params = new URLSearchParams(search);
  206. let id = params.get('id');
  207. return id;
  208. }
  209. let splits = href.split('/');
  210. return splits[splits.length - 1].split('?')[0];
  211. }
  212.  
  213. function getThid(href) {
  214. let search = href.split('?')[1];
  215. let params = new URLSearchParams(search);
  216. let thid = params.get('thId');
  217. return thid;
  218. }
  219.  
  220. function checkForDuplicates(top) {
  221. let images = [];
  222. let sets = document.querySelectorAll('a.girr_set');
  223. for (let set of sets) {
  224. if (!top--) { break };
  225. if (isSetIncomplete(set)) { continue; }
  226. let girrgrid = set.childNodes[0];
  227. for (let img of girrgrid.childNodes) {
  228. if (img.className == "gir_wide") { img = img.childNodes[0]; }
  229. if (!img.hasAttribute('src')) { continue; } // probably gipholder
  230. let splits = img.src.split('/');
  231. let name = splits[splits.length - 1].split('?')[0];
  232. if (images.includes(name)) { return true; }
  233. images.push(name);
  234. }
  235. }
  236. return false;
  237. }
  238.  
  239. function post(url, data, respFunc, respData, errorFunc) {
  240. let a = {};
  241. if (data) { a = {'body': data, 'method': 'POST'}; }
  242. if (data == 'post') { a = {'method': 'POST'}; }
  243. fetch(url, a).then(response => {
  244. if (response.status == 500) {
  245. if (debug) { console.log(response); }
  246. throw new Error('Something went wrong');
  247. }
  248. return response.text();
  249. }).then(data => {
  250. if (respData) { respData(data); }
  251. }).catch((error) => {
  252. if (debug) { console.log(error); }
  253. if (errorFunc) { errorFunc(error); }
  254. });
  255. }
  256.  
  257. function getUrlParam(par) {
  258. let params = new URLSearchParams(document.location.search);
  259. let val = params.get(par.toLowerCase()) || params.get(par.toUpperCase());
  260. return val;
  261. }
  262.  
  263. let setObserver = (function() {
  264. var observers = [];
  265.  
  266. return function(conditionFunc, doFunc, pop, body) {
  267. if (!pop) { pop = true; }
  268. if (!body) { body = document.body; }
  269. if (conditionFunc()) {
  270. doFunc();
  271. if (pop) { return; }
  272. }
  273.  
  274. let observer = {};
  275. observer.index = observers.length;
  276. observer.cond = conditionFunc;
  277. observer.do = doFunc;
  278. observer.pop = pop;
  279. observer.observer = new MutationObserver(function() {
  280. if (observer.cond()) {
  281. observer.do();
  282. if (observer.pop) {
  283. observer.observer.disconnect();
  284. observers.splice(observer.index, 1);
  285. }
  286. }
  287. });
  288. observer.observer.observe(body, { childList: true, subtree: true });
  289. observers.push(observer);
  290. }
  291. })();
  292.  
  293. function downloadImage(url, date, prompt, index, total, edit) {
  294. let name = 'Bing - ';
  295. if (file_name_format == 'prompt') { name += prompt; }
  296. if (file_name_format.slice(0, 9) == 'timestamp') { name += date; }
  297. if (file_name_format == 'timestamp+prompt') { name += " - " + prompt; }
  298. name = name.slice(0, file_name_length);
  299. if (index != undefined) {name += ' (' + index.toString() + '-' + total.toString() + ')'; }
  300. if (edit) { name += '-E'}
  301. if (debug) { console.log('download: ' + name); }
  302. GM_download({url: url, name: name + '.' + file_img_type});
  303. }
  304.  
  305. let doRequest = (function() {
  306. var errorCount = 0;
  307.  
  308. var requestData = function(data) {
  309. let parser = new DOMParser();
  310. let doc = parser.parseFromString(data, 'text/html');
  311. let links = elementPreviewLinks(doc);
  312. if (links.length) {
  313. let extractedHref = links[0].getAttribute('href');
  314. let finalUrl = "https://www.bing.com" + extractedHref;
  315. finalUrl = finalUrl.replace(/&/g, '&');
  316. window.location.href = finalUrl; // visit ongoing request
  317. return;
  318. }
  319.  
  320. // something went wrong with the request
  321. (new Storage('autoRequestCount')).value = 0;
  322. setRequestButton('Error', false);
  323.  
  324. if (isContent(doc)) {
  325. setInfoLabel('Content warning (Prompt filter triggered)');
  326. document.getElementById('auto_option_OFF').click(); // stop auto clicking
  327. setTimeout(function() { setRequestButton(); }, 3000);
  328. return;
  329. }
  330. if (isRobot(doc)) {
  331. if (!elementBanner(doc)) {
  332. setInfoLabel('There was a problem creating your images (You may be logged out)');
  333. setRequestButton('Auto Login', function() { window.location.href = 'https://www.bing.com/images/create?sude=1'; });
  334. return;
  335. }
  336. setInfoLabel('There was a problem creating your images (Robot)');
  337. errorCount++;
  338. setTimeout(function() { setRequestButton(); }, 1000 * errorCount);
  339. if (errorCount > 2 && (new Storage('autoOption')).value == 'INF') {
  340. document.getElementById('auto_option_OFF').click();
  341. playAudio('error');
  342. }
  343. return;
  344. }
  345. if (isPanda(doc)) {
  346. setInfoLabel('We\'re sorry — we\'ve run into an issue. (Panda)');
  347. setRequestButton('Solve Panda', function() {
  348. let newTab = window.open('https://www.bing.com/profile/history?FORM=O2HV46', '_blank');
  349. if (newTab == null || typeof(newTab)=='undefined') {
  350. playAudio('error');
  351. setTimeout(function() { alert('Please disable your pop-up blocker to resolve Panda'); }, 1000);
  352. return;
  353. }
  354. setTimeout(function() { elementCreateButton(document).click(); }, 3000);
  355. });
  356. return;
  357. }
  358. if (isLimit(doc)) {
  359. setInfoLabel('You can\'t submit any more prompts (Daily request limit reached)');
  360. setRequestButton('Daily Limit', false);
  361. if ((new Storage('autoOption')).value != 'OFF') {
  362. document.getElementById('auto_option_OFF').click();
  363. playAudio('error');
  364. }
  365. return;
  366. }
  367.  
  368. setInfoLabel('Response not found or unavailable (Peak hours)');
  369. setTimeout(function() { setRequestButton(); }, 3000);
  370. };
  371.  
  372. var requestError = function(error) {
  373. // unknown error
  374. setRequestButton('Error', false);
  375. if (debug) { playAudio('debug') };
  376. setInfoLabel('Error: ' + error);
  377. setTimeout(function() { setRequestButton(); }, 5000);
  378. };
  379.  
  380. return function() {
  381. // disable boost if tokens is out
  382. let token_bal = elementTokenBalance(document);
  383. let tokens = parseInt(token_bal.innerText);
  384. let boostOption = new Storage('boostOption');
  385. if (tokens == 0 && boostOption.value == 'B') {
  386. let boostOff = document.getElementById('boost_option_S');
  387. boostOff.click(); // disable boosts
  388. }
  389. // store last prompt
  390. let prompt = elementSearchBox(document).value; // todo: add check that prompt is not empty
  391. (new Storage('lastPrompt')).value = prompt;
  392. // create request url
  393. let url = new URL('https://www.bing.com/images/create');
  394. url.searchParams.append('q', prompt);
  395. if (tokens && (boostOption.value == 'B' || boostOption.value == 'U')) {
  396. url.searchParams.append('rt', '4');
  397. } else {
  398. url.searchParams.append('rt', '3');
  399. }
  400. let data = 'q=' + encodeURIComponent(prompt) + '&qs=ds';
  401. (new Storage('requestCount')).value++;
  402. (new Storage('newSetsCount', 0)).value = 0;
  403. // do request
  404. post(url, data, null, requestData, requestError);
  405. };
  406. })();
  407.  
  408. function eventRequest() {
  409. let autoRequestCount = new Storage('autoRequestCount', 0);
  410. if (autoRequestCount.value) { return; }
  411. let boostOption = new Storage('boostOption');
  412. autoRequestCount.value = boostOption.value == 'U' ? 3 : 1;
  413. (new Storage('latestAutoRequestCount', 0)).value = autoRequestCount.value;
  414. setRequestButton('Sending', false, true);
  415. setTimeout(updateRequests, 2000);
  416. }
  417.  
  418. let clickRequestButton = eventRequest;
  419.  
  420. let setRequestButton = (function() {
  421. var animationInterval = null;
  422. return function (text, clickFunc, wait) {
  423. let button = document.getElementById("request_button");
  424. if (!text) { text = 'Request'; }
  425. button.innerText = text;
  426. if (animationInterval) { clearInterval(animationInterval); }
  427. animationInterval = null;
  428. if (clickFunc === false) {
  429. button.disabled = true;
  430. button.style.cursor = 'default';
  431. button.style.backgroundColor = '#787673';
  432. button.style.border = '0';
  433. if (wait) {
  434. let count = 0;
  435. animationInterval = setInterval(function() {
  436. if (count < 3) {
  437. button.innerText += '.';
  438. count++;
  439. } else {
  440. button.innerText = button.innerText.slice(0, -3);
  441. count = 0;
  442. }
  443. }, 500);
  444. }
  445. return;
  446. }
  447. if (clickFunc === undefined) {clickFunc = eventRequest}
  448. clickRequestButton = clickFunc;
  449. button.disabled = false;
  450. button.style.cursor = '';
  451. button.style.backgroundColor = '';
  452. button.style.border = '';
  453. }
  454. })();
  455.  
  456. function createRequestButton() {
  457. let button = document.createElement('button');
  458. button.style.display = 'inline-block';
  459. button.style.marginLeft = '15px';
  460. button.id = 'request_button';
  461. button.className = 'gi_btn_p';
  462. button.innerText = 'Request';
  463. button.addEventListener('click', function() { clickRequestButton(); });
  464. return button
  465. }
  466.  
  467. // todo: update label when requests in auto edit
  468. function createRequestCountLabel() {
  469. let requestCount = new Storage('requestCount', 0);
  470. let label = document.createElement('label');
  471. label.className = 'text';
  472. label.id = 'requestCountLabel'
  473. label.innerText = requestCount.value.toString();
  474. label.style.position = 'relative';
  475. label.display = 'inline-block';
  476. label.style.display = 'inline-flex';
  477. label.style.top = '-10px';
  478. label.style.marginLeft = '15px';
  479. return label;
  480. }
  481.  
  482. function updatePromptLength() {
  483. let label = document.getElementById('promptLengthLabel');
  484. let searchBox = elementSearchBox(document);
  485. let maxLength = searchBox.getAttribute('maxlength');
  486. let currentLength = searchBox.value.length;
  487. label.innerText = '[' + (currentLength) + '/' + (maxLength) + ']';
  488. }
  489.  
  490. function createPromptLengthLabel() {
  491. let label = document.createElement('label');
  492. label.className = 'text';
  493. label.id = 'promptLengthLabel';
  494. label.style.position = 'relative';
  495. label.display = 'inline-block';
  496. label.style.display = 'inline-flex';
  497. label.style.top = '-10px';
  498. label.style.marginLeft = '15px';
  499. label.innerText = '-';
  500. let searchBox = elementSearchBox(document);
  501. searchBox.addEventListener('input', updatePromptLength);
  502. return label;
  503. }
  504.  
  505. function createToolTip() {
  506. let div = document.createElement('div');
  507. div.id = 'tooltip';
  508. div.className = 'tooltip';
  509. div.style.position = 'absolute';
  510. div.style.left = '100px';
  511. div.style.top = '100px';
  512. div.style.width = '450px';
  513. div.style.zIndex = '11';
  514.  
  515. let span = document.createElement('span');
  516. span.className = 'tooltiptext';
  517. span.innerHTML = 'Tooltip text';
  518. span.style.position = 'absolute';
  519. div.appendChild(span);
  520. div.style.display = 'none';
  521.  
  522. return div;
  523. }
  524.  
  525. let showTooltip = (function() {
  526. var toolTipTimeOut = null;
  527.  
  528. var showToolTip = function(element) {
  529. let tooltip = document.getElementById('tooltip');
  530. let span = tooltip.childNodes[0];
  531. tooltip.style.display = "block";
  532. let rectElement = element.getBoundingClientRect();
  533. let rectToggle = element.getBoundingClientRect();
  534. tooltip.style.left = (rectElement.left + (rectElement.right - rectElement.left)/2 - span.offsetWidth/2 + window.scrollX).toString() + 'px';
  535. tooltip.style.top = (rectElement.top - span.offsetHeight - 10 + window.scrollY).toString() + 'px';
  536. }
  537.  
  538. return function (show, tip, element) {
  539. let tooltip = document.getElementById('tooltip');
  540. if (!show) {
  541. tooltip.style.display = 'none';
  542. if (toolTipTimeOut) { clearTimeout(toolTipTimeOut); toolTipTimeOut = null; }
  543. return;
  544. }
  545. let span = tooltip.childNodes[0];
  546. span.innerHTML = tip;
  547.  
  548. if (!toolTipTimeOut) { toolTipTimeOut = setTimeout(function() { showToolTip(element); }, 1000); }
  549. }
  550. })();
  551.  
  552. function createBoostToggle() {
  553. let boostOption = new Storage('boostOption', 'S');
  554.  
  555. let toggle = document.createElement('div');
  556. toggle.className = 'toggle-switch';
  557. toggle.id = 'boost_toggle';
  558. toggle.style.width = '75px';
  559. toggle.style.display = 'inline-flex';
  560. toggle.style.marginLeft = '15px';
  561.  
  562. let tip =
  563. 'U(ltra) = do 3 requests at once<br/>' +
  564. 'B(oost) = boost mode<br/>' +
  565. 'S(low) = slow mode (saves boosts)<br/>' +
  566. '- Slow mode takes the time needed as you were out of Boosts<br/>' +
  567. '- Note it still counts on your daily request limit';
  568.  
  569. toggle.addEventListener("mouseover", function() { showTooltip(true, tip, this); } );
  570. toggle.addEventListener("mouseout", function() { showTooltip(false); } );
  571.  
  572. let options = ['U', 'B', 'S'];
  573. for (let i = 0; i < options.length; i++) {
  574. let input = document.createElement('input');
  575. input.type = 'radio';
  576. input.id = 'boost_option_' + options[i];
  577. input.name = 'boost';
  578. input.setAttribute('option', options[i]);
  579. let label = document.createElement('label');
  580. label.htmlFor = 'boost_option_' + options[i];
  581. label.innerText = options[i];
  582. toggle.appendChild(input);
  583. toggle.appendChild(label);
  584. input.addEventListener('change', function() {
  585. boostOption.value = this.getAttribute('option');
  586. });
  587. if (boostOption.value == options[i]) {
  588. input.checked = true;
  589. }
  590. }
  591. return toggle;
  592. }
  593.  
  594. function updateDownloadAllButton(button) {
  595. if (!button) { button = document.getElementById('download_all_btn'); }
  596. let count = 0;
  597. let localSets = (new Storage('localSets', [])).value;
  598. for (let set of localSets) {
  599. for (let image of set.images) {
  600. if (set.deleted) { continue; }
  601. if (image.downloaded == 'downloaded') { continue; }
  602. count++;
  603. }
  604. }
  605.  
  606. if (count) {
  607. button.innerText = 'Download All (' + count.toString() + ')';
  608. button.disabled = false;
  609. button.style.cursor = '';
  610. button.style.backgroundColor = '';
  611. button.style.border = '';
  612. } else {
  613. button.innerText = 'Download All';
  614. button.disabled = true;
  615. button.style.cursor = 'default';
  616. button.style.backgroundColor = '#787673';
  617. button.style.border = '0';
  618. }
  619. }
  620.  
  621. function createDownloadAllButton() {
  622. let button = document.createElement('button');
  623. button.className = 'gi_btn_p';
  624. button.id = 'download_all_btn';
  625. button.style.display = 'inline-block';
  626. button.style.marginLeft = '15px';
  627. button.addEventListener('click', function() {
  628. updateAutoDownload(true);
  629. });
  630.  
  631. let tip =
  632. 'Will download all not earlier downloaded images,<br/>' +
  633. 'except the deleted ones';
  634.  
  635. button.addEventListener("mouseover", function() { showTooltip(true, tip, this); } );
  636. button.addEventListener("mouseout", function() { showTooltip(false); } );
  637.  
  638. updateDownloadAllButton(button);
  639. return button;
  640. }
  641.  
  642. function createAutoDownloadButton() {
  643. let autoDownload = new Storage('autoDownload', true)
  644. let button = document.createElement('button');
  645. button.className = 'gi_btn_p';
  646. button.id = 'auto_download_btn';
  647. button.innerText = autoDownload.value ? 'Auto-Download: ON' : 'Auto-Download: OFF';
  648. button.style.display = 'inline-block';
  649. button.style.marginLeft = '15px';
  650. button.addEventListener('click', function() {
  651. autoDownload.value = !autoDownload.value;
  652. this.innerText = autoDownload.value ? 'Auto-Download: ON' : 'Auto-Download: OFF';
  653. });
  654. let tip =
  655. 'Auto-Download = automatically triggers \'Download All\' after the Request is ready';
  656.  
  657. button.addEventListener("mouseover", function() { showTooltip(true, tip, this); } );
  658. button.addEventListener("mouseout", function() { showTooltip(false); } );
  659. return button;
  660. }
  661.  
  662. function createAutoToggle() {
  663. let autoOption = new Storage('autoOption', 'OFF');
  664.  
  665. let toggle = document.createElement('div');
  666. toggle.className = 'toggle-switch';
  667. toggle.id = 'auto_toggle';
  668. toggle.style.display = 'inline-flex';
  669. toggle.style.marginLeft = '15px';
  670.  
  671. let tip =
  672. 'INF = auto click enabled and won\'t stop even after an image is generated.<br/>' +
  673. 'ON = auto click if dogged<br/>' +
  674. 'OFF = auto click disabled';
  675.  
  676. toggle.addEventListener("mouseover", function() { showTooltip(true, tip, this); } );
  677. toggle.addEventListener("mouseout", function() { showTooltip(false); } );
  678.  
  679. let options = ['INF', 'ON', 'OFF'];
  680. for (let i = 0; i < options.length; i++) {
  681. let input = document.createElement('input');
  682. input.type = 'radio';
  683. input.id = 'auto_option_' + options[i];
  684. input.name = 'auto';
  685. input.setAttribute('option', options[i]);
  686. let label = document.createElement('label');
  687. label.htmlFor = 'auto_option_' + options[i];
  688. label.innerText = options[i];
  689. toggle.appendChild(input);
  690. toggle.appendChild(label);
  691. input.addEventListener('change', function() {
  692. autoOption.value = this.getAttribute('option');
  693. updateAutoRequest();
  694. });
  695. if (autoOption.value == options[i]) {
  696. input.checked = true;
  697. }
  698. }
  699. return toggle;
  700. }
  701.  
  702. function getEditPendingCount() {
  703. let localSets = (new Storage('localSets', [])).value;
  704. let count = 0;
  705. for (let set of localSets) {
  706. for (let image of set.images) {
  707. if (image.edit == 'pending') { count++; }
  708. }
  709. }
  710. return count;
  711. }
  712.  
  713. function createEditToggle() {
  714. let editOption = new Storage('editOption', 'OFF');
  715.  
  716. let toggle = document.createElement('div');
  717. toggle.className = 'toggle-switch';
  718. toggle.id = 'edit_toggle';
  719. toggle.style.width = '75px';
  720. toggle.style.display = 'inline-flex';
  721. toggle.style.marginLeft = '15px';
  722.  
  723. let tip =
  724. 'L(andscape) = automatic request landscape version of the generated image<br/>' +
  725. 'OFF = disabled';
  726.  
  727. toggle.addEventListener("mouseover", function() { showTooltip(true, tip, this); } );
  728. toggle.addEventListener("mouseout", function() { showTooltip(false); } );
  729.  
  730. let options = ['L', 'OFF'];
  731. for (let i = 0; i < options.length; i++) {
  732. let input = document.createElement('input');
  733. input.type = 'radio';
  734. input.id = 'edit_option_' + options[i];
  735. input.name = 'edit';
  736. input.setAttribute('option', options[i]);
  737. let label = document.createElement('label');
  738. label.htmlFor = 'edit_option_' + options[i];
  739. label.innerText = options[i];
  740. toggle.appendChild(input);
  741. toggle.appendChild(label);
  742. input.addEventListener('change', function() {
  743. editOption.value = this.getAttribute('option');
  744. });
  745. if (editOption.value == options[i]) {
  746. input.checked = true;
  747. }
  748. }
  749. return toggle;
  750. }
  751.  
  752. function createReloadSlider() {
  753. let reloadTime = new Storage('reloadTime', 70);
  754.  
  755. let slider = document.createElement('div');
  756. slider.className = 'value-slider';
  757. slider.id = 'reload_slider';
  758. slider.style.display = 'inline-block';
  759. slider.style.marginLeft = '15px';
  760.  
  761. let tip =
  762. 'Refresh time in seconds during a request<br/><br/>' +
  763. 'When out of Boosts, set a shorter time <br/>' +
  764. 'to check if a request is ready more frequent';
  765.  
  766. slider.addEventListener("mouseover", function() { showTooltip(true, tip, this); } );
  767. slider.addEventListener("mouseout", function() { showTooltip(false); } );
  768.  
  769. let input = document.createElement('input');
  770. input.type = 'range';
  771. input.min = '10';
  772. input.max = '70';
  773. input.value = reloadTime.value.toString();
  774. input.addEventListener('input', function() {
  775. label.innerText = input.value + ' s';
  776. reloadTime.value = parseInt(input.value);
  777. });
  778. slider.appendChild(input);
  779.  
  780. let label = document.createElement('label');
  781. label.innerText = input.value + ' s';
  782. slider.appendChild(label);
  783.  
  784. return slider;
  785. }
  786.  
  787. function setInfoLabel(text) {
  788. let infoLabel = document.getElementById('infoLabel');
  789. if (infoLabel) { infoLabel.innerText = text; }
  790. }
  791.  
  792. function createInfoLabel() {
  793. let label = document.createElement('label');
  794. label.className = 'text';
  795. label.id = 'infoLabel'
  796. label.innerText = '-';
  797. label.display = 'inline-block';
  798. label.style.display = 'inline-flex';
  799. return label;
  800. }
  801.  
  802. function createFrame() {
  803. let iframe = document.createElement('iframe');
  804. iframe.id = 'iframe'
  805. iframe.setAttribute('src', 'https://www.bing.com/profile/history?FORM=O2HV46');
  806. iframe.style.visibility = 'hidden';
  807. iframe.style.position = 'absolute';
  808. iframe.style.top = '100px';
  809. iframe.style.left = '0px';
  810. iframe.style.width = '400px';
  811. iframe.style.height = '300px';
  812. if (debug) {
  813. GM_addStyle(`#iframe { zoom: 0.33;
  814. -moz-transform: scale(0.33);
  815. -moz-transform-origin: 0 0;
  816. -o-transform: scale(0.33);
  817. -o-transform-origin: 0 0;
  818. -webkit-transform: scale(0.33);
  819. -webkit-transform-origin: 0 0; }`);
  820. iframe.style.visibility = 'visible';
  821. if (navigator.userAgent.toLowerCase().includes('firefox')) {
  822. iframe.style.top = '400px';
  823. iframe.style.width = '1200px';
  824. iframe.style.height = '900px';
  825. }
  826. else {
  827. iframe.style.top = '1200px';
  828. iframe.style.width = '4000px';
  829. iframe.style.height = '3000px';
  830. }
  831. }
  832. return iframe;
  833. }
  834.  
  835.  
  836. function downloadSetById(id) {
  837. let localSets = new Storage('localSets').value;
  838. for (let localSet of localSets) {
  839. if (localSet.id != id) { continue; }
  840. for (let image of localSet.images) { image.downloaded = 'pending'; }
  841. break;
  842. }
  843. (new Storage('localSets')).value = localSets;
  844. updateAutoDownload();
  845. }
  846.  
  847. function requestEditsBySetId(id) {
  848. let localSets = (new Storage('localSets', [])).value;
  849. for (let localSet of localSets) {
  850. if (localSet.id != id) { continue; }
  851. for (let image of localSet.images) { image.edit = 'pending'; }
  852. break;
  853. }
  854. (new Storage('localSets')).value = localSets;
  855. updateAutoRequests();
  856. }
  857.  
  858. function deleteSet(id) {
  859. let localSets = (new Storage('localSets', [])).value;
  860. for (let localSet of localSets) {
  861. if (localSet.id != id) { continue; }
  862. localSet.deleted = true;
  863. localSet.downloaded = 'skipped'
  864. break;
  865. }
  866. (new Storage('localSets')).value = localSets;
  867. updateSitePreviewSets();
  868. updateDownloadAllButton();
  869. }
  870.  
  871. function createSetSubMenu()
  872. {
  873. let menu = document.createElement('div');
  874. menu.id = 'set-submenu';
  875. menu.style.position = 'absolute';
  876. menu.style.left = '10px';
  877. menu.style.top = '10px';
  878. menu.style.width = '170px';
  879. menu.style.display = 'none';
  880. menu.style.backgroundColor = getBackgroundColor();
  881.  
  882. let hideSubmenu = function() {
  883. menu = document.getElementById('set-submenu');
  884. if (!menu) { return; }
  885. menu.style.display = 'none';
  886. };
  887. window.addEventListener('click', hideSubmenu);
  888. let girrcc = document.getElementById('girrcc');
  889. if (girrcc) {
  890. girrcc.addEventListener('scroll', hideSubmenu);
  891. }
  892.  
  893. let button = document.createElement('button');
  894. button.className = 'gi_btn_p';
  895. button.id = 'set-submenu-download';
  896. button.innerText = 'Download Set';
  897. button.style.width = '100%';
  898. button.style.height = '34px';
  899. button.style.fontSize ='14px';
  900. button.style.marginBottom ='4px';
  901. button.addEventListener('click', function() {
  902. downloadSetById(this.set_id);
  903. });
  904. menu.appendChild(button);
  905.  
  906. button = document.createElement('button');
  907. button.className = 'gi_btn_p';
  908. button.id = 'set-submenu-request-edit';
  909. button.innerText = 'Request Landscape';
  910. button.style.width = '100%';
  911. button.style.height = '34px';
  912. button.style.fontSize ='14px';
  913. button.style.marginBottom ='4px';
  914. button.addEventListener('click', function() {
  915. requestEditsBySetId(this.set_id);
  916. });
  917. menu.appendChild(button);
  918.  
  919. button = document.createElement('button');
  920. button.className = 'gi_btn_p';
  921. button.id = 'set-submenu-delete';
  922. button.innerText = 'Delete';
  923. button.style.width = '100%';
  924. button.style.height = '34px';
  925. button.style.fontSize ='14px';
  926. button.style.marginBottom ='4px';
  927. button.addEventListener('click', function() {
  928. deleteSet(this.set_id);
  929. });
  930. menu.appendChild(button);
  931.  
  932. return menu;
  933. }
  934.  
  935. function createVersion() {
  936. let div = document.createElement('div');
  937. div.id = 'version';
  938. div.style.marginLeft = '4px';
  939.  
  940. let span = document.createElement('span');
  941. span.className = 'text';
  942. span.innerHTML = 'with Bing AI SLOP (' + GM_info.script.version + ')';
  943. span.style.fontSize ='16px';
  944. div.appendChild(span);
  945. return div;
  946. }
  947.  
  948. function createSlider() {
  949. let div = document.createElement('div');
  950. div.className = 'girrfil';
  951. div.setAttribute('tabindex', '0');
  952. div.setAttribute('data-hidetext', 'Hide deleted');
  953. div.setAttribute('data-showtext', 'Show deleted');
  954. div.setAttribute('data-tooltip', 'Show deleted');
  955. if (mobile) {
  956. div.style.right = '125px'
  957. }
  958.  
  959. let span = document.createElement('span');
  960. span.className = 'girrfil_label';
  961. span.innerHTML = 'Show deleted';
  962. div.appendChild(span);
  963.  
  964. let label = document.createElement('label');
  965. label.id = 'girrfil_tog';
  966. label.className = 'switch'
  967.  
  968. let input = document.createElement('input');
  969. input.id = 'girrfil_tog_input_show_deleted';
  970. input.type = 'checkbox';
  971. input.checked = '';
  972. input.addEventListener('change', function() {
  973. if (this.checked) {
  974. div.setAttribute('data-tooltip', 'Hide deleted');
  975. span.innerHTML = 'Hide deleted';
  976. } else {
  977. div.setAttribute('data-tooltip', 'Show deleted');
  978. span.innerHTML = 'Show deleted';
  979. }
  980. updateSitePreviewSets();
  981. });
  982. label.appendChild(input);
  983.  
  984. let span2 = document.createElement('span');
  985. span2.className = 'slider round';
  986. label.appendChild(span2);
  987.  
  988. div.appendChild(label);
  989.  
  990. return div;
  991. }
  992.  
  993. function createBanner() {
  994. let banner = document.createElement('div');
  995. banner.id = 'newBanner';
  996. banner.className = 'gihead';
  997. banner.role = 'banner';
  998. banner.style.height = '10%'
  999. banner.style.width = '100%'
  1000. banner.style.marginTop = '10px'
  1001. banner.style.backgroundColor = 'rgba(0,0,0,.0)';
  1002.  
  1003. let wrapper = document.createElement('div');
  1004. wrapper.style.textAlign = 'center';
  1005. wrapper.style.width = '100%';
  1006. wrapper.style.justifyContent = 'center';
  1007. wrapper.style.alignItems = 'center';
  1008.  
  1009. wrapper.appendChild(createRequestCountLabel());
  1010. wrapper.appendChild(createRequestButton());
  1011. wrapper.appendChild(createBoostToggle());
  1012. wrapper.appendChild(createDownloadAllButton());
  1013. wrapper.appendChild(createAutoDownloadButton());
  1014. wrapper.appendChild(createAutoToggle());
  1015. wrapper.appendChild(createEditToggle());
  1016. wrapper.appendChild(createReloadSlider());
  1017. wrapper.appendChild(createPromptLengthLabel());
  1018. wrapper.appendChild(document.createElement('br'));
  1019. wrapper.appendChild(createInfoLabel());
  1020. wrapper.appendChild(document.createElement('br'));
  1021. wrapper.appendChild(createFrame());
  1022.  
  1023. banner.appendChild(wrapper);
  1024.  
  1025. return banner;
  1026. }
  1027.  
  1028. function getBackgroundColor() {
  1029. let banner = elementBanner(document);
  1030. let style = window.getComputedStyle(banner);
  1031. return style.getPropertyValue('background-color');
  1032. }
  1033.  
  1034. function setTheme() {
  1035. let switchColor = window.getComputedStyle(document.getElementById('auto_download_btn')).getPropertyValue('background-color');
  1036. let textColor = window.getComputedStyle(elementTokenBalance(document)).getPropertyValue('color');
  1037. GM_addStyle(`
  1038. .toggle-switch {
  1039. border: 2px solid ${switchColor};
  1040. }
  1041.  
  1042. .toggle-switch input:checked + label {
  1043. background-color: ${switchColor};
  1044. }
  1045.  
  1046. .value-slider input::-webkit-slider-thumb {
  1047. background: ${switchColor};
  1048. }
  1049.  
  1050. .value-slider input::-moz-range-thumb {
  1051. background: ${switchColor};
  1052. }
  1053.  
  1054. .text {
  1055. color: ${textColor};
  1056. }
  1057.  
  1058. /*.toggle-switch label {
  1059. background-color: ${textColor};
  1060. }*/
  1061. `);
  1062. }
  1063.  
  1064. GM_addStyle(`
  1065. .toggle-switch {
  1066. position: relative;
  1067. width: 110px;
  1068. border-radius: 15px;
  1069. overflow: hidden;
  1070. }
  1071.  
  1072. .toggle-switch input {
  1073. display: none;
  1074. }
  1075.  
  1076. .toggle-switch label {
  1077. float: left;
  1078. width: 50%;
  1079. margin: 0;
  1080. padding: 5px 0;
  1081. text-align: center;
  1082. background-color: #777;
  1083. color: #fff;
  1084. cursor: pointer;
  1085. transition: background-color 0.3s ease-in-out;
  1086. border-right: 1px solid #fff;
  1087. box-sizing: border-box;
  1088. }
  1089.  
  1090. .toggle-switch label:last-child {
  1091. border-right: none;
  1092. }
  1093.  
  1094. .value-slider {
  1095. position: relative;
  1096. width: 80px;
  1097. }
  1098.  
  1099. .value-slider label {
  1100. position: absolute;
  1101. top: 50%;
  1102. left: 50%;
  1103. transform: translate(-50%, -50%);
  1104. pointer-events: none;
  1105. -moz-user-select: none;
  1106. -khtml-user-select: none;
  1107. -webkit-user-select: none;
  1108. -ms-user-select: none;
  1109. user-select: none;
  1110. color: #fff;
  1111. }
  1112.  
  1113. .value-slider input {
  1114. -webkit-appearance: none;
  1115. appearance: none;
  1116. width: 100%;
  1117. height: 25px;
  1118. border-radius: 15px;
  1119. background: #777;
  1120. outline: none;
  1121. }
  1122.  
  1123. .value-slider input::-webkit-slider-thumb {
  1124. -webkit-appearance: none;
  1125. appearance: none;
  1126. width: 25px;
  1127. height: 25px;
  1128. border-radius: 15px;
  1129. cursor: pointer;
  1130. }
  1131.  
  1132. .value-slider input::-moz-range-thumb {
  1133. width: 25px;
  1134. height: 25px;
  1135. cursor: pointer;
  1136. }
  1137.  
  1138. #request_button {
  1139. height: 48px;
  1140. width: 140px;
  1141. font-size: 14px;
  1142. }
  1143.  
  1144. #download_all_btn, #auto_download_btn {
  1145. height: 34px;
  1146. width: 170px;
  1147. font-size: 14px;
  1148. }
  1149.  
  1150. .tooltiptext {
  1151. font-family: "Roboto",Helvetica,sans-serif;
  1152. background-color: #555;
  1153. color: #fff;
  1154. font-size: 12px;
  1155. text-align: left;
  1156. border-radius: 6px;
  1157. padding: 10px 10px;
  1158. position: absolute;
  1159. }
  1160.  
  1161. .tooltiptext::after {
  1162. content: "";
  1163. position: absolute;
  1164. top: 100%;
  1165. left: 50%;
  1166. margin-left: -5px;
  1167. border-width: 5px;
  1168. border-style: solid;
  1169. border-color: #555 transparent transparent transparent;
  1170. }
  1171.  
  1172. .text {
  1173. font-family: "Roboto",Helvetica,sans-serif;
  1174. font-size: 16px;
  1175. }
  1176.  
  1177. #girrcc::-webkit-scrollbar {
  1178. width: 6px;
  1179. }
  1180. `);
  1181.  
  1182. var requestEditByImageId = (function() {
  1183. var busy = false;
  1184. var skey = null;
  1185. var href = null;
  1186. var intervalPoll = null;
  1187. var doPoll = true;
  1188. var sid = null;
  1189. var iid = null;
  1190.  
  1191. var pollEditStatus = function(skey, id, retrieveImage, errorResp, exception) {
  1192. var getResponce = function(data) {
  1193. let resp = JSON.parse(data);
  1194. if (resp._type == 'RetrieveImagesResponse') {
  1195. if (resp.hasOwnProperty('images')) { retrieveImage(resp.images[0]); }
  1196. return;
  1197. }
  1198. if (resp._type == 'ErrorResponse') {
  1199. if (errorResp) { errorResp(resp.errors[0]); }
  1200. return;
  1201. }
  1202. }
  1203.  
  1204. var getException = function(error) {
  1205. if (exception) { exception(error); }
  1206. }
  1207.  
  1208. let url = '/images/edit/poll?iid=ey%3D%3D&skey=' + skey + '&id=' + id + '&q=a+cute-stone&partner=Sydney';
  1209. post(url, null , null, getResponce, getException);
  1210. }
  1211.  
  1212. var postException = function(error) {
  1213. setInfoLabel('Fail to request landscape (Post edit image request)');
  1214. if (intervalPoll) { clearInterval(intervalPoll); }
  1215. intervalPoll = null;
  1216. let localSets = (new Storage('localSets', [])).value;
  1217. let found = false;
  1218. for (let set of localSets) {
  1219. for (let image of set.images) {
  1220. if (image.id == iid && image.edit == 'pending') {
  1221. image.edit = 'fail';
  1222. found = true;
  1223. break;
  1224. }
  1225. }
  1226. if (found) { break; }
  1227. }
  1228. (new Storage('localSets')).value = localSets;
  1229. busy = false;
  1230. }
  1231.  
  1232. var postResponse = function(data) {
  1233. let resp = JSON.parse(data);
  1234. if (resp.hasOwnProperty('errors')) {
  1235. if (resp.errors[0].message.includes("InvalidOwner")) { setInfoLabel('Fail to request landscape (Invalid Owner)'); }
  1236. if (resp.errors[0].code == 'RateLimitExceeded') { setInfoLabel('Fail to request landscape (Daily Limit)'); }
  1237. if ((new Storage('editOption')).value == 'L') {
  1238. document.getElementById('edit_option_OFF').click();
  1239. }
  1240. return;
  1241. }
  1242.  
  1243. let splits = resp.webSearchUrl.split('/');
  1244. let id = splits[splits.length - 1];
  1245. href = "/images/create/a-cute-stone/" + id + "?_dbe=1&skey=" + skey;
  1246. let iframe = document.getElementById('iframe');
  1247. iframe.src = href;
  1248.  
  1249. var poll = function() {
  1250. if (intervalPoll) { clearInterval(intervalPoll); }
  1251. else { pollEditStatus(skey, id, retrieveImage, errorResponse, exception); }
  1252. intervalPoll = setInterval(function() {
  1253. pollEditStatus(skey, id, retrieveImage, errorResponse, exception)
  1254. }, 5000);
  1255. }
  1256.  
  1257. var exception = function(error) {
  1258. //setInfoLabel('Fail auto edit image (Get edit status)');
  1259. if (intervalPoll) { clearInterval(intervalPoll); }
  1260. intervalPoll = null;
  1261. busy = false;
  1262. }
  1263.  
  1264. var errorResponse = function(error) {
  1265. setInfoLabel('Fail to request landscape (Dogged)');
  1266. if (intervalPoll) { clearInterval(intervalPoll); }
  1267. intervalPoll = null;
  1268.  
  1269. let localSets = (new Storage('localSets', [])).value;
  1270. let found = false;
  1271. for (let set of localSets) {
  1272. for (let image of set.images) {
  1273. if (image.id == iid) { image.edit = 'blocked'; found = true; break; }
  1274. }
  1275. if (found) { break; }
  1276. }
  1277. (new Storage('localSets')).value = localSets;
  1278. busy = false;
  1279. }
  1280.  
  1281. var retrieveImage = function(image) {
  1282. if (intervalPoll) { clearInterval(intervalPoll); }
  1283. intervalPoll = null;
  1284.  
  1285. setInfoLabel('Successfully generated landscape');
  1286.  
  1287. let newSet = {};
  1288. newSet.id = getId(href);
  1289. newSet.prompt = ''; // todo: add prompt?
  1290. newSet.href = href;
  1291. newSet.date = getTimeStamp(new Date());
  1292. newSet.skey = skey;
  1293. newSet.images = []
  1294. //newSet.edit = sid;
  1295. newSet.status = 'done';
  1296.  
  1297. let newImage = {};
  1298. let src = image.thumbnailUrl;
  1299. newImage.src = src + '&w=100';
  1300. newImage.url = src.split('?')[0];
  1301. let splits = src.split('/');
  1302. newImage.thid = splits[splits.length - 1].split('?')[0];
  1303. newImage.id = iid;
  1304. newImage.downloaded = (new Storage('autoDownload')).value ? 'pending' : 'skipped';
  1305. newImage.edit = 'skipped';
  1306. newImage.deleted = false;
  1307. newImage.format = 'landscape';
  1308.  
  1309. newSet.images.push(newImage);
  1310.  
  1311. let localSets = (new Storage('localSets', [])).value;
  1312. let insertIndex = 0;
  1313. let i = 0;
  1314. for (let localSet of localSets) {
  1315. for (let image of localSet.images) {
  1316. if (image.id == iid && image.edit == 'pending') {
  1317. image.edit = 'done';
  1318. newSet.prompt = localSet.prompt;
  1319. insertIndex = i;
  1320. break;
  1321. }
  1322. }
  1323. if (insertIndex) { break; }
  1324. i++;
  1325. }
  1326.  
  1327. localSets.splice(insertIndex, 0, newSet);
  1328. (new Storage('localSets')).value = localSets;
  1329. updateSitePreviewSets();
  1330. updateAutoDownload();
  1331. busy = false;
  1332. }
  1333.  
  1334. poll();
  1335. }
  1336.  
  1337. return function(id) { // image id
  1338. if (busy) { return true; }
  1339. if (!id) { return false; }
  1340. busy = true;
  1341.  
  1342. iid = id;
  1343. let localSets = (new Storage('localSets')).value;
  1344. let setEdit;
  1345. let imageEdit;
  1346. for (let set of localSets) {
  1347. for (let image of set.images) {
  1348. if (image.id == id && image.edit == "pending") {
  1349. setEdit = set;
  1350. imageEdit = image;
  1351. break;
  1352. }
  1353. }
  1354. if (imageEdit) { break; }
  1355. }
  1356.  
  1357. if (!setEdit || !imageEdit) { return; }
  1358.  
  1359. sid = setEdit.id;
  1360. skey = setEdit.skey;
  1361.  
  1362. let q = 'a cute stone';
  1363. let ar = 1; //'Wide'; // landscape,
  1364. let partner = 'Sydney'
  1365. let s = 'original'; // style
  1366. let url = new URL('https://www.bing.com/images/edit/resize?');
  1367. url.searchParams.append('iid', imageEdit.id);
  1368. url.searchParams.append('skey', skey);
  1369. url.searchParams.append('id', setEdit.id);
  1370. url.searchParams.append('q', q);
  1371. url.searchParams.append('partner', partner);
  1372. url.searchParams.append('ar', ar);
  1373. url.searchParams.append('s', s);
  1374. let tokens = parseInt(elementTokenBalance(document).innerText);
  1375. let boostOption = new Storage('boostOption');
  1376. if (tokens && (boostOption.value == 'B' || boostOption.value == 'U')) {
  1377. url.searchParams.append('rt', '4');
  1378. } else {
  1379. url.searchParams.append('rt', '3');
  1380. }
  1381. let requestCount = new Storage('requestCount');
  1382. requestCount.value++;
  1383. setInfoLabel('Request landscape (left: ' + getEditPendingCount() + ')');
  1384. post(url, 'post', null, postResponse, postException);
  1385. return true;
  1386. }
  1387. })();
  1388.  
  1389. function iframeFetchImageSkey() {
  1390. let fetchSet = (new Storage('fetchSet')).value;
  1391. if (!fetchSet) { return; }
  1392.  
  1393. let iframe = document.getElementById('OverlayIFrame');
  1394. let win = unsafeWindow;
  1395. if (iframe) { win = iframe.contentWindow.window; }
  1396. let id = getId(win.location.href);
  1397. if (fetchSet.id != id) { return; }
  1398.  
  1399. let queryStrings = win.ImageDetailReducers.g_PageConfig.persistedQueryStrings;
  1400. let params = new URLSearchParams(queryStrings);
  1401. let skey = params.get('skey');
  1402.  
  1403. let localSets = (new Storage('localSets', [])).value;
  1404. for (let localSet of localSets) {
  1405. if (localSet.id != fetchSet.id) { continue; }
  1406. localSet.skey = skey;
  1407. for (let i = 0; i < localSet.images.length; i++) {
  1408. localSet.images[i].id = fetchSet.images[i].id;
  1409. }
  1410. break;
  1411. }
  1412. (new Storage('localSets')).value = localSets;
  1413. (new Storage('fetchSet')).value = null;
  1414. }
  1415.  
  1416. function fetchImageIds(set) {
  1417. let id = getId(window.location.href);
  1418. if (set.id != id) { return null; }
  1419. let href = null;
  1420. let images = document.getElementsByClassName('iusc');
  1421. if (images.length) {
  1422. href = images[0].getAttribute('href');
  1423. for (let image of images) {
  1424. let m = image.getAttribute('m');
  1425. let info = JSON.parse(m);
  1426. let url = info.ClickThroughUrl;
  1427. let search = url.split('?')[1];
  1428. let params = new URLSearchParams(search);
  1429. let thid = params.get('thId');
  1430. let iid = params.get('id');
  1431. for (let newImage of set.images) {
  1432. if (newImage.thid == thid) { newImage.id = iid; break; }
  1433. }
  1434. }
  1435. }
  1436.  
  1437. let image = document.getElementsByClassName('single-img-link')[0];
  1438. if (image) {
  1439. href = image.getAttribute('href');
  1440. let url = href;
  1441. let search = url.split('?')[1];
  1442. let params = new URLSearchParams(search);
  1443. let thid = params.get('thId');
  1444. let iid = params.get('id');
  1445. if (set.images[0].thid == thid) { set.images[0].id = iid; }
  1446. }
  1447.  
  1448. return set;
  1449. }
  1450.  
  1451. function iframeFetchImageIds() {
  1452. let fetchSet = (new Storage('fetchSet')).value;
  1453. if (!fetchSet) { return; }
  1454.  
  1455. fetchSet = fetchImageIds(fetchSet)
  1456. if (!fetchSet) { return; }
  1457. (new Storage('fetchSet')).value = fetchSet;
  1458.  
  1459. let href = null;
  1460. let images = document.getElementsByClassName('iusc');
  1461. if (images.length) { href = images[0].getAttribute('href'); }
  1462. let image = document.getElementsByClassName('single-img-link')[0];
  1463. if (image) { href = image.getAttribute('href'); }
  1464.  
  1465. window.location.href = href;
  1466. }
  1467.  
  1468. function autoClick() {
  1469. let autoOption = new Storage('autoOption');
  1470. if (autoOption.value == 'OFF') { return; }
  1471. let button = document.getElementById("request_button");
  1472. button.click();
  1473. }
  1474.  
  1475. function updateAutoRequest() {
  1476. let autoOption = new Storage('autoOption');
  1477. if (autoOption.value == 'INF' || (autoOption.value == 'ON' && isDogged(document))) {
  1478. setTimeout(autoClick, 3000);
  1479. setInterval(autoClick, 10000);
  1480. }
  1481. }
  1482.  
  1483.  
  1484. let updateLocalSets = (function() {
  1485. var mobile = false;
  1486. var tries = 3;
  1487.  
  1488. var fetchSiteSets = function() { // fetch image sets from site and ad it to local stored sets
  1489. if (checkForDuplicates(3)) {
  1490. if (tries--) { setTimeout(fetchSiteSets, 1000); }
  1491. if (debug) {
  1492. let duplicates = (new Storage('duplicates', [])).value;
  1493. duplicates.push(tries);
  1494. (new Storage('duplicates', [])).value = duplicates;
  1495. playAudio('debug');
  1496. }
  1497. return;
  1498. }
  1499.  
  1500. let siteSets = document.querySelectorAll('a.girr_set');
  1501. let localSets = (new Storage('localSets', [])).value;
  1502.  
  1503. for (let i = siteSets.length - 1; i >= 0; i--) {
  1504. let siteSet = siteSets[i];
  1505. let id = getId(siteSet.href);
  1506. let exist = false;
  1507. for (let localSet of localSets) {
  1508. if (localSet.id != id) { continue; }
  1509. exist = true;
  1510. if (localSet.href.includes('?q=')) { localSet.href = siteSet.href; } // update href (pending request is done)
  1511. if (localSet.status != 'pending') { continue; }
  1512. let girrgrid = siteSet.childNodes[0];
  1513. if (girrgrid.className.includes('inc')) { continue; } // set is not done
  1514. if (parseInt(girrgrid.getAttribute('data-imgcount')) == 0) { localSet.status = 'blocked'; continue; }
  1515. localSet.status = 'done';
  1516. localSet.href = siteSet.href;
  1517.  
  1518. for (let img of girrgrid.childNodes) {
  1519. if (img.className == "gir_wide") { img = img.childNodes[0]; }
  1520. if (!img.hasAttribute('src')) { continue; } // probably gipholder
  1521.  
  1522. let image = {}
  1523. image.src = img.src; // preview
  1524. image.url = img.src.split('?')[0];
  1525. let splits = img.src.split('/');
  1526. image.thid = splits[splits.length - 1].split('?')[0]; // todo: use help function
  1527. image.id = null;
  1528. image.downloaded = (new Storage('autoDownload')).value ? 'pending' : 'skipped';
  1529. image.edit = (new Storage('editOption')).value == 'L' ? 'pending' : 'skipped';
  1530. //if (getLocalImage(image.thid) ) { continue; } // image exist already (probably due to load bug on recent set list)
  1531. localSet.images.push(image);
  1532. }
  1533. (new Storage('newSetsCount')).value++;
  1534. }
  1535.  
  1536. if (exist) { continue; }
  1537.  
  1538. let newSet = {};
  1539. newSet.id = id;
  1540. newSet.prompt = siteSet.title;
  1541. newSet.date = getTimeStamp(new Date());
  1542. newSet.href = siteSet.href;
  1543. newSet.skey = null;
  1544. newSet.images = [];
  1545. newSet.status = 'pending';
  1546. localSets.unshift(newSet);
  1547. }
  1548. (new Storage('localSets')).value = localSets;
  1549. }
  1550.  
  1551. var deleteOldSets = function() {
  1552. let localSets = (new Storage('localSets')).value;
  1553. localSets = localSets.slice(0, max_stored_sets);
  1554. let count = 0;
  1555. for (let set of localSets) {
  1556. if (set.deleted) { continue; }
  1557. if (!set.images.length) { continue; }
  1558. count++;
  1559. if (count > auto_delete_sets) {
  1560. set.deleted = true;
  1561. }
  1562. }
  1563. (new Storage('localSets')).value = localSets;
  1564. }
  1565.  
  1566. return function()
  1567. {
  1568. fetchSiteSets();
  1569. deleteOldSets();
  1570. }
  1571. })();
  1572.  
  1573. function updatePreviewImages() {
  1574. let id = getId(window.location.href);
  1575. let localSets = (new Storage('localSets')).value;
  1576. for (let localSet of localSets) {
  1577. if (localSet.id == id) {
  1578. if (localSet.images.length && !localSet.images[0].id) {
  1579. fetchImageIds(localSet);
  1580. (new Storage('localSets')).value = localSets;
  1581. }
  1582. break;
  1583. }
  1584. }
  1585.  
  1586. let previewImages = document.getElementsByClassName('mimg');
  1587. if (!previewImages.length) { previewImages = document.getElementsByClassName('gir_mmimg'); }
  1588. for (let previewImage of previewImages) {
  1589. previewImage.addEventListener('click', function() {
  1590. initDetailsPage();
  1591. });
  1592. }
  1593. }
  1594.  
  1595. function isSetIncomplete(set) {
  1596. let girrgrid = set.childNodes[0];
  1597. return girrgrid.className.includes('inc');
  1598. }
  1599.  
  1600. // add local stored sets to the "recent sets list"
  1601. let updateSitePreviewSets = (function() {
  1602. var selected = null;
  1603.  
  1604. var addLocalPreviews = function() {
  1605. let localSets = (new Storage('localSets')).value;
  1606. if (!localSets) { return true; } // No local sets to add
  1607.  
  1608. // fetch sets from site (recent list)
  1609. let gircc = document.getElementById('girrcc');
  1610. if (!gircc) { return true; } // no preview grid
  1611.  
  1612. // clear recent list
  1613. let siteSets = gircc.childNodes;
  1614. let i = 0;
  1615. while (i < siteSets.length) {
  1616. let set = siteSets[i];
  1617. if (isSetIncomplete(set)) { i++; continue; }
  1618. set.remove();
  1619. }
  1620.  
  1621. let createElementSet = function(set, select) {
  1622. let a = document.createElement('a');
  1623. a.className = select ? 'girr_set seled' : 'girr_set ';
  1624. a.title = set.prompt;
  1625. a.setAttribute('data-imgcount', set.images.length.toString());
  1626. a.role = 'button';
  1627. a.typeof = 'button';
  1628. a.href = set.href;
  1629. if (mobile) {
  1630. a.className = select ? 'girr_set girrcswp seled' : 'girr_set girrcswp';
  1631. }
  1632.  
  1633. let div = document.createElement('div');
  1634. div.className = 'girrgrid ';
  1635. div.setAttribute('data-imgcount', set.images.length.toString());
  1636. a.appendChild(div);
  1637.  
  1638. for (let image of set.images) {
  1639. let img = document.createElement('img');
  1640. img.src = image.src;
  1641. if (image.hasOwnProperty('format') && image.format == 'landscape') {
  1642. img.style.height = '57px';
  1643. if (select) { a.setAttribute('data-imgcount', '2'); } //Hack a wide selection
  1644. }
  1645. img.alt = set.prompt;
  1646. div.appendChild(img);
  1647. }
  1648. return a;
  1649. };
  1650.  
  1651. let createBlockedSet = function(set) {
  1652. let a = document.createElement('a');
  1653. a.className = (new Storage('hideFailed')).value ? 'girr_blocked hide' : 'girr_blocked';
  1654. a.title = set.prompt;
  1655. a.setAttribute('tabindex', '0');
  1656. if (mobile) {
  1657. //a.className = select ? 'girr_set girrcswp seled' : 'girr_set girrcswp';
  1658. }
  1659. a.appendChild(createElementFromHTML('<div class="girrgrid"><div class="gipholder"></div><div class="gipholder"></div></div>'));
  1660. a.appendChild(createElementFromHTML('<div class="girr_blorur_info">' +
  1661. '<div class="girr_blorur_icon"><span class="girr_blorur_blocked" role="presentation"></span></div>' +
  1662. '<div class="girr_blorur_text"><span>Prompt blocked</span></div></div>'));
  1663. return a;
  1664. };
  1665.  
  1666. // add local sets to the recent list
  1667. let input = document.getElementById('girrfil_tog_input_show_deleted')
  1668. let showDeleted = input.checked;
  1669.  
  1670. let insert = null; //document.getElementById('girrcc').childNodes[0];
  1671. for (let localSet of localSets) {
  1672. if (localSet.deleted && !showDeleted) { continue; }
  1673.  
  1674. let a = null;
  1675. if (localSet.status == 'done') {
  1676. let select = (localSet.id == getId(window.location.href));
  1677. a = createElementSet(localSet, select);
  1678. if (select) { selected = a; }
  1679. }
  1680. else if (localSet.status == 'blocked') {
  1681. a = createBlockedSet(localSet);
  1682. }
  1683.  
  1684. if (!a) { continue; }
  1685.  
  1686. if (!insert) {
  1687. document.getElementById('girrcc').appendChild(a);
  1688. insert = a;
  1689. continue;
  1690. }
  1691. insertAfter(insert, a);
  1692. insert = a;
  1693. }
  1694. };
  1695.  
  1696. var addMenuButtons = function() {
  1697. let gircc = document.getElementById('girrcc');
  1698. if (!gircc) { return; } // no recent grid
  1699.  
  1700. let createSetMenu = function(set_id) {
  1701. let button = document.createElement('button');
  1702. button.className = 'gi_btn_p menu';
  1703. button.id = 'set_button';
  1704. button.innerText = 'Menu';
  1705. button.set_id = set_id;
  1706. button.style.position = 'relative';
  1707. button.style.width = '50px';
  1708. button.style.height = '22px';
  1709. button.style.marginLeft = '10px';
  1710. button.style.marginTop = '-18px';
  1711. if (mobile) {
  1712. button.style.fontSize = '11pt'
  1713. button.style.width = '';
  1714. button.style.height = '50px';
  1715. button.style.writingMode = 'vertical-rl';
  1716. button.style.marginLeft = '-18px';
  1717. button.style.marginTop = '';
  1718. }
  1719.  
  1720. button.addEventListener("mouseenter", function( event ) { event.target.style.backgroundColor = '#555'; }, false);
  1721. button.addEventListener("mouseleave", function( event ) { event.target.style.backgroundColor = ''; }, false);
  1722. button.addEventListener('click', function(event) {
  1723. event.stopPropagation();
  1724. let menu = document.getElementById('set-submenu');
  1725. let download = document.getElementById('set-submenu-download');
  1726. download.set_id = set_id;
  1727. let requestEdit = document.getElementById('set-submenu-request-edit');
  1728. requestEdit.set_id = set_id;
  1729. let del = document.getElementById('set-submenu-delete');
  1730. del.set_id = set_id;
  1731.  
  1732. var rect = this.getBoundingClientRect();
  1733. menu.style.display = 'block';
  1734. menu.style.left = (rect.left - menu.offsetWidth - 10 + window.scrollX).toString() + 'px';
  1735. menu.style.top = (rect.bottom - menu.offsetHeight - 10 + window.scrollY).toString() + 'px';
  1736. if (mobile) {
  1737. menu.style.left = (rect.left).toString() + 'px';
  1738. menu.style.top = (rect.top - menu.offsetHeight - 10 + window.scrollY).toString() + 'px';
  1739. }
  1740. });
  1741.  
  1742. let menu = document.createElement('div');
  1743. menu.id = 'set-menu-' + set_id;
  1744. menu.appendChild(button);
  1745.  
  1746. return menu;
  1747. }
  1748.  
  1749. for (let set of gircc.childNodes) {
  1750. let className = set.getAttribute('class');
  1751. if (!className) { continue; }
  1752. className = className.split(' ')[0];
  1753. if (className != 'girr_set') { continue; }
  1754. if (set.hasAttribute('menu')) { continue; }
  1755. set.setAttribute('menu', '1');
  1756. let menu = createSetMenu(getId(set.href));
  1757. insertAfter(set, menu)
  1758. }
  1759. };
  1760.  
  1761. var initUpdateHide = true;
  1762. var updateHide = function() {
  1763. let toggle = document.getElementById('girrfil_tog_input');
  1764. if (!toggle) { return; }
  1765. if (initUpdateHide) {
  1766. initUpdateHide = false;
  1767. let hideFailed = new Storage('hideFailed', false);
  1768. if (hideFailed.value) { toggle.click() }
  1769. toggle.addEventListener('click', function() {
  1770. hideFailed.value = !hideFailed.value;
  1771. });
  1772. }
  1773. }
  1774.  
  1775. var scrollToSelected = function() {
  1776. if (!selected) { return; }
  1777. let gircc = document.getElementById('girrcc')
  1778. if (mobile) {
  1779. gircc.scrollLeft = selected.offsetLeft - gircc.offsetWidth/2;
  1780. return;
  1781. }
  1782. gircc.scrollTop = selected.offsetTop - gircc.offsetHeight/2;
  1783. }
  1784.  
  1785. var adjustRecentWidth = function() {
  1786. if (mobile) { return; }
  1787.  
  1788. let small = false;
  1789. let img = document.querySelector('.girrgrid[data-imgcount="1"] img');
  1790. if (!img) { img = document.querySelector('.girrgrid img'); small = true}
  1791. if (!img) { return; }
  1792. let style = getComputedStyle(img);
  1793. let width = parseInt(style.width);
  1794. if (small) { width = width * 2 + 2; }
  1795.  
  1796. let girrvc = document.getElementById('girrvc')
  1797. girrvc.style.width = (width + 40).toString() + 'px';
  1798.  
  1799. if (!navigator.userAgent.toLowerCase().includes('firefox')) { return; }
  1800. girrvc.style.width = (width + 45).toString() + 'px';
  1801. let girrcc = document.getElementById('girrcc')
  1802. girrcc.style.width = (width + 35).toString() + 'px';
  1803. }
  1804.  
  1805. return function() {
  1806. addLocalPreviews();
  1807. addMenuButtons();
  1808. updateHide();
  1809. scrollToSelected();
  1810. adjustRecentWidth();
  1811. }
  1812. })();
  1813.  
  1814. var updateAutoDownload = (function() {
  1815. var run = false;
  1816. var force = false;
  1817. return async function(doForce) {
  1818. force = doForce || force;
  1819. if (run) { return; }
  1820. run = true;
  1821. updateDownloadAllButton();
  1822. let autoDownload = new Storage('autoDownload');
  1823. while (true) {
  1824. let restart = false;
  1825. let localSets = (new Storage('localSets', [])).value;
  1826. for (let i = localSets.length - 1; i >= 0; i--) {
  1827. let localSet = localSets[i];
  1828. let index = 0;
  1829. for (let image of localSet.images) {
  1830. index++;
  1831. if (image.downloaded == 'downloaded') { continue; }
  1832. if (image.downloaded == 'skipped' && !force) { continue; }
  1833. downloadImage(image.url, localSet.date, localSet.prompt, index, localSet.images.length);
  1834. image.downloaded = 'downloaded';
  1835. (new Storage('localSets')).value = localSets;
  1836. updateDownloadAllButton();
  1837. await sleep(3000);
  1838. restart = true;
  1839. break;
  1840. }
  1841. if (restart) { break; }
  1842. }
  1843. if (!restart) {
  1844. run = false;
  1845. force = false;
  1846. break;
  1847. }
  1848. }
  1849. }
  1850. })();
  1851.  
  1852. function updateRequests() {
  1853. let autoRequestCount = new Storage('autoRequestCount');
  1854. if (!autoRequestCount.value) { return; }
  1855. setTimeout(function() { doRequest(); }, ((new Storage('boostOption')).value =='U' && autoRequestCount.value < 3) ? 1500 : 0);
  1856. autoRequestCount.value--;
  1857. }
  1858.  
  1859. let updateWorking = (function() {
  1860. var reloadTimeOut = null;
  1861.  
  1862. var hideLoaderImage = function() {
  1863. let loader = elementLoaderImage(document);
  1864. if (loader && hide_loader_image) { loader.style.display = "none"; }
  1865. };
  1866.  
  1867. return function() {
  1868. if (isWorking(document)) {
  1869. document.title = "Working..."
  1870. setRequestButton('Creating', false, true);
  1871. let reloadTime = parseInt(document.getElementById('reload_slider').getElementsByTagName('input')[0].value);
  1872. if (!reloadTimeOut) { reloadTimeOut = setTimeout(function() { location.reload(); }, reloadTime*1000); }
  1873. setObserver(function() { return elementPatiance(document); }, function() { setTimeout(function() { location.reload(); }, 2000); });
  1874. setObserver(function() { return elementLoaderImage(document); }, hideLoaderImage);
  1875. return true;
  1876. }
  1877.  
  1878. setRequestButton();
  1879. if (reloadTimeOut) {clearTimeout(reloadTimeOut); reloadTimeOut = null; }
  1880. return false;
  1881. }
  1882. })();
  1883.  
  1884. function updateClickUnfinishedCell() {
  1885. let top = 3
  1886. let images = [];
  1887. let sets = document.querySelectorAll('a.girr_set');
  1888. for (let set of sets) {
  1889. if (!top--) { break };
  1890. if (isSetIncomplete(set)) {
  1891. setTimeout(function() { isDogged(document) ? set.click() : location.reload(); }, 2000);
  1892. return;
  1893. }
  1894. let girrgrid = set.childNodes[0];
  1895. for (let img of girrgrid.childNodes) {
  1896. if (img.className == "gir_wide") { img = img.childNodes[0]; }
  1897. if (!img.hasAttribute('src')) { continue; } // probably gipholder
  1898. let splits = img.src.split('/');
  1899. let name = splits[splits.length - 1].split('?')[0];
  1900. if (images.includes(name)) { setTimeout(function() { location.reload(); }, 2000); return; } // duplicate images in wrong set, need refresh
  1901. images.push(name);
  1902. }
  1903. }
  1904.  
  1905. if (isDogged(document)) {
  1906. if (!(new Storage('newSetsCount')).value) { return; }
  1907. sets = document.querySelectorAll('a.girr_set');
  1908. for (let set of sets) { setTimeout(function() { set.click(); }, 2000); return; }
  1909. }
  1910. }
  1911.  
  1912. let updateAutoRequests = (function() {
  1913. var doAutoEditRequests = async function() {
  1914. while (true) {
  1915. let found = false;
  1916. let localSet;
  1917. let image;
  1918. let localSets = (new Storage('localSets')).value;
  1919. loop: for (localSet of localSets) {
  1920. for (image of localSet.images) {
  1921. if (image.edit == 'pending') {
  1922. found = true;
  1923. break loop;
  1924. }
  1925. }
  1926. }
  1927.  
  1928. if (!found) { return; }
  1929.  
  1930. if (!localSet.skey || !image.id) {
  1931. let fetchSet = new Storage('fetchSet');
  1932. fetchSet.value = localSet;
  1933. let iframe = document.getElementById('iframe');
  1934. iframe.src = localSet.href;
  1935. if (!await wait(function() { return !fetchSet.value; }, 10000)) {
  1936. if (debug) { console.log('time out fetch skey and id'); }
  1937. return;
  1938. }
  1939. continue;
  1940. }
  1941.  
  1942. requestEditByImageId(image.id);
  1943. if (!await wait(function() {return !requestEditByImageId(); }, 30000)) {
  1944. if (debug) { console.log('time out request edit'); }
  1945. return;
  1946. }
  1947. }
  1948. }
  1949.  
  1950. return async function() {
  1951. await doAutoEditRequests();
  1952. updateAutoRequest();
  1953. }
  1954. })();
  1955.  
  1956. let updateDone = (function() {
  1957. return function() {
  1958. document.title = 'Done!';
  1959. if ((new Storage('autoOption')).value == 'ON' && (new Storage('newSetsCount')).value) {
  1960. playAudio('done', 8000);
  1961. }
  1962. }
  1963. })();
  1964.  
  1965. function update() {
  1966. updateLocalSets();
  1967. updatePreviewImages();
  1968. updateSitePreviewSets();
  1969. updateAutoDownload();
  1970. updateRequests()
  1971. let working = updateWorking();
  1972. if (working) {
  1973. setObserver(function() { return !isWorking(document); }, function() { update(); });
  1974. return;
  1975. }
  1976. updateClickUnfinishedCell();
  1977. updateAutoRequests();
  1978. updateDone();
  1979. }
  1980.  
  1981. var mobile = null;
  1982. function initMobile() {
  1983. mobile = document.head.querySelector('meta[name="mobileoptimized"]') ? true : false;
  1984. }
  1985.  
  1986. function initVersion() {
  1987. let loggo = document.getElementById('giheadlgsrch');
  1988. let version = createVersion();
  1989. loggo.appendChild(version);
  1990. }
  1991.  
  1992. let initBanner = (function() {
  1993. var addLastPrompt = function() {
  1994. if (elementSearchBox(document).value) { return; }
  1995. let lastPrompt = new Storage('lastPrompt', '');
  1996. elementSearchBox(document).value = lastPrompt.value;
  1997. }
  1998.  
  1999. return function() {
  2000. let banner = createBanner();
  2001. let existingBanner = elementBanner(document);
  2002. existingBanner.insertAdjacentElement('afterend', banner);
  2003. setTheme();
  2004. addLastPrompt();
  2005. updatePromptLength();
  2006. }
  2007. })();
  2008.  
  2009. function initSubMenu() {
  2010. let subMenu = createSetSubMenu();
  2011. let content = document.getElementById('gi_content')
  2012. if (!content) { return; }
  2013. content.appendChild(subMenu);
  2014. }
  2015.  
  2016. function initToolTip() {
  2017. let toolTip = createToolTip();
  2018. let content = document.getElementById('b_content')
  2019. if (!content) { content = document.getElementById('bpage'); }
  2020. if (!content) { return; }
  2021. content.appendChild(toolTip);
  2022. }
  2023.  
  2024. function addHideDeletedSlider()
  2025. {
  2026. let girrvc = document.getElementById('girrvc');
  2027. if (!girrvc) { return; }
  2028. let girrheader = girrvc.getElementsByClassName('girrheader')[0];
  2029. let slider = createSlider();
  2030. girrheader.appendChild(slider);
  2031. }
  2032.  
  2033. function init() {
  2034. initMobile();
  2035. initVersion();
  2036. initBanner();
  2037. initSubMenu();
  2038. initToolTip();
  2039. addHideDeletedSlider();
  2040. update();
  2041. }
  2042.  
  2043. let addEditButton = (function() { // replace share button with edit
  2044. var navigationLeft = null;
  2045. var navigationRight = null;
  2046. return function() {
  2047. let editButton = document.createElement('a');
  2048. editButton.id = 'edit-button';
  2049. editButton.textContent = 'Edit';
  2050. editButton.target = '_blank';
  2051. editButton.classList.add('action');
  2052. editButton.classList.add('share');
  2053.  
  2054. let updateButtons = function() {
  2055. let navl = document.getElementById('navl');
  2056. if (navl) {
  2057. if (!navigationLeft) {
  2058. navigationLeft = navl;
  2059. if (navigationLeft) { navigationLeft.addEventListener('click', function() { setTimeout(updateButtons, 250); }); }
  2060. }
  2061. } else {
  2062. navigationLeft = null;
  2063. }
  2064.  
  2065. let navr = document.getElementById('navr');
  2066. if (navr) {
  2067. if (!navigationRight) {
  2068. navigationRight = navr;
  2069. if (navigationRight) { navigationRight.addEventListener('click', function() { setTimeout(updateButtons, 250); }); }
  2070. }
  2071. } else {
  2072. navigationRight = null;
  2073. }
  2074.  
  2075. let id = getId(window.location.href);
  2076. let container = document.getElementById('canvas_cc');
  2077. if (container) {
  2078. container = container.getElementsByClassName('curr')[0];
  2079. } else {
  2080. container = document.getElementById('mainImageContainer');
  2081. container = container.getElementsByClassName('mainImage current curimgonview')[0];
  2082. }
  2083. let img = container.getElementsByTagName('img')[0];
  2084. let src = img.src;
  2085. let splits = src.split('/');
  2086. let thid = splits[splits.length - 1].split('?')[0];
  2087. let localSets = (new Storage('localSets')).value
  2088. let image = null;
  2089. let localSet = null;
  2090. loop: for (localSet of localSets) {
  2091. if (localSet.id != id) { continue; }
  2092. for (image of localSet.images) {
  2093. if (image.thid == thid) { break loop; }
  2094. }
  2095. }
  2096. let url = new URL(window.location.href.split('?')[0]);
  2097. url.searchParams.append('id', image.id);
  2098. url.searchParams.append('thId', image.thid);
  2099. url.searchParams.append('FORM', 'GCRIDP');
  2100. let href = url.href + '&edit=1&clientName=BING+CHAT&sappdirectloa=1&showselective=1&FORM=SYDBIC';
  2101. editButton.href = href;
  2102. }
  2103. updateButtons();
  2104.  
  2105. let share = elementShareButton(document);
  2106. if (share) {
  2107. share.innerHTML = "";
  2108. share.appendChild(editButton);
  2109. }
  2110. setObserver(function() { return elementShareButton(document) && !document.getElementById('edit-button'); }, addEditButton);
  2111. }
  2112. })();
  2113.  
  2114. function initDetailsPage()
  2115. {
  2116. let doc = document;
  2117. let iframe = document.getElementById('OverlayIFrame')
  2118. if (iframe) {doc = iframe.contentWindow.document; }
  2119. let init = function() {
  2120. addEditButton();
  2121. iframeFetchImageSkey();
  2122. }
  2123. setObserver(function() { return doc.getElementsByClassName('action share rm nofocus').length; }, init, true, iframe);
  2124.  
  2125. if (!remove_related_content) { return; }
  2126. let removeRelatedContent = function() {
  2127. let elements = doc.getElementsByClassName('idp-refresh-page-bottom-page');
  2128. if (!elements.length) { return; }
  2129. let div = elements[0];
  2130. div.remove();
  2131. }
  2132. setObserver(function() { return doc.getElementsByClassName('idp-refresh-page-bottom-page').length; }, removeRelatedContent, true, iframe);
  2133. }
  2134.  
  2135. function autoLogin() {
  2136. let loginAttempts = new Storage('loginAttempts', 0);
  2137. if (!isLoggedOut(document)) {
  2138. loginAttempts.value = auto_login ? 3 : 0;
  2139. return false;
  2140. }
  2141.  
  2142. if (loginAttempts.value) {
  2143. loginAttempts.value--;
  2144. window.location.href = 'https://www.bing.com/images/create?sude=1';
  2145. }
  2146. return true;
  2147. }
  2148.  
  2149. function autoReload() {
  2150. if (!elementBanner(document)) {
  2151. setTimeout(function() { window.location.href = 'https://www.bing.com/images/create?'; }, 2000);
  2152. return true;
  2153. }
  2154. return false;
  2155. }
  2156.  
  2157. function auto() {
  2158. if (autoLogin()) { return; }
  2159. if (autoReload()) { return; }
  2160. }
  2161.  
  2162. function load() {
  2163. if (getUrlParam("FORM") == "BICREC") { return; }
  2164. if (getUrlParam("FORM") == "GCRIDP") { initDetailsPage(); return; }
  2165. if (inIframe()) {
  2166. setObserver(function() { return document.getElementById('gir_async'); }, function() { setTimeout(iframeFetchImageIds, 1000); });
  2167. return;
  2168. }
  2169. setObserver(function() { return elementBanner(document); }, function() { setTimeout(init, 0); } );
  2170. setTimeout(auto, 3000);
  2171. }
  2172.  
  2173. window.onload = setTimeout(load, 0);
Advertisement
Add Comment
Please, Sign In to add comment