henkan 0.6.1 → 0.8.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 (63) hide show
  1. package/README.md +4 -2
  2. package/dist/index.cjs.js +53 -165
  3. package/dist/index.cjs.js.map +3 -3
  4. package/dist/index.mjs +53 -163
  5. package/dist/index.mjs.map +2 -2
  6. package/dist/types/constants.d.ts +0 -3
  7. package/dist/types/constants.d.ts.map +1 -1
  8. package/dist/types/types.d.ts +21 -6
  9. package/dist/types/types.d.ts.map +1 -1
  10. package/dist/types/utils.d.ts +10 -14
  11. package/dist/types/utils.d.ts.map +1 -1
  12. package/docs/api/README.md +1 -1
  13. package/docs/api/functions/capitalizeString.md +1 -1
  14. package/docs/api/functions/convertJMdict.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/generateAnkiNote.md +1 -1
  20. package/docs/api/functions/generateAnkiNotesFile.md +1 -1
  21. package/docs/api/functions/getKanji.md +1 -1
  22. package/docs/api/functions/getKanjiExtended.md +1 -1
  23. package/docs/api/functions/getWord.md +1 -1
  24. package/docs/api/functions/isStringArray.md +1 -1
  25. package/docs/api/functions/isValidArray.md +1 -1
  26. package/docs/api/functions/isValidArrayWithFirstElement.md +1 -1
  27. package/docs/api/functions/shuffleArray.md +1 -1
  28. package/docs/api/functions/synthesizeSpeech.md +25 -13
  29. package/docs/api/interfaces/DictKanji.md +5 -5
  30. package/docs/api/interfaces/DictKanjiForm.md +4 -4
  31. package/docs/api/interfaces/DictKanjiMisc.md +5 -5
  32. package/docs/api/interfaces/DictKanjiReading.md +3 -3
  33. package/docs/api/interfaces/DictKanjiReadingMeaning.md +3 -3
  34. package/docs/api/interfaces/DictKanjiReadingMeaningGroup.md +3 -3
  35. package/docs/api/interfaces/DictKanjiWithRadicals.md +3 -3
  36. package/docs/api/interfaces/DictMeaning.md +11 -11
  37. package/docs/api/interfaces/DictRadical.md +4 -4
  38. package/docs/api/interfaces/DictReading.md +5 -5
  39. package/docs/api/interfaces/DictWord.md +8 -8
  40. package/docs/api/interfaces/ExamplePart.md +7 -7
  41. package/docs/api/interfaces/GlossSpecificNumber.md +31 -0
  42. package/docs/api/interfaces/Grammar.md +15 -15
  43. package/docs/api/interfaces/GrammarMeaning.md +3 -3
  44. package/docs/api/interfaces/Kana.md +11 -11
  45. package/docs/api/interfaces/Kanji.md +22 -22
  46. package/docs/api/interfaces/KanjiComponent.md +3 -3
  47. package/docs/api/interfaces/KanjiForm.md +4 -4
  48. package/docs/api/interfaces/NoteAndTag.md +3 -3
  49. package/docs/api/interfaces/Phrase.md +16 -4
  50. package/docs/api/interfaces/Radical.md +16 -16
  51. package/docs/api/interfaces/Reading.md +5 -5
  52. package/docs/api/interfaces/ResultEntry.md +7 -7
  53. package/docs/api/interfaces/TanakaExample.md +16 -6
  54. package/docs/api/interfaces/Translation.md +3 -3
  55. package/docs/api/interfaces/UsefulRegExps.md +8 -20
  56. package/docs/api/interfaces/Word.md +14 -14
  57. package/docs/api/type-aliases/Dict.md +1 -1
  58. package/docs/api/type-aliases/DictName.md +1 -1
  59. package/docs/api/type-aliases/EntryType.md +1 -1
  60. package/docs/api/type-aliases/JLPT.md +1 -1
  61. package/docs/api/type-aliases/Result.md +1 -1
  62. package/package.json +5 -5
  63. package/docs/api/functions/makeSSML.md +0 -33
package/dist/index.mjs CHANGED
@@ -10,60 +10,11 @@ var regexps = {
10
10
  hiragana: /[\u{3040}-\u{309F}]/u,
11
11
  katakana: /[\u{30A0}-\u{30FF}]/u,
12
12
  kanji: new RegExp("\\p{Script=Han}+", "u"),
13
- scriptSplit: /([\p{sc=Han}]+|[\p{sc=Hiragana}]+|[\p{sc=Katakana}]+|[^\p{sc=Han}\p{sc=Hiragana}\p{sc=Katakana}]+)/u,
14
13
  regExChars: /[-\/\\^$*+?.()|[\]{}]/,
15
14
  tanakaID: /#ID=(?<id>\d+_\d+)$/,
16
15
  tanakaPart: /(?<base>[^()\[\]\{\}\s]+)(?:\((?<reading>[\S]+)\))?(?:\[(?<glossnum>[\S]+)\])?(?:\{(?<inflection>[\S]+)\})?/,
17
16
  tanakaReferenceID: /#(?<entryid>[\d]+)/
18
17
  };
19
- var romajiMap = {
20
- A: "\u30A8\u30FC",
21
- B: "\u30D3\u30FC",
22
- C: "\u30B7\u30FC",
23
- D: "\u30C7\u30A3\u30FC",
24
- E: "\u30A4\u30FC",
25
- F: "\u30A8\u30D5",
26
- G: "\u30B8\u30FC",
27
- H: "\u30A8\u30A4\u30C1",
28
- I: "\u30A2\u30A4",
29
- J: "\u30B8\u30A7\u30FC",
30
- K: "\u30B1\u30FC",
31
- L: "\u30A8\u30EB",
32
- M: "\u30A8\u30E0",
33
- N: "\u30A8\u30CC",
34
- O: "\u30AA\u30FC",
35
- P: "\u30D4\u30FC",
36
- Q: "\u30AD\u30E5\u30FC",
37
- R: "\u30A2\u30FC\u30EB",
38
- S: "\u30A8\u30B9",
39
- T: "\u30C6\u30A3\u30FC",
40
- U: "\u30E6\u30FC",
41
- V: "\u30D6\u30A4",
42
- W: "\u30C0\u30D6\u30EA\u30E5\u30FC",
43
- X: "\u30A8\u30C3\u30AF\u30B9",
44
- Y: "\u30EF\u30A4",
45
- Z: "\u30BC\u30C3\u30C8"
46
- };
47
- var numberMap = {
48
- "0": "\u30BC\u30ED",
49
- "1": "\u30A4\u30C1",
50
- "2": "\u30CB",
51
- "3": "\u30B5\u30F3",
52
- "4": "\u30E8\u30F3",
53
- "5": "\u30B4",
54
- "6": "\u30ED\u30AF",
55
- "7": "\u30CA\u30CA",
56
- "8": "\u30CF\u30C1",
57
- "9": "\u30AD\u30E5\u30A6"
58
- };
59
- var symbolMap = {
60
- "\uFF04": "\u30C9\u30EB",
61
- "%": "\u30D1\u30FC\u30BB\u30F3\u30C8",
62
- "\xA5": "\u30A8\u30F3",
63
- "#": "\u30B7\u30E3\u30FC\u30D7",
64
- "@": "\u30A2\u30C3\u30C8",
65
- "&": "\u30A2\u30F3\u30C9"
66
- };
67
18
  var notSearchedForms = /* @__PURE__ */ new Set([
68
19
  "search-only kana form",
69
20
  "Search-only kana form",
@@ -1131,9 +1082,7 @@ var noteMap = /* @__PURE__ */ new Map([
1131
1082
  import libxml from "libxmljs2";
1132
1083
  import xml from "xml2js";
1133
1084
  import iconv from "iconv-lite";
1134
- import {
1135
- SynthesizeSpeechCommand
1136
- } from "@aws-sdk/client-polly";
1085
+ import fetch from "node-fetch";
1137
1086
  var Kuroshiro = __require("kuroshiro");
1138
1087
  var KuromojiAnalyzer = __require("kuroshiro-analyzer-kuromoji");
1139
1088
  function capitalizeString(value) {
@@ -1279,11 +1228,9 @@ function convertJMdict(xmlString, examples) {
1279
1228
  ).map((reading) => reading.reading)
1280
1229
  );
1281
1230
  const kanjiForms2 = entryObj.kanjiForms ? new Set(
1282
- entryObj.kanjiForms.filter(
1283
- (kanjiForm) => (!kanjiForm.notes || !kanjiForm.notes.some(
1284
- (note) => notSearchedForms.has(note)
1285
- )) && (entryObj.isCommon === void 0 || kanjiForm.commonness && kanjiForm.commonness.length > 0)
1286
- ).map((kanjiForm) => kanjiForm.form)
1231
+ entryObj.kanjiForms.map(
1232
+ (kanjiForm) => kanjiForm.form
1233
+ )
1287
1234
  ) : void 0;
1288
1235
  let existsExample = false;
1289
1236
  if (kanjiForms2 && kanjiForms2.size > 0 && tanakaParts) {
@@ -1465,9 +1412,9 @@ function convertRadkFile(radkBuffer, kanjiDic) {
1465
1412
  try {
1466
1413
  const fileParsed = iconv.decode(radkBuffer, "euc-jp").split("\n").filter((line) => !line.startsWith("#"));
1467
1414
  const radicals = [];
1468
- for (let i = 0; i <= fileParsed.length; i++) {
1415
+ for (let i = 0; i < fileParsed.length; i++) {
1469
1416
  const line = fileParsed[i];
1470
- if (!line) throw new Error("Invalid radkfile2 buffer");
1417
+ if (!line) continue;
1471
1418
  if (line.startsWith("$ ")) {
1472
1419
  const radical = {
1473
1420
  radical: line.charAt(2).trim(),
@@ -1475,7 +1422,7 @@ function convertRadkFile(radkBuffer, kanjiDic) {
1475
1422
  };
1476
1423
  let j = i + 1;
1477
1424
  let kanjiLine = fileParsed[j];
1478
- if (!kanjiLine) throw new Error("Invalid radkfile2 buffer");
1425
+ if (!kanjiLine) continue;
1479
1426
  const kanjiList = [];
1480
1427
  while (kanjiLine && !kanjiLine.startsWith("$ ")) {
1481
1428
  const kanjis = kanjiLine.split("");
@@ -1511,8 +1458,7 @@ function convertKradFile(kradBuffer, kanjiDic, katakanaList) {
1511
1458
  const split = line.split(" : ");
1512
1459
  const kanjiChar = split[0];
1513
1460
  const radicalsRow = split[1];
1514
- if (!kanjiChar || !radicalsRow)
1515
- throw new Error("Invalid kradfile2 buffer");
1461
+ if (!kanjiChar || !radicalsRow) continue;
1516
1462
  const kanji = {
1517
1463
  ...kanjiChar && radicalsRow && kanjiChar.length === 1 && radicalsRow.length > 0 ? { kanji: kanjiChar } : { kanji: "" },
1518
1464
  radicals: []
@@ -1723,11 +1669,9 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1723
1669
  ).map((reading) => reading.reading)
1724
1670
  );
1725
1671
  const kanjiForms = word.kanjiForms ? new Set(
1726
- word.kanjiForms.filter(
1727
- (kanjiForm) => (!kanjiForm.notes || !kanjiForm.notes.some(
1728
- (note) => notSearchedForms.has(note)
1729
- )) && (word.common === void 0 || kanjiForm.common === true)
1730
- ).map((kanjiForm) => kanjiForm.kanjiForm)
1672
+ word.kanjiForms.map(
1673
+ (kanjiForm) => kanjiForm.kanjiForm
1674
+ )
1731
1675
  ) : void 0;
1732
1676
  const kanjiFormExamples = [];
1733
1677
  const readingMatchingKanjiFormExamples = [];
@@ -1735,7 +1679,7 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1735
1679
  const partParts = /* @__PURE__ */ new Set();
1736
1680
  for (const example of examples)
1737
1681
  for (const part of example.parts) {
1738
- const readingAsReadingMatch = part.reading !== void 0 && readings.has(part.reading);
1682
+ const readingAsReadingMatch = part.reading !== void 0 && readings.has(part.reading) || part.inflectedForm !== void 0 && readings.has(part.inflectedForm);
1739
1683
  if (kanjiForms && kanjiForms.size > 0 && kanjiForms.has(part.baseForm)) {
1740
1684
  if (readingAsReadingMatch) {
1741
1685
  readingMatchingKanjiFormExamples.push(example);
@@ -1748,17 +1692,20 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1748
1692
  }
1749
1693
  const readingAsBaseFormMatch = readings.has(part.baseForm);
1750
1694
  const referenceIDMatch = part.referenceID !== void 0 && word.id !== void 0 && part.referenceID === word.id;
1751
- if (readingAsReadingMatch || readingAsBaseFormMatch || referenceIDMatch) {
1695
+ if (readingAsBaseFormMatch || referenceIDMatch) {
1752
1696
  readingExamples.push(example);
1753
- if (readingAsReadingMatch) partParts.add(part.reading);
1754
1697
  if (readingAsBaseFormMatch) partParts.add(part.baseForm);
1755
1698
  if (referenceIDMatch) partParts.add(part.referenceID);
1756
1699
  break;
1757
1700
  }
1758
1701
  }
1759
1702
  const exampleSize = readingMatchingKanjiFormExamples.length + kanjiFormExamples.length + readingExamples.length;
1760
- const includeKanjiFormExamples = readingMatchingKanjiFormExamples.length < Math.max(2, Math.round(exampleSize * 0.05));
1761
- const includeReadingExamples = word.usuallyInKana === void 0 && includeKanjiFormExamples && readingExamples.length >= Math.max(10, Math.round(exampleSize * 0.15)) || word.usuallyInKana === true && readingExamples.length >= Math.max(2, Math.round(exampleSize * 0.5));
1703
+ const includeReadingThreshold = Math.max(
1704
+ 10,
1705
+ Math.round(exampleSize * 0.5)
1706
+ );
1707
+ const includeKanjiFormExamples = word.kanjiForms !== void 0;
1708
+ const includeReadingExamples = readingExamples.length >= includeReadingThreshold && readingExamples.length >= readingMatchingKanjiFormExamples.length && readingExamples.length >= kanjiFormExamples.length || readingExamples.length >= includeReadingThreshold && word.usuallyInKana === true || word.kanjiForms === void 0;
1762
1709
  let wordExamples = [
1763
1710
  ...readingMatchingKanjiFormExamples,
1764
1711
  ...includeKanjiFormExamples ? kanjiFormExamples : [],
@@ -1770,7 +1717,11 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1770
1717
  outer: for (const example of wordExamples) {
1771
1718
  if (seenPhrases.has(example.phrase)) continue;
1772
1719
  for (const part of example.parts)
1773
- if (part.glossNumber === i + 1 && (partParts.has(part.baseForm) || part.reading && partParts.has(part.reading) || part.referenceID && partParts.has(part.referenceID))) {
1720
+ if (part.glossNumber === i + 1 && (partParts.has(part.baseForm) || includeReadingExamples && (part.reading && partParts.has(part.reading) || part.inflectedForm && partParts.has(part.inflectedForm) || part.referenceID && partParts.has(part.referenceID)))) {
1721
+ example.glossNumber = {
1722
+ wordId: word.id,
1723
+ glossNumber: i + 1
1724
+ };
1774
1725
  glossSpecificExamples.push(example);
1775
1726
  seenPhrases.add(example.phrase);
1776
1727
  break outer;
@@ -1789,7 +1740,8 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1789
1740
  word.phrases = (wordExamples.length > 5 ? wordExamples.slice(0, 5) : wordExamples).map((ex) => ({
1790
1741
  phrase: ex.furigana ?? ex.phrase,
1791
1742
  translation: ex.translation,
1792
- originalPhrase: ex.phrase
1743
+ originalPhrase: ex.phrase,
1744
+ ...ex.glossNumber ? { glossNumber: ex.glossNumber } : {}
1793
1745
  }));
1794
1746
  }
1795
1747
  return word;
@@ -1993,92 +1945,34 @@ function getKanjiExtended(kanjiChar, info, dict, useJpdbWords, jmDict, svgList,
1993
1945
  throw err;
1994
1946
  }
1995
1947
  }
1996
- var getCharType = (char) => {
1997
- if (regexps.kanji.test(char)) return "kanji";
1998
- if (regexps.hiragana.test(char)) return "hiragana";
1999
- if (regexps.katakana.test(char)) return "katakana";
2000
- return "other";
2001
- };
2002
- var splitByScript = (text) => text.match(regexps.scriptSplit) || [];
2003
- var convertToHiragana = (str) => str.replace(
2004
- regexps.katakana,
2005
- (c) => String.fromCharCode(c.charCodeAt(0) - 96)
2006
- );
2007
- var convertOtherToKatakana = (str) => str.split("").map((c) => {
2008
- if (romajiMap[c.toUpperCase()]) return romajiMap[c.toUpperCase()];
2009
- if (numberMap[c]) return numberMap[c];
2010
- if (symbolMap[c]) return symbolMap[c];
2011
- return c;
2012
- }).join("");
2013
- function makeSSML(formText, fullReading) {
2014
- let ssml = "";
2015
- const allTypes = Array.from(
2016
- formText
2017
- ).map((c) => getCharType(c));
2018
- const uniqueTypes = Array.from(new Set(allTypes));
2019
- if (uniqueTypes.length === 1)
2020
- switch (uniqueTypes[0]) {
2021
- case "kanji":
2022
- ssml = `<speak><phoneme alphabet="x-amazon-yomigana" ph="${fullReading}">${formText}</phoneme></speak>`;
2023
- break;
2024
- case "katakana":
2025
- ssml = `<speak><phoneme alphabet="x-amazon-pron-kana" ph="${formText}">${formText}</phoneme></speak>`;
2026
- break;
2027
- case "hiragana":
2028
- default:
2029
- ssml = `<speak>${formText}</speak>`;
2030
- }
2031
- else {
2032
- const segments = splitByScript(formText);
2033
- let pureKanjiReading = convertToHiragana(fullReading);
2034
- segments.forEach((seg) => {
2035
- const type = getCharType(
2036
- seg[0]
2037
- );
2038
- if (type !== "kanji") {
2039
- const converted = type === "other" ? convertToHiragana(convertOtherToKatakana(seg)) : convertToHiragana(seg);
2040
- pureKanjiReading = pureKanjiReading.replace(converted, "");
2041
- }
2042
- });
2043
- const kanjiSegments = segments.filter(
2044
- (seg) => getCharType(seg[0]) === "kanji"
2045
- );
2046
- let readingPointer = 0;
2047
- const ssmlSegments = segments.map((seg) => {
2048
- const type = getCharType(
2049
- seg[0]
2050
- );
2051
- if (type === "kanji") {
2052
- const expectedLength = pureKanjiReading.length / kanjiSegments.length;
2053
- const allocated = pureKanjiReading.slice(
2054
- readingPointer,
2055
- readingPointer + Math.ceil(expectedLength)
2056
- );
2057
- readingPointer += allocated.length;
2058
- return `<phoneme alphabet="x-amazon-yomigana" ph="${allocated}">${seg}</phoneme>`;
2059
- } else if (type === "katakana")
2060
- return `<phoneme alphabet="x-amazon-pron-kana" ph="${seg}">${seg}</phoneme>`;
2061
- else if (type === "other") {
2062
- const katakanaReading = convertOtherToKatakana(seg);
2063
- return `<phoneme alphabet="x-amazon-pron-kana" ph="${katakanaReading}">${seg}</phoneme>`;
2064
- } else return seg;
2065
- });
2066
- ssml = `<speak>${ssmlSegments.join("")}</speak>`;
2067
- }
2068
- return ssml;
2069
- }
2070
- async function synthesizeSpeech(client, ssmlText, options) {
1948
+ async function synthesizeSpeech(textOrSSML, apiKey, options) {
2071
1949
  return await new Promise(
2072
1950
  async (resolve, reject) => {
2073
1951
  try {
2074
- const command = new SynthesizeSpeechCommand({
2075
- Text: ssmlText,
2076
- TextType: "ssml",
2077
- ...options
1952
+ const res = await fetch("https://ttsfree.com/api/v1/tts", {
1953
+ method: "POST",
1954
+ body: JSON.stringify({
1955
+ text: textOrSSML,
1956
+ ...options
1957
+ }),
1958
+ headers: {
1959
+ "Content-Type": "application/json",
1960
+ apikey: apiKey
1961
+ }
2078
1962
  });
2079
- const response = await client.send(command);
2080
- const stream = response.AudioStream ? Buffer.from(await response.AudioStream.transformToByteArray()) : null;
2081
- resolve(stream);
1963
+ if (!res.ok)
1964
+ throw new Error(
1965
+ `TTS request failed:
1966
+ ${res.status}: ${res.statusText}`
1967
+ );
1968
+ const data = await res.json();
1969
+ if (data.status !== "success" || data.mess !== "success" || data.audioData.length === 0)
1970
+ throw new Error("Invalid TTS response data");
1971
+ const mp3Buffer = Buffer.from(
1972
+ data.audioData,
1973
+ "base64"
1974
+ );
1975
+ resolve(mp3Buffer);
2082
1976
  } catch (err) {
2083
1977
  reject(err);
2084
1978
  }
@@ -2125,7 +2019,7 @@ function generateAnkiNote(entry) {
2125
2019
  ).join("") : noKanjiForms
2126
2020
  ],
2127
2021
  entry.translations.map(
2128
- (translationEntry, index) => `${index > 2 ? "<details><summary>Show translation</summary>" : ""}${createEntry(`<span class="word word-translation">${translationEntry.translation}</span>`, translationEntry.notes)}${index > 2 ? "</details>" : ""}`
2022
+ (translationEntry, index) => `<span class="word word-index${entry.phrases && entry.phrases.some((phrase, index2) => index === index2 && phrase.glossNumber && phrase.glossNumber.wordId === entry.id && phrase.glossNumber.glossNumber === index + 1) ? " gloss-specific" : ""}">${index + 1}</span>${index > 2 ? "<details><summary>Show translation</summary>" : ""}${createEntry(`<span class="word word-translation">${translationEntry.translation}</span>`, translationEntry.notes)}${index > 2 ? "</details>" : ""}`
2129
2023
  ).join(""),
2130
2024
  entry.kanji ? entry.kanji.map(
2131
2025
  (kanjiEntry) => createEntry(
@@ -2134,11 +2028,11 @@ function generateAnkiNote(entry) {
2134
2028
  )
2135
2029
  ).join("") : '<span class="word word-kanji">(no kanji)</span>',
2136
2030
  entry.phrases ? entry.phrases.map(
2137
- (phraseEntry) => createEntry(
2031
+ (phraseEntry, index) => `<span class="word word-index${entry.translations.some((_translation, index2) => index === index2 && phraseEntry.glossNumber && phraseEntry.glossNumber.wordId === entry.id && phraseEntry.glossNumber.glossNumber === index2 + 1) ? " gloss-specific" : ""}">${index + 1}</span>${createEntry(
2138
2032
  `<span class="word word-phrase"><span class="word word-phrase-original">${phraseEntry.originalPhrase}</span><span class="word word-phrase-furigana">${phraseEntry.phrase}</span></span>`,
2139
2033
  [phraseEntry.translation],
2140
2034
  true
2141
- )
2035
+ )}`
2142
2036
  ).join("") : '<span class="word word-phrase">(no phrases) (Search on dictionaries!)</span>',
2143
2037
  ...entry.tags && entry.tags.length > 0 ? [
2144
2038
  entry.tags.map(
@@ -2319,14 +2213,10 @@ export {
2319
2213
  isValidArray,
2320
2214
  isValidArrayWithFirstElement,
2321
2215
  isWord,
2322
- makeSSML,
2323
2216
  notSearchedForms,
2324
2217
  noteMap,
2325
- numberMap,
2326
2218
  regexps,
2327
- romajiMap,
2328
2219
  shuffleArray,
2329
- symbolMap,
2330
2220
  synthesizeSpeech
2331
2221
  };
2332
2222
  //# sourceMappingURL=index.mjs.map