Khan Academy Hack

Respostas

  1. // ==UserScript==
  2. // @name Khan Academy Hack
  3. // @version 2.0
  4. // @description Respostas
  5. // @author Kinjinho
  6. // @match https://pt.khanacademy.org/*
  7. // @grant none
  8. // @namespace https://greasyfork.org/users/1064859
  9. // ==/UserScript==
  10.  
  11.  
  12. (function () {
  13. let overlayHTML = ` <link rel="preconnect" href="https://fonts.googleapis.com">
  14. <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  15. <link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
  16. <div id="box">
  17. <button class="main" id="accordian">=</button>
  18. <div class="main" id="box2">
  19. <center><p class="pdark" id="pdark"> Krakdemy V2 </p></center>
  20. <button onclick="location.reload()" class="inputans">Resetar lista</button>
  21. <br>
  22. <center><section><label id="ansHead">Respostas:</label></section></center>
  23.  
  24. <center id="mainCen">
  25. <section><label id="ansBreak">&nbsp;</label></section>
  26.  
  27. </center>
  28. <section><label>&nbsp;</label></section>
  29. <section class="toggleclass"><label>Tecla F esconde o menu</label></section>
  30. <section class="toggleclass"><label>Patch 21e58d6m8a24</label></section>
  31. </div>
  32. </div>
  33.  
  34. <style>
  35. #box {
  36. z-index: 9999;
  37. position: fixed;
  38. top: 0;
  39. right: 0;}
  40. #box2 {
  41. padding: 15px;
  42. margin-bottom: 5px;
  43. display: grid;
  44. border-radius: 15px;};
  45. section {
  46. display: flex;
  47. justify-content: space-between;margin:5px;}
  48. .main {
  49. background-color: #15151515;
  50. letter-spacing: 2px;
  51. font-weight: none;
  52. font-size: 11px;
  53. font-family: 'Roboto', sans-serif;
  54. color:#1e1e1e;
  55. webkit-user-select: all;}
  56. .pdark {
  57. border-bottom:2px solid black;
  58.  
  59. }
  60. #accordian {
  61. width: 100%;
  62. border: 0;
  63. cursor: pointer;
  64. border-radius: 25px;}
  65. .inputans {
  66. border: 0;
  67. cursor: pointer;
  68. border-radius: 25px;
  69. background-color: #30303030;
  70. color: black;
  71. font-family: 'Roboto', sans-serif;
  72. }
  73. .inputans:hover {
  74. background-color: #121212;
  75. color: white;
  76. }
  77. .toggleclass {
  78. text-align: center;
  79. }
  80. </style>
  81. `
  82.  
  83.  
  84.  
  85. function get(x) { return document.getElementById(x); }
  86.  
  87. let overlay = document.createElement("div");
  88. overlay.innerHTML = overlayHTML;
  89. document.body.appendChild(overlay);
  90.  
  91. let acc = get("accordian"),
  92. darkToggle = get("darkToggle"),
  93. ansbutton = get("inputans"),
  94. ansbutton2 = get("inputans2")
  95.  
  96. acc.onclick = function() {
  97. let panel = get("box2");
  98. let acc = get("accordian")
  99. if (panel.style.display == "grid") panel.style.display = "none";
  100. else { panel.style.display = "grid";}
  101.  
  102. }
  103.  
  104. document.addEventListener('keydown', (event) => {
  105. if (event.key === 'f') {
  106.  
  107. let panel = get("box2");
  108. if (panel.style.display == "grid") panel.style.display = "none";
  109. else { panel.style.display = "grid"; }
  110. }
  111. });
  112. document.addEventListener('keydown', (event) => {
  113. if (event.key === 'F') {
  114.  
  115. let panel = get("box2");
  116. if (panel.style.display == "grid") panel.style.display = "none";
  117. else { panel.style.display = "grid"; }
  118. }
  119. });
  120.  
  121. 'use strict';
  122. window.loaded = false;
  123.  
  124. class Answer {
  125.  
  126. constructor(answer, type) {
  127. this.body = answer;
  128. this.type = type;
  129. }
  130.  
  131. get isMultiChoice() {
  132. return this.type == "multiple_choice";
  133. }
  134.  
  135. get isFreeResponse() {
  136. return this.type == "free_response";
  137. }
  138.  
  139. get isExpression() {
  140. return this.type == "expression";
  141. }
  142.  
  143. get isDropdown() {
  144. return this.type == "dropdown";
  145. }
  146.  
  147. log() {
  148. const answer = this.body;
  149.  
  150. answer.map(ans => {
  151. if (typeof ans == "string") {
  152. if (ans.includes("web+graphie")) {
  153. this.body[this.body.indexOf(ans)] = "";
  154. this.printImage(ans);
  155. } else {
  156. answer[answer.indexOf(ans)] = ans.replaceAll(" ", "");
  157. }
  158. }
  159. });
  160.  
  161.  
  162. }
  163.  
  164.  
  165. }
  166.  
  167. const originalFetch = window.fetch;
  168. window.fetch = function () {
  169. return originalFetch.apply(this, arguments).then(async (res) => {
  170. if (res.url.includes("/getAssessmentItem")) {
  171. const clone = res.clone();
  172. const json = await clone.json()
  173. let item, question;
  174.  
  175.  
  176. item = json.data.assessmentItem.item.itemData;
  177. question = JSON.parse(item).question;
  178.  
  179.  
  180. Object.keys(question.widgets).map(widgetName => {
  181. switch (widgetName.split(" ")[0]) {
  182. case "numeric-input":
  183. return freeResponseAnswerFrom(question).log();
  184. case "radio":
  185. return multipleChoiceAnswerFrom(question).log();
  186. case "expression":
  187. return expressionAnswerFrom(question).log();
  188. case "dropdown":
  189. return dropdownAnswerFrom(question).log();
  190. }
  191. });
  192. }
  193.  
  194. if (!window.loaded) {
  195. console.clear();
  196.  
  197. window.loaded = true;
  198. }
  199.  
  200. return res;
  201. })
  202. }
  203.  
  204. let curAns = 1
  205.  
  206. function freeResponseAnswerFrom(question) {
  207. const answer = Object.values(question.widgets).map((widget) => {
  208. if (widget.options?.answers) {
  209. return widget.options.answers.map(answer => {
  210. if (answer.status == "correct") {
  211.  
  212. var parNumCurAns = "parNum" + curAns
  213. var createPar = document.createElement('section')
  214. createPar.innerHTML = answer.value
  215. document.getElementById('ansBreak').append(createPar)
  216.  
  217. curAns++
  218. }
  219. });
  220. }
  221. }).flat().filter((val) => { return val !== undefined; });
  222.  
  223. return new Answer(answer, "free_response");
  224. }
  225.  
  226.  
  227.  
  228. function multipleChoiceAnswerFrom(question) {
  229. const answer = Object.values(question.widgets).map((widget) => {
  230. if (widget.options?.choices) {
  231. return widget.options.choices.map(choice => {
  232. if (choice.correct) {
  233.  
  234. var parNumCurAns = "parNum" + curAns
  235. var createPar = document.createElement('section')
  236. createPar.innerHTML = choice.content
  237. document.getElementById('ansBreak').append(createPar)
  238.  
  239. curAns++
  240.  
  241. }
  242. });
  243. }
  244. }).flat().filter((val) => { return val !== undefined; });
  245.  
  246. return new Answer(answer, "multiple_choice");
  247. }
  248.  
  249. function expressionAnswerFrom(question) {
  250. const answer = Object.values(question.widgets).map((widget) => {
  251. if (widget.options?.answerForms) {
  252. return widget.options.answerForms.map(answer => {
  253. if (Object.values(answer).includes("correct")) {
  254.  
  255. var parNumCurAns = "parNum" + curAns
  256. var createPar = document.createElement('section')
  257. createPar.innerHTML = answer.value
  258. document.getElementById('ansBreak').append(createPar)
  259.  
  260. curAns++
  261.  
  262. }
  263. });
  264. }
  265. }).flat();
  266.  
  267. return new Answer(answer, "expression");
  268. }
  269.  
  270. function dropdownAnswerFrom(question) {
  271. const answer = Object.values(question.widgets).map((widget) => {
  272. if (widget.options?.choices) {
  273. return widget.options.choices.map(choice => {
  274. if (choice.correct) {
  275.  
  276. var parNumCurAns = "parNum" + curAns
  277. var createPar = document.createElement('section')
  278. createPar.innerHTML = choice.content
  279. document.getElementById('ansBreak').append(createPar)
  280.  
  281. curAns++
  282. }
  283. });
  284. }
  285. }).flat();
  286.  
  287. return new Answer(answer, "dropdown");
  288. }
  289. })();