Project Euler Problem Translator

Provides translations in Romanian, Russian, Korean and German for Project Euler problems

当前为 2014-09-07 提交的版本,查看 最新版本

  1. /*******************************************************************************
  2. * Copyright (c) 2012 - 2014 Radu Murzea. All rights reserved.
  3. *
  4. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  5. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  6. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  7. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  8. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  9. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  10. * THE SOFTWARE.
  11. *
  12. *******************************************************************************/
  13. /*******************************************************************************
  14. * DESCRIPTION:
  15. *
  16. * This script is intended for use only on ProjectEuler.net.
  17. * It places 5 flags (British, Romanian, Russian, Korean and German) on top of every problem's page.
  18. * By clicking on the flag, the corresponding translation of a problem is retrieved.
  19. * The technique behind this is JSONP (JSON with padding), since AJAX wouldn't
  20. * work (see Same Origin Policy).
  21. *
  22. * The processing function (only 2 - 3 lines of code) is another file,
  23. * which is retrieved from the server every time. That function will be executed
  24. * when the response comes back.
  25. *
  26. * The romanian and british versions of the problems come from the same server as the backend part
  27. * of the script; the other 3 are parsed from the corresponding translations websites:
  28. *
  29. * - http://euler.jakumo.org/ for Russian,
  30. * - http://euler.synap.co.kr/ for Korean and
  31. * - http://projekteuler.de for German
  32. *
  33. * If a problem is not translated, the word 'NONE' is sent back from the
  34. * server, a response which the script ignores.
  35. *
  36. * The 5 flag images are stored inside the script in Base64 format, to avoid
  37. * additional HTTP requests.
  38. *
  39. * As you can see: the script can be very easily extended to include
  40. * translations in dozens of languages; in this context, it is highly scalable.
  41. *
  42. *******************************************************************************/
  43. /***************************************************
  44. *
  45. * Version 1.6 (15 June 2014)
  46. * _______________________________
  47. * - Since Firefox introduced the Mixed Active Content blocker in Firefox 23, this script will
  48. * only run when viewing problems in HTTP mode and it will fail in HTTPS. So it's now
  49. * disabled on HTTPS.
  50. *
  51. * Version 1.5 (15 June 2014)
  52. * _______________________________
  53. * - Added translations in German.
  54. *
  55. * Version 1.4 (24 May 2014)
  56. * _______________________________
  57. * - Due to significant and frequent accessibility issues, support for Spanish translations is now
  58. * dropped.
  59. *
  60. *
  61. * Version 1.3 (18 March 2013)
  62. * _______________________________
  63. * - support for Korean added. At this date, 110 problems are translated in this language.
  64. *
  65. *
  66. * Version 1.2.5 (13 January 2013)
  67. * _______________________________
  68. * - the flags will no longer appear on the page exactly after
  69. * you enter a (correct or incorrect) answer. This issue existed because the URL remains
  70. * the same.
  71. * - a few minor changes
  72. *
  73. *
  74. * Version 1.2 (28 December 2012)
  75. * _______________________________
  76. * - translations are now offered in Russian and Spanish as well. These translations are parsed from
  77. * euler.jakumo.org and euleres.tk, respectively. Because of this, additional roundtrips must be made to
  78. * retrieve these translations, which is why it will feel slower... sometimes very slow.
  79. *
  80. * - some small changes here and there.
  81. *
  82. * - the backend part has been changed from "read.php" to "getjsontranslation.php". Although the old version
  83. * is still functional, it is highly recommended to switch to the new one (spanish and russian are accessible
  84. * only in the new one). Please note that the old version will be taken out of rotation on the 20th of January.
  85. *
  86. * WARNING: I have no control over how many problems are accessible in the 2 new languages and the quality
  87. * of these translations. Any problem regarding these 2 languages (Russian and Spanish) should be directed
  88. * to their authors.
  89. *
  90. * WARNING: In my tests, the Spanish version would sometimes fail for some problems and then work again
  91. * a few minutes later. Apparently, this issue has something to do
  92. * with network connection timeouts (low quality hosting ?), so this is not a bug in the script
  93. * itself. Please do not report this as a bug.
  94. *
  95. *
  96. * Version 1.0.2 (17 December 2012)
  97. * _______________________________
  98. * - script functionality was broken by some changes in
  99. * the HTML code on projecteuler.net that occured on 16 December 2012. This version
  100. * fixes this issue.
  101. *
  102. *
  103. * Version 1.0.1 (22 September 2012)
  104. * _______________________________
  105. * - added some extra safety by checking that the parsing of
  106. * the problem's ID did not return NaN
  107. *
  108. *
  109. * Version 1.0 (18 September 2012)
  110. * _______________________________
  111. * - initial release
  112. *
  113. ****************************************************/
  114.  
  115.  
  116. // ==UserScript==
  117. // @name Project Euler Problem Translator
  118. // @description Provides translations in Romanian, Russian, Korean and German for Project Euler problems
  119. // @author Radu Murzea
  120. // @version 1.6
  121. // @icon http://projecteuler.javafling.org/favicon.ico
  122. // @include http://projecteuler.net/problem=*
  123. // @grant none
  124. // @namespace https://greasyfork.org/users/5099
  125. // ==/UserScript==
  126.  
  127.  
  128.  
  129. function setNewTranslation(problem, lang)
  130. {
  131. var script = document.createElement('script');
  132. script.setAttribute('src', 'http://projecteuler.javafling.org/getjsontranslation.php?problem=' + problem + '&lang=' + lang);
  133. document.getElementsByTagName('head')[0].appendChild(script);
  134. }
  135.  
  136. function getProblemID()
  137. {
  138. var h3Nodes = document.getElementsByTagName('h3');
  139. for (var nodeIndex = 0; nodeIndex < h3Nodes.length; nodeIndex++) {
  140. var nodePieces = h3Nodes[nodeIndex].innerHTML.split(" ");
  141. if (nodePieces[0] === "Problem") {
  142. var problemID = parseInt(nodePieces[1]);
  143. return problemID;
  144. }
  145. }
  146. return -1;
  147. }
  148.  
  149. function getROFlag()
  150. {
  151. var RO = document.createElement("img");
  152. RO.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAALCAIAAAD5gJpuAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHd" +
  153. "hcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGBSURBVHjaYmTQPs7w6Q8DCDAxMLC8P2DOwcbA8I/hHxix/GD4pw3kIRBAALEwvPtT3aQIV" +
  154. "P7vH+O//0yc0hWsrD8ZGP78//8HRH75/T/mz//fv///AZFfNm0CCCAWBhYGhv8MT17//vvv/99/TP/+PWJg+P7//28o+vP7/+1f/3/9Aqp" +
  155. "mlJUF2gAQQCwgs/8zAFX/+QtCQIP///8FJn+DGP+Aqn9DNDD8/g3UABBALAx//oFV//vzhwGs4RfCeBAbRQPQdIAAYmH49Q+o7vef/zANv" +
  156. "5H0gBm/oE5i+PMHaANAAIE0/AUZ//8XUM9fBiQNYBLJSYxgJwEEEEjD778Mv/6A9Pz+wwB1BpoNYOOBbgAGHEAAsTD8BNL/gJqBrvr9lxF" +
  157. "JA8QGsIY/QA1/Gf7+BfoBIICAofQHqFRShBXkjb/MTEzSDAzfGBmB/gMa95uB5Q+D0h+QUjACOgkggBgZGLYyMPwCS4Nc+HxvMAsLw78/4" +
  158. "HgFkh8Y/oVD4xgCAAIMACetb51Fz+5FAAAAAElFTkSuQmCC";
  159. RO.alt = "Romania";
  160. RO.title = "Romanian";
  161. RO.style.cursor = "pointer";
  162. RO.onclick = function() {
  163. var problemID = getProblemID();
  164. if (! isNaN(problemID) && problemID !== -1) {
  165. setNewTranslation(problemID, "ro");
  166. }
  167. };
  168.  
  169. return RO;
  170. }
  171.  
  172. function getDEFlag()
  173. {
  174. var DE = document.createElement("img");
  175. DE.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAALCAIAAAD5gJpuAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHd" +
  176. "hcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGzSURBVHjaYvTxcWb4+53h3z8GZpZff/79+v3n/7/fDAz/GHAAgABi+f37e3FxOZD1Dwz+/" +
  177. "v3z9y+E/AMFv3//+Qumfv9et241QACxMDExAVWfOHkJJAEW/gUEP0EQDn78+AHE/gFOQJUAAcQiy8Ag8O+fLFj1n1+/QDp+/gQioK7fP37" +
  178. "8+vkDqOH39x9A/RJ/gE5lAAhAYhzcAACCQBDkgRXRjP034R0IaDTZTFZn0DItot37S94KLOINerEcI7aKHAHE8v/3r/9//zIA1f36/R+o4" +
  179. "tevf1ANYNVA9P07RD9IJQMDQACxADHD3z8Ig4GMHz+AqqHagKp//fwLVA0U//v7LwMDQACx/LZiYFD7/5/53/+///79BqK/EMZ/UPACSYa" +
  180. "/v/8DyX9A0oTxx2EGgABi+a/H8F/m339BoCoQ+g8kgRaCQvgPJJiBYmAuw39hxn+uDAABxMLwi+E/0PusRkwMvxhBGoDkH4b/v/+D2EDyz" +
  181. "///QB1/QLb8+sP0lQEggFh+vGXYM2/SP6A2Zoaf30Ex/J+PgekHwz9gQDAz/P0FYrAyMfz7wcDAzPDtFwNAgAEAd3SIyRitX1gAAAAASUV" +
  182. "ORK5CYII=";
  183. DE.alt = "Germany";
  184. DE.title = "German";
  185. DE.style.cursor = "pointer";
  186. DE.onclick = function() {
  187. var problemID = getProblemID();
  188. if (! isNaN(problemID) && problemID !== -1) {
  189. setNewTranslation(problemID, "de");
  190. }
  191. };
  192.  
  193. return DE;
  194. }
  195.  
  196. function getKRFlag()
  197. {
  198. var KR = document.createElement("img");
  199. KR.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAALCAIAAAD5gJpuAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHd" +
  200. "hcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHDSURBVHjaYjSs/f/lBwME/Pn379cfIMnw6xfDrz9A9r/fIA4SYmMACCDGgzf/q4iBlf///" +
  201. "5+B4d9/KPMfCIMY/xn+//sH4f4/duMLQAAxfmRgZO/v+/fiFcNfkJkMLEz/v3wB6fn95//fPyDy9+9/f37///WbSUry+ZzZAAHEApRifPW" +
  202. "KiYmBOSiEUV6e8efPX6tX/9m9m+HXb4bfv0Do129GoBN//2b49YOJgQEggJj+AZ3x9y+zv/+/W7f+P7j/a8cO5qCg/2xs/379AqK/P3/9/" +
  203. "QVCf4Dc30DdDAABBNLA8Ocvg6gIk77+z1Wrmays/vPwMIiI/P8N0gB0z3+wTiD5/8+fPwwMAAHEBHIu0K0vXv7evIklIODP9u0M37//e/7" +
  204. "838+fIEU/f0JVg20AKgYIIKAfGBiBdi1ZwpaY+F9SgkVN7Wdt7f83bxjBZgOdDvEA0HgmIGJgAAggFqAt/3h4/j169K29AxRQwOD78pWBi" +
  205. "+s/K+s/sDpwKAFj588/QUFghAEEEMups9+1pFlAgQ0Nc0iog6MCLAQR/weSY9hx6jVAADEyx3/9+wEWkcB4BRryC4kLj+l/QDYDAx8DQIA" +
  206. "BAA2EWORnICKSAAAAAElFTkSuQmCC";
  207. KR.alt = "Korea";
  208. KR.title = "Korean";
  209. KR.style.cursor = "pointer";
  210. KR.onclick = function() {
  211. var problemID = getProblemID();
  212. if (! isNaN(problemID) && problemID !== -1) {
  213. setNewTranslation(problemID, "kr");
  214. }
  215. };
  216. return KR;
  217. }
  218.  
  219. function getRUFlag()
  220. {
  221. var RU = document.createElement("img");
  222. RU.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAALCAIAAAD5gJpuAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHd" +
  223. "hcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAE2SURBVHjaYvz69T8DAvz79w9CQVj/0MCffwwAAcQClObiAin6/x+okxHMgPCAbOb//5n+I" +
  224. "4EXL74ABBALxGSwagTjPzbAyMgItAQggBg9Pf9nZPx//x7kjL9////9C2QAyf9//qCQQCQkxFhY+BEggFi2b/+nq8v46BEDSPQ3w+8//3/" +
  225. "/BqFfv9BJeXmQEwACCOSkP38YgHy4Bog0RN0vIOMXVOTPH6Cv/gEEEEgDxFKgHEgDXCmGDUAE1AAQQCybGZg1f/d8//XsH0jTn3+///z79" +
  226. "RtE/v4NZfz68xfI/vOX+4/0ZoZFAAHE4gYMvD+3/v2+h91wCANo9Z+/jH9VxBkYAAKIBRg9TL//MEhKAuWAogxgZzGC2CCfgUggAoYdGAE" +
  227. "VAwQQ41egu5AQAyoXTQoIAAIMAD+JZR7YOGEWAAAAAElFTkSuQmCC";
  228. RU.alt = "Russia";
  229. RU.title = "Russian";
  230. RU.style.cursor = "pointer";
  231. RU.onclick = function() {
  232. var problemID = getProblemID();
  233. if (! isNaN(problemID) && problemID !== -1) {
  234. setNewTranslation(problemID, "ru");
  235. }
  236. };
  237. return RU;
  238. }
  239.  
  240. function getUKFlag()
  241. {
  242. var UK = document.createElement("img");
  243. UK.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAALCAIAAAD5gJpuAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJ" +
  244. "lYWR5ccllPAAAAflJREFUeNpinDRzn5qN3uFDt16+YWBg+Pv339+KGN0rbVP+//2rW5tf0Hfy/2+mr99+yKpyOl3Ydt8njEWIn8f9zj639" +
  245. "NC7j78eP//8739GVUUhNUNuhl8//ysKeZrJ/v7z10Zb2PTQTIY1XZO2Xmfad+f7XgkXxuUrVB6cjPVXef78JyMjA8PFuwyX7gAZj97+T2e" +
  246. "9o3d4BWNp84K1NzubTjAB3fH0+fv6N3qP/ir9bW6ozNQCijB8/8zw/TuQ7r4/ndvN5mZgkpPXiis3Pv34+ZPh5t23//79Rwehof/9/NDEg" +
  247. "MrOXHvJcrllgpoRN8PFOwy/fzP8+gUlgZI/f/5xcPj/69e/37//AUX+/mXRkN555gsOG2xt/5hZQMwF4r9///75++f3nz8nr75gSms82jf" +
  248. "vQnT6zqvXPjC8e/srJQHo9P9fvwNtAHmG4f8zZ6dDc3bIyM2LTNlsbtfM9OPHH3FhtqUz3eXX9H+cOy9ZMB2o6t/Pn0DHMPz/b+2wXGTvP" +
  249. "lPGFxdcD+mZyjP8+8MUE6sa7a/xo6Pykn1s4zdzIZ6///8zMGpKM2pKAB0jqy4UE7/msKat6Jw5mafrsxNtWZ6/fjvNLW29qv25pQd///n" +
  250. "+5+/fxDDVbcc//P/zx/36m5Ub9zL8+7t66yEROcHK7q5bldMBAgwADcRBCuVLfoEAAAAASUVORK5CYII=";
  251. UK.alt = "United Kingdom";
  252. UK.title = "British English";
  253. UK.style.cursor = "pointer";
  254. UK.onclick = function() {
  255. var problemID = getProblemID();
  256. if (! isNaN(problemID) && problemID !== -1) {
  257. setNewTranslation(problemID, "en");
  258. }
  259. };
  260. return UK;
  261. }
  262.  
  263. function insertFlags()
  264. {
  265. var UK = getUKFlag(); //UK
  266. var RO = getROFlag(); //Romania
  267. var RU = getRUFlag(); //Russia
  268. var KR = getKRFlag(); //Korea
  269. var DE = getDEFlag(); //Germany
  270. var flagsParagraph = document.createElement("p");
  271. UK.style.marginRight = "12px";
  272. RO.style.marginRight = "12px";
  273. RU.style.marginRight = "12px";
  274. KR.style.marginRight = "12px";
  275. flagsParagraph.appendChild(UK);
  276. flagsParagraph.appendChild(RO);
  277. flagsParagraph.appendChild(RU);
  278. flagsParagraph.appendChild(KR);
  279. flagsParagraph.appendChild(DE);
  280. flagsParagraph.style.display = "block";
  281. flagsParagraph.style.marginLeft = "auto";
  282. flagsParagraph.style.marginRight = "auto";
  283. flagsParagraph.style.textAlign = "center";
  284. // reference node
  285. var refNode = document.getElementById("content");
  286. // insert before
  287. refNode.parentNode.insertBefore(flagsParagraph, refNode);
  288. }
  289.  
  290. function insertTranslationProcessing()
  291. {
  292. var pscript = document.createElement('script');
  293. pscript.setAttribute('type', 'text/javascript');
  294. pscript.setAttribute('src', 'http://projecteuler.javafling.org/processtranslation.js');
  295. var bodyElement = document.getElementsByTagName('body')[0];
  296. bodyElement.insertBefore(pscript, bodyElement.firstChild);
  297. }
  298.  
  299. var problemID = getProblemID();
  300.  
  301. if (! isNaN(problemID) && problemID !== -1) {
  302. insertFlags();
  303. insertTranslationProcessing();
  304. }