From 3e419aa562aab03ca20421aaf7e4d1a39194a5b4 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 31 Jan 2024 08:28:05 -0500 Subject: Language transformer (#582) * Set up new deinflection data file * Define types * Test * Add internal types * Set up loading for transforms * Add getPartOfSpeechFlags * Convert static methods * Add note * Add transform function * Update trace structure * Add a language tag to the language transform descriptor * Add clear function * Add function for multiple parts of speech * Clarify naming * Add getConditionFlagsFromConditionType * Add plural function * Replace usages of Deinflector * Update tests * Update config * Remove old * Rename * Rename files --- .eslintrc.json | 2 +- dev/jsconfig.json | 5 +- ext/data/deinflect.json | 645 ---------------- ext/data/language/japanese-transforms.json | 851 +++++++++++++++++++++ ext/js/background/backend.js | 6 +- ext/js/background/offscreen-proxy.js | 6 +- ext/js/background/offscreen.js | 4 +- ext/js/language/deinflector.js | 140 ---- ext/js/language/language-transformer.js | 245 ++++++ ext/js/language/translator.js | 32 +- test/data/json.json | 10 +- test/deinflection-cycles.test.js | 165 ---- test/deinflector.test.js | 1044 ------------------------- test/fixtures/translator-test.js | 6 +- test/language-transformer-cycles.test.js | 170 +++++ test/language-transformer.test.js | 1049 ++++++++++++++++++++++++++ types/ext/deinflector.d.ts | 43 -- types/ext/language-transformer-internal.d.ts | 41 + types/ext/language-transformer.d.ts | 62 ++ types/ext/offscreen.d.ts | 4 +- types/ext/translation-internal.d.ts | 19 +- 21 files changed, 2456 insertions(+), 2093 deletions(-) delete mode 100644 ext/data/deinflect.json create mode 100644 ext/data/language/japanese-transforms.json delete mode 100644 ext/js/language/deinflector.js create mode 100644 ext/js/language/language-transformer.js delete mode 100644 test/deinflection-cycles.test.js delete mode 100644 test/deinflector.test.js create mode 100644 test/language-transformer-cycles.test.js create mode 100644 test/language-transformer.test.js delete mode 100644 types/ext/deinflector.d.ts create mode 100644 types/ext/language-transformer-internal.d.ts create mode 100644 types/ext/language-transformer.d.ts diff --git a/.eslintrc.json b/.eslintrc.json index eec25b5c..aea94cde 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -684,7 +684,7 @@ "ext/js/general/object-property-accessor.js", "ext/js/general/regex-util.js", "ext/js/general/text-source-map.js", - "ext/js/language/deinflector.js", + "ext/js/language/language-transformer.js", "ext/js/dictionary/dictionary-database.js", "ext/js/dictionary/dictionary-data-util.js", "ext/js/language/sandbox/japanese-util.js", diff --git a/dev/jsconfig.json b/dev/jsconfig.json index c0ff07d0..db38b6df 100644 --- a/dev/jsconfig.json +++ b/dev/jsconfig.json @@ -18,7 +18,6 @@ "core": ["../types/ext/core"], "css-style-applier": ["../types/ext/css-style-applier"], "database": ["../types/ext/database"], - "deinflector": ["../types/ext/deinflector"], "dictionary": ["../types/ext/dictionary"], "dictionary-data": ["../types/ext/dictionary-data"], "dictionary-data-util": ["../types/ext/dictionary-data-util"], @@ -30,6 +29,8 @@ "event-listener-collection": ["../types/ext/event-listener-collection"], "japanese-util": ["../types/ext/japanese-util"], "ext/json-schema": ["../types/ext/json-schema"], + "language-transformer": ["../types/ext/language-transformer"], + "language-transformer-internal": ["../types/ext/language-transformer-internal"], "log": ["../types/ext/log"], "settings": ["../types/ext/settings"], "structured-content": ["../types/ext/structured-content"], @@ -64,7 +65,7 @@ "../ext/js/general/cache-map.js", "../ext/js/general/regex-util.js", "../ext/js/general/text-source-map.js", - "../ext/js/language/deinflector.js", + "../ext/js/language/language-transformer.js", "../ext/js/dictionary/dictionary-importer.js", "../ext/js/dictionary/dictionary-database.js", "../ext/js/dictionary/dictionary-data-util.js", diff --git a/ext/data/deinflect.json b/ext/data/deinflect.json deleted file mode 100644 index 884dbcc1..00000000 --- a/ext/data/deinflect.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "-ba": [ - {"kanaIn": "ければ", "kanaOut": "い", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "えば", "kanaOut": "う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "けば", "kanaOut": "く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "げば", "kanaOut": "ぐ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "せば", "kanaOut": "す", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "てば", "kanaOut": "つ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ねば", "kanaOut": "ぬ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "べば", "kanaOut": "ぶ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "めば", "kanaOut": "む", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "れば", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v1", "v5", "vk", "vs", "vz"]} - ], - "-chau": [ - {"kanaIn": "ちゃう", "kanaOut": "る", "rulesIn": ["v5"], "rulesOut": ["v1"]}, - {"kanaIn": "いじゃう", "kanaOut": "ぐ", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "いちゃう", "kanaOut": "く", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "しちゃう", "kanaOut": "す", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "っちゃう", "kanaOut": "う", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "っちゃう", "kanaOut": "く", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "っちゃう", "kanaOut": "つ", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "っちゃう", "kanaOut": "る", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "んじゃう", "kanaOut": "ぬ", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "んじゃう", "kanaOut": "ぶ", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "んじゃう", "kanaOut": "む", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "じちゃう", "kanaOut": "ずる", "rulesIn": ["v5"], "rulesOut": ["vz"]}, - {"kanaIn": "しちゃう", "kanaOut": "する", "rulesIn": ["v5"], "rulesOut": ["vs"]}, - {"kanaIn": "為ちゃう", "kanaOut": "為る", "rulesIn": ["v5"], "rulesOut": ["vs"]}, - {"kanaIn": "きちゃう", "kanaOut": "くる", "rulesIn": ["v5"], "rulesOut": ["vk"]}, - {"kanaIn": "来ちゃう", "kanaOut": "来る", "rulesIn": ["v5"], "rulesOut": ["vk"]}, - {"kanaIn": "來ちゃう", "kanaOut": "來る", "rulesIn": ["v5"], "rulesOut": ["vk"]} - ], - "-chimau": [ - {"kanaIn": "ちまう", "kanaOut": "る", "rulesIn": ["v5"], "rulesOut": ["v1"]}, - {"kanaIn": "いじまう", "kanaOut": "ぐ", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "いちまう", "kanaOut": "く", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "しちまう", "kanaOut": "す", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "っちまう", "kanaOut": "う", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "っちまう", "kanaOut": "く", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "っちまう", "kanaOut": "つ", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "っちまう", "kanaOut": "る", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "んじまう", "kanaOut": "ぬ", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "んじまう", "kanaOut": "ぶ", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "んじまう", "kanaOut": "む", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "じちまう", "kanaOut": "ずる", "rulesIn": ["v5"], "rulesOut": ["vz"]}, - {"kanaIn": "しちまう", "kanaOut": "する", "rulesIn": ["v5"], "rulesOut": ["vs"]}, - {"kanaIn": "為ちまう", "kanaOut": "為る", "rulesIn": ["v5"], "rulesOut": ["vs"]}, - {"kanaIn": "きちまう", "kanaOut": "くる", "rulesIn": ["v5"], "rulesOut": ["vk"]}, - {"kanaIn": "来ちまう", "kanaOut": "来る", "rulesIn": ["v5"], "rulesOut": ["vk"]}, - {"kanaIn": "來ちまう", "kanaOut": "來る", "rulesIn": ["v5"], "rulesOut": ["vk"]} - ], - "-shimau": [ - {"kanaIn": "てしまう", "kanaOut": "て", "rulesIn": ["v5"], "rulesOut": ["iru"]}, - {"kanaIn": "でしまう", "kanaOut": "で", "rulesIn": ["v5"], "rulesOut": ["iru"]} - ], - "-nasai": [ - {"kanaIn": "なさい", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v1"]}, - {"kanaIn": "いなさい", "kanaOut": "う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "きなさい", "kanaOut": "く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ぎなさい", "kanaOut": "ぐ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "しなさい", "kanaOut": "す", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ちなさい", "kanaOut": "つ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "になさい", "kanaOut": "ぬ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "びなさい", "kanaOut": "ぶ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "みなさい", "kanaOut": "む", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "りなさい", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "じなさい", "kanaOut": "ずる", "rulesIn": [], "rulesOut": ["vz"]}, - {"kanaIn": "しなさい", "kanaOut": "する", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "為なさい", "kanaOut": "為る", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "きなさい", "kanaOut": "くる", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "来なさい", "kanaOut": "来る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "來なさい", "kanaOut": "來る", "rulesIn": [], "rulesOut": ["vk"]} - ], - "-sou": [ - {"kanaIn": "そう", "kanaOut": "い", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "そう", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v1"]}, - {"kanaIn": "いそう", "kanaOut": "う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "きそう", "kanaOut": "く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ぎそう", "kanaOut": "ぐ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "しそう", "kanaOut": "す", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ちそう", "kanaOut": "つ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "にそう", "kanaOut": "ぬ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "びそう", "kanaOut": "ぶ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "みそう", "kanaOut": "む", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "りそう", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "じそう", "kanaOut": "ずる", "rulesIn": [], "rulesOut": ["vz"]}, - {"kanaIn": "しそう", "kanaOut": "する", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "為そう", "kanaOut": "為る", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "きそう", "kanaOut": "くる", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "来そう", "kanaOut": "来る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "來そう", "kanaOut": "來る", "rulesIn": [], "rulesOut": ["vk"]} - ], - "-sugiru": [ - {"kanaIn": "すぎる", "kanaOut": "い", "rulesIn": ["v1"], "rulesOut": ["adj-i"]}, - {"kanaIn": "すぎる", "kanaOut": "る", "rulesIn": ["v1"], "rulesOut": ["v1"]}, - {"kanaIn": "いすぎる", "kanaOut": "う", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "きすぎる", "kanaOut": "く", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "ぎすぎる", "kanaOut": "ぐ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "しすぎる", "kanaOut": "す", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "ちすぎる", "kanaOut": "つ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "にすぎる", "kanaOut": "ぬ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "びすぎる", "kanaOut": "ぶ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "みすぎる", "kanaOut": "む", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "りすぎる", "kanaOut": "る", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "じすぎる", "kanaOut": "ずる", "rulesIn": ["v1"], "rulesOut": ["vz"]}, - {"kanaIn": "しすぎる", "kanaOut": "する", "rulesIn": ["v1"], "rulesOut": ["vs"]}, - {"kanaIn": "為すぎる", "kanaOut": "為る", "rulesIn": ["v1"], "rulesOut": ["vs"]}, - {"kanaIn": "きすぎる", "kanaOut": "くる", "rulesIn": ["v1"], "rulesOut": ["vk"]}, - {"kanaIn": "来すぎる", "kanaOut": "来る", "rulesIn": ["v1"], "rulesOut": ["vk"]}, - {"kanaIn": "來すぎる", "kanaOut": "來る", "rulesIn": ["v1"], "rulesOut": ["vk"]} - ], - "-tai": [ - {"kanaIn": "たい", "kanaOut": "る", "rulesIn": ["adj-i"], "rulesOut": ["v1"]}, - {"kanaIn": "いたい", "kanaOut": "う", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "きたい", "kanaOut": "く", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "ぎたい", "kanaOut": "ぐ", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "したい", "kanaOut": "す", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "ちたい", "kanaOut": "つ", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "にたい", "kanaOut": "ぬ", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "びたい", "kanaOut": "ぶ", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "みたい", "kanaOut": "む", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "りたい", "kanaOut": "る", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "じたい", "kanaOut": "ずる", "rulesIn": ["adj-i"], "rulesOut": ["vz"]}, - {"kanaIn": "したい", "kanaOut": "する", "rulesIn": ["adj-i"], "rulesOut": ["vs"]}, - {"kanaIn": "為たい", "kanaOut": "為る", "rulesIn": ["adj-i"], "rulesOut": ["vs"]}, - {"kanaIn": "きたい", "kanaOut": "くる", "rulesIn": ["adj-i"], "rulesOut": ["vk"]}, - {"kanaIn": "来たい", "kanaOut": "来る", "rulesIn": ["adj-i"], "rulesOut": ["vk"]}, - {"kanaIn": "來たい", "kanaOut": "來る", "rulesIn": ["adj-i"], "rulesOut": ["vk"]} - ], - "-tara": [ - {"kanaIn": "かったら", "kanaOut": "い", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "たら", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v1"]}, - {"kanaIn": "いたら", "kanaOut": "く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "いだら", "kanaOut": "ぐ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "したら", "kanaOut": "す", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ったら", "kanaOut": "う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ったら", "kanaOut": "つ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ったら", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "んだら", "kanaOut": "ぬ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "んだら", "kanaOut": "ぶ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "んだら", "kanaOut": "む", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "じたら", "kanaOut": "ずる", "rulesIn": [], "rulesOut": ["vz"]}, - {"kanaIn": "したら", "kanaOut": "する", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "為たら", "kanaOut": "為る", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "きたら", "kanaOut": "くる", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "来たら", "kanaOut": "来る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "來たら", "kanaOut": "來る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "いったら", "kanaOut": "いく", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "おうたら", "kanaOut": "おう", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "こうたら", "kanaOut": "こう", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "そうたら", "kanaOut": "そう", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "とうたら", "kanaOut": "とう", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "行ったら", "kanaOut": "行く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "逝ったら", "kanaOut": "逝く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "往ったら", "kanaOut": "往く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "請うたら", "kanaOut": "請う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "乞うたら", "kanaOut": "乞う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "恋うたら", "kanaOut": "恋う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "問うたら", "kanaOut": "問う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "負うたら", "kanaOut": "負う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "沿うたら", "kanaOut": "沿う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "添うたら", "kanaOut": "添う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "副うたら", "kanaOut": "副う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "厭うたら", "kanaOut": "厭う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "のたもうたら", "kanaOut": "のたまう", "rulesIn": [], "rulesOut": ["v5"]} - ], - "-tari": [ - {"kanaIn": "かったり", "kanaOut": "い", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "たり", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v1"]}, - {"kanaIn": "いたり", "kanaOut": "く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "いだり", "kanaOut": "ぐ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "したり", "kanaOut": "す", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ったり", "kanaOut": "う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ったり", "kanaOut": "つ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ったり", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "んだり", "kanaOut": "ぬ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "んだり", "kanaOut": "ぶ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "んだり", "kanaOut": "む", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "じたり", "kanaOut": "ずる", "rulesIn": [], "rulesOut": ["vz"]}, - {"kanaIn": "したり", "kanaOut": "する", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "為たり", "kanaOut": "為る", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "きたり", "kanaOut": "くる", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "来たり", "kanaOut": "来る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "來たり", "kanaOut": "來る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "いったり", "kanaOut": "いく", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "おうたり", "kanaOut": "おう", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "こうたり", "kanaOut": "こう", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "そうたり", "kanaOut": "そう", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "とうたり", "kanaOut": "とう", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "行ったり", "kanaOut": "行く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "逝ったり", "kanaOut": "逝く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "往ったり", "kanaOut": "往く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "請うたり", "kanaOut": "請う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "乞うたり", "kanaOut": "乞う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "恋うたり", "kanaOut": "恋う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "問うたり", "kanaOut": "問う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "負うたり", "kanaOut": "負う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "沿うたり", "kanaOut": "沿う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "添うたり", "kanaOut": "添う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "副うたり", "kanaOut": "副う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "厭うたり", "kanaOut": "厭う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "のたもうたり", "kanaOut": "のたまう", "rulesIn": [], "rulesOut": ["v5"]} - ], - "-te": [ - {"kanaIn": "くて", "kanaOut": "い", "rulesIn": ["iru"], "rulesOut": ["adj-i"]}, - {"kanaIn": "て", "kanaOut": "る", "rulesIn": ["iru"], "rulesOut": ["v1"]}, - {"kanaIn": "いて", "kanaOut": "く", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "いで", "kanaOut": "ぐ", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "して", "kanaOut": "す", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "って", "kanaOut": "う", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "って", "kanaOut": "つ", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "って", "kanaOut": "る", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "んで", "kanaOut": "ぬ", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "んで", "kanaOut": "ぶ", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "んで", "kanaOut": "む", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "じて", "kanaOut": "ずる", "rulesIn": ["iru"], "rulesOut": ["vz"]}, - {"kanaIn": "して", "kanaOut": "する", "rulesIn": ["iru"], "rulesOut": ["vs"]}, - {"kanaIn": "為て", "kanaOut": "為る", "rulesIn": ["iru"], "rulesOut": ["vs"]}, - {"kanaIn": "きて", "kanaOut": "くる", "rulesIn": ["iru"], "rulesOut": ["vk"]}, - {"kanaIn": "来て", "kanaOut": "来る", "rulesIn": ["iru"], "rulesOut": ["vk"]}, - {"kanaIn": "來て", "kanaOut": "來る", "rulesIn": ["iru"], "rulesOut": ["vk"]}, - {"kanaIn": "いって", "kanaOut": "いく", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "おうて", "kanaOut": "おう", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "こうて", "kanaOut": "こう", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "そうて", "kanaOut": "そう", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "とうて", "kanaOut": "とう", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "行って", "kanaOut": "行く", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "逝って", "kanaOut": "逝く", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "往って", "kanaOut": "往く", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "請うて", "kanaOut": "請う", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "乞うて", "kanaOut": "乞う", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "恋うて", "kanaOut": "恋う", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "問うて", "kanaOut": "問う", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "負うて", "kanaOut": "負う", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "沿うて", "kanaOut": "沿う", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "添うて", "kanaOut": "添う", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "副うて", "kanaOut": "副う", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "厭うて", "kanaOut": "厭う", "rulesIn": ["iru"], "rulesOut": ["v5"]}, - {"kanaIn": "のたもうて", "kanaOut": "のたまう", "rulesIn": ["iru"], "rulesOut": ["v5"]} - ], - "-zu": [ - {"kanaIn": "ず", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v1"]}, - {"kanaIn": "かず", "kanaOut": "く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "がず", "kanaOut": "ぐ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "さず", "kanaOut": "す", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "たず", "kanaOut": "つ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "なず", "kanaOut": "ぬ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ばず", "kanaOut": "ぶ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "まず", "kanaOut": "む", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "らず", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "わず", "kanaOut": "う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ぜず", "kanaOut": "ずる", "rulesIn": [], "rulesOut": ["vz"]}, - {"kanaIn": "せず", "kanaOut": "する", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "為ず", "kanaOut": "為る", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "こず", "kanaOut": "くる", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "来ず", "kanaOut": "来る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "來ず", "kanaOut": "來る", "rulesIn": [], "rulesOut": ["vk"]} - ], - "-nu": [ - {"kanaIn": "ぬ", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v1"]}, - {"kanaIn": "かぬ", "kanaOut": "く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "がぬ", "kanaOut": "ぐ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "さぬ", "kanaOut": "す", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "たぬ", "kanaOut": "つ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "なぬ", "kanaOut": "ぬ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ばぬ", "kanaOut": "ぶ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "まぬ", "kanaOut": "む", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "らぬ", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "わぬ", "kanaOut": "う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ぜぬ", "kanaOut": "ずる", "rulesIn": [], "rulesOut": ["vz"]}, - {"kanaIn": "せぬ", "kanaOut": "する", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "為ぬ", "kanaOut": "為る", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "こぬ", "kanaOut": "くる", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "来ぬ", "kanaOut": "来る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "來ぬ", "kanaOut": "來る", "rulesIn": [], "rulesOut": ["vk"]} - ], - "adv": [ - {"kanaIn": "く", "kanaOut": "い", "rulesIn": [], "rulesOut": ["adj-i"]} - ], - "causative": [ - {"kanaIn": "させる", "kanaOut": "る", "rulesIn": ["v1"], "rulesOut": ["v1"]}, - {"kanaIn": "かせる", "kanaOut": "く", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "がせる", "kanaOut": "ぐ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "させる", "kanaOut": "す", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "たせる", "kanaOut": "つ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "なせる", "kanaOut": "ぬ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "ばせる", "kanaOut": "ぶ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "ませる", "kanaOut": "む", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "らせる", "kanaOut": "る", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "わせる", "kanaOut": "う", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "じさせる", "kanaOut": "ずる", "rulesIn": ["v1"], "rulesOut": ["vz"]}, - {"kanaIn": "ぜさせる", "kanaOut": "ずる", "rulesIn": ["v1"], "rulesOut": ["vz"]}, - {"kanaIn": "させる", "kanaOut": "する", "rulesIn": ["v1"], "rulesOut": ["vs"]}, - {"kanaIn": "為せる", "kanaOut": "為る", "rulesIn": ["v1"], "rulesOut": ["vs"]}, - {"kanaIn": "せさせる", "kanaOut": "する", "rulesIn": ["v1"], "rulesOut": ["vs"]}, - {"kanaIn": "為させる", "kanaOut": "為る", "rulesIn": ["v1"], "rulesOut": ["vs"]}, - {"kanaIn": "こさせる", "kanaOut": "くる", "rulesIn": ["v1"], "rulesOut": ["vk"]}, - {"kanaIn": "来させる", "kanaOut": "来る", "rulesIn": ["v1"], "rulesOut": ["vk"]}, - {"kanaIn": "來させる", "kanaOut": "來る", "rulesIn": ["v1"], "rulesOut": ["vk"]} - ], - "imperative": [ - {"kanaIn": "ろ", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v1"]}, - {"kanaIn": "よ", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v1"]}, - {"kanaIn": "え", "kanaOut": "う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "け", "kanaOut": "く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "げ", "kanaOut": "ぐ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "せ", "kanaOut": "す", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "て", "kanaOut": "つ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ね", "kanaOut": "ぬ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "べ", "kanaOut": "ぶ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "め", "kanaOut": "む", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "れ", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "じろ", "kanaOut": "ずる", "rulesIn": [], "rulesOut": ["vz"]}, - {"kanaIn": "ぜよ", "kanaOut": "ずる", "rulesIn": [], "rulesOut": ["vz"]}, - {"kanaIn": "しろ", "kanaOut": "する", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "せよ", "kanaOut": "する", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "為ろ", "kanaOut": "為る", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "為よ", "kanaOut": "為る", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "こい", "kanaOut": "くる", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "来い", "kanaOut": "来る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "來い", "kanaOut": "來る", "rulesIn": [], "rulesOut": ["vk"]} - ], - "imperative negative": [ - {"kanaIn": "な", "kanaOut": "", "rulesIn": [], "rulesOut": ["v1", "v5", "vk", "vs", "vz"]} - ], - "masu stem": [ - {"kanaIn": "い", "kanaOut": "いる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "え", "kanaOut": "える", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "き", "kanaOut": "きる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "ぎ", "kanaOut": "ぎる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "け", "kanaOut": "ける", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "げ", "kanaOut": "げる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "じ", "kanaOut": "じる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "せ", "kanaOut": "せる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "ぜ", "kanaOut": "ぜる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "ち", "kanaOut": "ちる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "て", "kanaOut": "てる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "で", "kanaOut": "でる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "に", "kanaOut": "にる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "ね", "kanaOut": "ねる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "ひ", "kanaOut": "ひる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "び", "kanaOut": "びる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "へ", "kanaOut": "へる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "べ", "kanaOut": "べる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "み", "kanaOut": "みる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "め", "kanaOut": "める", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "り", "kanaOut": "りる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "れ", "kanaOut": "れる", "rulesIn": [], "rulesOut": ["v1d"]}, - {"kanaIn": "い", "kanaOut": "う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "き", "kanaOut": "く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ぎ", "kanaOut": "ぐ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "し", "kanaOut": "す", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ち", "kanaOut": "つ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "に", "kanaOut": "ぬ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "び", "kanaOut": "ぶ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "み", "kanaOut": "む", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "り", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "き", "kanaOut": "くる", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "来", "kanaOut": "来る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "來", "kanaOut": "來る", "rulesIn": [], "rulesOut": ["vk"]} - ], - "negative": [ - {"kanaIn": "くない", "kanaOut": "い", "rulesIn": ["adj-i"], "rulesOut": ["adj-i"]}, - {"kanaIn": "ない", "kanaOut": "る", "rulesIn": ["adj-i"], "rulesOut": ["v1"]}, - {"kanaIn": "かない", "kanaOut": "く", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "がない", "kanaOut": "ぐ", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "さない", "kanaOut": "す", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "たない", "kanaOut": "つ", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "なない", "kanaOut": "ぬ", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "ばない", "kanaOut": "ぶ", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "まない", "kanaOut": "む", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "らない", "kanaOut": "る", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "わない", "kanaOut": "う", "rulesIn": ["adj-i"], "rulesOut": ["v5"]}, - {"kanaIn": "じない", "kanaOut": "ずる", "rulesIn": ["adj-i"], "rulesOut": ["vz"]}, - {"kanaIn": "しない", "kanaOut": "する", "rulesIn": ["adj-i"], "rulesOut": ["vs"]}, - {"kanaIn": "為ない", "kanaOut": "為る", "rulesIn": ["adj-i"], "rulesOut": ["vs"]}, - {"kanaIn": "こない", "kanaOut": "くる", "rulesIn": ["adj-i"], "rulesOut": ["vk"]}, - {"kanaIn": "来ない", "kanaOut": "来る", "rulesIn": ["adj-i"], "rulesOut": ["vk"]}, - {"kanaIn": "來ない", "kanaOut": "來る", "rulesIn": ["adj-i"], "rulesOut": ["vk"]} - ], - "noun": [ - {"kanaIn": "さ", "kanaOut": "い", "rulesIn": [], "rulesOut": ["adj-i"]} - ], - "passive": [ - {"kanaIn": "かれる", "kanaOut": "く", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "がれる", "kanaOut": "ぐ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "される", "kanaOut": "す", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "たれる", "kanaOut": "つ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "なれる", "kanaOut": "ぬ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "ばれる", "kanaOut": "ぶ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "まれる", "kanaOut": "む", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "われる", "kanaOut": "う", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "られる", "kanaOut": "る", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "じされる", "kanaOut": "ずる", "rulesIn": ["v1"], "rulesOut": ["vz"]}, - {"kanaIn": "ぜされる", "kanaOut": "ずる", "rulesIn": ["v1"], "rulesOut": ["vz"]}, - {"kanaIn": "される", "kanaOut": "する", "rulesIn": ["v1"], "rulesOut": ["vs"]}, - {"kanaIn": "為れる", "kanaOut": "為る", "rulesIn": ["v1"], "rulesOut": ["vs"]}, - {"kanaIn": "こられる", "kanaOut": "くる", "rulesIn": ["v1"], "rulesOut": ["vk"]}, - {"kanaIn": "来られる", "kanaOut": "来る", "rulesIn": ["v1"], "rulesOut": ["vk"]}, - {"kanaIn": "來られる", "kanaOut": "來る", "rulesIn": ["v1"], "rulesOut": ["vk"]} - ], - "past": [ - {"kanaIn": "かった", "kanaOut": "い", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "た", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v1"]}, - {"kanaIn": "いた", "kanaOut": "く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "いだ", "kanaOut": "ぐ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "した", "kanaOut": "す", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "った", "kanaOut": "う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "った", "kanaOut": "つ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "った", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "んだ", "kanaOut": "ぬ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "んだ", "kanaOut": "ぶ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "んだ", "kanaOut": "む", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "じた", "kanaOut": "ずる", "rulesIn": [], "rulesOut": ["vz"]}, - {"kanaIn": "した", "kanaOut": "する", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "為た", "kanaOut": "為る", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "きた", "kanaOut": "くる", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "来た", "kanaOut": "来る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "來た", "kanaOut": "來る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "いった", "kanaOut": "いく", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "おうた", "kanaOut": "おう", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "こうた", "kanaOut": "こう", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "そうた", "kanaOut": "そう", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "とうた", "kanaOut": "とう", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "行った", "kanaOut": "行く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "逝った", "kanaOut": "逝く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "往った", "kanaOut": "往く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "請うた", "kanaOut": "請う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "乞うた", "kanaOut": "乞う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "恋うた", "kanaOut": "恋う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "問うた", "kanaOut": "問う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "負うた", "kanaOut": "負う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "沿うた", "kanaOut": "沿う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "添うた", "kanaOut": "添う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "副うた", "kanaOut": "副う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "厭うた", "kanaOut": "厭う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "のたもうた", "kanaOut": "のたまう", "rulesIn": [], "rulesOut": ["v5"]} - ], - "polite": [ - {"kanaIn": "ます", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v1"]}, - {"kanaIn": "います", "kanaOut": "う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "きます", "kanaOut": "く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ぎます", "kanaOut": "ぐ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "します", "kanaOut": "す", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ちます", "kanaOut": "つ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "にます", "kanaOut": "ぬ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "びます", "kanaOut": "ぶ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "みます", "kanaOut": "む", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ります", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "じます", "kanaOut": "ずる", "rulesIn": [], "rulesOut": ["vz"]}, - {"kanaIn": "します", "kanaOut": "する", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "為ます", "kanaOut": "為る", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "きます", "kanaOut": "くる", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "来ます", "kanaOut": "来る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "來ます", "kanaOut": "來る", "rulesIn": [], "rulesOut": ["vk"]} - ], - "polite negative": [ - {"kanaIn": "くありません", "kanaOut": "い", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "ません", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v1"]}, - {"kanaIn": "いません", "kanaOut": "う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "きません", "kanaOut": "く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ぎません", "kanaOut": "ぐ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "しません", "kanaOut": "す", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ちません", "kanaOut": "つ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "にません", "kanaOut": "ぬ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "びません", "kanaOut": "ぶ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "みません", "kanaOut": "む", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "りません", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "じません", "kanaOut": "ずる", "rulesIn": [], "rulesOut": ["vz"]}, - {"kanaIn": "しません", "kanaOut": "する", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "為ません", "kanaOut": "為る", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "きません", "kanaOut": "くる", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "来ません", "kanaOut": "来る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "來ません", "kanaOut": "來る", "rulesIn": [], "rulesOut": ["vk"]} - ], - "polite past": [ - {"kanaIn": "ました", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v1"]}, - {"kanaIn": "いました", "kanaOut": "う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "きました", "kanaOut": "く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ぎました", "kanaOut": "ぐ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "しました", "kanaOut": "す", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ちました", "kanaOut": "つ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "にました", "kanaOut": "ぬ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "びました", "kanaOut": "ぶ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "みました", "kanaOut": "む", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "りました", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "じました", "kanaOut": "ずる", "rulesIn": [], "rulesOut": ["vz"]}, - {"kanaIn": "しました", "kanaOut": "する", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "為ました", "kanaOut": "為る", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "きました", "kanaOut": "くる", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "来ました", "kanaOut": "来る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "來ました", "kanaOut": "來る", "rulesIn": [], "rulesOut": ["vk"]} - ], - "polite past negative": [ - {"kanaIn": "くありませんでした", "kanaOut": "い", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "ませんでした", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v1"]}, - {"kanaIn": "いませんでした", "kanaOut": "う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "きませんでした", "kanaOut": "く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ぎませんでした", "kanaOut": "ぐ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "しませんでした", "kanaOut": "す", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ちませんでした", "kanaOut": "つ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "にませんでした", "kanaOut": "ぬ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "びませんでした", "kanaOut": "ぶ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "みませんでした", "kanaOut": "む", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "りませんでした", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "じませんでした", "kanaOut": "ずる", "rulesIn": [], "rulesOut": ["vz"]}, - {"kanaIn": "しませんでした", "kanaOut": "する", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "為ませんでした", "kanaOut": "為る", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "きませんでした", "kanaOut": "くる", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "来ませんでした", "kanaOut": "来る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "來ませんでした", "kanaOut": "來る", "rulesIn": [], "rulesOut": ["vk"]} - ], - "polite volitional": [ - {"kanaIn": "ましょう", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v1"]}, - {"kanaIn": "いましょう", "kanaOut": "う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "きましょう", "kanaOut": "く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ぎましょう", "kanaOut": "ぐ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "しましょう", "kanaOut": "す", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ちましょう", "kanaOut": "つ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "にましょう", "kanaOut": "ぬ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "びましょう", "kanaOut": "ぶ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "みましょう", "kanaOut": "む", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "りましょう", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "じましょう", "kanaOut": "ずる", "rulesIn": [], "rulesOut": ["vz"]}, - {"kanaIn": "しましょう", "kanaOut": "する", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "為ましょう", "kanaOut": "為る", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "きましょう", "kanaOut": "くる", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "来ましょう", "kanaOut": "来る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "來ましょう", "kanaOut": "來る", "rulesIn": [], "rulesOut": ["vk"]} - ], - "potential": [ - {"kanaIn": "れる", "kanaOut": "る", "rulesIn": ["v1"], "rulesOut": ["v1", "v5"]}, - {"kanaIn": "える", "kanaOut": "う", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "ける", "kanaOut": "く", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "げる", "kanaOut": "ぐ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "せる", "kanaOut": "す", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "てる", "kanaOut": "つ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "ねる", "kanaOut": "ぬ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "べる", "kanaOut": "ぶ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "める", "kanaOut": "む", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "できる", "kanaOut": "する", "rulesIn": ["v1"], "rulesOut": ["vs"]}, - {"kanaIn": "出来る", "kanaOut": "する", "rulesIn": ["v1"], "rulesOut": ["vs"]}, - {"kanaIn": "これる", "kanaOut": "くる", "rulesIn": ["v1"], "rulesOut": ["vk"]}, - {"kanaIn": "来れる", "kanaOut": "来る", "rulesIn": ["v1"], "rulesOut": ["vk"]}, - {"kanaIn": "來れる", "kanaOut": "來る", "rulesIn": ["v1"], "rulesOut": ["vk"]} - ], - "potential or passive": [ - {"kanaIn": "られる", "kanaOut": "る", "rulesIn": ["v1"], "rulesOut": ["v1"]}, - {"kanaIn": "ざれる", "kanaOut": "ずる", "rulesIn": ["v1"], "rulesOut": ["vz"]}, - {"kanaIn": "ぜられる", "kanaOut": "ずる", "rulesIn": ["v1"], "rulesOut": ["vz"]}, - {"kanaIn": "せられる", "kanaOut": "する", "rulesIn": ["v1"], "rulesOut": ["vs"]}, - {"kanaIn": "為られる", "kanaOut": "為る", "rulesIn": ["v1"], "rulesOut": ["vs"]}, - {"kanaIn": "こられる", "kanaOut": "くる", "rulesIn": ["v1"], "rulesOut": ["vk"]}, - {"kanaIn": "来られる", "kanaOut": "来る", "rulesIn": ["v1"], "rulesOut": ["vk"]}, - {"kanaIn": "來られる", "kanaOut": "來る", "rulesIn": ["v1"], "rulesOut": ["vk"]} - ], - "volitional": [ - {"kanaIn": "よう", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v1"]}, - {"kanaIn": "おう", "kanaOut": "う", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "こう", "kanaOut": "く", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ごう", "kanaOut": "ぐ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "そう", "kanaOut": "す", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "とう", "kanaOut": "つ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "のう", "kanaOut": "ぬ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ぼう", "kanaOut": "ぶ", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "もう", "kanaOut": "む", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "ろう", "kanaOut": "る", "rulesIn": [], "rulesOut": ["v5"]}, - {"kanaIn": "じよう", "kanaOut": "ずる", "rulesIn": [], "rulesOut": ["vz"]}, - {"kanaIn": "しよう", "kanaOut": "する", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "為よう", "kanaOut": "為る", "rulesIn": [], "rulesOut": ["vs"]}, - {"kanaIn": "こよう", "kanaOut": "くる", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "来よう", "kanaOut": "来る", "rulesIn": [], "rulesOut": ["vk"]}, - {"kanaIn": "來よう", "kanaOut": "來る", "rulesIn": [], "rulesOut": ["vk"]} - ], - "causative passive": [ - {"kanaIn": "かされる", "kanaOut": "く", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "がされる", "kanaOut": "ぐ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "たされる", "kanaOut": "つ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "なされる", "kanaOut": "ぬ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "ばされる", "kanaOut": "ぶ", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "まされる", "kanaOut": "む", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "らされる", "kanaOut": "る", "rulesIn": ["v1"], "rulesOut": ["v5"]}, - {"kanaIn": "わされる", "kanaOut": "う", "rulesIn": ["v1"], "rulesOut": ["v5"]} - ], - "-toku": [ - {"kanaIn": "とく", "kanaOut": "る", "rulesIn": ["v5"], "rulesOut": ["v1"]}, - {"kanaIn": "いとく", "kanaOut": "く", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "いどく", "kanaOut": "ぐ", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "しとく", "kanaOut": "す", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "っとく", "kanaOut": "う", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "っとく", "kanaOut": "つ", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "っとく", "kanaOut": "る", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "んどく", "kanaOut": "ぬ", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "んどく", "kanaOut": "ぶ", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "んどく", "kanaOut": "む", "rulesIn": ["v5"], "rulesOut": ["v5"]}, - {"kanaIn": "じとく", "kanaOut": "ずる", "rulesIn": ["v5"], "rulesOut": ["vz"]}, - {"kanaIn": "しとく", "kanaOut": "する", "rulesIn": ["v5"], "rulesOut": ["vs"]}, - {"kanaIn": "為とく", "kanaOut": "為る", "rulesIn": ["v5"], "rulesOut": ["vs"]}, - {"kanaIn": "きとく", "kanaOut": "くる", "rulesIn": ["v5"], "rulesOut": ["vk"]}, - {"kanaIn": "来とく", "kanaOut": "来る", "rulesIn": ["v5"], "rulesOut": ["vk"]}, - {"kanaIn": "來とく", "kanaOut": "來る", "rulesIn": ["v5"], "rulesOut": ["vk"]} - ], - "progressive or perfect": [ - {"kanaIn": "ている", "kanaOut": "て", "rulesIn": ["v1"], "rulesOut": ["iru"]}, - {"kanaIn": "ておる", "kanaOut": "て", "rulesIn": ["v5"], "rulesOut": ["iru"]}, - {"kanaIn": "てる", "kanaOut": "て", "rulesIn": ["v1p"], "rulesOut": ["iru"]}, - {"kanaIn": "でいる", "kanaOut": "で", "rulesIn": ["v1"], "rulesOut": ["iru"]}, - {"kanaIn": "でおる", "kanaOut": "で", "rulesIn": ["v5"], "rulesOut": ["iru"]}, - {"kanaIn": "でる", "kanaOut": "で", "rulesIn": ["v1p"], "rulesOut": ["iru"]}, - {"kanaIn": "とる", "kanaOut": "て", "rulesIn": ["v5"], "rulesOut": ["iru"]}, - {"kanaIn": "ないでいる", "kanaOut": "ない", "rulesIn": ["v1"], "rulesOut": ["adj-i"]} - ], - "-ki": [ - {"kanaIn": "き", "kanaOut": "い", "rulesIn": [], "rulesOut": ["adj-i"]} - ], - "-ge": [ - {"kanaIn": "しげ", "kanaOut": "しい", "rulesIn": [], "rulesOut": ["adj-i"]} - ], - "-e": [ - {"kanaIn": "ねえ", "kanaOut": "ない", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "めえ", "kanaOut": "むい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "みい", "kanaOut": "むい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "ちぇえ", "kanaOut": "つい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "ちい", "kanaOut": "つい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "せえ", "kanaOut": "すい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "ええ", "kanaOut": "いい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "ええ", "kanaOut": "わい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "ええ", "kanaOut": "よい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "いぇえ", "kanaOut": "よい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "うぇえ", "kanaOut": "わい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "けえ", "kanaOut": "かい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "げえ", "kanaOut": "がい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "げえ", "kanaOut": "ごい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "せえ", "kanaOut": "さい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "めえ", "kanaOut": "まい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "ぜえ", "kanaOut": "ずい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "っぜえ", "kanaOut": "ずい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "れえ", "kanaOut": "らい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "れえ", "kanaOut": "らい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "ちぇえ", "kanaOut": "ちゃい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "でえ", "kanaOut": "どい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "れえ", "kanaOut": "れい", "rulesIn": [], "rulesOut": ["adj-i"]}, - {"kanaIn": "べえ", "kanaOut": "ばい", "rulesIn": [], "rulesOut": ["adj-i"]} - ] -} diff --git a/ext/data/language/japanese-transforms.json b/ext/data/language/japanese-transforms.json new file mode 100644 index 00000000..007b1404 --- /dev/null +++ b/ext/data/language/japanese-transforms.json @@ -0,0 +1,851 @@ +{ + "language": "ja", + "conditions": { + "v1": { + "name": "Ichidan verb", + "partsOfSpeech": ["v1"], + "i18n": [ + { + "language": "ja", + "name": "一段動詞" + } + ], + "subConditions": ["v1d", "v1p"] + }, + "v1d": { + "name": "Ichidan verb, dictionary form", + "partsOfSpeech": ["v1"], + "i18n": [ + { + "language": "ja", + "name": "一段動詞、辞書形" + } + ] + }, + "v1p": { + "name": "Ichidan verb, progressive or perfect form", + "partsOfSpeech": ["v1"], + "i18n": [ + { + "language": "ja", + "name": "一段動詞、進行形または完了形" + } + ] + }, + "v5": { + "name": "Godan verb", + "partsOfSpeech": ["v5"], + "i18n": [ + { + "language": "ja", + "name": "五段動詞" + } + ] + }, + "vk": { + "name": "Kuru verb", + "partsOfSpeech": ["vk"], + "i18n": [ + { + "language": "ja", + "name": "来る動詞" + } + ] + }, + "vs": { + "name": "Suru verb", + "partsOfSpeech": ["vs"], + "i18n": [ + { + "language": "ja", + "name": "する動詞" + } + ] + }, + "vz": { + "name": "Zuru verb", + "partsOfSpeech": ["vz"], + "i18n": [ + { + "language": "ja", + "name": "ずる動詞" + } + ] + }, + "adj-i": { + "name": "Adjective with i ending", + "partsOfSpeech": ["adj-i"], + "i18n": [ + { + "language": "ja", + "name": "形容詞" + } + ] + }, + "iru": { + "name": "Intermediate -iru endings for progressive or perfect tense", + "partsOfSpeech": [] + } + }, + "transforms": [ + { + "name": "-ba", + "description": "Conditional", + "i18n": [ + { + "language": "ja", + "name": "ば", + "description": "仮定形" + } + ], + "rules": [ + {"suffixIn": "ければ", "suffixOut": "い", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "えば", "suffixOut": "う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "けば", "suffixOut": "く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "げば", "suffixOut": "ぐ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "せば", "suffixOut": "す", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "てば", "suffixOut": "つ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ねば", "suffixOut": "ぬ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "べば", "suffixOut": "ぶ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "めば", "suffixOut": "む", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "れば", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v1", "v5", "vk", "vs", "vz"]} + ] + }, + { + "name": "-chau", + "rules": [ + {"suffixIn": "ちゃう", "suffixOut": "る", "conditionsIn": ["v5"], "conditionsOut": ["v1"]}, + {"suffixIn": "いじゃう", "suffixOut": "ぐ", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "いちゃう", "suffixOut": "く", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "しちゃう", "suffixOut": "す", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "っちゃう", "suffixOut": "う", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "っちゃう", "suffixOut": "く", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "っちゃう", "suffixOut": "つ", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "っちゃう", "suffixOut": "る", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "んじゃう", "suffixOut": "ぬ", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "んじゃう", "suffixOut": "ぶ", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "んじゃう", "suffixOut": "む", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "じちゃう", "suffixOut": "ずる", "conditionsIn": ["v5"], "conditionsOut": ["vz"]}, + {"suffixIn": "しちゃう", "suffixOut": "する", "conditionsIn": ["v5"], "conditionsOut": ["vs"]}, + {"suffixIn": "為ちゃう", "suffixOut": "為る", "conditionsIn": ["v5"], "conditionsOut": ["vs"]}, + {"suffixIn": "きちゃう", "suffixOut": "くる", "conditionsIn": ["v5"], "conditionsOut": ["vk"]}, + {"suffixIn": "来ちゃう", "suffixOut": "来る", "conditionsIn": ["v5"], "conditionsOut": ["vk"]}, + {"suffixIn": "來ちゃう", "suffixOut": "來る", "conditionsIn": ["v5"], "conditionsOut": ["vk"]} + ] + }, + { + "name": "-chimau", + "rules": [ + {"suffixIn": "ちまう", "suffixOut": "る", "conditionsIn": ["v5"], "conditionsOut": ["v1"]}, + {"suffixIn": "いじまう", "suffixOut": "ぐ", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "いちまう", "suffixOut": "く", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "しちまう", "suffixOut": "す", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "っちまう", "suffixOut": "う", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "っちまう", "suffixOut": "く", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "っちまう", "suffixOut": "つ", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "っちまう", "suffixOut": "る", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "んじまう", "suffixOut": "ぬ", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "んじまう", "suffixOut": "ぶ", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "んじまう", "suffixOut": "む", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "じちまう", "suffixOut": "ずる", "conditionsIn": ["v5"], "conditionsOut": ["vz"]}, + {"suffixIn": "しちまう", "suffixOut": "する", "conditionsIn": ["v5"], "conditionsOut": ["vs"]}, + {"suffixIn": "為ちまう", "suffixOut": "為る", "conditionsIn": ["v5"], "conditionsOut": ["vs"]}, + {"suffixIn": "きちまう", "suffixOut": "くる", "conditionsIn": ["v5"], "conditionsOut": ["vk"]}, + {"suffixIn": "来ちまう", "suffixOut": "来る", "conditionsIn": ["v5"], "conditionsOut": ["vk"]}, + {"suffixIn": "來ちまう", "suffixOut": "來る", "conditionsIn": ["v5"], "conditionsOut": ["vk"]} + ] + }, + { + "name": "-shimau", + "rules": [ + {"suffixIn": "てしまう", "suffixOut": "て", "conditionsIn": ["v5"], "conditionsOut": ["iru"]}, + {"suffixIn": "でしまう", "suffixOut": "で", "conditionsIn": ["v5"], "conditionsOut": ["iru"]} + ] + }, + { + "name": "-nasai", + "rules": [ + {"suffixIn": "なさい", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v1"]}, + {"suffixIn": "いなさい", "suffixOut": "う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "きなさい", "suffixOut": "く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ぎなさい", "suffixOut": "ぐ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "しなさい", "suffixOut": "す", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ちなさい", "suffixOut": "つ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "になさい", "suffixOut": "ぬ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "びなさい", "suffixOut": "ぶ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "みなさい", "suffixOut": "む", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "りなさい", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "じなさい", "suffixOut": "ずる", "conditionsIn": [], "conditionsOut": ["vz"]}, + {"suffixIn": "しなさい", "suffixOut": "する", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "為なさい", "suffixOut": "為る", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "きなさい", "suffixOut": "くる", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "来なさい", "suffixOut": "来る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "來なさい", "suffixOut": "來る", "conditionsIn": [], "conditionsOut": ["vk"]} + ] + }, + { + "name": "-sou", + "rules": [ + {"suffixIn": "そう", "suffixOut": "い", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "そう", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v1"]}, + {"suffixIn": "いそう", "suffixOut": "う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "きそう", "suffixOut": "く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ぎそう", "suffixOut": "ぐ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "しそう", "suffixOut": "す", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ちそう", "suffixOut": "つ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "にそう", "suffixOut": "ぬ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "びそう", "suffixOut": "ぶ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "みそう", "suffixOut": "む", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "りそう", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "じそう", "suffixOut": "ずる", "conditionsIn": [], "conditionsOut": ["vz"]}, + {"suffixIn": "しそう", "suffixOut": "する", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "為そう", "suffixOut": "為る", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "きそう", "suffixOut": "くる", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "来そう", "suffixOut": "来る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "來そう", "suffixOut": "來る", "conditionsIn": [], "conditionsOut": ["vk"]} + ] + }, + { + "name": "-sugiru", + "rules": [ + {"suffixIn": "すぎる", "suffixOut": "い", "conditionsIn": ["v1"], "conditionsOut": ["adj-i"]}, + {"suffixIn": "すぎる", "suffixOut": "る", "conditionsIn": ["v1"], "conditionsOut": ["v1"]}, + {"suffixIn": "いすぎる", "suffixOut": "う", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "きすぎる", "suffixOut": "く", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "ぎすぎる", "suffixOut": "ぐ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "しすぎる", "suffixOut": "す", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "ちすぎる", "suffixOut": "つ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "にすぎる", "suffixOut": "ぬ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "びすぎる", "suffixOut": "ぶ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "みすぎる", "suffixOut": "む", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "りすぎる", "suffixOut": "る", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "じすぎる", "suffixOut": "ずる", "conditionsIn": ["v1"], "conditionsOut": ["vz"]}, + {"suffixIn": "しすぎる", "suffixOut": "する", "conditionsIn": ["v1"], "conditionsOut": ["vs"]}, + {"suffixIn": "為すぎる", "suffixOut": "為る", "conditionsIn": ["v1"], "conditionsOut": ["vs"]}, + {"suffixIn": "きすぎる", "suffixOut": "くる", "conditionsIn": ["v1"], "conditionsOut": ["vk"]}, + {"suffixIn": "来すぎる", "suffixOut": "来る", "conditionsIn": ["v1"], "conditionsOut": ["vk"]}, + {"suffixIn": "來すぎる", "suffixOut": "來る", "conditionsIn": ["v1"], "conditionsOut": ["vk"]} + ] + }, + { + "name": "-tai", + "rules": [ + {"suffixIn": "たい", "suffixOut": "る", "conditionsIn": ["adj-i"], "conditionsOut": ["v1"]}, + {"suffixIn": "いたい", "suffixOut": "う", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "きたい", "suffixOut": "く", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "ぎたい", "suffixOut": "ぐ", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "したい", "suffixOut": "す", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "ちたい", "suffixOut": "つ", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "にたい", "suffixOut": "ぬ", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "びたい", "suffixOut": "ぶ", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "みたい", "suffixOut": "む", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "りたい", "suffixOut": "る", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "じたい", "suffixOut": "ずる", "conditionsIn": ["adj-i"], "conditionsOut": ["vz"]}, + {"suffixIn": "したい", "suffixOut": "する", "conditionsIn": ["adj-i"], "conditionsOut": ["vs"]}, + {"suffixIn": "為たい", "suffixOut": "為る", "conditionsIn": ["adj-i"], "conditionsOut": ["vs"]}, + {"suffixIn": "きたい", "suffixOut": "くる", "conditionsIn": ["adj-i"], "conditionsOut": ["vk"]}, + {"suffixIn": "来たい", "suffixOut": "来る", "conditionsIn": ["adj-i"], "conditionsOut": ["vk"]}, + {"suffixIn": "來たい", "suffixOut": "來る", "conditionsIn": ["adj-i"], "conditionsOut": ["vk"]} + ] + }, + { + "name": "-tara", + "rules": [ + {"suffixIn": "かったら", "suffixOut": "い", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "たら", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v1"]}, + {"suffixIn": "いたら", "suffixOut": "く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "いだら", "suffixOut": "ぐ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "したら", "suffixOut": "す", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ったら", "suffixOut": "う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ったら", "suffixOut": "つ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ったら", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "んだら", "suffixOut": "ぬ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "んだら", "suffixOut": "ぶ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "んだら", "suffixOut": "む", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "じたら", "suffixOut": "ずる", "conditionsIn": [], "conditionsOut": ["vz"]}, + {"suffixIn": "したら", "suffixOut": "する", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "為たら", "suffixOut": "為る", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "きたら", "suffixOut": "くる", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "来たら", "suffixOut": "来る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "來たら", "suffixOut": "來る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "いったら", "suffixOut": "いく", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "おうたら", "suffixOut": "おう", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "こうたら", "suffixOut": "こう", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "そうたら", "suffixOut": "そう", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "とうたら", "suffixOut": "とう", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "行ったら", "suffixOut": "行く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "逝ったら", "suffixOut": "逝く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "往ったら", "suffixOut": "往く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "請うたら", "suffixOut": "請う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "乞うたら", "suffixOut": "乞う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "恋うたら", "suffixOut": "恋う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "問うたら", "suffixOut": "問う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "負うたら", "suffixOut": "負う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "沿うたら", "suffixOut": "沿う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "添うたら", "suffixOut": "添う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "副うたら", "suffixOut": "副う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "厭うたら", "suffixOut": "厭う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "のたもうたら", "suffixOut": "のたまう", "conditionsIn": [], "conditionsOut": ["v5"]} + ] + }, + { + "name": "-tari", + "rules": [ + {"suffixIn": "かったり", "suffixOut": "い", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "たり", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v1"]}, + {"suffixIn": "いたり", "suffixOut": "く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "いだり", "suffixOut": "ぐ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "したり", "suffixOut": "す", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ったり", "suffixOut": "う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ったり", "suffixOut": "つ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ったり", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "んだり", "suffixOut": "ぬ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "んだり", "suffixOut": "ぶ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "んだり", "suffixOut": "む", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "じたり", "suffixOut": "ずる", "conditionsIn": [], "conditionsOut": ["vz"]}, + {"suffixIn": "したり", "suffixOut": "する", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "為たり", "suffixOut": "為る", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "きたり", "suffixOut": "くる", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "来たり", "suffixOut": "来る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "來たり", "suffixOut": "來る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "いったり", "suffixOut": "いく", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "おうたり", "suffixOut": "おう", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "こうたり", "suffixOut": "こう", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "そうたり", "suffixOut": "そう", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "とうたり", "suffixOut": "とう", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "行ったり", "suffixOut": "行く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "逝ったり", "suffixOut": "逝く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "往ったり", "suffixOut": "往く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "請うたり", "suffixOut": "請う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "乞うたり", "suffixOut": "乞う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "恋うたり", "suffixOut": "恋う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "問うたり", "suffixOut": "問う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "負うたり", "suffixOut": "負う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "沿うたり", "suffixOut": "沿う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "添うたり", "suffixOut": "添う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "副うたり", "suffixOut": "副う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "厭うたり", "suffixOut": "厭う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "のたもうたり", "suffixOut": "のたまう", "conditionsIn": [], "conditionsOut": ["v5"]} + ] + }, + { + "name": "-te", + "rules": [ + {"suffixIn": "くて", "suffixOut": "い", "conditionsIn": ["iru"], "conditionsOut": ["adj-i"]}, + {"suffixIn": "て", "suffixOut": "る", "conditionsIn": ["iru"], "conditionsOut": ["v1"]}, + {"suffixIn": "いて", "suffixOut": "く", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "いで", "suffixOut": "ぐ", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "して", "suffixOut": "す", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "って", "suffixOut": "う", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "って", "suffixOut": "つ", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "って", "suffixOut": "る", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "んで", "suffixOut": "ぬ", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "んで", "suffixOut": "ぶ", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "んで", "suffixOut": "む", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "じて", "suffixOut": "ずる", "conditionsIn": ["iru"], "conditionsOut": ["vz"]}, + {"suffixIn": "して", "suffixOut": "する", "conditionsIn": ["iru"], "conditionsOut": ["vs"]}, + {"suffixIn": "為て", "suffixOut": "為る", "conditionsIn": ["iru"], "conditionsOut": ["vs"]}, + {"suffixIn": "きて", "suffixOut": "くる", "conditionsIn": ["iru"], "conditionsOut": ["vk"]}, + {"suffixIn": "来て", "suffixOut": "来る", "conditionsIn": ["iru"], "conditionsOut": ["vk"]}, + {"suffixIn": "來て", "suffixOut": "來る", "conditionsIn": ["iru"], "conditionsOut": ["vk"]}, + {"suffixIn": "いって", "suffixOut": "いく", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "おうて", "suffixOut": "おう", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "こうて", "suffixOut": "こう", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "そうて", "suffixOut": "そう", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "とうて", "suffixOut": "とう", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "行って", "suffixOut": "行く", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "逝って", "suffixOut": "逝く", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "往って", "suffixOut": "往く", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "請うて", "suffixOut": "請う", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "乞うて", "suffixOut": "乞う", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "恋うて", "suffixOut": "恋う", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "問うて", "suffixOut": "問う", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "負うて", "suffixOut": "負う", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "沿うて", "suffixOut": "沿う", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "添うて", "suffixOut": "添う", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "副うて", "suffixOut": "副う", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "厭うて", "suffixOut": "厭う", "conditionsIn": ["iru"], "conditionsOut": ["v5"]}, + {"suffixIn": "のたもうて", "suffixOut": "のたまう", "conditionsIn": ["iru"], "conditionsOut": ["v5"]} + ] + }, + { + "name": "-zu", + "rules": [ + {"suffixIn": "ず", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v1"]}, + {"suffixIn": "かず", "suffixOut": "く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "がず", "suffixOut": "ぐ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "さず", "suffixOut": "す", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "たず", "suffixOut": "つ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "なず", "suffixOut": "ぬ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ばず", "suffixOut": "ぶ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "まず", "suffixOut": "む", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "らず", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "わず", "suffixOut": "う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ぜず", "suffixOut": "ずる", "conditionsIn": [], "conditionsOut": ["vz"]}, + {"suffixIn": "せず", "suffixOut": "する", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "為ず", "suffixOut": "為る", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "こず", "suffixOut": "くる", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "来ず", "suffixOut": "来る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "來ず", "suffixOut": "來る", "conditionsIn": [], "conditionsOut": ["vk"]} + ] + }, + { + "name": "-nu", + "rules": [ + {"suffixIn": "ぬ", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v1"]}, + {"suffixIn": "かぬ", "suffixOut": "く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "がぬ", "suffixOut": "ぐ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "さぬ", "suffixOut": "す", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "たぬ", "suffixOut": "つ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "なぬ", "suffixOut": "ぬ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ばぬ", "suffixOut": "ぶ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "まぬ", "suffixOut": "む", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "らぬ", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "わぬ", "suffixOut": "う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ぜぬ", "suffixOut": "ずる", "conditionsIn": [], "conditionsOut": ["vz"]}, + {"suffixIn": "せぬ", "suffixOut": "する", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "為ぬ", "suffixOut": "為る", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "こぬ", "suffixOut": "くる", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "来ぬ", "suffixOut": "来る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "來ぬ", "suffixOut": "來る", "conditionsIn": [], "conditionsOut": ["vk"]} + ] + }, + { + "name": "adv", + "rules": [ + {"suffixIn": "く", "suffixOut": "い", "conditionsIn": [], "conditionsOut": ["adj-i"]} + ] + }, + { + "name": "causative", + "rules": [ + {"suffixIn": "させる", "suffixOut": "る", "conditionsIn": ["v1"], "conditionsOut": ["v1"]}, + {"suffixIn": "かせる", "suffixOut": "く", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "がせる", "suffixOut": "ぐ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "させる", "suffixOut": "す", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "たせる", "suffixOut": "つ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "なせる", "suffixOut": "ぬ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "ばせる", "suffixOut": "ぶ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "ませる", "suffixOut": "む", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "らせる", "suffixOut": "る", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "わせる", "suffixOut": "う", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "じさせる", "suffixOut": "ずる", "conditionsIn": ["v1"], "conditionsOut": ["vz"]}, + {"suffixIn": "ぜさせる", "suffixOut": "ずる", "conditionsIn": ["v1"], "conditionsOut": ["vz"]}, + {"suffixIn": "させる", "suffixOut": "する", "conditionsIn": ["v1"], "conditionsOut": ["vs"]}, + {"suffixIn": "為せる", "suffixOut": "為る", "conditionsIn": ["v1"], "conditionsOut": ["vs"]}, + {"suffixIn": "せさせる", "suffixOut": "する", "conditionsIn": ["v1"], "conditionsOut": ["vs"]}, + {"suffixIn": "為させる", "suffixOut": "為る", "conditionsIn": ["v1"], "conditionsOut": ["vs"]}, + {"suffixIn": "こさせる", "suffixOut": "くる", "conditionsIn": ["v1"], "conditionsOut": ["vk"]}, + {"suffixIn": "来させる", "suffixOut": "来る", "conditionsIn": ["v1"], "conditionsOut": ["vk"]}, + {"suffixIn": "來させる", "suffixOut": "來る", "conditionsIn": ["v1"], "conditionsOut": ["vk"]} + ] + }, + { + "name": "imperative", + "rules": [ + {"suffixIn": "ろ", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v1"]}, + {"suffixIn": "よ", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v1"]}, + {"suffixIn": "え", "suffixOut": "う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "け", "suffixOut": "く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "げ", "suffixOut": "ぐ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "せ", "suffixOut": "す", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "て", "suffixOut": "つ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ね", "suffixOut": "ぬ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "べ", "suffixOut": "ぶ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "め", "suffixOut": "む", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "れ", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "じろ", "suffixOut": "ずる", "conditionsIn": [], "conditionsOut": ["vz"]}, + {"suffixIn": "ぜよ", "suffixOut": "ずる", "conditionsIn": [], "conditionsOut": ["vz"]}, + {"suffixIn": "しろ", "suffixOut": "する", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "せよ", "suffixOut": "する", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "為ろ", "suffixOut": "為る", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "為よ", "suffixOut": "為る", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "こい", "suffixOut": "くる", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "来い", "suffixOut": "来る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "來い", "suffixOut": "來る", "conditionsIn": [], "conditionsOut": ["vk"]} + ] + }, + { + "name": "imperative negative", + "rules": [ + {"suffixIn": "な", "suffixOut": "", "conditionsIn": [], "conditionsOut": ["v1", "v5", "vk", "vs", "vz"]} + ] + }, + { + "name": "masu stem", + "rules": [ + {"suffixIn": "い", "suffixOut": "いる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "え", "suffixOut": "える", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "き", "suffixOut": "きる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "ぎ", "suffixOut": "ぎる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "け", "suffixOut": "ける", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "げ", "suffixOut": "げる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "じ", "suffixOut": "じる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "せ", "suffixOut": "せる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "ぜ", "suffixOut": "ぜる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "ち", "suffixOut": "ちる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "て", "suffixOut": "てる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "で", "suffixOut": "でる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "に", "suffixOut": "にる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "ね", "suffixOut": "ねる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "ひ", "suffixOut": "ひる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "び", "suffixOut": "びる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "へ", "suffixOut": "へる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "べ", "suffixOut": "べる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "み", "suffixOut": "みる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "め", "suffixOut": "める", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "り", "suffixOut": "りる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "れ", "suffixOut": "れる", "conditionsIn": [], "conditionsOut": ["v1d"]}, + {"suffixIn": "い", "suffixOut": "う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "き", "suffixOut": "く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ぎ", "suffixOut": "ぐ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "し", "suffixOut": "す", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ち", "suffixOut": "つ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "に", "suffixOut": "ぬ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "び", "suffixOut": "ぶ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "み", "suffixOut": "む", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "り", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "き", "suffixOut": "くる", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "来", "suffixOut": "来る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "來", "suffixOut": "來る", "conditionsIn": [], "conditionsOut": ["vk"]} + ] + }, + { + "name": "negative", + "rules": [ + {"suffixIn": "くない", "suffixOut": "い", "conditionsIn": ["adj-i"], "conditionsOut": ["adj-i"]}, + {"suffixIn": "ない", "suffixOut": "る", "conditionsIn": ["adj-i"], "conditionsOut": ["v1"]}, + {"suffixIn": "かない", "suffixOut": "く", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "がない", "suffixOut": "ぐ", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "さない", "suffixOut": "す", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "たない", "suffixOut": "つ", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "なない", "suffixOut": "ぬ", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "ばない", "suffixOut": "ぶ", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "まない", "suffixOut": "む", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "らない", "suffixOut": "る", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "わない", "suffixOut": "う", "conditionsIn": ["adj-i"], "conditionsOut": ["v5"]}, + {"suffixIn": "じない", "suffixOut": "ずる", "conditionsIn": ["adj-i"], "conditionsOut": ["vz"]}, + {"suffixIn": "しない", "suffixOut": "する", "conditionsIn": ["adj-i"], "conditionsOut": ["vs"]}, + {"suffixIn": "為ない", "suffixOut": "為る", "conditionsIn": ["adj-i"], "conditionsOut": ["vs"]}, + {"suffixIn": "こない", "suffixOut": "くる", "conditionsIn": ["adj-i"], "conditionsOut": ["vk"]}, + {"suffixIn": "来ない", "suffixOut": "来る", "conditionsIn": ["adj-i"], "conditionsOut": ["vk"]}, + {"suffixIn": "來ない", "suffixOut": "來る", "conditionsIn": ["adj-i"], "conditionsOut": ["vk"]} + ] + }, + { + "name": "noun", + "rules": [ + {"suffixIn": "さ", "suffixOut": "い", "conditionsIn": [], "conditionsOut": ["adj-i"]} + ] + }, + { + "name": "passive", + "rules": [ + {"suffixIn": "かれる", "suffixOut": "く", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "がれる", "suffixOut": "ぐ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "される", "suffixOut": "す", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "たれる", "suffixOut": "つ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "なれる", "suffixOut": "ぬ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "ばれる", "suffixOut": "ぶ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "まれる", "suffixOut": "む", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "われる", "suffixOut": "う", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "られる", "suffixOut": "る", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "じされる", "suffixOut": "ずる", "conditionsIn": ["v1"], "conditionsOut": ["vz"]}, + {"suffixIn": "ぜされる", "suffixOut": "ずる", "conditionsIn": ["v1"], "conditionsOut": ["vz"]}, + {"suffixIn": "される", "suffixOut": "する", "conditionsIn": ["v1"], "conditionsOut": ["vs"]}, + {"suffixIn": "為れる", "suffixOut": "為る", "conditionsIn": ["v1"], "conditionsOut": ["vs"]}, + {"suffixIn": "こられる", "suffixOut": "くる", "conditionsIn": ["v1"], "conditionsOut": ["vk"]}, + {"suffixIn": "来られる", "suffixOut": "来る", "conditionsIn": ["v1"], "conditionsOut": ["vk"]}, + {"suffixIn": "來られる", "suffixOut": "來る", "conditionsIn": ["v1"], "conditionsOut": ["vk"]} + ] + }, + { + "name": "past", + "rules": [ + {"suffixIn": "かった", "suffixOut": "い", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "た", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v1"]}, + {"suffixIn": "いた", "suffixOut": "く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "いだ", "suffixOut": "ぐ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "した", "suffixOut": "す", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "った", "suffixOut": "う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "った", "suffixOut": "つ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "った", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "んだ", "suffixOut": "ぬ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "んだ", "suffixOut": "ぶ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "んだ", "suffixOut": "む", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "じた", "suffixOut": "ずる", "conditionsIn": [], "conditionsOut": ["vz"]}, + {"suffixIn": "した", "suffixOut": "する", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "為た", "suffixOut": "為る", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "きた", "suffixOut": "くる", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "来た", "suffixOut": "来る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "來た", "suffixOut": "來る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "いった", "suffixOut": "いく", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "おうた", "suffixOut": "おう", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "こうた", "suffixOut": "こう", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "そうた", "suffixOut": "そう", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "とうた", "suffixOut": "とう", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "行った", "suffixOut": "行く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "逝った", "suffixOut": "逝く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "往った", "suffixOut": "往く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "請うた", "suffixOut": "請う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "乞うた", "suffixOut": "乞う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "恋うた", "suffixOut": "恋う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "問うた", "suffixOut": "問う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "負うた", "suffixOut": "負う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "沿うた", "suffixOut": "沿う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "添うた", "suffixOut": "添う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "副うた", "suffixOut": "副う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "厭うた", "suffixOut": "厭う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "のたもうた", "suffixOut": "のたまう", "conditionsIn": [], "conditionsOut": ["v5"]} + ] + }, + { + "name": "polite", + "rules": [ + {"suffixIn": "ます", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v1"]}, + {"suffixIn": "います", "suffixOut": "う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "きます", "suffixOut": "く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ぎます", "suffixOut": "ぐ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "します", "suffixOut": "す", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ちます", "suffixOut": "つ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "にます", "suffixOut": "ぬ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "びます", "suffixOut": "ぶ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "みます", "suffixOut": "む", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ります", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "じます", "suffixOut": "ずる", "conditionsIn": [], "conditionsOut": ["vz"]}, + {"suffixIn": "します", "suffixOut": "する", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "為ます", "suffixOut": "為る", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "きます", "suffixOut": "くる", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "来ます", "suffixOut": "来る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "來ます", "suffixOut": "來る", "conditionsIn": [], "conditionsOut": ["vk"]} + ] + }, + { + "name": "polite negative", + "rules": [ + {"suffixIn": "くありません", "suffixOut": "い", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "ません", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v1"]}, + {"suffixIn": "いません", "suffixOut": "う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "きません", "suffixOut": "く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ぎません", "suffixOut": "ぐ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "しません", "suffixOut": "す", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ちません", "suffixOut": "つ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "にません", "suffixOut": "ぬ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "びません", "suffixOut": "ぶ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "みません", "suffixOut": "む", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "りません", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "じません", "suffixOut": "ずる", "conditionsIn": [], "conditionsOut": ["vz"]}, + {"suffixIn": "しません", "suffixOut": "する", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "為ません", "suffixOut": "為る", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "きません", "suffixOut": "くる", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "来ません", "suffixOut": "来る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "來ません", "suffixOut": "來る", "conditionsIn": [], "conditionsOut": ["vk"]} + ] + }, + { + "name": "polite past", + "rules": [ + {"suffixIn": "ました", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v1"]}, + {"suffixIn": "いました", "suffixOut": "う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "きました", "suffixOut": "く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ぎました", "suffixOut": "ぐ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "しました", "suffixOut": "す", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ちました", "suffixOut": "つ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "にました", "suffixOut": "ぬ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "びました", "suffixOut": "ぶ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "みました", "suffixOut": "む", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "りました", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "じました", "suffixOut": "ずる", "conditionsIn": [], "conditionsOut": ["vz"]}, + {"suffixIn": "しました", "suffixOut": "する", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "為ました", "suffixOut": "為る", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "きました", "suffixOut": "くる", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "来ました", "suffixOut": "来る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "來ました", "suffixOut": "來る", "conditionsIn": [], "conditionsOut": ["vk"]} + ] + }, + { + "name": "polite past negative", + "rules": [ + {"suffixIn": "くありませんでした", "suffixOut": "い", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "ませんでした", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v1"]}, + {"suffixIn": "いませんでした", "suffixOut": "う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "きませんでした", "suffixOut": "く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ぎませんでした", "suffixOut": "ぐ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "しませんでした", "suffixOut": "す", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ちませんでした", "suffixOut": "つ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "にませんでした", "suffixOut": "ぬ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "びませんでした", "suffixOut": "ぶ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "みませんでした", "suffixOut": "む", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "りませんでした", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "じませんでした", "suffixOut": "ずる", "conditionsIn": [], "conditionsOut": ["vz"]}, + {"suffixIn": "しませんでした", "suffixOut": "する", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "為ませんでした", "suffixOut": "為る", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "きませんでした", "suffixOut": "くる", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "来ませんでした", "suffixOut": "来る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "來ませんでした", "suffixOut": "來る", "conditionsIn": [], "conditionsOut": ["vk"]} + ] + }, + { + "name": "polite volitional", + "rules": [ + {"suffixIn": "ましょう", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v1"]}, + {"suffixIn": "いましょう", "suffixOut": "う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "きましょう", "suffixOut": "く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ぎましょう", "suffixOut": "ぐ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "しましょう", "suffixOut": "す", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ちましょう", "suffixOut": "つ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "にましょう", "suffixOut": "ぬ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "びましょう", "suffixOut": "ぶ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "みましょう", "suffixOut": "む", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "りましょう", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "じましょう", "suffixOut": "ずる", "conditionsIn": [], "conditionsOut": ["vz"]}, + {"suffixIn": "しましょう", "suffixOut": "する", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "為ましょう", "suffixOut": "為る", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "きましょう", "suffixOut": "くる", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "来ましょう", "suffixOut": "来る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "來ましょう", "suffixOut": "來る", "conditionsIn": [], "conditionsOut": ["vk"]} + ] + }, + { + "name": "potential", + "rules": [ + {"suffixIn": "れる", "suffixOut": "る", "conditionsIn": ["v1"], "conditionsOut": ["v1", "v5"]}, + {"suffixIn": "える", "suffixOut": "う", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "ける", "suffixOut": "く", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "げる", "suffixOut": "ぐ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "せる", "suffixOut": "す", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "てる", "suffixOut": "つ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "ねる", "suffixOut": "ぬ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "べる", "suffixOut": "ぶ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "める", "suffixOut": "む", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "できる", "suffixOut": "する", "conditionsIn": ["v1"], "conditionsOut": ["vs"]}, + {"suffixIn": "出来る", "suffixOut": "する", "conditionsIn": ["v1"], "conditionsOut": ["vs"]}, + {"suffixIn": "これる", "suffixOut": "くる", "conditionsIn": ["v1"], "conditionsOut": ["vk"]}, + {"suffixIn": "来れる", "suffixOut": "来る", "conditionsIn": ["v1"], "conditionsOut": ["vk"]}, + {"suffixIn": "來れる", "suffixOut": "來る", "conditionsIn": ["v1"], "conditionsOut": ["vk"]} + ] + }, + { + "name": "potential or passive", + "rules": [ + {"suffixIn": "られる", "suffixOut": "る", "conditionsIn": ["v1"], "conditionsOut": ["v1"]}, + {"suffixIn": "ざれる", "suffixOut": "ずる", "conditionsIn": ["v1"], "conditionsOut": ["vz"]}, + {"suffixIn": "ぜられる", "suffixOut": "ずる", "conditionsIn": ["v1"], "conditionsOut": ["vz"]}, + {"suffixIn": "せられる", "suffixOut": "する", "conditionsIn": ["v1"], "conditionsOut": ["vs"]}, + {"suffixIn": "為られる", "suffixOut": "為る", "conditionsIn": ["v1"], "conditionsOut": ["vs"]}, + {"suffixIn": "こられる", "suffixOut": "くる", "conditionsIn": ["v1"], "conditionsOut": ["vk"]}, + {"suffixIn": "来られる", "suffixOut": "来る", "conditionsIn": ["v1"], "conditionsOut": ["vk"]}, + {"suffixIn": "來られる", "suffixOut": "來る", "conditionsIn": ["v1"], "conditionsOut": ["vk"]} + ] + }, + { + "name": "volitional", + "rules": [ + {"suffixIn": "よう", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v1"]}, + {"suffixIn": "おう", "suffixOut": "う", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "こう", "suffixOut": "く", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ごう", "suffixOut": "ぐ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "そう", "suffixOut": "す", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "とう", "suffixOut": "つ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "のう", "suffixOut": "ぬ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ぼう", "suffixOut": "ぶ", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "もう", "suffixOut": "む", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "ろう", "suffixOut": "る", "conditionsIn": [], "conditionsOut": ["v5"]}, + {"suffixIn": "じよう", "suffixOut": "ずる", "conditionsIn": [], "conditionsOut": ["vz"]}, + {"suffixIn": "しよう", "suffixOut": "する", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "為よう", "suffixOut": "為る", "conditionsIn": [], "conditionsOut": ["vs"]}, + {"suffixIn": "こよう", "suffixOut": "くる", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "来よう", "suffixOut": "来る", "conditionsIn": [], "conditionsOut": ["vk"]}, + {"suffixIn": "來よう", "suffixOut": "來る", "conditionsIn": [], "conditionsOut": ["vk"]} + ] + }, + { + "name": "causative passive", + "rules": [ + {"suffixIn": "かされる", "suffixOut": "く", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "がされる", "suffixOut": "ぐ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "たされる", "suffixOut": "つ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "なされる", "suffixOut": "ぬ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "ばされる", "suffixOut": "ぶ", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "まされる", "suffixOut": "む", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "らされる", "suffixOut": "る", "conditionsIn": ["v1"], "conditionsOut": ["v5"]}, + {"suffixIn": "わされる", "suffixOut": "う", "conditionsIn": ["v1"], "conditionsOut": ["v5"]} + ] + }, + { + "name": "-toku", + "rules": [ + {"suffixIn": "とく", "suffixOut": "る", "conditionsIn": ["v5"], "conditionsOut": ["v1"]}, + {"suffixIn": "いとく", "suffixOut": "く", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "いどく", "suffixOut": "ぐ", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "しとく", "suffixOut": "す", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "っとく", "suffixOut": "う", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "っとく", "suffixOut": "つ", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "っとく", "suffixOut": "る", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "んどく", "suffixOut": "ぬ", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "んどく", "suffixOut": "ぶ", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "んどく", "suffixOut": "む", "conditionsIn": ["v5"], "conditionsOut": ["v5"]}, + {"suffixIn": "じとく", "suffixOut": "ずる", "conditionsIn": ["v5"], "conditionsOut": ["vz"]}, + {"suffixIn": "しとく", "suffixOut": "する", "conditionsIn": ["v5"], "conditionsOut": ["vs"]}, + {"suffixIn": "為とく", "suffixOut": "為る", "conditionsIn": ["v5"], "conditionsOut": ["vs"]}, + {"suffixIn": "きとく", "suffixOut": "くる", "conditionsIn": ["v5"], "conditionsOut": ["vk"]}, + {"suffixIn": "来とく", "suffixOut": "来る", "conditionsIn": ["v5"], "conditionsOut": ["vk"]}, + {"suffixIn": "來とく", "suffixOut": "來る", "conditionsIn": ["v5"], "conditionsOut": ["vk"]} + ] + }, + { + "name": "progressive or perfect", + "rules": [ + {"suffixIn": "ている", "suffixOut": "て", "conditionsIn": ["v1"], "conditionsOut": ["iru"]}, + {"suffixIn": "ておる", "suffixOut": "て", "conditionsIn": ["v5"], "conditionsOut": ["iru"]}, + {"suffixIn": "てる", "suffixOut": "て", "conditionsIn": ["v1p"], "conditionsOut": ["iru"]}, + {"suffixIn": "でいる", "suffixOut": "で", "conditionsIn": ["v1"], "conditionsOut": ["iru"]}, + {"suffixIn": "でおる", "suffixOut": "で", "conditionsIn": ["v5"], "conditionsOut": ["iru"]}, + {"suffixIn": "でる", "suffixOut": "で", "conditionsIn": ["v1p"], "conditionsOut": ["iru"]}, + {"suffixIn": "とる", "suffixOut": "て", "conditionsIn": ["v5"], "conditionsOut": ["iru"]}, + {"suffixIn": "ないでいる", "suffixOut": "ない", "conditionsIn": ["v1"], "conditionsOut": ["adj-i"]} + ] + }, + { + "name": "-ki", + "rules": [ + {"suffixIn": "き", "suffixOut": "い", "conditionsIn": [], "conditionsOut": ["adj-i"]} + ] + }, + { + "name": "-ge", + "rules": [ + {"suffixIn": "しげ", "suffixOut": "しい", "conditionsIn": [], "conditionsOut": ["adj-i"]} + ] + }, + { + "name": "-e", + "rules": [ + {"suffixIn": "ねえ", "suffixOut": "ない", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "めえ", "suffixOut": "むい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "みい", "suffixOut": "むい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "ちぇえ", "suffixOut": "つい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "ちい", "suffixOut": "つい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "せえ", "suffixOut": "すい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "ええ", "suffixOut": "いい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "ええ", "suffixOut": "わい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "ええ", "suffixOut": "よい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "いぇえ", "suffixOut": "よい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "うぇえ", "suffixOut": "わい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "けえ", "suffixOut": "かい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "げえ", "suffixOut": "がい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "げえ", "suffixOut": "ごい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "せえ", "suffixOut": "さい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "めえ", "suffixOut": "まい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "ぜえ", "suffixOut": "ずい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "っぜえ", "suffixOut": "ずい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "れえ", "suffixOut": "らい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "れえ", "suffixOut": "らい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "ちぇえ", "suffixOut": "ちゃい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "でえ", "suffixOut": "どい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "れえ", "suffixOut": "れい", "conditionsIn": [], "conditionsOut": ["adj-i"]}, + {"suffixIn": "べえ", "suffixOut": "ばい", "conditionsIn": [], "conditionsOut": ["adj-i"]} + ] + } + ] +} \ No newline at end of file diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js index 74c1370c..0773dc4b 100644 --- a/ext/js/background/backend.js +++ b/ext/js/background/backend.js @@ -282,9 +282,9 @@ export class Backend { log.error(e); } - /** @type {import('deinflector').ReasonsRaw} */ - const deinflectionReasons = await this._fetchJson('/data/deinflect.json'); - this._translator.prepare(deinflectionReasons); + /** @type {import('language-transformer').LanguageTransformDescriptor} */ + const descriptor = await this._fetchJson('/data/language/japanese-transforms.json'); + this._translator.prepare(descriptor); await this._optionsUtil.prepare(); this._defaultAnkiFieldTemplates = (await this._fetchText('/data/templates/default-anki-field-templates.handlebars')).trim(); diff --git a/ext/js/background/offscreen-proxy.js b/ext/js/background/offscreen-proxy.js index 555c3abc..80ff31c0 100644 --- a/ext/js/background/offscreen-proxy.js +++ b/ext/js/background/offscreen-proxy.js @@ -159,10 +159,10 @@ export class TranslatorProxy { } /** - * @param {import('deinflector').ReasonsRaw} deinflectionReasons + * @param {import('language-transformer').LanguageTransformDescriptor} descriptor */ - async prepare(deinflectionReasons) { - await this._offscreen.sendMessagePromise({action: 'translatorPrepareOffscreen', params: {deinflectionReasons}}); + async prepare(descriptor) { + await this._offscreen.sendMessagePromise({action: 'translatorPrepareOffscreen', params: {descriptor}}); } /** diff --git a/ext/js/background/offscreen.js b/ext/js/background/offscreen.js index a0f5592e..ef05508a 100644 --- a/ext/js/background/offscreen.js +++ b/ext/js/background/offscreen.js @@ -115,8 +115,8 @@ export class Offscreen { } /** @type {import('offscreen').ApiHandler<'translatorPrepareOffscreen'>} */ - _prepareTranslatorHandler({deinflectionReasons}) { - this._translator.prepare(deinflectionReasons); + _prepareTranslatorHandler({descriptor}) { + this._translator.prepare(descriptor); } /** @type {import('offscreen').ApiHandler<'findKanjiOffscreen'>} */ diff --git a/ext/js/language/deinflector.js b/ext/js/language/deinflector.js deleted file mode 100644 index b52b7f5b..00000000 --- a/ext/js/language/deinflector.js +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2023-2024 Yomitan Authors - * Copyright (C) 2016-2022 Yomichan Authors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -export class Deinflector { - /* eslint-disable no-multi-spaces */ - /** @type {Map} @readonly */ - static _ruleTypes = new Map([ - ['v1', /** @type {import('translation-internal').DeinflectionRuleFlags} */ (0b000000011)], // Verb ichidan - ['v1d', /** @type {import('translation-internal').DeinflectionRuleFlags} */ (0b000000010)], // Verb ichidan dictionary form - ['v1p', /** @type {import('translation-internal').DeinflectionRuleFlags} */ (0b000000001)], // Verb ichidan progressive or perfect - ['v5', /** @type {import('translation-internal').DeinflectionRuleFlags} */ (0b000000100)], // Verb godan - ['vs', /** @type {import('translation-internal').DeinflectionRuleFlags} */ (0b000001000)], // Verb suru - ['vk', /** @type {import('translation-internal').DeinflectionRuleFlags} */ (0b000010000)], // Verb kuru - ['vz', /** @type {import('translation-internal').DeinflectionRuleFlags} */ (0b000100000)], // Verb zuru - ['adj-i', /** @type {import('translation-internal').DeinflectionRuleFlags} */ (0b001000000)], // Adjective i - ['iru', /** @type {import('translation-internal').DeinflectionRuleFlags} */ (0b010000000)] // Intermediate -iru endings for progressive or perfect tense - ]); - /* eslint-enable no-multi-spaces */ - - /** - * @param {import('deinflector').ReasonsRaw} reasons - * @example - * const deinflectionReasons = parseJson( - * readFileSync(path.join('ext/data/deinflect.json')).toString(), - * ); - * const deinflector = new Deinflector(deinflectionReasons); - */ - constructor(reasons) { - /** @type {import('deinflector').Reason[]} */ - this.reasons = Deinflector.normalizeReasons(reasons); - } - - /** - * Deinflects a Japanese term to all of its possible dictionary forms. - * @param {string} source The source term to deinflect. - * @returns {import('translation-internal').Deinflection[]} - * @example - * const deinflector = new Deinflector(deinflectionReasons); - * // [{ term: '食べた', rules: 0, reasons: [] }, { term: '食べる', rules: 1, reasons: ['past'] }, { term: '食ぶ', rules: 2, reasons: ['potential', 'past'] }] - * console.log(deinflector.deinflect('食べた')); - */ - deinflect(source) { - const results = [this._createDeinflection(source, 0, [])]; - for (let i = 0; i < results.length; ++i) { - const {rules, term, reasons} = results[i]; - for (const [reason, variants] of this.reasons) { - for (const [kanaIn, kanaOut, rulesIn, rulesOut] of variants) { - if ( - !Deinflector.rulesMatch(rules, rulesIn) || - !term.endsWith(kanaIn) || - (term.length - kanaIn.length + kanaOut.length) <= 0 - ) { - continue; - } - - results.push(this._createDeinflection( - term.substring(0, term.length - kanaIn.length) + kanaOut, - rulesOut, - [reason, ...reasons] - )); - } - } - } - return results; - } - - /** - * @param {string} term - * @param {import('translation-internal').DeinflectionRuleFlags} rules - * @param {import('dictionary').InflectionRuleChain} reasons - * @returns {import('translation-internal').Deinflection} - */ - _createDeinflection(term, rules, reasons) { - return {term, rules, reasons}; - } - - /** - * @param {import('deinflector').ReasonsRaw} reasons - * @returns {import('deinflector').Reason[]} - */ - static normalizeReasons(reasons) { - /** @type {import('deinflector').Reason[]} */ - const normalizedReasons = []; - for (const [reason, reasonInfo] of Object.entries(reasons)) { - /** @type {import('deinflector').ReasonVariant[]} */ - const variants = []; - for (const {kanaIn, kanaOut, rulesIn, rulesOut} of reasonInfo) { - variants.push([ - kanaIn, - kanaOut, - this.rulesToRuleFlags(rulesIn), - this.rulesToRuleFlags(rulesOut) - ]); - } - normalizedReasons.push([reason, variants]); - } - return normalizedReasons; - } - - /** - * @param {string[]} rules - * @returns {import('translation-internal').DeinflectionRuleFlags} - */ - static rulesToRuleFlags(rules) { - const ruleTypes = this._ruleTypes; - let value = 0; - for (const rule of rules) { - const ruleBits = ruleTypes.get(rule); - if (typeof ruleBits === 'undefined') { continue; } - value |= ruleBits; - } - return value; - } - - /** - * If `currentRules` is `0`, then `nextRules` is ignored and `true` is returned. - * Otherwise, there must be at least one shared rule between `currentRules` and `nextRules`. - * @param {number} currentRules - * @param {number} nextRules - * @returns {boolean} - */ - static rulesMatch(currentRules, nextRules) { - return currentRules === 0 || (currentRules & nextRules) !== 0; - } -} diff --git a/ext/js/language/language-transformer.js b/ext/js/language/language-transformer.js new file mode 100644 index 00000000..c9e261ea --- /dev/null +++ b/ext/js/language/language-transformer.js @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2024 Yomitan Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +export class LanguageTransformer { + constructor() { + /** @type {number} */ + this._nextFlagIndex = 0; + /** @type {import('language-transformer-internal').Transform[]} */ + this._transforms = []; + /** @type {Map} */ + this._conditionTypeToConditionFlagsMap = new Map(); + /** @type {Map} */ + this._partOfSpeechToConditionFlagsMap = new Map(); + } + + /** */ + clear() { + this._nextFlagIndex = 0; + this._transforms = []; + this._conditionTypeToConditionFlagsMap.clear(); + this._partOfSpeechToConditionFlagsMap.clear(); + } + + /** + * Note: this function does not currently combine properly with previous descriptors, + * they are treated as completely separate collections. This should eventually be changed. + * @param {import('language-transformer').LanguageTransformDescriptor} descriptor + * @throws {Error} + */ + addDescriptor(descriptor) { + const {conditions, transforms} = descriptor; + const conditionEntries = Object.entries(conditions); + const {conditionFlagsMap, nextFlagIndex} = this._getConditionFlagsMap(conditionEntries, this._nextFlagIndex); + + /** @type {import('language-transformer-internal').Transform[]} */ + const transforms2 = []; + for (let i = 0, ii = transforms.length; i < ii; ++i) { + const {name, rules} = transforms[i]; + /** @type {import('language-transformer-internal').Rule[]} */ + const rules2 = []; + for (let j = 0, jj = rules.length; j < jj; ++j) { + const {suffixIn, suffixOut, conditionsIn, conditionsOut} = rules[j]; + const conditionFlagsIn = this._getConditionFlags(conditionFlagsMap, conditionsIn); + if (conditionFlagsIn === null) { throw new Error(`Invalid conditionsIn for transform[${i}].rules[${j}]`); } + const conditionFlagsOut = this._getConditionFlags(conditionFlagsMap, conditionsOut); + if (conditionFlagsOut === null) { throw new Error(`Invalid conditionsOut for transform[${i}].rules[${j}]`); } + rules2.push({ + suffixIn, + suffixOut, + conditionsIn: conditionFlagsIn, + conditionsOut: conditionFlagsOut + }); + } + transforms2.push({name, rules: rules2}); + } + + this._nextFlagIndex = nextFlagIndex; + for (const transform of transforms2) { + this._transforms.push(transform); + } + + for (const [type, condition] of conditionEntries) { + const flags = conditionFlagsMap.get(type); + if (typeof flags === 'undefined') { continue; } // This case should never happen + this._conditionTypeToConditionFlagsMap.set(type, flags); + for (const partOfSpeech of condition.partsOfSpeech) { + this._partOfSpeechToConditionFlagsMap.set(partOfSpeech, this.getConditionFlagsFromPartOfSpeech(partOfSpeech) | flags); + } + } + } + + /** + * @param {string} partOfSpeech + * @returns {number} + */ + getConditionFlagsFromPartOfSpeech(partOfSpeech) { + const conditionFlags = this._partOfSpeechToConditionFlagsMap.get(partOfSpeech); + return typeof conditionFlags !== 'undefined' ? conditionFlags : 0; + } + + /** + * @param {string[]} partsOfSpeech + * @returns {number} + */ + getConditionFlagsFromPartsOfSpeech(partsOfSpeech) { + let result = 0; + for (const partOfSpeech of partsOfSpeech) { + result |= this.getConditionFlagsFromPartOfSpeech(partOfSpeech); + } + return result; + } + + /** + * @param {string} conditionType + * @returns {number} + */ + getConditionFlagsFromConditionType(conditionType) { + const conditionFlags = this._conditionTypeToConditionFlagsMap.get(conditionType); + return typeof conditionFlags !== 'undefined' ? conditionFlags : 0; + } + + /** + * @param {string[]} conditionTypes + * @returns {number} + */ + getConditionFlagsFromConditionTypes(conditionTypes) { + let result = 0; + for (const conditionType of conditionTypes) { + result |= this.getConditionFlagsFromConditionType(conditionType); + } + return result; + } + + /** + * @param {string} sourceText + * @returns {import('language-transformer-internal').TransformedText[]} + */ + transform(sourceText) { + const results = [this._createTransformedText(sourceText, 0, [])]; + for (let i = 0; i < results.length; ++i) { + const {text, conditions, trace} = results[i]; + for (const {name, rules} of this._transforms) { + for (let j = 0, jj = rules.length; j < jj; ++j) { + const rule = rules[j]; + if (!LanguageTransformer.conditionsMatch(conditions, rule.conditionsIn)) { continue; } + const {suffixIn, suffixOut} = rule; + if (!text.endsWith(suffixIn) || (text.length - suffixIn.length + suffixOut.length) <= 0) { continue; } + results.push(this._createTransformedText( + text.substring(0, text.length - suffixIn.length) + suffixOut, + rule.conditionsOut, + this._extendTrace(trace, {transform: name, ruleIndex: j}) + )); + } + } + } + return results; + } + + /** + * @param {import('language-transformer').ConditionMapEntries} conditions + * @param {number} nextFlagIndex + * @returns {{conditionFlagsMap: Map, nextFlagIndex: number}} + * @throws {Error} + */ + _getConditionFlagsMap(conditions, nextFlagIndex) { + /** @type {Map} */ + const conditionFlagsMap = new Map(); + /** @type {import('language-transformer').ConditionMapEntries} */ + let targets = conditions; + while (targets.length > 0) { + const nextTargets = []; + for (const target of targets) { + const [type, condition] = target; + const {subConditions} = condition; + let flags = 0; + if (typeof subConditions === 'undefined') { + if (nextFlagIndex >= 32) { + // Flags greater than or equal to 32 don't work because JavaScript only supports up to 32-bit integer operations + throw new Error('Maximum number of conditions was exceeded'); + } + flags = 1 << nextFlagIndex; + ++nextFlagIndex; + } else { + const multiFlags = this._getConditionFlags(conditionFlagsMap, subConditions); + if (multiFlags === null) { + nextTargets.push(target); + continue; + } else { + flags = multiFlags; + } + } + conditionFlagsMap.set(type, flags); + } + if (nextTargets.length === targets.length) { + // Cycle in subRule declaration + throw new Error('Maximum number of conditions was exceeded'); + } + targets = nextTargets; + } + return {conditionFlagsMap, nextFlagIndex}; + } + + /** + * @param {Map} conditionFlagsMap + * @param {string[]} conditionTypes + * @returns {?number} + */ + _getConditionFlags(conditionFlagsMap, conditionTypes) { + let flags = 0; + for (const conditionType of conditionTypes) { + const flags2 = conditionFlagsMap.get(conditionType); + if (typeof flags2 === 'undefined') { return null; } + flags |= flags2; + } + return flags; + } + + /** + * @param {string} text + * @param {number} conditions + * @param {import('language-transformer-internal').Trace} trace + * @returns {import('language-transformer-internal').TransformedText} + */ + _createTransformedText(text, conditions, trace) { + return {text, conditions, trace}; + } + + /** + * @param {import('language-transformer-internal').Trace} trace + * @param {import('language-transformer-internal').TraceFrame} newFrame + * @returns {import('language-transformer-internal').Trace} + */ + _extendTrace(trace, newFrame) { + const newTrace = [newFrame]; + for (const {transform, ruleIndex} of trace) { + newTrace.push({transform, ruleIndex}); + } + return newTrace; + } + + /** + * If `currentConditions` is `0`, then `nextConditions` is ignored and `true` is returned. + * Otherwise, there must be at least one shared condition between `currentConditions` and `nextConditions`. + * @param {number} currentConditions + * @param {number} nextConditions + * @returns {boolean} + */ + static conditionsMatch(currentConditions, nextConditions) { + return currentConditions === 0 || (currentConditions & nextConditions) !== 0; + } +} diff --git a/ext/js/language/translator.js b/ext/js/language/translator.js index 66eeb69f..9d2f18e0 100644 --- a/ext/js/language/translator.js +++ b/ext/js/language/translator.js @@ -18,9 +18,9 @@ import {RegexUtil} from '../general/regex-util.js'; import {TextSourceMap} from '../general/text-source-map.js'; -import {Deinflector} from './deinflector.js'; import {convertAlphabeticToKana} from './japanese-wanakana.js'; import {collapseEmphaticSequences, convertHalfWidthKanaToFullWidth, convertHiraganaToKatakana, convertKatakanaToHiragana, convertNumericToFullWidth, isCodePointJapanese} from './japanese.js'; +import {LanguageTransformer} from './language-transformer.js'; /** * Class which finds term and kanji dictionary entries for text. @@ -33,8 +33,8 @@ export class Translator { constructor({database}) { /** @type {import('../dictionary/dictionary-database.js').DictionaryDatabase} */ this._database = database; - /** @type {?Deinflector} */ - this._deinflector = null; + /** @type {LanguageTransformer} */ + this._languageTransformer = new LanguageTransformer(); /** @type {import('translator').DictionaryTagCache} */ this._tagCache = new Map(); /** @type {Intl.Collator} */ @@ -44,12 +44,11 @@ export class Translator { } /** - * Initializes the instance for use. The public API should not be used until - * this function has been called. - * @param {import('deinflector').ReasonsRaw} deinflectionReasons The raw deinflections reasons data that the Deinflector uses. + * Initializes the instance for use. The public API should not be used until this function has been called. + * @param {import('language-transformer').LanguageTransformDescriptor} descriptor */ - prepare(deinflectionReasons) { - this._deinflector = new Deinflector(deinflectionReasons); + prepare(descriptor) { + this._languageTransformer.addDescriptor(descriptor); } /** @@ -407,10 +406,9 @@ export class Translator { const entryDictionary = /** @type {import('translation').FindTermDictionary} */ (enabledDictionaryMap.get(databaseEntry.dictionary)); const {partsOfSpeechFilter} = entryDictionary; - const definitionRules = Deinflector.rulesToRuleFlags(databaseEntry.rules); + const definitionConditions = this._languageTransformer.getConditionFlagsFromPartsOfSpeech(databaseEntry.rules); for (const deinflection of uniqueDeinflectionArrays[databaseEntry.index]) { - const deinflectionRules = deinflection.rules; - if (!partsOfSpeechFilter || Deinflector.rulesMatch(deinflectionRules, definitionRules)) { + if (!partsOfSpeechFilter || LanguageTransformer.conditionsMatch(deinflection.conditions, definitionConditions)) { deinflection.databaseEntries.push(databaseEntry); } } @@ -473,13 +471,13 @@ export class Translator { if (used.has(source)) { break; } used.add(source); const rawSource = sourceMap.source.substring(0, sourceMap.getSourceLength(i)); - for (const {term, rules, reasons} of /** @type {Deinflector} */ (this._deinflector).deinflect(source)) { + for (const {text: transformedText, conditions, trace} of this._languageTransformer.transform(source)) { /** @type {import('dictionary').InflectionRuleChainCandidate} */ const inflectionRuleChainCandidate = { source: 'algorithm', - inflectionRules: reasons + inflectionRules: trace.map((frame) => frame.transform) }; - deinflections.push(this._createDeinflection(rawSource, source, term, rules, [inflectionRuleChainCandidate])); + deinflections.push(this._createDeinflection(rawSource, source, transformedText, conditions, [inflectionRuleChainCandidate])); } } } @@ -570,12 +568,12 @@ export class Translator { * @param {string} originalText * @param {string} transformedText * @param {string} deinflectedText - * @param {import('translation-internal').DeinflectionRuleFlags} rules + * @param {number} conditions * @param {import('dictionary').InflectionRuleChainCandidate[]} inflectionRuleChainCandidates * @returns {import('translation-internal').DatabaseDeinflection} */ - _createDeinflection(originalText, transformedText, deinflectedText, rules, inflectionRuleChainCandidates) { - return {originalText, transformedText, deinflectedText, rules, inflectionRuleChainCandidates, databaseEntries: []}; + _createDeinflection(originalText, transformedText, deinflectedText, conditions, inflectionRuleChainCandidates) { + return {originalText, transformedText, deinflectedText, conditions, inflectionRuleChainCandidates, databaseEntries: []}; } // Term dictionary entry grouping diff --git a/test/data/json.json b/test/data/json.json index 83b1b4e0..fe7df57d 100644 --- a/test/data/json.json +++ b/test/data/json.json @@ -29,11 +29,6 @@ "typeFile": "types/dev/manifest.d.ts", "type": "ManifestConfig" }, - { - "path": "ext/data/deinflect.json", - "typeFile": "types/ext/deinflector.d.ts", - "type": "ReasonsRaw" - }, { "path": "ext/data/pronunciation-style.json", "typeFile": "types/ext/css-style-applier.d.ts", @@ -94,6 +89,11 @@ "typeFile": "types/test/json.d.ts", "type": "AjvSchema" }, + { + "path": "ext/data/language/japanese-transforms.json", + "typeFile": "types/ext/language-transformer.d.ts", + "type": "LanguageTransformDescriptor" + }, { "path": "test/data/translator-test-inputs.json", "typeFile": "types/test/translator.d.ts", diff --git a/test/deinflection-cycles.test.js b/test/deinflection-cycles.test.js deleted file mode 100644 index a010d7a3..00000000 --- a/test/deinflection-cycles.test.js +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2024 Yomitan Authors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import {readFileSync} from 'fs'; -import {join, dirname as pathDirname} from 'path'; -import {fileURLToPath} from 'url'; -import {describe, test} from 'vitest'; -import {parseJson} from '../dev/json.js'; -import {Deinflector} from '../ext/js/language/deinflector.js'; - -class DeinflectionNode { - /** - * @param {string} text - * @param {import('deinflector').ReasonTypeRaw[]} ruleNames - * @param {?RuleNode} ruleNode - * @param {?DeinflectionNode} previous - */ - constructor(text, ruleNames, ruleNode, previous) { - /** @type {string} */ - this.text = text; - /** @type {import('deinflector').ReasonTypeRaw[]} */ - this.ruleNames = ruleNames; - /** @type {?RuleNode} */ - this.ruleNode = ruleNode; - /** @type {?DeinflectionNode} */ - this.previous = previous; - } - - /** - * @param {DeinflectionNode} other - * @returns {boolean} - */ - historyIncludes(other) { - /** @type {?DeinflectionNode} */ - // eslint-disable-next-line @typescript-eslint/no-this-alias - let node = this; - for (; node !== null; node = node.previous) { - if ( - node.ruleNode === other.ruleNode && - node.text === other.text && - arraysAreEqual(node.ruleNames, other.ruleNames) - ) { - return true; - } - } - return false; - } - - /** - * @returns {DeinflectionNode[]} - */ - getHistory() { - /** @type {DeinflectionNode[]} */ - const results = []; - /** @type {?DeinflectionNode} */ - // eslint-disable-next-line @typescript-eslint/no-this-alias - let node = this; - for (; node !== null; node = node.previous) { - results.unshift(node); - } - return results; - } -} - -class RuleNode { - /** - * @param {string} groupName - * @param {import('deinflector').ReasonRaw} rule - */ - constructor(groupName, rule) { - /** @type {string} */ - this.groupName = groupName; - /** @type {import('deinflector').ReasonRaw} */ - this.rule = rule; - } -} - -/** - * @template [T=unknown] - * @param {T[]} rules1 - * @param {T[]} rules2 - * @returns {boolean} - */ -function arraysAreEqual(rules1, rules2) { - if (rules1.length !== rules2.length) { return false; } - for (const rule1 of rules1) { - if (!rules2.includes(rule1)) { return false; } - } - return true; -} - -describe('Deinflection data', () => { - test('Check for cycles', ({expect}) => { - const dirname = pathDirname(fileURLToPath(import.meta.url)); - - /** @type {import('deinflector').ReasonsRaw} */ - const deinflectionReasons = parseJson(readFileSync(join(dirname, '../ext/data/deinflect.json'), {encoding: 'utf8'})); - - /** @type {RuleNode[]} */ - const ruleNodes = []; - for (const [groupName, reasonInfo] of Object.entries(deinflectionReasons)) { - for (const rule of reasonInfo) { - ruleNodes.push(new RuleNode(groupName, rule)); - } - } - - /** @type {DeinflectionNode[]} */ - const deinflectionNodes = []; - for (const ruleNode of ruleNodes) { - deinflectionNodes.push(new DeinflectionNode(`?${ruleNode.rule.kanaIn}`, [], null, null)); - } - for (let i = 0; i < deinflectionNodes.length; ++i) { - const deinflectionNode = deinflectionNodes[i]; - const {text, ruleNames} = deinflectionNode; - for (const ruleNode of ruleNodes) { - const {kanaIn, kanaOut, rulesIn, rulesOut} = ruleNode.rule; - if ( - !Deinflector.rulesMatch(Deinflector.rulesToRuleFlags(ruleNames), Deinflector.rulesToRuleFlags(rulesIn)) || - !text.endsWith(kanaIn) || - (text.length - kanaIn.length + kanaOut.length) <= 0 - ) { - continue; - } - - const newDeinflectionNode = new DeinflectionNode( - text.substring(0, text.length - kanaIn.length) + kanaOut, - rulesOut, - ruleNode, - deinflectionNode - ); - - // Cycle check - if (deinflectionNode.historyIncludes(newDeinflectionNode)) { - const stack = []; - for (const item of newDeinflectionNode.getHistory()) { - stack.push( - item.ruleNode === null ? - `${item.text} (start)` : - `${item.text} (${item.ruleNode.groupName}, ${item.ruleNode.rule.rulesIn.join(',')}=>${item.ruleNode.rule.rulesOut.join(',')}, ${item.ruleNode.rule.kanaIn}=>${item.ruleNode.rule.kanaOut})` - ); - } - const message = `Cycle detected:\n ${stack.join('\n ')}`; - expect.soft(true, message).toEqual(false); - continue; - } - - deinflectionNodes.push(newDeinflectionNode); - } - } - }); -}); \ No newline at end of file diff --git a/test/deinflector.test.js b/test/deinflector.test.js deleted file mode 100644 index 71eb9349..00000000 --- a/test/deinflector.test.js +++ /dev/null @@ -1,1044 +0,0 @@ -/* - * Copyright (C) 2023-2024 Yomitan Authors - * Copyright (C) 2020-2022 Yomichan Authors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import fs from 'fs'; -import {fileURLToPath} from 'node:url'; -import path from 'path'; -import {describe, expect, test} from 'vitest'; -import {parseJson} from '../dev/json.js'; -import {Deinflector} from '../ext/js/language/deinflector.js'; - -const dirname = path.dirname(fileURLToPath(import.meta.url)); - -/** - * @param {Deinflector} deinflector - * @param {string} source - * @param {string} expectedTerm - * @param {string|null} expectedRule - * @param {string[]|null} expectedReasons - * @returns {{has: false, reasons: null, rules: null}|{has: true, reasons: string[], rules: number}} - */ -function hasTermReasons(deinflector, source, expectedTerm, expectedRule, expectedReasons) { - for (const {term, reasons, rules} of deinflector.deinflect(source)) { - if (term !== expectedTerm) { continue; } - if (expectedRule !== null) { - const expectedFlags = Deinflector.rulesToRuleFlags([expectedRule]); - if (!Deinflector.rulesMatch(rules, expectedFlags)) { continue; } - } - let okay = true; - if (expectedReasons !== null) { - if (reasons.length !== expectedReasons.length) { continue; } - for (let i = 0, ii = expectedReasons.length; i < ii; ++i) { - if (expectedReasons[i] !== reasons[i]) { - okay = false; - break; - } - } - } - if (okay) { - return {has: true, reasons, rules}; - } - } - return {has: false, reasons: null, rules: null}; -} - - -/** */ -function testDeinflections() { - /* eslint-disable no-multi-spaces */ - const data = [ - { - category: 'adjectives', - valid: true, - tests: [ - {term: '愛しい', source: '愛しい', rule: 'adj-i', reasons: []}, - {term: '愛しい', source: '愛しそう', rule: 'adj-i', reasons: ['-sou']}, - {term: '愛しい', source: '愛しすぎる', rule: 'adj-i', reasons: ['-sugiru']}, - {term: '愛しい', source: '愛しかったら', rule: 'adj-i', reasons: ['-tara']}, - {term: '愛しい', source: '愛しかったり', rule: 'adj-i', reasons: ['-tari']}, - {term: '愛しい', source: '愛しくて', rule: 'adj-i', reasons: ['-te']}, - {term: '愛しい', source: '愛しく', rule: 'adj-i', reasons: ['adv']}, - {term: '愛しい', source: '愛しくない', rule: 'adj-i', reasons: ['negative']}, - {term: '愛しい', source: '愛しさ', rule: 'adj-i', reasons: ['noun']}, - {term: '愛しい', source: '愛しかった', rule: 'adj-i', reasons: ['past']}, - {term: '愛しい', source: '愛しくありません', rule: 'adj-i', reasons: ['polite negative']}, - {term: '愛しい', source: '愛しくありませんでした', rule: 'adj-i', reasons: ['polite past negative']}, - {term: '愛しい', source: '愛しき', rule: 'adj-i', reasons: ['-ki']}, - {term: '愛しい', source: '愛しげ', rule: 'adj-i', reasons: ['-ge']} - ] - }, - { - category: 'ichidan verbs', - valid: true, - tests: [ - {term: '食べる', source: '食べる', rule: 'v1', reasons: []}, - {term: '食べる', source: '食べます', rule: 'v1', reasons: ['polite']}, - {term: '食べる', source: '食べた', rule: 'v1', reasons: ['past']}, - {term: '食べる', source: '食べました', rule: 'v1', reasons: ['polite past']}, - {term: '食べる', source: '食べて', rule: 'v1', reasons: ['-te']}, - {term: '食べる', source: '食べられる', rule: 'v1', reasons: ['potential or passive']}, - {term: '食べる', source: '食べられる', rule: 'v1', reasons: ['potential or passive']}, - {term: '食べる', source: '食べさせる', rule: 'v1', reasons: ['causative']}, - {term: '食べる', source: '食べさせられる', rule: 'v1', reasons: ['causative', 'potential or passive']}, - {term: '食べる', source: '食べろ', rule: 'v1', reasons: ['imperative']}, - {term: '食べる', source: '食べない', rule: 'v1', reasons: ['negative']}, - {term: '食べる', source: '食べません', rule: 'v1', reasons: ['polite negative']}, - {term: '食べる', source: '食べなかった', rule: 'v1', reasons: ['negative', 'past']}, - {term: '食べる', source: '食べませんでした', rule: 'v1', reasons: ['polite past negative']}, - {term: '食べる', source: '食べなくて', rule: 'v1', reasons: ['negative', '-te']}, - {term: '食べる', source: '食べられない', rule: 'v1', reasons: ['potential or passive', 'negative']}, - {term: '食べる', source: '食べられない', rule: 'v1', reasons: ['potential or passive', 'negative']}, - {term: '食べる', source: '食べさせない', rule: 'v1', reasons: ['causative', 'negative']}, - {term: '食べる', source: '食べさせられない', rule: 'v1', reasons: ['causative', 'potential or passive', 'negative']}, - {term: '食べる', source: '食べるな', rule: 'v1', reasons: ['imperative negative']}, - - {term: '食べる', source: '食べれば', rule: 'v1', reasons: ['-ba']}, - {term: '食べる', source: '食べちゃう', rule: 'v1', reasons: ['-chau']}, - {term: '食べる', source: '食べちまう', rule: 'v1', reasons: ['-chimau']}, - {term: '食べる', source: '食べなさい', rule: 'v1', reasons: ['-nasai']}, - {term: '食べる', source: '食べそう', rule: 'v1', reasons: ['-sou']}, - {term: '食べる', source: '食べすぎる', rule: 'v1', reasons: ['-sugiru']}, - {term: '食べる', source: '食べたい', rule: 'v1', reasons: ['-tai']}, - {term: '食べる', source: '食べたら', rule: 'v1', reasons: ['-tara']}, - {term: '食べる', source: '食べたり', rule: 'v1', reasons: ['-tari']}, - {term: '食べる', source: '食べず', rule: 'v1', reasons: ['-zu']}, - {term: '食べる', source: '食べぬ', rule: 'v1', reasons: ['-nu']}, - {term: '食べる', source: '食べ', rule: 'v1d', reasons: ['masu stem']}, - {term: '食べる', source: '食べましょう', rule: 'v1', reasons: ['polite volitional']}, - {term: '食べる', source: '食べよう', rule: 'v1', reasons: ['volitional']}, - // ['causative passive'] - {term: '食べる', source: '食べとく', rule: 'v1', reasons: ['-toku']}, - {term: '食べる', source: '食べている', rule: 'v1', reasons: ['-te', 'progressive or perfect']}, - {term: '食べる', source: '食べておる', rule: 'v1', reasons: ['-te', 'progressive or perfect']}, - {term: '食べる', source: '食べてる', rule: 'v1', reasons: ['-te', 'progressive or perfect']}, - {term: '食べる', source: '食べとる', rule: 'v1', reasons: ['-te', 'progressive or perfect']}, - {term: '食べる', source: '食べてしまう', rule: 'v1', reasons: ['-te', '-shimau']} - ] - }, - { - category: '-u verbs', - valid: true, - tests: [ - {term: '買う', source: '買う', rule: 'v5', reasons: []}, - {term: '買う', source: '買います', rule: 'v5', reasons: ['polite']}, - {term: '買う', source: '買った', rule: 'v5', reasons: ['past']}, - {term: '買う', source: '買いました', rule: 'v5', reasons: ['polite past']}, - {term: '買う', source: '買って', rule: 'v5', reasons: ['-te']}, - {term: '買う', source: '買える', rule: 'v5', reasons: ['potential']}, - {term: '買う', source: '買われる', rule: 'v5', reasons: ['passive']}, - {term: '買う', source: '買わせる', rule: 'v5', reasons: ['causative']}, - {term: '買う', source: '買わせられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, - {term: '買う', source: '買え', rule: 'v5', reasons: ['imperative']}, - {term: '買う', source: '買わない', rule: 'v5', reasons: ['negative']}, - {term: '買う', source: '買いません', rule: 'v5', reasons: ['polite negative']}, - {term: '買う', source: '買わなかった', rule: 'v5', reasons: ['negative', 'past']}, - {term: '買う', source: '買いませんでした', rule: 'v5', reasons: ['polite past negative']}, - {term: '買う', source: '買わなくて', rule: 'v5', reasons: ['negative', '-te']}, - {term: '買う', source: '買えない', rule: 'v5', reasons: ['potential', 'negative']}, - {term: '買う', source: '買われない', rule: 'v5', reasons: ['passive', 'negative']}, - {term: '買う', source: '買わせない', rule: 'v5', reasons: ['causative', 'negative']}, - {term: '買う', source: '買わせられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, - {term: '買う', source: '買うな', rule: 'v5', reasons: ['imperative negative']}, - - {term: '買う', source: '買えば', rule: 'v5', reasons: ['-ba']}, - {term: '買う', source: '買っちゃう', rule: 'v5', reasons: ['-chau']}, - {term: '買う', source: '買っちまう', rule: 'v5', reasons: ['-chimau']}, - {term: '買う', source: '買いなさい', rule: 'v5', reasons: ['-nasai']}, - {term: '買う', source: '買いそう', rule: 'v5', reasons: ['-sou']}, - {term: '買う', source: '買いすぎる', rule: 'v5', reasons: ['-sugiru']}, - {term: '買う', source: '買いたい', rule: 'v5', reasons: ['-tai']}, - {term: '買う', source: '買ったら', rule: 'v5', reasons: ['-tara']}, - {term: '買う', source: '買ったり', rule: 'v5', reasons: ['-tari']}, - {term: '買う', source: '買わず', rule: 'v5', reasons: ['-zu']}, - {term: '買う', source: '買わぬ', rule: 'v5', reasons: ['-nu']}, - {term: '買う', source: '買い', rule: 'v5', reasons: ['masu stem']}, - {term: '買う', source: '買いましょう', rule: 'v5', reasons: ['polite volitional']}, - {term: '買う', source: '買おう', rule: 'v5', reasons: ['volitional']}, - {term: '買う', source: '買わされる', rule: 'v5', reasons: ['causative passive']}, - {term: '買う', source: '買っとく', rule: 'v5', reasons: ['-toku']}, - {term: '買う', source: '買っている', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '買う', source: '買っておる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '買う', source: '買ってる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '買う', source: '買っとる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '買う', source: '買ってしまう', rule: 'v5', reasons: ['-te', '-shimau']} - ] - }, - { - category: '-ku verbs', - valid: true, - tests: [ - {term: '行く', source: '行く', rule: 'v5', reasons: []}, - {term: '行く', source: '行きます', rule: 'v5', reasons: ['polite']}, - {term: '行く', source: '行った', rule: 'v5', reasons: ['past']}, - {term: '行く', source: '行きました', rule: 'v5', reasons: ['polite past']}, - {term: '行く', source: '行って', rule: 'v5', reasons: ['-te']}, - {term: '行く', source: '行ける', rule: 'v5', reasons: ['potential']}, - {term: '行く', source: '行かれる', rule: 'v5', reasons: ['passive']}, - {term: '行く', source: '行かせる', rule: 'v5', reasons: ['causative']}, - {term: '行く', source: '行かせられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, - {term: '行く', source: '行け', rule: 'v5', reasons: ['imperative']}, - {term: '行く', source: '行かない', rule: 'v5', reasons: ['negative']}, - {term: '行く', source: '行きません', rule: 'v5', reasons: ['polite negative']}, - {term: '行く', source: '行かなかった', rule: 'v5', reasons: ['negative', 'past']}, - {term: '行く', source: '行きませんでした', rule: 'v5', reasons: ['polite past negative']}, - {term: '行く', source: '行かなくて', rule: 'v5', reasons: ['negative', '-te']}, - {term: '行く', source: '行けない', rule: 'v5', reasons: ['potential', 'negative']}, - {term: '行く', source: '行かれない', rule: 'v5', reasons: ['passive', 'negative']}, - {term: '行く', source: '行かせない', rule: 'v5', reasons: ['causative', 'negative']}, - {term: '行く', source: '行かせられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, - {term: '行く', source: '行くな', rule: 'v5', reasons: ['imperative negative']}, - - {term: '行く', source: '行けば', rule: 'v5', reasons: ['-ba']}, - {term: '行く', source: '行っちゃう', rule: 'v5', reasons: ['-chau']}, - {term: '行く', source: '行っちまう', rule: 'v5', reasons: ['-chimau']}, - {term: '行く', source: '行きなさい', rule: 'v5', reasons: ['-nasai']}, - {term: '行く', source: '行きそう', rule: 'v5', reasons: ['-sou']}, - {term: '行く', source: '行きすぎる', rule: 'v5', reasons: ['-sugiru']}, - {term: '行く', source: '行きたい', rule: 'v5', reasons: ['-tai']}, - {term: '行く', source: '行いたら', rule: 'v5', reasons: ['-tara']}, - {term: '行く', source: '行いたり', rule: 'v5', reasons: ['-tari']}, - {term: '行く', source: '行かず', rule: 'v5', reasons: ['-zu']}, - {term: '行く', source: '行かぬ', rule: 'v5', reasons: ['-nu']}, - {term: '行く', source: '行き', rule: 'v5', reasons: ['masu stem']}, - {term: '行く', source: '行きましょう', rule: 'v5', reasons: ['polite volitional']}, - {term: '行く', source: '行こう', rule: 'v5', reasons: ['volitional']}, - {term: '行く', source: '行かされる', rule: 'v5', reasons: ['causative passive']}, - {term: '行く', source: '行いとく', rule: 'v5', reasons: ['-toku']}, - {term: '行く', source: '行っている', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '行く', source: '行っておる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '行く', source: '行ってる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '行く', source: '行っとる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '行く', source: '行ってしまう', rule: 'v5', reasons: ['-te', '-shimau']} - ] - }, - { - category: '-gu verbs', - valid: true, - tests: [ - {term: '泳ぐ', source: '泳ぐ', rule: 'v5', reasons: []}, - {term: '泳ぐ', source: '泳ぎます', rule: 'v5', reasons: ['polite']}, - {term: '泳ぐ', source: '泳いだ', rule: 'v5', reasons: ['past']}, - {term: '泳ぐ', source: '泳ぎました', rule: 'v5', reasons: ['polite past']}, - {term: '泳ぐ', source: '泳いで', rule: 'v5', reasons: ['-te']}, - {term: '泳ぐ', source: '泳げる', rule: 'v5', reasons: ['potential']}, - {term: '泳ぐ', source: '泳がれる', rule: 'v5', reasons: ['passive']}, - {term: '泳ぐ', source: '泳がせる', rule: 'v5', reasons: ['causative']}, - {term: '泳ぐ', source: '泳がせられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, - {term: '泳ぐ', source: '泳げ', rule: 'v5', reasons: ['imperative']}, - {term: '泳ぐ', source: '泳がない', rule: 'v5', reasons: ['negative']}, - {term: '泳ぐ', source: '泳ぎません', rule: 'v5', reasons: ['polite negative']}, - {term: '泳ぐ', source: '泳がなかった', rule: 'v5', reasons: ['negative', 'past']}, - {term: '泳ぐ', source: '泳ぎませんでした', rule: 'v5', reasons: ['polite past negative']}, - {term: '泳ぐ', source: '泳がなくて', rule: 'v5', reasons: ['negative', '-te']}, - {term: '泳ぐ', source: '泳げない', rule: 'v5', reasons: ['potential', 'negative']}, - {term: '泳ぐ', source: '泳がれない', rule: 'v5', reasons: ['passive', 'negative']}, - {term: '泳ぐ', source: '泳がせない', rule: 'v5', reasons: ['causative', 'negative']}, - {term: '泳ぐ', source: '泳がせられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, - {term: '泳ぐ', source: '泳ぐな', rule: 'v5', reasons: ['imperative negative']}, - - {term: '泳ぐ', source: '泳げば', rule: 'v5', reasons: ['-ba']}, - {term: '泳ぐ', source: '泳いじゃう', rule: 'v5', reasons: ['-chau']}, - {term: '泳ぐ', source: '泳いじまう', rule: 'v5', reasons: ['-chimau']}, - {term: '泳ぐ', source: '泳ぎなさい', rule: 'v5', reasons: ['-nasai']}, - {term: '泳ぐ', source: '泳ぎそう', rule: 'v5', reasons: ['-sou']}, - {term: '泳ぐ', source: '泳ぎすぎる', rule: 'v5', reasons: ['-sugiru']}, - {term: '泳ぐ', source: '泳ぎたい', rule: 'v5', reasons: ['-tai']}, - {term: '泳ぐ', source: '泳いだら', rule: 'v5', reasons: ['-tara']}, - {term: '泳ぐ', source: '泳いだり', rule: 'v5', reasons: ['-tari']}, - {term: '泳ぐ', source: '泳がず', rule: 'v5', reasons: ['-zu']}, - {term: '泳ぐ', source: '泳がぬ', rule: 'v5', reasons: ['-nu']}, - {term: '泳ぐ', source: '泳ぎ', rule: 'v5', reasons: ['masu stem']}, - {term: '泳ぐ', source: '泳ぎましょう', rule: 'v5', reasons: ['polite volitional']}, - {term: '泳ぐ', source: '泳ごう', rule: 'v5', reasons: ['volitional']}, - {term: '泳ぐ', source: '泳がされる', rule: 'v5', reasons: ['causative passive']}, - {term: '泳ぐ', source: '泳いどく', rule: 'v5', reasons: ['-toku']}, - {term: '泳ぐ', source: '泳いでいる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '泳ぐ', source: '泳いでおる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '泳ぐ', source: '泳いでる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '泳ぐ', source: '泳いでしまう', rule: 'v5', reasons: ['-te', '-shimau']} - ] - }, - { - category: '-su verbs', - valid: true, - tests: [ - {term: '話す', source: '話す', rule: 'v5', reasons: []}, - {term: '話す', source: '話します', rule: 'v5', reasons: ['polite']}, - {term: '話す', source: '話した', rule: 'v5', reasons: ['past']}, - {term: '話す', source: '話しました', rule: 'v5', reasons: ['polite past']}, - {term: '話す', source: '話して', rule: 'v5', reasons: ['-te']}, - {term: '話す', source: '話せる', rule: 'v5', reasons: ['potential']}, - {term: '話す', source: '話される', rule: 'v5', reasons: ['passive']}, - {term: '話す', source: '話させる', rule: 'v5', reasons: ['causative']}, - {term: '話す', source: '話させられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, - {term: '話す', source: '話せ', rule: 'v5', reasons: ['imperative']}, - {term: '話す', source: '話さない', rule: 'v5', reasons: ['negative']}, - {term: '話す', source: '話しません', rule: 'v5', reasons: ['polite negative']}, - {term: '話す', source: '話さなかった', rule: 'v5', reasons: ['negative', 'past']}, - {term: '話す', source: '話しませんでした', rule: 'v5', reasons: ['polite past negative']}, - {term: '話す', source: '話さなくて', rule: 'v5', reasons: ['negative', '-te']}, - {term: '話す', source: '話せない', rule: 'v5', reasons: ['potential', 'negative']}, - {term: '話す', source: '話されない', rule: 'v5', reasons: ['passive', 'negative']}, - {term: '話す', source: '話させない', rule: 'v5', reasons: ['causative', 'negative']}, - {term: '話す', source: '話させられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, - {term: '話す', source: '話すな', rule: 'v5', reasons: ['imperative negative']}, - - {term: '話す', source: '話せば', rule: 'v5', reasons: ['-ba']}, - {term: '話す', source: '話しちゃう', rule: 'v5', reasons: ['-chau']}, - {term: '話す', source: '話しちまう', rule: 'v5', reasons: ['-chimau']}, - {term: '話す', source: '話しなさい', rule: 'v5', reasons: ['-nasai']}, - {term: '話す', source: '話しそう', rule: 'v5', reasons: ['-sou']}, - {term: '話す', source: '話しすぎる', rule: 'v5', reasons: ['-sugiru']}, - {term: '話す', source: '話したい', rule: 'v5', reasons: ['-tai']}, - {term: '話す', source: '話したら', rule: 'v5', reasons: ['-tara']}, - {term: '話す', source: '話したり', rule: 'v5', reasons: ['-tari']}, - {term: '話す', source: '話さず', rule: 'v5', reasons: ['-zu']}, - {term: '話す', source: '話さぬ', rule: 'v5', reasons: ['-nu']}, - {term: '話す', source: '話し', rule: 'v5', reasons: ['masu stem']}, - {term: '話す', source: '話しましょう', rule: 'v5', reasons: ['polite volitional']}, - {term: '話す', source: '話そう', rule: 'v5', reasons: ['volitional']}, - // ['causative passive'] - {term: '話す', source: '話しとく', rule: 'v5', reasons: ['-toku']}, - {term: '話す', source: '話している', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '話す', source: '話しておる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '話す', source: '話してる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '話す', source: '話しとる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '話す', source: '話してしまう', rule: 'v5', reasons: ['-te', '-shimau']} - ] - }, - { - category: '-tsu verbs', - valid: true, - tests: [ - {term: '待つ', source: '待つ', rule: 'v5', reasons: []}, - {term: '待つ', source: '待ちます', rule: 'v5', reasons: ['polite']}, - {term: '待つ', source: '待った', rule: 'v5', reasons: ['past']}, - {term: '待つ', source: '待ちました', rule: 'v5', reasons: ['polite past']}, - {term: '待つ', source: '待って', rule: 'v5', reasons: ['-te']}, - {term: '待つ', source: '待てる', rule: 'v5', reasons: ['potential']}, - {term: '待つ', source: '待たれる', rule: 'v5', reasons: ['passive']}, - {term: '待つ', source: '待たせる', rule: 'v5', reasons: ['causative']}, - {term: '待つ', source: '待たせられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, - {term: '待つ', source: '待て', rule: 'v5', reasons: ['imperative']}, - {term: '待つ', source: '待たない', rule: 'v5', reasons: ['negative']}, - {term: '待つ', source: '待ちません', rule: 'v5', reasons: ['polite negative']}, - {term: '待つ', source: '待たなかった', rule: 'v5', reasons: ['negative', 'past']}, - {term: '待つ', source: '待ちませんでした', rule: 'v5', reasons: ['polite past negative']}, - {term: '待つ', source: '待たなくて', rule: 'v5', reasons: ['negative', '-te']}, - {term: '待つ', source: '待てない', rule: 'v5', reasons: ['potential', 'negative']}, - {term: '待つ', source: '待たれない', rule: 'v5', reasons: ['passive', 'negative']}, - {term: '待つ', source: '待たせない', rule: 'v5', reasons: ['causative', 'negative']}, - {term: '待つ', source: '待たせられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, - {term: '待つ', source: '待つな', rule: 'v5', reasons: ['imperative negative']}, - - {term: '待つ', source: '待てば', rule: 'v5', reasons: ['-ba']}, - {term: '待つ', source: '待っちゃう', rule: 'v5', reasons: ['-chau']}, - {term: '待つ', source: '待っちまう', rule: 'v5', reasons: ['-chimau']}, - {term: '待つ', source: '待ちなさい', rule: 'v5', reasons: ['-nasai']}, - {term: '待つ', source: '待ちそう', rule: 'v5', reasons: ['-sou']}, - {term: '待つ', source: '待ちすぎる', rule: 'v5', reasons: ['-sugiru']}, - {term: '待つ', source: '待ちたい', rule: 'v5', reasons: ['-tai']}, - {term: '待つ', source: '待ったら', rule: 'v5', reasons: ['-tara']}, - {term: '待つ', source: '待ったり', rule: 'v5', reasons: ['-tari']}, - {term: '待つ', source: '待たず', rule: 'v5', reasons: ['-zu']}, - {term: '待つ', source: '待たぬ', rule: 'v5', reasons: ['-nu']}, - {term: '待つ', source: '待ち', rule: 'v5', reasons: ['masu stem']}, - {term: '待つ', source: '待ちましょう', rule: 'v5', reasons: ['polite volitional']}, - {term: '待つ', source: '待とう', rule: 'v5', reasons: ['volitional']}, - {term: '待つ', source: '待たされる', rule: 'v5', reasons: ['causative passive']}, - {term: '待つ', source: '待っとく', rule: 'v5', reasons: ['-toku']}, - {term: '待つ', source: '待っている', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '待つ', source: '待っておる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '待つ', source: '待ってる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '待つ', source: '待っとる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '待つ', source: '待ってしまう', rule: 'v5', reasons: ['-te', '-shimau']} - ] - }, - { - category: '-nu verbs', - valid: true, - tests: [ - {term: '死ぬ', source: '死ぬ', rule: 'v5', reasons: []}, - {term: '死ぬ', source: '死にます', rule: 'v5', reasons: ['polite']}, - {term: '死ぬ', source: '死んだ', rule: 'v5', reasons: ['past']}, - {term: '死ぬ', source: '死にました', rule: 'v5', reasons: ['polite past']}, - {term: '死ぬ', source: '死んで', rule: 'v5', reasons: ['-te']}, - {term: '死ぬ', source: '死ねる', rule: 'v5', reasons: ['potential']}, - {term: '死ぬ', source: '死なれる', rule: 'v5', reasons: ['passive']}, - {term: '死ぬ', source: '死なせる', rule: 'v5', reasons: ['causative']}, - {term: '死ぬ', source: '死なせられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, - {term: '死ぬ', source: '死ね', rule: 'v5', reasons: ['imperative']}, - {term: '死ぬ', source: '死なない', rule: 'v5', reasons: ['negative']}, - {term: '死ぬ', source: '死にません', rule: 'v5', reasons: ['polite negative']}, - {term: '死ぬ', source: '死ななかった', rule: 'v5', reasons: ['negative', 'past']}, - {term: '死ぬ', source: '死にませんでした', rule: 'v5', reasons: ['polite past negative']}, - {term: '死ぬ', source: '死ななくて', rule: 'v5', reasons: ['negative', '-te']}, - {term: '死ぬ', source: '死ねない', rule: 'v5', reasons: ['potential', 'negative']}, - {term: '死ぬ', source: '死なれない', rule: 'v5', reasons: ['passive', 'negative']}, - {term: '死ぬ', source: '死なせない', rule: 'v5', reasons: ['causative', 'negative']}, - {term: '死ぬ', source: '死なせられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, - {term: '死ぬ', source: '死ぬな', rule: 'v5', reasons: ['imperative negative']}, - - {term: '死ぬ', source: '死ねば', rule: 'v5', reasons: ['-ba']}, - {term: '死ぬ', source: '死んじゃう', rule: 'v5', reasons: ['-chau']}, - {term: '死ぬ', source: '死んじまう', rule: 'v5', reasons: ['-chimau']}, - {term: '死ぬ', source: '死になさい', rule: 'v5', reasons: ['-nasai']}, - {term: '死ぬ', source: '死にそう', rule: 'v5', reasons: ['-sou']}, - {term: '死ぬ', source: '死にすぎる', rule: 'v5', reasons: ['-sugiru']}, - {term: '死ぬ', source: '死にたい', rule: 'v5', reasons: ['-tai']}, - {term: '死ぬ', source: '死んだら', rule: 'v5', reasons: ['-tara']}, - {term: '死ぬ', source: '死んだり', rule: 'v5', reasons: ['-tari']}, - {term: '死ぬ', source: '死なず', rule: 'v5', reasons: ['-zu']}, - {term: '死ぬ', source: '死なぬ', rule: 'v5', reasons: ['-nu']}, - {term: '死ぬ', source: '死に', rule: 'v5', reasons: ['masu stem']}, - {term: '死ぬ', source: '死にましょう', rule: 'v5', reasons: ['polite volitional']}, - {term: '死ぬ', source: '死のう', rule: 'v5', reasons: ['volitional']}, - {term: '死ぬ', source: '死なされる', rule: 'v5', reasons: ['causative passive']}, - {term: '死ぬ', source: '死んどく', rule: 'v5', reasons: ['-toku']}, - {term: '死ぬ', source: '死んでいる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '死ぬ', source: '死んでおる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '死ぬ', source: '死んでる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '死ぬ', source: '死んでしまう', rule: 'v5', reasons: ['-te', '-shimau']} - ] - }, - { - category: '-bu verbs', - valid: true, - tests: [ - {term: '遊ぶ', source: '遊ぶ', rule: 'v5', reasons: []}, - {term: '遊ぶ', source: '遊びます', rule: 'v5', reasons: ['polite']}, - {term: '遊ぶ', source: '遊んだ', rule: 'v5', reasons: ['past']}, - {term: '遊ぶ', source: '遊びました', rule: 'v5', reasons: ['polite past']}, - {term: '遊ぶ', source: '遊んで', rule: 'v5', reasons: ['-te']}, - {term: '遊ぶ', source: '遊べる', rule: 'v5', reasons: ['potential']}, - {term: '遊ぶ', source: '遊ばれる', rule: 'v5', reasons: ['passive']}, - {term: '遊ぶ', source: '遊ばせる', rule: 'v5', reasons: ['causative']}, - {term: '遊ぶ', source: '遊ばせられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, - {term: '遊ぶ', source: '遊べ', rule: 'v5', reasons: ['imperative']}, - {term: '遊ぶ', source: '遊ばない', rule: 'v5', reasons: ['negative']}, - {term: '遊ぶ', source: '遊びません', rule: 'v5', reasons: ['polite negative']}, - {term: '遊ぶ', source: '遊ばなかった', rule: 'v5', reasons: ['negative', 'past']}, - {term: '遊ぶ', source: '遊びませんでした', rule: 'v5', reasons: ['polite past negative']}, - {term: '遊ぶ', source: '遊ばなくて', rule: 'v5', reasons: ['negative', '-te']}, - {term: '遊ぶ', source: '遊べない', rule: 'v5', reasons: ['potential', 'negative']}, - {term: '遊ぶ', source: '遊ばれない', rule: 'v5', reasons: ['passive', 'negative']}, - {term: '遊ぶ', source: '遊ばせない', rule: 'v5', reasons: ['causative', 'negative']}, - {term: '遊ぶ', source: '遊ばせられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, - {term: '遊ぶ', source: '遊ぶな', rule: 'v5', reasons: ['imperative negative']}, - - {term: '遊ぶ', source: '遊べば', rule: 'v5', reasons: ['-ba']}, - {term: '遊ぶ', source: '遊んじゃう', rule: 'v5', reasons: ['-chau']}, - {term: '遊ぶ', source: '遊んじまう', rule: 'v5', reasons: ['-chimau']}, - {term: '遊ぶ', source: '遊びなさい', rule: 'v5', reasons: ['-nasai']}, - {term: '遊ぶ', source: '遊びそう', rule: 'v5', reasons: ['-sou']}, - {term: '遊ぶ', source: '遊びすぎる', rule: 'v5', reasons: ['-sugiru']}, - {term: '遊ぶ', source: '遊びたい', rule: 'v5', reasons: ['-tai']}, - {term: '遊ぶ', source: '遊んだら', rule: 'v5', reasons: ['-tara']}, - {term: '遊ぶ', source: '遊んだり', rule: 'v5', reasons: ['-tari']}, - {term: '遊ぶ', source: '遊ばず', rule: 'v5', reasons: ['-zu']}, - {term: '遊ぶ', source: '遊ばぬ', rule: 'v5', reasons: ['-nu']}, - {term: '遊ぶ', source: '遊び', rule: 'v5', reasons: ['masu stem']}, - {term: '遊ぶ', source: '遊びましょう', rule: 'v5', reasons: ['polite volitional']}, - {term: '遊ぶ', source: '遊ぼう', rule: 'v5', reasons: ['volitional']}, - {term: '遊ぶ', source: '遊ばされる', rule: 'v5', reasons: ['causative passive']}, - {term: '遊ぶ', source: '遊んどく', rule: 'v5', reasons: ['-toku']}, - {term: '遊ぶ', source: '遊んでいる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '遊ぶ', source: '遊んでおる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '遊ぶ', source: '遊んでる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '遊ぶ', source: '遊んでしまう', rule: 'v5', reasons: ['-te', '-shimau']} - ] - }, - { - category: '-mu verbs', - valid: true, - tests: [ - {term: '飲む', source: '飲む', rule: 'v5', reasons: []}, - {term: '飲む', source: '飲みます', rule: 'v5', reasons: ['polite']}, - {term: '飲む', source: '飲んだ', rule: 'v5', reasons: ['past']}, - {term: '飲む', source: '飲みました', rule: 'v5', reasons: ['polite past']}, - {term: '飲む', source: '飲んで', rule: 'v5', reasons: ['-te']}, - {term: '飲む', source: '飲める', rule: 'v5', reasons: ['potential']}, - {term: '飲む', source: '飲まれる', rule: 'v5', reasons: ['passive']}, - {term: '飲む', source: '飲ませる', rule: 'v5', reasons: ['causative']}, - {term: '飲む', source: '飲ませられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, - {term: '飲む', source: '飲め', rule: 'v5', reasons: ['imperative']}, - {term: '飲む', source: '飲まない', rule: 'v5', reasons: ['negative']}, - {term: '飲む', source: '飲みません', rule: 'v5', reasons: ['polite negative']}, - {term: '飲む', source: '飲まなかった', rule: 'v5', reasons: ['negative', 'past']}, - {term: '飲む', source: '飲みませんでした', rule: 'v5', reasons: ['polite past negative']}, - {term: '飲む', source: '飲まなくて', rule: 'v5', reasons: ['negative', '-te']}, - {term: '飲む', source: '飲めない', rule: 'v5', reasons: ['potential', 'negative']}, - {term: '飲む', source: '飲まれない', rule: 'v5', reasons: ['passive', 'negative']}, - {term: '飲む', source: '飲ませない', rule: 'v5', reasons: ['causative', 'negative']}, - {term: '飲む', source: '飲ませられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, - {term: '飲む', source: '飲むな', rule: 'v5', reasons: ['imperative negative']}, - - {term: '飲む', source: '飲めば', rule: 'v5', reasons: ['-ba']}, - {term: '飲む', source: '飲んじゃう', rule: 'v5', reasons: ['-chau']}, - {term: '飲む', source: '飲んじまう', rule: 'v5', reasons: ['-chimau']}, - {term: '飲む', source: '飲みなさい', rule: 'v5', reasons: ['-nasai']}, - {term: '飲む', source: '飲みそう', rule: 'v5', reasons: ['-sou']}, - {term: '飲む', source: '飲みすぎる', rule: 'v5', reasons: ['-sugiru']}, - {term: '飲む', source: '飲みたい', rule: 'v5', reasons: ['-tai']}, - {term: '飲む', source: '飲んだら', rule: 'v5', reasons: ['-tara']}, - {term: '飲む', source: '飲んだり', rule: 'v5', reasons: ['-tari']}, - {term: '飲む', source: '飲まず', rule: 'v5', reasons: ['-zu']}, - {term: '飲む', source: '飲まぬ', rule: 'v5', reasons: ['-nu']}, - {term: '飲む', source: '飲み', rule: 'v5', reasons: ['masu stem']}, - {term: '飲む', source: '飲みましょう', rule: 'v5', reasons: ['polite volitional']}, - {term: '飲む', source: '飲もう', rule: 'v5', reasons: ['volitional']}, - {term: '飲む', source: '飲まされる', rule: 'v5', reasons: ['causative passive']}, - {term: '飲む', source: '飲んどく', rule: 'v5', reasons: ['-toku']}, - {term: '飲む', source: '飲んでいる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '飲む', source: '飲んでおる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '飲む', source: '飲んでる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '飲む', source: '飲んでしまう', rule: 'v5', reasons: ['-te', '-shimau']} - ] - }, - { - category: 'godan verbs', - valid: true, - tests: [ - {term: '作る', source: '作る', rule: 'v5', reasons: []}, - {term: '作る', source: '作ります', rule: 'v5', reasons: ['polite']}, - {term: '作る', source: '作った', rule: 'v5', reasons: ['past']}, - {term: '作る', source: '作りました', rule: 'v5', reasons: ['polite past']}, - {term: '作る', source: '作って', rule: 'v5', reasons: ['-te']}, - {term: '作る', source: '作れる', rule: 'v5', reasons: ['potential']}, - {term: '作る', source: '作られる', rule: 'v5', reasons: ['passive']}, - {term: '作る', source: '作らせる', rule: 'v5', reasons: ['causative']}, - {term: '作る', source: '作らせられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, - {term: '作る', source: '作れ', rule: 'v5', reasons: ['imperative']}, - {term: '作る', source: '作らない', rule: 'v5', reasons: ['negative']}, - {term: '作る', source: '作りません', rule: 'v5', reasons: ['polite negative']}, - {term: '作る', source: '作らなかった', rule: 'v5', reasons: ['negative', 'past']}, - {term: '作る', source: '作りませんでした', rule: 'v5', reasons: ['polite past negative']}, - {term: '作る', source: '作らなくて', rule: 'v5', reasons: ['negative', '-te']}, - {term: '作る', source: '作れない', rule: 'v5', reasons: ['potential', 'negative']}, - {term: '作る', source: '作られない', rule: 'v5', reasons: ['passive', 'negative']}, - {term: '作る', source: '作らせない', rule: 'v5', reasons: ['causative', 'negative']}, - {term: '作る', source: '作らせられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, - {term: '作る', source: '作るな', rule: 'v5', reasons: ['imperative negative']}, - - {term: '作る', source: '作れば', rule: 'v5', reasons: ['-ba']}, - {term: '作る', source: '作っちゃう', rule: 'v5', reasons: ['-chau']}, - {term: '作る', source: '作っちまう', rule: 'v5', reasons: ['-chimau']}, - {term: '作る', source: '作りなさい', rule: 'v5', reasons: ['-nasai']}, - {term: '作る', source: '作りそう', rule: 'v5', reasons: ['-sou']}, - {term: '作る', source: '作りすぎる', rule: 'v5', reasons: ['-sugiru']}, - {term: '作る', source: '作りたい', rule: 'v5', reasons: ['-tai']}, - {term: '作る', source: '作ったら', rule: 'v5', reasons: ['-tara']}, - {term: '作る', source: '作ったり', rule: 'v5', reasons: ['-tari']}, - {term: '作る', source: '作らず', rule: 'v5', reasons: ['-zu']}, - {term: '作る', source: '作らぬ', rule: 'v5', reasons: ['-nu']}, - {term: '作る', source: '作り', rule: 'v5', reasons: ['masu stem']}, - {term: '作る', source: '作りましょう', rule: 'v5', reasons: ['polite volitional']}, - {term: '作る', source: '作ろう', rule: 'v5', reasons: ['volitional']}, - {term: '作る', source: '作らされる', rule: 'v5', reasons: ['causative passive']}, - {term: '作る', source: '作っとく', rule: 'v5', reasons: ['-toku']}, - {term: '作る', source: '作っている', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '作る', source: '作っておる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '作る', source: '作ってる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '作る', source: '作っとる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, - {term: '作る', source: '作ってしまう', rule: 'v5', reasons: ['-te', '-shimau']} - ] - }, - { - category: 'irregular verbs', - valid: true, - tests: [ - {term: '為る', source: '為る', rule: 'vs', reasons: []}, - {term: '為る', source: '為ます', rule: 'vs', reasons: ['polite']}, - {term: '為る', source: '為た', rule: 'vs', reasons: ['past']}, - {term: '為る', source: '為ました', rule: 'vs', reasons: ['polite past']}, - {term: '為る', source: '為て', rule: 'vs', reasons: ['-te']}, - {term: '為る', source: '為られる', rule: 'vs', reasons: ['potential or passive']}, - {term: '為る', source: '為れる', rule: 'vs', reasons: ['passive']}, - {term: '為る', source: '為せる', rule: 'vs', reasons: ['causative']}, - {term: '為る', source: '為させる', rule: 'vs', reasons: ['causative']}, - {term: '為る', source: '為せられる', rule: 'vs', reasons: ['causative', 'potential or passive']}, - {term: '為る', source: '為させられる', rule: 'vs', reasons: ['causative', 'potential or passive']}, - {term: '為る', source: '為ろ', rule: 'vs', reasons: ['imperative']}, - {term: '為る', source: '為ない', rule: 'vs', reasons: ['negative']}, - {term: '為る', source: '為ません', rule: 'vs', reasons: ['polite negative']}, - {term: '為る', source: '為なかった', rule: 'vs', reasons: ['negative', 'past']}, - {term: '為る', source: '為ませんでした', rule: 'vs', reasons: ['polite past negative']}, - {term: '為る', source: '為なくて', rule: 'vs', reasons: ['negative', '-te']}, - {term: '為る', source: '為られない', rule: 'vs', reasons: ['potential or passive', 'negative']}, - {term: '為る', source: '為れない', rule: 'vs', reasons: ['passive', 'negative']}, - {term: '為る', source: '為せない', rule: 'vs', reasons: ['causative', 'negative']}, - {term: '為る', source: '為させない', rule: 'vs', reasons: ['causative', 'negative']}, - {term: '為る', source: '為せられない', rule: 'vs', reasons: ['causative', 'potential or passive', 'negative']}, - {term: '為る', source: '為させられない', rule: 'vs', reasons: ['causative', 'potential or passive', 'negative']}, - {term: '為る', source: '為るな', rule: 'vs', reasons: ['imperative negative']}, - - {term: '為る', source: '為れば', rule: 'vs', reasons: ['-ba']}, - {term: '為る', source: '為ちゃう', rule: 'vs', reasons: ['-chau']}, - {term: '為る', source: '為ちまう', rule: 'vs', reasons: ['-chimau']}, - {term: '為る', source: '為なさい', rule: 'vs', reasons: ['-nasai']}, - {term: '為る', source: '為そう', rule: 'vs', reasons: ['-sou']}, - {term: '為る', source: '為すぎる', rule: 'vs', reasons: ['-sugiru']}, - {term: '為る', source: '為たい', rule: 'vs', reasons: ['-tai']}, - {term: '為る', source: '為たら', rule: 'vs', reasons: ['-tara']}, - {term: '為る', source: '為たり', rule: 'vs', reasons: ['-tari']}, - {term: '為る', source: '為ず', rule: 'vs', reasons: ['-zu']}, - {term: '為る', source: '為ぬ', rule: 'vs', reasons: ['-nu']}, - // ['masu stem'] - {term: '為る', source: '為ましょう', rule: 'vs', reasons: ['polite volitional']}, - {term: '為る', source: '為よう', rule: 'vs', reasons: ['volitional']}, - // ['causative passive'] - {term: '為る', source: '為とく', rule: 'vs', reasons: ['-toku']}, - {term: '為る', source: '為ている', rule: 'vs', reasons: ['-te', 'progressive or perfect']}, - {term: '為る', source: '為ておる', rule: 'vs', reasons: ['-te', 'progressive or perfect']}, - {term: '為る', source: '為てる', rule: 'vs', reasons: ['-te', 'progressive or perfect']}, - {term: '為る', source: '為とる', rule: 'vs', reasons: ['-te', 'progressive or perfect']}, - {term: '為る', source: '為てしまう', rule: 'vs', reasons: ['-te', '-shimau']}, - - {term: 'する', source: 'する', rule: 'vs', reasons: []}, - {term: 'する', source: 'します', rule: 'vs', reasons: ['polite']}, - {term: 'する', source: 'した', rule: 'vs', reasons: ['past']}, - {term: 'する', source: 'しました', rule: 'vs', reasons: ['polite past']}, - {term: 'する', source: 'して', rule: 'vs', reasons: ['-te']}, - {term: 'する', source: 'できる', rule: 'vs', reasons: ['potential']}, - {term: 'する', source: '出来る', rule: 'vs', reasons: ['potential']}, - {term: 'する', source: 'せられる', rule: 'vs', reasons: ['potential or passive']}, - {term: 'する', source: 'される', rule: 'vs', reasons: ['passive']}, - {term: 'する', source: 'させる', rule: 'vs', reasons: ['causative']}, - {term: 'する', source: 'せさせる', rule: 'vs', reasons: ['causative']}, - {term: 'する', source: 'させられる', rule: 'vs', reasons: ['causative', 'potential or passive']}, - {term: 'する', source: 'せさせられる', rule: 'vs', reasons: ['causative', 'potential or passive']}, - {term: 'する', source: 'しろ', rule: 'vs', reasons: ['imperative']}, - {term: 'する', source: 'しない', rule: 'vs', reasons: ['negative']}, - {term: 'する', source: 'しません', rule: 'vs', reasons: ['polite negative']}, - {term: 'する', source: 'しなかった', rule: 'vs', reasons: ['negative', 'past']}, - {term: 'する', source: 'しませんでした', rule: 'vs', reasons: ['polite past negative']}, - {term: 'する', source: 'しなくて', rule: 'vs', reasons: ['negative', '-te']}, - {term: 'する', source: 'せられない', rule: 'vs', reasons: ['potential or passive', 'negative']}, - {term: 'する', source: 'されない', rule: 'vs', reasons: ['passive', 'negative']}, - {term: 'する', source: 'させない', rule: 'vs', reasons: ['causative', 'negative']}, - {term: 'する', source: 'せさせない', rule: 'vs', reasons: ['causative', 'negative']}, - {term: 'する', source: 'させられない', rule: 'vs', reasons: ['causative', 'potential or passive', 'negative']}, - {term: 'する', source: 'せさせられない', rule: 'vs', reasons: ['causative', 'potential or passive', 'negative']}, - {term: 'する', source: 'するな', rule: 'vs', reasons: ['imperative negative']}, - - {term: 'する', source: 'すれば', rule: 'vs', reasons: ['-ba']}, - {term: 'する', source: 'しちゃう', rule: 'vs', reasons: ['-chau']}, - {term: 'する', source: 'しちまう', rule: 'vs', reasons: ['-chimau']}, - {term: 'する', source: 'しなさい', rule: 'vs', reasons: ['-nasai']}, - {term: 'する', source: 'しそう', rule: 'vs', reasons: ['-sou']}, - {term: 'する', source: 'しすぎる', rule: 'vs', reasons: ['-sugiru']}, - {term: 'する', source: 'したい', rule: 'vs', reasons: ['-tai']}, - {term: 'する', source: 'したら', rule: 'vs', reasons: ['-tara']}, - {term: 'する', source: 'したり', rule: 'vs', reasons: ['-tari']}, - {term: 'する', source: 'せず', rule: 'vs', reasons: ['-zu']}, - {term: 'する', source: 'せぬ', rule: 'vs', reasons: ['-nu']}, - // ['masu stem'] - {term: 'する', source: 'しましょう', rule: 'vs', reasons: ['polite volitional']}, - {term: 'する', source: 'しよう', rule: 'vs', reasons: ['volitional']}, - // ['causative passive'] - {term: 'する', source: 'しとく', rule: 'vs', reasons: ['-toku']}, - {term: 'する', source: 'している', rule: 'vs', reasons: ['-te', 'progressive or perfect']}, - {term: 'する', source: 'しておる', rule: 'vs', reasons: ['-te', 'progressive or perfect']}, - {term: 'する', source: 'してる', rule: 'vs', reasons: ['-te', 'progressive or perfect']}, - {term: 'する', source: 'しとる', rule: 'vs', reasons: ['-te', 'progressive or perfect']}, - {term: 'する', source: 'してしまう', rule: 'vs', reasons: ['-te', '-shimau']}, - - {term: '来る', source: '来る', rule: 'vk', reasons: []}, - {term: '来る', source: '来ます', rule: 'vk', reasons: ['polite']}, - {term: '来る', source: '来た', rule: 'vk', reasons: ['past']}, - {term: '来る', source: '来ました', rule: 'vk', reasons: ['polite past']}, - {term: '来る', source: '来て', rule: 'vk', reasons: ['-te']}, - {term: '来る', source: '来られる', rule: 'vk', reasons: ['potential or passive']}, - {term: '来る', source: '来られる', rule: 'vk', reasons: ['potential or passive']}, - {term: '来る', source: '来させる', rule: 'vk', reasons: ['causative']}, - {term: '来る', source: '来させられる', rule: 'vk', reasons: ['causative', 'potential or passive']}, - {term: '来る', source: '来い', rule: 'vk', reasons: ['imperative']}, - {term: '来る', source: '来ない', rule: 'vk', reasons: ['negative']}, - {term: '来る', source: '来ません', rule: 'vk', reasons: ['polite negative']}, - {term: '来る', source: '来なかった', rule: 'vk', reasons: ['negative', 'past']}, - {term: '来る', source: '来ませんでした', rule: 'vk', reasons: ['polite past negative']}, - {term: '来る', source: '来なくて', rule: 'vk', reasons: ['negative', '-te']}, - {term: '来る', source: '来られない', rule: 'vk', reasons: ['potential or passive', 'negative']}, - {term: '来る', source: '来られない', rule: 'vk', reasons: ['potential or passive', 'negative']}, - {term: '来る', source: '来させない', rule: 'vk', reasons: ['causative', 'negative']}, - {term: '来る', source: '来させられない', rule: 'vk', reasons: ['causative', 'potential or passive', 'negative']}, - {term: '来る', source: '来るな', rule: 'vk', reasons: ['imperative negative']}, - - {term: '来る', source: '来れば', rule: 'vk', reasons: ['-ba']}, - {term: '来る', source: '来ちゃう', rule: 'vk', reasons: ['-chau']}, - {term: '来る', source: '来ちまう', rule: 'vk', reasons: ['-chimau']}, - {term: '来る', source: '来なさい', rule: 'vk', reasons: ['-nasai']}, - {term: '来る', source: '来そう', rule: 'vk', reasons: ['-sou']}, - {term: '来る', source: '来すぎる', rule: 'vk', reasons: ['-sugiru']}, - {term: '来る', source: '来たい', rule: 'vk', reasons: ['-tai']}, - {term: '来る', source: '来たら', rule: 'vk', reasons: ['-tara']}, - {term: '来る', source: '来たり', rule: 'vk', reasons: ['-tari']}, - {term: '来る', source: '来ず', rule: 'vk', reasons: ['-zu']}, - {term: '来る', source: '来ぬ', rule: 'vk', reasons: ['-nu']}, - {term: '来る', source: '来', rule: 'vk', reasons: ['masu stem']}, - {term: '来る', source: '来ましょう', rule: 'vk', reasons: ['polite volitional']}, - {term: '来る', source: '来よう', rule: 'vk', reasons: ['volitional']}, - // ['causative passive'] - {term: '来る', source: '来とく', rule: 'vk', reasons: ['-toku']}, - {term: '来る', source: '来ている', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, - {term: '来る', source: '来ておる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, - {term: '来る', source: '来てる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, - {term: '来る', source: '来とる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, - {term: '来る', source: '来てしまう', rule: 'vk', reasons: ['-te', '-shimau']}, - - {term: '來る', source: '來る', rule: 'vk', reasons: []}, - {term: '來る', source: '來ます', rule: 'vk', reasons: ['polite']}, - {term: '來る', source: '來た', rule: 'vk', reasons: ['past']}, - {term: '來る', source: '來ました', rule: 'vk', reasons: ['polite past']}, - {term: '來る', source: '來て', rule: 'vk', reasons: ['-te']}, - {term: '來る', source: '來られる', rule: 'vk', reasons: ['potential or passive']}, - {term: '來る', source: '來られる', rule: 'vk', reasons: ['potential or passive']}, - {term: '來る', source: '來させる', rule: 'vk', reasons: ['causative']}, - {term: '來る', source: '來させられる', rule: 'vk', reasons: ['causative', 'potential or passive']}, - {term: '來る', source: '來い', rule: 'vk', reasons: ['imperative']}, - {term: '來る', source: '來ない', rule: 'vk', reasons: ['negative']}, - {term: '來る', source: '來ません', rule: 'vk', reasons: ['polite negative']}, - {term: '來る', source: '來なかった', rule: 'vk', reasons: ['negative', 'past']}, - {term: '來る', source: '來ませんでした', rule: 'vk', reasons: ['polite past negative']}, - {term: '來る', source: '來なくて', rule: 'vk', reasons: ['negative', '-te']}, - {term: '來る', source: '來られない', rule: 'vk', reasons: ['potential or passive', 'negative']}, - {term: '來る', source: '來られない', rule: 'vk', reasons: ['potential or passive', 'negative']}, - {term: '來る', source: '來させない', rule: 'vk', reasons: ['causative', 'negative']}, - {term: '來る', source: '來させられない', rule: 'vk', reasons: ['causative', 'potential or passive', 'negative']}, - {term: '來る', source: '來るな', rule: 'vk', reasons: ['imperative negative']}, - - {term: '來る', source: '來れば', rule: 'vk', reasons: ['-ba']}, - {term: '來る', source: '來ちゃう', rule: 'vk', reasons: ['-chau']}, - {term: '來る', source: '來ちまう', rule: 'vk', reasons: ['-chimau']}, - {term: '來る', source: '來なさい', rule: 'vk', reasons: ['-nasai']}, - {term: '來る', source: '來そう', rule: 'vk', reasons: ['-sou']}, - {term: '來る', source: '來すぎる', rule: 'vk', reasons: ['-sugiru']}, - {term: '來る', source: '來たい', rule: 'vk', reasons: ['-tai']}, - {term: '來る', source: '來たら', rule: 'vk', reasons: ['-tara']}, - {term: '來る', source: '來たり', rule: 'vk', reasons: ['-tari']}, - {term: '來る', source: '來ず', rule: 'vk', reasons: ['-zu']}, - {term: '來る', source: '來ぬ', rule: 'vk', reasons: ['-nu']}, - {term: '來る', source: '來', rule: 'vk', reasons: ['masu stem']}, - {term: '來る', source: '來ましょう', rule: 'vk', reasons: ['polite volitional']}, - {term: '來る', source: '來よう', rule: 'vk', reasons: ['volitional']}, - // ['causative passive'] - {term: '來る', source: '來とく', rule: 'vk', reasons: ['-toku']}, - {term: '來る', source: '來ている', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, - {term: '來る', source: '來ておる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, - {term: '來る', source: '來てる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, - {term: '來る', source: '來とる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, - {term: '來る', source: '來てしまう', rule: 'vk', reasons: ['-te', '-shimau']}, - - {term: 'くる', source: 'くる', rule: 'vk', reasons: []}, - {term: 'くる', source: 'きます', rule: 'vk', reasons: ['polite']}, - {term: 'くる', source: 'きた', rule: 'vk', reasons: ['past']}, - {term: 'くる', source: 'きました', rule: 'vk', reasons: ['polite past']}, - {term: 'くる', source: 'きて', rule: 'vk', reasons: ['-te']}, - {term: 'くる', source: 'こられる', rule: 'vk', reasons: ['potential or passive']}, - {term: 'くる', source: 'こられる', rule: 'vk', reasons: ['potential or passive']}, - {term: 'くる', source: 'こさせる', rule: 'vk', reasons: ['causative']}, - {term: 'くる', source: 'こさせられる', rule: 'vk', reasons: ['causative', 'potential or passive']}, - {term: 'くる', source: 'こい', rule: 'vk', reasons: ['imperative']}, - {term: 'くる', source: 'こない', rule: 'vk', reasons: ['negative']}, - {term: 'くる', source: 'きません', rule: 'vk', reasons: ['polite negative']}, - {term: 'くる', source: 'こなかった', rule: 'vk', reasons: ['negative', 'past']}, - {term: 'くる', source: 'きませんでした', rule: 'vk', reasons: ['polite past negative']}, - {term: 'くる', source: 'こなくて', rule: 'vk', reasons: ['negative', '-te']}, - {term: 'くる', source: 'こられない', rule: 'vk', reasons: ['potential or passive', 'negative']}, - {term: 'くる', source: 'こられない', rule: 'vk', reasons: ['potential or passive', 'negative']}, - {term: 'くる', source: 'こさせない', rule: 'vk', reasons: ['causative', 'negative']}, - {term: 'くる', source: 'こさせられない', rule: 'vk', reasons: ['causative', 'potential or passive', 'negative']}, - {term: 'くる', source: 'くるな', rule: 'vk', reasons: ['imperative negative']}, - - {term: 'くる', source: 'くれば', rule: 'vk', reasons: ['-ba']}, - {term: 'くる', source: 'きちゃう', rule: 'vk', reasons: ['-chau']}, - {term: 'くる', source: 'きちまう', rule: 'vk', reasons: ['-chimau']}, - {term: 'くる', source: 'きなさい', rule: 'vk', reasons: ['-nasai']}, - {term: 'くる', source: 'きそう', rule: 'vk', reasons: ['-sou']}, - {term: 'くる', source: 'きすぎる', rule: 'vk', reasons: ['-sugiru']}, - {term: 'くる', source: 'きたい', rule: 'vk', reasons: ['-tai']}, - {term: 'くる', source: 'きたら', rule: 'vk', reasons: ['-tara']}, - {term: 'くる', source: 'きたり', rule: 'vk', reasons: ['-tari']}, - {term: 'くる', source: 'こず', rule: 'vk', reasons: ['-zu']}, - {term: 'くる', source: 'こぬ', rule: 'vk', reasons: ['-nu']}, - {term: 'くる', source: 'き', rule: 'vk', reasons: ['masu stem']}, - {term: 'くる', source: 'きましょう', rule: 'vk', reasons: ['polite volitional']}, - {term: 'くる', source: 'こよう', rule: 'vk', reasons: ['volitional']}, - // ['causative passive'] - {term: 'くる', source: 'きとく', rule: 'vk', reasons: ['-toku']}, - {term: 'くる', source: 'きている', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, - {term: 'くる', source: 'きておる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, - {term: 'くる', source: 'きてる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, - {term: 'くる', source: 'きとる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, - {term: 'くる', source: 'きてしまう', rule: 'vk', reasons: ['-te', '-shimau']} - ] - }, - { - category: '-zuru verbs', - valid: true, - tests: [ - {term: '論ずる', source: '論ずる', rule: 'vz', reasons: []}, - {term: '論ずる', source: '論じます', rule: 'vz', reasons: ['polite']}, - {term: '論ずる', source: '論じた', rule: 'vz', reasons: ['past']}, - {term: '論ずる', source: '論じました', rule: 'vz', reasons: ['polite past']}, - {term: '論ずる', source: '論じて', rule: 'vz', reasons: ['-te']}, - {term: '論ずる', source: '論ぜられる', rule: 'vz', reasons: ['potential or passive']}, - {term: '論ずる', source: '論ざれる', rule: 'vz', reasons: ['potential or passive']}, - {term: '論ずる', source: '論じされる', rule: 'vz', reasons: ['passive']}, - {term: '論ずる', source: '論ぜされる', rule: 'vz', reasons: ['passive']}, - {term: '論ずる', source: '論じさせる', rule: 'vz', reasons: ['causative']}, - {term: '論ずる', source: '論ぜさせる', rule: 'vz', reasons: ['causative']}, - {term: '論ずる', source: '論じさせられる', rule: 'vz', reasons: ['causative', 'potential or passive']}, - {term: '論ずる', source: '論ぜさせられる', rule: 'vz', reasons: ['causative', 'potential or passive']}, - {term: '論ずる', source: '論じろ', rule: 'vz', reasons: ['imperative']}, - {term: '論ずる', source: '論じない', rule: 'vz', reasons: ['negative']}, - {term: '論ずる', source: '論じません', rule: 'vz', reasons: ['polite negative']}, - {term: '論ずる', source: '論じなかった', rule: 'vz', reasons: ['negative', 'past']}, - {term: '論ずる', source: '論じませんでした', rule: 'vz', reasons: ['polite past negative']}, - {term: '論ずる', source: '論じなくて', rule: 'vz', reasons: ['negative', '-te']}, - {term: '論ずる', source: '論ぜられない', rule: 'vz', reasons: ['potential or passive', 'negative']}, - {term: '論ずる', source: '論じされない', rule: 'vz', reasons: ['passive', 'negative']}, - {term: '論ずる', source: '論ぜされない', rule: 'vz', reasons: ['passive', 'negative']}, - {term: '論ずる', source: '論じさせない', rule: 'vz', reasons: ['causative', 'negative']}, - {term: '論ずる', source: '論ぜさせない', rule: 'vz', reasons: ['causative', 'negative']}, - {term: '論ずる', source: '論じさせられない', rule: 'vz', reasons: ['causative', 'potential or passive', 'negative']}, - {term: '論ずる', source: '論ぜさせられない', rule: 'vz', reasons: ['causative', 'potential or passive', 'negative']}, - {term: '論ずる', source: '論ずるな', rule: 'vz', reasons: ['imperative negative']}, - - {term: '論ずる', source: '論ずれば', rule: 'vz', reasons: ['-ba']}, - {term: '論ずる', source: '論じちゃう', rule: 'vz', reasons: ['-chau']}, - {term: '論ずる', source: '論じちまう', rule: 'vz', reasons: ['-chimau']}, - {term: '論ずる', source: '論じなさい', rule: 'vz', reasons: ['-nasai']}, - {term: '論ずる', source: '論じそう', rule: 'vz', reasons: ['-sou']}, - {term: '論ずる', source: '論じすぎる', rule: 'vz', reasons: ['-sugiru']}, - {term: '論ずる', source: '論じたい', rule: 'vz', reasons: ['-tai']}, - {term: '論ずる', source: '論じたら', rule: 'vz', reasons: ['-tara']}, - {term: '論ずる', source: '論じたり', rule: 'vz', reasons: ['-tari']}, - {term: '論ずる', source: '論ぜず', rule: 'vz', reasons: ['-zu']}, - {term: '論ずる', source: '論ぜぬ', rule: 'vz', reasons: ['-nu']}, - // ['masu stem'] - {term: '論ずる', source: '論じましょう', rule: 'vz', reasons: ['polite volitional']}, - {term: '論ずる', source: '論じよう', rule: 'vz', reasons: ['volitional']}, - // ['causative passive'] - {term: '論ずる', source: '論じとく', rule: 'vz', reasons: ['-toku']}, - {term: '論ずる', source: '論じている', rule: 'vz', reasons: ['-te', 'progressive or perfect']}, - {term: '論ずる', source: '論じておる', rule: 'vz', reasons: ['-te', 'progressive or perfect']}, - {term: '論ずる', source: '論じてる', rule: 'vz', reasons: ['-te', 'progressive or perfect']}, - {term: '論ずる', source: '論じとる', rule: 'vz', reasons: ['-te', 'progressive or perfect']}, - {term: '論ずる', source: '論じてしまう', rule: 'vz', reasons: ['-te', '-shimau']} - ] - }, - { - category: '-e verbs', - valid: true, - tests: [ - {term: 'すごい', source: 'すげえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'やばい', source: 'やべえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'うるさい', source: 'うるせえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'ひどい', source: 'ひでえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'ない', source: 'ねえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'できる', source: 'できねえ', rule: 'v1', reasons: ['negative', '-e']}, - {term: 'しんじる', source: 'しんじねえ', rule: 'v1', reasons: ['negative', '-e']}, - {term: 'さむい', source: 'さめえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'さむい', source: 'さみい', rule: 'adj-i', reasons: ['-e']}, - {term: 'あつい', source: 'あちぇえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'あつい', source: 'あちい', rule: 'adj-i', reasons: ['-e']}, - {term: 'やすい', source: 'やせえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'たかい', source: 'たけえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'かわいい', source: 'かわええ', rule: 'adj-i', reasons: ['-e']}, - {term: 'つよい', source: 'ついぇえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'こわい', source: 'こうぇえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'みじかい', source: 'みじけえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'ながい', source: 'なげえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'くさい', source: 'くせえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'うまい', source: 'うめえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'でかい', source: 'でけえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'まずい', source: 'まっぜえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'ちっちゃい', source: 'ちっちぇえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'あかい', source: 'あけえ', rule: 'adj-i', reasons: ['-e']}, - {term: 'こわい', source: 'こええ', rule: 'adj-i', reasons: ['-e']}, - {term: 'つよい', source: 'つええ', rule: 'adj-i', reasons: ['-e']} - ] - }, - { - category: 'irregular verbs', - valid: false, - tests: [ - {term: 'する', source: 'すます', rule: 'vs', reasons: null}, - {term: 'する', source: 'すた', rule: 'vs', reasons: null}, - {term: 'する', source: 'すました', rule: 'vs', reasons: null}, - {term: 'する', source: 'すて', rule: 'vs', reasons: null}, - {term: 'する', source: 'すれる', rule: 'vs', reasons: null}, - {term: 'する', source: 'すせる', rule: 'vs', reasons: null}, - {term: 'する', source: 'すせられる', rule: 'vs', reasons: null}, - {term: 'する', source: 'すろ', rule: 'vs', reasons: null}, - {term: 'する', source: 'すない', rule: 'vs', reasons: null}, - {term: 'する', source: 'すません', rule: 'vs', reasons: null}, - {term: 'する', source: 'すなかった', rule: 'vs', reasons: null}, - {term: 'する', source: 'すませんでした', rule: 'vs', reasons: null}, - {term: 'する', source: 'すなくて', rule: 'vs', reasons: null}, - {term: 'する', source: 'すれない', rule: 'vs', reasons: null}, - {term: 'する', source: 'すせない', rule: 'vs', reasons: null}, - {term: 'する', source: 'すせられない', rule: 'vs', reasons: null}, - - {term: 'くる', source: 'くます', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くた', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くました', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くて', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くられる', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くられる', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くさせる', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くさせられる', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くい', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くない', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くません', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くなかった', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くませんでした', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くなくて', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くられない', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くられない', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くさせない', rule: 'vk', reasons: null}, - {term: 'くる', source: 'くさせられない', rule: 'vk', reasons: null} - ] - }, - { - category: 'uncommon irregular verbs', - valid: true, - tests: [ - {term: 'のたまう', source: 'のたもうて', rule: 'v5', reasons: ['-te']}, - {term: 'のたまう', source: 'のたもうた', rule: 'v5', reasons: ['past']}, - {term: 'のたまう', source: 'のたもうたら', rule: 'v5', reasons: ['-tara']}, - {term: 'のたまう', source: 'のたもうたり', rule: 'v5', reasons: ['-tari']}, - - {term: 'おう', source: 'おうて', rule: 'v5', reasons: ['-te']}, - {term: 'こう', source: 'こうて', rule: 'v5', reasons: ['-te']}, - {term: 'そう', source: 'そうて', rule: 'v5', reasons: ['-te']}, - {term: 'とう', source: 'とうて', rule: 'v5', reasons: ['-te']}, - {term: '請う', source: '請うて', rule: 'v5', reasons: ['-te']}, - {term: '乞う', source: '乞うて', rule: 'v5', reasons: ['-te']}, - {term: '恋う', source: '恋うて', rule: 'v5', reasons: ['-te']}, - {term: '問う', source: '問うて', rule: 'v5', reasons: ['-te']}, - {term: '負う', source: '負うて', rule: 'v5', reasons: ['-te']}, - {term: '沿う', source: '沿うて', rule: 'v5', reasons: ['-te']}, - {term: '添う', source: '添うて', rule: 'v5', reasons: ['-te']}, - {term: '副う', source: '副うて', rule: 'v5', reasons: ['-te']}, - {term: '厭う', source: '厭うて', rule: 'v5', reasons: ['-te']}, - - {term: 'おう', source: 'おうた', rule: 'v5', reasons: ['past']}, - {term: 'こう', source: 'こうた', rule: 'v5', reasons: ['past']}, - {term: 'そう', source: 'そうた', rule: 'v5', reasons: ['past']}, - {term: 'とう', source: 'とうた', rule: 'v5', reasons: ['past']}, - {term: '請う', source: '請うた', rule: 'v5', reasons: ['past']}, - {term: '乞う', source: '乞うた', rule: 'v5', reasons: ['past']}, - {term: '恋う', source: '恋うた', rule: 'v5', reasons: ['past']}, - {term: '問う', source: '問うた', rule: 'v5', reasons: ['past']}, - {term: '負う', source: '負うた', rule: 'v5', reasons: ['past']}, - {term: '沿う', source: '沿うた', rule: 'v5', reasons: ['past']}, - {term: '添う', source: '添うた', rule: 'v5', reasons: ['past']}, - {term: '副う', source: '副うた', rule: 'v5', reasons: ['past']}, - {term: '厭う', source: '厭うた', rule: 'v5', reasons: ['past']}, - - {term: 'おう', source: 'おうたら', rule: 'v5', reasons: ['-tara']}, - {term: 'こう', source: 'こうたら', rule: 'v5', reasons: ['-tara']}, - {term: 'そう', source: 'そうたら', rule: 'v5', reasons: ['-tara']}, - {term: 'とう', source: 'とうたら', rule: 'v5', reasons: ['-tara']}, - {term: '請う', source: '請うたら', rule: 'v5', reasons: ['-tara']}, - {term: '乞う', source: '乞うたら', rule: 'v5', reasons: ['-tara']}, - {term: '恋う', source: '恋うたら', rule: 'v5', reasons: ['-tara']}, - {term: '問う', source: '問うたら', rule: 'v5', reasons: ['-tara']}, - {term: '負う', source: '負うたら', rule: 'v5', reasons: ['-tara']}, - {term: '沿う', source: '沿うたら', rule: 'v5', reasons: ['-tara']}, - {term: '添う', source: '添うたら', rule: 'v5', reasons: ['-tara']}, - {term: '副う', source: '副うたら', rule: 'v5', reasons: ['-tara']}, - {term: '厭う', source: '厭うたら', rule: 'v5', reasons: ['-tara']}, - - {term: 'おう', source: 'おうたり', rule: 'v5', reasons: ['-tari']}, - {term: 'こう', source: 'こうたり', rule: 'v5', reasons: ['-tari']}, - {term: 'そう', source: 'そうたり', rule: 'v5', reasons: ['-tari']}, - {term: 'とう', source: 'とうたり', rule: 'v5', reasons: ['-tari']}, - {term: '請う', source: '請うたり', rule: 'v5', reasons: ['-tari']}, - {term: '乞う', source: '乞うたり', rule: 'v5', reasons: ['-tari']}, - {term: '恋う', source: '恋うたり', rule: 'v5', reasons: ['-tari']}, - {term: '問う', source: '問うたり', rule: 'v5', reasons: ['-tari']}, - {term: '負う', source: '負うたり', rule: 'v5', reasons: ['-tari']}, - {term: '沿う', source: '沿うたり', rule: 'v5', reasons: ['-tari']}, - {term: '添う', source: '添うたり', rule: 'v5', reasons: ['-tari']}, - {term: '副う', source: '副うたり', rule: 'v5', reasons: ['-tari']}, - {term: '厭う', source: '厭うたり', rule: 'v5', reasons: ['-tari']} - ] - }, - { - category: 'combinations', - valid: true, - tests: [ - {term: '抱き抱える', source: '抱き抱えていなければ', rule: 'v1', reasons: ['-te', 'progressive or perfect', 'negative', '-ba']}, - {term: '抱きかかえる', source: '抱きかかえていなければ', rule: 'v1', reasons: ['-te', 'progressive or perfect', 'negative', '-ba']}, - {term: '打ち込む', source: '打ち込んでいませんでした', rule: 'v5', reasons: ['-te', 'progressive or perfect', 'polite past negative']}, - {term: '食べる', source: '食べさせられたくなかった', rule: 'v1', reasons: ['causative', 'potential or passive', '-tai', 'negative', 'past']} - ] - }, - { - category: 'kawaii (this leads to infinite expansions)', - valid: false, - tests: [ - {term: 'かわいい', source: 'かわいげ', rule: 'adj-i', reasons: ['-ge']}, - {term: '可愛い', source: 'かわいげ', rule: 'adj-i', reasons: ['-ge']} - ] - }, - { - category: 'incorrect -te rule chain', - valid: false, - tests: [ - {term: '食べる', source: '食べて', rule: null, reasons: ['-te', 'progressive or perfect', 'masu stem']} - ] - } - ]; - /* eslint-enable no-multi-spaces */ - - /** @type {import('deinflector').ReasonsRaw} */ - const deinflectionReasons = parseJson(fs.readFileSync(path.join(dirname, '..', 'ext', 'data/deinflect.json'), {encoding: 'utf8'})); - const deinflector = new Deinflector(deinflectionReasons); - - describe('deinflections', () => { - // for (const {valid, tests} of data) { - describe.each(data)('$category', ({valid, tests}) => { - for (const {source, term, rule, reasons} of tests) { - const {has} = hasTermReasons(deinflector, source, term, rule, reasons); - let message = `${source} ${valid ? 'has' : 'does not have'} term candidate ${JSON.stringify(term)}`; - if (typeof rule !== 'undefined') { - message += ` with rule ${JSON.stringify(rule)}`; - } - if (reasons !== null) { - message += (typeof rule !== 'undefined' ? ' and' : ' with'); - message += ` reasons ${JSON.stringify(reasons)}`; - } - test(`${message}`, () => { - expect(has).toStrictEqual(valid); - }); - } - }); - }); -} - - -/** */ -function main() { - testDeinflections(); -} - -main(); diff --git a/test/fixtures/translator-test.js b/test/fixtures/translator-test.js index 6562931c..58247b70 100644 --- a/test/fixtures/translator-test.js +++ b/test/fixtures/translator-test.js @@ -32,7 +32,7 @@ import {DictionaryImporterMediaLoader} from '../mocks/dictionary-importer-media- import {createDomTest} from './dom-test.js'; const extDir = join(dirname(fileURLToPath(import.meta.url)), '../../ext'); -const deinflectionReasonsPath = join(extDir, 'data/deinflect.json'); +const languageTransformDescriptorPath = join(extDir, 'data/language/japanese-transforms.json'); vi.stubGlobal('indexedDB', indexedDB); vi.stubGlobal('IDBKeyRange', IDBKeyRange); @@ -65,8 +65,8 @@ async function createTranslatorContext(dictionaryDirectory, dictionaryName) { // Setup translator const translator = new Translator({database: dictionaryDatabase}); - /** @type {import('deinflector').ReasonsRaw} */ - const deinflectionReasons = parseJson(readFileSync(deinflectionReasonsPath, {encoding: 'utf8'})); + /** @type {import('language-transformer').LanguageTransformDescriptor} */ + const deinflectionReasons = parseJson(readFileSync(languageTransformDescriptorPath, {encoding: 'utf8'})); translator.prepare(deinflectionReasons); // Assign properties diff --git a/test/language-transformer-cycles.test.js b/test/language-transformer-cycles.test.js new file mode 100644 index 00000000..76bee83e --- /dev/null +++ b/test/language-transformer-cycles.test.js @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2024 Yomitan Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import {readFileSync} from 'fs'; +import {join, dirname as pathDirname} from 'path'; +import {fileURLToPath} from 'url'; +import {describe, test} from 'vitest'; +import {parseJson} from '../dev/json.js'; +import {LanguageTransformer} from '../ext/js/language/language-transformer.js'; + +class DeinflectionNode { + /** + * @param {string} text + * @param {string[]} ruleNames + * @param {?RuleNode} ruleNode + * @param {?DeinflectionNode} previous + */ + constructor(text, ruleNames, ruleNode, previous) { + /** @type {string} */ + this.text = text; + /** @type {string[]} */ + this.ruleNames = ruleNames; + /** @type {?RuleNode} */ + this.ruleNode = ruleNode; + /** @type {?DeinflectionNode} */ + this.previous = previous; + } + + /** + * @param {DeinflectionNode} other + * @returns {boolean} + */ + historyIncludes(other) { + /** @type {?DeinflectionNode} */ + // eslint-disable-next-line @typescript-eslint/no-this-alias + let node = this; + for (; node !== null; node = node.previous) { + if ( + node.ruleNode === other.ruleNode && + node.text === other.text && + arraysAreEqual(node.ruleNames, other.ruleNames) + ) { + return true; + } + } + return false; + } + + /** + * @returns {DeinflectionNode[]} + */ + getHistory() { + /** @type {DeinflectionNode[]} */ + const results = []; + /** @type {?DeinflectionNode} */ + // eslint-disable-next-line @typescript-eslint/no-this-alias + let node = this; + for (; node !== null; node = node.previous) { + results.unshift(node); + } + return results; + } +} + +class RuleNode { + /** + * @param {string} groupName + * @param {import('language-transformer').Rule} rule + */ + constructor(groupName, rule) { + /** @type {string} */ + this.groupName = groupName; + /** @type {import('language-transformer').Rule} */ + this.rule = rule; + } +} + +/** + * @template [T=unknown] + * @param {T[]} rules1 + * @param {T[]} rules2 + * @returns {boolean} + */ +function arraysAreEqual(rules1, rules2) { + if (rules1.length !== rules2.length) { return false; } + for (const rule1 of rules1) { + if (!rules2.includes(rule1)) { return false; } + } + return true; +} + +describe('Deinflection data', () => { + test('Check for cycles', ({expect}) => { + const dirname = pathDirname(fileURLToPath(import.meta.url)); + + /** @type {import('language-transformer').LanguageTransformDescriptor} */ + const descriptor = parseJson(readFileSync(join(dirname, '../ext/data/language/japanese-transforms.json'), {encoding: 'utf8'})); + const languageTransformer = new LanguageTransformer(); + languageTransformer.addDescriptor(descriptor); + + /** @type {RuleNode[]} */ + const ruleNodes = []; + for (const [groupName, reasonInfo] of Object.entries(descriptor.transforms)) { + for (const rule of reasonInfo.rules) { + ruleNodes.push(new RuleNode(groupName, rule)); + } + } + + /** @type {DeinflectionNode[]} */ + const deinflectionNodes = []; + for (const ruleNode of ruleNodes) { + deinflectionNodes.push(new DeinflectionNode(`?${ruleNode.rule.suffixIn}`, [], null, null)); + } + for (let i = 0; i < deinflectionNodes.length; ++i) { + const deinflectionNode = deinflectionNodes[i]; + const {text, ruleNames} = deinflectionNode; + for (const ruleNode of ruleNodes) { + const {suffixIn, suffixOut, conditionsIn, conditionsOut} = ruleNode.rule; + if ( + !LanguageTransformer.conditionsMatch( + languageTransformer.getConditionFlagsFromConditionTypes(ruleNames), + languageTransformer.getConditionFlagsFromConditionTypes(conditionsIn) + ) || + !text.endsWith(suffixIn) || + (text.length - suffixIn.length + suffixOut.length) <= 0 + ) { + continue; + } + + const newDeinflectionNode = new DeinflectionNode( + text.substring(0, text.length - suffixIn.length) + suffixOut, + conditionsOut, + ruleNode, + deinflectionNode + ); + + // Cycle check + if (deinflectionNode.historyIncludes(newDeinflectionNode)) { + const stack = []; + for (const item of newDeinflectionNode.getHistory()) { + stack.push( + item.ruleNode === null ? + `${item.text} (start)` : + `${item.text} (${item.ruleNode.groupName}, ${item.ruleNode.rule.conditionsIn.join(',')}=>${item.ruleNode.rule.conditionsOut.join(',')}, ${item.ruleNode.rule.suffixIn}=>${item.ruleNode.rule.suffixOut})` + ); + } + const message = `Cycle detected:\n ${stack.join('\n ')}`; + expect.soft(true, message).toEqual(false); + continue; + } + + deinflectionNodes.push(newDeinflectionNode); + } + } + }); +}); \ No newline at end of file diff --git a/test/language-transformer.test.js b/test/language-transformer.test.js new file mode 100644 index 00000000..b99c1bef --- /dev/null +++ b/test/language-transformer.test.js @@ -0,0 +1,1049 @@ +/* + * Copyright (C) 2023-2024 Yomitan Authors + * Copyright (C) 2020-2022 Yomichan Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import fs from 'fs'; +import {fileURLToPath} from 'node:url'; +import path from 'path'; +import {describe, expect, test} from 'vitest'; +import {parseJson} from '../dev/json.js'; +import {LanguageTransformer} from '../ext/js/language/language-transformer.js'; + +const dirname = path.dirname(fileURLToPath(import.meta.url)); + +/** + * @param {LanguageTransformer} languageTransformer + * @param {string} source + * @param {string} expectedTerm + * @param {string|null} expectedConditionName + * @param {string[]|null} expectedReasons + * @returns {{has: false, reasons: null, rules: null}|{has: true, reasons: string[], rules: number}} + */ +function hasTermReasons(languageTransformer, source, expectedTerm, expectedConditionName, expectedReasons) { + for (const {text, conditions, trace} of languageTransformer.transform(source)) { + if (text !== expectedTerm) { continue; } + if (expectedConditionName !== null) { + const expectedConditions = languageTransformer.getConditionFlagsFromConditionType(expectedConditionName); + if (!LanguageTransformer.conditionsMatch(conditions, expectedConditions)) { continue; } + } + let okay = true; + if (expectedReasons !== null) { + if (trace.length !== expectedReasons.length) { continue; } + for (let i = 0, ii = expectedReasons.length; i < ii; ++i) { + if (expectedReasons[i] !== trace[i].transform) { + okay = false; + break; + } + } + } + if (okay) { + return { + has: true, + reasons: trace.map((frame) => frame.transform), + rules: conditions + }; + } + } + return {has: false, reasons: null, rules: null}; +} + + +/** */ +function testDeinflections() { + /* eslint-disable no-multi-spaces */ + const data = [ + { + category: 'adjectives', + valid: true, + tests: [ + {term: '愛しい', source: '愛しい', rule: 'adj-i', reasons: []}, + {term: '愛しい', source: '愛しそう', rule: 'adj-i', reasons: ['-sou']}, + {term: '愛しい', source: '愛しすぎる', rule: 'adj-i', reasons: ['-sugiru']}, + {term: '愛しい', source: '愛しかったら', rule: 'adj-i', reasons: ['-tara']}, + {term: '愛しい', source: '愛しかったり', rule: 'adj-i', reasons: ['-tari']}, + {term: '愛しい', source: '愛しくて', rule: 'adj-i', reasons: ['-te']}, + {term: '愛しい', source: '愛しく', rule: 'adj-i', reasons: ['adv']}, + {term: '愛しい', source: '愛しくない', rule: 'adj-i', reasons: ['negative']}, + {term: '愛しい', source: '愛しさ', rule: 'adj-i', reasons: ['noun']}, + {term: '愛しい', source: '愛しかった', rule: 'adj-i', reasons: ['past']}, + {term: '愛しい', source: '愛しくありません', rule: 'adj-i', reasons: ['polite negative']}, + {term: '愛しい', source: '愛しくありませんでした', rule: 'adj-i', reasons: ['polite past negative']}, + {term: '愛しい', source: '愛しき', rule: 'adj-i', reasons: ['-ki']}, + {term: '愛しい', source: '愛しげ', rule: 'adj-i', reasons: ['-ge']} + ] + }, + { + category: 'ichidan verbs', + valid: true, + tests: [ + {term: '食べる', source: '食べる', rule: 'v1', reasons: []}, + {term: '食べる', source: '食べます', rule: 'v1', reasons: ['polite']}, + {term: '食べる', source: '食べた', rule: 'v1', reasons: ['past']}, + {term: '食べる', source: '食べました', rule: 'v1', reasons: ['polite past']}, + {term: '食べる', source: '食べて', rule: 'v1', reasons: ['-te']}, + {term: '食べる', source: '食べられる', rule: 'v1', reasons: ['potential or passive']}, + {term: '食べる', source: '食べられる', rule: 'v1', reasons: ['potential or passive']}, + {term: '食べる', source: '食べさせる', rule: 'v1', reasons: ['causative']}, + {term: '食べる', source: '食べさせられる', rule: 'v1', reasons: ['causative', 'potential or passive']}, + {term: '食べる', source: '食べろ', rule: 'v1', reasons: ['imperative']}, + {term: '食べる', source: '食べない', rule: 'v1', reasons: ['negative']}, + {term: '食べる', source: '食べません', rule: 'v1', reasons: ['polite negative']}, + {term: '食べる', source: '食べなかった', rule: 'v1', reasons: ['negative', 'past']}, + {term: '食べる', source: '食べませんでした', rule: 'v1', reasons: ['polite past negative']}, + {term: '食べる', source: '食べなくて', rule: 'v1', reasons: ['negative', '-te']}, + {term: '食べる', source: '食べられない', rule: 'v1', reasons: ['potential or passive', 'negative']}, + {term: '食べる', source: '食べられない', rule: 'v1', reasons: ['potential or passive', 'negative']}, + {term: '食べる', source: '食べさせない', rule: 'v1', reasons: ['causative', 'negative']}, + {term: '食べる', source: '食べさせられない', rule: 'v1', reasons: ['causative', 'potential or passive', 'negative']}, + {term: '食べる', source: '食べるな', rule: 'v1', reasons: ['imperative negative']}, + + {term: '食べる', source: '食べれば', rule: 'v1', reasons: ['-ba']}, + {term: '食べる', source: '食べちゃう', rule: 'v1', reasons: ['-chau']}, + {term: '食べる', source: '食べちまう', rule: 'v1', reasons: ['-chimau']}, + {term: '食べる', source: '食べなさい', rule: 'v1', reasons: ['-nasai']}, + {term: '食べる', source: '食べそう', rule: 'v1', reasons: ['-sou']}, + {term: '食べる', source: '食べすぎる', rule: 'v1', reasons: ['-sugiru']}, + {term: '食べる', source: '食べたい', rule: 'v1', reasons: ['-tai']}, + {term: '食べる', source: '食べたら', rule: 'v1', reasons: ['-tara']}, + {term: '食べる', source: '食べたり', rule: 'v1', reasons: ['-tari']}, + {term: '食べる', source: '食べず', rule: 'v1', reasons: ['-zu']}, + {term: '食べる', source: '食べぬ', rule: 'v1', reasons: ['-nu']}, + {term: '食べる', source: '食べ', rule: 'v1d', reasons: ['masu stem']}, + {term: '食べる', source: '食べましょう', rule: 'v1', reasons: ['polite volitional']}, + {term: '食べる', source: '食べよう', rule: 'v1', reasons: ['volitional']}, + // ['causative passive'] + {term: '食べる', source: '食べとく', rule: 'v1', reasons: ['-toku']}, + {term: '食べる', source: '食べている', rule: 'v1', reasons: ['-te', 'progressive or perfect']}, + {term: '食べる', source: '食べておる', rule: 'v1', reasons: ['-te', 'progressive or perfect']}, + {term: '食べる', source: '食べてる', rule: 'v1', reasons: ['-te', 'progressive or perfect']}, + {term: '食べる', source: '食べとる', rule: 'v1', reasons: ['-te', 'progressive or perfect']}, + {term: '食べる', source: '食べてしまう', rule: 'v1', reasons: ['-te', '-shimau']} + ] + }, + { + category: '-u verbs', + valid: true, + tests: [ + {term: '買う', source: '買う', rule: 'v5', reasons: []}, + {term: '買う', source: '買います', rule: 'v5', reasons: ['polite']}, + {term: '買う', source: '買った', rule: 'v5', reasons: ['past']}, + {term: '買う', source: '買いました', rule: 'v5', reasons: ['polite past']}, + {term: '買う', source: '買って', rule: 'v5', reasons: ['-te']}, + {term: '買う', source: '買える', rule: 'v5', reasons: ['potential']}, + {term: '買う', source: '買われる', rule: 'v5', reasons: ['passive']}, + {term: '買う', source: '買わせる', rule: 'v5', reasons: ['causative']}, + {term: '買う', source: '買わせられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, + {term: '買う', source: '買え', rule: 'v5', reasons: ['imperative']}, + {term: '買う', source: '買わない', rule: 'v5', reasons: ['negative']}, + {term: '買う', source: '買いません', rule: 'v5', reasons: ['polite negative']}, + {term: '買う', source: '買わなかった', rule: 'v5', reasons: ['negative', 'past']}, + {term: '買う', source: '買いませんでした', rule: 'v5', reasons: ['polite past negative']}, + {term: '買う', source: '買わなくて', rule: 'v5', reasons: ['negative', '-te']}, + {term: '買う', source: '買えない', rule: 'v5', reasons: ['potential', 'negative']}, + {term: '買う', source: '買われない', rule: 'v5', reasons: ['passive', 'negative']}, + {term: '買う', source: '買わせない', rule: 'v5', reasons: ['causative', 'negative']}, + {term: '買う', source: '買わせられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, + {term: '買う', source: '買うな', rule: 'v5', reasons: ['imperative negative']}, + + {term: '買う', source: '買えば', rule: 'v5', reasons: ['-ba']}, + {term: '買う', source: '買っちゃう', rule: 'v5', reasons: ['-chau']}, + {term: '買う', source: '買っちまう', rule: 'v5', reasons: ['-chimau']}, + {term: '買う', source: '買いなさい', rule: 'v5', reasons: ['-nasai']}, + {term: '買う', source: '買いそう', rule: 'v5', reasons: ['-sou']}, + {term: '買う', source: '買いすぎる', rule: 'v5', reasons: ['-sugiru']}, + {term: '買う', source: '買いたい', rule: 'v5', reasons: ['-tai']}, + {term: '買う', source: '買ったら', rule: 'v5', reasons: ['-tara']}, + {term: '買う', source: '買ったり', rule: 'v5', reasons: ['-tari']}, + {term: '買う', source: '買わず', rule: 'v5', reasons: ['-zu']}, + {term: '買う', source: '買わぬ', rule: 'v5', reasons: ['-nu']}, + {term: '買う', source: '買い', rule: 'v5', reasons: ['masu stem']}, + {term: '買う', source: '買いましょう', rule: 'v5', reasons: ['polite volitional']}, + {term: '買う', source: '買おう', rule: 'v5', reasons: ['volitional']}, + {term: '買う', source: '買わされる', rule: 'v5', reasons: ['causative passive']}, + {term: '買う', source: '買っとく', rule: 'v5', reasons: ['-toku']}, + {term: '買う', source: '買っている', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '買う', source: '買っておる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '買う', source: '買ってる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '買う', source: '買っとる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '買う', source: '買ってしまう', rule: 'v5', reasons: ['-te', '-shimau']} + ] + }, + { + category: '-ku verbs', + valid: true, + tests: [ + {term: '行く', source: '行く', rule: 'v5', reasons: []}, + {term: '行く', source: '行きます', rule: 'v5', reasons: ['polite']}, + {term: '行く', source: '行った', rule: 'v5', reasons: ['past']}, + {term: '行く', source: '行きました', rule: 'v5', reasons: ['polite past']}, + {term: '行く', source: '行って', rule: 'v5', reasons: ['-te']}, + {term: '行く', source: '行ける', rule: 'v5', reasons: ['potential']}, + {term: '行く', source: '行かれる', rule: 'v5', reasons: ['passive']}, + {term: '行く', source: '行かせる', rule: 'v5', reasons: ['causative']}, + {term: '行く', source: '行かせられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, + {term: '行く', source: '行け', rule: 'v5', reasons: ['imperative']}, + {term: '行く', source: '行かない', rule: 'v5', reasons: ['negative']}, + {term: '行く', source: '行きません', rule: 'v5', reasons: ['polite negative']}, + {term: '行く', source: '行かなかった', rule: 'v5', reasons: ['negative', 'past']}, + {term: '行く', source: '行きませんでした', rule: 'v5', reasons: ['polite past negative']}, + {term: '行く', source: '行かなくて', rule: 'v5', reasons: ['negative', '-te']}, + {term: '行く', source: '行けない', rule: 'v5', reasons: ['potential', 'negative']}, + {term: '行く', source: '行かれない', rule: 'v5', reasons: ['passive', 'negative']}, + {term: '行く', source: '行かせない', rule: 'v5', reasons: ['causative', 'negative']}, + {term: '行く', source: '行かせられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, + {term: '行く', source: '行くな', rule: 'v5', reasons: ['imperative negative']}, + + {term: '行く', source: '行けば', rule: 'v5', reasons: ['-ba']}, + {term: '行く', source: '行っちゃう', rule: 'v5', reasons: ['-chau']}, + {term: '行く', source: '行っちまう', rule: 'v5', reasons: ['-chimau']}, + {term: '行く', source: '行きなさい', rule: 'v5', reasons: ['-nasai']}, + {term: '行く', source: '行きそう', rule: 'v5', reasons: ['-sou']}, + {term: '行く', source: '行きすぎる', rule: 'v5', reasons: ['-sugiru']}, + {term: '行く', source: '行きたい', rule: 'v5', reasons: ['-tai']}, + {term: '行く', source: '行いたら', rule: 'v5', reasons: ['-tara']}, + {term: '行く', source: '行いたり', rule: 'v5', reasons: ['-tari']}, + {term: '行く', source: '行かず', rule: 'v5', reasons: ['-zu']}, + {term: '行く', source: '行かぬ', rule: 'v5', reasons: ['-nu']}, + {term: '行く', source: '行き', rule: 'v5', reasons: ['masu stem']}, + {term: '行く', source: '行きましょう', rule: 'v5', reasons: ['polite volitional']}, + {term: '行く', source: '行こう', rule: 'v5', reasons: ['volitional']}, + {term: '行く', source: '行かされる', rule: 'v5', reasons: ['causative passive']}, + {term: '行く', source: '行いとく', rule: 'v5', reasons: ['-toku']}, + {term: '行く', source: '行っている', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '行く', source: '行っておる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '行く', source: '行ってる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '行く', source: '行っとる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '行く', source: '行ってしまう', rule: 'v5', reasons: ['-te', '-shimau']} + ] + }, + { + category: '-gu verbs', + valid: true, + tests: [ + {term: '泳ぐ', source: '泳ぐ', rule: 'v5', reasons: []}, + {term: '泳ぐ', source: '泳ぎます', rule: 'v5', reasons: ['polite']}, + {term: '泳ぐ', source: '泳いだ', rule: 'v5', reasons: ['past']}, + {term: '泳ぐ', source: '泳ぎました', rule: 'v5', reasons: ['polite past']}, + {term: '泳ぐ', source: '泳いで', rule: 'v5', reasons: ['-te']}, + {term: '泳ぐ', source: '泳げる', rule: 'v5', reasons: ['potential']}, + {term: '泳ぐ', source: '泳がれる', rule: 'v5', reasons: ['passive']}, + {term: '泳ぐ', source: '泳がせる', rule: 'v5', reasons: ['causative']}, + {term: '泳ぐ', source: '泳がせられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, + {term: '泳ぐ', source: '泳げ', rule: 'v5', reasons: ['imperative']}, + {term: '泳ぐ', source: '泳がない', rule: 'v5', reasons: ['negative']}, + {term: '泳ぐ', source: '泳ぎません', rule: 'v5', reasons: ['polite negative']}, + {term: '泳ぐ', source: '泳がなかった', rule: 'v5', reasons: ['negative', 'past']}, + {term: '泳ぐ', source: '泳ぎませんでした', rule: 'v5', reasons: ['polite past negative']}, + {term: '泳ぐ', source: '泳がなくて', rule: 'v5', reasons: ['negative', '-te']}, + {term: '泳ぐ', source: '泳げない', rule: 'v5', reasons: ['potential', 'negative']}, + {term: '泳ぐ', source: '泳がれない', rule: 'v5', reasons: ['passive', 'negative']}, + {term: '泳ぐ', source: '泳がせない', rule: 'v5', reasons: ['causative', 'negative']}, + {term: '泳ぐ', source: '泳がせられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, + {term: '泳ぐ', source: '泳ぐな', rule: 'v5', reasons: ['imperative negative']}, + + {term: '泳ぐ', source: '泳げば', rule: 'v5', reasons: ['-ba']}, + {term: '泳ぐ', source: '泳いじゃう', rule: 'v5', reasons: ['-chau']}, + {term: '泳ぐ', source: '泳いじまう', rule: 'v5', reasons: ['-chimau']}, + {term: '泳ぐ', source: '泳ぎなさい', rule: 'v5', reasons: ['-nasai']}, + {term: '泳ぐ', source: '泳ぎそう', rule: 'v5', reasons: ['-sou']}, + {term: '泳ぐ', source: '泳ぎすぎる', rule: 'v5', reasons: ['-sugiru']}, + {term: '泳ぐ', source: '泳ぎたい', rule: 'v5', reasons: ['-tai']}, + {term: '泳ぐ', source: '泳いだら', rule: 'v5', reasons: ['-tara']}, + {term: '泳ぐ', source: '泳いだり', rule: 'v5', reasons: ['-tari']}, + {term: '泳ぐ', source: '泳がず', rule: 'v5', reasons: ['-zu']}, + {term: '泳ぐ', source: '泳がぬ', rule: 'v5', reasons: ['-nu']}, + {term: '泳ぐ', source: '泳ぎ', rule: 'v5', reasons: ['masu stem']}, + {term: '泳ぐ', source: '泳ぎましょう', rule: 'v5', reasons: ['polite volitional']}, + {term: '泳ぐ', source: '泳ごう', rule: 'v5', reasons: ['volitional']}, + {term: '泳ぐ', source: '泳がされる', rule: 'v5', reasons: ['causative passive']}, + {term: '泳ぐ', source: '泳いどく', rule: 'v5', reasons: ['-toku']}, + {term: '泳ぐ', source: '泳いでいる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '泳ぐ', source: '泳いでおる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '泳ぐ', source: '泳いでる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '泳ぐ', source: '泳いでしまう', rule: 'v5', reasons: ['-te', '-shimau']} + ] + }, + { + category: '-su verbs', + valid: true, + tests: [ + {term: '話す', source: '話す', rule: 'v5', reasons: []}, + {term: '話す', source: '話します', rule: 'v5', reasons: ['polite']}, + {term: '話す', source: '話した', rule: 'v5', reasons: ['past']}, + {term: '話す', source: '話しました', rule: 'v5', reasons: ['polite past']}, + {term: '話す', source: '話して', rule: 'v5', reasons: ['-te']}, + {term: '話す', source: '話せる', rule: 'v5', reasons: ['potential']}, + {term: '話す', source: '話される', rule: 'v5', reasons: ['passive']}, + {term: '話す', source: '話させる', rule: 'v5', reasons: ['causative']}, + {term: '話す', source: '話させられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, + {term: '話す', source: '話せ', rule: 'v5', reasons: ['imperative']}, + {term: '話す', source: '話さない', rule: 'v5', reasons: ['negative']}, + {term: '話す', source: '話しません', rule: 'v5', reasons: ['polite negative']}, + {term: '話す', source: '話さなかった', rule: 'v5', reasons: ['negative', 'past']}, + {term: '話す', source: '話しませんでした', rule: 'v5', reasons: ['polite past negative']}, + {term: '話す', source: '話さなくて', rule: 'v5', reasons: ['negative', '-te']}, + {term: '話す', source: '話せない', rule: 'v5', reasons: ['potential', 'negative']}, + {term: '話す', source: '話されない', rule: 'v5', reasons: ['passive', 'negative']}, + {term: '話す', source: '話させない', rule: 'v5', reasons: ['causative', 'negative']}, + {term: '話す', source: '話させられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, + {term: '話す', source: '話すな', rule: 'v5', reasons: ['imperative negative']}, + + {term: '話す', source: '話せば', rule: 'v5', reasons: ['-ba']}, + {term: '話す', source: '話しちゃう', rule: 'v5', reasons: ['-chau']}, + {term: '話す', source: '話しちまう', rule: 'v5', reasons: ['-chimau']}, + {term: '話す', source: '話しなさい', rule: 'v5', reasons: ['-nasai']}, + {term: '話す', source: '話しそう', rule: 'v5', reasons: ['-sou']}, + {term: '話す', source: '話しすぎる', rule: 'v5', reasons: ['-sugiru']}, + {term: '話す', source: '話したい', rule: 'v5', reasons: ['-tai']}, + {term: '話す', source: '話したら', rule: 'v5', reasons: ['-tara']}, + {term: '話す', source: '話したり', rule: 'v5', reasons: ['-tari']}, + {term: '話す', source: '話さず', rule: 'v5', reasons: ['-zu']}, + {term: '話す', source: '話さぬ', rule: 'v5', reasons: ['-nu']}, + {term: '話す', source: '話し', rule: 'v5', reasons: ['masu stem']}, + {term: '話す', source: '話しましょう', rule: 'v5', reasons: ['polite volitional']}, + {term: '話す', source: '話そう', rule: 'v5', reasons: ['volitional']}, + // ['causative passive'] + {term: '話す', source: '話しとく', rule: 'v5', reasons: ['-toku']}, + {term: '話す', source: '話している', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '話す', source: '話しておる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '話す', source: '話してる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '話す', source: '話しとる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '話す', source: '話してしまう', rule: 'v5', reasons: ['-te', '-shimau']} + ] + }, + { + category: '-tsu verbs', + valid: true, + tests: [ + {term: '待つ', source: '待つ', rule: 'v5', reasons: []}, + {term: '待つ', source: '待ちます', rule: 'v5', reasons: ['polite']}, + {term: '待つ', source: '待った', rule: 'v5', reasons: ['past']}, + {term: '待つ', source: '待ちました', rule: 'v5', reasons: ['polite past']}, + {term: '待つ', source: '待って', rule: 'v5', reasons: ['-te']}, + {term: '待つ', source: '待てる', rule: 'v5', reasons: ['potential']}, + {term: '待つ', source: '待たれる', rule: 'v5', reasons: ['passive']}, + {term: '待つ', source: '待たせる', rule: 'v5', reasons: ['causative']}, + {term: '待つ', source: '待たせられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, + {term: '待つ', source: '待て', rule: 'v5', reasons: ['imperative']}, + {term: '待つ', source: '待たない', rule: 'v5', reasons: ['negative']}, + {term: '待つ', source: '待ちません', rule: 'v5', reasons: ['polite negative']}, + {term: '待つ', source: '待たなかった', rule: 'v5', reasons: ['negative', 'past']}, + {term: '待つ', source: '待ちませんでした', rule: 'v5', reasons: ['polite past negative']}, + {term: '待つ', source: '待たなくて', rule: 'v5', reasons: ['negative', '-te']}, + {term: '待つ', source: '待てない', rule: 'v5', reasons: ['potential', 'negative']}, + {term: '待つ', source: '待たれない', rule: 'v5', reasons: ['passive', 'negative']}, + {term: '待つ', source: '待たせない', rule: 'v5', reasons: ['causative', 'negative']}, + {term: '待つ', source: '待たせられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, + {term: '待つ', source: '待つな', rule: 'v5', reasons: ['imperative negative']}, + + {term: '待つ', source: '待てば', rule: 'v5', reasons: ['-ba']}, + {term: '待つ', source: '待っちゃう', rule: 'v5', reasons: ['-chau']}, + {term: '待つ', source: '待っちまう', rule: 'v5', reasons: ['-chimau']}, + {term: '待つ', source: '待ちなさい', rule: 'v5', reasons: ['-nasai']}, + {term: '待つ', source: '待ちそう', rule: 'v5', reasons: ['-sou']}, + {term: '待つ', source: '待ちすぎる', rule: 'v5', reasons: ['-sugiru']}, + {term: '待つ', source: '待ちたい', rule: 'v5', reasons: ['-tai']}, + {term: '待つ', source: '待ったら', rule: 'v5', reasons: ['-tara']}, + {term: '待つ', source: '待ったり', rule: 'v5', reasons: ['-tari']}, + {term: '待つ', source: '待たず', rule: 'v5', reasons: ['-zu']}, + {term: '待つ', source: '待たぬ', rule: 'v5', reasons: ['-nu']}, + {term: '待つ', source: '待ち', rule: 'v5', reasons: ['masu stem']}, + {term: '待つ', source: '待ちましょう', rule: 'v5', reasons: ['polite volitional']}, + {term: '待つ', source: '待とう', rule: 'v5', reasons: ['volitional']}, + {term: '待つ', source: '待たされる', rule: 'v5', reasons: ['causative passive']}, + {term: '待つ', source: '待っとく', rule: 'v5', reasons: ['-toku']}, + {term: '待つ', source: '待っている', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '待つ', source: '待っておる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '待つ', source: '待ってる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '待つ', source: '待っとる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '待つ', source: '待ってしまう', rule: 'v5', reasons: ['-te', '-shimau']} + ] + }, + { + category: '-nu verbs', + valid: true, + tests: [ + {term: '死ぬ', source: '死ぬ', rule: 'v5', reasons: []}, + {term: '死ぬ', source: '死にます', rule: 'v5', reasons: ['polite']}, + {term: '死ぬ', source: '死んだ', rule: 'v5', reasons: ['past']}, + {term: '死ぬ', source: '死にました', rule: 'v5', reasons: ['polite past']}, + {term: '死ぬ', source: '死んで', rule: 'v5', reasons: ['-te']}, + {term: '死ぬ', source: '死ねる', rule: 'v5', reasons: ['potential']}, + {term: '死ぬ', source: '死なれる', rule: 'v5', reasons: ['passive']}, + {term: '死ぬ', source: '死なせる', rule: 'v5', reasons: ['causative']}, + {term: '死ぬ', source: '死なせられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, + {term: '死ぬ', source: '死ね', rule: 'v5', reasons: ['imperative']}, + {term: '死ぬ', source: '死なない', rule: 'v5', reasons: ['negative']}, + {term: '死ぬ', source: '死にません', rule: 'v5', reasons: ['polite negative']}, + {term: '死ぬ', source: '死ななかった', rule: 'v5', reasons: ['negative', 'past']}, + {term: '死ぬ', source: '死にませんでした', rule: 'v5', reasons: ['polite past negative']}, + {term: '死ぬ', source: '死ななくて', rule: 'v5', reasons: ['negative', '-te']}, + {term: '死ぬ', source: '死ねない', rule: 'v5', reasons: ['potential', 'negative']}, + {term: '死ぬ', source: '死なれない', rule: 'v5', reasons: ['passive', 'negative']}, + {term: '死ぬ', source: '死なせない', rule: 'v5', reasons: ['causative', 'negative']}, + {term: '死ぬ', source: '死なせられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, + {term: '死ぬ', source: '死ぬな', rule: 'v5', reasons: ['imperative negative']}, + + {term: '死ぬ', source: '死ねば', rule: 'v5', reasons: ['-ba']}, + {term: '死ぬ', source: '死んじゃう', rule: 'v5', reasons: ['-chau']}, + {term: '死ぬ', source: '死んじまう', rule: 'v5', reasons: ['-chimau']}, + {term: '死ぬ', source: '死になさい', rule: 'v5', reasons: ['-nasai']}, + {term: '死ぬ', source: '死にそう', rule: 'v5', reasons: ['-sou']}, + {term: '死ぬ', source: '死にすぎる', rule: 'v5', reasons: ['-sugiru']}, + {term: '死ぬ', source: '死にたい', rule: 'v5', reasons: ['-tai']}, + {term: '死ぬ', source: '死んだら', rule: 'v5', reasons: ['-tara']}, + {term: '死ぬ', source: '死んだり', rule: 'v5', reasons: ['-tari']}, + {term: '死ぬ', source: '死なず', rule: 'v5', reasons: ['-zu']}, + {term: '死ぬ', source: '死なぬ', rule: 'v5', reasons: ['-nu']}, + {term: '死ぬ', source: '死に', rule: 'v5', reasons: ['masu stem']}, + {term: '死ぬ', source: '死にましょう', rule: 'v5', reasons: ['polite volitional']}, + {term: '死ぬ', source: '死のう', rule: 'v5', reasons: ['volitional']}, + {term: '死ぬ', source: '死なされる', rule: 'v5', reasons: ['causative passive']}, + {term: '死ぬ', source: '死んどく', rule: 'v5', reasons: ['-toku']}, + {term: '死ぬ', source: '死んでいる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '死ぬ', source: '死んでおる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '死ぬ', source: '死んでる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '死ぬ', source: '死んでしまう', rule: 'v5', reasons: ['-te', '-shimau']} + ] + }, + { + category: '-bu verbs', + valid: true, + tests: [ + {term: '遊ぶ', source: '遊ぶ', rule: 'v5', reasons: []}, + {term: '遊ぶ', source: '遊びます', rule: 'v5', reasons: ['polite']}, + {term: '遊ぶ', source: '遊んだ', rule: 'v5', reasons: ['past']}, + {term: '遊ぶ', source: '遊びました', rule: 'v5', reasons: ['polite past']}, + {term: '遊ぶ', source: '遊んで', rule: 'v5', reasons: ['-te']}, + {term: '遊ぶ', source: '遊べる', rule: 'v5', reasons: ['potential']}, + {term: '遊ぶ', source: '遊ばれる', rule: 'v5', reasons: ['passive']}, + {term: '遊ぶ', source: '遊ばせる', rule: 'v5', reasons: ['causative']}, + {term: '遊ぶ', source: '遊ばせられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, + {term: '遊ぶ', source: '遊べ', rule: 'v5', reasons: ['imperative']}, + {term: '遊ぶ', source: '遊ばない', rule: 'v5', reasons: ['negative']}, + {term: '遊ぶ', source: '遊びません', rule: 'v5', reasons: ['polite negative']}, + {term: '遊ぶ', source: '遊ばなかった', rule: 'v5', reasons: ['negative', 'past']}, + {term: '遊ぶ', source: '遊びませんでした', rule: 'v5', reasons: ['polite past negative']}, + {term: '遊ぶ', source: '遊ばなくて', rule: 'v5', reasons: ['negative', '-te']}, + {term: '遊ぶ', source: '遊べない', rule: 'v5', reasons: ['potential', 'negative']}, + {term: '遊ぶ', source: '遊ばれない', rule: 'v5', reasons: ['passive', 'negative']}, + {term: '遊ぶ', source: '遊ばせない', rule: 'v5', reasons: ['causative', 'negative']}, + {term: '遊ぶ', source: '遊ばせられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, + {term: '遊ぶ', source: '遊ぶな', rule: 'v5', reasons: ['imperative negative']}, + + {term: '遊ぶ', source: '遊べば', rule: 'v5', reasons: ['-ba']}, + {term: '遊ぶ', source: '遊んじゃう', rule: 'v5', reasons: ['-chau']}, + {term: '遊ぶ', source: '遊んじまう', rule: 'v5', reasons: ['-chimau']}, + {term: '遊ぶ', source: '遊びなさい', rule: 'v5', reasons: ['-nasai']}, + {term: '遊ぶ', source: '遊びそう', rule: 'v5', reasons: ['-sou']}, + {term: '遊ぶ', source: '遊びすぎる', rule: 'v5', reasons: ['-sugiru']}, + {term: '遊ぶ', source: '遊びたい', rule: 'v5', reasons: ['-tai']}, + {term: '遊ぶ', source: '遊んだら', rule: 'v5', reasons: ['-tara']}, + {term: '遊ぶ', source: '遊んだり', rule: 'v5', reasons: ['-tari']}, + {term: '遊ぶ', source: '遊ばず', rule: 'v5', reasons: ['-zu']}, + {term: '遊ぶ', source: '遊ばぬ', rule: 'v5', reasons: ['-nu']}, + {term: '遊ぶ', source: '遊び', rule: 'v5', reasons: ['masu stem']}, + {term: '遊ぶ', source: '遊びましょう', rule: 'v5', reasons: ['polite volitional']}, + {term: '遊ぶ', source: '遊ぼう', rule: 'v5', reasons: ['volitional']}, + {term: '遊ぶ', source: '遊ばされる', rule: 'v5', reasons: ['causative passive']}, + {term: '遊ぶ', source: '遊んどく', rule: 'v5', reasons: ['-toku']}, + {term: '遊ぶ', source: '遊んでいる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '遊ぶ', source: '遊んでおる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '遊ぶ', source: '遊んでる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '遊ぶ', source: '遊んでしまう', rule: 'v5', reasons: ['-te', '-shimau']} + ] + }, + { + category: '-mu verbs', + valid: true, + tests: [ + {term: '飲む', source: '飲む', rule: 'v5', reasons: []}, + {term: '飲む', source: '飲みます', rule: 'v5', reasons: ['polite']}, + {term: '飲む', source: '飲んだ', rule: 'v5', reasons: ['past']}, + {term: '飲む', source: '飲みました', rule: 'v5', reasons: ['polite past']}, + {term: '飲む', source: '飲んで', rule: 'v5', reasons: ['-te']}, + {term: '飲む', source: '飲める', rule: 'v5', reasons: ['potential']}, + {term: '飲む', source: '飲まれる', rule: 'v5', reasons: ['passive']}, + {term: '飲む', source: '飲ませる', rule: 'v5', reasons: ['causative']}, + {term: '飲む', source: '飲ませられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, + {term: '飲む', source: '飲め', rule: 'v5', reasons: ['imperative']}, + {term: '飲む', source: '飲まない', rule: 'v5', reasons: ['negative']}, + {term: '飲む', source: '飲みません', rule: 'v5', reasons: ['polite negative']}, + {term: '飲む', source: '飲まなかった', rule: 'v5', reasons: ['negative', 'past']}, + {term: '飲む', source: '飲みませんでした', rule: 'v5', reasons: ['polite past negative']}, + {term: '飲む', source: '飲まなくて', rule: 'v5', reasons: ['negative', '-te']}, + {term: '飲む', source: '飲めない', rule: 'v5', reasons: ['potential', 'negative']}, + {term: '飲む', source: '飲まれない', rule: 'v5', reasons: ['passive', 'negative']}, + {term: '飲む', source: '飲ませない', rule: 'v5', reasons: ['causative', 'negative']}, + {term: '飲む', source: '飲ませられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, + {term: '飲む', source: '飲むな', rule: 'v5', reasons: ['imperative negative']}, + + {term: '飲む', source: '飲めば', rule: 'v5', reasons: ['-ba']}, + {term: '飲む', source: '飲んじゃう', rule: 'v5', reasons: ['-chau']}, + {term: '飲む', source: '飲んじまう', rule: 'v5', reasons: ['-chimau']}, + {term: '飲む', source: '飲みなさい', rule: 'v5', reasons: ['-nasai']}, + {term: '飲む', source: '飲みそう', rule: 'v5', reasons: ['-sou']}, + {term: '飲む', source: '飲みすぎる', rule: 'v5', reasons: ['-sugiru']}, + {term: '飲む', source: '飲みたい', rule: 'v5', reasons: ['-tai']}, + {term: '飲む', source: '飲んだら', rule: 'v5', reasons: ['-tara']}, + {term: '飲む', source: '飲んだり', rule: 'v5', reasons: ['-tari']}, + {term: '飲む', source: '飲まず', rule: 'v5', reasons: ['-zu']}, + {term: '飲む', source: '飲まぬ', rule: 'v5', reasons: ['-nu']}, + {term: '飲む', source: '飲み', rule: 'v5', reasons: ['masu stem']}, + {term: '飲む', source: '飲みましょう', rule: 'v5', reasons: ['polite volitional']}, + {term: '飲む', source: '飲もう', rule: 'v5', reasons: ['volitional']}, + {term: '飲む', source: '飲まされる', rule: 'v5', reasons: ['causative passive']}, + {term: '飲む', source: '飲んどく', rule: 'v5', reasons: ['-toku']}, + {term: '飲む', source: '飲んでいる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '飲む', source: '飲んでおる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '飲む', source: '飲んでる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '飲む', source: '飲んでしまう', rule: 'v5', reasons: ['-te', '-shimau']} + ] + }, + { + category: 'godan verbs', + valid: true, + tests: [ + {term: '作る', source: '作る', rule: 'v5', reasons: []}, + {term: '作る', source: '作ります', rule: 'v5', reasons: ['polite']}, + {term: '作る', source: '作った', rule: 'v5', reasons: ['past']}, + {term: '作る', source: '作りました', rule: 'v5', reasons: ['polite past']}, + {term: '作る', source: '作って', rule: 'v5', reasons: ['-te']}, + {term: '作る', source: '作れる', rule: 'v5', reasons: ['potential']}, + {term: '作る', source: '作られる', rule: 'v5', reasons: ['passive']}, + {term: '作る', source: '作らせる', rule: 'v5', reasons: ['causative']}, + {term: '作る', source: '作らせられる', rule: 'v5', reasons: ['causative', 'potential or passive']}, + {term: '作る', source: '作れ', rule: 'v5', reasons: ['imperative']}, + {term: '作る', source: '作らない', rule: 'v5', reasons: ['negative']}, + {term: '作る', source: '作りません', rule: 'v5', reasons: ['polite negative']}, + {term: '作る', source: '作らなかった', rule: 'v5', reasons: ['negative', 'past']}, + {term: '作る', source: '作りませんでした', rule: 'v5', reasons: ['polite past negative']}, + {term: '作る', source: '作らなくて', rule: 'v5', reasons: ['negative', '-te']}, + {term: '作る', source: '作れない', rule: 'v5', reasons: ['potential', 'negative']}, + {term: '作る', source: '作られない', rule: 'v5', reasons: ['passive', 'negative']}, + {term: '作る', source: '作らせない', rule: 'v5', reasons: ['causative', 'negative']}, + {term: '作る', source: '作らせられない', rule: 'v5', reasons: ['causative', 'potential or passive', 'negative']}, + {term: '作る', source: '作るな', rule: 'v5', reasons: ['imperative negative']}, + + {term: '作る', source: '作れば', rule: 'v5', reasons: ['-ba']}, + {term: '作る', source: '作っちゃう', rule: 'v5', reasons: ['-chau']}, + {term: '作る', source: '作っちまう', rule: 'v5', reasons: ['-chimau']}, + {term: '作る', source: '作りなさい', rule: 'v5', reasons: ['-nasai']}, + {term: '作る', source: '作りそう', rule: 'v5', reasons: ['-sou']}, + {term: '作る', source: '作りすぎる', rule: 'v5', reasons: ['-sugiru']}, + {term: '作る', source: '作りたい', rule: 'v5', reasons: ['-tai']}, + {term: '作る', source: '作ったら', rule: 'v5', reasons: ['-tara']}, + {term: '作る', source: '作ったり', rule: 'v5', reasons: ['-tari']}, + {term: '作る', source: '作らず', rule: 'v5', reasons: ['-zu']}, + {term: '作る', source: '作らぬ', rule: 'v5', reasons: ['-nu']}, + {term: '作る', source: '作り', rule: 'v5', reasons: ['masu stem']}, + {term: '作る', source: '作りましょう', rule: 'v5', reasons: ['polite volitional']}, + {term: '作る', source: '作ろう', rule: 'v5', reasons: ['volitional']}, + {term: '作る', source: '作らされる', rule: 'v5', reasons: ['causative passive']}, + {term: '作る', source: '作っとく', rule: 'v5', reasons: ['-toku']}, + {term: '作る', source: '作っている', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '作る', source: '作っておる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '作る', source: '作ってる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '作る', source: '作っとる', rule: 'v5', reasons: ['-te', 'progressive or perfect']}, + {term: '作る', source: '作ってしまう', rule: 'v5', reasons: ['-te', '-shimau']} + ] + }, + { + category: 'irregular verbs', + valid: true, + tests: [ + {term: '為る', source: '為る', rule: 'vs', reasons: []}, + {term: '為る', source: '為ます', rule: 'vs', reasons: ['polite']}, + {term: '為る', source: '為た', rule: 'vs', reasons: ['past']}, + {term: '為る', source: '為ました', rule: 'vs', reasons: ['polite past']}, + {term: '為る', source: '為て', rule: 'vs', reasons: ['-te']}, + {term: '為る', source: '為られる', rule: 'vs', reasons: ['potential or passive']}, + {term: '為る', source: '為れる', rule: 'vs', reasons: ['passive']}, + {term: '為る', source: '為せる', rule: 'vs', reasons: ['causative']}, + {term: '為る', source: '為させる', rule: 'vs', reasons: ['causative']}, + {term: '為る', source: '為せられる', rule: 'vs', reasons: ['causative', 'potential or passive']}, + {term: '為る', source: '為させられる', rule: 'vs', reasons: ['causative', 'potential or passive']}, + {term: '為る', source: '為ろ', rule: 'vs', reasons: ['imperative']}, + {term: '為る', source: '為ない', rule: 'vs', reasons: ['negative']}, + {term: '為る', source: '為ません', rule: 'vs', reasons: ['polite negative']}, + {term: '為る', source: '為なかった', rule: 'vs', reasons: ['negative', 'past']}, + {term: '為る', source: '為ませんでした', rule: 'vs', reasons: ['polite past negative']}, + {term: '為る', source: '為なくて', rule: 'vs', reasons: ['negative', '-te']}, + {term: '為る', source: '為られない', rule: 'vs', reasons: ['potential or passive', 'negative']}, + {term: '為る', source: '為れない', rule: 'vs', reasons: ['passive', 'negative']}, + {term: '為る', source: '為せない', rule: 'vs', reasons: ['causative', 'negative']}, + {term: '為る', source: '為させない', rule: 'vs', reasons: ['causative', 'negative']}, + {term: '為る', source: '為せられない', rule: 'vs', reasons: ['causative', 'potential or passive', 'negative']}, + {term: '為る', source: '為させられない', rule: 'vs', reasons: ['causative', 'potential or passive', 'negative']}, + {term: '為る', source: '為るな', rule: 'vs', reasons: ['imperative negative']}, + + {term: '為る', source: '為れば', rule: 'vs', reasons: ['-ba']}, + {term: '為る', source: '為ちゃう', rule: 'vs', reasons: ['-chau']}, + {term: '為る', source: '為ちまう', rule: 'vs', reasons: ['-chimau']}, + {term: '為る', source: '為なさい', rule: 'vs', reasons: ['-nasai']}, + {term: '為る', source: '為そう', rule: 'vs', reasons: ['-sou']}, + {term: '為る', source: '為すぎる', rule: 'vs', reasons: ['-sugiru']}, + {term: '為る', source: '為たい', rule: 'vs', reasons: ['-tai']}, + {term: '為る', source: '為たら', rule: 'vs', reasons: ['-tara']}, + {term: '為る', source: '為たり', rule: 'vs', reasons: ['-tari']}, + {term: '為る', source: '為ず', rule: 'vs', reasons: ['-zu']}, + {term: '為る', source: '為ぬ', rule: 'vs', reasons: ['-nu']}, + // ['masu stem'] + {term: '為る', source: '為ましょう', rule: 'vs', reasons: ['polite volitional']}, + {term: '為る', source: '為よう', rule: 'vs', reasons: ['volitional']}, + // ['causative passive'] + {term: '為る', source: '為とく', rule: 'vs', reasons: ['-toku']}, + {term: '為る', source: '為ている', rule: 'vs', reasons: ['-te', 'progressive or perfect']}, + {term: '為る', source: '為ておる', rule: 'vs', reasons: ['-te', 'progressive or perfect']}, + {term: '為る', source: '為てる', rule: 'vs', reasons: ['-te', 'progressive or perfect']}, + {term: '為る', source: '為とる', rule: 'vs', reasons: ['-te', 'progressive or perfect']}, + {term: '為る', source: '為てしまう', rule: 'vs', reasons: ['-te', '-shimau']}, + + {term: 'する', source: 'する', rule: 'vs', reasons: []}, + {term: 'する', source: 'します', rule: 'vs', reasons: ['polite']}, + {term: 'する', source: 'した', rule: 'vs', reasons: ['past']}, + {term: 'する', source: 'しました', rule: 'vs', reasons: ['polite past']}, + {term: 'する', source: 'して', rule: 'vs', reasons: ['-te']}, + {term: 'する', source: 'できる', rule: 'vs', reasons: ['potential']}, + {term: 'する', source: '出来る', rule: 'vs', reasons: ['potential']}, + {term: 'する', source: 'せられる', rule: 'vs', reasons: ['potential or passive']}, + {term: 'する', source: 'される', rule: 'vs', reasons: ['passive']}, + {term: 'する', source: 'させる', rule: 'vs', reasons: ['causative']}, + {term: 'する', source: 'せさせる', rule: 'vs', reasons: ['causative']}, + {term: 'する', source: 'させられる', rule: 'vs', reasons: ['causative', 'potential or passive']}, + {term: 'する', source: 'せさせられる', rule: 'vs', reasons: ['causative', 'potential or passive']}, + {term: 'する', source: 'しろ', rule: 'vs', reasons: ['imperative']}, + {term: 'する', source: 'しない', rule: 'vs', reasons: ['negative']}, + {term: 'する', source: 'しません', rule: 'vs', reasons: ['polite negative']}, + {term: 'する', source: 'しなかった', rule: 'vs', reasons: ['negative', 'past']}, + {term: 'する', source: 'しませんでした', rule: 'vs', reasons: ['polite past negative']}, + {term: 'する', source: 'しなくて', rule: 'vs', reasons: ['negative', '-te']}, + {term: 'する', source: 'せられない', rule: 'vs', reasons: ['potential or passive', 'negative']}, + {term: 'する', source: 'されない', rule: 'vs', reasons: ['passive', 'negative']}, + {term: 'する', source: 'させない', rule: 'vs', reasons: ['causative', 'negative']}, + {term: 'する', source: 'せさせない', rule: 'vs', reasons: ['causative', 'negative']}, + {term: 'する', source: 'させられない', rule: 'vs', reasons: ['causative', 'potential or passive', 'negative']}, + {term: 'する', source: 'せさせられない', rule: 'vs', reasons: ['causative', 'potential or passive', 'negative']}, + {term: 'する', source: 'するな', rule: 'vs', reasons: ['imperative negative']}, + + {term: 'する', source: 'すれば', rule: 'vs', reasons: ['-ba']}, + {term: 'する', source: 'しちゃう', rule: 'vs', reasons: ['-chau']}, + {term: 'する', source: 'しちまう', rule: 'vs', reasons: ['-chimau']}, + {term: 'する', source: 'しなさい', rule: 'vs', reasons: ['-nasai']}, + {term: 'する', source: 'しそう', rule: 'vs', reasons: ['-sou']}, + {term: 'する', source: 'しすぎる', rule: 'vs', reasons: ['-sugiru']}, + {term: 'する', source: 'したい', rule: 'vs', reasons: ['-tai']}, + {term: 'する', source: 'したら', rule: 'vs', reasons: ['-tara']}, + {term: 'する', source: 'したり', rule: 'vs', reasons: ['-tari']}, + {term: 'する', source: 'せず', rule: 'vs', reasons: ['-zu']}, + {term: 'する', source: 'せぬ', rule: 'vs', reasons: ['-nu']}, + // ['masu stem'] + {term: 'する', source: 'しましょう', rule: 'vs', reasons: ['polite volitional']}, + {term: 'する', source: 'しよう', rule: 'vs', reasons: ['volitional']}, + // ['causative passive'] + {term: 'する', source: 'しとく', rule: 'vs', reasons: ['-toku']}, + {term: 'する', source: 'している', rule: 'vs', reasons: ['-te', 'progressive or perfect']}, + {term: 'する', source: 'しておる', rule: 'vs', reasons: ['-te', 'progressive or perfect']}, + {term: 'する', source: 'してる', rule: 'vs', reasons: ['-te', 'progressive or perfect']}, + {term: 'する', source: 'しとる', rule: 'vs', reasons: ['-te', 'progressive or perfect']}, + {term: 'する', source: 'してしまう', rule: 'vs', reasons: ['-te', '-shimau']}, + + {term: '来る', source: '来る', rule: 'vk', reasons: []}, + {term: '来る', source: '来ます', rule: 'vk', reasons: ['polite']}, + {term: '来る', source: '来た', rule: 'vk', reasons: ['past']}, + {term: '来る', source: '来ました', rule: 'vk', reasons: ['polite past']}, + {term: '来る', source: '来て', rule: 'vk', reasons: ['-te']}, + {term: '来る', source: '来られる', rule: 'vk', reasons: ['potential or passive']}, + {term: '来る', source: '来られる', rule: 'vk', reasons: ['potential or passive']}, + {term: '来る', source: '来させる', rule: 'vk', reasons: ['causative']}, + {term: '来る', source: '来させられる', rule: 'vk', reasons: ['causative', 'potential or passive']}, + {term: '来る', source: '来い', rule: 'vk', reasons: ['imperative']}, + {term: '来る', source: '来ない', rule: 'vk', reasons: ['negative']}, + {term: '来る', source: '来ません', rule: 'vk', reasons: ['polite negative']}, + {term: '来る', source: '来なかった', rule: 'vk', reasons: ['negative', 'past']}, + {term: '来る', source: '来ませんでした', rule: 'vk', reasons: ['polite past negative']}, + {term: '来る', source: '来なくて', rule: 'vk', reasons: ['negative', '-te']}, + {term: '来る', source: '来られない', rule: 'vk', reasons: ['potential or passive', 'negative']}, + {term: '来る', source: '来られない', rule: 'vk', reasons: ['potential or passive', 'negative']}, + {term: '来る', source: '来させない', rule: 'vk', reasons: ['causative', 'negative']}, + {term: '来る', source: '来させられない', rule: 'vk', reasons: ['causative', 'potential or passive', 'negative']}, + {term: '来る', source: '来るな', rule: 'vk', reasons: ['imperative negative']}, + + {term: '来る', source: '来れば', rule: 'vk', reasons: ['-ba']}, + {term: '来る', source: '来ちゃう', rule: 'vk', reasons: ['-chau']}, + {term: '来る', source: '来ちまう', rule: 'vk', reasons: ['-chimau']}, + {term: '来る', source: '来なさい', rule: 'vk', reasons: ['-nasai']}, + {term: '来る', source: '来そう', rule: 'vk', reasons: ['-sou']}, + {term: '来る', source: '来すぎる', rule: 'vk', reasons: ['-sugiru']}, + {term: '来る', source: '来たい', rule: 'vk', reasons: ['-tai']}, + {term: '来る', source: '来たら', rule: 'vk', reasons: ['-tara']}, + {term: '来る', source: '来たり', rule: 'vk', reasons: ['-tari']}, + {term: '来る', source: '来ず', rule: 'vk', reasons: ['-zu']}, + {term: '来る', source: '来ぬ', rule: 'vk', reasons: ['-nu']}, + {term: '来る', source: '来', rule: 'vk', reasons: ['masu stem']}, + {term: '来る', source: '来ましょう', rule: 'vk', reasons: ['polite volitional']}, + {term: '来る', source: '来よう', rule: 'vk', reasons: ['volitional']}, + // ['causative passive'] + {term: '来る', source: '来とく', rule: 'vk', reasons: ['-toku']}, + {term: '来る', source: '来ている', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, + {term: '来る', source: '来ておる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, + {term: '来る', source: '来てる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, + {term: '来る', source: '来とる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, + {term: '来る', source: '来てしまう', rule: 'vk', reasons: ['-te', '-shimau']}, + + {term: '來る', source: '來る', rule: 'vk', reasons: []}, + {term: '來る', source: '來ます', rule: 'vk', reasons: ['polite']}, + {term: '來る', source: '來た', rule: 'vk', reasons: ['past']}, + {term: '來る', source: '來ました', rule: 'vk', reasons: ['polite past']}, + {term: '來る', source: '來て', rule: 'vk', reasons: ['-te']}, + {term: '來る', source: '來られる', rule: 'vk', reasons: ['potential or passive']}, + {term: '來る', source: '來られる', rule: 'vk', reasons: ['potential or passive']}, + {term: '來る', source: '來させる', rule: 'vk', reasons: ['causative']}, + {term: '來る', source: '來させられる', rule: 'vk', reasons: ['causative', 'potential or passive']}, + {term: '來る', source: '來い', rule: 'vk', reasons: ['imperative']}, + {term: '來る', source: '來ない', rule: 'vk', reasons: ['negative']}, + {term: '來る', source: '來ません', rule: 'vk', reasons: ['polite negative']}, + {term: '來る', source: '來なかった', rule: 'vk', reasons: ['negative', 'past']}, + {term: '來る', source: '來ませんでした', rule: 'vk', reasons: ['polite past negative']}, + {term: '來る', source: '來なくて', rule: 'vk', reasons: ['negative', '-te']}, + {term: '來る', source: '來られない', rule: 'vk', reasons: ['potential or passive', 'negative']}, + {term: '來る', source: '來られない', rule: 'vk', reasons: ['potential or passive', 'negative']}, + {term: '來る', source: '來させない', rule: 'vk', reasons: ['causative', 'negative']}, + {term: '來る', source: '來させられない', rule: 'vk', reasons: ['causative', 'potential or passive', 'negative']}, + {term: '來る', source: '來るな', rule: 'vk', reasons: ['imperative negative']}, + + {term: '來る', source: '來れば', rule: 'vk', reasons: ['-ba']}, + {term: '來る', source: '來ちゃう', rule: 'vk', reasons: ['-chau']}, + {term: '來る', source: '來ちまう', rule: 'vk', reasons: ['-chimau']}, + {term: '來る', source: '來なさい', rule: 'vk', reasons: ['-nasai']}, + {term: '來る', source: '來そう', rule: 'vk', reasons: ['-sou']}, + {term: '來る', source: '來すぎる', rule: 'vk', reasons: ['-sugiru']}, + {term: '來る', source: '來たい', rule: 'vk', reasons: ['-tai']}, + {term: '來る', source: '來たら', rule: 'vk', reasons: ['-tara']}, + {term: '來る', source: '來たり', rule: 'vk', reasons: ['-tari']}, + {term: '來る', source: '來ず', rule: 'vk', reasons: ['-zu']}, + {term: '來る', source: '來ぬ', rule: 'vk', reasons: ['-nu']}, + {term: '來る', source: '來', rule: 'vk', reasons: ['masu stem']}, + {term: '來る', source: '來ましょう', rule: 'vk', reasons: ['polite volitional']}, + {term: '來る', source: '來よう', rule: 'vk', reasons: ['volitional']}, + // ['causative passive'] + {term: '來る', source: '來とく', rule: 'vk', reasons: ['-toku']}, + {term: '來る', source: '來ている', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, + {term: '來る', source: '來ておる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, + {term: '來る', source: '來てる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, + {term: '來る', source: '來とる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, + {term: '來る', source: '來てしまう', rule: 'vk', reasons: ['-te', '-shimau']}, + + {term: 'くる', source: 'くる', rule: 'vk', reasons: []}, + {term: 'くる', source: 'きます', rule: 'vk', reasons: ['polite']}, + {term: 'くる', source: 'きた', rule: 'vk', reasons: ['past']}, + {term: 'くる', source: 'きました', rule: 'vk', reasons: ['polite past']}, + {term: 'くる', source: 'きて', rule: 'vk', reasons: ['-te']}, + {term: 'くる', source: 'こられる', rule: 'vk', reasons: ['potential or passive']}, + {term: 'くる', source: 'こられる', rule: 'vk', reasons: ['potential or passive']}, + {term: 'くる', source: 'こさせる', rule: 'vk', reasons: ['causative']}, + {term: 'くる', source: 'こさせられる', rule: 'vk', reasons: ['causative', 'potential or passive']}, + {term: 'くる', source: 'こい', rule: 'vk', reasons: ['imperative']}, + {term: 'くる', source: 'こない', rule: 'vk', reasons: ['negative']}, + {term: 'くる', source: 'きません', rule: 'vk', reasons: ['polite negative']}, + {term: 'くる', source: 'こなかった', rule: 'vk', reasons: ['negative', 'past']}, + {term: 'くる', source: 'きませんでした', rule: 'vk', reasons: ['polite past negative']}, + {term: 'くる', source: 'こなくて', rule: 'vk', reasons: ['negative', '-te']}, + {term: 'くる', source: 'こられない', rule: 'vk', reasons: ['potential or passive', 'negative']}, + {term: 'くる', source: 'こられない', rule: 'vk', reasons: ['potential or passive', 'negative']}, + {term: 'くる', source: 'こさせない', rule: 'vk', reasons: ['causative', 'negative']}, + {term: 'くる', source: 'こさせられない', rule: 'vk', reasons: ['causative', 'potential or passive', 'negative']}, + {term: 'くる', source: 'くるな', rule: 'vk', reasons: ['imperative negative']}, + + {term: 'くる', source: 'くれば', rule: 'vk', reasons: ['-ba']}, + {term: 'くる', source: 'きちゃう', rule: 'vk', reasons: ['-chau']}, + {term: 'くる', source: 'きちまう', rule: 'vk', reasons: ['-chimau']}, + {term: 'くる', source: 'きなさい', rule: 'vk', reasons: ['-nasai']}, + {term: 'くる', source: 'きそう', rule: 'vk', reasons: ['-sou']}, + {term: 'くる', source: 'きすぎる', rule: 'vk', reasons: ['-sugiru']}, + {term: 'くる', source: 'きたい', rule: 'vk', reasons: ['-tai']}, + {term: 'くる', source: 'きたら', rule: 'vk', reasons: ['-tara']}, + {term: 'くる', source: 'きたり', rule: 'vk', reasons: ['-tari']}, + {term: 'くる', source: 'こず', rule: 'vk', reasons: ['-zu']}, + {term: 'くる', source: 'こぬ', rule: 'vk', reasons: ['-nu']}, + {term: 'くる', source: 'き', rule: 'vk', reasons: ['masu stem']}, + {term: 'くる', source: 'きましょう', rule: 'vk', reasons: ['polite volitional']}, + {term: 'くる', source: 'こよう', rule: 'vk', reasons: ['volitional']}, + // ['causative passive'] + {term: 'くる', source: 'きとく', rule: 'vk', reasons: ['-toku']}, + {term: 'くる', source: 'きている', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, + {term: 'くる', source: 'きておる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, + {term: 'くる', source: 'きてる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, + {term: 'くる', source: 'きとる', rule: 'vk', reasons: ['-te', 'progressive or perfect']}, + {term: 'くる', source: 'きてしまう', rule: 'vk', reasons: ['-te', '-shimau']} + ] + }, + { + category: '-zuru verbs', + valid: true, + tests: [ + {term: '論ずる', source: '論ずる', rule: 'vz', reasons: []}, + {term: '論ずる', source: '論じます', rule: 'vz', reasons: ['polite']}, + {term: '論ずる', source: '論じた', rule: 'vz', reasons: ['past']}, + {term: '論ずる', source: '論じました', rule: 'vz', reasons: ['polite past']}, + {term: '論ずる', source: '論じて', rule: 'vz', reasons: ['-te']}, + {term: '論ずる', source: '論ぜられる', rule: 'vz', reasons: ['potential or passive']}, + {term: '論ずる', source: '論ざれる', rule: 'vz', reasons: ['potential or passive']}, + {term: '論ずる', source: '論じされる', rule: 'vz', reasons: ['passive']}, + {term: '論ずる', source: '論ぜされる', rule: 'vz', reasons: ['passive']}, + {term: '論ずる', source: '論じさせる', rule: 'vz', reasons: ['causative']}, + {term: '論ずる', source: '論ぜさせる', rule: 'vz', reasons: ['causative']}, + {term: '論ずる', source: '論じさせられる', rule: 'vz', reasons: ['causative', 'potential or passive']}, + {term: '論ずる', source: '論ぜさせられる', rule: 'vz', reasons: ['causative', 'potential or passive']}, + {term: '論ずる', source: '論じろ', rule: 'vz', reasons: ['imperative']}, + {term: '論ずる', source: '論じない', rule: 'vz', reasons: ['negative']}, + {term: '論ずる', source: '論じません', rule: 'vz', reasons: ['polite negative']}, + {term: '論ずる', source: '論じなかった', rule: 'vz', reasons: ['negative', 'past']}, + {term: '論ずる', source: '論じませんでした', rule: 'vz', reasons: ['polite past negative']}, + {term: '論ずる', source: '論じなくて', rule: 'vz', reasons: ['negative', '-te']}, + {term: '論ずる', source: '論ぜられない', rule: 'vz', reasons: ['potential or passive', 'negative']}, + {term: '論ずる', source: '論じされない', rule: 'vz', reasons: ['passive', 'negative']}, + {term: '論ずる', source: '論ぜされない', rule: 'vz', reasons: ['passive', 'negative']}, + {term: '論ずる', source: '論じさせない', rule: 'vz', reasons: ['causative', 'negative']}, + {term: '論ずる', source: '論ぜさせない', rule: 'vz', reasons: ['causative', 'negative']}, + {term: '論ずる', source: '論じさせられない', rule: 'vz', reasons: ['causative', 'potential or passive', 'negative']}, + {term: '論ずる', source: '論ぜさせられない', rule: 'vz', reasons: ['causative', 'potential or passive', 'negative']}, + {term: '論ずる', source: '論ずるな', rule: 'vz', reasons: ['imperative negative']}, + + {term: '論ずる', source: '論ずれば', rule: 'vz', reasons: ['-ba']}, + {term: '論ずる', source: '論じちゃう', rule: 'vz', reasons: ['-chau']}, + {term: '論ずる', source: '論じちまう', rule: 'vz', reasons: ['-chimau']}, + {term: '論ずる', source: '論じなさい', rule: 'vz', reasons: ['-nasai']}, + {term: '論ずる', source: '論じそう', rule: 'vz', reasons: ['-sou']}, + {term: '論ずる', source: '論じすぎる', rule: 'vz', reasons: ['-sugiru']}, + {term: '論ずる', source: '論じたい', rule: 'vz', reasons: ['-tai']}, + {term: '論ずる', source: '論じたら', rule: 'vz', reasons: ['-tara']}, + {term: '論ずる', source: '論じたり', rule: 'vz', reasons: ['-tari']}, + {term: '論ずる', source: '論ぜず', rule: 'vz', reasons: ['-zu']}, + {term: '論ずる', source: '論ぜぬ', rule: 'vz', reasons: ['-nu']}, + // ['masu stem'] + {term: '論ずる', source: '論じましょう', rule: 'vz', reasons: ['polite volitional']}, + {term: '論ずる', source: '論じよう', rule: 'vz', reasons: ['volitional']}, + // ['causative passive'] + {term: '論ずる', source: '論じとく', rule: 'vz', reasons: ['-toku']}, + {term: '論ずる', source: '論じている', rule: 'vz', reasons: ['-te', 'progressive or perfect']}, + {term: '論ずる', source: '論じておる', rule: 'vz', reasons: ['-te', 'progressive or perfect']}, + {term: '論ずる', source: '論じてる', rule: 'vz', reasons: ['-te', 'progressive or perfect']}, + {term: '論ずる', source: '論じとる', rule: 'vz', reasons: ['-te', 'progressive or perfect']}, + {term: '論ずる', source: '論じてしまう', rule: 'vz', reasons: ['-te', '-shimau']} + ] + }, + { + category: '-e verbs', + valid: true, + tests: [ + {term: 'すごい', source: 'すげえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'やばい', source: 'やべえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'うるさい', source: 'うるせえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'ひどい', source: 'ひでえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'ない', source: 'ねえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'できる', source: 'できねえ', rule: 'v1', reasons: ['negative', '-e']}, + {term: 'しんじる', source: 'しんじねえ', rule: 'v1', reasons: ['negative', '-e']}, + {term: 'さむい', source: 'さめえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'さむい', source: 'さみい', rule: 'adj-i', reasons: ['-e']}, + {term: 'あつい', source: 'あちぇえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'あつい', source: 'あちい', rule: 'adj-i', reasons: ['-e']}, + {term: 'やすい', source: 'やせえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'たかい', source: 'たけえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'かわいい', source: 'かわええ', rule: 'adj-i', reasons: ['-e']}, + {term: 'つよい', source: 'ついぇえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'こわい', source: 'こうぇえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'みじかい', source: 'みじけえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'ながい', source: 'なげえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'くさい', source: 'くせえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'うまい', source: 'うめえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'でかい', source: 'でけえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'まずい', source: 'まっぜえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'ちっちゃい', source: 'ちっちぇえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'あかい', source: 'あけえ', rule: 'adj-i', reasons: ['-e']}, + {term: 'こわい', source: 'こええ', rule: 'adj-i', reasons: ['-e']}, + {term: 'つよい', source: 'つええ', rule: 'adj-i', reasons: ['-e']} + ] + }, + { + category: 'irregular verbs', + valid: false, + tests: [ + {term: 'する', source: 'すます', rule: 'vs', reasons: null}, + {term: 'する', source: 'すた', rule: 'vs', reasons: null}, + {term: 'する', source: 'すました', rule: 'vs', reasons: null}, + {term: 'する', source: 'すて', rule: 'vs', reasons: null}, + {term: 'する', source: 'すれる', rule: 'vs', reasons: null}, + {term: 'する', source: 'すせる', rule: 'vs', reasons: null}, + {term: 'する', source: 'すせられる', rule: 'vs', reasons: null}, + {term: 'する', source: 'すろ', rule: 'vs', reasons: null}, + {term: 'する', source: 'すない', rule: 'vs', reasons: null}, + {term: 'する', source: 'すません', rule: 'vs', reasons: null}, + {term: 'する', source: 'すなかった', rule: 'vs', reasons: null}, + {term: 'する', source: 'すませんでした', rule: 'vs', reasons: null}, + {term: 'する', source: 'すなくて', rule: 'vs', reasons: null}, + {term: 'する', source: 'すれない', rule: 'vs', reasons: null}, + {term: 'する', source: 'すせない', rule: 'vs', reasons: null}, + {term: 'する', source: 'すせられない', rule: 'vs', reasons: null}, + + {term: 'くる', source: 'くます', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くた', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くました', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くて', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くられる', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くられる', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くさせる', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くさせられる', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くい', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くない', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くません', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くなかった', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くませんでした', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くなくて', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くられない', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くられない', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くさせない', rule: 'vk', reasons: null}, + {term: 'くる', source: 'くさせられない', rule: 'vk', reasons: null} + ] + }, + { + category: 'uncommon irregular verbs', + valid: true, + tests: [ + {term: 'のたまう', source: 'のたもうて', rule: 'v5', reasons: ['-te']}, + {term: 'のたまう', source: 'のたもうた', rule: 'v5', reasons: ['past']}, + {term: 'のたまう', source: 'のたもうたら', rule: 'v5', reasons: ['-tara']}, + {term: 'のたまう', source: 'のたもうたり', rule: 'v5', reasons: ['-tari']}, + + {term: 'おう', source: 'おうて', rule: 'v5', reasons: ['-te']}, + {term: 'こう', source: 'こうて', rule: 'v5', reasons: ['-te']}, + {term: 'そう', source: 'そうて', rule: 'v5', reasons: ['-te']}, + {term: 'とう', source: 'とうて', rule: 'v5', reasons: ['-te']}, + {term: '請う', source: '請うて', rule: 'v5', reasons: ['-te']}, + {term: '乞う', source: '乞うて', rule: 'v5', reasons: ['-te']}, + {term: '恋う', source: '恋うて', rule: 'v5', reasons: ['-te']}, + {term: '問う', source: '問うて', rule: 'v5', reasons: ['-te']}, + {term: '負う', source: '負うて', rule: 'v5', reasons: ['-te']}, + {term: '沿う', source: '沿うて', rule: 'v5', reasons: ['-te']}, + {term: '添う', source: '添うて', rule: 'v5', reasons: ['-te']}, + {term: '副う', source: '副うて', rule: 'v5', reasons: ['-te']}, + {term: '厭う', source: '厭うて', rule: 'v5', reasons: ['-te']}, + + {term: 'おう', source: 'おうた', rule: 'v5', reasons: ['past']}, + {term: 'こう', source: 'こうた', rule: 'v5', reasons: ['past']}, + {term: 'そう', source: 'そうた', rule: 'v5', reasons: ['past']}, + {term: 'とう', source: 'とうた', rule: 'v5', reasons: ['past']}, + {term: '請う', source: '請うた', rule: 'v5', reasons: ['past']}, + {term: '乞う', source: '乞うた', rule: 'v5', reasons: ['past']}, + {term: '恋う', source: '恋うた', rule: 'v5', reasons: ['past']}, + {term: '問う', source: '問うた', rule: 'v5', reasons: ['past']}, + {term: '負う', source: '負うた', rule: 'v5', reasons: ['past']}, + {term: '沿う', source: '沿うた', rule: 'v5', reasons: ['past']}, + {term: '添う', source: '添うた', rule: 'v5', reasons: ['past']}, + {term: '副う', source: '副うた', rule: 'v5', reasons: ['past']}, + {term: '厭う', source: '厭うた', rule: 'v5', reasons: ['past']}, + + {term: 'おう', source: 'おうたら', rule: 'v5', reasons: ['-tara']}, + {term: 'こう', source: 'こうたら', rule: 'v5', reasons: ['-tara']}, + {term: 'そう', source: 'そうたら', rule: 'v5', reasons: ['-tara']}, + {term: 'とう', source: 'とうたら', rule: 'v5', reasons: ['-tara']}, + {term: '請う', source: '請うたら', rule: 'v5', reasons: ['-tara']}, + {term: '乞う', source: '乞うたら', rule: 'v5', reasons: ['-tara']}, + {term: '恋う', source: '恋うたら', rule: 'v5', reasons: ['-tara']}, + {term: '問う', source: '問うたら', rule: 'v5', reasons: ['-tara']}, + {term: '負う', source: '負うたら', rule: 'v5', reasons: ['-tara']}, + {term: '沿う', source: '沿うたら', rule: 'v5', reasons: ['-tara']}, + {term: '添う', source: '添うたら', rule: 'v5', reasons: ['-tara']}, + {term: '副う', source: '副うたら', rule: 'v5', reasons: ['-tara']}, + {term: '厭う', source: '厭うたら', rule: 'v5', reasons: ['-tara']}, + + {term: 'おう', source: 'おうたり', rule: 'v5', reasons: ['-tari']}, + {term: 'こう', source: 'こうたり', rule: 'v5', reasons: ['-tari']}, + {term: 'そう', source: 'そうたり', rule: 'v5', reasons: ['-tari']}, + {term: 'とう', source: 'とうたり', rule: 'v5', reasons: ['-tari']}, + {term: '請う', source: '請うたり', rule: 'v5', reasons: ['-tari']}, + {term: '乞う', source: '乞うたり', rule: 'v5', reasons: ['-tari']}, + {term: '恋う', source: '恋うたり', rule: 'v5', reasons: ['-tari']}, + {term: '問う', source: '問うたり', rule: 'v5', reasons: ['-tari']}, + {term: '負う', source: '負うたり', rule: 'v5', reasons: ['-tari']}, + {term: '沿う', source: '沿うたり', rule: 'v5', reasons: ['-tari']}, + {term: '添う', source: '添うたり', rule: 'v5', reasons: ['-tari']}, + {term: '副う', source: '副うたり', rule: 'v5', reasons: ['-tari']}, + {term: '厭う', source: '厭うたり', rule: 'v5', reasons: ['-tari']} + ] + }, + { + category: 'combinations', + valid: true, + tests: [ + {term: '抱き抱える', source: '抱き抱えていなければ', rule: 'v1', reasons: ['-te', 'progressive or perfect', 'negative', '-ba']}, + {term: '抱きかかえる', source: '抱きかかえていなければ', rule: 'v1', reasons: ['-te', 'progressive or perfect', 'negative', '-ba']}, + {term: '打ち込む', source: '打ち込んでいませんでした', rule: 'v5', reasons: ['-te', 'progressive or perfect', 'polite past negative']}, + {term: '食べる', source: '食べさせられたくなかった', rule: 'v1', reasons: ['causative', 'potential or passive', '-tai', 'negative', 'past']} + ] + }, + { + category: 'kawaii (this leads to infinite expansions)', + valid: false, + tests: [ + {term: 'かわいい', source: 'かわいげ', rule: 'adj-i', reasons: ['-ge']}, + {term: '可愛い', source: 'かわいげ', rule: 'adj-i', reasons: ['-ge']} + ] + }, + { + category: 'incorrect -te rule chain', + valid: false, + tests: [ + {term: '食べる', source: '食べて', rule: null, reasons: ['-te', 'progressive or perfect', 'masu stem']} + ] + } + ]; + /* eslint-enable no-multi-spaces */ + + /** @type {import('language-transformer').LanguageTransformDescriptor} */ + const descriptor = parseJson(fs.readFileSync(path.join(dirname, '..', 'ext', 'data/language/japanese-transforms.json'), {encoding: 'utf8'})); + const languageTransformer = new LanguageTransformer(); + languageTransformer.addDescriptor(descriptor); + + describe('deinflections', () => { + // for (const {valid, tests} of data) { + describe.each(data)('$category', ({valid, tests}) => { + for (const {source, term, rule, reasons} of tests) { + const {has} = hasTermReasons(languageTransformer, source, term, rule, reasons); + let message = `${source} ${valid ? 'has' : 'does not have'} term candidate ${JSON.stringify(term)}`; + if (typeof rule !== 'undefined') { + message += ` with rule ${JSON.stringify(rule)}`; + } + if (reasons !== null) { + message += (typeof rule !== 'undefined' ? ' and' : ' with'); + message += ` reasons ${JSON.stringify(reasons)}`; + } + test(`${message}`, () => { + expect(has).toStrictEqual(valid); + }); + } + }); + }); +} + + +/** */ +function main() { + testDeinflections(); +} + +main(); diff --git a/types/ext/deinflector.d.ts b/types/ext/deinflector.d.ts deleted file mode 100644 index 18d0f04a..00000000 --- a/types/ext/deinflector.d.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2023-2024 Yomitan Authors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import type * as TranslationInternal from './translation-internal'; - -export type ReasonTypeRaw = 'v1' | 'v1d' | 'v1p' | 'v5' | 'vs' | 'vk' | 'vz' | 'adj-i' | 'iru'; - -export type ReasonsRaw = { - [reason: string]: ReasonRaw[]; -}; - -export type ReasonRaw = { - kanaIn: string; - kanaOut: string; - rulesIn: ReasonTypeRaw[]; - rulesOut: ReasonTypeRaw[]; -}; - -export type ReasonVariant = [ - kanaIn: string, - kanaOut: string, - rulesIn: TranslationInternal.DeinflectionRuleFlags, - rulesOut: TranslationInternal.DeinflectionRuleFlags, -]; - -export type Reason = [ - reason: string, - variants: ReasonVariant[], -]; diff --git a/types/ext/language-transformer-internal.d.ts b/types/ext/language-transformer-internal.d.ts new file mode 100644 index 00000000..cb0899e9 --- /dev/null +++ b/types/ext/language-transformer-internal.d.ts @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 Yomitan Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +export type Transform = { + name: string; + rules: Rule[]; +}; + +export type Rule = { + suffixIn: string; + suffixOut: string; + conditionsIn: number; + conditionsOut: number; +}; + +export type TransformedText = { + text: string; + conditions: number; + trace: Trace; +}; + +export type Trace = TraceFrame[]; + +export type TraceFrame = { + transform: string; + ruleIndex: number; +}; diff --git a/types/ext/language-transformer.d.ts b/types/ext/language-transformer.d.ts new file mode 100644 index 00000000..08c7a3dc --- /dev/null +++ b/types/ext/language-transformer.d.ts @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2024 Yomitan Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +export type LanguageTransformDescriptor = { + language: string; + conditions: ConditionMapObject; + transforms: Transform[]; +}; + +export type ConditionMapObject = { + [type: string]: Condition; +}; + +export type ConditionMapEntry = [type: string, condition: Condition]; + +export type ConditionMapEntries = ConditionMapEntry[]; + +export type Condition = { + name: string; + partsOfSpeech: string[]; + i18n?: RuleI18n[]; + subConditions?: string[]; +}; + +export type RuleI18n = { + language: string; + name: string; +}; + +export type Transform = { + name: string; + description?: string; + i18n?: TransformI18n[]; + rules: Rule[]; +}; + +export type TransformI18n = { + language: string; + name: string; + description?: string; +}; + +export type Rule = { + suffixIn: string; + suffixOut: string; + conditionsIn: string[]; + conditionsOut: string[]; +}; diff --git a/types/ext/offscreen.d.ts b/types/ext/offscreen.d.ts index a721c1b9..443e0b64 100644 --- a/types/ext/offscreen.d.ts +++ b/types/ext/offscreen.d.ts @@ -15,7 +15,6 @@ * along with this program. If not, see . */ -import type * as Deinflector from './deinflector'; import type * as Dictionary from './dictionary'; import type * as DictionaryDatabase from './dictionary-database'; import type * as DictionaryImporter from './dictionary-importer'; @@ -30,6 +29,7 @@ import type { ApiReturn as BaseApiReturn, ApiNames as BaseApiNames, } from './api-map'; +import type {LanguageTransformDescriptor} from './language-transformer'; type ApiSurface = { databasePrepareOffscreen: { @@ -52,7 +52,7 @@ type ApiSurface = { }; translatorPrepareOffscreen: { params: { - deinflectionReasons: Deinflector.ReasonsRaw; + descriptor: LanguageTransformDescriptor; }; return: void; }; diff --git a/types/ext/translation-internal.d.ts b/types/ext/translation-internal.d.ts index ada611d9..82704c54 100644 --- a/types/ext/translation-internal.d.ts +++ b/types/ext/translation-internal.d.ts @@ -39,28 +39,11 @@ export type TextDeinflectionOptionsArrays = [ emphatic: [collapseEmphatic: boolean, collapseEmphaticFull: boolean][], ]; -export enum DeinflectionRuleFlags { - None = 0x0, - VerbIchidan = 0b00000001, - VerbGodan = 0b00000010, - VerbSuru = 0b00000100, - VerbKuru = 0b00001000, - VerbZuru = 0b00010000, - AdjectiveI = 0b00100000, - IruEndingIntermediate = 0b01000000, -} - -export type Deinflection = { - term: string; - rules: DeinflectionRuleFlags; - reasons: Dictionary.InflectionRuleChain; -}; - export type DatabaseDeinflection = { originalText: string; transformedText: string; deinflectedText: string; - rules: DeinflectionRuleFlags; + conditions: number; inflectionRuleChainCandidates: Dictionary.InflectionRuleChainCandidate[]; databaseEntries: DictionaryDatabase.TermEntry[]; }; -- cgit v1.2.3