├── README.md
├── WhichFaceIsRealScoreKeeper
├── README.md
└── WhichFaceIsRealScoreKeeper.user.js
├── amazonReviewWall
├── README.md
├── amazonReviewWall.user.js
├── amazonReviewWallNewTab.user.js
├── amzn
└── images
│ ├── amazonReviewWall.gif
│ ├── amazonReviewWall.png
│ └── amazonReviewWall_small.png
├── githubForkz
├── README.md
├── githubForkz.user.js
└── showActivity.js
├── other
└── ignmf.js
└── pimeyesJS
├── README.md
└── pimeyesJS.user.js
/README.md:
--------------------------------------------------------------------------------
1 | # usefulUserScripts
2 | pimeyes.js: Mods to make pimeyes.com work better for both premium and free users
3 | amazonReviewWall: Mods to make Amazon show a zoomable review wall
4 |
--------------------------------------------------------------------------------
/WhichFaceIsRealScoreKeeper/README.md:
--------------------------------------------------------------------------------
1 | Test your human identification skills! This script keeps a rudimentary score for you on [whichfaceisreal.com](whichfaceisreal.com) since they don't have that built in.
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/WhichFaceIsRealScoreKeeper/WhichFaceIsRealScoreKeeper.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name WhichFaceIsReal Score Keeper
3 | // @namespace Violentmonkey Scripts
4 | // @namespace2 https://github.com/deltabravozulu/usefulUserScripts
5 | // @updateURL https://github.com/deltabravozulu/usefulUserScripts/raw/main/WhichFaceIsRealScoreKeeper/WhichFaceIsRealScoreKeeper.user.js
6 | // @match *://www.whichfaceisreal.com/*
7 | // @grant none
8 | // @version 4.20.69
9 | // @author DeltaBravoZulu
10 | // @description Test your human identification skills! This script keeps score for you on whichfaceisreal.com since they don't have that built in
11 | // @description 2/18/2022, 1:23:53 PM
12 | // @run-at document-idle
13 | // @license PayMe
14 | // ==/UserScript==
15 |
16 | // Make sure page loads before starting
17 | new MutationObserver(check).observe(document, {
18 | childList: true,
19 | subtree: true
20 | })
21 |
22 | function check (changes, observer) {
23 | if (
24 | document.querySelector('#bs-example-navbar-collapse-1 > ul > li:nth-child(6)')
25 | ) {
26 | observer.disconnect()
27 | doIt()
28 | }
29 | }
30 |
31 | function doIt () {
32 | let cor = 0
33 | let incor = 0
34 | let correct; let corElement = document.querySelector('html>body>div>div>div>p')
35 | if (corElement != null) {
36 | correct = document.querySelector('html>body>div>div>div>p').textContent.includes('You are correct')
37 | } else {
38 | correct === false
39 | }
40 | let incorrect; let incorElement = document.querySelector('html>body>div>div>div>p')
41 | if (incorElement != null) {
42 | incorrect = document.querySelector('html>body>div>div>div>p').textContent.includes('You are incorrect')
43 | } else {
44 | incorrect === false
45 | }
46 |
47 | function corScore () {
48 | // Get Item from LocalStorage or correctCount === 0
49 | let correctCount = parseInt(localStorage.getItem('correctCount'), 10) || parseInt(0, 10)
50 |
51 | if (typeof correct !== 'undefined') {
52 | if (correct === true) {
53 | cor += 1
54 | }
55 | }
56 | if (cor > 0) {
57 | // Set the score to the users' current points
58 | correctCount = parseInt(correctCount, 10) + parseInt(cor, 10)
59 | // Store the score
60 | localStorage.setItem('correctCount', parseInt(correctCount, 10))
61 | }
62 |
63 | // Return the high score
64 | return correctCount
65 | }
66 |
67 | function incorScore () {
68 | // Get Item from LocalStorage or incorrectCount === 0
69 | let incorrectCount = parseInt(localStorage.getItem('incorrectCount'), 10) || parseInt(0, 10)
70 |
71 | if (incorrect === true) { incor += 1 }
72 | if (incor > 0) {
73 | // Set the score to the users' current points
74 | incorrectCount = parseInt(incorrectCount, 10) + parseInt(incor, 10)
75 | // Store the score
76 | localStorage.setItem('incorrectCount', parseInt(incorrectCount, 10))
77 | }
78 |
79 | // Return the high score
80 | return incorrectCount
81 | }
82 |
83 | function getScore () {
84 | let currentCorScore = parseInt(localStorage.getItem('correctCount'), 10)
85 | let currentInCorScore = parseInt(localStorage.getItem('incorrectCount'), 10)
86 |
87 | function nukeScore () {
88 | localStorage.setItem('correctCount', 0)
89 | localStorage.setItem('incorrectCount', 0)
90 | document.querySelector('#inject').remove()
91 | getScore()
92 | }
93 | console.log('Correct: ' + currentCorScore)
94 | console.log('Incorrect: ' + currentInCorScore)
95 | htmlInject = '
'
96 | document.querySelector('body > nav').insertAdjacentHTML('afterend', htmlInject)
97 | scoreInject = ' Correct: ' + currentCorScore + ' Incorrect: ' + currentInCorScore + ''
98 | document.querySelector('#inject').insertAdjacentHTML('afterbegin', scoreInject)
99 | buttonInject = ''
100 | document.querySelector('#score').insertAdjacentHTML('afterend', buttonInject)
101 | document.getElementById('resetter').addEventListener('click', nukeScore)
102 | }
103 | corScore()
104 | incorScore()
105 | getScore()
106 | }
107 |
--------------------------------------------------------------------------------
/amazonReviewWall/README.md:
--------------------------------------------------------------------------------
1 |
2 | Mods to make Amazon show an image wall of user reviews
3 |
4 |
5 | - Adds a button which will open all review images in a zoomable review wall
6 | - Clicking on review image in wall will zoom in on high resolution photo
7 | - Pressing
[space]
, r
, or ⬆
will open the review in a new tab (when zoomed)
8 | - Pressing
p
or ⬇
will open the reviewer's profile in a new tab (when zoomed)
9 | - Todo: make it open in a new tab and/or add a method to return to original page without a refresh
10 |
11 |
12 |
13 | This is a UserScript written for Violent Monkey but should work on other UserScript extensions as well
14 |
15 | Installation:
16 | Open amazonReviewWall.user.js
17 |
18 |
19 |
--------------------------------------------------------------------------------
/amazonReviewWall/amazonReviewWall.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name amazonReviewWall
3 | // @namespace https://github.com/deltabravozulu/usefulUserScripts
4 | // @version 420.69.2022-05-12T14:28:42
5 | // @author DeltaBravoZulu
6 | // @description View Amazon review images in a zoomable wall
7 | // @homepage https://github.com/deltabravozulu/usefulUserScripts/tree/main/amazonReviewWall
8 | // @icon https://raw.githubusercontent.com/deltabravozulu/usefulUserScripts/main/amazonReviewWall/images/amazonReviewWall_small.png
9 | // @icon64 https://raw.githubusercontent.com/deltabravozulu/usefulUserScripts/main/amazonReviewWall/images/amazonReviewWall_small.png
10 | // @updateURL https://raw.githubusercontent.com/deltabravozulu/usefulUserScripts/main/amazonReviewWall/amazonReviewWall.user.js
11 | // @downloadURL https://raw.githubusercontent.com/deltabravozulu/usefulUserScripts/main/amazonReviewWall/amazonReviewWall.user.js
12 | // @supportURL https://github.com/deltabravozulu/usefulUserScripts
13 | // @include /^https?:\/\/(www|smile)\.amazon\.(cn|in|co\.jp|sg|ae|fr|de|it|nl|es|co\.uk|ca|com(\.(mx|au|br|tr))?)\/.*(dp|gp\/(product|video)|exec\/obidos\/ASIN|o\/ASIN)\/.*$/
14 | // @grant GM_setValue
15 | // @grant GM_getValue
16 | // @grant window.close
17 | // @grant window.focus
18 | // @run-at document-idle
19 | // @license PayMe
20 | // ==/UserScript==
21 | ///////////////////////////////////////
22 | // Amazon Review Photowall //
23 | ///////////////////////////////////////
24 | /*
25 | ** Makes a zoomable photo wall from Amazon review pictures
26 | */
27 | async function theStuff() {
28 | function sleep(ms) {
29 | return new Promise((resolve) => setTimeout(resolve, ms));
30 | }
31 | function appendHTML() {
32 | var wrapper = document.createElement("body");
33 | wrapper.innerHTML =
34 | '\
35 | \
89 | \
90 | ';
91 | document.appendChild(wrapper);
92 | }
93 | await sleep(1000);
94 | //https://stackoverflow.com/a/58316317/8398127
95 | function getChunks(selector, strStart, strEnd) {
96 | const html = document.querySelector(selector).innerHTML;
97 | const start = html.indexOf(strStart);
98 | const end = html.indexOf(strEnd, start);
99 | if (start == -1 || end == -1) return;
100 | return {
101 | before: html.substr(0, start),
102 | match: html.substr(start, end - start + strEnd.length),
103 | after: html.substr(end + strEnd.length, html.length - end),
104 | };
105 | }
106 | let chunkSelector = "#reviews-image-gallery-container > script";
107 | let chunkStart = "data, ";
108 | let chunkEnd = '");';
109 | chunks = getChunks(chunkSelector, chunkStart, chunkEnd).match;
110 | dataAndCSRF = chunks
111 | .replaceAll(");", "")
112 | .replaceAll('"', "")
113 | .replaceAll(" ", "");
114 | dataAndCSRFArray = dataAndCSRF.split(",");
115 | data = dataAndCSRFArray[1];
116 | firstReviewIds = dataAndCSRFArray[3];
117 | asin = data;
118 | csrfToken = firstReviewIds;
119 | let text = "";
120 | let date = new Date().toISOString();
121 | function AppendToLocalStorage(name, value) {
122 | let n = 0;
123 | while (localStorage.getItem(name + "-" + n)) {
124 | n++;
125 | }
126 | localStorage.setItem(name + "-" + n, value); //add item at first available index number
127 | }
128 | function GetLocalStorage(name) {
129 | let n = 0;
130 | let data = [];
131 | while (localStorage.getItem(name + "-" + n)) {
132 | data.push(localStorage.getItem(name + "-" + n++));
133 | }
134 | return data;
135 | }
136 | function AppendToGMStorage(name, value) {
137 | let n = 0;
138 | while (GM_getValue(name + "-" + n, "")) {
139 | n++;
140 | }
141 | GM_setValue(name + "-" + n, value); //add item at first available index number
142 | }
143 | function GetGMStorage(name) {
144 | let n = 0;
145 | let data = [];
146 | while (GM_getValue(name + "-" + n, "")) {
147 | data.push(GM_getValue(name + "-" + n++));
148 | }
149 | return data;
150 | }
151 | //https://www.amazon.com/hz/reviews-render/get-reviews-with-media?mediaType=image&asin=B08DKK2KD1&csrfToken=guMT%2B0nYuIuyIIE6DbwfM0%2BcGnpEsbBr8SAKSRIAAAABAAAAAGJ5vEhyYXcAAAAA%2B4kUEk%2F7iMGR3xPcX6iU
152 | function loadReviews() {
153 | url =
154 | "https://www.amazon.com/hz/reviews-render/get-reviews-with-media?mediaType=image&asin=" +
155 | asin +
156 | "&csrfToken=" +
157 | csrfToken;
158 | function getJSON(url) {
159 | var resp;
160 | var xmlHttp;
161 | resp = "";
162 | xmlHttp = new XMLHttpRequest();
163 | if (xmlHttp != null) {
164 | xmlHttp.open("GET", url, false);
165 | xmlHttp.send(null);
166 | resp = xmlHttp.responseText;
167 | }
168 | return resp;
169 | }
170 | jsonGot = getJSON(url);
171 | jsonParsed = JSON.parse(jsonGot);
172 | //need to keep doing this until all pages are hit
173 | csrfToken = jsonParsed.csrfToken;
174 | reviews = jsonParsed.reviewsWithMediaList;
175 | reviewKeys = Object.keys(reviews);
176 | reviewCount = reviewKeys.length;
177 | for (var r = 0; r < reviewCount; r++) {
178 | reviewKey = reviewKeys[r];
179 | review = reviews[reviewKey];
180 | //console.log(review)
181 | reviewId = review.reviewId;
182 | reviewUrl =
183 | "https://www.amazon.com/gp/customer-reviews/" + reviewId;
184 | profileUrl = "https://www.amazon.com" + review.customerProfileLink;
185 | AppendToGMStorage(asin, profileUrl);
186 | AppendToLocalStorage(asin, profileUrl);
187 | for (var j = 0; j < review.images.length; j++) {
188 | imgUrl = review.images[j].source;
189 | text +=
190 | '
';
197 | console.log(
198 | "imgUrl: " +
199 | imgUrl +
200 | ", reviewUrl: " +
201 | reviewUrl +
202 | ", profileUrl: " +
203 | profileUrl
204 | );
205 | //console.log(csrfToken)
206 | }
207 | }
208 | }
209 | loadReviews();
210 | await sleep(3000);
211 | var newDoc = document.open("text/html", "replace");
212 | appendHTML();
213 | await sleep(1000);
214 | document.getElementById("zoomwall").innerHTML = text;
215 | await sleep(1000);
216 | var zoomwall = {
217 | create: function (blocks, enableKeys) {
218 | zoomwall.resize(blocks.children);
219 | blocks.classList.remove("loading");
220 | // shrink blocks if an empty space is clicked
221 | blocks.addEventListener("click", function () {
222 | if (this.children && this.children.length > 0) {
223 | zoomwall.shrink(this.children[0]);
224 | }
225 | });
226 | // add click listeners to blocks
227 | for (var i = 0; i < blocks.children.length; i++) {
228 | blocks.children[i].addEventListener("click", zoomwall.animate);
229 | }
230 | // add key down listener
231 | if (enableKeys) {
232 | var keyPager = function (event) {
233 | which = event.which;
234 | keyCode = event.keyCode;
235 | shiftKey = event.shiftKey;
236 | altKey = event.altKey;
237 | ctrlKey = event.ctrlKey;
238 | metaKey = event.metaKey;
239 | key = event.key;
240 | defaultPrevented = event.defaultPrevented;
241 | //[prevent key codes from working when shift,alt,ctrl,cmd,windows,super,etc. keys are working ]
242 | if (
243 | defaultPrevented ||
244 | shiftKey ||
245 | altKey ||
246 | ctrlKey ||
247 | metaKey
248 | ) {
249 | console.log(key);
250 | return;
251 | }
252 | //[ESC] = zoom out
253 | else if (keyCode === 27) {
254 | console.log(key);
255 | if (blocks.children && blocks.children.length > 0) {
256 | zoomwall.shrink(blocks.children[0]);
257 | }
258 | event.preventDefault();
259 | }
260 | //[⬅] = previous
261 | else if (keyCode === 37) {
262 | console.log(key);
263 | zoomwall.page(blocks, false);
264 | event.preventDefault();
265 | }
266 | //[➡] = next
267 | else if (keyCode === 39) {
268 | console.log(key);
269 | zoomwall.page(blocks, true);
270 | event.preventDefault();
271 | }
272 | //[space]||[⬆]||[r] = open review
273 | else if (
274 | keyCode === 32 ||
275 | keyCode === 38 ||
276 | keyCode === 82
277 | ) {
278 | console.log(key);
279 | zoomwall.reviewUrl(blocks);
280 | event.preventDefault();
281 | }
282 | //[⬇]||[p] = open profile
283 | else if (keyCode === 40 || keyCode === 80) {
284 | console.log(key);
285 | zoomwall.profileUrl(blocks);
286 | event.preventDefault();
287 | } else {
288 | console.log(key);
289 | return;
290 | }
291 | };
292 | document.addEventListener("keydown", keyPager);
293 | }
294 | },
295 | resizeRow: function (row, width) {
296 | if (row && row.length > 1) {
297 | for (var i in row) {
298 | row[i].style.width =
299 | (parseInt(window.getComputedStyle(row[i]).width, 10) /
300 | width) *
301 | 100 +
302 | "%";
303 | row[i].style.height = "auto";
304 | }
305 | }
306 | },
307 | calcRowWidth: function (row) {
308 | var width = 0;
309 | for (var i in row) {
310 | width += parseInt(window.getComputedStyle(row[i]).width, 10);
311 | }
312 | return width;
313 | },
314 | resize: function (blocks) {
315 | var row = [];
316 | var top = -1;
317 | for (var c = 0; c < blocks.length; c++) {
318 | var block = blocks[c];
319 | if (block) {
320 | if (top == -1) {
321 | top = block.offsetTop;
322 | } else if (block.offsetTop != top) {
323 | zoomwall.resizeRow(row, zoomwall.calcRowWidth(row));
324 | row = [];
325 | top = block.offsetTop;
326 | }
327 | row.push(block);
328 | }
329 | }
330 | zoomwall.resizeRow(row, zoomwall.calcRowWidth(row));
331 | },
332 | reset: function (block) {
333 | block.style.transform = "translate(0, 0) scale(1)";
334 | block.style.webkitTransform = "translate(0, 0) scale(1)";
335 | block.classList.remove("active");
336 | },
337 | shrink: function (block) {
338 | block.parentNode.classList.remove("lightbox");
339 | // reset all blocks
340 | zoomwall.reset(block);
341 | var prev = block.previousElementSibling;
342 | while (prev) {
343 | zoomwall.reset(prev);
344 | prev = prev.previousElementSibling;
345 | }
346 | var next = block.nextElementSibling;
347 | while (next) {
348 | zoomwall.reset(next);
349 | next = next.nextElementSibling;
350 | }
351 | // swap images
352 | if (block.dataset.lowres) {
353 | block.src = block.dataset.lowres;
354 | }
355 | },
356 | expand: function (block) {
357 | block.classList.add("active");
358 | block.parentNode.classList.add("lightbox");
359 | // parent dimensions
360 | var parentStyle = window.getComputedStyle(block.parentNode);
361 | var parentWidth = parseInt(parentStyle.width, 10);
362 | var parentHeight = parseInt(parentStyle.height, 10);
363 | var parentTop = block.parentNode.getBoundingClientRect().top;
364 | // block dimensions
365 | var blockStyle = window.getComputedStyle(block);
366 | var blockWidth = parseInt(blockStyle.width, 10);
367 | var blockHeight = parseInt(blockStyle.height, 10);
368 | // determine maximum height
369 | var targetHeight = window.innerHeight;
370 | if (parentHeight < window.innerHeight) {
371 | targetHeight = parentHeight;
372 | } else if (parentTop > 0) {
373 | targetHeight -= parentTop;
374 | }
375 | // swap images
376 | if (block.dataset.highres) {
377 | if (
378 | block.src != block.dataset.highres &&
379 | block.dataset.lowres === undefined
380 | ) {
381 | block.dataset.lowres = block.src;
382 | }
383 | block.src = block.dataset.highres;
384 | }
385 | // determine what blocks are on this row
386 | var row = [];
387 | row.push(block);
388 | var next = block.nextElementSibling;
389 | while (next && next.offsetTop == block.offsetTop) {
390 | row.push(next);
391 | next = next.nextElementSibling;
392 | }
393 | var prev = block.previousElementSibling;
394 | while (prev && prev.offsetTop == block.offsetTop) {
395 | row.unshift(prev);
396 | prev = prev.previousElementSibling;
397 | }
398 | // calculate scale
399 | var scale = targetHeight / blockHeight;
400 | if (blockWidth * scale > parentWidth) {
401 | scale = parentWidth / blockWidth;
402 | }
403 | // determine offset
404 | var offsetY =
405 | parentTop - block.parentNode.offsetTop + block.offsetTop;
406 | if (offsetY > 0) {
407 | if (parentHeight < window.innerHeight) {
408 | offsetY -= targetHeight / 2 - (blockHeight * scale) / 2;
409 | }
410 | if (parentTop > 0) {
411 | offsetY -= parentTop;
412 | }
413 | }
414 | var leftOffsetX = 0; // shift in current row
415 | for (var i = 0; i < row.length && row[i] != block; i++) {
416 | leftOffsetX +=
417 | parseInt(window.getComputedStyle(row[i]).width, 10) * scale;
418 | }
419 | leftOffsetX =
420 | parentWidth / 2 - (blockWidth * scale) / 2 - leftOffsetX;
421 | var rightOffsetX = 0; // shift in current row
422 | for (var i = row.length - 1; i >= 0 && row[i] != block; i--) {
423 | rightOffsetX +=
424 | parseInt(window.getComputedStyle(row[i]).width, 10) * scale;
425 | }
426 | rightOffsetX =
427 | parentWidth / 2 - (blockWidth * scale) / 2 - rightOffsetX;
428 | // transform current row
429 | var itemOffset = 0; // offset due to scaling of previous items
430 | var prevWidth = 0;
431 | for (var i = 0; i < row.length; i++) {
432 | itemOffset += prevWidth * scale - prevWidth;
433 | prevWidth = parseInt(window.getComputedStyle(row[i]).width, 10);
434 | var percentageOffsetX =
435 | ((itemOffset + leftOffsetX) / prevWidth) * 100;
436 | var percentageOffsetY =
437 | (-offsetY /
438 | parseInt(window.getComputedStyle(row[i]).height, 10)) *
439 | 100;
440 | row[i].style.transformOrigin = "0% 0%";
441 | row[i].style.webkitTransformOrigin = "0% 0%";
442 | row[i].style.transform =
443 | "translate(" +
444 | percentageOffsetX.toFixed(8) +
445 | "%, " +
446 | percentageOffsetY.toFixed(8) +
447 | "%) scale(" +
448 | scale.toFixed(8) +
449 | ")";
450 | row[i].style.webkitTransform =
451 | "translate(" +
452 | percentageOffsetX.toFixed(8) +
453 | "%, " +
454 | percentageOffsetY.toFixed(8) +
455 | "%) scale(" +
456 | scale.toFixed(8) +
457 | ")";
458 | }
459 | // transform items after
460 | var nextOffsetY = blockHeight * (scale - 1) - offsetY;
461 | var prevHeight;
462 | itemOffset = 0; // offset due to scaling of previous items
463 | prevWidth = 0;
464 | var next = row[row.length - 1].nextElementSibling;
465 | var nextRowTop = -1;
466 | while (next) {
467 | var curTop = next.offsetTop;
468 | if (curTop == nextRowTop) {
469 | itemOffset += prevWidth * scale - prevWidth;
470 | } else {
471 | if (nextRowTop != -1) {
472 | itemOffset = 0;
473 | nextOffsetY += prevHeight * (scale - 1);
474 | }
475 | nextRowTop = curTop;
476 | }
477 | prevWidth = parseInt(window.getComputedStyle(next).width, 10);
478 | prevHeight = parseInt(window.getComputedStyle(next).height, 10);
479 | var percentageOffsetX =
480 | ((itemOffset + leftOffsetX) / prevWidth) * 100;
481 | var percentageOffsetY = (nextOffsetY / prevHeight) * 100;
482 | next.style.transformOrigin = "0% 0%";
483 | next.style.webkitTransformOrigin = "0% 0%";
484 | next.style.transform =
485 | "translate(" +
486 | percentageOffsetX.toFixed(8) +
487 | "%, " +
488 | percentageOffsetY.toFixed(8) +
489 | "%) scale(" +
490 | scale.toFixed(8) +
491 | ")";
492 | next.style.webkitTransform =
493 | "translate(" +
494 | percentageOffsetX.toFixed(8) +
495 | "%, " +
496 | percentageOffsetY.toFixed(8) +
497 | "%) scale(" +
498 | scale.toFixed(8) +
499 | ")";
500 | next = next.nextElementSibling;
501 | }
502 | // transform items before
503 | var prevOffsetY = -offsetY;
504 | itemOffset = 0; // offset due to scaling of previous items
505 | prevWidth = 0;
506 | var prev = row[0].previousElementSibling;
507 | var prevRowTop = -1;
508 | while (prev) {
509 | var curTop = prev.offsetTop;
510 | if (curTop == prevRowTop) {
511 | itemOffset -= prevWidth * scale - prevWidth;
512 | } else {
513 | itemOffset = 0;
514 | prevOffsetY -=
515 | parseInt(window.getComputedStyle(prev).height, 10) *
516 | (scale - 1);
517 | prevRowTop = curTop;
518 | }
519 | prevWidth = parseInt(window.getComputedStyle(prev).width, 10);
520 | var percentageOffsetX =
521 | ((itemOffset - rightOffsetX) / prevWidth) * 100;
522 | var percentageOffsetY =
523 | (prevOffsetY /
524 | parseInt(window.getComputedStyle(prev).height, 10)) *
525 | 100;
526 | prev.style.transformOrigin = "100% 0%";
527 | prev.style.webkitTransformOrigin = "100% 0%";
528 | prev.style.transform =
529 | "translate(" +
530 | percentageOffsetX.toFixed(8) +
531 | "%, " +
532 | percentageOffsetY.toFixed(8) +
533 | "%) scale(" +
534 | scale.toFixed(8) +
535 | ")";
536 | prev.style.webkitTransform =
537 | "translate(" +
538 | percentageOffsetX.toFixed(8) +
539 | "%, " +
540 | percentageOffsetY.toFixed(8) +
541 | "%) scale(" +
542 | scale.toFixed(8) +
543 | ")";
544 | prev = prev.previousElementSibling;
545 | }
546 | },
547 | animate: function (e) {
548 | if (this.classList.contains("active")) {
549 | zoomwall.shrink(this);
550 | } else {
551 | var actives = this.parentNode.getElementsByClassName("active");
552 | for (var i = 0; i < actives.length; i++) {
553 | actives[i].classList.remove("active");
554 | }
555 | zoomwall.expand(this);
556 | }
557 | e.stopPropagation();
558 | },
559 | reviewUrl: function (blocks) {
560 | var actives = blocks.getElementsByClassName("active");
561 | if (actives && actives.length > 0) {
562 | var current = actives[0];
563 | }
564 | window.open(current.attributes.reviewurl.value, "_blank").blur();
565 | self.focus();
566 | },
567 | profileUrl: function (blocks) {
568 | var actives = blocks.getElementsByClassName("active");
569 | if (actives && actives.length > 0) {
570 | var current = actives[0];
571 | }
572 | window.open(current.attributes.profileurl.value, "_blank").blur();
573 | self.focus();
574 | },
575 | page: function (blocks, isNext) {
576 | var actives = blocks.getElementsByClassName("active");
577 | if (actives && actives.length > 0) {
578 | var current = actives[0];
579 | var next;
580 | if (isNext) {
581 | next = current.nextElementSibling;
582 | } else {
583 | next = current.previousElementSibling;
584 | }
585 | if (next) {
586 | current.classList.remove("active");
587 | // swap images
588 | if (current.dataset.lowres) {
589 | current.src = current.dataset.lowres;
590 | }
591 | zoomwall.expand(next);
592 | }
593 | }
594 | },
595 | };
596 | await sleep(1000);
597 | zoomwall.create(document.getElementById("zoomwall"), true);
598 | await sleep(1000);
599 | newDoc.close();
600 | }
601 | ///////////////////////////////////////
602 | // Button Injections //
603 | ///////////////////////////////////////
604 | /*
605 | ** Adds button to process start
606 | */
607 | function addButts() {
608 | console.log("Adding Button");
609 | var oldButtons = document.querySelector("#productTitle");
610 | var newButtons = oldButtons.parentElement;
611 | var iconHtml =
612 | '';
613 | newButtons.insertAdjacentHTML("beforeend", iconHtml);
614 | document
615 | .getElementById("ImageWallButton")
616 | .addEventListener("click", theStuff);
617 | console.log("Added Button");
618 | }
619 | addButts();
620 |
--------------------------------------------------------------------------------
/amazonReviewWall/amazonReviewWallNewTab.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name amazonReviewWallNewTab
3 | // @namespace https://github.com/deltabravozulu/usefulUserScripts
4 | // @version 420.69.2022-05-12T15:13:40
5 | // @author DeltaBravoZulu
6 | // @description View Amazon review images in a zoomable wall
7 | // @homepage https://github.com/deltabravozulu/usefulUserScripts/tree/main/amazonReviewWall
8 | // @icon https://raw.githubusercontent.com/deltabravozulu/usefulUserScripts/main/amazonReviewWall/images/amazonReviewWall_small.png
9 | // @icon64 https://raw.githubusercontent.com/deltabravozulu/usefulUserScripts/main/amazonReviewWall/images/amazonReviewWall_small.png
10 | // @updateURL https://raw.githubusercontent.com/deltabravozulu/usefulUserScripts/main/amazonReviewWall/amazonReviewWallNewTab.user.js
11 | // @downloadURL https://raw.githubusercontent.com/deltabravozulu/usefulUserScripts/main/amazonReviewWall/amazonReviewWallNewTab.user.js
12 | // @supportURL https://github.com/deltabravozulu/usefulUserScripts
13 | // @include /^https?:\/\/(www|smile)\.amazon\.(cn|in|co\.jp|sg|ae|fr|de|it|nl|es|co\.uk|ca|com(\.(mx|au|br|tr))?)\/.*(dp|gp\/(product|video)|exec\/obidos\/ASIN|o\/ASIN)\/.*$/
14 | // @grant GM_setValue
15 | // @grant GM_getValue
16 | // @grant window.close
17 | // @grant window.focus
18 | // @run-at document-idle
19 | // @license PayMe
20 | // ==/UserScript==
21 | ///////////////////////////////////////
22 | // Amazon Review Photowall //
23 | ///////////////////////////////////////
24 | /*
25 | ** Makes a zoomable photo wall from Amazon review pictures
26 | */
27 | async function theStuff() {
28 | function sleep(ms) {
29 | return new Promise((resolve) => setTimeout(resolve, ms));
30 | }
31 | function appendHTML() {
32 | var wrapper = newWindow.document.createElement("body");
33 | wrapper.innerHTML =
34 | '\
35 | \
89 | \
90 | ';
91 | newWindow.document.appendChild(wrapper);
92 | }
93 | await sleep(1000);
94 | //https://stackoverflow.com/a/58316317/8398127
95 | function getChunks(selector, strStart, strEnd) {
96 | const html = document.querySelector(selector).innerHTML;
97 | const start = html.indexOf(strStart);
98 | const end = html.indexOf(strEnd, start);
99 | if (start == -1 || end == -1) return;
100 | return {
101 | before: html.substr(0, start),
102 | match: html.substr(start, end - start + strEnd.length),
103 | after: html.substr(end + strEnd.length, html.length - end),
104 | };
105 | }
106 | let chunkSelector = "#reviews-image-gallery-container > script";
107 | let chunkStart = "data, ";
108 | let chunkEnd = '");';
109 | chunks = getChunks(chunkSelector, chunkStart, chunkEnd).match;
110 | dataAndCSRF = chunks
111 | .replaceAll(");", "")
112 | .replaceAll('"', "")
113 | .replaceAll(" ", "");
114 | dataAndCSRFArray = dataAndCSRF.split(",");
115 | data = dataAndCSRFArray[1];
116 | firstReviewIds = dataAndCSRFArray[3];
117 | asin = data;
118 | csrfToken = firstReviewIds;
119 | let text = "";
120 | let date = new Date().toISOString();
121 | function AppendToLocalStorage(name, value) {
122 | let n = 0;
123 | while (localStorage.getItem(name + "-" + n)) {
124 | n++;
125 | }
126 | localStorage.setItem(name + "-" + n, value); //add item at first available index number
127 | }
128 | function GetLocalStorage(name) {
129 | let n = 0;
130 | let data = [];
131 | while (localStorage.getItem(name + "-" + n)) {
132 | data.push(localStorage.getItem(name + "-" + n++));
133 | }
134 | return data;
135 | }
136 | function AppendToGMStorage(name, value) {
137 | let n = 0;
138 | while (GM_getValue(name + "-" + n, "")) {
139 | n++;
140 | }
141 | GM_setValue(name + "-" + n, value); //add item at first available index number
142 | }
143 | function GetGMStorage(name) {
144 | let n = 0;
145 | let data = [];
146 | while (GM_getValue(name + "-" + n, "")) {
147 | data.push(GM_getValue(name + "-" + n++));
148 | }
149 | return data;
150 | }
151 | //https://www.amazon.com/hz/reviews-render/get-reviews-with-media?mediaType=image&asin=B08DKK2KD1&csrfToken=guMT%2B0nYuIuyIIE6DbwfM0%2BcGnpEsbBr8SAKSRIAAAABAAAAAGJ5vEhyYXcAAAAA%2B4kUEk%2F7iMGR3xPcX6iU
152 | function loadReviews() {
153 | url =
154 | "https://www.amazon.com/hz/reviews-render/get-reviews-with-media?mediaType=image&asin=" +
155 | asin +
156 | "&csrfToken=" +
157 | csrfToken;
158 | function getJSON(url) {
159 | var resp;
160 | var xmlHttp;
161 | resp = "";
162 | xmlHttp = new XMLHttpRequest();
163 | if (xmlHttp != null) {
164 | xmlHttp.open("GET", url, false);
165 | xmlHttp.send(null);
166 | resp = xmlHttp.responseText;
167 | }
168 | return resp;
169 | }
170 | jsonGot = getJSON(url);
171 | jsonParsed = JSON.parse(jsonGot);
172 | //need to keep doing this until all pages are hit
173 | csrfToken = jsonParsed.csrfToken;
174 | reviews = jsonParsed.reviewsWithMediaList;
175 | reviewKeys = Object.keys(reviews);
176 | reviewCount = reviewKeys.length;
177 | for (var r = 0; r < reviewCount; r++) {
178 | reviewKey = reviewKeys[r];
179 | review = reviews[reviewKey];
180 | //console.log(review)
181 | reviewId = review.reviewId;
182 | reviewUrl =
183 | "https://www.amazon.com/gp/customer-reviews/" + reviewId;
184 | profileUrl = "https://www.amazon.com" + review.customerProfileLink;
185 | AppendToGMStorage(asin, profileUrl);
186 | AppendToLocalStorage(asin, profileUrl);
187 | for (var j = 0; j < review.images.length; j++) {
188 | imgUrl = review.images[j].source;
189 | text +=
190 | '
';
197 | console.log(
198 | "imgUrl: " +
199 | imgUrl +
200 | ", reviewUrl: " +
201 | reviewUrl +
202 | ", profileUrl: " +
203 | profileUrl
204 | );
205 | //console.log(csrfToken)
206 | }
207 | }
208 | }
209 | loadReviews();
210 | await sleep(3000);
211 | var newWindow = window.open();
212 | newWindow.document.body.innerHTML = 'howdy';
213 | var newDoc = newWindow.document.open("text/html", "replace");
214 | appendHTML();
215 | await sleep(1000);
216 | newWindow.document.getElementById("zoomwall").innerHTML = text;
217 | await sleep(1000);
218 | var zoomwall = {
219 | create: function (blocks, enableKeys) {
220 | zoomwall.resize(blocks.children);
221 | blocks.classList.remove("loading");
222 | // shrink blocks if an empty space is clicked
223 | blocks.addEventListener("click", function () {
224 | if (this.children && this.children.length > 0) {
225 | zoomwall.shrink(this.children[0]);
226 | }
227 | });
228 | // add click listeners to blocks
229 | for (var i = 0; i < blocks.children.length; i++) {
230 | blocks.children[i].addEventListener("click", zoomwall.animate);
231 | }
232 | // add key down listener
233 | if (enableKeys) {
234 | var keyPager = function (event) {
235 | which = event.which;
236 | keyCode = event.keyCode;
237 | shiftKey = event.shiftKey;
238 | altKey = event.altKey;
239 | ctrlKey = event.ctrlKey;
240 | metaKey = event.metaKey;
241 | key = event.key;
242 | defaultPrevented = event.defaultPrevented;
243 | //[prevent key codes from working when shift,alt,ctrl,cmd,windows,super,etc. keys are working ]
244 | if (
245 | defaultPrevented ||
246 | shiftKey ||
247 | altKey ||
248 | ctrlKey ||
249 | metaKey
250 | ) {
251 | console.log(key);
252 | return;
253 | }
254 | //[ESC] = zoom out
255 | else if (keyCode === 27) {
256 | console.log(key);
257 | if (blocks.children && blocks.children.length > 0) {
258 | zoomwall.shrink(blocks.children[0]);
259 | }
260 | event.preventDefault();
261 | }
262 | //[⬅] = previous
263 | else if (keyCode === 37) {
264 | console.log(key);
265 | zoomwall.page(blocks, false);
266 | event.preventDefault();
267 | }
268 | //[➡] = next
269 | else if (keyCode === 39) {
270 | console.log(key);
271 | zoomwall.page(blocks, true);
272 | event.preventDefault();
273 | }
274 | //[space]||[⬆]||[r] = open review
275 | else if (
276 | keyCode === 32 ||
277 | keyCode === 38 ||
278 | keyCode === 82
279 | ) {
280 | console.log(key);
281 | zoomwall.reviewUrl(blocks);
282 | event.preventDefault();
283 | }
284 | //[⬇]||[p] = open profile
285 | else if (keyCode === 40 || keyCode === 80) {
286 | console.log(key);
287 | zoomwall.profileUrl(blocks);
288 | event.preventDefault();
289 | } else {
290 | console.log(key);
291 | return;
292 | }
293 | };
294 | newWindow.document.addEventListener("keydown", keyPager);
295 | }
296 | },
297 | resizeRow: function (row, width) {
298 | if (row && row.length > 1) {
299 | for (var i in row) {
300 | row[i].style.width =
301 | (parseInt(window.getComputedStyle(row[i]).width, 10) /
302 | width) *
303 | 100 +
304 | "%";
305 | row[i].style.height = "auto";
306 | }
307 | }
308 | },
309 | calcRowWidth: function (row) {
310 | var width = 0;
311 | for (var i in row) {
312 | width += parseInt(window.getComputedStyle(row[i]).width, 10);
313 | }
314 | return width;
315 | },
316 | resize: function (blocks) {
317 | var row = [];
318 | var top = -1;
319 | for (var c = 0; c < blocks.length; c++) {
320 | var block = blocks[c];
321 | if (block) {
322 | if (top == -1) {
323 | top = block.offsetTop;
324 | } else if (block.offsetTop != top) {
325 | zoomwall.resizeRow(row, zoomwall.calcRowWidth(row));
326 | row = [];
327 | top = block.offsetTop;
328 | }
329 | row.push(block);
330 | }
331 | }
332 | zoomwall.resizeRow(row, zoomwall.calcRowWidth(row));
333 | },
334 | reset: function (block) {
335 | block.style.transform = "translate(0, 0) scale(1)";
336 | block.style.webkitTransform = "translate(0, 0) scale(1)";
337 | block.classList.remove("active");
338 | },
339 | shrink: function (block) {
340 | block.parentNode.classList.remove("lightbox");
341 | // reset all blocks
342 | zoomwall.reset(block);
343 | var prev = block.previousElementSibling;
344 | while (prev) {
345 | zoomwall.reset(prev);
346 | prev = prev.previousElementSibling;
347 | }
348 | var next = block.nextElementSibling;
349 | while (next) {
350 | zoomwall.reset(next);
351 | next = next.nextElementSibling;
352 | }
353 | // swap images
354 | if (block.dataset.lowres) {
355 | block.src = block.dataset.lowres;
356 | }
357 | },
358 | expand: function (block) {
359 | block.classList.add("active");
360 | block.parentNode.classList.add("lightbox");
361 | // parent dimensions
362 | var parentStyle = newWindow.getComputedStyle(block.parentNode);
363 | var parentWidth = parseInt(parentStyle.width, 10);
364 | var parentHeight = parseInt(parentStyle.height, 10);
365 | var parentTop = block.parentNode.getBoundingClientRect().top;
366 | // block dimensions
367 | var blockStyle = newWindow.getComputedStyle(block);
368 | var blockWidth = parseInt(blockStyle.width, 10);
369 | var blockHeight = parseInt(blockStyle.height, 10);
370 | // determine maximum height
371 | var targetHeight = newWindow.innerHeight;
372 | if (parentHeight < newWindow.innerHeight) {
373 | targetHeight = parentHeight;
374 | } else if (parentTop > 0) {
375 | targetHeight -= parentTop;
376 | }
377 | // swap images
378 | if (block.dataset.highres) {
379 | if (
380 | block.src != block.dataset.highres &&
381 | block.dataset.lowres === undefined
382 | ) {
383 | block.dataset.lowres = block.src;
384 | }
385 | block.src = block.dataset.highres;
386 | }
387 | // determine what blocks are on this row
388 | var row = [];
389 | row.push(block);
390 | var next = block.nextElementSibling;
391 | while (next && next.offsetTop == block.offsetTop) {
392 | row.push(next);
393 | next = next.nextElementSibling;
394 | }
395 | var prev = block.previousElementSibling;
396 | while (prev && prev.offsetTop == block.offsetTop) {
397 | row.unshift(prev);
398 | prev = prev.previousElementSibling;
399 | }
400 | // calculate scale
401 | var scale = targetHeight / blockHeight;
402 | if (blockWidth * scale > parentWidth) {
403 | scale = parentWidth / blockWidth;
404 | }
405 | // determine offset
406 | var offsetY =
407 | parentTop - block.parentNode.offsetTop + block.offsetTop;
408 | if (offsetY > 0) {
409 | if (parentHeight < newWindow.innerHeight) {
410 | offsetY -= targetHeight / 2 - (blockHeight * scale) / 2;
411 | }
412 | if (parentTop > 0) {
413 | offsetY -= parentTop;
414 | }
415 | }
416 | var leftOffsetX = 0; // shift in current row
417 | for (var i = 0; i < row.length && row[i] != block; i++) {
418 | leftOffsetX +=
419 | parseInt(window.getComputedStyle(row[i]).width, 10) * scale;
420 | }
421 | leftOffsetX =
422 | parentWidth / 2 - (blockWidth * scale) / 2 - leftOffsetX;
423 | var rightOffsetX = 0; // shift in current row
424 | for (var i = row.length - 1; i >= 0 && row[i] != block; i--) {
425 | rightOffsetX +=
426 | parseInt(window.getComputedStyle(row[i]).width, 10) * scale;
427 | }
428 | rightOffsetX =
429 | parentWidth / 2 - (blockWidth * scale) / 2 - rightOffsetX;
430 | // transform current row
431 | var itemOffset = 0; // offset due to scaling of previous items
432 | var prevWidth = 0;
433 | for (var i = 0; i < row.length; i++) {
434 | itemOffset += prevWidth * scale - prevWidth;
435 | prevWidth = parseInt(window.getComputedStyle(row[i]).width, 10);
436 | var percentageOffsetX =
437 | ((itemOffset + leftOffsetX) / prevWidth) * 100;
438 | var percentageOffsetY =
439 | (-offsetY /
440 | parseInt(window.getComputedStyle(row[i]).height, 10)) *
441 | 100;
442 | row[i].style.transformOrigin = "0% 0%";
443 | row[i].style.webkitTransformOrigin = "0% 0%";
444 | row[i].style.transform =
445 | "translate(" +
446 | percentageOffsetX.toFixed(8) +
447 | "%, " +
448 | percentageOffsetY.toFixed(8) +
449 | "%) scale(" +
450 | scale.toFixed(8) +
451 | ")";
452 | row[i].style.webkitTransform =
453 | "translate(" +
454 | percentageOffsetX.toFixed(8) +
455 | "%, " +
456 | percentageOffsetY.toFixed(8) +
457 | "%) scale(" +
458 | scale.toFixed(8) +
459 | ")";
460 | }
461 | // transform items after
462 | var nextOffsetY = blockHeight * (scale - 1) - offsetY;
463 | var prevHeight;
464 | itemOffset = 0; // offset due to scaling of previous items
465 | prevWidth = 0;
466 | var next = row[row.length - 1].nextElementSibling;
467 | var nextRowTop = -1;
468 | while (next) {
469 | var curTop = next.offsetTop;
470 | if (curTop == nextRowTop) {
471 | itemOffset += prevWidth * scale - prevWidth;
472 | } else {
473 | if (nextRowTop != -1) {
474 | itemOffset = 0;
475 | nextOffsetY += prevHeight * (scale - 1);
476 | }
477 | nextRowTop = curTop;
478 | }
479 | prevWidth = parseInt(window.getComputedStyle(next).width, 10);
480 | prevHeight = parseInt(window.getComputedStyle(next).height, 10);
481 | var percentageOffsetX =
482 | ((itemOffset + leftOffsetX) / prevWidth) * 100;
483 | var percentageOffsetY = (nextOffsetY / prevHeight) * 100;
484 | next.style.transformOrigin = "0% 0%";
485 | next.style.webkitTransformOrigin = "0% 0%";
486 | next.style.transform =
487 | "translate(" +
488 | percentageOffsetX.toFixed(8) +
489 | "%, " +
490 | percentageOffsetY.toFixed(8) +
491 | "%) scale(" +
492 | scale.toFixed(8) +
493 | ")";
494 | next.style.webkitTransform =
495 | "translate(" +
496 | percentageOffsetX.toFixed(8) +
497 | "%, " +
498 | percentageOffsetY.toFixed(8) +
499 | "%) scale(" +
500 | scale.toFixed(8) +
501 | ")";
502 | next = next.nextElementSibling;
503 | }
504 | // transform items before
505 | var prevOffsetY = -offsetY;
506 | itemOffset = 0; // offset due to scaling of previous items
507 | prevWidth = 0;
508 | var prev = row[0].previousElementSibling;
509 | var prevRowTop = -1;
510 | while (prev) {
511 | var curTop = prev.offsetTop;
512 | if (curTop == prevRowTop) {
513 | itemOffset -= prevWidth * scale - prevWidth;
514 | } else {
515 | itemOffset = 0;
516 | prevOffsetY -=
517 | parseInt(window.getComputedStyle(prev).height, 10) *
518 | (scale - 1);
519 | prevRowTop = curTop;
520 | }
521 | prevWidth = parseInt(window.getComputedStyle(prev).width, 10);
522 | var percentageOffsetX =
523 | ((itemOffset - rightOffsetX) / prevWidth) * 100;
524 | var percentageOffsetY =
525 | (prevOffsetY /
526 | parseInt(window.getComputedStyle(prev).height, 10)) *
527 | 100;
528 | prev.style.transformOrigin = "100% 0%";
529 | prev.style.webkitTransformOrigin = "100% 0%";
530 | prev.style.transform =
531 | "translate(" +
532 | percentageOffsetX.toFixed(8) +
533 | "%, " +
534 | percentageOffsetY.toFixed(8) +
535 | "%) scale(" +
536 | scale.toFixed(8) +
537 | ")";
538 | prev.style.webkitTransform =
539 | "translate(" +
540 | percentageOffsetX.toFixed(8) +
541 | "%, " +
542 | percentageOffsetY.toFixed(8) +
543 | "%) scale(" +
544 | scale.toFixed(8) +
545 | ")";
546 | prev = prev.previousElementSibling;
547 | }
548 | },
549 | animate: function (e) {
550 | if (this.classList.contains("active")) {
551 | zoomwall.shrink(this);
552 | } else {
553 | var actives = this.parentNode.getElementsByClassName("active");
554 | for (var i = 0; i < actives.length; i++) {
555 | actives[i].classList.remove("active");
556 | }
557 | zoomwall.expand(this);
558 | }
559 | e.stopPropagation();
560 | },
561 | reviewUrl: function (blocks) {
562 | var actives = blocks.getElementsByClassName("active");
563 | if (actives && actives.length > 0) {
564 | var current = actives[0];
565 | }
566 | window.open(current.attributes.reviewurl.value, "_blank").blur();
567 | newWindow.focus();
568 | },
569 | profileUrl: function (blocks) {
570 | var actives = blocks.getElementsByClassName("active");
571 | if (actives && actives.length > 0) {
572 | var current = actives[0];
573 | }
574 | window.open(current.attributes.profileurl.value, "_blank").blur();
575 | newWindow.focus();
576 | },
577 | page: function (blocks, isNext) {
578 | var actives = blocks.getElementsByClassName("active");
579 | if (actives && actives.length > 0) {
580 | var current = actives[0];
581 | var next;
582 | if (isNext) {
583 | next = current.nextElementSibling;
584 | } else {
585 | next = current.previousElementSibling;
586 | }
587 | if (next) {
588 | current.classList.remove("active");
589 | // swap images
590 | if (current.dataset.lowres) {
591 | current.src = current.dataset.lowres;
592 | }
593 | zoomwall.expand(next);
594 | }
595 | }
596 | },
597 | };
598 | await sleep(1000);
599 | zoomwall.create(newWindow.document.getElementById("zoomwall"), true);
600 | await sleep(1000);
601 | newDoc.close();
602 | }
603 | ///////////////////////////////////////
604 | // Button Injections //
605 | ///////////////////////////////////////
606 | /*
607 | ** Adds button to process start
608 | */
609 | function addButts() {
610 | console.log("Adding Button");
611 | var oldButtons = document.querySelector("#productTitle");
612 | var newButtons = oldButtons.parentElement;
613 | var iconHtml =
614 | '';
615 | newButtons.insertAdjacentHTML("beforeend", iconHtml);
616 | document
617 | .getElementById("ImageWallButton")
618 | .addEventListener("click", theStuff);
619 | console.log("Added Button");
620 | }
621 | addButts();
622 |
--------------------------------------------------------------------------------
/amazonReviewWall/amzn:
--------------------------------------------------------------------------------
1 | //https://stackoverflow.com/a/58316317/8398127
2 | function getChunks(selector, strStart, strEnd) {
3 | const html = document.querySelector(selector).innerHTML;
4 | const start = html.indexOf(strStart);
5 | const end = html.indexOf(strEnd, start);
6 |
7 | if (start == -1 || end == -1) return;
8 |
9 | return {
10 | before: html.substr(0, start),
11 | match: html.substr(start, end - start + strEnd.length),
12 | after: html.substr(end + strEnd.length, html.length - end)
13 | };
14 | }
15 |
16 | //document.documentElement.innerHTML.search('imagePopoverController.loadDataAndInitImageGalleryPopover')
17 | let chunkSelector = '#reviews-image-gallery-container > script'
18 | let chunkStart = 'data, '
19 | let chunkEnd = '");'
20 |
21 | chunks = getChunks(chunkSelector, chunkStart, chunkEnd).match
22 | dataAndCSRF = chunks.replaceAll(');', '').replaceAll('"', '').replaceAll(' ', '')
23 | dataAndCSRFArray = dataAndCSRF.split(',')
24 | data = dataAndCSRFArray[1]
25 | firstReviewIds = dataAndCSRFArray[3]
26 | asin = data
27 | csrfToken = firstReviewIds
28 |
29 |
30 | //https://www.amazon.com/hz/reviews-render/get-reviews-with-media?mediaType=image&asin=B08DKK2KD1&csrfToken=guMT%2B0nYuIuyIIE6DbwfM0%2BcGnpEsbBr8SAKSRIAAAABAAAAAGJ5vEhyYXcAAAAA%2B4kUEk%2F7iMGR3xPcX6iU
31 |
32 | function loadReviews() {
33 |
34 | url = 'https://www.amazon.com/hz/reviews-render/get-reviews-with-media?mediaType=image&asin=' + asin + '&csrfToken=' + csrfToken
35 |
36 |
37 | function getJSON(url) {
38 | var resp;
39 | var xmlHttp;
40 |
41 | resp = '';
42 | xmlHttp = new XMLHttpRequest();
43 |
44 | if (xmlHttp != null) {
45 | xmlHttp.open("GET", url, false);
46 | xmlHttp.send(null);
47 | resp = xmlHttp.responseText;
48 | }
49 |
50 | return resp;
51 | }
52 |
53 | jsonGot = getJSON(url)
54 | jsonParsed = JSON.parse(jsonGot)
55 |
56 | //need to keep doing this until all pages are hit
57 | csrfToken = jsonParsed.csrfToken
58 | reviews = jsonParsed.reviewsWithMediaList
59 |
60 | reviewKeys = Object.keys(reviews)
61 | reviewCount = reviewKeys.length
62 |
63 | for (var r = 0; r < reviewCount; r++) {
64 | reviewKey = reviewKeys[r]
65 | review = reviews[reviewKey];
66 | //console.log(review)
67 | reviewId = review.reviewId
68 | review_url = 'https://www.amazon.com/gp/customer-reviews/' + reviewId
69 | profile = 'https://www.amazon.com' + review.customerProfileLink
70 | for (var j = 0; j < review.images.length; j++) {
71 | imgurl = review.images[j].source
72 | console.log(imgurl)
73 | //console.log(csrfToken)
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/amazonReviewWall/images/amazonReviewWall.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deltabravozulu/usefulUserScripts/c3428d24fa50184479d453bf6d37f62ed3095c5a/amazonReviewWall/images/amazonReviewWall.gif
--------------------------------------------------------------------------------
/amazonReviewWall/images/amazonReviewWall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deltabravozulu/usefulUserScripts/c3428d24fa50184479d453bf6d37f62ed3095c5a/amazonReviewWall/images/amazonReviewWall.png
--------------------------------------------------------------------------------
/amazonReviewWall/images/amazonReviewWall_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deltabravozulu/usefulUserScripts/c3428d24fa50184479d453bf6d37f62ed3095c5a/amazonReviewWall/images/amazonReviewWall_small.png
--------------------------------------------------------------------------------
/githubForkz/README.md:
--------------------------------------------------------------------------------
1 | Adds a button beside "Fork", which opens a new tab to find "Active Forks" and "Useful Forks", both websites which show cool derivatives of the current github repository you are viewing.
2 |
3 |
4 | Known Issues: This userscript might screw up with random buttons like "Sponsor". Let me know if it does.
5 |
6 |
7 |
--------------------------------------------------------------------------------
/githubForkz/githubForkz.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name githubForkz
3 | // @namespace https://github.com/deltabravozulu/usefulUserScripts
4 | // @match *://github.com/*/*
5 | // @updateURL https://github.com/deltabravozulu/usefulUserScripts/raw/main/githubForkz/githubForkz.user.js
6 | // @grant none
7 | // @version 4.20.69.2022-05-09T22:04:20
8 | // @author DeltaBravoZulu
9 | // @icon data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2012.172%2015.766%22%3E%3Cpath%20d%3D%22M6.562%201.04a1.412%201.412%200%200%200-1.448%201.369v.071a1.384%201.384%200%200%200%20.76%201.266c.115%201.584-.7%201.96-2.469%202.613-.39.145-.788.294-1.186.469V2.741a1.387%201.387%200%200%200%20.731-1.249V1.48A1.41%201.41%200%200%200%202.486.413a1.5%201.5%200%200%200-.984-.362A1.41%201.41%200%200%200%20.051%201.418v.074a1.378%201.378%200%200%200%20.732%201.249v5.638a4.016%204.016%200%200%200%200%20.676v.3a1.386%201.386%200%200%200-.732%201.251v.011a1.409%201.409%200%200%200%201.389%201.434h.061a1.411%201.411%200%200%200%201.45-1.369v-.071a1.408%201.408%200%200%200-.466-1.067%201.357%201.357%200%200%200-.255-.173c0-.118%200-.239-.01-.353v-.562a.281.281%200%200%201%20.008-.031%2013.068%2013.068%200%200%201%201.679-.716c1.673-.621%203.558-1.321%203.406-4a1.388%201.388%200%200%200%20.7-1.234v-.004A1.41%201.41%200%200%200%206.624%201.04zm-5.85.444a.748.748%200%200%201%20.726-.77h.064a.748.748%200%200%201%20.785.71v.06a.749.749%200%200%201-.725.772h-.06a.75.75%200%200%201-.787-.711.62.62%200%200%201%200-.061zm1.573%209.132a.748.748%200%200%201-.724.771h-.059a.771.771%200%200%201-.05-1.542h.05a.75.75%200%200%201%20.785.712l.001.059zm4.277-7.371a.75.75%200%200%201-.786-.71v-.061a.749.749%200%200%201%20.727-.771h.059a.751.751%200%200%201%20.786.711v.06a.749.749%200%200%201-.726.771z%22%20fill%3D%22%2357a5c4%22%20stroke%3D%22%23000%22%20stroke-miterlimit%3D%2210%22%20stroke-width%3D%220.1px%22%2F%3E%3Cpath%20d%3D%22M10.716%2012.909a1.4%201.4%200%200%200-1.369%201.086%203.963%203.963%200%200%201-.911-.338%201.061%201.061%200%200%201-.245-.18.866.866%200%200%201-.123-.159q-.021-.034-.039-.069a2.054%202.054%200%200%201-.146-.358c-.054-.181-.093-.382-.132-.577l-.02-.1a4.708%204.708%200%200%200-.109-.436%202.156%202.156%200%200%200-.174-.422%201.65%201.65%200%200%200-.145-.218%201.787%201.787%200%200%200-.63-.5%201.773%201.773%200%200%200%20.63-.5%201.182%201.182%200%200%200%20.08-.11c.025-.038.039-.073.065-.106a2.152%202.152%200%200%200%20.18-.422%204.407%204.407%200%200%200%20.109-.429l.02-.1c.039-.2.078-.4.132-.577a1.912%201.912%200%200%201%20.146-.357.789.789%200%200%201%20.033-.066.827.827%200%200%201%20.123-.158%201.037%201.037%200%200%201%20.245-.181%203.911%203.911%200%200%201%20.918-.339%201.4%201.4%200%201%200-.029-.525%204.435%204.435%200%200%200-1.139.411%201.529%201.529%200%200%200-.368.276%201.471%201.471%200%200%200-.192.245l-.053.094a2.444%202.444%200%200%200-.184.453c-.06.2-.1.416-.143.622l-.02.1c-.028.135-.06.266-.1.389a1.708%201.708%200%200%201-.138.32.881.881%200%200%201-.047.077c-.016.025-.034.05-.052.074a1.5%201.5%200%200%201-.9.49l-.182.021H2.875a1.394%201.394%200%201%200-.014.6h2.952l.179.021a1.5%201.5%200%200%201%20.895.49c.019.023.036.049.052.072s.033.053.047.078a1.636%201.636%200%200%201%20.138.322c.037.123.069.253.1.389l.02.1c.04.207.083.421.143.623a2.4%202.4%200%200%200%20.187.457l.052.094a1.51%201.51%200%200%200%20.193.251%201.529%201.529%200%200%200%20.368.276%204.548%204.548%200%200%200%201.142.412%201.4%201.4%200%201%200%201.39-1.61zm0-6.836a.879.879%200%201%201-.883.879.879.879%200%200%201%20.883-.881zm-9.22%205.416a.879.879%200%201%201%20.885-.879.879.879%200%200%201-.885.879zm9.22%203.695a.88.88%200%201%201%20.884-.88.88.88%200%200%201-.884.88z%22%20fill%3D%22%23c0799a%22%20stroke%3D%22%23000%22%20stroke-miterlimit%3D%2210%22%20stroke-width%3D%220.1px%22%2F%3E%3C%2Fsvg%3E
10 | // @description Adds a button to find active and useful forks on Github
11 | // @run-at document-idle
12 | // @license PayMe
13 | // ==/UserScript==
14 | (function() {
15 | 'use strict';
16 |
17 | try {
18 | let ulActions = Array.from(document.querySelectorAll('#repository-container-header > div.d-flex.mb-3.px-3.px-md-4.px-lg-5 >ul > li')).find(el => el.textContent.match( 'Fork')).querySelector('span').parentNode.parentNode;
19 | if (ulActions !== undefined) {
20 | let findActiveFork = document.location.pathname.substr(1).split('/');
21 | findActiveFork = 'https://techgaun.github.io/active-forks/index.html#' + findActiveFork[0] + '/' + findActiveFork[1];
22 | let findUsefulFork = document.location.pathname.substr(1).split('/');
23 | findUsefulFork = 'https://useful-forks.github.io/?repo=' + findUsefulFork[0] + '/' + findUsefulFork[1];
24 | let forkFinder=Array.from(document.querySelectorAll('#repository-container-header > div.d-flex.mb-3.px-3.px-md-4.px-lg-5 >ul > li')).find(el => el.textContent.match( 'Fork')).querySelector('span').parentNode;
25 | forkFinder.classList.add("btn-with-count")
26 | ulActions.innerHTML = ulActions.innerHTML + `
27 |
28 |
47 | `;
48 | }
49 | } catch (e) {
50 | console.log(e);
51 | }
52 | })();
53 |
--------------------------------------------------------------------------------
/githubForkz/showActivity.js:
--------------------------------------------------------------------------------
1 | function sleep(ms) {
2 | return new Promise(resolve => setTimeout(resolve, ms));
3 | }
4 |
5 | async function viewAllActivity() {
6 | while ( document.querySelector('#js-contribution-activity > form > button') !== null) {
7 | document.querySelector('#js-contribution-activity > form > button').click();
8 | await sleep(1);
9 | }
10 | }
11 |
12 |
13 | yearList=document.getElementsByClassName('js-year-link')[0].parentElement.parentElement
14 | allYears=`\n \n View all
\n \n `
15 | yearList.innerHTML=allYears+yearList.innerHTML
16 | function click() {alert('hi')}
17 | document.getElementById('year-link-all').addEventListener("click",viewAllActivity)
18 |
--------------------------------------------------------------------------------
/pimeyesJS/README.md:
--------------------------------------------------------------------------------
1 |
2 | Mods to make pimeyes.com work better for both premium and free users†
3 |
4 |
5 | - Adds a button for autoscrolling to the bottom of the results
6 | - Adds a 18+ button which will autoscroll to the bottom and remove normal photos for fast filtering
7 | - Reveals the graph query url, which you can use to combine multiple image sets together (e.g. if you use Search By Image)
8 | - Adds a copy button to export the open graph ID and can import it in another pimeyes tab to unify image search results
9 | - Adds highlighted copyable url to popup
10 | - Removes upsell popups and parts of the page
11 | - Counts explicit results
12 | - Other stuff
13 |
14 | This is a UserScript written for Violent Monkey but should work on other extensions as well
15 | † Probably not anymore—Pimeyes has shut down good free searching :(
16 |
--------------------------------------------------------------------------------
/pimeyesJS/pimeyesJS.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name pimeyesJS
3 | // @namespace https://github.com/deltabravozulu/usefulUserScripts
4 | // @match *://pimeyes.com/en/search/*
5 | // @updateURL https://github.com/deltabravozulu/usefulUserScripts/raw/main/pimeyesJS/pimeyesJS.user.js
6 | // @grant none
7 | // @version 9.6.9_420.11
8 | // @icon https://pimeyes.com/favicon.ico
9 | // @author DeltaBravoZulu
10 | // @description Mods to make pimeyes.com work better for both premium and free users
11 | // @description 2022-05-09T18:04:20
12 | // @require https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js
13 | // @run-at document-idle
14 | // @license PayMe
15 | // ==/UserScript==
16 | ///////////////////////////////////////////////////////////////////////////////////
17 | ///////////////////////////////////////////////////////////////////////////////////
18 | //// A script to allow automatic image loading, page improvements via CSS, ////
19 | //// explicit result isolation, and other neat stuff on pimeyes.com ////
20 | //// by DeltaBravoZulu ////
21 | ///////////////////////////////////////////////////////////////////////////////////
22 | ///////////////////////////////////////////////////////////////////////////////////
23 |
24 | ///////////////////////////////////////
25 | // Script Initialization //
26 | ///////////////////////////////////////
27 | /*
28 | ** Invokes injection of buttons
29 | ** Sets initial variables and gathers stats
30 | */
31 |
32 | //Make sure page loads before starting
33 | new MutationObserver(check).observe(document, {
34 | childList: true,
35 | subtree: true,
36 | });
37 |
38 | function check(changes, observer) {
39 | if (
40 | document.querySelector(
41 | "#results > div > div > div.top-slot > div > div > div > button:nth-child(5) > img"
42 | )
43 | ) {
44 | observer.disconnect();
45 | explicitButts();
46 | scrollButts();
47 | importButts();
48 | exportButts();
49 | explicitCount = 0;
50 | explicitStats();
51 | scrolled = 0;
52 | //Gets the Open Graph url which was removed in June
53 | var ogUrl=document.querySelectorAll('meta[property="og:url"]')[0].content.replace('https://pimeyes.com/en','')
54 | //Adds the URL to the URL bar so you can copypaste it
55 | var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + ogUrl;
56 | window.history.pushState({path:newurl},'',newurl);
57 | //Adds scroll explicit counter
58 | scrollResultsUpdateListener();
59 | //Adds mousedown event listener to highlight text during popup for copying
60 | clickThumb = document.querySelector("div.results-grid");
61 | clickThumb.addEventListener("mousedown", highlightUrl);
62 | //Removes the 'Pay 299/month' overlay if hitting the Deep Search button
63 | document.querySelector("div[data-v-69882821]").remove();
64 | //Makes rows wider and shows images better
65 | //This is broken//document.querySelector("div.results-grid").style.width="90";
66 | document.querySelector("div.results-grid").style.minWidth="60%";
67 | document.querySelector("div.results-grid").style.maxWidth="100%";
68 | document.querySelector("div.results-grid").style.gridTemplateColumns = "repeat(5,20%)";
69 | document.querySelector("div.results-grid").style.gridAutoRows = "auto";
70 |
71 | }
72 | }
73 |
74 | //Alternative way of doing it
75 | /*
76 | var observer = new MutationObserver(resetTimer);
77 | var timer = setTimeout(action, 2000, observer); // wait for the page to stay still for 2 seconds
78 | observer.observe(document, {childList: true, subtree: true});
79 | function resetTimer(changes, observer) {
80 | clearTimeout(timer);
81 | timer = setTimeout(action, 2000, observer);
82 | }
83 |
84 | function action(o) {
85 | o.disconnect();
86 | observer.disconnect();
87 | explicitButts();
88 | scrollButts();
89 | explicitCount = 0;
90 | explicitStats();
91 | scrolled = 0;
92 | scrollResultsUpdateListener();
93 | }
94 | */
95 |
96 | ///////////////////////////////////////
97 | // Button Injections //
98 | ///////////////////////////////////////
99 | /*
100 | ** Adds buttons to invoke scrolling and removal
101 | ** Sets initial variable and gathers stats
102 | */
103 |
104 | //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
105 | function explicitButts() {
106 | console.log("Adding 18+ Button");
107 | var oldButtons = document.querySelector(
108 | "#results > div > div > div.top-slot > div > div > div > button:last-child"
109 | );
110 | var explicitButtons = oldButtons.parentElement;
111 | var iconHtml =
112 | '';
113 | explicitButtons.insertAdjacentHTML("beforeend", iconHtml);
114 | document.getElementById("18Button").addEventListener("click", explicitJS);
115 | console.log("Added 18+ Button");
116 | }
117 |
118 | //Injects a scroll button which will allow one to load all images on the page automatically
119 | function scrollButts() {
120 | console.log("Adding Scroll Button");
121 | var oldButtons = document.querySelector(
122 | "#results > div > div > div.top-slot > div > div > div > button:last-child"
123 | );
124 | var scrollButton = oldButtons.parentElement;
125 | var scrollIconHtml =
126 | '';
127 | scrollButton.insertAdjacentHTML("beforeend", scrollIconHtml);
128 | document.getElementById("scrollButton").addEventListener("click", betterScroller);
129 | console.log("Added Scroll Button");
130 | }
131 |
132 | //Injects a button that, when pressed, will copy the Open Graph index to the clipboard
133 | function exportButts() {
134 | console.log("Adding OG URL Export Button");
135 | var oldButtons = document.querySelector(
136 | "#results > div > div > div.top-slot > div > div > div > button:last-child"
137 | );
138 | var exportButton = oldButtons.parentElement;
139 | var exportIconHtml =
140 | '';
141 | scrollButton.insertAdjacentHTML("afterend", exportIconHtml);
142 | document.getElementById("exportButton").addEventListener("click", exporter);
143 | console.log("Added Export Button");
144 | }
145 |
146 | //Injects a button that, when pressed, will paste the Open Graph index from the clipboard to the URL bar
147 | function importButts() {
148 | console.log("Adding OG URL Import Button");
149 | var oldButtons = document.querySelector(
150 | "#results > div > div > div.top-slot > div > div > div > button:last-child"
151 | );
152 | var importButton = oldButtons.parentElement;
153 | var importIconHtml =
154 | '';
155 | scrollButton.insertAdjacentHTML("afterend", importIconHtml);
156 | document.getElementById("importButton").addEventListener("click", importer);
157 | console.log("Added Import Button");
158 | }
159 |
160 |
161 | ///////////////////////////////////////
162 | // Export/Import OpenGraph Url //
163 | ///////////////////////////////////////
164 | /*
165 | ** Includes a scroller to load the page, stats, and sleep timers
166 | */
167 |
168 | //Copies the open graph url to the clipboard
169 |
170 | ogUrl=document.querySelectorAll('meta[property="og:url"]')[0].content.replace('https://pimeyes.com/en','')
171 | ogUrlCut=ogUrl.substring(0, ogUrl.lastIndexOf('?')).replace('/search/','')
172 |
173 | function exporter() {
174 | executeCopy = function() {
175 | var copyhelper = document.createElement("input");
176 | copyhelper.className = 'copyhelper'
177 | document.body.appendChild(copyhelper);
178 | copyhelper.value = ogUrlCut;
179 | copyhelper.select();
180 | document.execCommand("copy");
181 | document.body.removeChild(copyhelper);
182 | };
183 | executeCopy();
184 | console.log("ogURLCut is " + ogUrlCut)
185 | }
186 |
187 | async function importer() {
188 | oldPage=window.location.href;
189 | oldPageIndex=oldPage.indexOf(ogUrlCut)
190 | ogUrlImport= await navigator.clipboard.readText();
191 | newPage=oldPage.substr(0, oldPageIndex) + ogUrlImport + "_" + oldPage.substr(oldPageIndex)
192 | console.log("oldPage is " + oldPage)
193 | console.log("newPage is " + newPage)
194 | window.history.pushState({path:newPage},'',newPage);
195 | window.location.href=newPage
196 | }
197 |
198 |
199 |
200 | ///////////////////////////////////////
201 | // Removal Prerequisites //
202 | ///////////////////////////////////////
203 | /*
204 | ** Includes a scroller to load the page, stats, and sleep timers
205 | */
206 |
207 | //Scrolls down the page as fast as possible
208 | function scrollDown() {
209 | window.scrollBy(0, 10000);
210 | window.scrollTo(0, document.body.scrollHeight);
211 | }
212 |
213 | //Scrolls to the top of the page
214 | function scrollUp() {
215 | window.scrollBy(0, -50000);
216 | window.scrollTo(0, 0);
217 | }
218 |
219 | //Scrolls all the way to the bottom of the page to load all results, then scrolls back to the top
220 | async function scroller() {
221 | if (document.querySelectorAll("div.results-end").length === 1) {
222 | scrolled = 1;
223 | } else if (document.querySelectorAll("div.results-end").length === 0) {
224 | scrolled = 0;
225 | }
226 | while (scrolled < 1) {
227 | console.log("Scrolling to the bottom of the results");
228 | var scrollCount = 1;
229 | do {
230 | scrollDown();
231 | console.log("Sleeping 1000ms");
232 | await sleep(1000);
233 | console.log("Still scrolling (" + scrollCount + "x)");
234 | scrollCount++;
235 | } while (document.querySelectorAll("div.results-end").length === 0);
236 | console.log("Done scrolling");
237 | console.log("Sleeping 1000ms");
238 | await sleep(1000);
239 | console.log("Scrolling to top of page");
240 | scrollUp();
241 | console.log("We reached the top");
242 | console.log("Sleeping 1000ms");
243 | await sleep(1000);
244 | scrolled = 1;
245 | }
246 | }
247 |
248 | //Scrolls but lets you control it
249 | function betterScroller() {
250 | var a = document.body.clientHeight,
251 | b = document.documentElement.scrollHeight,
252 | c = document.documentElement.clientHeight,
253 | d = innerHeight,
254 | e = document.height;
255 | 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() {
256 | var e = null,
257 | t = 0,
258 | s = function() {
259 | console.log("Clicked; stopping autoscroll"), clearInterval(e), document.body.removeEventListener("click", s)
260 | };
261 | document.body.addEventListener("click", s), e = setInterval(function() {
262 | var o = document.body.scrollHeight - document.body.scrollTop - window.innerHeight;
263 | 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++)
264 | }, 1e3)
265 | }();
266 | else {
267 | let e, t = 1,
268 | s = [
269 | [0, 0],
270 | [25, 200],
271 | [36, 120],
272 | [49, 72],
273 | [64, 43.2],
274 | [81, 25.9],
275 | [100, 31],
276 | [121, 37.2],
277 | [144, 44.8],
278 | [169, 26.4],
279 | [196, 32]
280 | ],
281 | o = document.onkeypress;
282 | _ss_stop = function() {
283 | clearTimeout(e)
284 | }, _ss_start = function() {
285 | _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])
286 | }, _ss_adj = function(e) {
287 | t += e, Math.abs(t) >= s.length && (t = (s.length - 1) * (t / Math.abs(t)))
288 | }, _ss_quit = function() {
289 | _ss_stop(), document.onkeypress = o
290 | }, document.onkeypress = function(e) {
291 | if (113 != e.charCode && 27 != e.keyCode) {
292 | if (e.charCode >= 48 && e.charCode <= 57) t = e.charCode - 48;
293 | else switch (e.charCode) {
294 | case 95:
295 | _ss_adj(-2);
296 | case 45:
297 | _ss_adj(-1);
298 | break;
299 | case 43:
300 | _ss_adj(2);
301 | case 61:
302 | _ss_adj(1)
303 | }
304 | _ss_stop(), _ss_start()
305 | } else _ss_quit()
306 | }, _ss_stop(), _ss_start()
307 | }
308 | }
309 |
310 | //Lets script sleep after functions to allow page a bit of time to catch up
311 | function sleep(ms) {
312 | return new Promise((resolve) => setTimeout(resolve, ms));
313 | }
314 |
315 | //Helper script to update the count of explicit results
316 | function expResultsUpdater() {
317 | explicitCount = document.querySelectorAll(
318 | "#results div.results-grid div.result div.thumbnail span.explicit-result"
319 | ).length;
320 | console.log(explicitCount + " potentially explicit results so far");
321 | document.getElementById("expResults").innerHTML = explicitCount;
322 | }
323 |
324 | //Injects an explicit results running total at the top of the page
325 | function explicitStats() {
326 | console.log("Inserting Stats Counter");
327 | var oldResults = document.querySelector(
328 | "#results > div.container > div > div.top-slot > div > div.container > span.stats > span:nth-child(1)"
329 | );
330 | var explicitResults = oldResults;
331 | var resultsHtml =
332 | '' +
333 | '' +
334 | explicitCount +
335 | "" +
336 | " potentially explicit results so far";
337 | explicitResults.insertAdjacentHTML("beforebegin", resultsHtml);
338 | expResultsUpdater();
339 | }
340 |
341 | //Updates the explicit results count that was injected at the top of the page then stops doing anything after page-end is reached
342 | function scrollResultsUpdateListener() {
343 | addEventListener("scroll", function () {
344 | if (document.querySelectorAll("div.results-end").length === 0) {
345 | expResultsUpdater();
346 | scrolled = 0;
347 | }
348 | });
349 | }
350 |
351 |
352 |
353 | //Highlights and generates url to go to site where image is hosted
354 | async function highlightUrl() {
355 | console.log("Waiting to highlight");
356 | await sleep(200);
357 | var spanUrl = document.querySelector(
358 | "div.modal-content div.thumbnail span.url"
359 | );
360 | if (typeof spanUrl != "undefined" && spanUrl != null) {
361 | spanUrl = document.querySelector(
362 | "div.modal-content div.thumbnail span.url"
363 | );
364 | spanUrl.innerHTML =
365 | `` + spanUrl.innerHTML + ``;
366 |
367 | function selectText(node) {
368 | node = spanUrl;
369 |
370 | if (document.body.createTextRange) {
371 | const range = document.body.createTextRange();
372 | range.moveToElementText(node);
373 | range.select();
374 | } else if (window.getSelection) {
375 | const selection = window.getSelection();
376 | const range = document.createRange();
377 | range.selectNodeContents(node);
378 | selection.removeAllRanges();
379 | selection.addRange(range);
380 | } else {
381 | console.warn(
382 | "Could not select text in node: Unsupported browser."
383 | );
384 | }
385 | }
386 | selectText("spanUrl");
387 | } else {
388 | console.log(
389 | "Tried to highlight URL because of highlightUrl mousedown event listener but popup does not exist!"
390 | );
391 | }
392 | }
393 |
394 | ///////////////////////////////////////
395 | // Removal Scripts //
396 | ///////////////////////////////////////
397 | /*
398 | **Pure Javascript based removal scripts
399 | */
400 |
401 | //Script to remove nonexplicit images using jQuery
402 | function jsRemover() {
403 | console.log("Running removal script (Pure JavaScript)");
404 | document
405 | .querySelectorAll("#results div.results-grid div.result div.thumbnail")
406 | .forEach(function (element) {
407 | if (!element.querySelector("span.explicit-result")) {
408 | element.parentNode.remove();
409 | }
410 | });
411 | console.log("Finished removal script");
412 | }
413 |
414 | //jsRemover helper script
415 | async function explicitJS() {
416 | console.log("Starting the removal process");
417 | await scroller();
418 | jsRemover();
419 | console.log("Finished the removal process");
420 | }
421 |
422 | /*
423 | **jQuery based removal scripts
424 | */
425 |
426 | //Script to remove nonexplicit images using jQuery
427 | function jqRemover() {
428 | console.log("Running removal service (jQuery)");
429 | jQuery(
430 | "#results div.results-grid div.result div.thumbnail:has(span):not(:has(.explicit-result))"
431 | )
432 | .parent()
433 | .remove();
434 | console.log("Finished removal script");
435 | }
436 |
437 | //jqRemover helper script
438 | async function explicitJQ() {
439 | jqGetter();
440 | console.log("Starting the removal process");
441 | await scroller();
442 | jsRemover();
443 | console.log("Finished the removal process");
444 | }
445 |
446 | //Downloads jQuery to the page
447 | function jqGetter() {
448 | console.log("Downloading jQuery to page");
449 | var el = document.createElement("div"),
450 | b = document.getElementsByTagName("body")[0],
451 | otherlib = !1,
452 | msg = "";
453 | (el.style.position = "fixed"),
454 | (el.style.height = "32px"),
455 | (el.style.width = "220px"),
456 | (el.style.marginLeft = "-110px"),
457 | (el.style.top = "0"),
458 | (el.style.left = "50%"),
459 | (el.style.padding = "5px 10px"),
460 | (el.style.zIndex = 1001),
461 | (el.style.fontSize = "12px"),
462 | (el.style.color = "#222"),
463 | (el.style.backgroundColor = "#f99");
464 |
465 | function showMsg() {
466 | var txt = document.createTextNode(msg);
467 | el.appendChild(txt),
468 | b.appendChild(el),
469 | window.setTimeout(function () {
470 | (txt = null),
471 | typeof jQuery == "undefined"
472 | ? b.removeChild(el)
473 | : (jQuery(el).fadeOut("slow", function () {
474 | jQuery(this).remove();
475 | }),
476 | otherlib && (window.$jq = jQuery.noConflict()));
477 | }, 2500);
478 | }
479 | if (typeof jQuery != "undefined")
480 | return (
481 | (msg = "This page already using jQuery v" + jQuery.fn.jquery),
482 | showMsg()
483 | );
484 | typeof $ == "function" && (otherlib = !0);
485 |
486 | function getScript(url, success) {
487 | var script = document.createElement("script");
488 | script.src = url;
489 | var head = document.getElementsByTagName("head")[0],
490 | done = !1;
491 | (script.onload = script.onreadystatechange = function () {
492 | !done &&
493 | (!this.readyState ||
494 | this.readyState == "loaded" ||
495 | this.readyState == "complete") &&
496 | ((done = !0),
497 | success(),
498 | (script.onload = script.onreadystatechange = null),
499 | head.removeChild(script));
500 | }),
501 | head.appendChild(script);
502 | }
503 | getScript("//code.jquery.com/jquery.min.js", function () {
504 | return (
505 | typeof jQuery == "undefined"
506 | ? (msg = "Sorry, but jQuery was not able to load")
507 | : ((msg =
508 | "This page is now jQuerified with v" +
509 | jQuery.fn.jquery),
510 | otherlib &&
511 | (msg += " and noConflict(). Use $jq(), not $().")),
512 | showMsg()
513 | );
514 | });
515 | console.log("jQuery downloaded to page");
516 | }
517 |
518 | ///////////////////////////////////////
519 | // CSS Mods/Page Improvement //
520 | ///////////////////////////////////////
521 | /**
522 | * Utility function to add CSS in multiple passes.
523 | * @param {string} styleString
524 | * From http://stackoverflow.com/a/15506705
525 | **/
526 | function addStyle(styleString) {
527 | const style = document.createElement("style");
528 | style.textContent = styleString;
529 | document.head.append(style);
530 | }
531 |
532 | //From https://greasyfork.org/scripts/406062
533 | addStyle(`
534 | /*Un-blur the URLs*/
535 | .blurred-source-url {
536 | user-select: all !important;
537 | ;
538 | }
539 | `);
540 |
541 | //From https://greasyfork.org/scripts/406062
542 | /*div.modal-content>div.thumbnail>span.url*/
543 |
544 | addStyle(`
545 | /*Make the URLs selectable, and visible*/
546 | *.url {
547 | filter: none !important;
548 | ;
549 | overflow: visible !important;
550 | ;
551 | user-select: initial !important;
552 | ;
553 | max-width: initial !important;
554 | ;
555 | pointer-events: none !important;
556 | ;
557 | position: initial !important;
558 | }
559 | `);
560 |
561 | //From https://greasyfork.org/scripts/406062
562 | addStyle(`
563 | /*Remove the Buy Premium overlay on images*/
564 | .zoom {
565 | display: none !important;
566 | ;
567 | }
568 | `);
569 |
570 | //From https://greasyfork.org/scripts/406062
571 | addStyle(`
572 | /*Remove the 'Get access to archival results and Deep search for $299.99/mo overlay on images*/
573 | .promo {
574 | display: none !important;
575 | ;
576 | }
577 | `);
578 |
579 | //From https://greasyfork.org/scripts/406062
580 | addStyle(`
581 | /*Remove the actions menu, so we can select the image*/
582 | .actions {
583 | display: none !important;
584 | ;
585 | }
586 | `);
587 |
588 | //From https://greasyfork.org/scripts/406062
589 | /*
590 | addStyle(`
591 | /*Hide UNLOCK buttons*\/
592 | button[type="button"] {
593 | display: none !important;
594 | ;
595 | }
596 | `);
597 | */
598 |
599 | //From https://greasyfork.org/scripts/406062
600 | addStyle(`
601 | /*un-hide add picture button*/
602 | button[class="spacer"] {
603 | display: inherit !important;
604 | ;
605 | }
606 | `);
607 |
608 | //From https://greasyfork.org/scripts/406062
609 | addStyle(`
610 | /*Remove events from image*/
611 | div.thumbnail {
612 | pointer-events: none !important;
613 | ;
614 | }
615 | `);
616 |
617 | addStyle(`
618 | /*Hide the unlock popup/buttons if it appears*/
619 | #app > div:nth-child(4) > div > div.mask {
620 | display: none !important;
621 | ;
622 | }
623 | `);
624 |
625 | addStyle(`
626 | /*Hide the unlock popup/buttons if it appears*/
627 | #app > div:nth-child(4) > div.wrapper {
628 | display: none !important;
629 | ;
630 | }
631 | `);
632 |
633 | //Hide the unlock popup if it appears in another way (e.g. hitting Deep search on a paid account)
634 | //Prevent block-scroll from impacting the body if one hits "Deep search" or any button which causes an overlay
635 | addStyle(`
636 | /*Hide the unlock popup if it appears in another way#1*/
637 | /*Prevent block-scroll from impacting the body if one hits "Deep search" or any button which causes an overlay*/
638 | .block-scroll {
639 | touch-action: auto !important;
640 | -webkit-overflow-scrolling: touch!important;
641 | overflow: visible!important;
642 | -ms-scroll-chaining: none!important;
643 | overscroll-behavior: unset!important;
644 | }
645 | `);
646 |
647 |
648 | //Stops the button sizes from changing if one happens to hit the Deep Search button or cause an overlay
649 | addStyle(`
650 | /*Hide the unlock popup if it appears in another way #2*/
651 | /*Stops the button sizes from changing if one happens to hit the Deep Search button or cause an overlay*/
652 | *, :after, :before {
653 | box-sizing: revert !important;
654 | }
655 | `);
656 |
657 | addStyle(`
658 | /*Hide the Formspring payment request*/
659 | #fscCanvas {
660 | display: none !important;
661 | ;
662 | }
663 | `);
664 |
665 | addStyle(`
666 | /*Prevent the overlays from blocking scrolling*
667 | body {
668 | overflow: visible !important;
669 | ;
670 | }
671 | `);
672 |
673 | /*
674 | ** bookmarklet
675 | 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
676 | */
677 |
--------------------------------------------------------------------------------