pimeyesJS

Mods to make pimeyes.com work better for both premium and free users

Instalar este script¿?
Script recomendado por el autor

Puede que también te guste amazonReviewWall.

Instalar este script
  1. // ==UserScript==
  2. // @name pimeyesJS
  3. // @namespace https://github.com/deltabravozulu/usefulUserScripts
  4. // @match *://pimeyes.com/en/search/*
  5. // @grant none
  6. // @version 9.6.9_420.11
  7. // @icon https://pimeyes.com/favicon.ico
  8. // @author DeltaBravoZulu
  9. // @description Mods to make pimeyes.com work better for both premium and free users
  10. // @description 2022-05-09T18:04:20
  11. // @require https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js
  12. // @run-at document-idle
  13. // @license PayMe
  14. // ==/UserScript==
  15. ///////////////////////////////////////////////////////////////////////////////////
  16. ///////////////////////////////////////////////////////////////////////////////////
  17. //// A script to allow automatic image loading, page improvements via CSS, ////
  18. //// explicit result isolation, and other neat stuff on pimeyes.com ////
  19. //// by DeltaBravoZulu ////
  20. ///////////////////////////////////////////////////////////////////////////////////
  21. ///////////////////////////////////////////////////////////////////////////////////
  22.  
  23. ///////////////////////////////////////
  24. // Script Initialization //
  25. ///////////////////////////////////////
  26. /*
  27. ** Invokes injection of buttons
  28. ** Sets initial variables and gathers stats
  29. */
  30.  
  31. //Make sure page loads before starting
  32. new MutationObserver(check).observe(document, {
  33. childList: true,
  34. subtree: true,
  35. });
  36.  
  37. function check(changes, observer) {
  38. if (
  39. document.querySelector(
  40. "#results > div > div > div.top-slot > div > div > div > button:nth-child(5) > img"
  41. )
  42. ) {
  43. observer.disconnect();
  44. explicitButts();
  45. scrollButts();
  46. importButts();
  47. exportButts();
  48. explicitCount = 0;
  49. explicitStats();
  50. scrolled = 0;
  51. //Gets the Open Graph url which was removed in June
  52. var ogUrl=document.querySelectorAll('meta[property="og:url"]')[0].content.replace('https://pimeyes.com/en','')
  53. //Adds the URL to the URL bar so you can copypaste it
  54. var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + ogUrl;
  55. window.history.pushState({path:newurl},'',newurl);
  56. //Adds scroll explicit counter
  57. scrollResultsUpdateListener();
  58. //Adds mousedown event listener to highlight text during popup for copying
  59. clickThumb = document.querySelector("div.results-grid");
  60. clickThumb.addEventListener("mousedown", highlightUrl);
  61. //Removes the 'Pay 299/month' overlay if hitting the Deep Search button
  62. document.querySelector("div[data-v-69882821]").remove();
  63. //Makes rows wider and shows images better
  64. //This is broken//document.querySelector("div.results-grid").style.width="90";
  65. document.querySelector("div.results-grid").style.minWidth="60%";
  66. document.querySelector("div.results-grid").style.maxWidth="100%";
  67. document.querySelector("div.results-grid").style.gridTemplateColumns = "repeat(5,20%)";
  68. document.querySelector("div.results-grid").style.gridAutoRows = "auto";
  69.  
  70. }
  71. }
  72.  
  73. //Alternative way of doing it
  74. /*
  75. var observer = new MutationObserver(resetTimer);
  76. var timer = setTimeout(action, 2000, observer); // wait for the page to stay still for 2 seconds
  77. observer.observe(document, {childList: true, subtree: true});
  78. function resetTimer(changes, observer) {
  79. clearTimeout(timer);
  80. timer = setTimeout(action, 2000, observer);
  81. }
  82.  
  83. function action(o) {
  84. o.disconnect();
  85. observer.disconnect();
  86. explicitButts();
  87. scrollButts();
  88. explicitCount = 0;
  89. explicitStats();
  90. scrolled = 0;
  91. scrollResultsUpdateListener();
  92. }
  93. */
  94.  
  95. ///////////////////////////////////////
  96. // Button Injections //
  97. ///////////////////////////////////////
  98. /*
  99. ** Adds buttons to invoke scrolling and removal
  100. ** Sets initial variable and gathers stats
  101. */
  102.  
  103. //Injects a button that, when pressed, will scroll to the bottom of the page to load all images, then remove all images that are not explicit
  104. function explicitButts() {
  105. console.log("Adding 18+ Button");
  106. var oldButtons = document.querySelector(
  107. "#results > div > div > div.top-slot > div > div > div > button:last-child"
  108. );
  109. var explicitButtons = oldButtons.parentElement;
  110. var iconHtml =
  111. '<button data-v-4ccff48d="" type="button" class="default icon-only" data-v-46dbee4d="" id="18Button" title="Scroll to the bottom and remove non-explicit images"><img data-v-4ccff48d="" src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMzEwLjkgMzEwLjkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTk1IDIxMS40di04OS4zSDc0LjRWOTkuMmg0OS4xdjExMi4yem0xMzUuNi04My4yYzAgOS44LTUuMyAxOC40LTE0LjEgMjMuMiAxMi4zIDUuMSAyMCAxNS44IDIwIDI4LjMgMCAyMC4yLTE3LjkgMzMtNDUuOSAzM3MtNDUuOS0xMi42LTQ1LjktMzIuNWMwLTEyLjggOC4zLTIzLjcgMjEuMy0yOC44LTkuNC01LjMtMTUuNS0xNC4yLTE1LjUtMjQgMC0xNy45IDE1LjctMjkuMyA0MC0yOS4zIDI0LjUuMSA0MC4xIDExLjcgNDAuMSAzMC4xem0tNTkuMSA0OS4yYzAgOS40IDYuNyAxNC43IDE5IDE0LjdzMTkuMi01LjEgMTkuMi0xNC43YzAtOS4zLTYuOS0xNC42LTE5LjItMTQuNnMtMTkgNS4zLTE5IDE0LjZ6bTIuOS00Ny42YzAgOCA1LjggMTIuNSAxNi4yIDEyLjVzMTYuMi00LjUgMTYuMi0xMi41YzAtOC4zLTUuOC0xMy0xNi4yLTEzLTEwLjUuMS0xNi4yIDQuNy0xNi4yIDEzeiIvPjxwYXRoIGQ9Ik0xNTUuNCAzMTAuOUM2OS43IDMxMC45IDAgMjQxLjEgMCAxNTUuNFM2OS43IDAgMTU1LjQgMGMxMS42IDAgMjMuMiAxLjMgMzQuNSAzLjlWMTVjLTExLjItMi44LTIyLjgtNC4xLTM0LjUtNC4xLTc5LjcgMC0xNDQuNiA2NC45LTE0NC42IDE0NC42czY0LjkgMTQ0LjYgMTQ0LjYgMTQ0LjZTMzAwIDIzNS4yIDMwMCAxNTUuNWMwLTExLjctMS40LTIzLjMtNC4xLTM0LjVIMzA3YzIuNiAxMS4zIDMuOSAyMi44IDMuOSAzNC41IDAgODUuNi02OS44IDE1NS40LTE1NS41IDE1NS40eiIvPjxwYXRoIGQ9Ik0yNzUuNyAzNS4xVjMuNkgyNTN2MzEuNWgtMzEuNHYyMi43SDI1M3YzMS41aDIyLjdWNTcuOGgzMS41VjM1LjF6Ii8+PC9zdmc+"> <span data-v-4ccff48d="">View Explicit</span></button>';
  112. explicitButtons.insertAdjacentHTML("beforeend", iconHtml);
  113. document.getElementById("18Button").addEventListener("click", explicitJS);
  114. console.log("Added 18+ Button");
  115. }
  116.  
  117. //Injects a scroll button which will allow one to load all images on the page automatically
  118. function scrollButts() {
  119. console.log("Adding Scroll Button");
  120. var oldButtons = document.querySelector(
  121. "#results > div > div > div.top-slot > div > div > div > button:last-child"
  122. );
  123. var scrollButton = oldButtons.parentElement;
  124. var scrollIconHtml =
  125. '<button data-v-4ccff48d="" type="button" class="default icon-only" data-v-46dbee4d="" id="scrollButton" title="Scroll to the bottom"><img data-v-4ccff48d="" src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNDkwLjcgNDkwLjciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTQ3Mi4zIDIxNi41LTIyNy4xIDIyNy4yLTIyNy4xLTIyNy4yYy00LjItNC4xLTExLTQtMTUuMS4zLTQgNC4xLTQgMTAuNyAwIDE0LjhsMjM0LjcgMjM0LjdjNC4yIDQuMiAxMC45IDQuMiAxNS4xIDBsMjM0LjctMjM0LjdjNC4xLTQuMiA0LTExLS4zLTE1LjEtNC4yLTQtMTAuNy00LTE0LjkgMHoiIGZpbGw9IiM2MDdkOGIiLz48cGF0aCBkPSJtNDcyLjMgMjQuNS0yMjcuMSAyMjcuMi0yMjcuMS0yMjcuMmMtNC4yLTQuMS0xMS00LTE1LjEuMy00IDQuMS00IDEwLjcgMCAxNC44bDIzNC43IDIzNC43YzQuMiA0LjIgMTAuOSA0LjIgMTUuMSAwbDIzNC42LTIzNC43YzQuMi00LjEgNC40LTEwLjguMy0xNS4xLTQuMS00LjItMTAuOC00LjQtMTUuMS0uMy0uMS4yLS4yLjItLjMuM3oiIGZpbGw9IiM2MDdkOGIiLz48cGF0aCBkPSJtMjQ1LjIgNDY5LjRjLTIuOCAwLTUuNS0xLjEtNy42LTMuMWwtMjM0LjYtMjM0LjdjLTQuMS00LjItNC0xMSAuMy0xNS4xIDQuMS00IDEwLjctNCAxNC44IDBsMjI3LjEgMjI3LjEgMjI3LjEtMjI3LjFjNC4yLTQuMSAxMS00IDE1LjEuMyA0IDQuMSA0IDEwLjcgMCAxNC44bC0yMzQuNyAyMzQuN2MtMiAyLTQuNyAzLjEtNy41IDMuMXoiLz48cGF0aCBkPSJtMjQ1LjIgMjc3LjRjLTIuOCAwLTUuNS0xLjEtNy42LTMuMWwtMjM0LjYtMjM0LjdjLTQuMS00LjItNC0xMSAuMy0xNS4xIDQuMS00IDEwLjctNCAxNC44IDBsMjI3LjEgMjI3LjEgMjI3LjEtMjI3LjFjNC4xLTQuMiAxMC44LTQuNCAxNS4xLS4zczQuNCAxMC44LjMgMTUuMWMtLjEuMS0uMi4yLS4zLjNsLTIzNC43IDIzNC43Yy0yIDItNC43IDMuMS03LjUgMy4xeiIvPjwvc3ZnPg=="> <span data-v-4ccff48d="">Scroll Button</span></button>';
  126. scrollButton.insertAdjacentHTML("beforeend", scrollIconHtml);
  127. document.getElementById("scrollButton").addEventListener("click", betterScroller);
  128. console.log("Added Scroll Button");
  129. }
  130.  
  131. //Injects a button that, when pressed, will copy the Open Graph index to the clipboard
  132. function exportButts() {
  133. console.log("Adding OG URL Export Button");
  134. var oldButtons = document.querySelector(
  135. "#results > div > div > div.top-slot > div > div > div > button:last-child"
  136. );
  137. var exportButton = oldButtons.parentElement;
  138. var exportIconHtml =
  139. '<button data-v-4ccff48d="" type="button" class="default icon-only" data-v-46dbee4d="" id="exportButton" title="Export Open Graph URL to clipboard"><img data-v-4ccff48d="" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0ODguMyA0ODguMyI+PHBhdGggZD0iTTMxNC4yNSA4NS40aC0yMjdjLTIxLjMgMC0zOC42IDE3LjMtMzguNiAzOC42djMyNS43YzAgMjEuMyAxNy4zIDM4LjYgMzguNiAzOC42aDIyN2MyMS4zIDAgMzguNi0xNy4zIDM4LjYtMzguNlYxMjRjLS4xLTIxLjMtMTcuNC0zOC42LTM4LjYtMzguNnptMTEuNSAzNjQuMmMwIDYuNC01LjIgMTEuNi0xMS42IDExLjZoLTIyN2MtNi40IDAtMTEuNi01LjItMTEuNi0xMS42VjEyNGMwLTYuNCA1LjItMTEuNiAxMS42LTExLjZoMjI3YzYuNCAwIDExLjYgNS4yIDExLjYgMTEuNnYzMjUuNnoiLz48cGF0aCBkPSJNNDAxLjA1IDBoLTIyN2MtMjEuMyAwLTM4LjYgMTcuMy0zOC42IDM4LjYgMCA3LjUgNiAxMy41IDEzLjUgMTMuNXMxMy41LTYgMTMuNS0xMy41YzAtNi40IDUuMi0xMS42IDExLjYtMTEuNmgyMjdjNi40IDAgMTEuNiA1LjIgMTEuNiAxMS42djMyNS43YzAgNi40LTUuMiAxMS42LTExLjYgMTEuNi03LjUgMC0xMy41IDYtMTMuNSAxMy41czYgMTMuNSAxMy41IDEzLjVjMjEuMyAwIDM4LjYtMTcuMyAzOC42LTM4LjZWMzguNmMwLTIxLjMtMTcuMy0zOC42LTM4LjYtMzguNnoiLz48L3N2Zz4="> <span data-v-4ccff48d="">Export Button</span></button>';
  140. scrollButton.insertAdjacentHTML("afterend", exportIconHtml);
  141. document.getElementById("exportButton").addEventListener("click", exporter);
  142. console.log("Added Export Button");
  143. }
  144.  
  145. //Injects a button that, when pressed, will paste the Open Graph index from the clipboard to the URL bar
  146. function importButts() {
  147. console.log("Adding OG URL Import Button");
  148. var oldButtons = document.querySelector(
  149. "#results > div > div > div.top-slot > div > div > div > button:last-child"
  150. );
  151. var importButton = oldButtons.parentElement;
  152. var importIconHtml =
  153. '<button data-v-4ccff48d="" type="button" class="default icon-only" data-v-46dbee4d="" id="importButton" title="Import Open Graph URL from clipboard"><img data-v-4ccff48d="" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiB2aWV3Qm94PSIwIDAgMTYgMTYiPjxsaW5lYXJHcmFkaWVudCB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJhIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KC05LjUgOSAtOSAtOS41IDc0LjUzNiA4OCkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4Mj0iMSI+PHN0b3Agb2Zmc2V0PSIuMDA3Ii8+PHN0b3Agb2Zmc2V0PSIxIi8+PC9saW5lYXJHcmFkaWVudD48cGF0aCBkPSJNNjMuNTU2IDkzLjQ4OHYyLjVhMi41IDIuNSAwIDAgMCAyLjUgMi41aDEwYTIuNSAyLjUgMCAwIDAgMi41LTIuNXYtMi4wNmEuNS41IDAgMCAwLTEgMHYyLjA2YTEuNSAxLjUgMCAwIDEtMS41IDEuNWgtMTBhMS41IDEuNSAwIDAgMS0xLjUtMS41di0yLjVhLjUuNSAwIDAgMC0xIDB6bTcuMDAxLjM1NWwtMS4yNjktMS4yNjlhLjUuNSAwIDAgMC0uNzA3LjcwN2wyLjEyMSAyLjEyMWEuNDk5LjQ5OSAwIDAgMCAuNzA3IDBsMi4xMjItMi4xMjFhLjUuNSAwIDAgMC0uNzA3LS43MDdsLTEuMjY3IDEuMjY3LjAwNy03LjgyOWEuNS41IDAgMCAwLTEtLjAwMXoiIGZpbGw9InVybCgjYSkiIGRhdGEtb3JpZ2luYWw9InVybCgjX0xpbmVhcjEpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNjMuMDM2IC04NCkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIvPjwvc3ZnPg=="> <span data-v-4ccff48d="">Import Button</span></button>';
  154. scrollButton.insertAdjacentHTML("afterend", importIconHtml);
  155. document.getElementById("importButton").addEventListener("click", importer);
  156. console.log("Added Import Button");
  157. }
  158.  
  159.  
  160. ///////////////////////////////////////
  161. // Export/Import OpenGraph Url //
  162. ///////////////////////////////////////
  163. /*
  164. ** Includes a scroller to load the page, stats, and sleep timers
  165. */
  166.  
  167. //Copies the open graph url to the clipboard
  168.  
  169. ogUrl=document.querySelectorAll('meta[property="og:url"]')[0].content.replace('https://pimeyes.com/en','')
  170. ogUrlCut=ogUrl.substring(0, ogUrl.lastIndexOf('?')).replace('/search/','')
  171.  
  172. function exporter() {
  173. executeCopy = function() {
  174. var copyhelper = document.createElement("input");
  175. copyhelper.className = 'copyhelper'
  176. document.body.appendChild(copyhelper);
  177. copyhelper.value = ogUrlCut;
  178. copyhelper.select();
  179. document.execCommand("copy");
  180. document.body.removeChild(copyhelper);
  181. };
  182. executeCopy();
  183. console.log("ogURLCut is " + ogUrlCut)
  184. }
  185.  
  186. async function importer() {
  187. oldPage=window.location.href;
  188. oldPageIndex=oldPage.indexOf(ogUrlCut)
  189. ogUrlImport= await navigator.clipboard.readText();
  190. newPage=oldPage.substr(0, oldPageIndex) + ogUrlImport + "_" + oldPage.substr(oldPageIndex)
  191. console.log("oldPage is " + oldPage)
  192. console.log("newPage is " + newPage)
  193. window.history.pushState({path:newPage},'',newPage);
  194. window.location.href=newPage
  195. }
  196.  
  197.  
  198.  
  199. ///////////////////////////////////////
  200. // Removal Prerequisites //
  201. ///////////////////////////////////////
  202. /*
  203. ** Includes a scroller to load the page, stats, and sleep timers
  204. */
  205.  
  206. //Scrolls down the page as fast as possible
  207. function scrollDown() {
  208. window.scrollBy(0, 10000);
  209. window.scrollTo(0, document.body.scrollHeight);
  210. }
  211.  
  212. //Scrolls to the top of the page
  213. function scrollUp() {
  214. window.scrollBy(0, -50000);
  215. window.scrollTo(0, 0);
  216. }
  217.  
  218. //Scrolls all the way to the bottom of the page to load all results, then scrolls back to the top
  219. async function scroller() {
  220. if (document.querySelectorAll("div.results-end").length === 1) {
  221. scrolled = 1;
  222. } else if (document.querySelectorAll("div.results-end").length === 0) {
  223. scrolled = 0;
  224. }
  225. while (scrolled < 1) {
  226. console.log("Scrolling to the bottom of the results");
  227. var scrollCount = 1;
  228. do {
  229. scrollDown();
  230. console.log("Sleeping 1000ms");
  231. await sleep(1000);
  232. console.log("Still scrolling (" + scrollCount + "x)");
  233. scrollCount++;
  234. } while (document.querySelectorAll("div.results-end").length === 0);
  235. console.log("Done scrolling");
  236. console.log("Sleeping 1000ms");
  237. await sleep(1000);
  238. console.log("Scrolling to top of page");
  239. scrollUp();
  240. console.log("We reached the top");
  241. console.log("Sleeping 1000ms");
  242. await sleep(1000);
  243. scrolled = 1;
  244. }
  245. }
  246.  
  247. //Scrolls but lets you control it
  248. function betterScroller() {
  249. var a = document.body.clientHeight,
  250. b = document.documentElement.scrollHeight,
  251. c = document.documentElement.clientHeight,
  252. d = innerHeight,
  253. e = document.height;
  254. if (console.log("document.body.clientHeight:\t\t\t\t\t" + a + ";\ndocument.documentElement.scrollHeight:\t\t" + b + ";\ndocument.documentElement.clientHeight:\t\t" + c + ";\ninnerHeight:\t\t\t\t\t\t\t\t" + d + ";\ndocument.height:\t\t\t\t\t\t\t" + e), document.URL.includes("facebook.com")) ! function() {
  255. var e = null,
  256. t = 0,
  257. s = function() {
  258. console.log("Clicked; stopping autoscroll"), clearInterval(e), document.body.removeEventListener("click", s)
  259. };
  260. document.body.addEventListener("click", s), e = setInterval(function() {
  261. var o = document.body.scrollHeight - document.body.scrollTop - window.innerHeight;
  262. o > 0 ? (window.scrollBy(0, o), t > 0 && (t = 0), console.log("scrolling down more")) : t >= 3 ? (console.log("reached bottom of page; stopping"), clearInterval(e), document.body.removeEventListener("click", s)) : (console.log("[apparenty] hit bottom of page; retrying: " + (t + 1)), t++)
  263. }, 1e3)
  264. }();
  265. else {
  266. let e, t = 1,
  267. s = [
  268. [0, 0],
  269. [25, 200],
  270. [36, 120],
  271. [49, 72],
  272. [64, 43.2],
  273. [81, 25.9],
  274. [100, 31],
  275. [121, 37.2],
  276. [144, 44.8],
  277. [169, 26.4],
  278. [196, 32]
  279. ],
  280. o = document.onkeypress;
  281. _ss_stop = function() {
  282. clearTimeout(e)
  283. }, _ss_start = function() {
  284. _ss_abs_speed = Math.abs(t), _ss_direction = t / _ss_abs_speed, _ss_speed_pair = s[_ss_abs_speed], e = setInterval("scrollBy(0," + _ss_direction * _ss_speed_pair[0] + "); if((pageYOffset<=1)||(pageYOffset==document.documentElement.scrollHeight-innerHeight)) _ss_speed=0;", _ss_speed_pair[1])
  285. }, _ss_adj = function(e) {
  286. t += e, Math.abs(t) >= s.length && (t = (s.length - 1) * (t / Math.abs(t)))
  287. }, _ss_quit = function() {
  288. _ss_stop(), document.onkeypress = o
  289. }, document.onkeypress = function(e) {
  290. if (113 != e.charCode && 27 != e.keyCode) {
  291. if (e.charCode >= 48 && e.charCode <= 57) t = e.charCode - 48;
  292. else switch (e.charCode) {
  293. case 95:
  294. _ss_adj(-2);
  295. case 45:
  296. _ss_adj(-1);
  297. break;
  298. case 43:
  299. _ss_adj(2);
  300. case 61:
  301. _ss_adj(1)
  302. }
  303. _ss_stop(), _ss_start()
  304. } else _ss_quit()
  305. }, _ss_stop(), _ss_start()
  306. }
  307. }
  308.  
  309. //Lets script sleep after functions to allow page a bit of time to catch up
  310. function sleep(ms) {
  311. return new Promise((resolve) => setTimeout(resolve, ms));
  312. }
  313.  
  314. //Helper script to update the count of explicit results
  315. function expResultsUpdater() {
  316. explicitCount = document.querySelectorAll(
  317. "#results div.results-grid div.result div.thumbnail span.explicit-result"
  318. ).length;
  319. console.log(explicitCount + " potentially explicit results so far");
  320. document.getElementById("expResults").innerHTML = explicitCount;
  321. }
  322.  
  323. //Injects an explicit results running total at the top of the page
  324. function explicitStats() {
  325. console.log("Inserting Stats Counter");
  326. var oldResults = document.querySelector(
  327. "#results > div.container > div > div.top-slot > div > div.container > span.stats > span:nth-child(1)"
  328. );
  329. var explicitResults = oldResults;
  330. var resultsHtml =
  331. '<span data-v-26e5f418="">' +
  332. '<bdi id="expResults">' +
  333. explicitCount +
  334. "</bdi>" +
  335. " potentially explicit results so far</span>";
  336. explicitResults.insertAdjacentHTML("beforebegin", resultsHtml);
  337. expResultsUpdater();
  338. }
  339.  
  340. //Updates the explicit results count that was injected at the top of the page then stops doing anything after page-end is reached
  341. function scrollResultsUpdateListener() {
  342. addEventListener("scroll", function () {
  343. if (document.querySelectorAll("div.results-end").length === 0) {
  344. expResultsUpdater();
  345. scrolled = 0;
  346. }
  347. });
  348. }
  349.  
  350.  
  351.  
  352. //Highlights and generates url to go to site where image is hosted
  353. async function highlightUrl() {
  354. console.log("Waiting to highlight");
  355. await sleep(200);
  356. var spanUrl = document.querySelector(
  357. "div.modal-content div.thumbnail span.url"
  358. );
  359. if (typeof spanUrl != "undefined" && spanUrl != null) {
  360. spanUrl = document.querySelector(
  361. "div.modal-content div.thumbnail span.url"
  362. );
  363. spanUrl.innerHTML =
  364. `<a href="` + spanUrl.innerHTML + `">` + spanUrl.innerHTML + `</a>`;
  365.  
  366. function selectText(node) {
  367. node = spanUrl;
  368.  
  369. if (document.body.createTextRange) {
  370. const range = document.body.createTextRange();
  371. range.moveToElementText(node);
  372. range.select();
  373. } else if (window.getSelection) {
  374. const selection = window.getSelection();
  375. const range = document.createRange();
  376. range.selectNodeContents(node);
  377. selection.removeAllRanges();
  378. selection.addRange(range);
  379. } else {
  380. console.warn(
  381. "Could not select text in node: Unsupported browser."
  382. );
  383. }
  384. }
  385. selectText("spanUrl");
  386. } else {
  387. console.log(
  388. "Tried to highlight URL because of highlightUrl mousedown event listener but popup does not exist!"
  389. );
  390. }
  391. }
  392.  
  393. ///////////////////////////////////////
  394. // Removal Scripts //
  395. ///////////////////////////////////////
  396. /*
  397. **Pure Javascript based removal scripts
  398. */
  399.  
  400. //Script to remove nonexplicit images using jQuery
  401. function jsRemover() {
  402. console.log("Running removal script (Pure JavaScript)");
  403. document
  404. .querySelectorAll("#results div.results-grid div.result div.thumbnail")
  405. .forEach(function (element) {
  406. if (!element.querySelector("span.explicit-result")) {
  407. element.parentNode.remove();
  408. }
  409. });
  410. console.log("Finished removal script");
  411. }
  412.  
  413. //jsRemover helper script
  414. async function explicitJS() {
  415. console.log("Starting the removal process");
  416. await scroller();
  417. jsRemover();
  418. console.log("Finished the removal process");
  419. }
  420.  
  421. /*
  422. **jQuery based removal scripts
  423. */
  424.  
  425. //Script to remove nonexplicit images using jQuery
  426. function jqRemover() {
  427. console.log("Running removal service (jQuery)");
  428. jQuery(
  429. "#results div.results-grid div.result div.thumbnail:has(span):not(:has(.explicit-result))"
  430. )
  431. .parent()
  432. .remove();
  433. console.log("Finished removal script");
  434. }
  435.  
  436. //jqRemover helper script
  437. async function explicitJQ() {
  438. jqGetter();
  439. console.log("Starting the removal process");
  440. await scroller();
  441. jsRemover();
  442. console.log("Finished the removal process");
  443. }
  444.  
  445. //Downloads jQuery to the page
  446. function jqGetter() {
  447. console.log("Downloading jQuery to page");
  448. var el = document.createElement("div"),
  449. b = document.getElementsByTagName("body")[0],
  450. otherlib = !1,
  451. msg = "";
  452. (el.style.position = "fixed"),
  453. (el.style.height = "32px"),
  454. (el.style.width = "220px"),
  455. (el.style.marginLeft = "-110px"),
  456. (el.style.top = "0"),
  457. (el.style.left = "50%"),
  458. (el.style.padding = "5px 10px"),
  459. (el.style.zIndex = 1001),
  460. (el.style.fontSize = "12px"),
  461. (el.style.color = "#222"),
  462. (el.style.backgroundColor = "#f99");
  463.  
  464. function showMsg() {
  465. var txt = document.createTextNode(msg);
  466. el.appendChild(txt),
  467. b.appendChild(el),
  468. window.setTimeout(function () {
  469. (txt = null),
  470. typeof jQuery == "undefined"
  471. ? b.removeChild(el)
  472. : (jQuery(el).fadeOut("slow", function () {
  473. jQuery(this).remove();
  474. }),
  475. otherlib && (window.$jq = jQuery.noConflict()));
  476. }, 2500);
  477. }
  478. if (typeof jQuery != "undefined")
  479. return (
  480. (msg = "This page already using jQuery v" + jQuery.fn.jquery),
  481. showMsg()
  482. );
  483. typeof $ == "function" && (otherlib = !0);
  484.  
  485. function getScript(url, success) {
  486. var script = document.createElement("script");
  487. script.src = url;
  488. var head = document.getElementsByTagName("head")[0],
  489. done = !1;
  490. (script.onload = script.onreadystatechange = function () {
  491. !done &&
  492. (!this.readyState ||
  493. this.readyState == "loaded" ||
  494. this.readyState == "complete") &&
  495. ((done = !0),
  496. success(),
  497. (script.onload = script.onreadystatechange = null),
  498. head.removeChild(script));
  499. }),
  500. head.appendChild(script);
  501. }
  502. getScript("//code.jquery.com/jquery.min.js", function () {
  503. return (
  504. typeof jQuery == "undefined"
  505. ? (msg = "Sorry, but jQuery was not able to load")
  506. : ((msg =
  507. "This page is now jQuerified with v" +
  508. jQuery.fn.jquery),
  509. otherlib &&
  510. (msg += " and noConflict(). Use $jq(), not $().")),
  511. showMsg()
  512. );
  513. });
  514. console.log("jQuery downloaded to page");
  515. }
  516.  
  517. ///////////////////////////////////////
  518. // CSS Mods/Page Improvement //
  519. ///////////////////////////////////////
  520. /**
  521. * Utility function to add CSS in multiple passes.
  522. * @param {string} styleString
  523. * From http://stackoverflow.com/a/15506705
  524. **/
  525. function addStyle(styleString) {
  526. const style = document.createElement("style");
  527. style.textContent = styleString;
  528. document.head.append(style);
  529. }
  530.  
  531. //From https://greasyfork.org/scripts/406062
  532. addStyle(`
  533. /*Un-blur the URLs*/
  534. .blurred-source-url {
  535. user-select: all !important;
  536. ;
  537. }
  538. `);
  539.  
  540. //From https://greasyfork.org/scripts/406062
  541. /*div.modal-content>div.thumbnail>span.url*/
  542.  
  543. addStyle(`
  544. /*Make the URLs selectable, and visible*/
  545. *.url {
  546. filter: none !important;
  547. ;
  548. overflow: visible !important;
  549. ;
  550. user-select: initial !important;
  551. ;
  552. max-width: initial !important;
  553. ;
  554. pointer-events: none !important;
  555. ;
  556. position: initial !important;
  557. }
  558. `);
  559.  
  560. //From https://greasyfork.org/scripts/406062
  561. addStyle(`
  562. /*Remove the Buy Premium overlay on images*/
  563. .zoom {
  564. display: none !important;
  565. ;
  566. }
  567. `);
  568.  
  569. //From https://greasyfork.org/scripts/406062
  570. addStyle(`
  571. /*Remove the 'Get access to archival results and Deep search for $299.99/mo overlay on images*/
  572. .promo {
  573. display: none !important;
  574. ;
  575. }
  576. `);
  577.  
  578. //From https://greasyfork.org/scripts/406062
  579. addStyle(`
  580. /*Remove the actions menu, so we can select the image*/
  581. .actions {
  582. display: none !important;
  583. ;
  584. }
  585. `);
  586.  
  587. //From https://greasyfork.org/scripts/406062
  588. /*
  589. addStyle(`
  590. /*Hide UNLOCK buttons*\/
  591. button[type="button"] {
  592. display: none !important;
  593. ;
  594. }
  595. `);
  596. */
  597.  
  598. //From https://greasyfork.org/scripts/406062
  599. addStyle(`
  600. /*un-hide add picture button*/
  601. button[class="spacer"] {
  602. display: inherit !important;
  603. ;
  604. }
  605. `);
  606.  
  607. //From https://greasyfork.org/scripts/406062
  608. addStyle(`
  609. /*Remove events from image*/
  610. div.thumbnail {
  611. pointer-events: none !important;
  612. ;
  613. }
  614. `);
  615.  
  616. addStyle(`
  617. /*Hide the unlock popup/buttons if it appears*/
  618. #app > div:nth-child(4) > div > div.mask {
  619. display: none !important;
  620. ;
  621. }
  622. `);
  623.  
  624. addStyle(`
  625. /*Hide the unlock popup/buttons if it appears*/
  626. #app > div:nth-child(4) > div.wrapper {
  627. display: none !important;
  628. ;
  629. }
  630. `);
  631.  
  632. //Hide the unlock popup if it appears in another way (e.g. hitting Deep search on a paid account)
  633. //Prevent block-scroll from impacting the body if one hits "Deep search" or any button which causes an overlay
  634. addStyle(`
  635. /*Hide the unlock popup if it appears in another way#1*/
  636. /*Prevent block-scroll from impacting the body if one hits "Deep search" or any button which causes an overlay*/
  637. .block-scroll {
  638. touch-action: auto !important;
  639. -webkit-overflow-scrolling: touch!important;
  640. overflow: visible!important;
  641. -ms-scroll-chaining: none!important;
  642. overscroll-behavior: unset!important;
  643. }
  644. `);
  645.  
  646.  
  647. //Stops the button sizes from changing if one happens to hit the Deep Search button or cause an overlay
  648. addStyle(`
  649. /*Hide the unlock popup if it appears in another way #2*/
  650. /*Stops the button sizes from changing if one happens to hit the Deep Search button or cause an overlay*/
  651. *, :after, :before {
  652. box-sizing: revert !important;
  653. }
  654. `);
  655.  
  656. addStyle(`
  657. /*Hide the Formspring payment request*/
  658. #fscCanvas {
  659. display: none !important;
  660. ;
  661. }
  662. `);
  663.  
  664. addStyle(`
  665. /*Prevent the overlays from blocking scrolling*
  666. body {
  667. overflow: visible !important;
  668. ;
  669. }
  670. `);
  671.  
  672. /*
  673. ** bookmarklet
  674. javascript:(function()%7Beval(function(p%2Ca%2Cc%2Ck%2Ce%2Cr)%7Be%3Dfunction(c)%7Breturn(c%3Ca%3F''%3Ae(parseInt(c%2Fa)))%2B((c%3Dc%25a)%3E35%3FString.fromCharCode(c%2B29)%3Ac.toString(36))%7D%3Bif(!''.replace(%2F%5E%2F%2CString))%7Bwhile(c--)r%5Be(c)%5D%3Dk%5Bc%5D%7C%7Ce(c)%3Bk%3D%5Bfunction(e)%7Breturn%20r%5Be%5D%7D%5D%3Be%3Dfunction()%7Breturn'%5C%5Cw%2B'%7D%3Bc%3D1%7D%3Bwhile(c--)if(k%5Bc%5D)p%3Dp.replace(new%20RegExp('%5C%5Cb'%2Be(c)%2B'%5C%5Cb'%2C'g')%2Ck%5Bc%5D)%3Breturn%20p%7D('b%201q()%7B7.8(%221r%2018%2B%20u%22)%3B5.k(%22%23c%20%3E%203%20%3E%203%20%3E%203.w-Z%20%3E%203%20%3E%203%20%3E%203%20%3E%20g%3A1s-y%22).1t.10(%221u%22%2C%5C'%3Cg%20h-v-m%3D%22%22%201v%3D%22g%22%2011%3D%221w%201x-1y%22%20h-v-1z%3D%22%22%2012%3D%221A%22%3E%3C1B%20h-v-m%3D%22%22%201C%3D%22h%3AH%2F1D%2B1E%3B1F%2C2q%2B2r%2B2s%2B%22%3E%20%3Cf%20h-v-m%3D%22%22%3E2t%202u%3C%2Ff%3E%3C%2Fg%3E%5C')%2C5.13(%221A%22).I(%221G%22%2C1H)%2C7.8(%221I%2018%2B%20u%22)%7Db%201J()%7B7.8(%221r%2014%20u%22)%3B5.k(%22%23c%20%3E%203%20%3E%203%20%3E%203.w-Z%20%3E%203%20%3E%203%20%3E%203%20%3E%20g%3A1s-y%22).1t.10(%221u%22%2C%5C'%3Cg%20h-v-m%3D%22%22%201v%3D%22g%22%2011%3D%221w%201x-1y%22%20h-v-1z%3D%22%22%2012%3D%221K%22%3E%3C1B%20h-v-m%3D%22%22%201C%3D%22h%3AH%2F1D%2B1E%3B1F%2C2v%2B2w%3D%3D%22%3E%20%3Cf%20h-v-m%3D%22%22%3E14%20u%3C%2Ff%3E%3C%2Fg%3E%5C')%2C5.13(%221K%22).I(%221G%22%2C15)%2C7.8(%221I%2014%20u%22)%7Db%201L()%7Bo.1M(0%2C2x)%2Co.1N(0%2C5.J.2y)%7Db%201O()%7Bo.1M(0%2C-2z)%2Co.1N(0%2C0)%7D16%20b%2015()%7B1P(1%3D%3D%3D5.p(%223.c-K%22).z%3Fq%3D1%3A0%3D%3D%3D5.p(%223.c-K%22).z%26%26(q%3D0)%3Bq%3C1%3B)%7B7.8(%221Q%20r%209%202A%2017%209%20c%22)%3B19%20e%3D1%3B2B%7B1L()%2C7.8(%221a%201b%22)%2CA%20B(1c)%2C7.8(%222C%20L%20(%22%2Be%2B%22x)%22)%2Ce%2B%2B%7D2D(0%3D%3D%3D5.p(%223.c-K%22).z)%3B7.8(%222E%20L%22)%2C7.8(%221a%201b%22)%2CA%20B(1c)%2C7.8(%221Q%20r%20w%2017%202F%22)%2C1O()%2C7.8(%222G%202H%209%20w%22)%2C7.8(%221a%201b%22)%2CA%20B(1c)%2Cq%3D1%7D%7Db%20B(e)%7B2I%202J%202K(t%3D%3E2L(t%2Ce))%7Db%201d()%7BC%3D5.p(%22%23c%203.c-1e%203.M%203.s%20f.N-M%22).z%2C7.8(C%2B%22%201R%20N%20c%201f%201S%22)%2C5.13(%221T%22).O%3DC%7Db%201U()%7B7.8(%222M%202N%202O%22)%3B19%20e%3D5.k(%22%23c%20%3E%203%20%3E%203%20%3E%203.w-Z%20%3E%203%20%3E%203%20%3E%20f%20%3E%20f%3A1g-y(2)%22)%2Ct%3D%5C'%3Cf%20h-v-2P%3D%22%22%3E%3C1V%2012%3D%221T%22%3E%5C'%2BC%2B%22%3C%2F1V%3E%201R%20N%20c%201f%201S%3C%2Ff%3E%22%3Be.10(%222Q%22%2Ct)%2C1d()%7Db%201W()%7BI(%22P%22%2Cb()%7B0%3D%3D%3D5.p(%223.c-K%22).z%26%26(1d()%2Cq%3D0)%7D)%7D16%20b%201h()%7B7.8(%222R%20r%201X%22)%2CA%20B(2S)%3B19%20e%3D5.k(%223.1i-1j%203.s%20f.D%22)%3Bj(2T%200!%3D%3De%26%262U!%3De)%7B(e%3D5.k(%223.1i-1j%203.s%20f.D%22)).O%3D%5C'%3Ca%202V%3D%22%5C'%2Be.O%2B%5C'%22%3E%5C'%2Be.O%2B%22%3C%2Fa%3E%22%2Cb(t)%7Bj(t%3De%2C5.J.1Y)%7B1k%20e%3D5.J.1Y()%3Be.2W(t)%2Ce.E()%7D1l%20j(o.1Z)%7B1k%20e%3Do.1Z()%2Cn%3D5.2X()%3Bn.2Y(t)%2Ce.2Z()%2Ce.30(n)%7D1l%207.31(%2232%2020%20E%2033%201m%2034%3A%2035%2036.%22)%7D(%2237%22)%7D1l%207.8(%2238%20r%201X%2039%203a%2017%201h%2021%203b%203c%203d%20F%203e%2020%203f!%22)%7Db%2022()%7B7.8(%223g%20Q%2023%20(3h%203i)%22)%2C5.p(%22%23c%203.c-1e%203.M%203.s%22).3j(b(e)%7Be.k(%22f.N-M%22)%7C%7Ce.3k.24()%7D)%2C7.8(%2225%20Q%2023%22)%7D16%20b%201H()%7B7.8(%223l%209%20Q%2026%22)%2CA%2015()%2C22()%2C7.8(%2225%209%20Q%2026%22)%7Db%20d(e)%7B1k%20t%3D5.3m(%223n%22)%3Bt.3o%3De%2C5.3p.3q(t)%7D1q()%2C1J()%2CC%3D0%2C1U()%2Cq%3D0%2C1W()%2C27%3D5.k(%223.c-1e%22)%2C27.I(%2221%22%2C1h)%2Cd(%22%5C%5Cn%2F*3r-3s%209%2028*%2F%5C%5Cn.3t-3u-D%20%7B%5C%5Cn%20%20%20%2029-E%3A%203v%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%22%5C%5Cn%2F*3w%209%2028%203x%2C%202a%20R*%2F%5C%5Cn%2F*3.1i-1j%3E3.s%3Ef.D*%2F%5C%5Cn*.D%20%7B%5C%5Cn%20%20%20%203y%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%20%20%20%20S%3A%20R%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%20%20%20%2029-E%3A%201n%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%20%20%20%203z-3A%3A%201n%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%20%20%20%202b-1o%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%20%20%20%203B%3A%201n%20!6%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%22%5C%5Cn%2F*T%209%203C%203D%20U%202c%202d*%2F%5C%5Cn.3E%20%7B%5C%5Cn%20%20%20%20l%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%22%5C%5Cn%2F*T%209%20%5C'3F%203G%20r%203H%20c%202a%201p%202e%201P%20%243I.3J%2F3K%20U%202c%202d*%2F%5C%5Cn.3L%20%7B%5C%5Cn%20%20%20%20l%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%22%5C%5Cn%2F*T%209%202f%203M%2C%201f%203N%203O%20E%209%20H*%2F%5C%5Cn.2f%20%7B%5C%5Cn%20%20%20%20l%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%5C'%5C%5Cn%2F*3P-3Q%203R%203S%20g*%2F%5C%5C3T%5B11%3D%223U%22%5D%20%7B%5C%5Cn%20%20%20%20l%3A%203V%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%5C')%2Cd(%22%5C%5Cn%2F*T%201o%20V%20H*%2F%5C%5C3W.s%20%7B%5C%5Cn%20%20%20%202b-1o%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%22%5C%5Cn%2F*G%209%20W%20F%2F2g%20j%20X%20Y*%2F%5C%5Cn%232h%20%3E%203%3A1g-y(4)%20%3E%203%20%3E%203.3X%20%7B%5C%5Cn%20%20%20%20l%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%22%5C%5Cn%2F*G%209%20W%20F%2F2g%20j%20X%20Y*%2F%5C%5Cn%232h%20%3E%203%3A1g-y(4)%20%3E%203.3Y%20%7B%5C%5Cn%20%20%20%20l%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%5C'%5C%5Cn%2F*G%209%20W%20F%20j%20X%20Y%201m%202i%202j%231*%2F%5C%5Cn%2F*2k%202l-P%20V%203Z%209%20J%20j%202m%2040%20%221p%202e%22%202n%2041%20g%2042%2043%202o%20U*%2F%5C%5Cn.2l-P%20%7B%5C%5Cn%20%20%20%202p-44%3A%2045%20!6%3B%5C%5Cn%20%20%20%20-46-S-L%3A%202p!6%3B%5C%5Cn%20%20%20%20S%3A%20R!6%3B%5C%5Cn%20%20%20%20-47-P-48%3A%20i!6%3B%5C%5Cn%20%20%20%2049-4a%3A%204b!6%3B%5C%5Cn%7D%5C%5Cn%5C%5Ct%5C')%2C5.k(%223%5Bh-v-4c%5D%22).24()%2Cd(%22%5C%5Cn%2F*G%209%20W%20F%20j%20X%20Y%201m%202i%202j%20%232*%2F%5C%5Cn%2F*4d%209%20g%204e%20V%204f%20j%202m%204g%20r%204h%209%201p%204i%20g%202n%204j%202o%20U*%2F%5C%5Cn*%2C%20%3A4k%2C%20%3A4l%20%7B%5C%5Cn%20%20%20%204m-4n%3A%204o%20!6%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%22%5C%5Cn%2F*G%209%204p%204q%204r*%2F%5C%5Cn%234s%20%7B%5C%5Cn%20%20%20%20l%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%22%5C%5Cn%2F*2k%209%204t%20V%204u%20L*%5C%5C4v%20%7B%5C%5Cn%20%20%20%20S%3A%20R%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%3B'%2C62%2C280%2C'%7C%7C%7Cdiv%7C%7Cdocument%7Cimportant%7Cconsole%7Clog%7Cthe%7C%7Cfunction%7Cresults%7CaddStyle%7C%7Cspan%7Cbutton%7Cdata%7Cnone%7Cif%7CquerySelector%7Cdisplay%7C4ccff48d%7C%7Cwindow%7CquerySelectorAll%7Cscrolled%7Cto%7Cthumbnail%7C%7CButton%7C%7Ctop%7C%7Cchild%7Clength%7Cawait%7Csleep%7CexplicitCount%7Curl%7Cselect%7Cpopup%7CHide%7Cimage%7CaddEventListener%7Cbody%7Cend%7Cscrolling%7Cresult%7Cexplicit%7CinnerHTML%7Cscroll%7Cremoval%7Cvisible%7Coverflow%7CRemove%7Coverlay%7Cfrom%7Cunlock%7Cit%7Cappears%7Cslot%7CinsertAdjacentHTML%7Cclass%7Cid%7CgetElementById%7CScroll%7Cscroller%7Casync%7Cof%7C%7Cvar%7CSleeping%7C1000ms%7C1e3%7CexpResultsUpdater%7Cgrid%7Cso%7Cnth%7ChighlightUrl%7Cmodal%7Ccontent%7Cconst%7Celse%7Cin%7Cinitial%7Cevents%7CDeep%7CexplicitButts%7CAdding%7Clast%7CparentElement%7Cbeforeend%7Ctype%7Cdefault%7Cicon%7Conly%7C46dbee4d%7C18Button%7Cimg%7Csrc%7Csvg%7Cxml%7Cbase64%7Cclick%7CexplicitJS%7CAdded%7CscrollButts%7CscrollButton%7CscrollDown%7CscrollBy%7CscrollTo%7CscrollUp%7Cfor%7CScrolling%7Cpotentially%7Cfar%7CexpResults%7CexplicitStats%7Cbdi%7CscrollResultsUpdateListener%7Chighlight%7CcreateTextRange%7CgetSelection%7Cnot%7Cmousedown%7CjsRemover%7Cscript%7Cremove%7CFinished%7Cprocess%7CclickThumb%7CURLs%7Cuser%7Cand%7Cpointer%7Con%7Cimages%7Csearch%7Cactions%7Cbuttons%7Capp%7Canother%7Cway%7CPrevent%7Cblock%7Cone%7Cor%7Can%7Ctouch%7CPHN2ZyB2aWV3Qm94PSIwIDAgMzEwLjkgMzEwLjkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI%7CPHBhdGggZD0iTTk1IDIxMS40di04OS4zSDc0LjRWOTkuMmg0OS4xdjExMi4yem0xMzUuNi04My4yYzAgOS44LTUuMyAxOC40LTE0LjEgMjMuMiAxMi4zIDUuMSAyMCAxNS44IDIwIDI4LjMgMCAyMC4yLTE3LjkgMzMtNDUuOSAzM3MtNDUuOS0xMi42LTQ1LjktMzIuNWMwLTEyLjggOC4zLTIzLjcgMjEuMy0yOC44LTkuNC01LjMtMTUuNS0xNC4yLTE1LjUtMjQgMC0xNy45IDE1LjctMjkuMyA0MC0yOS4zIDI0LjUuMSA0MC4xIDExLjcgNDAuMSAzMC4xem0tNTkuMSA0OS4yYzAgOS40IDYuNyAxNC43IDE5IDE0LjdzMTkuMi01LjEgMTkuMi0xNC43YzAtOS4zLTYuOS0xNC42LTE5LjItMTQuNnMtMTkgNS4zLTE5IDE0LjZ6bTIuOS00Ny42YzAgOCA1LjggMTIuNSAxNi4yIDEyLjVzMTYuMi00LjUgMTYuMi0xMi41YzAtOC4zLTUuOC0xMy0xNi4yLTEzLTEwLjUuMS0xNi4yIDQuNy0xNi4yIDEzeiIvPjxwYXRoIGQ9Ik0xNTUuNCAzMTAuOUM2OS43IDMxMC45IDAgMjQxLjEgMCAxNTUuNFM2OS43IDAgMTU1LjQgMGMxMS42IDAgMjMuMiAxLjMgMzQuNSAzLjlWMTVjLTExLjItMi44LTIyLjgtNC4xLTM0LjUtNC4xLTc5LjcgMC0xNDQuNiA2NC45LTE0NC42IDE0NC42czY0LjkgMTQ0LjYgMTQ0LjYgMTQ0LjZTMzAwIDIzNS4yIDMwMCAxNTUuNWMwLTExLjctMS40LTIzLjMtNC4xLTM0LjVIMzA3YzIuNiAxMS4zIDMuOSAyMi44IDMuOSAzNC41IDAgODUuNi02OS44IDE1NS40LTE1NS41IDE1NS40eiIvPjxwYXRoIGQ9Ik0yNzUuNyAzNS4xVjMuNkgyNTN2MzEuNWgtMzEuNHYyMi43SDI1M3YzMS41aDIyLjdWNTcuOGgzMS41VjM1LjF6Ii8%7CPC9zdmc%7CView%7CExplicit%7CPHN2ZyB2aWV3Qm94PSIwIDAgNDkwLjcgNDkwLjciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI%7CPHBhdGggZD0ibTQ3Mi4zIDIxNi41LTIyNy4xIDIyNy4yLTIyNy4xLTIyNy4yYy00LjItNC4xLTExLTQtMTUuMS4zLTQgNC4xLTQgMTAuNyAwIDE0LjhsMjM0LjcgMjM0LjdjNC4yIDQuMiAxMC45IDQuMiAxNS4xIDBsMjM0LjctMjM0LjdjNC4xLTQuMiA0LTExLS4zLTE1LjEtNC4yLTQtMTAuNy00LTE0LjkgMHoiIGZpbGw9IiM2MDdkOGIiLz48cGF0aCBkPSJtNDcyLjMgMjQuNS0yMjcuMSAyMjcuMi0yMjcuMS0yMjcuMmMtNC4yLTQuMS0xMS00LTE1LjEuMy00IDQuMS00IDEwLjcgMCAxNC44bDIzNC43IDIzNC43YzQuMiA0LjIgMTAuOSA0LjIgMTUuMSAwbDIzNC42LTIzNC43YzQuMi00LjEgNC40LTEwLjguMy0xNS4xLTQuMS00LjItMTAuOC00LjQtMTUuMS0uMy0uMS4yLS4yLjItLjMuM3oiIGZpbGw9IiM2MDdkOGIiLz48cGF0aCBkPSJtMjQ1LjIgNDY5LjRjLTIuOCAwLTUuNS0xLjEtNy42LTMuMWwtMjM0LjYtMjM0LjdjLTQuMS00LjItNC0xMSAuMy0xNS4xIDQuMS00IDEwLjctNCAxNC44IDBsMjI3LjEgMjI3LjEgMjI3LjEtMjI3LjFjNC4yLTQuMSAxMS00IDE1LjEuMyA0IDQuMSA0IDEwLjcgMCAxNC44bC0yMzQuNyAyMzQuN2MtMiAyLTQuNyAzLjEtNy41IDMuMXoiLz48cGF0aCBkPSJtMjQ1LjIgMjc3LjRjLTIuOCAwLTUuNS0xLjEtNy42LTMuMWwtMjM0LjYtMjM0LjdjLTQuMS00LjItNC0xMSAuMy0xNS4xIDQuMS00IDEwLjctNCAxNC44IDBsMjI3LjEgMjI3LjEgMjI3LjEtMjI3LjFjNC4xLTQuMiAxMC44LTQuNCAxNS4xLS4zczQuNCAxMC44LjMgMTUuMWMtLjEuMS0uMi4yLS4zLjNsLTIzNC43IDIzNC43Yy0yIDItNC43IDMuMS03LjUgMy4xeiIvPjwvc3ZnPg%7C1e4%7CscrollHeight%7C5e4%7Cbottom%7Cdo%7CStill%7Cwhile%7CDone%7Cpage%7CWe%7Creached%7Creturn%7Cnew%7CPromise%7CsetTimeout%7CInserting%7CStats%7CCounter%7C26e5f418%7Cbeforebegin%7CWaiting%7C200%7Cvoid%7Cnull%7Chref%7CmoveToElementText%7CcreateRange%7CselectNodeContents%7CremoveAllRanges%7CaddRange%7Cwarn%7CCould%7Ctext%7Cnode%7CUnsupported%7Cbrowser%7CspanUrl%7CTried%7CURL%7Cbecause%7Cevent%7Clistener%7Cbut%7Cdoes%7Cexist%7CRunning%7CPure%7CJavaScript%7CforEach%7CparentNode%7CStarting%7CcreateElement%7Cstyle%7CtextContent%7Chead%7Cappend%7CUn%7Cblur%7Cblurred%7Csource%7Call%7CMake%7Cselectable%7Cfilter%7Cmax%7Cwidth%7Cposition%7CBuy%7CPremium%7Czoom%7CGet%7Caccess%7Carchival%7C299%7C99%7Cmo%7Cpromo%7Cmenu%7Cwe%7Ccan%7Cun%7Chide%7Cadd%7Cpicture%7Cnbutton%7Cspacer%7Cinherit%7Cndiv%7Cmask%7Cwrapper%7Cimpacting%7Chits%7Cany%7Cwhich%7Ccauses%7Caction%7Cauto%7Cwebkit%7Cms%7Cchaining%7Coverscroll%7Cbehavior%7Cunset%7C69882821%7CStops%7Csizes%7Cchanging%7Chappens%7Chit%7CSearch%7Ccause%7Cafter%7Cbefore%7Cbox%7Csizing%7Crevert%7CFormspring%7Cpayment%7Crequest%7CfscCanvas%7Coverlays%7Cblocking%7Cnbody'.split('%7C')%2C0%2C%7B%7D))%7D)()%3B
  675. */