🏠 Home 

Greasy Fork is available in English.

WanaKana

Utilities for detecting and transliterating between Hiragana, Katakana, and Romaji

Этот скрипт недоступен для установки пользователем. Он является библиотекой, которая подключается к другим скриптам мета-ключом // @require https://update.greasyfork.org/scripts/19781/126349/WanaKana.js

  1. // ==UserScript==
  2. // @name WanaKana
  3. // @version 1.3.7
  4. // @namespace https://github.com/WaniKani/WanaKana
  5. // @description Utilities for detecting and transliterating between Hiragana, Katakana, and Romaji
  6. // @author Mims H. Wright
  7. // @license MIT; http://opensource.org/licenses/MIT
  8. // ==/UserScript==
  9. /*
  10. The MIT License (MIT)
  11. Copyright (c) 2013 WaniKani Community Github
  12. Permission is hereby granted, free of charge, to any person obtaining a copy of
  13. this software and associated documentation files (the "Software"), to deal in
  14. the Software without restriction, including without limitation the rights to
  15. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  16. the Software, and to permit persons to whom the Software is furnished to do so,
  17. subject to the following conditions:
  18. The above copyright notice and this permission notice shall be included in all
  19. copies or substantial portions of the Software.
  20. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  22. FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  23. COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  24. IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  25. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  26. */
  27. var wanakana,
  28. __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
  29. wanakana = wanakana || {};
  30. wanakana.version = "1.3.7";
  31. if (typeof define === "function" && define.amd) {
  32. define("wanakana", [], function() {
  33. return wanakana;
  34. });
  35. }
  36. wanakana.LOWERCASE_START = 0x61;
  37. wanakana.LOWERCASE_END = 0x7A;
  38. wanakana.UPPERCASE_START = 0x41;
  39. wanakana.UPPERCASE_END = 0x5A;
  40. wanakana.HIRAGANA_START = 0x3041;
  41. wanakana.HIRAGANA_END = 0x3096;
  42. wanakana.KATAKANA_START = 0x30A1;
  43. wanakana.KATAKANA_END = 0x30FA;
  44. wanakana.LOWERCASE_FULLWIDTH_START = 0xFF41;
  45. wanakana.LOWERCASE_FULLWIDTH_END = 0xFF5A;
  46. wanakana.UPPERCASE_FULLWIDTH_START = 0xFF21;
  47. wanakana.UPPERCASE_FULLWIDTH_END = 0xFF3A;
  48. wanakana.defaultOptions = {
  49. useObseleteKana: false,
  50. IMEMode: false
  51. };
  52. /**
  53. * Automatically sets up an input field to be an IME.
  54. */
  55. wanakana.bind = function(input) {
  56. return input.addEventListener('input', wanakana._onInput);
  57. };
  58. wanakana.unbind = function(input) {
  59. return input.removeEventListener('input', wanakana._onInput);
  60. };
  61. wanakana._onInput = function(event) {
  62. var input, newText, normalizedInputString, range, startingCursor, startingLength;
  63. input = event.target;
  64. startingCursor = input.selectionStart;
  65. startingLength = input.value.length;
  66. normalizedInputString = wanakana._convertFullwidthCharsToASCII(input.value);
  67. newText = wanakana.toKana(normalizedInputString, {
  68. IMEMode: true
  69. });
  70. if (normalizedInputString !== newText) {
  71. input.value = newText;
  72. if (typeof input.selectionStart === "number") {
  73. return input.selectionStart = input.selectionEnd = input.value.length;
  74. } else if (typeof input.createTextRange !== "undefined") {
  75. input.focus();
  76. range = input.createTextRange();
  77. range.collapse(false);
  78. return range.select();
  79. }
  80. }
  81. };
  82. wanakana._extend = function(target, source) {
  83. var prop;
  84. if (target == null) {
  85. return source;
  86. }
  87. for (prop in source) {
  88. if ((target[prop] == null) && (source[prop] != null)) {
  89. target[prop] = source[prop];
  90. }
  91. }
  92. return target;
  93. };
  94. /**
  95. * Takes a character and a unicode range. Returns true if the char is in the range.
  96. */
  97. wanakana._isCharInRange = function(char, start, end) {
  98. var code;
  99. code = char.charCodeAt(0);
  100. return (start <= code && code <= end);
  101. };
  102. wanakana._isCharVowel = function(char, includeY) {
  103. var regexp;
  104. if (includeY == null) {
  105. includeY = true;
  106. }
  107. regexp = includeY ? /[aeiouy]/ : /[aeiou]/;
  108. return char.toLowerCase().charAt(0).search(regexp) !== -1;
  109. };
  110. wanakana._isCharConsonant = function(char, includeY) {
  111. var regexp;
  112. if (includeY == null) {
  113. includeY = true;
  114. }
  115. regexp = includeY ? /[bcdfghjklmnpqrstvwxyz]/ : /[bcdfghjklmnpqrstvwxz]/;
  116. return char.toLowerCase().charAt(0).search(regexp) !== -1;
  117. };
  118. wanakana._isCharKatakana = function(char) {
  119. return wanakana._isCharInRange(char, wanakana.KATAKANA_START, wanakana.KATAKANA_END);
  120. };
  121. wanakana._isCharHiragana = function(char) {
  122. return wanakana._isCharInRange(char, wanakana.HIRAGANA_START, wanakana.HIRAGANA_END);
  123. };
  124. wanakana._isCharKana = function(char) {
  125. return wanakana._isCharHiragana(char) || wanakana._isCharKatakana(char);
  126. };
  127. wanakana._isCharNotKana = function(char) {
  128. return !wanakana._isCharHiragana(char) && !wanakana._isCharKatakana(char);
  129. };
  130. wanakana._convertFullwidthCharsToASCII = function(string) {
  131. var char, chars, code, i, _i, _len;
  132. chars = string.split("");
  133. for (i = _i = 0, _len = chars.length; _i < _len; i = ++_i) {
  134. char = chars[i];
  135. code = char.charCodeAt(0);
  136. if (wanakana._isCharInRange(char, wanakana.LOWERCASE_FULLWIDTH_START, wanakana.LOWERCASE_FULLWIDTH_END)) {
  137. chars[i] = String.fromCharCode(code - wanakana.LOWERCASE_FULLWIDTH_START + wanakana.LOWERCASE_START);
  138. }
  139. if (wanakana._isCharInRange(char, wanakana.UPPERCASE_FULLWIDTH_START, wanakana.UPPERCASE_FULLWIDTH_END)) {
  140. chars[i](String.fromCharCode(code - wanakana.UPPERCASE_FULLWIDTH_START + wanakana.UPPERCASE_START));
  141. }
  142. }
  143. return chars.join("");
  144. };
  145. wanakana._katakanaToHiragana = function(kata) {
  146. var code, hira, hiraChar, kataChar, _i, _len, _ref;
  147. hira = [];
  148. _ref = kata.split("");
  149. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  150. kataChar = _ref[_i];
  151. if (wanakana._isCharKatakana(kataChar)) {
  152. code = kataChar.charCodeAt(0);
  153. code += wanakana.HIRAGANA_START - wanakana.KATAKANA_START;
  154. hiraChar = String.fromCharCode(code);
  155. hira.push(hiraChar);
  156. } else {
  157. hira.push(kataChar);
  158. }
  159. }
  160. return hira.join("");
  161. };
  162. wanakana._hiraganaToKatakana = function(hira) {
  163. var code, hiraChar, kata, kataChar, _i, _len, _ref;
  164. kata = [];
  165. _ref = hira.split("");
  166. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  167. hiraChar = _ref[_i];
  168. if (wanakana._isCharHiragana(hiraChar)) {
  169. code = hiraChar.charCodeAt(0);
  170. code += wanakana.KATAKANA_START - wanakana.HIRAGANA_START;
  171. kataChar = String.fromCharCode(code);
  172. kata.push(kataChar);
  173. } else {
  174. kata.push(hiraChar);
  175. }
  176. }
  177. return kata.join("");
  178. };
  179. wanakana._hiraganaToRomaji = function(hira, options) {
  180. var chunk, chunkSize, cursor, getChunk, len, maxChunk, nextCharIsDoubleConsonant, resetChunkSize, roma, romaChar;
  181. options = wanakana._extend(options, wanakana.defaultOptions);
  182. len = hira.length;
  183. roma = [];
  184. cursor = 0;
  185. chunkSize = 0;
  186. maxChunk = 2;
  187. getChunk = function() {
  188. return hira.substr(cursor, chunkSize);
  189. };
  190. resetChunkSize = function() {
  191. return chunkSize = Math.min(maxChunk, len - cursor);
  192. };
  193. while (cursor < len) {
  194. resetChunkSize();
  195. while (chunkSize > 0) {
  196. chunk = getChunk();
  197. if (wanakana.isKatakana(chunk)) {
  198. chunk = wanakana._katakanaToHiragana(chunk);
  199. }
  200. if (chunk.charAt(0) === "っ" && chunkSize === 1 && cursor < (len - 1)) {
  201. nextCharIsDoubleConsonant = true;
  202. romaChar = "";
  203. break;
  204. }
  205. romaChar = wanakana.J_to_R[chunk];
  206. if ((romaChar != null) && nextCharIsDoubleConsonant) {
  207. romaChar = romaChar.charAt(0).concat(romaChar);
  208. nextCharIsDoubleConsonant = false;
  209. }
  210. if (romaChar != null) {
  211. break;
  212. }
  213. chunkSize--;
  214. }
  215. if (romaChar == null) {
  216. romaChar = chunk;
  217. }
  218. roma.push(romaChar);
  219. cursor += chunkSize || 1;
  220. }
  221. return roma.join("");
  222. };
  223. wanakana._romajiToHiragana = function(roma, options) {
  224. return wanakana._romajiToKana(roma, options, true);
  225. };
  226. wanakana._romajiToKana = function(roma, options, ignoreCase) {
  227. var chunk, chunkLC, chunkSize, cursor, getChunk, isCharUpperCase, kana, kanaChar, len, maxChunk;
  228. if (ignoreCase == null) {
  229. ignoreCase = false;
  230. }
  231. options = wanakana._extend(options, wanakana.defaultOptions);
  232. len = roma.length;
  233. kana = [];
  234. cursor = 0;
  235. maxChunk = 3;
  236. getChunk = function() {
  237. return roma.substr(cursor, chunkSize);
  238. };
  239. isCharUpperCase = function(char) {
  240. return wanakana._isCharInRange(char, wanakana.UPPERCASE_START, wanakana.UPPERCASE_END);
  241. };
  242. while (cursor < len) {
  243. chunkSize = Math.min(maxChunk, len - cursor);
  244. while (chunkSize > 0) {
  245. chunk = getChunk();
  246. chunkLC = chunk.toLowerCase();
  247. if (__indexOf.call(wanakana.FOUR_CHARACTER_EDGE_CASES, chunkLC) >= 0 && (len - cursor) >= 4) {
  248. chunkSize++;
  249. chunk = getChunk();
  250. chunkLC = chunk.toLowerCase();
  251. } else {
  252. if (chunkLC.charAt(0) === "n") {
  253. if (options.IMEMode && chunkLC.charAt(1) === "'" && chunkSize === 2) {
  254. kanaChar = "ん";
  255. break;
  256. }
  257. if (wanakana._isCharConsonant(chunkLC.charAt(1), false) && wanakana._isCharVowel(chunkLC.charAt(2))) {
  258. chunkSize = 1;
  259. chunk = getChunk();
  260. chunkLC = chunk.toLowerCase();
  261. }
  262. }
  263. if (chunkLC.charAt(0) !== "n" && wanakana._isCharConsonant(chunkLC.charAt(0)) && chunk.charAt(0) === chunk.charAt(1)) {
  264. chunkSize = 1;
  265. if (wanakana._isCharInRange(chunk.charAt(0), wanakana.UPPERCASE_START, wanakana.UPPERCASE_END)) {
  266. chunkLC = chunk = "ッ";
  267. } else {
  268. chunkLC = chunk = "っ";
  269. }
  270. }
  271. }
  272. kanaChar = wanakana.R_to_J[chunkLC];
  273. if (kanaChar != null) {
  274. break;
  275. }
  276. if (chunkSize === 4) {
  277. chunkSize -= 2;
  278. } else {
  279. chunkSize--;
  280. }
  281. }
  282. if (kanaChar == null) {
  283. chunk = wanakana._convertPunctuation(chunk);
  284. kanaChar = chunk;
  285. }
  286. if (options != null ? options.useObseleteKana : void 0) {
  287. if (chunkLC === "wi") {
  288. kanaChar = "ゐ";
  289. }
  290. if (chunkLC === "we") {
  291. kanaChar = "ゑ";
  292. }
  293. }
  294. if (options.IMEMode && chunkLC.charAt(0) === "n") {
  295. if (roma.charAt(cursor + 1).toLowerCase() === "y" && wanakana._isCharVowel(roma.charAt(cursor + 2)) === false || cursor === (len - 1) || wanakana.isKana(roma.charAt(cursor + 1))) {
  296. kanaChar = chunk.charAt(0);
  297. }
  298. }
  299. if (!ignoreCase) {
  300. if (isCharUpperCase(chunk.charAt(0))) {
  301. kanaChar = wanakana._hiraganaToKatakana(kanaChar);
  302. }
  303. }
  304. kana.push(kanaChar);
  305. cursor += chunkSize || 1;
  306. }
  307. return kana.join("");
  308. };
  309. wanakana._convertPunctuation = function(input, options) {
  310. if (input === ' ') {
  311. return ' ';
  312. }
  313. if (input === '-') {
  314. return 'ー';
  315. }
  316. return input;
  317. };
  318. /**
  319. * Returns true if input is entirely hiragana.
  320. */
  321. wanakana.isHiragana = function(input) {
  322. var chars;
  323. chars = input.split("");
  324. return chars.every(wanakana._isCharHiragana);
  325. };
  326. wanakana.isKatakana = function(input) {
  327. var chars;
  328. chars = input.split("");
  329. return chars.every(wanakana._isCharKatakana);
  330. };
  331. wanakana.isKana = function(input) {
  332. var chars;
  333. chars = input.split("");
  334. return chars.every(function(char) {
  335. return (wanakana.isHiragana(char)) || (wanakana.isKatakana(char));
  336. });
  337. };
  338. wanakana.isRomaji = function(input) {
  339. var chars;
  340. chars = input.split("");
  341. return chars.every(function(char) {
  342. return (!wanakana.isHiragana(char)) && (!wanakana.isKatakana(char));
  343. });
  344. };
  345. wanakana.toHiragana = function(input, options) {
  346. if (wanakana.isRomaji(input)) {
  347. return input = wanakana._romajiToHiragana(input, options);
  348. }
  349. if (wanakana.isKatakana(input)) {
  350. return input = wanakana._katakanaToHiragana(input, options);
  351. }
  352. return input;
  353. };
  354. wanakana.toKatakana = function(input, options) {
  355. if (wanakana.isHiragana(input)) {
  356. return input = wanakana._hiraganaToKatakana(input, options);
  357. }
  358. if (wanakana.isRomaji(input)) {
  359. input = wanakana._romajiToHiragana(input, options);
  360. return input = wanakana._hiraganaToKatakana(input, options);
  361. }
  362. return input;
  363. };
  364. wanakana.toKana = function(input, options) {
  365. return input = wanakana._romajiToKana(input, options);
  366. };
  367. wanakana.toRomaji = function(input, options) {
  368. return input = wanakana._hiraganaToRomaji(input);
  369. };
  370. wanakana.R_to_J = {
  371. a: 'あ',
  372. i: 'い',
  373. u: 'う',
  374. e: 'え',
  375. o: 'お',
  376. yi: 'い',
  377. wu: 'う',
  378. whu: 'う',
  379. xa: 'ぁ',
  380. xi: 'ぃ',
  381. xu: 'ぅ',
  382. xe: 'ぇ',
  383. xo: 'ぉ',
  384. xyi: 'ぃ',
  385. xye: 'ぇ',
  386. ye: 'いぇ',
  387. wha: 'うぁ',
  388. whi: 'うぃ',
  389. whe: 'うぇ',
  390. who: 'うぉ',
  391. wi: 'うぃ',
  392. we: 'うぇ',
  393. va: 'ゔぁ',
  394. vi: 'ゔぃ',
  395. vu: 'ゔ',
  396. ve: 'ゔぇ',
  397. vo: 'ゔぉ',
  398. vya: 'ゔゃ',
  399. vyi: 'ゔぃ',
  400. vyu: 'ゔゅ',
  401. vye: 'ゔぇ',
  402. vyo: 'ゔょ',
  403. ka: 'か',
  404. ki: 'き',
  405. ku: 'く',
  406. ke: 'け',
  407. ko: 'こ',
  408. lka: 'ヵ',
  409. lke: 'ヶ',
  410. xka: 'ヵ',
  411. xke: 'ヶ',
  412. kya: 'きゃ',
  413. kyi: 'きぃ',
  414. kyu: 'きゅ',
  415. kye: 'きぇ',
  416. kyo: 'きょ',
  417. ca: 'か',
  418. ci: 'き',
  419. cu: 'く',
  420. ce: 'け',
  421. co: 'こ',
  422. lca: 'ヵ',
  423. lce: 'ヶ',
  424. xca: 'ヵ',
  425. xce: 'ヶ',
  426. qya: 'くゃ',
  427. qyu: 'くゅ',
  428. qyo: 'くょ',
  429. qwa: 'くぁ',
  430. qwi: 'くぃ',
  431. qwu: 'くぅ',
  432. qwe: 'くぇ',
  433. qwo: 'くぉ',
  434. qa: 'くぁ',
  435. qi: 'くぃ',
  436. qe: 'くぇ',
  437. qo: 'くぉ',
  438. kwa: 'くぁ',
  439. qyi: 'くぃ',
  440. qye: 'くぇ',
  441. ga: 'が',
  442. gi: 'ぎ',
  443. gu: 'ぐ',
  444. ge: 'げ',
  445. go: 'ご',
  446. gya: 'ぎゃ',
  447. gyi: 'ぎぃ',
  448. gyu: 'ぎゅ',
  449. gye: 'ぎぇ',
  450. gyo: 'ぎょ',
  451. gwa: 'ぐぁ',
  452. gwi: 'ぐぃ',
  453. gwu: 'ぐぅ',
  454. gwe: 'ぐぇ',
  455. gwo: 'ぐぉ',
  456. sa: 'さ',
  457. si: 'し',
  458. shi: 'し',
  459. su: 'す',
  460. se: 'せ',
  461. so: 'そ',
  462. za: 'ざ',
  463. zi: 'じ',
  464. zu: 'ず',
  465. ze: 'ぜ',
  466. zo: 'ぞ',
  467. ji: 'じ',
  468. sya: 'しゃ',
  469. syi: 'しぃ',
  470. syu: 'しゅ',
  471. sye: 'しぇ',
  472. syo: 'しょ',
  473. sha: 'しゃ',
  474. shu: 'しゅ',
  475. she: 'しぇ',
  476. sho: 'しょ',
  477. shya: 'しゃ',
  478. shyu: 'しゅ',
  479. shye: 'しぇ',
  480. shyo: 'しょ',
  481. swa: 'すぁ',
  482. swi: 'すぃ',
  483. swu: 'すぅ',
  484. swe: 'すぇ',
  485. swo: 'すぉ',
  486. zya: 'じゃ',
  487. zyi: 'じぃ',
  488. zyu: 'じゅ',
  489. zye: 'じぇ',
  490. zyo: 'じょ',
  491. ja: 'じゃ',
  492. ju: 'じゅ',
  493. je: 'じぇ',
  494. jo: 'じょ',
  495. jya: 'じゃ',
  496. jyi: 'じぃ',
  497. jyu: 'じゅ',
  498. jye: 'じぇ',
  499. jyo: 'じょ',
  500. ta: 'た',
  501. ti: 'ち',
  502. tu: 'つ',
  503. te: 'て',
  504. to: 'と',
  505. chi: 'ち',
  506. tsu: 'つ',
  507. ltu: 'っ',
  508. xtu: 'っ',
  509. tya: 'ちゃ',
  510. tyi: 'ちぃ',
  511. tyu: 'ちゅ',
  512. tye: 'ちぇ',
  513. tyo: 'ちょ',
  514. cha: 'ちゃ',
  515. chu: 'ちゅ',
  516. che: 'ちぇ',
  517. cho: 'ちょ',
  518. cya: 'ちゃ',
  519. cyi: 'ちぃ',
  520. cyu: 'ちゅ',
  521. cye: 'ちぇ',
  522. cyo: 'ちょ',
  523. chya: 'ちゃ',
  524. chyu: 'ちゅ',
  525. chye: 'ちぇ',
  526. chyo: 'ちょ',
  527. tsa: 'つぁ',
  528. tsi: 'つぃ',
  529. tse: 'つぇ',
  530. tso: 'つぉ',
  531. tha: 'てゃ',
  532. thi: 'てぃ',
  533. thu: 'てゅ',
  534. the: 'てぇ',
  535. tho: 'てょ',
  536. twa: 'とぁ',
  537. twi: 'とぃ',
  538. twu: 'とぅ',
  539. twe: 'とぇ',
  540. two: 'とぉ',
  541. da: 'だ',
  542. di: 'ぢ',
  543. du: 'づ',
  544. de: 'で',
  545. "do": 'ど',
  546. dya: 'ぢゃ',
  547. dyi: 'ぢぃ',
  548. dyu: 'ぢゅ',
  549. dye: 'ぢぇ',
  550. dyo: 'ぢょ',
  551. dha: 'でゃ',
  552. dhi: 'でぃ',
  553. dhu: 'でゅ',
  554. dhe: 'でぇ',
  555. dho: 'でょ',
  556. dwa: 'どぁ',
  557. dwi: 'どぃ',
  558. dwu: 'どぅ',
  559. dwe: 'どぇ',
  560. dwo: 'どぉ',
  561. na: 'な',
  562. ni: 'に',
  563. nu: 'ぬ',
  564. ne: 'ね',
  565. no: 'の',
  566. nya: 'にゃ',
  567. nyi: 'にぃ',
  568. nyu: 'にゅ',
  569. nye: 'にぇ',
  570. nyo: 'にょ',
  571. ha: 'は',
  572. hi: 'ひ',
  573. hu: 'ふ',
  574. he: 'へ',
  575. ho: 'ほ',
  576. fu: 'ふ',
  577. hya: 'ひゃ',
  578. hyi: 'ひぃ',
  579. hyu: 'ひゅ',
  580. hye: 'ひぇ',
  581. hyo: 'ひょ',
  582. fya: 'ふゃ',
  583. fyu: 'ふゅ',
  584. fyo: 'ふょ',
  585. fwa: 'ふぁ',
  586. fwi: 'ふぃ',
  587. fwu: 'ふぅ',
  588. fwe: 'ふぇ',
  589. fwo: 'ふぉ',
  590. fa: 'ふぁ',
  591. fi: 'ふぃ',
  592. fe: 'ふぇ',
  593. fo: 'ふぉ',
  594. fyi: 'ふぃ',
  595. fye: 'ふぇ',
  596. ba: 'ば',
  597. bi: 'び',
  598. bu: 'ぶ',
  599. be: 'べ',
  600. bo: 'ぼ',
  601. bya: 'びゃ',
  602. byi: 'びぃ',
  603. byu: 'びゅ',
  604. bye: 'びぇ',
  605. byo: 'びょ',
  606. pa: 'ぱ',
  607. pi: 'ぴ',
  608. pu: 'ぷ',
  609. pe: 'ぺ',
  610. po: 'ぽ',
  611. pya: 'ぴゃ',
  612. pyi: 'ぴぃ',
  613. pyu: 'ぴゅ',
  614. pye: 'ぴぇ',
  615. pyo: 'ぴょ',
  616. ma: 'ま',
  617. mi: 'み',
  618. mu: 'む',
  619. me: 'め',
  620. mo: 'も',
  621. mya: 'みゃ',
  622. myi: 'みぃ',
  623. myu: 'みゅ',
  624. mye: 'みぇ',
  625. myo: 'みょ',
  626. ya: 'や',
  627. yu: 'ゆ',
  628. yo: 'よ',
  629. xya: 'ゃ',
  630. xyu: 'ゅ',
  631. xyo: 'ょ',
  632. ra: 'ら',
  633. ri: 'り',
  634. ru: 'る',
  635. re: 'れ',
  636. ro: 'ろ',
  637. rya: 'りゃ',
  638. ryi: 'りぃ',
  639. ryu: 'りゅ',
  640. rye: 'りぇ',
  641. ryo: 'りょ',
  642. la: 'ら',
  643. li: 'り',
  644. lu: 'る',
  645. le: 'れ',
  646. lo: 'ろ',
  647. lya: 'りゃ',
  648. lyi: 'りぃ',
  649. lyu: 'りゅ',
  650. lye: 'りぇ',
  651. lyo: 'りょ',
  652. wa: 'わ',
  653. wo: 'を',
  654. lwe: 'ゎ',
  655. xwa: 'ゎ',
  656. n: 'ん',
  657. nn: 'ん',
  658. 'n ': 'ん',
  659. xn: 'ん',
  660. ltsu: 'っ'
  661. };
  662. wanakana.FOUR_CHARACTER_EDGE_CASES = ['lts', 'chy', 'shy'];
  663. wanakana.J_to_R = {
  664. あ: 'a',
  665. い: 'i',
  666. う: 'u',
  667. え: 'e',
  668. お: 'o',
  669. ゔぁ: 'va',
  670. ゔぃ: 'vi',
  671. ゔ: 'vu',
  672. ゔぇ: 've',
  673. ゔぉ: 'vo',
  674. か: 'ka',
  675. き: 'ki',
  676. きゃ: 'kya',
  677. きぃ: 'kyi',
  678. きゅ: 'kyu',
  679. く: 'ku',
  680. け: 'ke',
  681. こ: 'ko',
  682. が: 'ga',
  683. ぎ: 'gi',
  684. ぐ: 'gu',
  685. げ: 'ge',
  686. ご: 'go',
  687. ぎゃ: 'gya',
  688. ぎぃ: 'gyi',
  689. ぎゅ: 'gyu',
  690. ぎぇ: 'gye',
  691. ぎょ: 'gyo',
  692. さ: 'sa',
  693. す: 'su',
  694. せ: 'se',
  695. そ: 'so',
  696. ざ: 'za',
  697. ず: 'zu',
  698. ぜ: 'ze',
  699. ぞ: 'zo',
  700. し: 'shi',
  701. しゃ: 'sha',
  702. しゅ: 'shu',
  703. しょ: 'sho',
  704. じ: 'ji',
  705. じゃ: 'ja',
  706. じゅ: 'ju',
  707. じょ: 'jo',
  708. た: 'ta',
  709. ち: 'chi',
  710. ちゃ: 'cha',
  711. ちゅ: 'chu',
  712. ちょ: 'cho',
  713. つ: 'tsu',
  714. て: 'te',
  715. と: 'to',
  716. だ: 'da',
  717. ぢ: 'di',
  718. づ: 'du',
  719. で: 'de',
  720. ど: 'do',
  721. な: 'na',
  722. に: 'ni',
  723. にゃ: 'nya',
  724. にゅ: 'nyu',
  725. にょ: 'nyo',
  726. ぬ: 'nu',
  727. ね: 'ne',
  728. の: 'no',
  729. は: 'ha',
  730. ひ: 'hi',
  731. ふ: 'fu',
  732. へ: 'he',
  733. ほ: 'ho',
  734. ひゃ: 'hya',
  735. ひゅ: 'hyu',
  736. ひょ: 'hyo',
  737. ふぁ: 'fa',
  738. ふぃ: 'fi',
  739. ふぇ: 'fe',
  740. ふぉ: 'fo',
  741. ば: 'ba',
  742. び: 'bi',
  743. ぶ: 'bu',
  744. べ: 'be',
  745. ぼ: 'bo',
  746. びゃ: 'bya',
  747. びゅ: 'byu',
  748. びょ: 'byo',
  749. ぱ: 'pa',
  750. ぴ: 'pi',
  751. ぷ: 'pu',
  752. ぺ: 'pe',
  753. ぽ: 'po',
  754. ぴゃ: 'pya',
  755. ぴゅ: 'pyu',
  756. ぴょ: 'pyo',
  757. ま: 'ma',
  758. み: 'mi',
  759. む: 'mu',
  760. め: 'me',
  761. も: 'mo',
  762. みゃ: 'mya',
  763. みゅ: 'myu',
  764. みょ: 'myo',
  765. や: 'ya',
  766. ゆ: 'yu',
  767. よ: 'yo',
  768. ら: 'ra',
  769. り: 'ri',
  770. る: 'ru',
  771. れ: 're',
  772. ろ: 'ro',
  773. りゃ: 'rya',
  774. りゅ: 'ryu',
  775. りょ: 'ryo',
  776. わ: 'wa',
  777. を: 'wo',
  778. ん: 'n',
  779. ゐ: 'wi',
  780. ゑ: 'we',
  781. きぇ: 'kye',
  782. きょ: 'kyo',
  783. じぃ: 'jyi',
  784. じぇ: 'jye',
  785. ちぃ: 'cyi',
  786. ちぇ: 'che',
  787. ひぃ: 'hyi',
  788. ひぇ: 'hye',
  789. びぃ: 'byi',
  790. びぇ: 'bye',
  791. ぴぃ: 'pyi',
  792. ぴぇ: 'pye',
  793. みぇ: 'mye',
  794. みぃ: 'myi',
  795. りぃ: 'ryi',
  796. りぇ: 'rye',
  797. にぃ: 'nyi',
  798. にぇ: 'nye',
  799. しぃ: 'syi',
  800. しぇ: 'she',
  801. いぇ: 'ye',
  802. うぁ: 'wha',
  803. うぉ: 'who',
  804. うぃ: 'wi',
  805. うぇ: 'we',
  806. ゔゃ: 'vya',
  807. ゔゅ: 'vyu',
  808. ゔょ: 'vyo',
  809. すぁ: 'swa',
  810. すぃ: 'swi',
  811. すぅ: 'swu',
  812. すぇ: 'swe',
  813. すぉ: 'swo',
  814. くゃ: 'qya',
  815. くゅ: 'qyu',
  816. くょ: 'qyo',
  817. くぁ: 'qwa',
  818. くぃ: 'qwi',
  819. くぅ: 'qwu',
  820. くぇ: 'qwe',
  821. くぉ: 'qwo',
  822. ぐぁ: 'gwa',
  823. ぐぃ: 'gwi',
  824. ぐぅ: 'gwu',
  825. ぐぇ: 'gwe',
  826. ぐぉ: 'gwo',
  827. つぁ: 'tsa',
  828. つぃ: 'tsi',
  829. つぇ: 'tse',
  830. つぉ: 'tso',
  831. てゃ: 'tha',
  832. てぃ: 'thi',
  833. てゅ: 'thu',
  834. てぇ: 'the',
  835. てょ: 'tho',
  836. とぁ: 'twa',
  837. とぃ: 'twi',
  838. とぅ: 'twu',
  839. とぇ: 'twe',
  840. とぉ: 'two',
  841. ぢゃ: 'dya',
  842. ぢぃ: 'dyi',
  843. ぢゅ: 'dyu',
  844. ぢぇ: 'dye',
  845. ぢょ: 'dyo',
  846. でゃ: 'dha',
  847. でぃ: 'dhi',
  848. でゅ: 'dhu',
  849. でぇ: 'dhe',
  850. でょ: 'dho',
  851. どぁ: 'dwa',
  852. どぃ: 'dwi',
  853. どぅ: 'dwu',
  854. どぇ: 'dwe',
  855. どぉ: 'dwo',
  856. ふぅ: 'fwu',
  857. ふゃ: 'fya',
  858. ふゅ: 'fyu',
  859. ふょ: 'fyo',
  860. ぁ: 'a',
  861. ぃ: 'i',
  862. ぇ: 'e',
  863. ぅ: 'u',
  864. ぉ: 'o',
  865. ゃ: 'ya',
  866. ゅ: 'yu',
  867. ょ: 'yo',
  868. っ: '',
  869. ゕ: 'ka',
  870. ゖ: 'ka',
  871. ゎ: 'wa',
  872. ' ': ' ',
  873. んあ: 'n\'a',
  874. んい: 'n\'i',
  875. んう: 'n\'u',
  876. んえ: 'n\'e',
  877. んお: 'n\'o',
  878. んや: 'n\'ya',
  879. んゆ: 'n\'yu',
  880. んよ: 'n\'yo'
  881. };