index.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <!DOCTYPE html>
  2. {% macro lang_option(lang_name, current_lang) %}
  3. <option value="{{ lang_name }}" {{ 'selected' if current_lang == lang_name else '' }}>{{ lang_name }}</option>
  4. {% endmacro %}
  5. {% macro supported_source_lang_options(current_lang) %}
  6. {% for lang_name in supported_source_languages.keys() %}
  7. {{ lang_option(lang_name, current_lang) }}
  8. {% endfor %}
  9. {% endmacro %}
  10. {% macro supported_target_lang_options(current_lang) %}
  11. {% for lang_name in supported_target_languages.keys() %}
  12. {{ lang_option(lang_name, current_lang) }}
  13. {% endfor %}
  14. {% endmacro %}
  15. <html lang="en">
  16. <head>
  17. <title>SimplyTranslate</title>
  18. <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.gif') }}">
  19. <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
  20. <meta name="description" content="Experience simple and private translations">
  21. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  22. <meta charset="UTF-8">
  23. <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
  24. <meta name="robots" content="noindex,nofollow,noarchive" />
  25. </head>
  26. <body>
  27. <div class="wrap">
  28. <header><h1>SimplyTranslate</h1><nav><a href="/?engine={{ engine }}&text={{ inp|urlencode }}&sl={{ from_l_code }}&tl={{ to_l_code }}"><?xml version="1.0" encoding="UTF-8"?>
  29. <svg width="30" height="30" viewBox="0 0 30 30">
  30. <path fill-rule="nonzero" fill="rgb(255%, 255%, 255%)" fill-opacity="1" d="M 23.753906 12.488281 C 27.199219 12.488281 30 9.6875 30 6.246094 C 30 2.800781 27.199219 0 23.753906 0 C 20.3125 0 17.511719 2.800781 17.511719 6.246094 C 17.511719 7.449219 17.863281 8.570312 18.453125 9.527344 L 8.855469 15.632812 C 7.914062 14.800781 6.679688 14.285156 5.324219 14.285156 C 2.390625 14.285156 0 16.671875 0 19.609375 C 0 22.542969 2.390625 24.933594 5.324219 24.933594 C 7.242188 24.933594 8.925781 23.90625 9.859375 22.378906 L 17.976562 25.625 C 17.988281 28.039062 19.957031 30 22.375 30 C 24.800781 30 26.773438 28.027344 26.773438 25.597656 C 26.773438 23.171875 24.800781 21.199219 22.375 21.199219 C 20.445312 21.199219 18.820312 22.453125 18.226562 24.183594 L 10.4375 21.070312 C 10.570312 20.605469 10.644531 20.117188 10.644531 19.609375 C 10.644531 18.546875 10.332031 17.5625 9.792969 16.730469 L 19.339844 10.65625 C 20.472656 11.789062 22.035156 12.488281 23.753906 12.488281 Z M 22.375 22.625 C 24.011719 22.625 25.347656 23.960938 25.347656 25.597656 C 25.347656 27.238281 24.011719 28.570312 22.375 28.570312 C 20.734375 28.570312 19.402344 27.238281 19.402344 25.597656 C 19.402344 23.960938 20.734375 22.625 22.375 22.625 Z M 5.324219 23.5 C 3.175781 23.5 1.429688 21.753906 1.429688 19.609375 C 1.429688 17.460938 3.175781 15.714844 5.324219 15.714844 C 7.46875 15.714844 9.21875 17.460938 9.21875 19.609375 C 9.21875 21.757812 7.472656 23.5 5.324219 23.5 Z M 23.753906 1.429688 C 26.414062 1.429688 28.570312 3.589844 28.570312 6.246094 C 28.570312 8.902344 26.414062 11.058594 23.753906 11.058594 C 21.101562 11.058594 18.941406 8.902344 18.941406 6.246094 C 18.941406 3.589844 21.101562 1.429688 23.753906 1.429688 Z M 23.753906 1.429688 "/>
  31. </svg></a></nav></header>
  32. <form class="wrap2" action="/?engine={{ engine }}" method="POST" id="translation-form">
  33. {% if engines|length > 1 %}
  34. <div>
  35. Translation Engine
  36. {% for _engine in engines %}
  37. <a style="
  38. {# Show the currently selected engine by underlining it #}
  39. {% if engine == _engine.name %}
  40. text-decoration: underline;
  41. {% endif %}
  42. " href="/?engine={{ _engine.name }}">
  43. {{ _engine.display_name -}}
  44. </a>
  45. {% if not loop.last %}
  46. {% endif %}
  47. {% endfor %}
  48. </div>
  49. <br>
  50. {% endif %}
  51. <div class="language" style="grid-area:languages1;">
  52. {% if use_text_fields %}
  53. <input type="text" id="from_language" name="from_language" aria-label="Source language" value="{{ from_l }}" placeholder="from" />
  54. {% else %}
  55. <select name="from_language" id="from_language" aria-label="Source language">
  56. {{ supported_source_lang_options(from_l) }}
  57. </select>
  58. {% endif %}
  59. </div>
  60. <div class="switch_languages">
  61. <button id="switchbutton" aria-label="Switch languages" formaction="/switchlanguages/?engine={{ engine }}" type="submit">
  62. <svg width="30" height="30" viewBox="0 0 30 30">
  63. <path fill-rule="nonzero" fill="rgb(255%, 255%, 255%)" fill-opacity="1" d="M 18.480469 2.773438 L 24.097656 8.394531 C 24.429688 8.726562 24.460938 9.246094 24.1875 9.613281 L 24.097656 9.71875 L 18.480469 15.347656 C 18.113281 15.714844 17.519531 15.714844 17.152344 15.351562 C 16.820312 15.019531 16.789062 14.496094 17.0625 14.128906 L 17.152344 14.023438 L 21.171875 9.996094 L 6.554688 9.996094 C 6.078125 9.996094 5.6875 9.644531 5.625 9.1875 L 5.617188 9.058594 C 5.617188 8.585938 5.96875 8.191406 6.425781 8.128906 L 6.554688 8.121094 L 21.175781 8.121094 L 17.152344 4.101562 C 16.820312 3.769531 16.789062 3.246094 17.0625 2.878906 L 17.152344 2.773438 C 17.484375 2.441406 18.007812 2.410156 18.375 2.683594 L 18.480469 2.773438 L 24.097656 8.394531 Z M 24.375 20.8125 L 24.382812 20.9375 C 24.382812 21.414062 24.03125 21.804688 23.574219 21.867188 L 23.445312 21.875 L 8.828125 21.875 L 12.851562 25.898438 C 13.1875 26.230469 13.214844 26.753906 12.945312 27.121094 L 12.855469 27.226562 C 12.519531 27.558594 12 27.589844 11.632812 27.316406 L 11.527344 27.226562 L 5.902344 21.605469 C 5.570312 21.273438 5.539062 20.75 5.8125 20.382812 L 5.902344 20.28125 L 11.527344 14.648438 C 11.894531 14.285156 12.488281 14.285156 12.851562 14.648438 C 13.1875 14.980469 13.214844 15.503906 12.945312 15.871094 L 12.855469 15.976562 L 8.832031 20 L 23.445312 20 C 23.921875 20 24.3125 20.355469 24.375 20.8125 L 24.382812 20.9375 Z M 24.375 20.8125 "/>
  64. </svg>
  65. </button>
  66. </div>
  67. <div class="language" style="grid-area:languages2;">
  68. {% if use_text_fields %}
  69. <input type="text" id="to_language" aria-label="Target language" name="to_language" value="{{ to_l }}" placeholder="from" />
  70. {% else %}
  71. <select name="to_language" id="to_language" aria-label="Target language">
  72. {{ supported_target_lang_options(to_l) }}
  73. </select>
  74. {% endif %}
  75. </div>
  76. {% if could_not_switch_languages %}
  77. <div id="could_not_switch_languages_text">
  78. Sorry, {{ engine }} doesn't support switching from autodetect.
  79. </div>
  80. <br>
  81. {% endif %}
  82. <textarea autofocus style="grid-area:input;" id="input" name="input" dir="auto" placeholder="Enter Text Here">{{ inp }}</textarea>
  83. {%- if tts_enabled and tts_from is not none -%}
  84. <div class="audio-player" style="grid-area:audio1;">
  85. <audio controls>
  86. <source type="audio/mpeg" src="{{ tts_from }}">
  87. </audio>
  88. </div>
  89. {%- endif -%}
  90. <button id="translate-button" type="submit">
  91. <svg width="40" height="40" viewBox="0 0 40 40">
  92. <path fill="none" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(255%, 255%, 255%)" stroke-opacity="1" stroke-miterlimit="4" d="M 232 216 L 176 104 L 120 216 " transform="matrix(0.15625, 0, 0, 0.15625, 0, 0)"/>
  93. <path fill="none" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(255%, 255%, 255%)" stroke-opacity="1" stroke-miterlimit="4" d="M 136 184 L 216 184 " transform="matrix(0.15625, 0, 0, 0.15625, 0, 0)"/>
  94. <path fill="none" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(255%, 255%, 255%)" stroke-opacity="1" stroke-miterlimit="4" d="M 88 32 L 88 56 " transform="matrix(0.15625, 0, 0, 0.15625, 0, 0)"/>
  95. <path fill="none" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(255%, 255%, 255%)" stroke-opacity="1" stroke-miterlimit="4" d="M 24 56 L 152 56 " transform="matrix(0.15625, 0, 0, 0.15625, 0, 0)"/>
  96. <path fill="none" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(255%, 255%, 255%)" stroke-opacity="1" stroke-miterlimit="4" d="M 120 56 C 120 109.025 77.025 152 24 152 " transform="matrix(0.15625, 0, 0, 0.15625, 0, 0)"/>
  97. <path fill="none" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke="rgb(255%, 255%, 255%)" stroke-opacity="1" stroke-miterlimit="4" d="M 61.5 88 C 75.025 126.375 111.3 152.025 152 152 " transform="matrix(0.15625, 0, 0, 0.15625, 0, 0)"/>
  98. </svg>
  99. </button>
  100. <textarea id="output" style="grid-area:input2;" dir="auto" placeholder="Translation" readonly>
  101. {%- if translation is not none -%}{%- if translation['translated-text'] is not none -%}{{ translation['translated-text'] }}{%- endif -%}{%- endif -%}
  102. </textarea>
  103. {%- if tts_enabled and tts_to is not none -%}
  104. <div class="audio-player" style="grid-area:audio2;">
  105. <audio controls>
  106. <source type="audio/mpeg" src="{{ tts_to }}">
  107. </audio>
  108. </div>
  109. {%- endif -%}
  110. {% if translation is not none and "definitions" in translation %}
  111. <div class="definitions">
  112. <input id="list-1" type="checkbox">
  113. <label for="list-1">Check Definition</label>
  114. <div class="def-content">
  115. {% for type, definitions in translation["definitions"].items() %}
  116. <span class="def_type">Definition</span>
  117. <ol>
  118. {% for definition_item in definitions %}
  119. <li>
  120. {{definition_item["definition"]}}
  121. <br>
  122. {% if "use-in-sentence" in definition_item %}
  123. <span class="use_in_sentence">
  124. "{{definition_item["use-in-sentence"]}}"
  125. </span>
  126. <br>
  127. {% endif %}
  128. {% if "synonyms" in definition_item %}
  129. {% for synonym_type in definition_item["synonyms"] %}
  130. <span class="syn">
  131. {% if synonym_type != "" %}
  132. <br>
  133. <span class="syn_type">{{synonym_type}}: </span>
  134. {% endif %}
  135. {{", ".join(definition_item["synonyms"][synonym_type])}}
  136. </span>
  137. {% endfor %}
  138. {% endif %}
  139. </li>
  140. {% endfor %}
  141. </ol>
  142. {% endfor %}
  143. </div></div>
  144. {% endif %}
  145. {% if translation is not none and "translations" in translation %}
  146. <div class="translations">
  147. <input id="list-2" type="checkbox">
  148. <label for="list-2">Check Definition</label>
  149. <div class="trans-content">
  150. {% for def_type, translations in translation["translations"].items() %}
  151. <span class="def_type">Translation</span>
  152. <ol>
  153. {% for word, word_translations in translations.items() %}
  154. <li>
  155. <span class="syn_type">{{word}}:</span>
  156. <span class="syn">{{", ".join(word_translations["words"])}}</span>
  157. <span class="syn_type">{{word_translations["frequency"]}}</span>
  158. </li>
  159. <br>
  160. {% endfor %}
  161. </ol>
  162. {% endfor %}
  163. </div></div>
  164. {% endif %}
  165. </form>
  166. <footer>
  167. <ul>
  168. <li><a rel="noopener noreferrer" href="/prefs">Preferences</a></li>
  169. <li><a href="https://notabug.org/jyushimatsu/SimplyTranslate-fork">Forked Project Page</a></li>
  170. <li><a href="https://codeberg.org/SimpleWeb/SimplyTranslate-Web">Original Project Page</a></li>
  171. </footer>
  172. </div>
  173. <script>
  174. document.getElementById("input").addEventListener("keydown", function(event) {
  175. if (event.keyCode === 13 && (event.metaKey || event.ctrlKey)) {
  176. document.getElementById("translation-form").submit();
  177. }
  178. });
  179. </script>
  180. </body>
  181. </html>