· 6 years ago · Mar 23, 2020, 02:14 PM
1~function () {
2 const timer = 'Exploit API loaded in';
3 console.time(timer);
4
5 window.drewsnow = {
6 'mouse': { 'x': 0, 'y': 0 },
7
8 /**
9 * Allow a container to be dragged around
10 * @param {HTMLElement} container - Container of the draggable element
11 * @param {HTMLElement} dragItem - Element to drag to move container
12 * @memberof Modules
13 */
14 'draggable': (container, dragItem) => {
15 if (dragItem === undefined) dragItem = container;
16
17 let xOffset = 0,
18 yOffset = 0,
19 active = false,
20 currentX,
21 currentY,
22 initialX,
23 initialY;
24
25 container.addEventListener('touchstart', dragStart, false);
26 document.addEventListener('touchend', dragEnd, false);
27 document.addEventListener('touchmove', drag, false);
28
29 container.addEventListener('mousedown', dragStart, false);
30 document.addEventListener('mouseup', dragEnd, false);
31 document.addEventListener('mousemove', drag, false);
32
33 function dragStart(e) {
34 if (e.type === 'touchstart') {
35 initialX = e.touches[0].clientX - xOffset;
36 initialY = e.touches[0].clientY - yOffset;
37 } else {
38 initialX = e.clientX - xOffset;
39 initialY = e.clientY - yOffset;
40 }
41 let ignoredElems = ['INPUT', 'BUTTON', 'A', 'P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'];
42 if (e.target === dragItem || container === dragItem && ignoredElems.indexOf(e.target.nodeName) == -1) active = true;
43 }
44
45 function dragEnd(e) {
46 initialX = currentX;
47 initialY = currentY;
48 active = false;
49 }
50
51 function drag(e) {
52 if (active) {
53 e.preventDefault();
54 if (e.type === 'touchmove') {
55 currentX = e.touches[0].clientX - initialX;
56 currentY = e.touches[0].clientY - initialY;
57 } else {
58 currentX = e.clientX - initialX;
59 currentY = e.clientY - initialY;
60 }
61 xOffset = currentX;
62 yOffset = currentY;
63 setTranslate(currentX, currentY, container);
64 }
65 }
66
67 function setTranslate(xPos, yPos, el) {
68 el.style.transform = 'translate3d(' + xPos + 'px, ' + yPos + 'px, 0)';
69 }
70 },
71
72 /**
73 * Create new cascading style sheet (CSS)
74 * @param {String} css - CSS style to add to the page
75 * @returns {HTMLElement} New style sheet
76 * @memberof Modules
77 */
78 'css': (css) => {
79 let elem = document.createElement('style');
80 elem.textContent = css;
81 document.head.appendChild(elem);
82 return elem;
83 },
84
85 /**
86 * Append HTML to body or given element
87 * @param {String} html - HTML to append to parent
88 * @param {HTMLElement} [HTMLElement] parent - Parent to append HTML to
89 * @returns {HTMLElement} New HTML element
90 * @memberof Modules
91 */
92 'html': (html, parent) => {
93 elements = new DOMParser().parseFromString(html, 'text/html');
94 container = elements.body.firstChild;
95 (parent || document.body).appendChild(container);
96 return container;
97 },
98
99 /**
100 * Create and run a new script
101 * @param {String} script - Script element to create
102 * @returns {HTMLElement} New HTML element
103 * @memberof Modules
104 */
105 'script': (script) => {
106 let elem = document.createElement('script');
107 elem.type = 'text/javascript';
108 elem.textContent = script;
109 elem.onload = function () { this.remove(); };
110 document.body.appendChild(elem);
111 },
112
113 /**
114 * Create a new keybind
115 * @param {Function} func - Function to run on keydown
116 * @param {*} code - Identifier to select or remove keybind
117 * @param {Number} key - Key to call function
118 * @param {Boolean} [false] bool - Does the keybind start as on or off
119 * @memberof Modules
120 */
121 'addKeyBind': function (func, code = -1, key = '', bool = false) {
122 this.keybinds.push({
123 'key': key,
124 'on': bool,
125 'func': func,
126 'code': code
127 });
128 if (bool) func();
129 },
130
131 /**
132 * Remove keybind(s) with given identifier
133 * @param {*} code - Identifier to find and remove keybind
134 * @returns {Boolean} Keybind found or not
135 * @memberof Modules
136 */
137 'removeKeyBind': function (code) {
138 for (let i = 0; i < this.keybinds.length; i++) {
139 let binds = this.keybinds;
140 if (binds[i].code === code) {
141 binds.splice(i, 1);
142 return true;
143 }
144 }
145 return false;
146 },
147
148 'keybinds': [],
149
150 /**
151 * Find the angle between two given points
152 * @param {Number} x1 - X position of first point
153 * @param {Number} y1 - Y position of first point
154 * @param {Number} x2 - X position of second point
155 * @param {Number} y2 - Y position of second point
156 * @returns {Number} Angle between the two points
157 * @memberof Modules
158 */
159 'angle': (x1, y1, x2, y2) => {
160 return Math.atan2(y1 - y2, x1 - x2);
161 },
162
163 /**
164 * Find the distance between two given points
165 * @param {Number} x1 - X position of first point
166 * @param {Number} y1 - Y position of first point
167 * @param {Number} x2 - X position of second point
168 * @param {Number} y2 - Y position of second point
169 * @returns {Number} Distance between the two points
170 * @memberof Modules
171 */
172 'distance': (x1, y1, x2, y2) => {
173 let a = x1 - x2,
174 b = y1 - y2;
175
176 return Math.sqrt(a * a + b * b);
177 },
178
179 /**
180 * Find the closest object in an array to the given point
181 * @param {Object} you - Main charecter's position
182 * @param {String} you.x - Main charecter's position on X-axis
183 * @param {String} you.y - Main charecter's position on Y-axis
184 * @param {Array} objects - Array of positions of the other charecters
185 * @returns {Object} Closest object to main charecter
186 * @memberof Modules
187 */
188 'closest': function (you, objects=[]) {
189 let closestObj = objects[0];
190 let closestDist = Infinity;
191 for (let i = 0; i < objects.length; i++) {
192 let obj = objects[i],
193 dist = this.getDist(you.x, you.y, obj.x, obj.y);
194 if (dist < closestDist) {
195 closestObj = obj;
196 closestDist = dist;
197 }
198 }
199 return closestObj;
200 },
201
202 /**
203 * Spoof input event on given element
204 * @param {HTMLElement} elem - Element to dispatch the event onto
205 * @param {String} data - Data to be fed into the event
206 * @memberof Modules
207 */
208 'input': function (elem, data='') {
209 let event = new InputEvent('input', {
210 bubbles: true,
211 cancelBubble: false,
212 cancelable: false,
213 composed: true,
214 currentTarget: null,
215 dataTransfer: null,
216 defaultPrevented: false,
217 detail: 0,
218 view: null,
219 which: 0,
220 returnValue: true,
221 sourceCapabilities: null,
222 eventPhase: 0,
223 isComposing: false,
224 inputType: 'insertText',
225 srcElement: elem,
226 target: elem,
227 data
228 });
229 elem.dispatchEvent(event);
230 },
231
232 /**
233 * Spoof focus event on given element
234 * @param {HTMLElement} elem - Element to dispatch the event onto
235 * @memberof Modules
236 */
237 'focus': function (elem) {
238 elem.focus();
239 let event = new FocusEvent('focus', {
240 bubbles: false,
241 cancelBubble: false,
242 cancelable: false,
243 composed: true,
244 currentTarget: null,
245 defaultPrevented: false,
246 detail: 0,
247 eventPhase: 0,
248 isTrusted: true,
249 relatedTarget: null,
250 returnValue: true,
251 sourceCapabilities: null,
252 srcElement: elem,
253 target: elem,
254 view: window,
255 which: 0
256 });
257 elem.dispatchEvent(event);
258 },
259
260 /**
261 * Download a file with given name and contents
262 * @param {String} filename - Name of the file to download
263 * @param {String} data - Contents of the file to download
264 * @memberof Modules
265 */
266 'download': function (filename, data) {
267 let elem = document.createElement('a');
268 elem.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(data));
269 elem.setAttribute('download', filename);
270
271 elem.style.display = 'none';
272 document.body.appendChild(elem);
273
274 elem.click();
275
276 document.body.removeChild(elem);
277 },
278
279 /**
280 * Attempt to go fullscreen
281 */
282 'fullscreen': function () {
283 let elem = document.documentElement;
284 if (elem.requestFullscreen) {
285 elem.requestFullscreen();
286 } else if (elem.mozRequestFullScreen) {
287 elem.mozRequestFullScreen();
288 } else if (elem.webkitRequestFullscreen) {
289 elem.webkitRequestFullscreen();
290 } else if (elem.msRequestFullscreen) {
291 elem.msRequestFullscreen();
292 }
293 },
294
295 /**
296 * Attempt to intercept scripts
297 * @param {String} match - String to match the script SRC to
298 * @param {String} script - Script to replace the file with
299 * @memberof Modules
300 */
301 'intercept': function (match, script) {
302 document.addEventListener('beforescriptexecute', function (e) {
303 src = e.target.src;
304 content = e.target.text;
305
306 if (src.indexOf(match) != -1) {
307 e.preventDefault();
308 e.stopPropagation();
309 e.target.remove();
310
311 this.script(script);
312 }
313 });
314 },
315
316 /**
317 * Attempt to copy text to clipboard
318 * @param {String} text - String to copy to clipboard
319 * @memberof Modules
320 */
321 'copy': function (text) {
322 let input = document.createElement('textarea');
323
324 input.value = text;
325 input.setAttribute('readonly', '');
326 document.body.appendChild(input);
327
328 input.focus();
329 input.select();
330
331 try {
332 input.style = 'opacity: 0; visibility: hidden;';
333
334 document.execCommand('copy');
335 document.body.removeChild(input);
336 } catch (e) {
337 input.style = 'z-index: 2147483646; position: fixed; left: 50%; top: 50%; width: 50%; height: 50%; transform: translate(-50%, -50%)';
338
339 input.onclick = function () {
340 this.focus();
341 this.select();
342 document.execCommand('copy');
343 };
344
345 input.onblur = function () { this.remove(); };
346 }
347 },
348
349 /**
350 * Spoof mousedown event on given element
351 * @param {HTMLElement} elem - Element to dispatch the event onto
352 * @param {Object} params - Parameters to be fed into the event
353 * @memberof Modules
354 */
355 'mousedown': function (elem, params={}) {
356 let event = new MouseEvent('mousedown', {
357 currentTarget: params.currentTarget || elem || document.body,
358 view: params.view || window,
359 bubbles: params.bubbles || true,
360 cancelable: params.cancelable || true,
361 clientX: params.x || 0,
362 clientY: params.y || 0,
363 pageX: params.x || 0,
364 pageY: params.y || 0
365 });
366 elem.dispatchEvent(event);
367 },
368
369 /**
370 * Spoof mouseup event on given element
371 * @param {HTMLElement} elem - Element to dispatch the event onto
372 * @param {Object} params - Parameters to be fed into the event
373 * @memberof Modules
374 */
375 'mouseup': function (elem, params={}) {
376 let event = new MouseEvent('mouseup', {
377 currentTarget: params.currentTarget || elem || document.body,
378 view: params.view || window,
379 bubbles: params.bubbles || true,
380 cancelable: params.cancelable || true,
381 clientX: params.x || 0,
382 clientY: params.y || 0,
383 pageX: params.x || 0,
384 pageY: params.y || 0
385 });
386 elem.dispatchEvent(event);
387 },
388
389 /**
390 * Spoof mousemove event on given element
391 * @param {HTMLElement} elem - Element to dispatch the event onto
392 * @param {Object} params - Parameters to be fed into the event
393 * @memberof Modules
394 */
395 'mousemove': function (elem, params={}) {
396 let event = new MouseEvent('mousemove', {
397 currentTarget: params.currentTarget || elem || document.body,
398 view: params.view || window,
399 bubbles: params.bubbles || true,
400 cancelable: params.cancelable || true,
401 clientX: params.x || 0,
402 clientY: params.y || 0,
403 pageX: params.x || 0,
404 pageY: params.y || 0
405 });
406 elem.dispatchEvent(event);
407 },
408
409 /**
410 * Picks a random number inbetween two given numbers
411 * @param {Number} min - Minimum number
412 * @param {Number} max - Maximum number
413 * @memberof Modules
414 */
415 'random': (min, max) => {
416 return Math.floor(Math.random() * (max - min) + min);
417 },
418
419 'init': function () {
420 const binds = this.keybinds;
421 document.body.addEventListener('keydown', (e) => {
422 for (let i = 0; i < binds.length; i++) {
423 let data = binds[i];
424 if ((e.which || e.keyCode) === data.code) {
425 data.func(data.on);
426 data.on = !data.on;
427 }
428 }
429 });
430
431 window.addEventListener('mousemove', e => {
432 this.mouse.x = e.clientX;
433 this.mouse.y = e.clientY;
434 });
435
436 let elem = this.html(`
437 <div style="pointer-events: none; user-select: none;box-shadow: 0 5px 35px rgba(0, 0, 0, .65);font-family: Consolas, monaco, monospace;transition: transform 1s ease;transform: translateX(125%);border-radius: 3px 0 0 3px;width: 250px; height: 90px;background-color: #11af00;box-sizing: content-box;bottom: 20px; right: 0;box-sizing: border-box;margin: 0; padding: 0;z-index: 2147483647;text-align: center;line-height: 100%;padding-top: 30px;position: fixed;line-height: 0;color: #000;">
438 <span style="line-height: 0px; font-size: 25px; font-family: inherit;">Developed By</span><br>
439 <span style="line-height: 45px; font-size: 45px; text-shadow: 0 1px #808d93, -1px 0 #cdd2d5, -1px 2px #808d93, -2px 1px #cdd2d5, -2px 3px #808d93, -3px 2px #cdd2d5, -3px 4px #808d93, -4px 3px #cdd2d5, 2px 2px 2px rgba(206, 89, 55, 0.1); font-family: inherit;">Drew Snow</span>
440 </div>
441 `.trim());
442
443 setTimeout(() => { elem.style.transform = ''; }, 1);
444
445 setTimeout(() => { elem.style.transform = 'translateX(125%)'; }, 4000);
446
447 setTimeout(() => { elem.remove(); }, 5250);
448
449 Number.prototype.toDegree = function () { return this * (180 / Math.PI); };
450
451 Number.prototype.toRadian = function () { return this * (Math.PI / 180); };
452
453 Array.prototype.random = function () { return this[Math.floor(Math.random() * this.length)] || []; };
454
455 Element.prototype.forEach = function (callback) { for (let i = 0; i < this.length; i++) callback(this[i], i); };
456
457 Array.prototype.contains = function (value) {
458 for (let i = 0; i < this.length; i++)
459 if (this[i] === value) return true;
460 return false;
461 };
462
463 Array.prototype.findByName = function (name = '', exact = false) {
464 let result = [],
465 index = -1;
466 if (this.length < 1) return [];
467
468 for (let i = 0; i < this.length; i++) {
469 let obj = this[i];
470
471 if (exact && obj.name != name) continue;
472 if (!exact && obj.name !== name) continue;
473
474 result.push(obj);
475 index = i;
476 }
477
478 return result[0];
479 };
480
481 String.prototype.encode = function () {
482 return this
483 .replace(/</g, '<')
484 .replace(/>/g, '>')
485 .replace(/"/g, '"')
486 .replace(/'/g, ''');
487 };
488
489 CanvasRenderingContext2D.prototype.line = function (x1, y1, x2, y2, color = '#000', thickness = 1) {
490 this.save();
491 this.lineWidth = thickness;
492 this.strokeStyle = color;
493
494 this.beginPath();
495 this.moveTo(x1, y1);
496 this.lineTo(x2, y2);
497 this.stroke();
498 this.restore();
499 };
500
501 CanvasRenderingContext2D.prototype.circle = function (x, y, r, color = '#000') {
502 this.save();
503
504 this.arc(x, y, r, 0, 2 * Math.PI, false);
505 this.fillStyle = color;
506 this.fill();
507
508 this.restore();
509 };
510
511 CanvasRenderingContext2D.prototype.rect = function (x, y, width, height, color = '#000') {
512 this.save();
513
514 this.fillStyle = color;
515 this.fillRect(x, y, width, height, color);
516
517 this.restore();
518 };
519
520 console.timeEnd(timer);
521 }
522 };
523 window.drewsnow.init();
524}();
525function Alert(header, content) {
526 let container = document.createElement('div');
527 container.style = `box-shadow: 0 0.3125rem 1rem 0 rgba(0, 0, 0, 0.24); transform: translateX(-50%); margin-bottom: 2.8125rem; margin-top: 2.8125rem; max-width: 100%; width: 37.5rem; position: relative; top: 0; left: 50%; z-index: 2147483647; color: rgb(69, 83, 88); display: block; background-clip: border-box; background-color: rgb(255, 255, 255)`;
528 container.className = 'custom-alert-container';
529
530 let head = document.createElement('div');
531 head.style = `background-color: rgb(66, 87, 178); color: rgb(255, 255, 255); font-size: 30px; line-height: 26px; padding: 32px;`;
532 head.innerHTML = `${header}<span onclick="this.parentElement.parentElement.remove();" class="UIButton-wrapper" style="position: absolute; right: 0; width: 94px; cursor: pointer;"><svg class="UIIcon UIIcon--x-thin"><noscript></noscript><use xlink:href="#x-thin"></use><noscript></noscript></svg></span>`;
533 container.appendChild(head);
534
535 let body = document.createElement('div');
536 body.style = `color: rgb(69, 83, 88); font-size: 16px; padding: 32px;`;
537 body.innerHTML = content;
538 container.appendChild(body);
539
540 document.body.appendChild(container);
541 return container;
542}
543
544function removeClass(className) {
545 let elems = document.getElementsByClassName(className);
546
547 for (let i = 0; i < elems.length; i++) elems[i].remove();
548}
549
550function obfuscate(msg, num=77) {
551 let answer = '';
552 for (let i = 0; i < msg.length; i++) answer += ('-' + (msg.charCodeAt(i) + num % (i + 1)));
553 return answer.slice(1);
554}
555
556function copyText(text) {
557 let input = document.createElement('textarea');
558
559 input.value = text;
560 input.setAttribute('readonly', '');
561
562 document.body.appendChild(input);
563
564 input.focus();
565 input.select();
566
567 if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0, 4))) {
568 input.style = 'z-index: 2147483646; position: fixed; left: 50%; top: 50%; width: 50%; height: 50%; transform: translate(-50%, -50%)';
569
570 input.onclick = function () {
571 this.focus();
572 this.select();
573 document.execCommand('copy');
574 };
575
576 input.onblur = function () { this.remove(); };
577 } else {
578 input.stype = 'opacity: 0; visibility: hidden;';
579
580 document.execCommand('copy');
581 document.body.removeChild(input);
582 }
583}
584window.settings = {
585 'default': {
586 'developer': 'Drew Snow',
587 'gravity': { 'score': 4294967295 },
588 'learn': { 'speed': 100 },
589 'live': { 'answerDelay': 100, 'autoAnswer': true, 'displayAnswer': true, 'key': 67 },
590 'match': { 'time': 0.5 },
591 'night': false,
592 'test': { 'key': 67 }
593 },
594 'current': {
595 'developer': 'Drew Snow',
596 'gravity': { 'score': 4294967295 },
597 'learn': { 'speed': 100 },
598 'live': { 'answerDelay': 100, 'autoAnswer': true, 'displayAnswer': true, 'key': 67 },
599 'match': { 'time': 0.5 },
600 'night': false,
601 'test': { 'key': 67 }
602 },
603 'fix': function () {
604 this.current = this.get();
605 if (typeof this.current.developer != 'string') this.current.developer = this.default.developer;
606 if (typeof this.current.gravity.score != 'number') this.current.gravity.score = this.default.gravity.score;
607 if (typeof this.current.learn.speed != 'number') this.current.learn.speed = this.default.learn.speed;
608 if (typeof this.current.live.answerDelay != 'number') this.current.live.answerDelay = this.default.live.answerDelay;
609 if (typeof this.current.live.autoAnswer != 'boolean') this.current.live.autoAnswer = this.default.live.autoAnswer;
610 if (typeof this.current.live.displayAnswer != 'boolean') this.current.live.displayAnswer = this.default.live.displayAnswer;
611 if (typeof this.current.live.key != 'number') this.current.live.key = this.default.live.key;
612 if (typeof this.current.match.time != 'number') this.current.match.time = this.default.match.time;
613 if (typeof this.current.night != 'boolean') this.current.night = this.default.night;
614 if (typeof this.current.test.key != 'number') this.current.test.key = this.default.test.key;
615 this.save();
616 },
617 'reset': function () {
618 localStorage.setItem('extensionSettings', JSON.stringify(this.default));
619 },
620 'save': function () {
621 localStorage.setItem('extensionSettings', JSON.stringify(this.current));
622 },
623 'get': function () {
624 if (localStorage) {
625 if (!localStorage.getItem('extensionSettings')) this.reset();
626 return JSON.parse(localStorage.getItem('extensionSettings'));
627 }
628 return this.default;
629 }
630};
631settings.fix();
632
633~function () {
634 let style = drewsnow.css(`
635 #extensionSettingsContainer {
636 transition: transform 1s ease;
637 transform: translateY(355px);
638
639 box-shadow: 0 5px 35px rgba(0, 0, 0, .65);
640 font-family: Roboto, Verdana, Arial;
641 border-top: 25px solid #d86d02;
642 height: 380px; width: 300px;
643 border-radius: 0 5px 0 0;
644 background-color: #000;
645 box-sizing: border-box;
646 z-index: 2147483638;
647 bottom: 0; left: 0;
648 position: fixed;
649 display: block;
650 line-height: 1;
651 padding: 10px;
652 color: #fff;
653 }
654
655 #extensionSettingsContainer:hover {
656 transform: translateY(0);
657 }
658
659 #extensionSettingsContainer h2 {
660 margin-top: 10px;
661 }
662
663 #extensionSettingsContainer input {
664 background-color: rgba(255, 255, 255, .8);
665 margin-right: 10px;
666 border-radius: 2px;
667 max-width: 150px;
668 outline: none;
669 float: right;
670 color: #000;
671 }
672
673 #extensionSettingsContainer #saveSettings {
674 width: 100%; height: 30px;
675 border-radius: 5px;
676 outline: none;
677 }
678
679 #extensionSettingsContainer .adaptKeyInput {
680 width: 70px;
681 }
682
683 #extensionSettingsContainer .numberOnlyInput {
684 width: 80px;
685 }
686
687 #extensionSettingsContainer .extensionMenuItem {
688 margin-right: 5px;
689 cursor: pointer;
690 float: right;
691 }
692
693 #extensionSettingsContainer .extensionMenuItem:hover {
694 color: #8c8c8c;
695 }
696 `);
697
698 let container = drewsnow.html(`
699 <div id="extensionSettingsContainer">
700 <span class="extensionMenuItem" id="extensionExitButton">×</span>
701 <span class="extensionMenuItem" id="extensionResetButton">↺</span>
702 <h2>Settings</h2>
703 <div>Gravity Score<input id="gravityScoreInput" class="numberOnlyInput"></input></div><br>
704 <div>Learn Speed<input id="learnSpeedInput" class="numberOnlyInput"></input></div><br>
705 <div>Live Answer Delay<input id="liveDelayInput" class="numberOnlyInput"></input></div><br>
706 <div>Live Auto-Answer<input id="liveAutoAnswerInput" type="checkbox"></input></div><br>
707 <div>Live Show Answer<input id="liveShowAnswerInput" type="checkbox"></input></div><br>
708 <div>Live Toggle Key<input name="live" class="adaptKeyInput" id="liveKeyInput"></input></div><br>
709 <div>Match Time<input id="matchTimeInput" class="numberOnlyInput"></input></div><br>
710 <div>Test Key<input name="test" class="adaptKeyInput" id="testKeyInput"></input></div><br>
711 <button id='saveSettings'>Save</button>
712 </div>
713 `);
714
715 let inputs = document.getElementsByClassName('adaptKeyInput');
716
717 for (let i = 0; i < inputs.length; i++) {
718 let input = inputs[i];
719 input.onkeypress = changeSettingOnKey;
720 input.onkeydown = changeSettingOnKey;
721 input.onkeyup = changeSettingOnKey;
722 }
723
724 inputs = document.getElementsByClassName('numberOnlyInput');
725 for (let i = 0; i < inputs.length; i++) {
726 let input = inputs[i];
727 input.onkeydown = e => {
728 if (!/^([0-9.,]|Backspace)$/i.test(e.key)) e.preventDefault();
729 }
730 }
731
732 document.getElementById('extensionResetButton').onclick = () => {
733 localStorage.setItem('extensionSettings', JSON.stringify({
734 'developer': 'Drew Snow',
735 'gravity': { 'score': 4294967295 },
736 'learn': { 'speed': 100 },
737 'live': { 'answerDelay': 100, 'autoAnswer': true, 'displayAnswer': true, 'key': 67 },
738 'match': { 'time': 0.5 },
739 'night': false,
740 'test': { 'key': 67 }
741 }));
742 window.location.reload();
743 };
744
745 document.getElementById('extensionExitButton').onclick = function () {
746 this.parentElement.remove();
747 }
748
749 document.getElementById('saveSettings').onclick = () => {
750 localStorage.setItem('extensionSettings', JSON.stringify({
751 "developer": "Drew Snow",
752 "gravity": {
753 "score": Number(document.getElementById('gravityScoreInput').value)
754 },
755 "learn": {
756 "speed": Number(document.getElementById('learnSpeedInput').value)
757 },
758 "live": {
759 "answerDelay": Number(document.getElementById('liveDelayInput').value),
760 "autoAnswer": !!document.getElementById('liveAutoAnswerInput').checked,
761 "displayAnswer": !!document.getElementById('liveShowAnswerInput').checked,
762 "key": Number(document.getElementById('liveKeyInput').value)
763 },
764 "match": {
765 "time": Number(document.getElementById('matchTimeInput').value)
766 },
767 "night": false,
768 "test": {
769 "key": Number(document.getElementById('testKeyInput').value)
770 }
771 }));
772 };
773
774 let settings = JSON.parse(localStorage.getItem('extensionSettings')) || { "developer": "Drew Snow", "gravity": { "score": 4294967295 }, "learn": { "speed": 700 }, "live": { "answerDelay": 100, "autoAnswer": 1, "displayAnswer": 1, "key": "c" }, "match": { "time": 0.5 }, "night": false, "test": { "key": "c" } };
775 document.getElementById('gravityScoreInput').value = settings.gravity.score;
776 document.getElementById('learnSpeedInput').value = settings.learn.speed;
777 document.getElementById('liveDelayInput').value = settings.live.answerDelay;
778 document.getElementById('liveAutoAnswerInput').checked = +settings.live.autoAnswer;
779 document.getElementById('liveShowAnswerInput').checked = +settings.live.displayAnswer;
780 document.getElementById('liveKeyInput').value = settings.live.key;
781 document.getElementById('matchTimeInput').value = settings.match.time;
782 document.getElementById('testKeyInput').value = settings.test.key;
783
784 function changeSettingOnKey(e) {
785 e.preventDefault();
786 this.value = e.keyCode || e.which;
787 }
788}();
789
790window.Answers = {
791 'duplicates': function (terms = this.get()) {
792 let words = terms.map(e => e.word),
793 images = terms.map(e => e.photo || e._imageUrl),
794 definitions = terms.map(e => e.definition);
795
796 if (new Set(words).size != words.length) return true;
797 if (new Set(definitions).size != definitions.length) return true;
798 if (words.filter(e => definitions.indexOf(e) != -1).length) return true;
799
800 return false;
801 },
802
803 'get': function () {
804 if (Quizlet.assistantModeData !== undefined) {
805 return Quizlet.assistantModeData.terms;
806 } else if (Quizlet.learnGameData !== undefined) {
807 return Quizlet.learnGameData.allTerms;
808 } else if (Quizlet.testModeData !== undefined) {
809 return Quizlet.testModeData.terms;
810 } else if (Quizlet.spellModeData !== undefined) {
811 return Quizlet.spellModeData.spellGameData.termsById;
812 } else if (Quizlet.matchModeData !== undefined) {
813 return Quizlet.matchModeData.terms;
814 } else if (Quizlet.gravityModeData !== undefined) {
815 return Quizlet.gravityModeData.terms;
816 }
817 return [];
818 },
819
820 'find': function (question = '', terms = this.get()) {
821 let words = terms.filter(e => e.word == question),
822 definitions = terms.filter(e => e.definition == question),
823 images = terms.filter(e => e.photo == question || e._imageUrl == question);
824
825 answers = [...words, ...definitions, ...images];
826 return answers;
827 },
828
829 'exact': function (question, src = '', terms = this.get()) {
830 let matches = [];
831
832 // Test for normal matching text and image
833 for (let i = 0; i < terms.length; ++i) {
834 let word = terms[i].word,
835 definition = terms[i].definition,
836 image = terms[i].photo || terms[i]._imageUrl;
837
838 if (question == word && src == image) matches.push(definition);
839 }
840
841 // Test for defintion with text and image
842 if (matches.length == 0) {
843 for (let i = 0; i < terms.length; ++i) {
844 let word = terms[i].word,
845 definition = terms[i].definition,
846 image = terms[i].photo || terms[i]._imageUrl;
847
848 if (question == definition && src == image) matches.push(word);
849 }
850 }
851
852 // Test for only matching word
853 if (matches.length == 0) {
854 for (let i = 0; i < terms.length; ++i) {
855 let word = terms[i].word,
856 definition = terms[i].definition;
857
858 if (question == word) matches.push(definition);
859 }
860 }
861
862 // Test for only matching definition
863 if (matches.length == 0) {
864 for (let i = 0; i < terms.length; ++i) {
865 let word = terms[i].word,
866 definition = terms[i].definition;
867
868 if (question == definition) matches.push(word);
869 }
870 }
871
872 return matches;
873 },
874
875 'post': function (game = 'match', score = '1') {
876 let data = {};
877
878 score = String(score);
879
880 if (game === 'gravity') {
881 score = score || prompt('Highest possible score is 4294967295.\nScore: ', 4294967295) || 4294967295;
882
883 data = {
884 sessionId: undefined,
885 score: score,
886 previous_record: Quizlet.highscoresModalData.previousRecord || 420,
887 time_started: Date.now() - 53582,
888 selectedOnly: false
889 }
890 } else if (game === 'match') {
891 score = score || prompt('Fastest possible time is 0.5\nScore: ', '0.5') || '0.5';
892
893 if (score.indexOf('.') == -1) score += '0';
894 score = score.replace(/[^0-9]/g, '');
895
896 data = {
897 score: Math.min(Math.max(5, score), 4294967295),
898 previous_record: Quizlet.matchModeData.recordTime || 69,
899 too_small: 0,
900 time_started: Quizlet.SERVER_TIME,
901 selectedOnly: false
902 }
903 }
904
905 let message = { 'data': obfuscate(JSON.stringify(data), 77) };
906
907 let send = new XMLHttpRequest;
908 send.onreadystatechange = function () {
909 if (send.readyState === 4) {
910 try {
911 let response = JSON.parse(send.responseText);
912 if (send.status == 200) Alert('Success!', `Injected a ${game} score of ${JSON.parse(send.responseText).responses[0].models.session[0].score} into ${JSON.parse(send.responseText).responses[0].models.user[0].username}'s (${JSON.parse(send.responseText).responses[0].models.user[0].id}) account!`);
913 else Alert('Error in sending request!', 'Sending negative numbers, decimal numbers, and numbers lower than five will not work! If you have done none of these and this is happening multiple times, please submit a bug report with the following information:<br><textarea style="width: 100%; resize: none;">' + 'Status:' + send.status + '\nGame:' + game + '\nScore:' + score + '\nError:' + e + '</textarea>');
914 } catch (e) { Alert('Error in parsing response!', 'Sending negative numbers, decimal numbers, and numbers lower than five will not work! If you have done none of these and this is happening multiple times, please submit a bug report with the following information:<br><textarea style="width: 100%; resize: none;">' + 'Game:' + game + '\nScore:' + score + '\nError:' + e + '</textarea>'); }
915 }
916 }
917 send.open('POST', document.location.href + '/highscores');
918 send.setRequestHeader('CS-Token', Quizlet.getCsToken());
919 send.setRequestHeader('Accept', 'application/json');
920 send.setRequestHeader('Content-Type', 'application/json');
921 send.send(JSON.stringify(message));
922 }
923}
924function Live() {
925 this.paused = false;
926
927 this.container = drewsnow.html(`
928 <div style="line-height: 1.2; top: 0; left: 0; font-family: 'Courier New', Courier, monospace; z-index: 2147483647; background-color: #202020; position: fixed; width: 350px; height: 475px; margin: 0; padding: 0; box-shadow: 0 5px 35px rgba(0, 0, 0, .75)">
929 <nav style="cursor: move; user-select: none; text-align: right; color: #fff; position: absolute; width: 348px; height: 25px; margin: 1px;">
930 <span onclick="alert('Intructions:\\n1.) Enter the Quizlet Live code into the input with a placeholder of 123456.\\n\\n2.) Click the large orange button that says Obtain Live Data.\\n\\n3.) Copy the text that is in the site that pops up (Ctrl + a, then Ctrl + c) and paste it (Ctrl + v) all in the textarea that says Paste The Site Data Here.\\n\\n4.) If the data if correct, the answer will be shown in the top right corner of your screen, and if you have the answer, it will be clicked for you.\\n\\nNotes:\\nPressing C will hide the answer.\\n\\nYou can toggle the script from automatically clicking the answer by clicking the text in the top right of your screen.\\n\\nPressing Ctrl + a will select all the text on a page.\\n\\nPressing Ctrl + v will paste the copied text for you.\\n\\nThis script was made by Drew Snow.');" style="font-size: 15px; cursor: pointer; width: 100%; height: 100%;">?</span>
931 <span onclick="this.parentElement.parentElement.remove();" aria-label="Close Interface Model" style="cursor: pointer; width: 100%; height: 100%; padding-right: 5px; font-size: 20px;">×</span>
932 </nav>
933
934 <div style="margin: 0; border-radius: 3px; background-color: #141414; position: absolute; bottom: 276px; width: 346px; height: 170px; margin: 2px;">
935 <button id="getLiveDataButton">Obtain Live Data</button>
936 <div id="liveCodeInput" style="height: 20px; width: 132px; position: relative; left: 0; margin-left: 50%; transform: translateX(-50%);"><input><input><input><input><input><input></div>
937 <textarea spellcheck="false" id="quizletLiveDataInput" class="customScrollBar" placeholder="Paste The Site Data Here"></textarea>
938 </div>
939
940 <div style="margin: 0; position: absolute; bottom: 0px; width: 346px; height: 275px; margin: 2px;">
941 <div style="margin: 0;" id="customCommandOutput" class="customScrollBar">
942 <div style="color: #339b00;">Loaded initial HTML.</div>
943 </div>
944 </div>
945 </div>
946 `);
947
948 this.css = drewsnow.css(`
949 @keyframes shake-animation {
950 0% { transform: translate(-51%, -1px) rotate(1deg); }
951 20% { transform: translate(-50%, 1px) rotate(0deg); }
952 40% { transform: translate(-49%, 2px) rotate(-1deg); }
953 60% { transform: translate(-51%, 0px) rotate(1deg); }
954 80% { transform: translate(-50%, -1px) rotate(-1deg); }
955 100% { transform: translate(-49%, 1px) rotate(0deg); }
956 }
957
958 .shakingElement {
959 animation: shake-animation .4s;
960 animation-iteration-count: infinite;
961 }
962
963 #getLiveDataButton {
964 width: 346px;
965 }
966
967 #quizletLiveDataInput {
968 background-color: rgba(0, 0, 0, .2);
969 width: 340px; height: 103px;
970 overflow-x: hidden;
971 color: #d6d6d6;
972 outline: none;
973 resize: none;
974 }
975
976 #customCommandOutput {
977 font-family: 'Courier New', Courier, monospace;
978 background-color: rgba(0, 0, 0, .1);
979 transition: all .3s ease;
980 border-radius: 3px;
981 overflow-y: scroll;
982 font-size: 15px;
983 height: 266px;
984 padding: 5px;
985 }
986
987 .customScrollBar::-webkit-scrollbar {
988 width: 10px;
989 }
990
991 .customScrollBar::-webkit-scrollbar-track {
992 background: #1c1c1c;
993 }
994
995 .customScrollBar::-webkit-scrollbar-thumb {
996 background: #3d3d3d;
997 }
998
999 .customScrollBar::-webkit-scrollbar-thumb:hover {
1000 background: #686868;
1001 }
1002
1003 #getLiveDataButton {
1004 transition: opacity .3s, background .8s ease, color .5s ease, box-shadow .5s ease;
1005 background-color: #ef7f00;
1006 position: relative;
1007 font-size: 1.6em;
1008 cursor: pointer;
1009 padding: 0 2em;
1010 outline: none;
1011 height: 40px;
1012 border: none;
1013 opacity: .8;
1014 color: #fff;
1015 }
1016
1017 #getLiveDataButton:hover {
1018 background-color: #d3d3d3;
1019 color: #000;
1020 opacity: 1;
1021 }
1022
1023 #getLiveDataButton:before, #getLiveDataButton:after {
1024 transition: width .8s ease;
1025 width: 0; height: 2px;
1026 background: #ffb25b;
1027 position: absolute;
1028 top: 0; right: 0;
1029 content: '';
1030 }
1031
1032 #getLiveDataButton:after {
1033 right: inherit; top: inherit;
1034 left: 0; bottom: 0;
1035 }
1036
1037 #getLiveDataButton:active:before, #getLiveDataButton:active:after {
1038 transition: all .8s ease;
1039 width: 100%;
1040 }
1041
1042 #getLiveDataButton:hover {
1043 box-shadow: 0px 5px 13px 0px rgba(166, 166, 166, .5);
1044 }
1045 `);
1046
1047 this.cmd = document.getElementById('customCommandOutput');
1048 this.input = document.getElementById('quizletLiveDataInput');
1049
1050 this.input.onchange = e => { this.update(e); };
1051 this.input.onkeyup = e => { this.update(e); };
1052 this.input.oninput = e => { this.update(e); };
1053
1054 this.btnLive = document.getElementById('getLiveDataButton');
1055 this.btnLive.onclick = () => { this.getData(); };
1056
1057 this.inpLive = document.getElementById('liveCodeInput');
1058 this.inputs = this.inpLive.querySelectorAll('input');
1059
1060 this.options = document.createElement('div');
1061 this.options.style = 'transition: all 0.3s; position: absolute; padding-right: 5px; opacity: 1; margin: 0; right: 0; top: 0';
1062 this.options.id = 'liveSettingsContainer';
1063 this.options.innerHTML = '<span style="color: #fff" id="liveAnswerPhrase">Answer</span><span style="user-select: none; color: #000;"> — </span><span style="color: #ff0000; cursor: pointer; user-select: none;" id="btnToggleHack">Pause</span>';
1064 document.body.appendChild(this.options);
1065
1066 this.setup();
1067
1068 this.inpLive.addEventListener('paste', e => { this.paste(e); });
1069
1070 this.data = {};
1071 this.loop = setInterval(() => { this.interval(); }, 250);
1072
1073 drewsnow.addKeyBind(() => {
1074 let container = document.getElementById('liveSettingsContainer');
1075 if (container.style.opacity != 0) container.style.opacity = 0;
1076 else container.style.opacity = 1;
1077 }, settings.current.live.key || 67, 'c');
1078
1079 drewsnow.addKeyBind(() => {
1080 try { document.getElementById('btnToggleHack').click(); } catch (e) { };
1081 }, 86, 'v');
1082
1083 this.btnToggle = document.getElementById('btnToggleHack');
1084
1085 this.btnToggle.onclick = () => {
1086 let btn = this.btnToggle;
1087
1088 this.paused = !this.paused;
1089 if (this.paused) {
1090 btn.style.color = '#00ff00';
1091 btn.textContent = 'Resume';
1092 } else {
1093 btn.style.color = '#ff0000';
1094 btn.textContent = 'Pause';
1095 }
1096 };
1097
1098 drewsnow.draggable(this.container, this.container.querySelector('nav'));
1099
1100 this.log('Finished Executing JavaScript.', '#339b00');
1101 this.log('For help click the \'?\' in the top right corner.', '#1c73ff');
1102}
1103
1104Live.prototype.click = element => {
1105 if (element.fireEvent) {
1106 element.fireEvent('onclick');
1107 } else {
1108 let event = document.createEvent('Events');
1109 event.initEvent('click', true, false);
1110 element.dispatchEvent(event);
1111 }
1112}
1113
1114Live.prototype.log = function (msg, color = '#c6c6c6') {
1115 let element = document.createElement('div'),
1116 cmd = this.cmd;
1117
1118 element.style.display = 'block';
1119 element.style.color = color;
1120 element.textContent = msg;
1121
1122 cmd.appendChild(element);
1123 cmd.children[cmd.children.length - 1].scrollIntoView();
1124
1125 if (cmd.children.length > 25) cmd.children[0].remove();
1126}
1127
1128Live.prototype.update = function (e) {
1129 if (!e.target.value) e.target.style.border = '1px solid blue';
1130 else {
1131 try {
1132 let json = JSON.parse(e.target.value);
1133 if (json.terms.length < 1) throw 0;
1134 e.target.style.border = '1px solid green';
1135 this.data = json;
1136 } catch (error) { e.target.style.border = '1px solid red'; }
1137 }
1138}
1139
1140Live.prototype.getData = function () {
1141 let code = '',
1142 inputs = this.inpLive.querySelectorAll('input');
1143
1144 for (let i = 0; i < inputs.length; i++) code += inputs[i].value;
1145
1146 if (code.length == 6 && !isNaN(code)) {
1147 this.log('Sending GET requests to Quizlet...', '#3884ff');
1148 fetch(`https://quizlet.com/webapi/3.2/game-instances?filters={"gameCode":${code},"isInProgress":true,"isDeleted":false}&perPage=500`)
1149 .then((resp) => resp.json())
1150 .then((data) => {
1151 this.log('Recieved data from Quizlet.', '#3884ff');
1152 if (data.responses[0].models.gameInstance.length > 0) {
1153 let id = data.responses[0].models.gameInstance[0].itemId;
1154 fetch(`https://quizlet.com/${id}/flashcards`)
1155 .then(e => e.text())
1156 .then(html => {
1157 let matches = html.match(/window\.Quizlet\["cardsModeData"\] = (.+?); QLoad\("Quizlet\.cardsModeData"\);/);
1158 try {
1159 this.input.value = matches[1];
1160 this.data = JSON.parse(matches[1]);
1161 this.log('Found answers!', '#339b00');
1162 } catch (e) { this.log('Unable to find answers!', '#ff0015'); }
1163 });
1164 this.log('Grabbing answers...', '#fff');
1165 } else {
1166 this.log('Unable to find live game with code ' + code, '#ff0015');
1167 }
1168 })
1169 .catch((e) => {
1170 this.log('Unable to send request.', '#ef9700');
1171 });
1172 } else {
1173 this.log('Please enter a correct live code!', '#ff0015');
1174 this.inpLive.classList.toggle('shakingElement');
1175 setTimeout(() => { this.inpLive.classList.toggle('shakingElement'); }, 400);
1176 }
1177}
1178
1179Live.prototype.setup = function () {
1180 for (let i = 0; i < this.inputs.length; i++) {
1181 let input = this.inputs[i];
1182 input.style = 'border: none; border-bottom: 1px solid #969696; background-color: rgba(0,0,0,0.1); text-align: center; outline: none; margin: 1px 1px; width: 20px; color: #fff;';
1183
1184 input.name = i;
1185 input.maxLength = 1;
1186 input.placeholder = i + 1;
1187
1188 input.onkeydown = e => {
1189 if (!(e.keyCode == 86 || e.which == 86) && !e.ctrlKey && e.shiftKey && e.altKey)
1190 e.preventDefault();
1191
1192 let nextInput = this.inpLive.querySelectorAll('input[name="' + (Number(e.target.name) + 1) + '"')[0],
1193 prevInput = this.inpLive.querySelectorAll('input[name="' + (Number(e.target.name) - 1) + '"]')[0];
1194
1195 if (e.keyCode == 8 || e.which == 8) {
1196 e.target.value = '';
1197 if (prevInput) {
1198 prevInput.value = '';
1199 setTimeout(() => { prevInput.focus(); }, 0);
1200 }
1201 } else if (e.key.match(/[0-9]/) != null) {
1202 e.target.value = e.key;
1203 if (nextInput) setTimeout(() => { nextInput.focus(); }, 0);
1204 }
1205 }
1206 }
1207}
1208
1209Live.prototype.paste = function (e) {
1210 let clipboardData = e.clipboardData || window.clipboardData,
1211 pastedData = clipboardData.getData('Text');
1212
1213 let formattedText = pastedData.replace(/[^0-9]/g, '').slice(0, 6);
1214 for (let i = 0; i < this.inputs.length; i++)
1215 this.inputs[i].value = formattedText[i];
1216}
1217
1218Live.prototype.interval = function () {
1219 if (this.data && Object.keys(this.data).length > 0 && window.location.href.indexOf('quizlet') > 0 && window.location.href.indexOf('live') > 0) {
1220 if (document.getElementById('liveAnswerPhrase') && document.getElementsByClassName('StudentPrompt-inner')[0] && document.getElementsByClassName('StudentTerm is-clickable can-beClicked').length) {
1221 let question = document.getElementsByClassName('StudentPrompt-inner')[0].innerText.toLowerCase().trim(),
1222 options = document.getElementsByClassName('StudentTerm is-clickable can-beClicked');
1223
1224 this.data.terms.filter(data => {
1225 if (data.word.toLowerCase() == question) return true;
1226 else if (data.definition.toLowerCase() == question) return true;
1227 }).forEach(data => {
1228 if (data.word.toLowerCase() == question) document.getElementById('liveAnswerPhrase').textContent = word.definition;
1229 else document.getElementById('liveAnswerPhrase').textContent = data.word;
1230
1231 if (!this.paused) {
1232 for (let i = 0; i < options.length; i++) {
1233 let option = options[i].innerText.toLowerCase().trim();
1234 if (data.definition.toLowerCase() == option) this.click(options[i]);
1235 else if (data.word.toLowerCase() == option) this.click(options[i]);
1236 }
1237 }
1238 });
1239 }
1240 }
1241}
1242function Flashcards() {
1243 const options = {
1244 'text': atob('RHJldyBTbm93IHdhcyBoZXJl'),
1245 'size': 150,
1246 'weight': 800,
1247 'speed': 2500
1248 };
1249
1250 for (let i = 0; i < 50; i++) {
1251 let element = document.createElement('div');
1252 element.className = 'floatingElements'
1253 element.style = `width: 100%; height: 100%; margin: auto; pointer-events: none; user-select: none; font-weight: ${options.weight}; font-size: ${options.size}px; position: absolute; z-index: 2147483647; transition: all ${options.speed/1000}s linear; transform-origin: center center; text-align: center;`;
1254 element.textContent = options.text;
1255
1256 document.body.appendChild(element);
1257 }
1258
1259 setInterval(() => {
1260 let elements = document.getElementsByClassName('floatingElements');
1261 for (let i = 0; i < elements.length; i++) {
1262 elements[i].style.color = color();
1263 elements[i].style.opacity = Math.random() + .1;
1264 elements[i].style.transform = `rotate(${drewsnow.random(0,360)}deg) translate(${drewsnow.random(-1000,1000)}px, ${drewsnow.random(-500,500)}px) translate3d(${drewsnow.random(0,200)}px,${drewsnow.random(0,200)}px,${drewsnow.random(0,200)}px) rotateX(${drewsnow.random(0,360)}deg) rotateY(${drewsnow.random(0,360)}deg) rotateZ(${drewsnow.random(0,360)}deg)`;
1265 }
1266 }, options.speed);
1267
1268 function color() { return ['red', 'orange', 'yellow', 'green', 'blue', 'purple', 'pink'][Math.floor(Math.random() * 7)]; }
1269}
1270function Gravity() {
1271 this.speed = 100;
1272 this.score = settings.current.gravity.score || 4294967295;
1273
1274 Answers.post('gravity', this.score);
1275
1276 this.loop = setInterval(() => {
1277 this.wrong();
1278 }, this.speed);
1279}
1280
1281Gravity.prototype.solve = function () {
1282 let input = document.getElementsByClassName('GravityTypingPrompt-input')[0],
1283 element = this.elements()[0];
1284
1285 if (!element || !input) return;
1286
1287 let text = this.text(element).innerText,
1288 src = this.image(element).src,
1289 answer = Answers.exact(text, src);
1290
1291 if (answer) {
1292 input.value = answer;
1293 input.focus();
1294 }
1295}
1296
1297Gravity.prototype.wrong = () => {
1298 let element = document.getElementsByClassName('GravityCopyTermView-answer')[0],
1299 input = document.getElementsByClassName('GravityCopyTermView-input')[0],
1300 answer = undefined;
1301
1302 if (!element || !input) return;
1303 input.value = element.innerText;
1304 input.focus();
1305}
1306
1307Gravity.prototype.elements = () => {
1308 return document.getElementsByClassName('GravityTerm');
1309}
1310
1311Gravity.prototype.text = element => {
1312 let elem = element.getElementsByClassName('TermText')[0];
1313
1314 if (!elem) return document.createElement('span');
1315 return elem;
1316}
1317
1318Gravity.prototype.image = element => {
1319 let elem = element.getElementsByTagName('img')[0];
1320
1321 if (!elem) return document.createElement('img');
1322 return elem;
1323}
1324function Learn() {
1325 this.interval = settings.current.learn.speed || 100;
1326 this.running = true;
1327
1328 this.interval = setInterval(() => {
1329 if (this.running) this.loop();
1330 }, this.interval);
1331}
1332
1333Learn.prototype.pause = function () {
1334 this.running = false;
1335}
1336
1337Learn.prototype.start = function () {
1338 this.running = true;
1339}
1340
1341Learn.prototype.loop = function () {
1342 if (this.mode() == 'choice') this.solve();
1343 else if (this.mode() == 'written' || this.mode() == 'flashcards') {
1344 let btns = document.getElementsByClassName('UIButton');
1345
1346 for (let i = 0; i < btns.length; ++i)
1347 if (btns[i].innerText.trim() == 'Options') btns[i].click();
1348
1349 alert('Please make sure \'Question Type\' is set to choice only.');
1350 this.running = false;
1351 }
1352 else if (this.mode() == 'other') this.next();
1353}
1354
1355Learn.prototype.solve = function () {
1356 let elements = this.questions(),
1357 answers = this.answers();
1358
1359 loop:
1360 for (let i = 0; i < elements.length; ++i) {
1361 for (let j = 0; j < answers.length; ++j) {
1362 if (elements[i].innerText.substr(2) == answers[j]) {
1363 elements[i].click();
1364 break loop;
1365 }
1366 }
1367 }
1368}
1369
1370Learn.prototype.answers = function () {
1371 if (this.questions().length == 0) return [];
1372
1373 return Answers.exact(this.text().innerText, this.image().src);
1374}
1375
1376Learn.prototype.next = () => {
1377 let btns = document.getElementsByClassName('UIButton');
1378
1379 for (let i = 0; i < btns.length; ++i) {
1380 if (btns[i].innerText.trim() == 'Press any key to continue') btns[i].click();
1381 }
1382}
1383
1384Learn.prototype.questions = () => {
1385 let assistant = document.getElementsByClassName('AssistantMultipleChoiceQuestionPromptView-termOption'),
1386 learn = document.getElementsByClassName('LearnMultipleChoiceQuestionPrompt-termOption'),
1387 mc = document.getElementsByClassName('MultipleChoiceQuestionPrompt-termOption');
1388
1389 return [...assistant, ...learn, ...mc];
1390}
1391
1392Learn.prototype.parent = () => {
1393 let assistant = document.getElementsByClassName('AssistantMultipleChoiceQuestionPromptView-promptArea'),
1394 learn = document.getElementsByClassName('LearnMultipleChoiceQuestionPrompt-promptArea'),
1395 mc = document.getElementsByClassName('MultipleChoiceQuestionPrompt-promptArea');
1396
1397 return [...assistant, ...learn, ...mc][0];
1398}
1399
1400Learn.prototype.image = function () {
1401 if (this.questions().length == 0) return false;
1402
1403 let container = this.parent().getElementsByClassName('FormattedTextWithImage-image')[0];
1404 if (!container) return document.createElement('img');
1405
1406 return container.getElementsByClassName('Image-image')[0];
1407}
1408
1409Learn.prototype.text = function () {
1410 if (this.questions().length == 0) return false;
1411
1412 let container = this.parent().getElementsByClassName('PromptTextWithImage')[0],
1413 parent = container.getElementsByClassName('FormattedText')[0];
1414
1415 if (!parent) return document.createElement('div');
1416
1417 return parent.children[0];
1418}
1419
1420Learn.prototype.mode = () => {
1421 if (document.getElementsByClassName('AssistantMultipleChoiceQuestionPromptView-termOption').length > 0 || document.getElementsByClassName('LearnMultipleChoiceQuestionPrompt-termOption').length > 0 || document.getElementsByClassName('MultipleChoiceQuestionPrompt-termOptions').length > 0) return 'choice';
1422 if (document.getElementsByClassName('AutoExpandTextarea-textarea').length > 0) return 'written';
1423 if (document.getElementsByClassName('FlippableFlashcard').length > 0) return 'flashcards';
1424
1425 return 'other';
1426}
1427function Match() {
1428 this.colors = ['#87b5ff', '#7dffe5', '#7dff9e', '#daff7d', '#ffb44a', '#ff7236', '#ff3636', '#2672ff', '#756be8', '#a76be8', '#e86be4', '#ff2176', '#b89e9e', '#8a8124'];
1429 this.stopTime = settings.current.match.time || 0.5;
1430
1431 Answers.post('match', this.stopTime);
1432 this.start();
1433
1434 this.interval = setInterval(() => {
1435 if (this.time() >= this.stopTime) {
1436 clearInterval(this.interval);
1437 this.stop();
1438 }
1439 }, 50);
1440
1441 setTimeout(() => {
1442 this.color();
1443 }, 1);
1444}
1445
1446Match.prototype.stop = () => {
1447 let timeouts = setTimeout(';');
1448 for (let i = 0; i < timeouts; i++) clearTimeout(i);
1449}
1450
1451Match.prototype.start = () => {
1452 let btns = document.getElementsByClassName('UIButton');
1453
1454 if (btns[0]) btns[0].click();
1455}
1456
1457Match.prototype.time = () => {
1458 let elem = document.getElementsByClassName('MatchModeControls-currentTime')[0];
1459 if (!elem) return -1;
1460
1461 return Number(elem.innerText);
1462}
1463
1464Match.prototype.color = function() {
1465 let tiles = this.tiles();
1466
1467 for (let i = 0; i < tiles.length; ++i) {
1468 let text = this.text(tiles[i]).innerText,
1469 src = this.image(tiles[i]).src,
1470 color = this.colors[i];
1471
1472 let options = document.querySelectorAll('.MatchModeQuestionScatterTile:not(.solved)');
1473
1474 if (text == '...') text = '';
1475 let answer = Answers.exact(text, src).random(),
1476 match = undefined;
1477
1478 for (let j = 0; j < options.length; ++j) {
1479 let text = this.text(options[j]).innerText;
1480 if (text == '...') text = '';
1481 if (text == answer) {
1482 match = options[j];
1483 break;
1484 }
1485 }
1486
1487 if (!match) continue;
1488
1489 tiles[i].style.backgroundColor = color;
1490 match.style.backgroundColor = color;
1491
1492 tiles[i].classList.add('solved');
1493 match.classList.add('solved');
1494 }
1495}
1496
1497Match.prototype.tiles = () => {
1498 return document.getElementsByClassName('MatchModeQuestionScatterTile');
1499}
1500
1501Match.prototype.text = element => {
1502 let elem = element.getElementsByClassName('TermText')[0];
1503
1504 if (!elem) return document.createElement('span');
1505 return elem;
1506}
1507
1508Match.prototype.image = element => {
1509 let elem = element.getElementsByClassName('MatchModeQuestionScatterTile-image')[0];
1510
1511 if (!elem) return document.createElement('img');
1512 return elem;
1513}
1514function Micromatch() {
1515 this.redirect();
1516}
1517
1518Micromatch.prototype.redirect = () => {
1519 window.location.href = window.location.href.replace('micromatch', 'match');
1520}
1521function Spell() {
1522 this.hijack();
1523 this.play();
1524
1525 this.cooldown = 10;
1526 this.last_called = Date.now();
1527
1528 try {
1529 document.getElementsByClassName('UIIcon--audio')[0].parentElement.click()
1530 } catch(e) {}
1531}
1532
1533Spell.prototype.play = function () {
1534 let elem1 = document.getElementById('js-spellReplayAudio'),
1535 elem2 = document.getElementsByClassName('SpellQuestionView-replayAudio')[0];
1536
1537 let event = new KeyboardEvent('keydown', {
1538 bubbles: true,
1539 cancelable: true,
1540 char: 'Escape',
1541 key: 'Escape',
1542 shiftKey: false,
1543 keyCode: 27,
1544 which: 27
1545 });
1546 (elem2 || elem1).dispatchEvent(event);
1547}
1548
1549Spell.prototype.input = () => {
1550 let elem1 = document.getElementById('js-spellInput'),
1551 elem2 = document.getElementsByClassName('AutoExpandTextarea-textarea')[0],
1552 elem3 = document.querySelector('textarea');
1553
1554 return elem2 || elem1 || elem3;
1555}
1556
1557Spell.prototype.alert = function () {
1558 Alert(
1559 'SnowLord\'s Quizlet Extension',
1560 `<h2>Game Mode: Spell</h2>Thank you for using SnowLord7's Quizlet Exploit<br>Without you, this exploit wouldn't be possible.<br><h4>Instructions:</h4>Just wait for this script to finish!<br><br><button class="UIButton" type="button"><span class="UIButton-wrapper"><span>Inject</span></span></button>`
1561 );
1562}
1563
1564Spell.prototype.hijack = function () {
1565 let self = this;
1566
1567 Howl.prototype.oldPlay = Howl.prototype.play;
1568 Howl.prototype.play = function () { self.solve(this); }
1569}
1570
1571Spell.prototype.enter = function () {
1572 let event = new KeyboardEvent('keydown', {
1573 bubbles: true,
1574 cancelable: true,
1575 char: 'Enter',
1576 key: 'Enter',
1577 shiftKey: false,
1578 keyCode: 13,
1579 which: 13
1580 });
1581 this.input().dispatchEvent(event);
1582}
1583
1584Spell.prototype.solve = function (e) {
1585 e.oldPlay();
1586
1587 let now = Date.now();
1588 if (now - this.last_called <= this.cooldown) return false;
1589 this.last_called = now;
1590
1591 let terms = Answers.get(),
1592 answer = e._src,
1593 input = this.input();
1594
1595 for (let i = 0; i < terms.length; ++i) {
1596 let src = terms[i]._wordAudioUrl;
1597 if (src == answer) {
1598 let word = terms[i].word;
1599
1600 let event = window.document.createEvent('Event');
1601 event.initEvent('input', true, true);
1602
1603 let inp = input,
1604 data = Object.getOwnPropertyDescriptor(inp.constructor.prototype, 'value');
1605
1606 (null == data ? void 0 : data.set) ? data.set.call(inp, word) : inp.value = word;
1607 input.dispatchEvent(event);
1608
1609 //setTimeout(() => { this.enter(); }, 100);
1610 break;
1611 }
1612 }
1613}
1614~function() {
1615 window.Test = function() {
1616 this.truefalse = new TrueFalse();
1617 this.choice = new Choice();
1618 this.write = new Written();
1619 this.match = new Matching();
1620
1621 drewsnow.addKeyBind(bool => {
1622 let elements = document.getElementsByClassName('answer');
1623
1624 for (let i = 0; i < elements.length; ++i)
1625 elements[i].style.opacity = +bool;
1626 }, settings.current.test.key || 67, 'c');
1627 }
1628
1629 // True false mode
1630 function TrueFalse() {
1631 this.solve();
1632 }
1633
1634 TrueFalse.prototype.solve = function () {
1635 let elements = this.elements();
1636
1637 for (let i = 0; i < elements.length; ++i) {
1638 let question = this.question(elements[i]).innerText,
1639 response = this.answer(elements[i]).innerText,
1640 src = this.image(elements[i]).src,
1641 options = this.options(elements[i]),
1642 answer = Answers.exact(question, src).random();
1643
1644 if (answer == response) options[0].click();
1645 else options[1].click();
1646 }
1647 }
1648
1649 TrueFalse.prototype.elements = () => {
1650 return document.getElementsByClassName('TestModeTrueFalseQuestion');
1651 }
1652
1653 TrueFalse.prototype.question = element => {
1654 let parent = element.getElementsByClassName('TermText')[0];
1655
1656 if (!parent) return document.createElement('span');
1657 return parent;
1658 }
1659
1660 TrueFalse.prototype.image = element => {
1661 let parent = element.getElementsByClassName('TestModeTermText-image')[0];
1662
1663 if (!parent) return document.createElement('img');
1664 return parent;
1665 }
1666
1667 TrueFalse.prototype.answer = element => {
1668 let parent = element.getElementsByClassName('TermText')[1];
1669
1670 if (!parent) return document.createElement('span');
1671 return parent;
1672 }
1673
1674 TrueFalse.prototype.options = element => {
1675 return element.getElementsByTagName('input');
1676 }
1677
1678 // Choice Mode
1679 function Choice() {
1680 this.solve();
1681 }
1682
1683 Choice.prototype.solve = function () {
1684 let elements = this.elements();
1685
1686 for (let i = 0; i < elements.length; ++i) {
1687 let question = this.question(elements[i]).innerText,
1688 answers = this.answers(elements[i]),
1689 src = this.image(elements[i]).src,
1690 answer = Answers.exact(question, src).random();
1691
1692 for (let j = 0; j < answers.length; j++) {
1693 if (this.text(answers[j]).innerText == answer) {
1694 answers[j].click();
1695 break;
1696 }
1697 }
1698 }
1699 }
1700
1701 Choice.prototype.elements = () => {
1702 return document.getElementsByClassName('TestModeMultipleChoiceQuestion');
1703 }
1704
1705 Choice.prototype.question = element => {
1706 let parent = element.getElementsByClassName('TestModeMultipleChoiceQuestion-prompt')[0];
1707
1708 if (!parent) return document.createElement('span');
1709 return parent.getElementsByClassName('TermText')[0];
1710 }
1711
1712 Choice.prototype.image = element => {
1713 let parent = element.getElementsByClassName('TestModeTermText-image')[0];
1714
1715 if (!parent) return document.createElement('img');
1716 return parent;
1717 }
1718
1719 Choice.prototype.answers = element => {
1720 return element.getElementsByClassName('TestModeMultipleChoiceQuestion-choice');
1721 }
1722
1723 Choice.prototype.text = element => {
1724 let text = element.getElementsByClassName('TestModeTermText')[0];
1725
1726 if (!text) return document.createElement('span');
1727 return text.getElementsByClassName('TermText')[0];
1728 }
1729
1730 // Matching Mode
1731 function Matching() {
1732 this.matches = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
1733 this.solve();
1734 }
1735
1736 Matching.prototype.solve = function () {
1737 let questions = this.questions(),
1738 answers = this.answers();
1739
1740 for (let i = 0; i < answers.length; ++i) {
1741 let text = this.text(answers[i]).innerText,
1742 src = this.image(answers[i]).src,
1743 answer = Answers.exact(text, src).random();
1744
1745 for (let j = 0; j < questions.length; j++) {
1746 if (questions[j].innerText == answer) {
1747 let input = this.input(questions[j])
1748 input.placeholder = this.matches[i];
1749 break;
1750 }
1751 }
1752 }
1753 }
1754
1755 Matching.prototype.questions = () => {
1756 return document.getElementsByClassName('TestModeMatchingQuestion-promptSideListItem');
1757 }
1758
1759 Matching.prototype.input = element => {
1760 let input = element.getElementsByTagName('input')[0];
1761
1762 if (!input) return document.createElement('input');
1763 return input;
1764 }
1765
1766 Matching.prototype.text = element => {
1767 let text = element.getElementsByClassName('TermText')[0];
1768
1769 if (!text) return document.createElement('span');
1770 return text;
1771 }
1772
1773 Matching.prototype.answers = () => {
1774 return document.getElementsByClassName('TestModeMatchingQuestion-optionsSideListItem');
1775 }
1776
1777 Matching.prototype.image = element => {
1778 let parent = element.getElementsByClassName('TestModeTermText-image')[0];
1779
1780 if (!parent) return document.createElement('img');
1781 return parent;
1782 }
1783
1784 // Written mode
1785 function Written() {
1786 this.solve();
1787 }
1788
1789 Written.prototype.solve = function() {
1790 let elements = this.elements();
1791
1792 for (let i = 0; i < elements.length; ++i) {
1793 let parent = elements[i],
1794 text = this.text(parent).innerText,
1795 image = this.image(parent).src,
1796 input = this.input(parent);
1797
1798 let elem = parent.getElementsByClassName('answer')[0];
1799
1800 if (!elem) {
1801 elem = document.createElement('input');
1802 elem.readonly = true;
1803 elem.onclick = function () {
1804 this.select();
1805 document.execCommand('copy');
1806 }
1807 elem.className = 'answer';
1808 elem.style = 'outline: none; display: block; border-radius: 5px; border: 1px solid #000; opacity: .8; text-align: center;';
1809 parent.appendChild(elem);
1810 }
1811
1812 elem.value = Answers.exact(text, image).random();
1813 }
1814 }
1815
1816 Written.prototype.elements = () => {
1817 return document.getElementsByClassName('TestModeWrittenQuestion');
1818 }
1819
1820 Written.prototype.text = element => {
1821 let parent = element.getElementsByClassName('TestModeTermText')[0];
1822
1823 if (!parent) return document.createElement('span');
1824 return parent.getElementsByClassName('TermText')[0];
1825 }
1826
1827 Written.prototype.image = element => {
1828 let parent = element.getElementsByClassName('TestModeTermText-image')[0];
1829
1830 if (!parent) return document.createElement('img');
1831 return parent;
1832 }
1833
1834 Written.prototype.input = element => {
1835 let parent = element.getElementsByTagName('textarea')[0];
1836
1837 if (!parent) return document.createElement('textarea');
1838 return parent;
1839 }
1840}();
1841function Write() {
1842 this.speed = 50;
1843 this.solve();
1844}
1845
1846Write.prototype.solve = function () {
1847 let element = document.getElementsByClassName('LearnModeProgressBar-value')[0];
1848
1849 if (element) {
1850 let remaining = Number(element.innerText) || 0;
1851
1852 for (let i = 0; i < remaining; i++) {
1853 setTimeout(() => {
1854 document.getElementById('user-answer').value = 'abcdefghijk';
1855 document.getElementById('js-learnModeAnswerButton').click();
1856 document.getElementsByClassName('js-learnModeOverrideIncorrect')[0].click();
1857 }, i * this.speed);
1858 }
1859 }
1860}
1861function Exploit() {
1862 this.version = '0.0.1';
1863 this.attempts = 0;
1864 this.mode = undefined;
1865 //this.detect();
1866}
1867
1868Exploit.prototype.modules = function () {
1869 let missing = [];
1870 if (window.Answers == undefined) missing.push('Answers.js');
1871 if (window.Flashcards == undefined) missing.push('Flashcards.js');
1872 if (window.Alert == undefined) missing.push('Functions.js');
1873 if (window.obfuscate == undefined) missing.push('Functions.js');
1874 if (window.Gravity == undefined) missing.push('Gravity.js');
1875 if (window.Learn == undefined) missing.push('Learn.js');
1876 if (window.Live == undefined) missing.push('Live.js');
1877 if (window.Match == undefined) missing.push('Match.js');
1878 if (window.Micromatch == undefined) missing.push('Micromatch.js');
1879 if (window.drewsnow == undefined) missing.push('Module.js');
1880 if (window.settings == undefined) missing.push('Settings.js');
1881 if (window.Spell == undefined) missing.push('Spell.js');
1882 if (window.Test == undefined) missing.push('Test.js');
1883 if (window.Write == undefined) missing.push('Write.js');
1884 return missing;
1885}
1886
1887Exploit.prototype.detect = function () {
1888 try {
1889 const email = window.Quizlet.coreData.user.email;
1890 if (email.indexOf('sandi.net') != -1) alert('Mrs. Mcglin is watching you');
1891 } catch (e) { console.log('Error getting email, but email isn\'t important so ignore this.'); }
1892}
1893
1894Exploit.prototype.exceeded = function () {
1895 console.error('ERROR: Unable to find / load required modules after (10) attempts.');
1896 return false;
1897}
1898
1899Exploit.prototype.init = function () {
1900 let href = window.location.href,
1901 option = undefined,
1902 missing = this.modules();
1903
1904
1905 if (window.location.host !== 'quizlet.com') window.location.href = 'https://quizlet.com/latest';
1906
1907 if (this.attempts > 9) return this.exceeded();
1908
1909 if (missing.length > 0) {
1910 console.warn('Missing modules', missing.join(', '));
1911 this.attempts++;
1912
1913 return setTimeout(() => { this.init(); }, 100);
1914 }
1915 console.log('All modules have been loaded!');
1916
1917 try {
1918 Quizlet.NotificationContainer.addNotification({
1919 title: 'Quizlet Extension v0.12',
1920 message: atob('VGhhbmsgeW91IGZvciB1c2luZyBEcmV3IFNub3cncyBRdWl6bGV0IEV4dGVuc2lvbi4='),
1921 });
1922 } catch(e) {}
1923
1924 if (settings['\x63\x75\x72\x72\x65\x6E\x74']['\x64\x65\x76\x65\x6C\x6F\x70\x65\x72'] != '\x44\x72\x65\x77\x20\x53\x6E\x6F\x77') return;
1925 if (href.includes('/learn')) option = 'Learn';
1926 else if (href.includes('/flashcards')) option = 'Flashcards';
1927 else if (href.includes('/write')) option = 'Write';
1928 else if (href.includes('/spell')) option = 'Spell';
1929 else if (href.includes('/test')) option = 'Test';
1930 else if (href.includes('/micromatch')) option = 'Micromatch';
1931 else if (href.includes('/match')) option = 'Match';
1932 else if (href.includes('/gravity')) option = 'Gravity';
1933 else if (href.includes('/live')) option = 'Live';
1934 else {
1935 alert('Error: Please go to a supported gamemode.');
1936 return -1;
1937 }
1938
1939 try {
1940 if (Answers.duplicates()) Alert('Duplicate terms found!', 'Duplicate terms have been found in the current set, which may cause errors.');
1941 this.mode = new window[option]();
1942 } catch (e) { alert('Error: ' + e); }
1943
1944 (() => { document.title = 'Quizlet v' + this.version + ' | ' + (Quizlet.user.username || 'unknown') + ' | ' + (settings.current.developer || 'unknown'); let e = document.createElement('script'); e.src = 'https://www.googletagmanager.com/gtag/js?id=UA-119530221-2', e.onload = function () { function e() { dataLayer.push(arguments) } window.dataLayer = window.dataLayer || [], e('js', new Date), e('config', 'UA-119530221-2'), this.remove() }, document.head.appendChild(e) })();
1945}
1946
1947var Session = new Exploit();
1948Session.init();