henkan 2.0.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/index.cjs.js +621 -694
  2. package/dist/index.cjs.js.map +2 -2
  3. package/dist/index.mjs +615 -689
  4. package/dist/index.mjs.map +2 -2
  5. package/dist/types/constants.d.ts.map +1 -1
  6. package/dist/types/types.d.ts +40 -19
  7. package/dist/types/types.d.ts.map +1 -1
  8. package/dist/types/utils.d.ts +32 -24
  9. package/dist/types/utils.d.ts.map +1 -1
  10. package/docs/api/README.md +4 -1
  11. package/docs/api/functions/capitalizeString.md +1 -1
  12. package/docs/api/functions/convertJMdict.md +1 -1
  13. package/docs/api/functions/convertJawiktionaryAsync.md +1 -1
  14. package/docs/api/functions/convertJawiktionarySync.md +1 -1
  15. package/docs/api/functions/convertKanjiDic.md +1 -1
  16. package/docs/api/functions/convertKradFile.md +1 -1
  17. package/docs/api/functions/convertRadkFile.md +1 -1
  18. package/docs/api/functions/convertTanakaCorpus.md +1 -1
  19. package/docs/api/functions/convertTanakaCorpusWithFurigana.md +1 -1
  20. package/docs/api/functions/generateAnkiNote.md +1 -1
  21. package/docs/api/functions/generateAnkiNotesFile.md +1 -1
  22. package/docs/api/functions/getKanji.md +7 -7
  23. package/docs/api/functions/getKanjiExtended.md +6 -6
  24. package/docs/api/functions/getValidForms.md +39 -0
  25. package/docs/api/functions/getWord.md +9 -9
  26. package/docs/api/functions/getWordDefinitions.md +1 -1
  27. package/docs/api/functions/getWordDefinitionsWithFurigana.md +1 -1
  28. package/docs/api/functions/isObjectArray.md +27 -0
  29. package/docs/api/functions/isStringArray.md +2 -2
  30. package/docs/api/functions/isValidArrayWithFirstElement.md +2 -2
  31. package/docs/api/functions/shuffleArray.md +1 -1
  32. package/docs/api/interfaces/DefaultNoteInfo.md +4 -4
  33. package/docs/api/interfaces/Definition.md +4 -4
  34. package/docs/api/interfaces/DictKanji.md +5 -5
  35. package/docs/api/interfaces/DictKanjiForm.md +4 -4
  36. package/docs/api/interfaces/DictKanjiMisc.md +5 -5
  37. package/docs/api/interfaces/DictKanjiReading.md +3 -3
  38. package/docs/api/interfaces/DictKanjiReadingMeaning.md +3 -3
  39. package/docs/api/interfaces/DictKanjiReadingMeaningGroup.md +3 -3
  40. package/docs/api/interfaces/DictKanjiWithRadicals.md +3 -3
  41. package/docs/api/interfaces/DictMeaning.md +15 -15
  42. package/docs/api/interfaces/DictRadical.md +4 -4
  43. package/docs/api/interfaces/DictReading.md +5 -5
  44. package/docs/api/interfaces/DictWord.md +9 -9
  45. package/docs/api/interfaces/ExamplePart.md +8 -8
  46. package/docs/api/interfaces/GlossSpecificNumber.md +4 -4
  47. package/docs/api/interfaces/Grammar.md +15 -15
  48. package/docs/api/interfaces/GrammarMeaning.md +3 -3
  49. package/docs/api/interfaces/JaWiktionaryEntry.md +8 -20
  50. package/docs/api/interfaces/Kana.md +11 -11
  51. package/docs/api/interfaces/Kanji.md +24 -24
  52. package/docs/api/interfaces/KanjiComponent.md +3 -3
  53. package/docs/api/interfaces/KanjiForm.md +4 -4
  54. package/docs/api/interfaces/NoteAndTag.md +3 -3
  55. package/docs/api/interfaces/NoteHeaderKeys.md +7 -7
  56. package/docs/api/interfaces/Phrase.md +5 -5
  57. package/docs/api/interfaces/Radical.md +16 -16
  58. package/docs/api/interfaces/Reading.md +5 -5
  59. package/docs/api/interfaces/ReadingsKanjiFormsPair.md +31 -0
  60. package/docs/api/interfaces/ResultEntry.md +7 -7
  61. package/docs/api/interfaces/TanakaExample.md +7 -7
  62. package/docs/api/interfaces/Translation.md +3 -3
  63. package/docs/api/interfaces/UsefulRegExps.md +8 -8
  64. package/docs/api/interfaces/Word.md +15 -15
  65. package/docs/api/interfaces/WordDefinitionPair.md +4 -4
  66. package/docs/api/type-aliases/Dict.md +1 -1
  67. package/docs/api/type-aliases/DictTranslation.md +1 -1
  68. package/docs/api/type-aliases/EntryType.md +1 -1
  69. package/docs/api/type-aliases/Result.md +1 -1
  70. package/docs/api/type-aliases/StringNumber.md +13 -0
  71. package/package.json +2 -2
  72. package/docs/api/functions/isValidArray.md +0 -27
package/dist/index.cjs.js CHANGED
@@ -43,15 +43,16 @@ __export(index_exports, {
43
43
  generateAnkiNotesFile: () => generateAnkiNotesFile,
44
44
  getKanji: () => getKanji,
45
45
  getKanjiExtended: () => getKanjiExtended,
46
+ getValidForms: () => getValidForms,
46
47
  getWord: () => getWord,
47
48
  getWordDefinitions: () => getWordDefinitions,
48
49
  getWordDefinitionsWithFurigana: () => getWordDefinitionsWithFurigana,
49
50
  isGrammar: () => isGrammar,
50
51
  isKana: () => isKana,
51
52
  isKanji: () => isKanji,
53
+ isObjectArray: () => isObjectArray,
52
54
  isRadical: () => isRadical,
53
55
  isStringArray: () => isStringArray,
54
- isValidArray: () => isValidArray,
55
56
  isValidArrayWithFirstElement: () => isValidArrayWithFirstElement,
56
57
  isWord: () => isWord,
57
58
  notSearchedForms: () => notSearchedForms,
@@ -112,6 +113,9 @@ var noteMap = /* @__PURE__ */ new Map([
112
113
  ["tsugaru-ben", ["dialect::tsugaru-ben", "Dialect: Tsugaru-ben"]],
113
114
  ["aichi dialect", ["dialect::aichi", "Dialect: Aichi"]],
114
115
  ["tochigi dialect", ["dialect::tochigi", "Dialect: Tochigi"]],
116
+ ["lit", ["literal_meaning", "Literal meaning"]],
117
+ ["expl", ["explanation", "Explanation"]],
118
+ ["tm", ["trademark", "Trademark"]],
115
119
  ["adjective (keiyoushi)", ["adjective::i", "\u3044-adjective", "\u5F62\u5BB9\u8A5E"]],
116
120
  ["'taru' adjective", ["adjective::taru", "\u305F\u308B-adjective", "\u5F62\u5BB9\u52D5\u8A5E"]],
117
121
  [
@@ -1246,14 +1250,14 @@ var KuromojiAnalyzer = require("kuroshiro-analyzer-kuromoji");
1246
1250
  function capitalizeString(value) {
1247
1251
  return value.charAt(0).toUpperCase() + value.slice(1);
1248
1252
  }
1249
- function isValidArray(arg) {
1250
- return arg !== null && arg !== void 0 && Array.isArray(arg);
1251
- }
1252
1253
  function isValidArrayWithFirstElement(arg) {
1253
- return arg !== null && arg !== void 0 && Array.isArray(arg) && arg[0] !== null && arg[0] !== void 0;
1254
+ return Array.isArray(arg) && arg.length > 0;
1254
1255
  }
1255
1256
  function isStringArray(arg) {
1256
- return arg !== null && arg !== void 0 && Array.isArray(arg) && arg.every((element) => typeof element === "string");
1257
+ return isValidArrayWithFirstElement(arg) && arg.every((element) => typeof element === "string");
1258
+ }
1259
+ function isObjectArray(arg) {
1260
+ return isValidArrayWithFirstElement(arg) && arg.every((element) => typeof element === "object");
1257
1261
  }
1258
1262
  function shuffleArray(arr) {
1259
1263
  const a = arr.slice();
@@ -1265,6 +1269,37 @@ function shuffleArray(arr) {
1265
1269
  }
1266
1270
  return a;
1267
1271
  }
1272
+ function getValidForms(readings, kanjiForms, wordIsCommon) {
1273
+ const kanjiFormRestrictions = /* @__PURE__ */ new Set();
1274
+ const validReadings = readings.filter(
1275
+ (reading) => {
1276
+ if (reading.notes === void 0 || !reading.notes.some((note) => notSearchedForms.has(note))) {
1277
+ if (reading.kanjiFormRestrictions) {
1278
+ for (const kfr of reading.kanjiFormRestrictions)
1279
+ kanjiFormRestrictions.add(kfr);
1280
+ return true;
1281
+ }
1282
+ if (wordIsCommon === void 0 || reading.commonness !== void 0)
1283
+ return true;
1284
+ }
1285
+ return false;
1286
+ }
1287
+ );
1288
+ const existValidKf = kanjiForms ? kanjiForms.some(
1289
+ (kf) => (kf.notes === void 0 || !kf.notes.some((note) => notSearchedForms.has(note))) && (wordIsCommon === void 0 || kf.commonness !== void 0) || kanjiFormRestrictions.has(kf.form)
1290
+ ) : void 0;
1291
+ const validKanjiForms = kanjiForms ? kanjiForms.filter((kanjiForm) => {
1292
+ if (existValidKf === true)
1293
+ return (kanjiForm.notes === void 0 || !kanjiForm.notes.some(
1294
+ (note) => notSearchedForms.has(note)
1295
+ )) && (wordIsCommon === void 0 || kanjiForm.commonness !== void 0) || kanjiFormRestrictions.has(kanjiForm.form);
1296
+ else return true;
1297
+ }) : void 0;
1298
+ return {
1299
+ readings: validReadings,
1300
+ ...validKanjiForms ? { kanjiForms: validKanjiForms } : {}
1301
+ };
1302
+ }
1268
1303
  function convertJMdict(xmlString, examples) {
1269
1304
  const dictParsed = import_libxmljs2.default.parseXml(xmlString, {
1270
1305
  dtdvalid: true,
@@ -1273,144 +1308,116 @@ function convertJMdict(xmlString, examples) {
1273
1308
  recover: false
1274
1309
  });
1275
1310
  const dict = [];
1276
- import_xml2js.default.parseString(dictParsed, (err, result) => {
1277
- if (err === null) {
1278
- const tanakaParts = examples && examples.length > 0 ? new Set(
1279
- examples.map(
1280
- (example) => example.parts.map((part) => [
1281
- part.baseForm,
1282
- ...part.reading ? [part.reading] : [],
1283
- ...part.referenceID ? [part.referenceID] : []
1284
- ])
1285
- ).flat(2)
1286
- ) : void 0;
1287
- if (result.JMdict && typeof result.JMdict === "object" && isValidArray(result.JMdict.entry))
1288
- for (const entry of result.JMdict.entry) {
1289
- const entryObj = {
1290
- id: entry.ent_seq[0],
1291
- readings: [],
1292
- meanings: []
1311
+ import_xml2js.default.parseString(dictParsed, (_err, result) => {
1312
+ const tanakaParts = examples && examples.length > 0 ? new Set(
1313
+ examples.flatMap(
1314
+ (example) => example.parts.flatMap((part) => [
1315
+ part.baseForm,
1316
+ ...part.reading ? [part.reading] : [],
1317
+ ...part.inflectedForm ? [part.inflectedForm] : [],
1318
+ ...part.referenceID ? [part.referenceID] : []
1319
+ ])
1320
+ )
1321
+ ) : void 0;
1322
+ for (const entry of result.JMdict.entry) {
1323
+ const entryObj = {
1324
+ id: entry.ent_seq[0],
1325
+ readings: [],
1326
+ meanings: []
1327
+ };
1328
+ const kanjiForms = entry.k_ele;
1329
+ const readings = entry.r_ele;
1330
+ const meanings = entry.sense;
1331
+ if (isObjectArray(kanjiForms)) {
1332
+ entryObj.kanjiForms = [];
1333
+ for (const kanjiForm of kanjiForms) {
1334
+ const form = {
1335
+ form: kanjiForm.keb[0]
1293
1336
  };
1294
- if (typeof entryObj.id === "string") {
1295
- const kanjiForms = entry.k_ele;
1296
- const readings = entry.r_ele;
1297
- const meanings = entry.sense;
1298
- if (isValidArray(kanjiForms)) {
1299
- entryObj.kanjiForms = [];
1300
- for (const kanjiForm of kanjiForms) {
1301
- const form = {
1302
- form: kanjiForm.keb[0]
1303
- };
1304
- if (typeof form.form === "string") {
1305
- if (isStringArray(kanjiForm.ke_inf))
1306
- form.notes = kanjiForm.ke_inf;
1307
- if (isStringArray(kanjiForm.ke_pri)) {
1308
- form.commonness = kanjiForm.ke_pri;
1309
- if (entryObj.isCommon === void 0)
1310
- entryObj.isCommon = true;
1311
- }
1312
- entryObj.kanjiForms.push(form);
1313
- }
1314
- }
1315
- }
1316
- if (isValidArray(readings))
1317
- for (const reading of readings) {
1318
- const readingObj = {
1319
- reading: reading.reb[0]
1320
- };
1321
- if (typeof readingObj.reading === "string") {
1322
- if (isStringArray(reading.re_inf))
1323
- readingObj.notes = reading.re_inf;
1324
- if (isStringArray(reading.re_restr))
1325
- readingObj.kanjiFormRestrictions = reading.re_restr;
1326
- if (isStringArray(reading.re_pri)) {
1327
- readingObj.commonness = reading.re_pri;
1328
- if (entryObj.isCommon === void 0)
1329
- entryObj.isCommon = true;
1330
- }
1331
- entryObj.readings.push(readingObj);
1332
- }
1333
- }
1334
- if (isValidArray(meanings)) {
1335
- let usuallyInKanaMeanings = 0;
1336
- for (const meaning of meanings) {
1337
- const meaningObj = {};
1338
- if (isStringArray(meaning.pos))
1339
- meaningObj.partOfSpeech = meaning.pos;
1340
- if (isValidArray(meaning.gloss)) {
1341
- meaningObj.translations = [];
1342
- for (const gloss of meaning.gloss)
1343
- if (typeof gloss === "string")
1344
- meaningObj.translations.push(gloss);
1345
- else if (typeof gloss === "object" && gloss._ && typeof gloss._ === "string" && gloss.$ && typeof gloss.$ === "object" && gloss.$.g_type && (gloss.$.g_type === "lit" || gloss.$.g_type === "expl" || gloss.$.g_type === "tm"))
1346
- meaningObj.translations.push({
1347
- translation: gloss._,
1348
- type: gloss.$.g_type
1349
- });
1350
- }
1351
- if (isStringArray(meaning.xref))
1352
- meaningObj.references = meaning.xref;
1353
- if (isStringArray(meaning.stagk))
1354
- meaningObj.kanjiFormRestrictions = meaning.stagk;
1355
- if (isStringArray(meaning.stagr))
1356
- meaningObj.readingRestrictions = meaning.stagr;
1357
- if (isStringArray(meaning.ant))
1358
- meaningObj.antonyms = meaning.ant;
1359
- if (isStringArray(meaning.field))
1360
- meaningObj.fields = meaning.field;
1361
- if (isStringArray(meaning.s_inf))
1362
- meaningObj.info = meaning.s_inf;
1363
- if (isStringArray(meaning.misc)) {
1364
- meaningObj.misc = meaning.misc;
1365
- if (meaningObj.misc && meaningObj.misc.includes(
1366
- "word usually written using kana alone"
1367
- ))
1368
- usuallyInKanaMeanings++;
1369
- }
1370
- if (isStringArray(meaning.dial))
1371
- meaningObj.dialects = meaning.dial;
1372
- if (meaningObj.partOfSpeech && meaningObj.partOfSpeech.length > 0)
1373
- entryObj.meanings.push(meaningObj);
1374
- }
1375
- if (entryObj.meanings.length === usuallyInKanaMeanings)
1376
- entryObj.usuallyInKana = true;
1377
- }
1378
- if (examples) {
1379
- const readings2 = new Set(
1380
- entryObj.readings.filter(
1381
- (reading) => reading.notes === void 0 || !reading.notes.some(
1382
- (note) => notSearchedForms.has(note)
1383
- ) || reading.commonness
1384
- ).map((reading) => reading.reading)
1385
- );
1386
- const kanjiForms2 = entryObj.kanjiForms ? new Set(
1387
- entryObj.kanjiForms.map(
1388
- (kanjiForm) => kanjiForm.form
1389
- )
1390
- ) : void 0;
1391
- let existsExample = false;
1392
- if (kanjiForms2 && kanjiForms2.size > 0 && tanakaParts) {
1393
- for (const kf of kanjiForms2)
1394
- if (tanakaParts.has(kf)) {
1395
- existsExample = true;
1396
- break;
1397
- }
1398
- }
1399
- if (!existsExample && readings2.size > 0 && tanakaParts) {
1400
- for (const r of readings2)
1401
- if (tanakaParts.has(r)) {
1402
- existsExample = true;
1403
- break;
1404
- }
1337
+ if (isStringArray(kanjiForm.ke_inf)) form.notes = kanjiForm.ke_inf;
1338
+ if (isStringArray(kanjiForm.ke_pri)) {
1339
+ form.commonness = kanjiForm.ke_pri;
1340
+ if (entryObj.isCommon === void 0) entryObj.isCommon = true;
1341
+ }
1342
+ entryObj.kanjiForms.push(form);
1343
+ }
1344
+ }
1345
+ for (const reading of readings) {
1346
+ const readingObj = {
1347
+ reading: reading.reb[0]
1348
+ };
1349
+ if (isStringArray(reading.re_inf)) readingObj.notes = reading.re_inf;
1350
+ if (isStringArray(reading.re_restr))
1351
+ readingObj.kanjiFormRestrictions = reading.re_restr;
1352
+ if (isStringArray(reading.re_pri)) {
1353
+ readingObj.commonness = reading.re_pri;
1354
+ if (entryObj.isCommon === void 0) entryObj.isCommon = true;
1355
+ }
1356
+ entryObj.readings.push(readingObj);
1357
+ }
1358
+ let usuallyInKanaMeanings = 0;
1359
+ for (const meaning of meanings) {
1360
+ const meaningObj = { partOfSpeech: [], translations: [] };
1361
+ meaningObj.partOfSpeech = meaning.pos;
1362
+ meaningObj.translations = [];
1363
+ for (const gloss of meaning.gloss)
1364
+ if (typeof gloss === "string") meaningObj.translations.push(gloss);
1365
+ else if (typeof gloss === "object" && gloss._ && typeof gloss._ === "string" && gloss.$ && typeof gloss.$ === "object" && gloss.$.g_type && (gloss.$.g_type === "lit" || gloss.$.g_type === "expl" || gloss.$.g_type === "tm"))
1366
+ meaningObj.translations.push({
1367
+ translation: gloss._,
1368
+ type: gloss.$.g_type
1369
+ });
1370
+ if (isStringArray(meaning.xref)) meaningObj.references = meaning.xref;
1371
+ if (isStringArray(meaning.stagk))
1372
+ meaningObj.kanjiFormRestrictions = meaning.stagk;
1373
+ if (isStringArray(meaning.stagr))
1374
+ meaningObj.readingRestrictions = meaning.stagr;
1375
+ if (isStringArray(meaning.ant)) meaningObj.antonyms = meaning.ant;
1376
+ if (isStringArray(meaning.field)) meaningObj.fields = meaning.field;
1377
+ if (isStringArray(meaning.s_inf)) meaningObj.info = meaning.s_inf;
1378
+ if (isStringArray(meaning.misc)) {
1379
+ meaningObj.misc = meaning.misc;
1380
+ if (meaningObj.misc && meaningObj.misc.includes("word usually written using kana alone"))
1381
+ usuallyInKanaMeanings++;
1382
+ }
1383
+ if (isStringArray(meaning.dial)) meaningObj.dialects = meaning.dial;
1384
+ entryObj.meanings.push(meaningObj);
1385
+ }
1386
+ if (entryObj.meanings.length === usuallyInKanaMeanings)
1387
+ entryObj.usuallyInKana = true;
1388
+ if (examples) {
1389
+ let existsExample = false;
1390
+ if (tanakaParts && tanakaParts.has(entryObj.id)) existsExample = true;
1391
+ if (!existsExample) {
1392
+ const rkf = getValidForms(
1393
+ entryObj.readings,
1394
+ entryObj.kanjiForms,
1395
+ entryObj.isCommon
1396
+ );
1397
+ const readings2 = new Set(
1398
+ rkf.readings.map((r) => r.reading)
1399
+ );
1400
+ const kanjiForms2 = rkf.kanjiForms ? new Set(
1401
+ rkf.kanjiForms.map((kf) => kf.form)
1402
+ ) : void 0;
1403
+ if (kanjiForms2 && kanjiForms2.size > 0 && tanakaParts) {
1404
+ for (const kf of kanjiForms2)
1405
+ if (tanakaParts.has(kf)) {
1406
+ existsExample = true;
1407
+ break;
1405
1408
  }
1406
- if (tanakaParts && tanakaParts.has(entryObj.id))
1409
+ }
1410
+ if (entryObj.kanjiForms === void 0 && readings2.size > 0 && tanakaParts) {
1411
+ for (const r of readings2)
1412
+ if (tanakaParts.has(r)) {
1407
1413
  existsExample = true;
1408
- if (existsExample) entryObj.hasPhrases = true;
1409
- }
1410
- if (entryObj.id.length > 0 && entryObj.readings.length > 0 && entryObj.meanings.length > 0)
1411
- dict.push(entryObj);
1414
+ break;
1415
+ }
1412
1416
  }
1413
1417
  }
1418
+ if (existsExample) entryObj.hasPhrases = true;
1419
+ }
1420
+ dict.push(entryObj);
1414
1421
  }
1415
1422
  });
1416
1423
  return dict;
@@ -1423,75 +1430,64 @@ function convertKanjiDic(xmlString) {
1423
1430
  recover: false
1424
1431
  });
1425
1432
  const dict = [];
1426
- import_xml2js.default.parseString(dictParsed, (err, result) => {
1427
- if (err === null) {
1428
- if (result.kanjidic2 && typeof result.kanjidic2 === "object" && isValidArray(result.kanjidic2.character))
1429
- for (const entry of result.kanjidic2.character) {
1430
- const kanjiObj = {
1431
- kanji: entry.literal[0]
1432
- };
1433
- if (typeof kanjiObj.kanji === "string" && kanjiObj.kanji.length === 1) {
1434
- if (isValidArrayWithFirstElement(entry.misc) && typeof entry.misc[0] === "object") {
1435
- const misc = entry.misc[0];
1436
- kanjiObj.misc = {};
1437
- if (isValidArrayWithFirstElement(misc.stroke_count) && typeof misc.stroke_count[0] === "string")
1438
- kanjiObj.misc.strokeNumber = misc.stroke_count[0];
1439
- if (isValidArrayWithFirstElement(misc.grade) && typeof misc.grade[0] === "string")
1440
- kanjiObj.misc.grade = misc.grade[0];
1441
- if (isValidArrayWithFirstElement(misc.freq) && typeof misc.freq[0] === "string")
1442
- kanjiObj.misc.frequency = misc.freq[0];
1443
- if (isValidArrayWithFirstElement(misc.jlpt) && typeof misc.jlpt[0] === "string" && ["5", "4", "3", "2", "1"].includes(misc.jlpt[0]))
1444
- kanjiObj.misc.jlpt = `N${misc.jlpt[0]}`;
1445
- }
1446
- if (isValidArray(entry.reading_meaning))
1447
- for (const rm of entry.reading_meaning) {
1448
- const rmObj = { groups: [] };
1449
- if (isValidArray(rm.rmgroup))
1450
- for (const group of rm.rmgroup) {
1451
- const groupObj = {
1452
- readings: [],
1453
- meanings: []
1454
- };
1455
- if (isValidArray(group.reading)) {
1456
- for (const reading of group.reading)
1457
- if (reading._ && typeof reading._ === "string" && reading.$ && typeof reading.$ === "object" && reading.$.r_type && (reading.$.r_type === "ja_on" || reading.$.r_type === "ja_kun"))
1458
- groupObj.readings.push({
1459
- reading: reading._,
1460
- type: reading.$.r_type
1461
- });
1462
- }
1463
- if (isValidArray(group.meaning)) {
1464
- for (const meaning of group.meaning)
1465
- if (typeof meaning === "string") {
1466
- if (kanjiObj.isKokuji === void 0 && meaning === "(kokuji)")
1467
- kanjiObj.isKokuji = true;
1468
- groupObj.meanings.push(meaning);
1469
- }
1470
- }
1471
- if (groupObj.readings.length > 0 || groupObj.meanings.length > 0) {
1472
- if (groupObj.readings.length === 0)
1473
- delete groupObj.readings;
1474
- if (groupObj.meanings.length === 0)
1475
- delete groupObj.meanings;
1476
- rmObj.groups.push(groupObj);
1433
+ import_xml2js.default.parseString(dictParsed, (_err, result) => {
1434
+ for (const entry of result.kanjidic2.character) {
1435
+ const kanjiObj = {
1436
+ kanji: entry.literal[0],
1437
+ readingMeaning: []
1438
+ };
1439
+ if (typeof kanjiObj.kanji === "string" && kanjiObj.kanji.length === 1) {
1440
+ const misc = entry.misc[0];
1441
+ kanjiObj.misc = { strokeNumber: misc.stroke_count[0] };
1442
+ if (isStringArray(misc.grade)) kanjiObj.misc.grade = misc.grade[0];
1443
+ if (isStringArray(misc.freq)) kanjiObj.misc.frequency = misc.freq[0];
1444
+ if (isStringArray(misc.jlpt) && ["5", "4", "3", "2", "1"].includes(misc.jlpt[0]))
1445
+ kanjiObj.misc.jlpt = `N${misc.jlpt[0]}`;
1446
+ if (isObjectArray(entry.reading_meaning))
1447
+ for (const rm of entry.reading_meaning) {
1448
+ const rmObj = { groups: [] };
1449
+ for (const group of rm.rmgroup) {
1450
+ const groupObj = {
1451
+ readings: [],
1452
+ meanings: []
1453
+ };
1454
+ if (isObjectArray(group.reading)) {
1455
+ for (const reading of group.reading)
1456
+ if (reading._ && typeof reading._ === "string" && reading.$ && typeof reading.$ === "object" && reading.$.r_type && (reading.$.r_type === "ja_on" || reading.$.r_type === "ja_kun"))
1457
+ groupObj.readings.push({
1458
+ reading: reading._,
1459
+ type: reading.$.r_type
1460
+ });
1461
+ }
1462
+ if (Array.isArray(group.meaning)) {
1463
+ for (const meaning of group.meaning)
1464
+ if (typeof meaning === "string") {
1465
+ if (kanjiObj.isKokuji === void 0 && meaning === "(kokuji)") {
1466
+ kanjiObj.isKokuji = true;
1467
+ continue;
1477
1468
  }
1469
+ groupObj.meanings.push(meaning);
1478
1470
  }
1479
- if (isStringArray(rm.nanori) && rm.nanori.length > 0)
1480
- rmObj.nanori = rm.nanori;
1481
- if (rmObj.groups.length > 0 || rmObj.nanori) {
1482
- if (kanjiObj.readingMeaning === void 0)
1483
- kanjiObj.readingMeaning = [];
1484
- kanjiObj.readingMeaning.push(rmObj);
1485
- }
1486
1471
  }
1487
- dict.push(kanjiObj);
1472
+ if (groupObj.readings.length > 0 || groupObj.meanings.length > 0) {
1473
+ if (groupObj.readings.length === 0) delete groupObj.readings;
1474
+ if (groupObj.meanings.length === 0) delete groupObj.meanings;
1475
+ rmObj.groups.push(groupObj);
1476
+ }
1477
+ }
1478
+ if (isStringArray(rm.nanori) && rm.nanori.length > 0)
1479
+ rmObj.nanori = rm.nanori;
1480
+ if (rmObj.groups.length > 0 || rmObj.nanori)
1481
+ kanjiObj.readingMeaning.push(rmObj);
1488
1482
  }
1489
- }
1483
+ dict.push(kanjiObj);
1484
+ }
1490
1485
  }
1491
1486
  });
1492
1487
  return dict;
1493
1488
  }
1494
1489
  function convertTanakaCorpus(tanakaString) {
1490
+ var _a;
1495
1491
  const tanakaArray = [];
1496
1492
  const tanakaParsed = tanakaString.split("\n");
1497
1493
  for (let i = 0; i <= tanakaParsed.length; i += 2) {
@@ -1501,46 +1497,38 @@ function convertTanakaCorpus(tanakaString) {
1501
1497
  a = a.replace("A: ", "");
1502
1498
  b = b.replace("B: ", "");
1503
1499
  const idMatch = regexps.tanakaID.exec(a);
1504
- if (idMatch && idMatch.groups && idMatch.groups["id"]) {
1505
- const aParts = a.replace(regexps.tanakaID, "").split(" ");
1506
- const bRawParts = b.split(" ").filter((part) => part.trim().length !== 0);
1507
- const bParts = [];
1508
- for (const part of bRawParts) {
1509
- const partMatches = regexps.tanakaPart.exec(part);
1510
- if (partMatches && partMatches.groups && partMatches.length > 0) {
1511
- const baseForm = partMatches.groups["base"];
1512
- if (baseForm) {
1513
- const examplePart = { baseForm };
1514
- const reading = partMatches.groups["reading"];
1515
- const glossNumber = partMatches.groups["glossnum"];
1516
- const inflectedForm = partMatches.groups["inflection"];
1517
- if (reading)
1518
- if (regexps.tanakaReferenceID.test(reading)) {
1519
- const referenceID = regexps.tanakaReferenceID.exec(reading);
1520
- if (referenceID && referenceID.groups && referenceID.groups["entryid"])
1521
- examplePart.referenceID = referenceID.groups["entryid"];
1522
- } else examplePart.reading = reading;
1523
- if (glossNumber)
1524
- examplePart.glossNumber = glossNumber.startsWith("0") ? Number.parseInt(glossNumber.substring(1)) : Number.parseInt(glossNumber);
1525
- if (inflectedForm) examplePart.inflectedForm = inflectedForm;
1526
- if (baseForm.endsWith("~")) {
1527
- examplePart.edited = true;
1528
- examplePart.baseForm = examplePart.baseForm.replace("~", "");
1529
- }
1530
- bParts.push(examplePart);
1531
- }
1532
- }
1500
+ const aParts = a.replace(regexps.tanakaID, "").split(" ");
1501
+ const bRawParts = b.split(" ").filter((part) => part.trim().length !== 0);
1502
+ const bParts = [];
1503
+ for (const part of bRawParts) {
1504
+ const partMatches = regexps.tanakaPart.exec(part);
1505
+ const baseForm = partMatches == null ? void 0 : partMatches.groups["base"];
1506
+ const examplePart = { baseForm };
1507
+ const reading = partMatches == null ? void 0 : partMatches.groups["reading"];
1508
+ const glossNumber = partMatches == null ? void 0 : partMatches.groups["glossnum"];
1509
+ const inflectedForm = partMatches == null ? void 0 : partMatches.groups["inflection"];
1510
+ if (reading)
1511
+ if (regexps.tanakaReferenceID.test(reading)) {
1512
+ const referenceID = regexps.tanakaReferenceID.exec(reading);
1513
+ examplePart.referenceID = referenceID == null ? void 0 : referenceID.groups["entryid"];
1514
+ } else examplePart.reading = reading;
1515
+ if (glossNumber)
1516
+ examplePart.glossNumber = glossNumber.startsWith("0") ? Number.parseInt(glossNumber.substring(1)) : Number.parseInt(glossNumber);
1517
+ if (inflectedForm) examplePart.inflectedForm = inflectedForm;
1518
+ if (baseForm.endsWith("~")) {
1519
+ examplePart.edited = true;
1520
+ examplePart.baseForm = examplePart.baseForm.replace("~", "");
1533
1521
  }
1534
- const phrase = aParts[0];
1535
- const translation = aParts[1];
1536
- if (phrase && translation)
1537
- tanakaArray.push({
1538
- id: idMatch.groups["id"].trim(),
1539
- phrase: phrase.trim(),
1540
- translation: translation.trim(),
1541
- parts: bParts
1542
- });
1522
+ bParts.push(examplePart);
1543
1523
  }
1524
+ const phrase = aParts[0];
1525
+ const translation = aParts[1];
1526
+ tanakaArray.push({
1527
+ id: (_a = idMatch == null ? void 0 : idMatch.groups["id"]) == null ? void 0 : _a.trim(),
1528
+ phrase: phrase.trim(),
1529
+ translation: translation.trim(),
1530
+ parts: bParts
1531
+ });
1544
1532
  }
1545
1533
  }
1546
1534
  return tanakaArray;
@@ -1580,27 +1568,23 @@ function convertRadkFile(radkBuffer, kanjiDic) {
1580
1568
  };
1581
1569
  let j = i + 1;
1582
1570
  let kanjiLine = fileParsed[j];
1583
- if (kanjiLine) {
1584
- const kanjiList = [];
1585
- while (kanjiLine && !kanjiLine.startsWith("$ ")) {
1586
- const kanjis = kanjiLine.split("");
1587
- for (const kanji of kanjis) {
1588
- const foundKanji = kanjiDic.find(
1589
- (dictKanji) => dictKanji.kanji === kanji
1590
- );
1591
- let kanjiObj = { kanji };
1592
- if (foundKanji) kanjiObj = foundKanji;
1593
- kanjiList.push(kanjiObj);
1594
- }
1595
- j++;
1596
- kanjiLine = fileParsed[j];
1597
- if (!kanjiLine) continue;
1598
- if (kanjiLine.startsWith("$ ")) i = j - 1;
1571
+ const kanjiList = [];
1572
+ while (kanjiLine && !kanjiLine.startsWith("$ ")) {
1573
+ const kanjis = kanjiLine.split("");
1574
+ for (const kanji of kanjis) {
1575
+ const foundKanji = kanjiDic.find(
1576
+ (dictKanji) => dictKanji.kanji === kanji
1577
+ );
1578
+ let kanjiObj = { kanji };
1579
+ kanjiObj = foundKanji;
1580
+ kanjiList.push(kanjiObj);
1599
1581
  }
1600
- if (kanjiList.length > 0) radical.kanji = kanjiList;
1601
- if (radical.radical.length === 1 && radical.strokes.length > 0)
1602
- radicals.push(radical);
1582
+ kanjiLine = fileParsed[++j];
1583
+ if (!kanjiLine) continue;
1584
+ if (kanjiLine.startsWith("$ ")) i = j - 1;
1603
1585
  }
1586
+ if (kanjiList.length > 0) radical.kanji = kanjiList;
1587
+ radicals.push(radical);
1604
1588
  }
1605
1589
  }
1606
1590
  return radicals;
@@ -1613,45 +1597,39 @@ function convertKradFile(kradBuffer, kanjiDic, katakanaList) {
1613
1597
  const split = line.split(" : ");
1614
1598
  const kanjiChar = split[0];
1615
1599
  const radicalsRow = split[1];
1616
- if (kanjiChar && radicalsRow) {
1617
- const kanji = {
1618
- kanji: kanjiChar,
1619
- radicals: []
1620
- };
1621
- if (kanji.kanji.length === 1) {
1622
- const radicals = radicalsRow.split(" ");
1623
- for (const radical of radicals) {
1624
- const foundRadical = kanjiDic.find(
1625
- (dictKanji) => dictKanji.kanji === radical
1626
- );
1627
- let radicalObj = foundRadical != null ? foundRadical : { kanji: radical };
1628
- if (!foundRadical) {
1629
- const katakanaChar = katakanaList.find(
1630
- (kana) => kana.kana === radical
1631
- );
1632
- if (!katakanaChar) continue;
1633
- radicalObj = {
1634
- kanji: katakanaChar.kana,
1635
- readingMeaning: [
1600
+ const kanji = {
1601
+ kanji: kanjiChar,
1602
+ radicals: []
1603
+ };
1604
+ const radicals = radicalsRow.split(" ");
1605
+ for (const radical of radicals) {
1606
+ const foundRadical = kanjiDic.find(
1607
+ (dictKanji) => dictKanji.kanji === radical
1608
+ );
1609
+ let radicalObj = foundRadical != null ? foundRadical : { kanji: radical };
1610
+ if (!foundRadical) {
1611
+ const katakanaChar = katakanaList.find(
1612
+ (kana) => kana.kana === radical
1613
+ );
1614
+ if (!katakanaChar) continue;
1615
+ radicalObj = {
1616
+ kanji: katakanaChar.kana,
1617
+ readingMeaning: [
1618
+ {
1619
+ groups: [
1636
1620
  {
1637
- groups: [
1638
- {
1639
- readings: [
1640
- { reading: katakanaChar.kana, type: "ja_on" }
1641
- ],
1642
- meanings: [katakanaChar.reading]
1643
- }
1644
- ]
1621
+ readings: [{ reading: katakanaChar.kana, type: "ja_on" }],
1622
+ meanings: [katakanaChar.reading]
1645
1623
  }
1646
1624
  ]
1647
- };
1648
- }
1649
- kanji.radicals.push(radicalObj);
1650
- }
1625
+ }
1626
+ ]
1627
+ };
1651
1628
  }
1652
- if (kanji.kanji.length === 1 && kanji.radicals.length > 0)
1653
- kanjiWithRadicals.push(kanji);
1629
+ kanji.radicals.push(radicalObj);
1654
1630
  }
1631
+ if (kanji.kanji.length === 1 && kanji.radicals.length > 0)
1632
+ kanjiWithRadicals.push(kanji);
1655
1633
  }
1656
1634
  }
1657
1635
  return kanjiWithRadicals;
@@ -1661,18 +1639,16 @@ function mapEntry(entry) {
1661
1639
  word: entry.word,
1662
1640
  pos_title: entry.pos_title,
1663
1641
  senses: entry.senses.filter(
1664
- (sense) => isValidArray(sense.form_of) && sense.form_of.every(
1642
+ (sense) => isObjectArray(sense.form_of) && sense.form_of.every(
1665
1643
  (form) => form.word && typeof form.word === "string"
1666
1644
  ) || isStringArray(sense.glosses)
1667
1645
  ).map((sense) => ({
1668
1646
  ...sense.form_of ? {
1669
- form_of: sense.form_of.map((form) => ({
1670
- word: form.word
1671
- }))
1647
+ form_of: sense.form_of.map((form) => form.word)
1672
1648
  } : {},
1673
1649
  glosses: sense.glosses
1674
1650
  })),
1675
- ...isValidArray(entry.forms) && entry.forms.every((form) => typeof form.form === "string") ? { forms: entry.forms.map((form) => ({ form: form.form })) } : {}
1651
+ ...isObjectArray(entry.forms) && entry.forms.every((form) => typeof form.form === "string") ? { forms: entry.forms.map((form) => form.form) } : {}
1676
1652
  };
1677
1653
  }
1678
1654
  function convertJawiktionarySync(buffer) {
@@ -1708,17 +1684,14 @@ async function convertJawiktionaryAsync(stream) {
1708
1684
  );
1709
1685
  }
1710
1686
  function parseEntry(entry, definitions, definitionMap) {
1711
- if (isValidArray(entry.senses)) {
1712
- for (const sense of entry.senses)
1713
- if (isStringArray(sense.glosses)) {
1714
- const definition = sense.glosses.join("");
1715
- if (!definitions.some((def) => def.definition === definition)) {
1716
- if (!definitionMap.has(definition))
1717
- definitionMap.set(definition, { count: 1 });
1718
- else definitionMap.get(definition).count++;
1719
- definitions.push({ definition });
1720
- }
1721
- }
1687
+ for (const sense of entry.senses) {
1688
+ const definition = sense.glosses.join("");
1689
+ if (!definitions.some((def) => def.definition === definition)) {
1690
+ if (!definitionMap.has(definition))
1691
+ definitionMap.set(definition, { count: 1 });
1692
+ else definitionMap.get(definition).count++;
1693
+ definitions.push({ definition });
1694
+ }
1722
1695
  }
1723
1696
  }
1724
1697
  function getWordDefinitions(entryList, jmDict) {
@@ -1726,31 +1699,26 @@ function getWordDefinitions(entryList, jmDict) {
1726
1699
  const entries = /* @__PURE__ */ new Map();
1727
1700
  for (const entry of entryList) {
1728
1701
  const ent = entries.get(entry.word);
1729
- if (ent) ent.push(mapEntry(entry));
1730
- else entries.set(entry.word, [mapEntry(entry)]);
1702
+ if (ent) ent.push(entry);
1703
+ else entries.set(entry.word, [entry]);
1731
1704
  }
1732
1705
  const japaneseDefinitions = [];
1733
1706
  const definitionMap = /* @__PURE__ */ new Map();
1734
1707
  const validWords = [];
1735
1708
  const validReadings = /* @__PURE__ */ new Set();
1736
1709
  const validKanjiForms = /* @__PURE__ */ new Set();
1737
- if (jmDict.length > 0)
1738
- for (const word of jmDict) {
1739
- let valid = false;
1740
- for (const r of word.readings)
1741
- if ((r.notes === void 0 || !r.notes.some((note) => notSearchedForms.has(note)) || r.commonness !== void 0) && !validReadings.has(r.reading)) {
1742
- validReadings.add(r.reading);
1743
- if (!valid) valid = true;
1744
- }
1745
- if (word.kanjiForms) {
1746
- for (const kf of word.kanjiForms)
1747
- if ((kf.notes === void 0 || !kf.notes.some((note) => notSearchedForms.has(note)) || kf.commonness !== void 0) && !validKanjiForms.has(kf.form)) {
1748
- validKanjiForms.add(kf.form);
1749
- if (!valid) valid = true;
1750
- }
1751
- }
1752
- if (valid) validWords.push(word);
1753
- }
1710
+ for (const word of jmDict) {
1711
+ const rkf = getValidForms(
1712
+ word.readings,
1713
+ word.kanjiForms,
1714
+ word.isCommon
1715
+ );
1716
+ if (rkf.readings.length > 0)
1717
+ for (const r of rkf.readings) validReadings.add(r.reading);
1718
+ if (rkf.kanjiForms && rkf.kanjiForms.length > 0)
1719
+ for (const kf of rkf.kanjiForms) validKanjiForms.add(kf.form);
1720
+ validWords.push(word);
1721
+ }
1754
1722
  const validTitleEntries = /* @__PURE__ */ new Map();
1755
1723
  const entriesWithFormTitlesGlobal = /* @__PURE__ */ new Map();
1756
1724
  const entriesWithFormsGlobal = /* @__PURE__ */ new Map();
@@ -1762,34 +1730,27 @@ function getWordDefinitions(entryList, jmDict) {
1762
1730
  let valid = false;
1763
1731
  if (validKanjiForms && validKanjiForms.has(entry.word)) {
1764
1732
  valid = true;
1765
- if (isValidArray(entry.senses))
1766
- for (const sense of entry.senses) {
1767
- if (isValidArray(sense.form_of) && sense.form_of.some(
1768
- (form) => form.word && typeof form.word === "string" && validReadings.has(form.word)
1769
- ))
1770
- validFormOfEntries.add(entry.word);
1771
- else if (isStringArray(sense.glosses)) {
1772
- for (const gloss of sense.glosses) {
1773
- let reading = void 0;
1774
- if (gloss !== void 0) {
1775
- if (gloss.trim().includes("\u6F22\u5B57\u8868\u8A18") || gloss.trim().includes("\u53C2\u7167")) {
1776
- for (const r of validReadings)
1777
- if (gloss.trim().includes(r)) {
1778
- reading = r;
1779
- break;
1780
- }
1781
- }
1733
+ for (const sense of entry.senses) {
1734
+ if (sense.form_of && sense.form_of.some((form) => validReadings.has(form)))
1735
+ validFormOfEntries.add(entry.word);
1736
+ for (const gloss of sense.glosses) {
1737
+ let reading = void 0;
1738
+ if (gloss.trim().includes("\u6F22\u5B57\u8868\u8A18") || gloss.trim().includes("\u53C2\u7167")) {
1739
+ for (const r of validReadings)
1740
+ if (gloss.trim().includes(r)) {
1741
+ reading = r;
1742
+ break;
1782
1743
  }
1783
- if (reading) validGlossesEntries.add(entry.word);
1784
- }
1785
1744
  }
1745
+ if (reading) validGlossesEntries.add(entry.word);
1786
1746
  }
1787
- if (isValidArray(entry.forms)) {
1747
+ }
1748
+ if (entry.forms) {
1788
1749
  for (const form of entry.forms)
1789
- if (form.form && typeof form.form === "string" && validReadings.has(form.form))
1790
- validFormsEntries.add(entry.word);
1750
+ if (validReadings.has(form)) validFormsEntries.add(entry.word);
1791
1751
  }
1792
- } else if (validReadings.has(entry.word)) {
1752
+ }
1753
+ if (validReadings.has(entry.word)) {
1793
1754
  valid = true;
1794
1755
  const ftEntry = entriesWithFormTitlesGlobal.get(entry.word);
1795
1756
  if (ftEntry) ftEntry.push(entry);
@@ -1800,8 +1761,8 @@ function getWordDefinitions(entryList, jmDict) {
1800
1761
  if (tEntry) tEntry.push(entry);
1801
1762
  else validTitleEntries.set(entry.word, [entry]);
1802
1763
  }
1803
- if (isValidArray(entry.forms) && (validKanjiForms.has(entry.word) || validReadings.has(entry.word)) && entry.forms.some(
1804
- (form) => validKanjiForms.has(form.form) || validReadings.has(form.form)
1764
+ if (entry.forms && (validKanjiForms.has(entry.word) || validReadings.has(entry.word)) && entry.forms.some(
1765
+ (form) => validKanjiForms.has(form) || validReadings.has(form)
1805
1766
  )) {
1806
1767
  const wfEntry = entriesWithFormsGlobal.get(entry.word);
1807
1768
  if (wfEntry) wfEntry.push(entry);
@@ -1856,7 +1817,7 @@ function getWordDefinitions(entryList, jmDict) {
1856
1817
  "\u982D\u5B57\u8A9E",
1857
1818
  "\u63A5\u5C3E\u8A9E"
1858
1819
  ]) {
1859
- if (!posMap.has(pos)) posMap.set(pos, {});
1820
+ posMap.set(pos, {});
1860
1821
  for (const te of vte)
1861
1822
  if (te.pos_title === pos || te.pos_title === "\u548C\u8A9E\u306E\u6F22\u5B57\u8868\u8A18") {
1862
1823
  const posEntries = posMap.get(pos);
@@ -1895,79 +1856,74 @@ function getWordDefinitions(entryList, jmDict) {
1895
1856
  const wordEntriesPairs = [];
1896
1857
  for (const word of validWords) {
1897
1858
  const poses = /* @__PURE__ */ new Set();
1898
- for (const m of word.meanings) {
1899
- if (m.partOfSpeech)
1900
- for (const note of m.partOfSpeech) {
1901
- const noteEntry = noteMap.get(note);
1902
- if (noteEntry && noteEntry.length === 3) {
1903
- const notePos = noteEntry[2];
1904
- if (Array.isArray(notePos))
1905
- for (const pos of notePos) {
1906
- if (!poses.has(pos)) poses.add(pos);
1907
- }
1908
- else if (typeof notePos === "string" && !poses.has(notePos))
1909
- poses.add(notePos);
1910
- }
1859
+ for (const m of word.meanings)
1860
+ for (const note of m.partOfSpeech) {
1861
+ const noteEntry = noteMap.get(note);
1862
+ if (noteEntry && noteEntry.length === 3) {
1863
+ const notePos = noteEntry[2];
1864
+ if (Array.isArray(notePos))
1865
+ for (const pos of notePos) {
1866
+ if (!poses.has(pos)) poses.add(pos);
1867
+ }
1868
+ else if (typeof notePos === "string" && !poses.has(notePos))
1869
+ poses.add(notePos);
1911
1870
  }
1912
- }
1871
+ }
1872
+ const rkf = getValidForms(
1873
+ word.readings,
1874
+ word.kanjiForms,
1875
+ word.isCommon
1876
+ );
1913
1877
  const validWordReadings = new Set(
1914
- word.readings.filter(
1915
- (r) => r.notes === void 0 || !r.notes.some((note) => notSearchedForms.has(note)) || r.commonness !== void 0
1916
- ).map((r) => r.reading)
1878
+ rkf.readings.map((r) => r.reading)
1917
1879
  );
1918
- const validWordKanjiForms = word.kanjiForms ? new Set(
1919
- word.kanjiForms.filter(
1920
- (kf) => kf.notes === void 0 || !kf.notes.some((note) => notSearchedForms.has(note)) || kf.commonness !== void 0
1921
- ).map((kf) => kf.form)
1922
- ) : void 0;
1880
+ const validWordKanjiForms = rkf.kanjiForms ? new Set(rkf.kanjiForms.map((kf) => kf.form)) : void 0;
1923
1881
  const entriesWithTitles = [];
1924
1882
  const entriesWithFormTitles = [];
1925
1883
  const entriesWithForms = [];
1926
1884
  if (poses.size > 0)
1927
1885
  for (const pos of poses) {
1928
1886
  const posEntries = posMap.get(pos);
1929
- if (posEntries) {
1930
- if (validWordKanjiForms)
1931
- for (const kf of validWordKanjiForms) {
1932
- const te = (_a = posEntries.title) == null ? void 0 : _a.get(kf);
1933
- const fe = (_b = posEntries.form) == null ? void 0 : _b.get(kf);
1934
- if (te)
1935
- entriesWithTitles.push(
1936
- ...te.filter(
1937
- (ent) => validFormOfEntries.has(ent.word) || validGlossesEntries.has(ent.word) || validFormsEntries.has(ent.word)
1938
- )
1939
- );
1940
- if (fe)
1941
- entriesWithForms.push(
1942
- ...fe.filter(
1943
- (ent) => ent.forms && ent.forms.some(
1944
- (form) => validWordKanjiForms.has(form.form) || validWordReadings.has(form.form)
1945
- )
1946
- )
1947
- );
1948
- }
1949
- for (const r of validWordReadings) {
1950
- const te = (_c = posEntries.title) == null ? void 0 : _c.get(r);
1951
- const fe = (_d = posEntries.form) == null ? void 0 : _d.get(r);
1952
- const fte = (_e = posEntries.formTitle) == null ? void 0 : _e.get(r);
1887
+ if (validWordKanjiForms)
1888
+ for (const kf of validWordKanjiForms) {
1889
+ const te = (_a = posEntries.title) == null ? void 0 : _a.get(kf);
1890
+ const fe = (_b = posEntries.form) == null ? void 0 : _b.get(kf);
1953
1891
  if (te)
1954
1892
  entriesWithTitles.push(
1955
1893
  ...te.filter(
1956
- (ent) => ent.forms && validWordKanjiForms && ent.forms.some(
1957
- (form) => validWordKanjiForms.has(form.form)
1958
- ) || validWordKanjiForms === void 0
1894
+ (ent) => validFormOfEntries.has(ent.word) || validGlossesEntries.has(ent.word) || validFormsEntries.has(ent.word)
1959
1895
  )
1960
1896
  );
1961
1897
  if (fe)
1962
1898
  entriesWithForms.push(
1963
1899
  ...fe.filter(
1964
1900
  (ent) => ent.forms && ent.forms.some(
1965
- (form) => validWordKanjiForms && validWordKanjiForms.has(form.form) || validWordReadings.has(form.form)
1901
+ (form) => validWordKanjiForms.has(form) || validWordReadings.has(form)
1966
1902
  )
1967
1903
  )
1968
1904
  );
1969
- if (fte) entriesWithFormTitles.push(...fte);
1970
1905
  }
1906
+ for (const r of validWordReadings) {
1907
+ const te = (_c = posEntries.title) == null ? void 0 : _c.get(r);
1908
+ const fe = (_d = posEntries.form) == null ? void 0 : _d.get(r);
1909
+ const fte = (_e = posEntries.formTitle) == null ? void 0 : _e.get(r);
1910
+ if (te)
1911
+ entriesWithTitles.push(
1912
+ ...te.filter(
1913
+ (ent) => ent.forms && validWordKanjiForms && ent.forms.some(
1914
+ (form) => validWordKanjiForms.has(form)
1915
+ ) || validWordKanjiForms === void 0
1916
+ )
1917
+ );
1918
+ if (fe)
1919
+ entriesWithForms.push(
1920
+ ...fe.filter(
1921
+ (ent) => ent.forms && ent.forms.some(
1922
+ (form) => validWordKanjiForms && validWordKanjiForms.has(form) || validWordReadings.has(form)
1923
+ )
1924
+ )
1925
+ );
1926
+ if (fte) entriesWithFormTitles.push(...fte);
1971
1927
  }
1972
1928
  }
1973
1929
  if (entriesWithTitles.length === 0 && entriesWithFormTitles.length === 0 && entriesWithForms.length === 0) {
@@ -1985,7 +1941,7 @@ function getWordDefinitions(entryList, jmDict) {
1985
1941
  entriesWithForms.push(
1986
1942
  ...fe.filter(
1987
1943
  (ent) => ent.forms && ent.forms.some(
1988
- (form) => validWordKanjiForms.has(form.form) || validWordReadings.has(form.form)
1944
+ (form) => validWordKanjiForms.has(form) || validWordReadings.has(form)
1989
1945
  )
1990
1946
  )
1991
1947
  );
@@ -1998,7 +1954,7 @@ function getWordDefinitions(entryList, jmDict) {
1998
1954
  entriesWithTitles.push(
1999
1955
  ...te.filter(
2000
1956
  (ent) => ent.forms && validWordKanjiForms && ent.forms.some(
2001
- (form) => validWordKanjiForms.has(form.form)
1957
+ (form) => validWordKanjiForms.has(form)
2002
1958
  ) || validWordKanjiForms === void 0
2003
1959
  )
2004
1960
  );
@@ -2006,7 +1962,7 @@ function getWordDefinitions(entryList, jmDict) {
2006
1962
  entriesWithForms.push(
2007
1963
  ...fe.filter(
2008
1964
  (ent) => ent.forms && ent.forms.some(
2009
- (form) => validWordKanjiForms && validWordKanjiForms.has(form.form) || validWordReadings.has(form.form)
1965
+ (form) => validWordKanjiForms && validWordKanjiForms.has(form) || validWordReadings.has(form)
2010
1966
  )
2011
1967
  )
2012
1968
  );
@@ -2035,31 +1991,29 @@ function getWordDefinitions(entryList, jmDict) {
2035
1991
  const validFormOf = validFormOfEntries.has(ent.word);
2036
1992
  const validGlosses = validGlossesEntries.has(ent.word);
2037
1993
  const validForms = validFormsEntries.has(ent.word);
1994
+ const hasKanjiForms = ent.forms !== void 0 && pair.kanjiForms !== void 0 && ent.forms.some((form) => pair.kanjiForms.has(form));
2038
1995
  if (pair.kanjiForms && pair.kanjiForms.has(ent.word) && (validFormOf || validGlosses || validForms)) {
2039
1996
  kanjiFormEntries.push(ent);
2040
- if ((validFormOf || validGlosses) && isValidArray(ent.senses))
1997
+ if ((validFormOf || validGlosses) && ent.senses)
2041
1998
  for (const sense of ent.senses) {
2042
- if (validFormOf && isValidArray(sense.form_of)) {
1999
+ if (validFormOf && sense.form_of) {
2043
2000
  for (const form of sense.form_of)
2044
- if (form.word && typeof form.word === "string" && pair.readings.has(form.word)) {
2045
- const elem = titleFormMap.get(
2046
- form.word
2047
- );
2001
+ if (pair.readings.has(form)) {
2002
+ const elem = titleFormMap.get(form);
2048
2003
  if (!elem)
2049
- titleFormMap.set(form.word, /* @__PURE__ */ new Set([ent.word]));
2004
+ titleFormMap.set(form, /* @__PURE__ */ new Set([ent.word]));
2050
2005
  else elem.add(ent.word);
2051
2006
  }
2052
- } else if (validGlosses && isStringArray(sense.glosses)) {
2007
+ }
2008
+ if (validGlosses) {
2053
2009
  for (const gloss of sense.glosses) {
2054
2010
  let reading = void 0;
2055
- if (gloss !== void 0) {
2056
- if (gloss.trim().includes("\u6F22\u5B57\u8868\u8A18") || gloss.trim().includes("\u53C2\u7167")) {
2057
- for (const r of pair.readings)
2058
- if (gloss.trim().includes(r)) {
2059
- reading = r;
2060
- break;
2061
- }
2062
- }
2011
+ if (gloss.trim().includes("\u6F22\u5B57\u8868\u8A18") || gloss.trim().includes("\u53C2\u7167")) {
2012
+ for (const r of pair.readings)
2013
+ if (gloss.trim().includes(r)) {
2014
+ reading = r;
2015
+ break;
2016
+ }
2063
2017
  }
2064
2018
  if (reading) {
2065
2019
  const elem = refsMap.get(reading);
@@ -2069,19 +2023,19 @@ function getWordDefinitions(entryList, jmDict) {
2069
2023
  }
2070
2024
  }
2071
2025
  }
2072
- if (validForms && isValidArray(ent.forms)) {
2026
+ if (validForms && ent.forms) {
2073
2027
  for (const form of ent.forms)
2074
- if (form.form && typeof form.form === "string" && pair.readings.has(form.form))
2075
- readingForms.add(form.form);
2028
+ if (pair.readings.has(form)) readingForms.add(form);
2076
2029
  }
2077
- } else if (pair.readings.has(ent.word) && isValidArray(ent.forms) && pair.kanjiForms && ent.forms.some((form) => pair.kanjiForms.has(form.form)))
2030
+ }
2031
+ if (pair.readings.has(ent.word) && hasKanjiForms)
2078
2032
  readingWithFormsEntries.push(ent);
2079
- else if (pair.kanjiForms === void 0 && pair.readings.has(ent.word))
2033
+ if (pair.kanjiForms === void 0 && pair.readings.has(ent.word))
2080
2034
  readingEntries.push(ent);
2081
2035
  }
2082
2036
  for (const entry of pair.entriesWithForms) {
2083
2037
  const elem = titleFormMap.get(entry.word);
2084
- if (elem && entry.forms.some((form) => elem.has(form.form)))
2038
+ if (elem && entry.forms && entry.forms.some((form) => elem.has(form)))
2085
2039
  readingWithFormsEntries.push(entry);
2086
2040
  }
2087
2041
  for (const entry of pair.entriesWithFormTitles) {
@@ -2158,12 +2112,12 @@ async function getWordDefinitionsWithFurigana(entryList, jmDict) {
2158
2112
  function lookupWordNote(key, notes, tags) {
2159
2113
  const info = noteMap.get(key.toLowerCase());
2160
2114
  if (!info) {
2161
- if (notes) notes.push(key);
2115
+ notes.push(key);
2162
2116
  return { note: key };
2163
2117
  }
2164
2118
  const tag = `word::${info[0]}`;
2165
- if (tags && !tags.includes(tag)) tags.push(tag);
2166
- if (notes) notes.push(info[1]);
2119
+ if (!tags.includes(tag)) tags.push(tag);
2120
+ notes.push(info[1]);
2167
2121
  return { note: info[1], tag };
2168
2122
  }
2169
2123
  var wordAddNoteArray = (arr, cb) => {
@@ -2171,11 +2125,16 @@ var wordAddNoteArray = (arr, cb) => {
2171
2125
  for (const v of arr) cb(v);
2172
2126
  };
2173
2127
  function getWord(word, dict, kanjiDic, examples, definitions, noteTypeName, deckPath) {
2174
- var _a;
2128
+ var _a, _b;
2175
2129
  let dictWord = void 0;
2176
- if (typeof word === "string" && dict)
2177
- dictWord = dict.find((entry) => entry.id === word);
2178
- else if (typeof word === "object") dictWord = word;
2130
+ if (typeof word === "string" && dict) {
2131
+ if (Array.isArray(dict))
2132
+ dictWord = dict.find(
2133
+ (entry) => entry.id === word
2134
+ );
2135
+ if (dict instanceof Map) dictWord = dict.get(word);
2136
+ }
2137
+ if (typeof word === "object") dictWord = word;
2179
2138
  if (dictWord) {
2180
2139
  const word2 = {
2181
2140
  id: dictWord.id,
@@ -2198,7 +2157,7 @@ function getWord(word, dict, kanjiDic, examples, definitions, noteTypeName, deck
2198
2157
  notes: dictKanjiForm.notes.map((note) => {
2199
2158
  const noteAndTag = lookupWordNote(
2200
2159
  note,
2201
- void 0,
2160
+ [],
2202
2161
  word2.tags
2203
2162
  );
2204
2163
  return capitalizeString(noteAndTag.note);
@@ -2217,7 +2176,7 @@ function getWord(word, dict, kanjiDic, examples, definitions, noteTypeName, deck
2217
2176
  ...dictReading.notes ? dictReading.notes.map((note) => {
2218
2177
  const noteAndTag = lookupWordNote(
2219
2178
  note,
2220
- void 0,
2179
+ [],
2221
2180
  word2.tags
2222
2181
  );
2223
2182
  return capitalizeString(noteAndTag.note);
@@ -2227,72 +2186,66 @@ function getWord(word, dict, kanjiDic, examples, definitions, noteTypeName, deck
2227
2186
  ...dictReading.commonness && dictReading.commonness.length > 0 ? { common: true } : {}
2228
2187
  }));
2229
2188
  word2.translations = [];
2230
- for (const dictMeaning of dictWord.meanings)
2231
- if (dictMeaning.translations) {
2232
- const translationTypes = [];
2233
- const translations = dictMeaning.translations.map(
2234
- (translation) => {
2235
- if (typeof translation === "string") return translation;
2236
- else {
2237
- if (translation.type === "lit") {
2238
- translationTypes.push("Literal meaning");
2239
- word2.tags.push("word::literal_meaning");
2240
- } else if (translation.type === "expl") {
2241
- translationTypes.push("Explanation");
2242
- word2.tags.push("word::explanation");
2243
- } else if (translation.type === "tm") {
2244
- translationTypes.push("Trademark");
2245
- word2.tags.push("word::trademark");
2246
- }
2247
- return translation.translation;
2248
- }
2189
+ for (const dictMeaning of dictWord.meanings) {
2190
+ const translationTypes = [];
2191
+ const translations = dictMeaning.translations.map(
2192
+ (translation) => {
2193
+ if (typeof translation === "string") return translation;
2194
+ else {
2195
+ const translationNoteAndTag = noteMap.get(
2196
+ translation.type
2197
+ );
2198
+ translationTypes.push(translationNoteAndTag[1]);
2199
+ word2.tags.push(`word::${translationNoteAndTag[0]}`);
2200
+ return translation.translation;
2249
2201
  }
2250
- );
2251
- const notes = [];
2252
- wordAddNoteArray(
2253
- dictMeaning.kanjiFormRestrictions,
2254
- (restriction) => notes.push(`Meaning restricted to ${restriction}`)
2255
- );
2256
- wordAddNoteArray(
2257
- dictMeaning.readingRestrictions,
2258
- (restriction) => notes.push(`Meaning restricted to ${restriction}`)
2259
- );
2260
- for (const t of translationTypes) notes.push(t);
2261
- wordAddNoteArray(
2262
- dictMeaning.partOfSpeech,
2263
- (pos) => lookupWordNote(pos, notes, word2.tags)
2264
- );
2265
- wordAddNoteArray(
2266
- dictMeaning.fields,
2267
- (field) => lookupWordNote(field, notes, word2.tags)
2268
- );
2269
- wordAddNoteArray(
2270
- dictMeaning.dialects,
2271
- (dialect) => lookupWordNote(dialect, notes, word2.tags)
2272
- );
2273
- wordAddNoteArray(
2274
- dictMeaning.antonyms,
2275
- (antonym) => notes.push(`Antonym: ${antonym}`)
2276
- );
2277
- wordAddNoteArray(
2278
- dictMeaning.references,
2279
- (reference) => notes.push(`Related: ${reference}`)
2280
- );
2281
- wordAddNoteArray(
2282
- dictMeaning.info,
2283
- (info) => lookupWordNote(info, notes, word2.tags)
2284
- );
2285
- wordAddNoteArray(
2286
- dictMeaning.misc,
2287
- (misc) => lookupWordNote(misc, notes, word2.tags)
2288
- );
2289
- for (let i = 0; i < notes.length; i++)
2290
- notes[i] = capitalizeString(notes[i]);
2291
- word2.translations.push({
2292
- translation: translations.join("; "),
2293
- notes
2294
- });
2295
- }
2202
+ }
2203
+ );
2204
+ const notes = [];
2205
+ wordAddNoteArray(
2206
+ dictMeaning.kanjiFormRestrictions,
2207
+ (restriction) => notes.push(`Meaning restricted to ${restriction}`)
2208
+ );
2209
+ wordAddNoteArray(
2210
+ dictMeaning.readingRestrictions,
2211
+ (restriction) => notes.push(`Meaning restricted to ${restriction}`)
2212
+ );
2213
+ for (const t of translationTypes) notes.push(t);
2214
+ wordAddNoteArray(
2215
+ dictMeaning.partOfSpeech,
2216
+ (pos) => lookupWordNote(pos, notes, word2.tags)
2217
+ );
2218
+ wordAddNoteArray(
2219
+ dictMeaning.fields,
2220
+ (field) => lookupWordNote(field, notes, word2.tags)
2221
+ );
2222
+ wordAddNoteArray(
2223
+ dictMeaning.dialects,
2224
+ (dialect) => lookupWordNote(dialect, notes, word2.tags)
2225
+ );
2226
+ wordAddNoteArray(
2227
+ dictMeaning.antonyms,
2228
+ (antonym) => notes.push(`Antonym: ${antonym}`)
2229
+ );
2230
+ wordAddNoteArray(
2231
+ dictMeaning.references,
2232
+ (reference) => notes.push(`Related: ${reference}`)
2233
+ );
2234
+ wordAddNoteArray(
2235
+ dictMeaning.info,
2236
+ (info) => lookupWordNote(info, notes, word2.tags)
2237
+ );
2238
+ wordAddNoteArray(
2239
+ dictMeaning.misc,
2240
+ (misc) => lookupWordNote(misc, notes, word2.tags)
2241
+ );
2242
+ for (let i = 0; i < notes.length; i++)
2243
+ notes[i] = capitalizeString(notes[i]);
2244
+ word2.translations.push({
2245
+ translation: translations.join("; "),
2246
+ notes
2247
+ });
2248
+ }
2296
2249
  if (dictWord.usuallyInKana === true) {
2297
2250
  word2.usuallyInKana = true;
2298
2251
  word2.tags.push("word::usually_in_kana_for_all_senses");
@@ -2315,130 +2268,117 @@ function getWord(word, dict, kanjiDic, examples, definitions, noteTypeName, deck
2315
2268
  }
2316
2269
  if (kanji.length > 0) word2.kanji = kanji;
2317
2270
  }
2318
- if (dictWord.hasPhrases === true && examples) {
2319
- const exampleList = Array.isArray(
2320
- examples
2321
- ) ? examples : examples.get(word2.id);
2322
- if (exampleList) {
2323
- const readings = new Set(
2324
- word2.readings.filter(
2325
- (reading) => (reading.notes === void 0 || !reading.notes.some(
2326
- (note) => notSearchedForms.has(note)
2327
- )) && (word2.common === void 0 || reading.common === true)
2328
- ).map((reading) => reading.reading)
2329
- );
2330
- const existValidKf = word2.kanjiForms && word2.kanjiForms.length > 0 ? word2.kanjiForms.some(
2331
- (kf) => (kf.notes === void 0 || !kf.notes.some(
2332
- (note) => notSearchedForms.has(note)
2333
- )) && (word2.common === void 0 || kf.common === true)
2334
- ) : void 0;
2335
- const kanjiForms = word2.kanjiForms && word2.kanjiForms.length > 0 ? new Set(
2336
- word2.kanjiForms.filter((kanjiForm) => {
2337
- if (existValidKf === true)
2338
- return (kanjiForm.notes === void 0 || !kanjiForm.notes.some(
2339
- (note) => notSearchedForms.has(note)
2340
- )) && (word2.common === void 0 || kanjiForm.common === true);
2341
- else return true;
2342
- }).map((kanjiForm) => kanjiForm.kanjiForm)
2343
- ) : void 0;
2344
- let kanjiFormExamples = [];
2345
- const readingMatchingKanjiFormExamples = [];
2346
- const readingExamples = [];
2347
- const readingMatchingKanjiForms = /* @__PURE__ */ new Set();
2348
- for (const example of exampleList)
2349
- for (let i = 0; i < example.parts.length; i++) {
2350
- const part = example.parts[i];
2351
- const readingAsReadingMatch = part.reading !== void 0 && readings.has(part.reading);
2352
- const readingAsInflectedFormMatch = part.inflectedForm !== void 0 && readings.has(part.inflectedForm);
2353
- const referenceIDMatch = part.referenceID !== void 0 && word2.id !== void 0 && part.referenceID === word2.id;
2354
- if (kanjiForms && kanjiForms.has(part.baseForm) || referenceIDMatch) {
2355
- if (readingAsReadingMatch || readingAsInflectedFormMatch) {
2356
- readingMatchingKanjiFormExamples.push({
2357
- ex: example,
2358
- partIndex: i
2359
- });
2360
- readingMatchingKanjiForms.add(part.baseForm);
2361
- } else
2362
- kanjiFormExamples.push({
2363
- ex: example,
2364
- partIndex: i,
2365
- form: part.baseForm
2366
- });
2367
- break;
2368
- }
2369
- const readingAsBaseFormMatch = readings.has(part.baseForm);
2370
- if ((readingAsBaseFormMatch || referenceIDMatch) && kanjiForms === void 0) {
2371
- readingExamples.push({ ex: example, partIndex: i });
2372
- break;
2373
- }
2271
+ if (dictWord.hasPhrases !== void 0 && examples) {
2272
+ const exampleList = Array.isArray(examples) ? examples : (_a = examples.get(
2273
+ dictWord.id
2274
+ )) != null ? _a : [];
2275
+ const rkf = getValidForms(
2276
+ dictWord.readings,
2277
+ dictWord.kanjiForms,
2278
+ dictWord.isCommon
2279
+ );
2280
+ const readings = new Set(
2281
+ rkf.readings.map((r) => r.reading)
2282
+ );
2283
+ const kanjiForms = rkf.kanjiForms ? new Set(rkf.kanjiForms.map((kf) => kf.form)) : void 0;
2284
+ let kanjiFormExamples = [];
2285
+ const readingMatchingKanjiFormExamples = [];
2286
+ const readingExamples = [];
2287
+ const readingMatchingKanjiForms = /* @__PURE__ */ new Set();
2288
+ for (const example of exampleList)
2289
+ for (let i = 0; i < example.parts.length; i++) {
2290
+ const part = example.parts[i];
2291
+ const readingAsReadingMatch = part.reading !== void 0 && readings.has(part.reading);
2292
+ const readingAsInflectedFormMatch = part.inflectedForm !== void 0 && readings.has(part.inflectedForm);
2293
+ const referenceIDMatch = part.referenceID === dictWord.id;
2294
+ if (kanjiForms && kanjiForms.has(part.baseForm) || referenceIDMatch) {
2295
+ if (readingAsReadingMatch || readingAsInflectedFormMatch) {
2296
+ readingMatchingKanjiFormExamples.push({
2297
+ ex: example,
2298
+ partIndex: i
2299
+ });
2300
+ readingMatchingKanjiForms.add(part.baseForm);
2301
+ } else
2302
+ kanjiFormExamples.push({
2303
+ ex: example,
2304
+ partIndex: i,
2305
+ form: part.baseForm
2306
+ });
2307
+ break;
2374
2308
  }
2375
- if (readingMatchingKanjiForms.size > 0)
2376
- kanjiFormExamples = kanjiFormExamples.filter(
2377
- (ex) => ex.form && readingMatchingKanjiForms.has(ex.form)
2378
- );
2379
- const includeKanjiFormExamples = word2.kanjiForms !== void 0;
2380
- let wordExamples = [
2381
- ...includeKanjiFormExamples ? [...readingMatchingKanjiFormExamples, ...kanjiFormExamples] : [],
2382
- ...!includeKanjiFormExamples ? readingExamples : []
2383
- ];
2384
- readingMatchingKanjiForms.clear();
2385
- const glossSpecificExamples = [];
2386
- const seenPhrases = /* @__PURE__ */ new Set();
2387
- for (let i = 0; i < word2.translations.length; i++) {
2388
- outer: for (const example of wordExamples) {
2389
- if (seenPhrases.has(example.ex.phrase)) continue;
2390
- for (let j = 0; j < example.ex.parts.length; j++) {
2391
- const part = example.ex.parts[j];
2392
- if (j === example.partIndex && part.glossNumber === i + 1) {
2393
- example.ex.glossNumber = {
2394
- wordId: word2.id,
2395
- glossNumber: i + 1
2396
- };
2397
- glossSpecificExamples.push(example);
2398
- seenPhrases.add(example.ex.phrase);
2399
- break outer;
2400
- }
2401
- }
2309
+ const readingAsBaseFormMatch = readings.has(part.baseForm);
2310
+ if ((readingAsBaseFormMatch || referenceIDMatch) && kanjiForms === void 0) {
2311
+ readingExamples.push({ ex: example, partIndex: i });
2312
+ break;
2402
2313
  }
2403
- if (glossSpecificExamples.length === 5) break;
2404
2314
  }
2405
- if (glossSpecificExamples.length === 5)
2406
- wordExamples = [...glossSpecificExamples];
2407
- else if (glossSpecificExamples.length > 0)
2408
- wordExamples = [
2409
- ...glossSpecificExamples,
2410
- ...wordExamples.filter(
2411
- (ex) => !seenPhrases.has(ex.ex.phrase)
2412
- ).slice(0, 5 - glossSpecificExamples.length)
2413
- ];
2414
- if (wordExamples.length > 0) {
2415
- word2.phrases = (wordExamples.length > 5 ? wordExamples.slice(0, 5) : wordExamples).map((ex) => {
2416
- var _a2;
2417
- return {
2418
- phrase: (_a2 = ex.ex.furigana) != null ? _a2 : ex.ex.phrase,
2419
- translation: ex.ex.translation,
2420
- originalPhrase: ex.ex.phrase,
2421
- ...ex.ex.glossNumber ? { glossNumber: ex.ex.glossNumber } : {}
2422
- };
2423
- });
2424
- word2.tags.push("word::has_phrases");
2425
- if (glossSpecificExamples.length > 0)
2426
- word2.tags.push("word::has_meaning-specific_phrases");
2315
+ if (readingMatchingKanjiForms.size > 0)
2316
+ kanjiFormExamples = kanjiFormExamples.filter(
2317
+ (ex) => ex.form && readingMatchingKanjiForms.has(ex.form)
2318
+ );
2319
+ const includeKanjiFormExamples = word2.kanjiForms !== void 0;
2320
+ let wordExamples = [
2321
+ ...includeKanjiFormExamples ? [...readingMatchingKanjiFormExamples, ...kanjiFormExamples] : readingExamples
2322
+ ];
2323
+ readingMatchingKanjiForms.clear();
2324
+ const glossSpecificExamples = [];
2325
+ const seenPhrases = /* @__PURE__ */ new Set();
2326
+ for (let i = 0; i < word2.translations.length; i++) {
2327
+ outer: for (const example of wordExamples) {
2328
+ if (seenPhrases.has(example.ex.phrase)) continue;
2329
+ for (let j = 0; j < example.ex.parts.length; j++) {
2330
+ const part = example.ex.parts[j];
2331
+ if (j === example.partIndex && part.glossNumber === i + 1) {
2332
+ example.ex.glossNumber = {
2333
+ wordId: word2.id,
2334
+ glossNumber: i + 1
2335
+ };
2336
+ glossSpecificExamples.push(example);
2337
+ seenPhrases.add(example.ex.phrase);
2338
+ break outer;
2339
+ }
2340
+ }
2427
2341
  }
2342
+ if (glossSpecificExamples.length === 5) break;
2343
+ }
2344
+ if (glossSpecificExamples.length === 5)
2345
+ wordExamples = [...glossSpecificExamples];
2346
+ else if (glossSpecificExamples.length > 0)
2347
+ wordExamples = [
2348
+ ...glossSpecificExamples,
2349
+ ...wordExamples.filter(
2350
+ (ex) => !seenPhrases.has(ex.ex.phrase)
2351
+ ).slice(0, 5 - glossSpecificExamples.length)
2352
+ ];
2353
+ if (wordExamples.length > 0) {
2354
+ word2.phrases = (wordExamples.length > 5 ? wordExamples.slice(0, 5) : wordExamples).map((ex) => {
2355
+ var _a2;
2356
+ return {
2357
+ phrase: (_a2 = ex.ex.furigana) != null ? _a2 : ex.ex.phrase,
2358
+ translation: ex.ex.translation,
2359
+ originalPhrase: ex.ex.phrase,
2360
+ ...ex.ex.glossNumber ? { glossNumber: ex.ex.glossNumber } : {}
2361
+ };
2362
+ });
2363
+ word2.tags.push("word::has_phrases");
2364
+ if (glossSpecificExamples.length > 0)
2365
+ word2.tags.push("word::has_meaning-specific_phrases");
2428
2366
  }
2429
2367
  }
2430
2368
  if (definitions) {
2431
- const defs = Array.isArray(definitions) ? (_a = definitions.find((wdp) => wdp.wordID === word2.id)) == null ? void 0 : _a.definitions : definitions.get(word2.id);
2369
+ const defs = Array.isArray(definitions) ? (_b = definitions.find((wdp) => wdp.wordID === word2.id)) == null ? void 0 : _b.definitions : definitions.get(
2370
+ word2.id
2371
+ );
2432
2372
  if (defs) word2.definitions = [...defs];
2433
2373
  }
2434
2374
  return word2;
2435
2375
  } else return void 0;
2436
2376
  }
2437
2377
  function getKanji(kanji, dict, jmDict, svgList, noteTypeName, deckPath) {
2438
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
2378
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
2439
2379
  let dictKanji = void 0;
2440
2380
  if (typeof kanji === "string" && dict)
2441
- dictKanji = dict.find((entry) => entry.kanji === kanji);
2381
+ dictKanji = Array.isArray(dict) ? dict.find((entry) => entry.kanji === kanji) : dict.get(kanji);
2442
2382
  else if (typeof kanji === "object") dictKanji = kanji;
2443
2383
  if (dictKanji) {
2444
2384
  const kanji2 = {
@@ -2459,23 +2399,20 @@ function getKanji(kanji, dict, jmDict, svgList, noteTypeName, deckPath) {
2459
2399
  const kunyomi = [];
2460
2400
  for (const rm of dictKanji.readingMeaning) {
2461
2401
  if (rm.nanori && rm.nanori.length > 0) nanori.push(...rm.nanori);
2462
- if (rm.groups)
2463
- for (const group of rm.groups) {
2464
- if (group.readings) {
2465
- onyomi.push(
2466
- ...group.readings.filter(
2467
- (reading) => reading.type === "ja_on"
2468
- ).map((reading) => reading.reading)
2469
- );
2470
- kunyomi.push(
2471
- ...group.readings.filter(
2472
- (reading) => reading.type === "ja_kun"
2473
- ).map((reading) => reading.reading)
2474
- );
2475
- }
2476
- if (group.meanings && group.meanings.length > 0)
2477
- meanings.push(...group.meanings);
2402
+ for (const group of rm.groups) {
2403
+ if (group.readings) {
2404
+ onyomi.push(
2405
+ ...group.readings.filter((reading) => reading.type === "ja_on").map((reading) => reading.reading)
2406
+ );
2407
+ kunyomi.push(
2408
+ ...group.readings.filter(
2409
+ (reading) => reading.type === "ja_kun"
2410
+ ).map((reading) => reading.reading)
2411
+ );
2478
2412
  }
2413
+ if (group.meanings && group.meanings.length > 0)
2414
+ meanings.push(...group.meanings);
2415
+ }
2479
2416
  }
2480
2417
  if (meanings.length > 0) kanji2.meanings = meanings;
2481
2418
  if (nanori.length > 0) kanji2.nanori = nanori;
@@ -2490,71 +2427,62 @@ function getKanji(kanji, dict, jmDict, svgList, noteTypeName, deckPath) {
2490
2427
  (word) => word.kanjiForms && word.kanjiForms[0].form.includes(kanji2.kanji)
2491
2428
  );
2492
2429
  if (firstKfWords && firstKfWords.length > 0) kanjiWords = firstKfWords;
2493
- else if (kanjiWords) kanjiWords = kanjiWords;
2494
2430
  if (kanjiWords) {
2495
2431
  const validWords = [];
2496
2432
  for (const word of kanjiWords) {
2497
2433
  const kanjiForm = (_a = firstKfWords && firstKfWords.length > 0 ? word.kanjiForms[0] : word.kanjiForms.find(
2498
2434
  (kf) => kf.form.includes(kanji2.kanji)
2499
2435
  )) == null ? void 0 : _a.form;
2500
- if (!kanjiForm) continue;
2501
- const reading = (_b = firstKfWords && firstKfWords.length > 0 ? word.readings[0] : word.readings.find(
2502
- (reading2) => reading2.kanjiFormRestrictions && reading2.kanjiFormRestrictions.includes(kanjiForm)
2503
- )) == null ? void 0 : _b.reading;
2504
- if (!reading) continue;
2505
- const meaning = firstKfWords && firstKfWords.length > 0 ? (_c = word.meanings[0]) == null ? void 0 : _c.translations[0] : (_d = word.meanings.find(
2506
- (m) => m.translations && m.kanjiFormRestrictions && m.kanjiFormRestrictions.includes(kanjiForm)
2507
- )) == null ? void 0 : _d.translations[0];
2508
- if (!meaning) continue;
2509
- validWords.push({
2510
- kanjiForms: [{ kanjiForm }],
2511
- readings: [{ reading }],
2512
- translations: [
2513
- {
2514
- translation: typeof meaning === "string" ? meaning : meaning.translation
2515
- }
2516
- ]
2517
- });
2436
+ if (kanjiForm) {
2437
+ const reading = (_b = firstKfWords && firstKfWords.length > 0 ? word.readings[0] : word.readings.find(
2438
+ (reading2) => reading2.kanjiFormRestrictions && reading2.kanjiFormRestrictions.includes(kanjiForm)
2439
+ )) == null ? void 0 : _b.reading;
2440
+ if (!reading) continue;
2441
+ const translation = (_c = firstKfWords && firstKfWords.length > 0 ? word.meanings[0] : word.meanings.find(
2442
+ (m) => m.translations && m.kanjiFormRestrictions && m.kanjiFormRestrictions.includes(kanjiForm)
2443
+ )) == null ? void 0 : _c.translations.map(
2444
+ (t) => typeof t === "string" ? t : t.translation
2445
+ )[0];
2446
+ if (!translation) continue;
2447
+ validWords.push({
2448
+ kanjiForms: [{ kanjiForm }],
2449
+ readings: [{ reading }],
2450
+ translations: [
2451
+ {
2452
+ translation
2453
+ }
2454
+ ]
2455
+ });
2456
+ }
2518
2457
  if (validWords.length === 3) break;
2519
2458
  }
2520
2459
  if (validWords.length > 0) kanji2.words = validWords;
2521
2460
  }
2522
2461
  }
2523
2462
  if (svgList) {
2524
- let codePoint = kanji2.kanji.codePointAt(0);
2525
- if (codePoint !== void 0) {
2526
- codePoint = codePoint.toString(16);
2527
- const fileNames = [
2528
- `0${codePoint}.svg`,
2529
- `${codePoint}.svg`
2530
- ];
2531
- const svg = svgList.find(
2532
- (svgFile) => fileNames.includes(svgFile.toLowerCase())
2533
- );
2534
- if (svg) kanji2.svg = svg;
2535
- }
2463
+ const codePoint = kanji2.kanji.codePointAt(0).toString(16).toLowerCase();
2464
+ const svg = Array.isArray(svgList) ? svgList.find(
2465
+ (svgFile) => [`${codePoint}.svg`, `0${codePoint}.svg`].includes(
2466
+ svgFile.toLowerCase()
2467
+ )
2468
+ ) : svgList.get(kanji2.kanji);
2469
+ if (svg) kanji2.svg = svg;
2536
2470
  }
2537
2471
  if (kanji2.tags && dictKanji.isKokuji === true) {
2538
2472
  kanji2.kokuji = true;
2539
2473
  kanji2.tags.push("kanji::kokuji");
2540
- if (kanji2.meanings)
2541
- kanji2.meanings.splice(
2542
- kanji2.meanings.findIndex((meaning) => meaning === "(kokuji)"),
2543
- 1
2544
- );
2545
2474
  }
2546
- if (kanji2.tags)
2547
- kanji2.tags.push(
2548
- `kanji::strokes::${kanji2.strokes}`,
2549
- ...kanji2.frequency ? [`kanji::frequency::${kanji2.frequency}`] : [],
2550
- ...kanji2.grade ? [`kanji::grade::${kanji2.grade}`] : [],
2551
- ...kanji2.jlpt ? [`kanji::pre-2010_jlpt::${kanji2.jlpt.toLowerCase()}`] : [],
2552
- `kanji::onyomi::${(_f = (_e = kanji2.onyomi) == null ? void 0 : _e.length) != null ? _f : 0}`,
2553
- `kanji::kunyomi::${(_h = (_g = kanji2.kunyomi) == null ? void 0 : _g.length) != null ? _h : 0}`,
2554
- `kanji::nanori::${(_j = (_i = kanji2.nanori) == null ? void 0 : _i.length) != null ? _j : 0}`,
2555
- `kanji::words::${(_l = (_k = kanji2.words) == null ? void 0 : _k.length) != null ? _l : 0}`,
2556
- ...kanji2.svg ? ["kanji::has_svg"] : []
2557
- );
2475
+ kanji2.tags.push(
2476
+ `kanji::strokes::${kanji2.strokes}`,
2477
+ ...kanji2.frequency ? [`kanji::frequency::${kanji2.frequency}`] : [],
2478
+ ...kanji2.grade ? [`kanji::grade::${kanji2.grade}`] : [],
2479
+ ...kanji2.jlpt ? [`kanji::pre-2010_jlpt::${kanji2.jlpt.toLowerCase()}`] : [],
2480
+ `kanji::onyomi::${(_e = (_d = kanji2.onyomi) == null ? void 0 : _d.length) != null ? _e : 0}`,
2481
+ `kanji::kunyomi::${(_g = (_f = kanji2.kunyomi) == null ? void 0 : _f.length) != null ? _g : 0}`,
2482
+ `kanji::nanori::${(_i = (_h = kanji2.nanori) == null ? void 0 : _h.length) != null ? _i : 0}`,
2483
+ `kanji::words::${(_k = (_j = kanji2.words) == null ? void 0 : _j.length) != null ? _k : 0}`,
2484
+ ...kanji2.svg ? ["kanji::has_svg"] : []
2485
+ );
2558
2486
  return kanji2;
2559
2487
  } else return void 0;
2560
2488
  }
@@ -2581,22 +2509,20 @@ function getKanjiExtended(info, kanji, dict, useWords, jmDict, svgList, noteType
2581
2509
  kanjiObj.words = info.words;
2582
2510
  usedInfo = true;
2583
2511
  }
2584
- if (kanjiObj.tags) {
2585
- if (kanjiObj.components)
2586
- kanjiObj.tags.push(`kanji::components::${kanjiObj.components.length}`);
2587
- if (kanjiObj.mnemonic && kanjiObj.mnemonic.length > 0)
2588
- kanjiObj.tags.push("kanji::has_mnemonic");
2589
- if (useWords === true && kanjiObj.words && info.words)
2590
- kanjiObj.tags.forEach((tag, index) => {
2591
- if (tag.startsWith("kanji::words::") && kanjiObj.words && kanjiObj.tags) {
2592
- kanjiObj.tags.splice(
2593
- index,
2594
- 1,
2595
- `kanji::words::${kanjiObj.words.length}`
2596
- );
2597
- }
2598
- });
2599
- }
2512
+ if (kanjiObj.components)
2513
+ kanjiObj.tags.push(`kanji::components::${kanjiObj.components.length}`);
2514
+ if (kanjiObj.mnemonic && kanjiObj.mnemonic.length > 0)
2515
+ kanjiObj.tags.push("kanji::has_mnemonic");
2516
+ if (useWords === true && kanjiObj.words && info.words)
2517
+ kanjiObj.tags.forEach((tag, index) => {
2518
+ if (tag.startsWith("kanji::words::") && kanjiObj.words) {
2519
+ kanjiObj.tags.splice(
2520
+ index,
2521
+ 1,
2522
+ `kanji::words::${kanjiObj.words.length}`
2523
+ );
2524
+ }
2525
+ });
2600
2526
  if (sourceURL && info.externalInfo === true && usedInfo)
2601
2527
  kanjiObj.source = sourceURL;
2602
2528
  return kanjiObj;
@@ -2856,15 +2782,15 @@ function generateAnkiNotesFile(list, defaultNoteInfo) {
2856
2782
  if (typeof defaultNoteInfo.deckPath === "string" && result.deckPath === void 0)
2857
2783
  result.deckPath = defaultNoteInfo.deckPath;
2858
2784
  if (!hasHeader.guid && result.noteID) {
2859
- headers.push(`${noteHeaderKeys.guid}:${++headerCount}`);
2785
+ headers.push(`${noteHeaderKeys.guid}${++headerCount}`);
2860
2786
  hasHeader.guid = true;
2861
2787
  }
2862
2788
  if (!hasHeader.noteType && result.noteTypeName) {
2863
- headers.push(`${noteHeaderKeys.notetype}:${++headerCount}`);
2789
+ headers.push(`${noteHeaderKeys.notetype}${++headerCount}`);
2864
2790
  hasHeader.noteType = true;
2865
2791
  }
2866
2792
  if (!hasHeader.deckPath && result.deckPath) {
2867
- headers.push(`${noteHeaderKeys.deck}:${++headerCount}`);
2793
+ headers.push(`${noteHeaderKeys.deck}${++headerCount}`);
2868
2794
  hasHeader.deckPath = true;
2869
2795
  }
2870
2796
  const note = generateAnkiNote(result);
@@ -2894,15 +2820,16 @@ ${ankiNotes}`;
2894
2820
  generateAnkiNotesFile,
2895
2821
  getKanji,
2896
2822
  getKanjiExtended,
2823
+ getValidForms,
2897
2824
  getWord,
2898
2825
  getWordDefinitions,
2899
2826
  getWordDefinitionsWithFurigana,
2900
2827
  isGrammar,
2901
2828
  isKana,
2902
2829
  isKanji,
2830
+ isObjectArray,
2903
2831
  isRadical,
2904
2832
  isStringArray,
2905
- isValidArray,
2906
2833
  isValidArrayWithFirstElement,
2907
2834
  isWord,
2908
2835
  notSearchedForms,