yomitan-core 0.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 (207) hide show
  1. package/README.md +485 -0
  2. package/dist/anki-connect-BQyCGW3O.cjs +513 -0
  3. package/dist/anki-connect-BQyCGW3O.cjs.map +1 -0
  4. package/dist/anki-connect-CPPuhyiQ.js +6 -0
  5. package/dist/anki-connect-DbrQHphS.js +495 -0
  6. package/dist/anki-connect-DbrQHphS.js.map +1 -0
  7. package/dist/anki-connect-DcheJrp-.cjs +6 -0
  8. package/dist/anki.cjs +1758 -0
  9. package/dist/anki.cjs.map +1 -0
  10. package/dist/anki.d.cts +751 -0
  11. package/dist/anki.d.cts.map +1 -0
  12. package/dist/anki.d.ts +751 -0
  13. package/dist/anki.d.ts.map +1 -0
  14. package/dist/anki.js +1751 -0
  15. package/dist/anki.js.map +1 -0
  16. package/dist/audio-D9DvYyB7.d.cts +48 -0
  17. package/dist/audio-D9DvYyB7.d.cts.map +1 -0
  18. package/dist/audio-DQulUkDM.d.ts +48 -0
  19. package/dist/audio-DQulUkDM.d.ts.map +1 -0
  20. package/dist/audio-url-generator-BXvQaqUi.cjs +4 -0
  21. package/dist/audio-url-generator-Dy2hb2Mm.cjs +414 -0
  22. package/dist/audio-url-generator-Dy2hb2Mm.cjs.map +1 -0
  23. package/dist/audio-url-generator-Qi0rfzHz.js +4 -0
  24. package/dist/audio-url-generator-pFQAB5Nb.js +390 -0
  25. package/dist/audio-url-generator-pFQAB5Nb.js.map +1 -0
  26. package/dist/audio.cjs +7 -0
  27. package/dist/audio.d.cts +86 -0
  28. package/dist/audio.d.cts.map +1 -0
  29. package/dist/audio.d.ts +86 -0
  30. package/dist/audio.d.ts.map +1 -0
  31. package/dist/audio.js +4 -0
  32. package/dist/batch-processor-BR-gB3H3.js +84 -0
  33. package/dist/batch-processor-BR-gB3H3.js.map +1 -0
  34. package/dist/batch-processor-CSF1acTw.cjs +3 -0
  35. package/dist/batch-processor-DFqM_L-_.cjs +91 -0
  36. package/dist/batch-processor-DFqM_L-_.cjs.map +1 -0
  37. package/dist/batch-processor-Quo9jUyf.js +3 -0
  38. package/dist/chunk-BCwAaXi7.cjs +31 -0
  39. package/dist/cjk-util-Dp0ZU0sh.cjs +167 -0
  40. package/dist/cjk-util-Dp0ZU0sh.cjs.map +1 -0
  41. package/dist/cjk-util-DubXBGDG.js +94 -0
  42. package/dist/cjk-util-DubXBGDG.js.map +1 -0
  43. package/dist/core-BUpclilG.d.cts +102 -0
  44. package/dist/core-BUpclilG.d.cts.map +1 -0
  45. package/dist/core-DFUj5GtA.d.ts +102 -0
  46. package/dist/core-DFUj5GtA.d.ts.map +1 -0
  47. package/dist/database.cjs +7 -0
  48. package/dist/database.d.cts +4 -0
  49. package/dist/database.d.ts +4 -0
  50. package/dist/database.js +5 -0
  51. package/dist/dictionary-D7l-qFt1.d.cts +316 -0
  52. package/dist/dictionary-D7l-qFt1.d.cts.map +1 -0
  53. package/dist/dictionary-_vzfBLWi.d.ts +316 -0
  54. package/dist/dictionary-_vzfBLWi.d.ts.map +1 -0
  55. package/dist/dictionary-data-util-CHnRdYZ9.cjs +378 -0
  56. package/dist/dictionary-data-util-CHnRdYZ9.cjs.map +1 -0
  57. package/dist/dictionary-data-util-CfOLfEDE.js +323 -0
  58. package/dist/dictionary-data-util-CfOLfEDE.js.map +1 -0
  59. package/dist/dictionary-database-BDC2f9zc.d.ts +58 -0
  60. package/dist/dictionary-database-BDC2f9zc.d.ts.map +1 -0
  61. package/dist/dictionary-database-CU4TsvCC.js +393 -0
  62. package/dist/dictionary-database-CU4TsvCC.js.map +1 -0
  63. package/dist/dictionary-database-DsOi04Sg.d.cts +58 -0
  64. package/dist/dictionary-database-DsOi04Sg.d.cts.map +1 -0
  65. package/dist/dictionary-database-lvFvftnO.cjs +412 -0
  66. package/dist/dictionary-database-lvFvftnO.cjs.map +1 -0
  67. package/dist/dictionary-importer-BkQQSBhm.d.ts +237 -0
  68. package/dist/dictionary-importer-BkQQSBhm.d.ts.map +1 -0
  69. package/dist/dictionary-importer-Cen1z6co.js +1821 -0
  70. package/dist/dictionary-importer-Cen1z6co.js.map +1 -0
  71. package/dist/dictionary-importer-DYmmWmcX.cjs +8 -0
  72. package/dist/dictionary-importer-Da3AuTZw.d.cts +237 -0
  73. package/dist/dictionary-importer-Da3AuTZw.d.cts.map +1 -0
  74. package/dist/dictionary-importer-Dhn75iZ4.cjs +1834 -0
  75. package/dist/dictionary-importer-Dhn75iZ4.cjs.map +1 -0
  76. package/dist/dictionary-importer-xWkel0h-.js +8 -0
  77. package/dist/dictionary-update-checker-BNE4pGTx.js +4 -0
  78. package/dist/dictionary-update-checker-Byjvifd2.cjs +75 -0
  79. package/dist/dictionary-update-checker-Byjvifd2.cjs.map +1 -0
  80. package/dist/dictionary-update-checker-YdpalZ41.cjs +4 -0
  81. package/dist/dictionary-update-checker-kKukiovj.js +69 -0
  82. package/dist/dictionary-update-checker-kKukiovj.js.map +1 -0
  83. package/dist/display-generator-BGVWiI0t.js +746 -0
  84. package/dist/display-generator-BGVWiI0t.js.map +1 -0
  85. package/dist/display-generator-BMQmG5Ov.cjs +9 -0
  86. package/dist/display-generator-BxZ7mBjP.js +9 -0
  87. package/dist/display-generator-DyP-HNzP.cjs +758 -0
  88. package/dist/display-generator-DyP-HNzP.cjs.map +1 -0
  89. package/dist/errors-BSezaJwm.cjs +35 -0
  90. package/dist/errors-BSezaJwm.cjs.map +1 -0
  91. package/dist/errors-DuuDSO5N.js +22 -0
  92. package/dist/errors-DuuDSO5N.js.map +1 -0
  93. package/dist/frequency-ranking-BXjfhhUQ.js +3 -0
  94. package/dist/frequency-ranking-Cx1kkIrw.cjs +3 -0
  95. package/dist/frequency-ranking-DEJMTMdg.js +159 -0
  96. package/dist/frequency-ranking-DEJMTMdg.js.map +1 -0
  97. package/dist/frequency-ranking-DVYxTXN-.cjs +166 -0
  98. package/dist/frequency-ranking-DVYxTXN-.cjs.map +1 -0
  99. package/dist/furigana-5HK97CY8.js +4 -0
  100. package/dist/furigana-9bBI9-qe.d.ts +47 -0
  101. package/dist/furigana-9bBI9-qe.d.ts.map +1 -0
  102. package/dist/furigana-B3-0y231.js +471 -0
  103. package/dist/furigana-B3-0y231.js.map +1 -0
  104. package/dist/furigana-CjOhzvZt.d.cts +47 -0
  105. package/dist/furigana-CjOhzvZt.d.cts.map +1 -0
  106. package/dist/furigana-DpZLcues.cjs +609 -0
  107. package/dist/furigana-DpZLcues.cjs.map +1 -0
  108. package/dist/furigana-h3v2ub4-.cjs +4 -0
  109. package/dist/import.cjs +12 -0
  110. package/dist/import.d.cts +107 -0
  111. package/dist/import.d.cts.map +1 -0
  112. package/dist/import.d.ts +107 -0
  113. package/dist/import.d.ts.map +1 -0
  114. package/dist/import.js +9 -0
  115. package/dist/index.cjs +275 -0
  116. package/dist/index.cjs.map +1 -0
  117. package/dist/index.d.cts +211 -0
  118. package/dist/index.d.cts.map +1 -0
  119. package/dist/index.d.ts +211 -0
  120. package/dist/index.d.ts.map +1 -0
  121. package/dist/index.js +238 -0
  122. package/dist/index.js.map +1 -0
  123. package/dist/json-DGd-cunA.js +17 -0
  124. package/dist/json-DGd-cunA.js.map +1 -0
  125. package/dist/json-DKWp-B7Y.cjs +30 -0
  126. package/dist/json-DKWp-B7Y.cjs.map +1 -0
  127. package/dist/language-KN_u-nTR.d.ts +104 -0
  128. package/dist/language-KN_u-nTR.d.ts.map +1 -0
  129. package/dist/language-xAbQxgXc.d.cts +104 -0
  130. package/dist/language-xAbQxgXc.d.cts.map +1 -0
  131. package/dist/language.cjs +15626 -0
  132. package/dist/language.cjs.map +1 -0
  133. package/dist/language.d.cts +959 -0
  134. package/dist/language.d.cts.map +1 -0
  135. package/dist/language.d.ts +959 -0
  136. package/dist/language.d.ts.map +1 -0
  137. package/dist/language.js +15522 -0
  138. package/dist/language.js.map +1 -0
  139. package/dist/log-D8KtR3aP.cjs +67 -0
  140. package/dist/log-D8KtR3aP.cjs.map +1 -0
  141. package/dist/log-hgSll-dS.js +60 -0
  142. package/dist/log-hgSll-dS.js.map +1 -0
  143. package/dist/lookup.cjs +13 -0
  144. package/dist/lookup.d.cts +161 -0
  145. package/dist/lookup.d.cts.map +1 -0
  146. package/dist/lookup.d.ts +161 -0
  147. package/dist/lookup.d.ts.map +1 -0
  148. package/dist/lookup.js +10 -0
  149. package/dist/media-loader-BABA_E4W.js +3 -0
  150. package/dist/media-loader-Ce9cuANS.cjs +21 -0
  151. package/dist/media-loader-Ce9cuANS.cjs.map +1 -0
  152. package/dist/media-loader-qRti-Q6h.js +14 -0
  153. package/dist/media-loader-qRti-Q6h.js.map +1 -0
  154. package/dist/media-loader-xlUGaJrx.cjs +3 -0
  155. package/dist/multi-language-transformer-AlxOM6b3.js +637 -0
  156. package/dist/multi-language-transformer-AlxOM6b3.js.map +1 -0
  157. package/dist/multi-language-transformer-MdbQBBOt.cjs +685 -0
  158. package/dist/multi-language-transformer-MdbQBBOt.cjs.map +1 -0
  159. package/dist/multi-language-transformer-SEhcJXEB.d.ts +63 -0
  160. package/dist/multi-language-transformer-SEhcJXEB.d.ts.map +1 -0
  161. package/dist/multi-language-transformer-Ul9mbRce.d.cts +63 -0
  162. package/dist/multi-language-transformer-Ul9mbRce.d.cts.map +1 -0
  163. package/dist/pronunciation-generator-BtBc4q_V.js +397 -0
  164. package/dist/pronunciation-generator-BtBc4q_V.js.map +1 -0
  165. package/dist/pronunciation-generator-CBYdXYou.js +4 -0
  166. package/dist/pronunciation-generator-CFbZlf5J.cjs +445 -0
  167. package/dist/pronunciation-generator-CFbZlf5J.cjs.map +1 -0
  168. package/dist/pronunciation-generator-DOz9hEuk.cjs +4 -0
  169. package/dist/render.cjs +2796 -0
  170. package/dist/render.cjs.map +1 -0
  171. package/dist/render.d.cts +424 -0
  172. package/dist/render.d.cts.map +1 -0
  173. package/dist/render.d.ts +424 -0
  174. package/dist/render.d.ts.map +1 -0
  175. package/dist/render.js +2777 -0
  176. package/dist/render.js.map +1 -0
  177. package/dist/sentence-parser-BPAJNzqW.js +126 -0
  178. package/dist/sentence-parser-BPAJNzqW.js.map +1 -0
  179. package/dist/sentence-parser-BVIOI64h.cjs +132 -0
  180. package/dist/sentence-parser-BVIOI64h.cjs.map +1 -0
  181. package/dist/sentence-parser-BoHO3cHn.js +5 -0
  182. package/dist/sentence-parser-DQVLSW0z.cjs +5 -0
  183. package/dist/structured-content-generator-BtOApkTW.cjs +4 -0
  184. package/dist/structured-content-generator-Bx62RYa8.js +4 -0
  185. package/dist/structured-content-generator-CLnybumI.js +276 -0
  186. package/dist/structured-content-generator-CLnybumI.js.map +1 -0
  187. package/dist/structured-content-generator-DrwkB0-k.cjs +282 -0
  188. package/dist/structured-content-generator-DrwkB0-k.cjs.map +1 -0
  189. package/dist/text-utilities-B7PIythe.js +8 -0
  190. package/dist/text-utilities-B7PIythe.js.map +1 -0
  191. package/dist/text-utilities-Del2Ivkg.cjs +15 -0
  192. package/dist/text-utilities-Del2Ivkg.cjs.map +1 -0
  193. package/dist/translator-CRPlPzqi.cjs +1545 -0
  194. package/dist/translator-CRPlPzqi.cjs.map +1 -0
  195. package/dist/translator-CWgG5drA.js +1539 -0
  196. package/dist/translator-CWgG5drA.js.map +1 -0
  197. package/dist/translator-CaGtJvnQ.cjs +6 -0
  198. package/dist/translator-Cc6OGxrW.d.ts +180 -0
  199. package/dist/translator-Cc6OGxrW.d.ts.map +1 -0
  200. package/dist/translator-CcA-s-W4.d.cts +180 -0
  201. package/dist/translator-CcA-s-W4.d.cts.map +1 -0
  202. package/dist/translator-CuJOTK6l.js +6 -0
  203. package/dist/utilities-C-lbZaJE.cjs +52 -0
  204. package/dist/utilities-C-lbZaJE.cjs.map +1 -0
  205. package/dist/utilities-bi3EF-q5.js +33 -0
  206. package/dist/utilities-bi3EF-q5.js.map +1 -0
  207. package/package.json +102 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display-generator-DyP-HNzP.cjs","names":["doc: Document","html: string","source: Document","name: string","template: HTMLTemplateElement","removeNodes: Node[]","doc: Document","contentManager: ContentManager","templateHtml: string","StructuredContentGenerator","PronunciationGenerator","language: string","dictionaryEntry: Dictionary.TermDictionaryEntry","dictionaryInfo: DictionaryImporter.Summary[]","dictionaryContentArray: string[]","dictionaryEntry: Dictionary.KanjiDictionaryEntry","name: string","headword: Dictionary.TermHeadword","headwordIndex: number","pronunciations: Dictionary.TermPronunciation[]","inflectionRuleChain: Dictionary.InflectionRuleChainCandidate","source: Dictionary.InflectionSource","inflection: Dictionary.InflectionRule","definition: Dictionary.TermDefinition","dictionaryTag: Dictionary.Tag","headwords: Dictionary.TermHeadword[]","uniqueTerms: Set<string>","uniqueReadings: Set<string>","entry: DictionaryData.TermGlossaryContent","dictionary: string","text: string","data: DictionaryData.TermGlossaryImage","content: StructuredContent.Content","disambiguation: string","character: string","reading: string","details: Dictionary.KanjiStat[]","details: Dictionary.KanjiStat","tag: Dictionary.Tag","tagInfo: DictionaryDataUtil.TagGroup","totalHeadwordCount: number","category: string","details: DictionaryDataUtil.DictionaryGroupedPronunciations","details: DictionaryDataUtil.GroupedPronunciation","pronunciation: Dictionary.PhoneticTranscription","pitchAccent: Dictionary.PitchAccent","container: HTMLElement","exclusiveTerms: string[]","exclusiveReadings: string[]","details:\n | DictionaryDataUtil.DictionaryFrequency<DictionaryDataUtil.TermFrequency>\n | DictionaryDataUtil.DictionaryFrequency<DictionaryDataUtil.KanjiFrequency>","kanji: boolean","details: DictionaryDataUtil.TermFrequency","dictionaryAlias: string","freqCount: string | undefined","details: DictionaryDataUtil.KanjiFrequency","node: HTMLElement","values: DictionaryDataUtil.FrequencyValue[]","node2","createItem: (item: TItem, arg: TExtraArg) => Node | null","detailsArray: TItem[]","arg?: TExtraArg","term: string","addText: (element: HTMLElement, text: string) => void","value: string","language?: string","element: HTMLElement","language: string | undefined","content: string","termPronunciations: Dictionary.TermPronunciation[]","wordClasses: string[]","element: Element | DocumentFragment","selector: string"],"sources":["../src/render/html-template-collection.ts","../src/render/display-generator.ts"],"sourcesContent":["/*\n * Copyright (C) 2023-2025 Yomitan Authors\n * Copyright (C) 2020-2022 Yomichan Authors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\n/**\n * A collection of HTML templates parsed from raw HTML strings.\n * Templates are identified by their `id` attribute, which must end with `-template`.\n * The prefix before `-template` is used as the template name.\n */\nexport class HtmlTemplateCollection {\n private _templates: Map<string, HTMLTemplateElement>;\n private _document: Document;\n\n /**\n * Creates a new HtmlTemplateCollection.\n * @param doc - The Document object to use for DOM operations.\n */\n constructor(doc: Document) {\n this._templates = new Map();\n this._document = doc;\n }\n\n /**\n * Loads templates from a raw HTML string.\n * @param html - The HTML string containing `<template>` elements.\n */\n loadFromString(html: string): void {\n const parser = new (this._document.defaultView as unknown as { DOMParser: typeof DOMParser }).DOMParser();\n const templatesDocument = parser.parseFromString(html, 'text/html');\n this.load(templatesDocument);\n }\n\n /**\n * Loads templates from a Document source.\n * @param source - The Document containing template elements.\n */\n load(source: Document): void {\n const pattern = /^([\\w\\W]+)-template$/;\n for (const template of Array.from(source.querySelectorAll('template')) as HTMLTemplateElement[]) {\n const match = pattern.exec(template.id);\n if (match === null) {\n continue;\n }\n this._prepareTemplate(template);\n this._templates.set(match[1], template);\n }\n }\n\n /**\n * Instantiates a template by name, returning the first element child as a deep clone.\n * @param name - The template name (without the `-template` suffix).\n * @returns The cloned first element child.\n * @throws Error if the template or its content element is not found.\n */\n instantiate(name: string): HTMLElement {\n const { firstElementChild } = this.getTemplateContent(name);\n if (firstElementChild === null) {\n throw new Error(`Failed to find template content element: ${name}`);\n }\n return this._document.importNode(firstElementChild, true) as HTMLElement;\n }\n\n /**\n * Instantiates a template by name, returning the entire content as a DocumentFragment clone.\n * @param name - The template name (without the `-template` suffix).\n * @returns The cloned DocumentFragment.\n */\n instantiateFragment(name: string): DocumentFragment {\n return this._document.importNode(this.getTemplateContent(name), true);\n }\n\n /**\n * Gets the content DocumentFragment of a named template.\n * @param name - The template name (without the `-template` suffix).\n * @returns The template's content DocumentFragment.\n * @throws Error if the template is not found.\n */\n getTemplateContent(name: string): DocumentFragment {\n const template = this._templates.get(name);\n if (typeof template === 'undefined') {\n throw new Error(`Failed to find template: ${name}`);\n }\n return template.content;\n }\n\n /**\n * Returns an iterator over all template elements.\n */\n getAllTemplates(): IterableIterator<HTMLTemplateElement> {\n return this._templates.values();\n }\n\n // Private\n\n private _prepareTemplate(template: HTMLTemplateElement): void {\n if (template.dataset.removeWhitespaceText === 'true') {\n this._removeWhitespaceText(template);\n }\n }\n\n private _removeWhitespaceText(template: HTMLTemplateElement): void {\n const { content } = template;\n const { TEXT_NODE } = this._document.defaultView\n ? (this._document.defaultView as unknown as { Node: typeof Node }).Node\n : { TEXT_NODE: 3 };\n const iterator = this._document.createNodeIterator(content, 4 /* NodeFilter.SHOW_TEXT */);\n const removeNodes: Node[] = [];\n while (true) {\n const node = iterator.nextNode();\n if (node === null) {\n break;\n }\n if (node.nodeType === TEXT_NODE && (node.nodeValue ?? '').trim().length === 0) {\n removeNodes.push(node);\n }\n }\n for (const node of removeNodes) {\n const { parentNode } = node;\n if (parentNode !== null) {\n parentNode.removeChild(node);\n }\n }\n }\n}\n","/*\n * Copyright (C) 2023-2025 Yomitan Authors\n * Copyright (C) 2019-2022 Yomichan Authors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\nimport { distributeFurigana } from '../language/ja/furigana.js';\nimport { getLanguageFromText } from '../language/text-utilities.js';\nimport type * as DictionaryDataUtil from '../types/dictionary-data-util.js';\nimport type * as DictionaryData from '../types/dictionary-data.js';\nimport type * as DictionaryImporter from '../types/dictionary-importer.js';\nimport type * as Dictionary from '../types/dictionary.js';\nimport type * as StructuredContent from '../types/structured-content.js';\nimport {\n getDisambiguations,\n getGroupedPronunciations,\n getTermFrequency,\n groupKanjiFrequencies,\n groupTermFrequencies,\n groupTermTags,\n isNonNounVerbOrAdjective,\n} from '../util/dictionary-data-util.js';\nimport type { ContentManager } from './content-manager.js';\nimport { HtmlTemplateCollection } from './html-template-collection.js';\nimport { getKanaMorae, getPitchCategory, isCodePointKanji } from './japanese-util.js';\nimport type { PitchCategory } from './japanese-util.js';\nimport { PronunciationGenerator } from './pronunciation-generator.js';\nimport { StructuredContentGenerator } from './structured-content-generator.js';\n\n/**\n * Generates DOM elements for displaying dictionary entries.\n * This is the main rendering class that creates term entries, kanji entries,\n * and all associated sub-elements (headwords, definitions, tags, frequencies, etc.).\n */\nexport class DisplayGenerator {\n private _contentManager: ContentManager;\n private _templates: HtmlTemplateCollection;\n private _structuredContentGenerator: StructuredContentGenerator;\n private _pronunciationGenerator: PronunciationGenerator;\n private _language: string;\n private _document: Document;\n\n /**\n * Creates a new DisplayGenerator.\n * @param doc - The Document object to use for DOM operations.\n * @param contentManager - The content manager for loading media.\n * @param templateHtml - The HTML string containing display templates.\n */\n constructor(doc: Document, contentManager: ContentManager, templateHtml: string) {\n this._document = doc;\n this._contentManager = contentManager;\n this._templates = new HtmlTemplateCollection(doc);\n this._templates.loadFromString(templateHtml);\n this._structuredContentGenerator = new StructuredContentGenerator(this._contentManager, doc);\n this._pronunciationGenerator = new PronunciationGenerator(doc);\n this._language = 'ja';\n }\n\n /** The current content manager. */\n get contentManager(): ContentManager {\n return this._contentManager;\n }\n\n set contentManager(contentManager: ContentManager) {\n this._contentManager = contentManager;\n }\n\n /**\n * Updates the target language for rendering.\n * @param language - The BCP 47 language tag (e.g. 'ja', 'zh').\n */\n updateLanguage(language: string): void {\n this._language = language;\n }\n\n /**\n * Creates a complete term entry element from a dictionary entry.\n * @param dictionaryEntry - The term dictionary entry data.\n * @param dictionaryInfo - Array of dictionary summary information.\n * @returns An HTMLElement representing the full term entry.\n */\n createTermEntry(\n dictionaryEntry: Dictionary.TermDictionaryEntry,\n dictionaryInfo: DictionaryImporter.Summary[],\n ): HTMLElement {\n const node = this._instantiate('term-entry');\n\n const headwordsContainer = this._querySelector(node, '.headword-list');\n const inflectionRuleChainsContainer = this._querySelector(node, '.inflection-rule-chains');\n const groupedPronunciationsContainer = this._querySelector(node, '.pronunciation-group-list');\n const frequencyGroupListContainer = this._querySelector(node, '.frequency-group-list');\n const definitionsContainer = this._querySelector(node, '.definition-list');\n const headwordTagsContainer = this._querySelector(node, '.headword-list-tag-list');\n\n const { headwords, type, inflectionRuleChainCandidates, definitions, frequencies, pronunciations } =\n dictionaryEntry;\n const groupedPronunciations = getGroupedPronunciations(dictionaryEntry);\n const pronunciationCount = groupedPronunciations.reduce((i, v) => i + v.pronunciations.length, 0);\n const groupedFrequencies = groupTermFrequencies(dictionaryEntry, dictionaryInfo);\n const termTags = groupTermTags(dictionaryEntry);\n\n const uniqueTerms = new Set<string>();\n const uniqueReadings = new Set<string>();\n const primaryMatchTypes = new Set<Dictionary.TermSourceMatchType>();\n for (const { term, reading, sources } of headwords) {\n uniqueTerms.add(term);\n uniqueReadings.add(reading);\n for (const { matchType, isPrimary } of sources) {\n if (!isPrimary) {\n continue;\n }\n primaryMatchTypes.add(matchType);\n }\n }\n\n node.dataset.format = type;\n node.dataset.headwordCount = `${headwords.length}`;\n node.dataset.definitionCount = `${definitions.length}`;\n node.dataset.pronunciationDictionaryCount = `${groupedPronunciations.length}`;\n node.dataset.pronunciationCount = `${pronunciationCount}`;\n node.dataset.uniqueTermCount = `${uniqueTerms.size}`;\n node.dataset.uniqueReadingCount = `${uniqueReadings.size}`;\n node.dataset.frequencyCount = `${frequencies.length}`;\n node.dataset.groupedFrequencyCount = `${groupedFrequencies.length}`;\n node.dataset.primaryMatchTypes = [...primaryMatchTypes].join(' ');\n\n for (let i = 0, ii = headwords.length; i < ii; ++i) {\n const node2 = this._createTermHeadword(headwords[i], i, pronunciations);\n node2.dataset.index = `${i}`;\n headwordsContainer.appendChild(node2);\n }\n headwordsContainer.dataset.count = `${headwords.length}`;\n\n this._appendMultiple(\n inflectionRuleChainsContainer,\n this._createInflectionRuleChain.bind(this),\n inflectionRuleChainCandidates,\n );\n this._appendMultiple(\n frequencyGroupListContainer,\n this._createFrequencyGroup.bind(this),\n groupedFrequencies,\n false,\n );\n this._appendMultiple(\n groupedPronunciationsContainer,\n this._createGroupedPronunciation.bind(this),\n groupedPronunciations,\n );\n this._appendMultiple(headwordTagsContainer, this._createTermTag.bind(this), termTags, headwords.length);\n\n for (const term of uniqueTerms) {\n headwordTagsContainer.appendChild(this._createSearchTag(term));\n }\n for (const reading of uniqueReadings) {\n if (uniqueTerms.has(reading)) {\n continue;\n }\n headwordTagsContainer.appendChild(this._createSearchTag(reading));\n }\n\n // Add definitions\n const dictionaryTag = this._createDictionaryTag('');\n for (let i = 0, ii = definitions.length; i < ii; ++i) {\n const definition = definitions[i];\n const { dictionary, dictionaryAlias } = definition;\n\n if (dictionaryTag.dictionaries.includes(dictionary)) {\n dictionaryTag.redundant = true;\n } else {\n dictionaryTag.redundant = false;\n dictionaryTag.dictionaries.push(dictionary);\n dictionaryTag.name = dictionaryAlias;\n dictionaryTag.content = [dictionary];\n\n const currentDictionaryInfo = dictionaryInfo.find(({ title }) => title === dictionary);\n if (currentDictionaryInfo) {\n const dictionaryContentArray: string[] = [];\n dictionaryContentArray.push(currentDictionaryInfo.title);\n if (currentDictionaryInfo.author) {\n dictionaryContentArray.push(`Author: ${currentDictionaryInfo.author}`);\n }\n if (currentDictionaryInfo.description) {\n dictionaryContentArray.push(`Description: ${currentDictionaryInfo.description}`);\n }\n if (currentDictionaryInfo.url) {\n dictionaryContentArray.push(`URL: ${currentDictionaryInfo.url}`);\n }\n\n const totalTerms = currentDictionaryInfo?.counts?.terms?.total;\n if (totalTerms !== undefined && totalTerms > 0) {\n dictionaryContentArray.push(`Term Count: ${totalTerms.toString()}`);\n }\n\n dictionaryTag.content = dictionaryContentArray;\n }\n }\n\n const node2 = this._createTermDefinition(definition, dictionaryTag, headwords, uniqueTerms, uniqueReadings);\n node2.dataset.index = `${i}`;\n definitionsContainer.appendChild(node2);\n }\n definitionsContainer.dataset.count = `${definitions.length}`;\n\n return node;\n }\n\n /**\n * Creates a complete kanji entry element from a dictionary entry.\n * @param dictionaryEntry - The kanji dictionary entry data.\n * @param dictionaryInfo - Array of dictionary summary information.\n * @returns An HTMLElement representing the full kanji entry.\n */\n createKanjiEntry(\n dictionaryEntry: Dictionary.KanjiDictionaryEntry,\n dictionaryInfo: DictionaryImporter.Summary[],\n ): HTMLElement {\n const node = this._instantiate('kanji-entry');\n node.dataset.dictionary = dictionaryEntry.dictionary;\n\n const glyphContainer = this._querySelector(node, '.kanji-glyph');\n const frequencyGroupListContainer = this._querySelector(node, '.frequency-group-list');\n const tagContainer = this._querySelector(node, '.kanji-tag-list');\n const definitionsContainer = this._querySelector(node, '.kanji-gloss-list');\n const chineseReadingsContainer = this._querySelector(node, '.kanji-readings-chinese');\n const japaneseReadingsContainer = this._querySelector(node, '.kanji-readings-japanese');\n const statisticsContainer = this._querySelector(node, '.kanji-statistics');\n const classificationsContainer = this._querySelector(node, '.kanji-classifications');\n const codepointsContainer = this._querySelector(node, '.kanji-codepoints');\n const dictionaryIndicesContainer = this._querySelector(node, '.kanji-dictionary-indices');\n\n this._setTextContent(glyphContainer, dictionaryEntry.character, this._language);\n if (this._language === 'ja') {\n glyphContainer.style.fontFamily = 'kanji-stroke-orders, sans-serif';\n }\n const groupedFrequencies = groupKanjiFrequencies(dictionaryEntry.frequencies, dictionaryInfo);\n\n const dictionaryTag = this._createDictionaryTag('');\n dictionaryTag.name = dictionaryEntry.dictionaryAlias;\n dictionaryTag.content = [dictionaryEntry.dictionary];\n const currentDictionaryInfo = dictionaryInfo.find(({ title }) => title === dictionaryEntry.dictionary);\n if (currentDictionaryInfo) {\n const dictionaryContentArray: string[] = [];\n dictionaryContentArray.push(currentDictionaryInfo.title);\n if (currentDictionaryInfo.author) {\n dictionaryContentArray.push(`Author: ${currentDictionaryInfo.author}`);\n }\n if (currentDictionaryInfo.description) {\n dictionaryContentArray.push(`Description: ${currentDictionaryInfo.description}`);\n }\n if (currentDictionaryInfo.url) {\n dictionaryContentArray.push(`URL: ${currentDictionaryInfo.url}`);\n }\n\n const totalKanji = currentDictionaryInfo?.counts?.kanji?.total;\n if (totalKanji !== undefined && totalKanji > 0) {\n dictionaryContentArray.push(`Kanji Count: ${totalKanji.toString()}`);\n }\n\n dictionaryTag.content = dictionaryContentArray;\n }\n\n this._appendMultiple(\n frequencyGroupListContainer,\n this._createFrequencyGroup.bind(this),\n groupedFrequencies,\n true,\n );\n this._appendMultiple(tagContainer, this._createTag.bind(this), [...dictionaryEntry.tags, dictionaryTag]);\n this._appendMultiple(definitionsContainer, this._createKanjiDefinition.bind(this), dictionaryEntry.definitions);\n this._appendMultiple(chineseReadingsContainer, this._createKanjiReading.bind(this), dictionaryEntry.onyomi);\n this._appendMultiple(japaneseReadingsContainer, this._createKanjiReading.bind(this), dictionaryEntry.kunyomi);\n\n statisticsContainer.appendChild(this._createKanjiInfoTable(dictionaryEntry.stats.misc));\n classificationsContainer.appendChild(this._createKanjiInfoTable(dictionaryEntry.stats.class));\n codepointsContainer.appendChild(this._createKanjiInfoTable(dictionaryEntry.stats.code));\n dictionaryIndicesContainer.appendChild(this._createKanjiInfoTable(dictionaryEntry.stats.index));\n\n return node;\n }\n\n /**\n * Creates an empty footer notification element.\n */\n createEmptyFooterNotification(): HTMLElement {\n return this._instantiate('footer-notification');\n }\n\n /**\n * Instantiates a named template, returning the first element child.\n * @param name - The template name.\n */\n instantiateTemplate(name: string): HTMLElement {\n return this._instantiate(name);\n }\n\n /**\n * Instantiates a named template, returning the full DocumentFragment.\n * @param name - The template name.\n */\n instantiateTemplateFragment(name: string): DocumentFragment {\n return this._templates.instantiateFragment(name);\n }\n\n // Private\n\n private _createTermHeadword(\n headword: Dictionary.TermHeadword,\n headwordIndex: number,\n pronunciations: Dictionary.TermPronunciation[],\n ): HTMLElement {\n const { term, reading, tags, sources } = headword;\n\n let isPrimaryAny = false;\n const matchTypes = new Set<string>();\n const matchSources = new Set<string>();\n for (const { matchType, matchSource, isPrimary } of sources) {\n if (isPrimary) {\n isPrimaryAny = true;\n }\n matchTypes.add(matchType);\n matchSources.add(matchSource);\n }\n\n const node = this._instantiate('headword');\n\n const termContainer = this._querySelector(node, '.headword-term');\n\n node.dataset.isPrimary = `${isPrimaryAny}`;\n node.dataset.readingIsSame = `${reading === term}`;\n node.dataset.frequency = getTermFrequency(tags);\n node.dataset.matchTypes = [...matchTypes].join(' ');\n node.dataset.matchSources = [...matchSources].join(' ');\n\n const { wordClasses } = headword;\n const pronunciationCategories = this._getPronunciationCategories(\n reading,\n pronunciations,\n wordClasses,\n headwordIndex,\n );\n if (pronunciationCategories !== null) {\n node.dataset.pronunciationCategories = pronunciationCategories;\n }\n if (wordClasses.length > 0) {\n node.dataset.wordClasses = wordClasses.join(' ');\n }\n\n const headwordReading = this._querySelector(node, '.headword-reading');\n this._setTextContent(headwordReading, reading);\n\n this._appendFurigana(termContainer, term, reading, this._appendKanjiLinks.bind(this));\n\n return node;\n }\n\n private _createInflectionRuleChain(\n inflectionRuleChain: Dictionary.InflectionRuleChainCandidate,\n ): HTMLElement | null {\n const { source, inflectionRules } = inflectionRuleChain;\n if (!Array.isArray(inflectionRules) || inflectionRules.length === 0) {\n return null;\n }\n const fragment = this._instantiate('inflection-rule-chain');\n\n const sourceIcon = this._getInflectionSourceIcon(source);\n fragment.appendChild(sourceIcon);\n\n this._appendMultiple(fragment, this._createTermInflection.bind(this), inflectionRules);\n return fragment;\n }\n\n private _getInflectionSourceIcon(source: Dictionary.InflectionSource): HTMLElement {\n const icon = this._document.createElement('span');\n icon.classList.add('inflection-source-icon');\n icon.dataset.inflectionSource = source;\n switch (source) {\n case 'dictionary':\n icon.title = 'Dictionary Deinflection';\n return icon;\n case 'algorithm':\n icon.title = 'Algorithm Deinflection';\n return icon;\n case 'both':\n icon.title = 'Dictionary and Algorithm Deinflection';\n return icon;\n }\n }\n\n private _createTermInflection(inflection: Dictionary.InflectionRule): DocumentFragment {\n const { name, description } = inflection;\n const fragment = this._templates.instantiateFragment('inflection');\n const node = this._querySelector(fragment, '.inflection');\n this._setTextContent(node, name);\n if (description) {\n node.title = description;\n }\n node.dataset.reason = name;\n return fragment;\n }\n\n private _createTermDefinition(\n definition: Dictionary.TermDefinition,\n dictionaryTag: Dictionary.Tag,\n headwords: Dictionary.TermHeadword[],\n uniqueTerms: Set<string>,\n uniqueReadings: Set<string>,\n ): HTMLElement {\n const { dictionary, tags, headwordIndices, entries } = definition;\n const disambiguations = getDisambiguations(headwords, headwordIndices, uniqueTerms, uniqueReadings);\n\n const node = this._instantiate('definition-item');\n\n const tagListContainer = this._querySelector(node, '.definition-tag-list');\n const onlyListContainer = this._querySelector(node, '.definition-disambiguation-list');\n const entriesContainer = this._querySelector(node, '.gloss-list');\n\n node.dataset.dictionary = dictionary;\n\n this._appendMultiple(tagListContainer, this._createTag.bind(this), [...tags, dictionaryTag]);\n this._appendMultiple(onlyListContainer, this._createTermDisambiguation.bind(this), disambiguations);\n this._appendMultiple(entriesContainer, this._createTermDefinitionEntry.bind(this), entries, dictionary);\n return node;\n }\n\n private _createTermDefinitionEntry(\n entry: DictionaryData.TermGlossaryContent,\n dictionary: string,\n ): HTMLElement | null {\n switch (typeof entry) {\n case 'string':\n return this._createTermDefinitionEntryText(entry);\n case 'object': {\n switch (entry.type) {\n case 'image':\n return this._createTermDefinitionEntryImage(entry, dictionary);\n case 'structured-content':\n return this._createTermDefinitionEntryStructuredContent(entry.content, dictionary);\n case 'text':\n break;\n }\n break;\n }\n }\n return null;\n }\n\n private _createTermDefinitionEntryText(text: string): HTMLElement {\n const node = this._instantiate('gloss-item');\n const container = this._querySelector(node, '.gloss-content');\n this._setMultilineTextContent(container, text);\n return node;\n }\n\n private _createTermDefinitionEntryImage(data: DictionaryData.TermGlossaryImage, dictionary: string): HTMLElement {\n const { description } = data;\n\n const node = this._instantiate('gloss-item');\n\n const contentContainer = this._querySelector(node, '.gloss-content');\n const image = this._structuredContentGenerator.createDefinitionImage(data, dictionary);\n contentContainer.appendChild(image);\n\n if (typeof description === 'string') {\n const fragment = this._templates.instantiateFragment('gloss-item-image-description');\n const container = this._querySelector(fragment, '.gloss-image-description');\n this._setMultilineTextContent(container, description);\n contentContainer.appendChild(fragment);\n }\n\n return node;\n }\n\n private _createTermDefinitionEntryStructuredContent(\n content: StructuredContent.Content,\n dictionary: string,\n ): HTMLElement {\n const node = this._instantiate('gloss-item');\n const contentContainer = this._querySelector(node, '.gloss-content');\n this._structuredContentGenerator.appendStructuredContent(contentContainer, content, dictionary);\n return node;\n }\n\n private _createTermDisambiguation(disambiguation: string): HTMLElement {\n const node = this._instantiate('definition-disambiguation');\n node.dataset.term = disambiguation;\n this._setTextContent(node, disambiguation, this._language);\n return node;\n }\n\n private _createKanjiLink(character: string): HTMLAnchorElement {\n const node = this._document.createElement('a');\n node.className = 'headword-kanji-link';\n this._setTextContent(node, character, this._language);\n return node;\n }\n\n private _createKanjiDefinition(text: string): HTMLElement {\n const node = this._instantiate('kanji-gloss-item');\n const container = this._querySelector(node, '.kanji-gloss-content');\n this._setMultilineTextContent(container, text);\n return node;\n }\n\n private _createKanjiReading(reading: string): HTMLElement {\n const node = this._instantiate('kanji-reading');\n this._setTextContent(node, reading, this._language);\n return node;\n }\n\n private _createKanjiInfoTable(details: Dictionary.KanjiStat[]): HTMLElement {\n const node = this._instantiate('kanji-info-table');\n const container = this._querySelector(node, '.kanji-info-table-body');\n\n const count = this._appendMultiple(container, this._createKanjiInfoTableItem.bind(this), details);\n if (count === 0) {\n const n = this._createKanjiInfoTableItemEmpty();\n container.appendChild(n);\n }\n\n return node;\n }\n\n private _createKanjiInfoTableItem(details: Dictionary.KanjiStat): HTMLElement {\n const { content, name, value } = details;\n const node = this._instantiate('kanji-info-table-item');\n const nameNode = this._querySelector(node, '.kanji-info-table-item-header');\n const valueNode = this._querySelector(node, '.kanji-info-table-item-value');\n this._setTextContent(nameNode, content.length > 0 ? content : name);\n this._setTextContent(valueNode, typeof value === 'string' ? value : `${value}`);\n return node;\n }\n\n private _createKanjiInfoTableItemEmpty(): HTMLElement {\n return this._instantiate('kanji-info-table-empty');\n }\n\n private _createTag(tag: Dictionary.Tag): HTMLElement {\n const { content, name, category, redundant } = tag;\n const node = this._instantiate('tag');\n\n const inner = this._querySelector(node, '.tag-label-content');\n\n const contentString = content.join('\\n');\n\n node.title = contentString;\n this._setTextContent(inner, name);\n node.dataset.details = contentString.length > 0 ? contentString : name;\n node.dataset.category = category;\n if (redundant) {\n node.dataset.redundant = 'true';\n }\n\n return node;\n }\n\n private _createTermTag(tagInfo: DictionaryDataUtil.TagGroup, totalHeadwordCount: number): HTMLElement {\n const { tag, headwordIndices } = tagInfo;\n const node = this._createTag(tag);\n node.dataset.headwords = headwordIndices.join(' ');\n node.dataset.totalHeadwordCount = `${totalHeadwordCount}`;\n node.dataset.matchedHeadwordCount = `${headwordIndices.length}`;\n node.dataset.unmatchedHeadwordCount = `${Math.max(0, totalHeadwordCount - headwordIndices.length)}`;\n return node;\n }\n\n private _createTagData(name: string, category: string): Dictionary.Tag {\n return {\n name,\n category,\n order: 0,\n score: 0,\n content: [],\n dictionaries: [],\n redundant: false,\n };\n }\n\n private _createSearchTag(text: string): HTMLElement {\n return this._createTag(this._createTagData(text, 'search'));\n }\n\n private _createGroupedPronunciation(details: DictionaryDataUtil.DictionaryGroupedPronunciations): HTMLElement {\n const { dictionary, dictionaryAlias, pronunciations } = details;\n\n const node = this._instantiate('pronunciation-group');\n node.dataset.dictionary = dictionary;\n node.dataset.pronunciationsMulti = 'true';\n node.dataset.pronunciationsCount = `${pronunciations.length}`;\n\n const n1 = this._querySelector(node, '.pronunciation-group-tag-list');\n const tag = this._createTag(this._createTagData(dictionaryAlias, 'pronunciation-dictionary'));\n tag.dataset.details = dictionary;\n n1.appendChild(tag);\n\n let hasTags = false;\n for (const {\n pronunciation: { tags },\n } of pronunciations) {\n if (tags.length > 0) {\n hasTags = true;\n break;\n }\n }\n\n const n = this._querySelector(node, '.pronunciation-list');\n n.dataset.hasTags = `${hasTags}`;\n this._appendMultiple(n, this._createPronunciation.bind(this), pronunciations);\n\n return node;\n }\n\n private _createPronunciation(details: DictionaryDataUtil.GroupedPronunciation): HTMLElement {\n const { pronunciation } = details;\n switch (pronunciation.type) {\n case 'pitch-accent':\n return this._createPronunciationPitchAccent(pronunciation, details);\n case 'phonetic-transcription':\n return this._createPronunciationPhoneticTranscription(pronunciation, details);\n }\n }\n\n private _createPronunciationPhoneticTranscription(\n pronunciation: Dictionary.PhoneticTranscription,\n details: DictionaryDataUtil.GroupedPronunciation,\n ): HTMLElement {\n const { ipa, tags } = pronunciation;\n const { exclusiveTerms, exclusiveReadings } = details;\n\n const node = this._instantiate('pronunciation');\n\n node.dataset.pronunciationType = pronunciation.type;\n node.dataset.tagCount = `${tags.length}`;\n\n let n = this._querySelector(node, '.pronunciation-tag-list');\n this._appendMultiple(n, this._createTag.bind(this), tags);\n\n n = this._querySelector(node, '.pronunciation-disambiguation-list');\n this._createPronunciationDisambiguations(n, exclusiveTerms, exclusiveReadings);\n\n n = this._querySelector(node, '.pronunciation-text-container');\n this._setTextContent(n, ipa);\n\n return node;\n }\n\n private _createPronunciationPitchAccent(\n pitchAccent: Dictionary.PitchAccent,\n details: DictionaryDataUtil.GroupedPronunciation,\n ): HTMLElement {\n const { positions, nasalPositions, devoicePositions, tags } = pitchAccent;\n const { reading, exclusiveTerms, exclusiveReadings } = details;\n const morae = getKanaMorae(reading);\n\n const node = this._instantiate('pronunciation');\n\n node.dataset.pitchAccentDownstepPosition = `${positions}`;\n node.dataset.pronunciationType = pitchAccent.type;\n if (nasalPositions.length > 0) {\n node.dataset.nasalMoraPosition = nasalPositions.join(' ');\n }\n if (devoicePositions.length > 0) {\n node.dataset.devoiceMoraPosition = devoicePositions.join(' ');\n }\n node.dataset.tagCount = `${tags.length}`;\n\n let n = this._querySelector(node, '.pronunciation-tag-list');\n this._appendMultiple(n, this._createTag.bind(this), tags);\n\n n = this._querySelector(node, '.pronunciation-disambiguation-list');\n this._createPronunciationDisambiguations(n, exclusiveTerms, exclusiveReadings);\n\n n = this._querySelector(node, '.pronunciation-downstep-notation-container');\n n.appendChild(this._pronunciationGenerator.createPronunciationDownstepPosition(positions));\n\n n = this._querySelector(node, '.pronunciation-text-container');\n n.lang = this._language;\n n.appendChild(\n this._pronunciationGenerator.createPronunciationText(morae, positions, nasalPositions, devoicePositions),\n );\n\n n = this._querySelector(node, '.pronunciation-graph-container');\n n.appendChild(this._pronunciationGenerator.createPronunciationGraph(morae, positions));\n\n return node;\n }\n\n private _createPronunciationDisambiguations(\n container: HTMLElement,\n exclusiveTerms: string[],\n exclusiveReadings: string[],\n ): void {\n const templateName = 'pronunciation-disambiguation';\n for (const term of exclusiveTerms) {\n const node = this._instantiate(templateName);\n node.dataset.type = 'term';\n this._setTextContent(node, term, this._language);\n container.appendChild(node);\n }\n\n for (const exclusiveReading of exclusiveReadings) {\n const node = this._instantiate(templateName);\n node.dataset.type = 'reading';\n this._setTextContent(node, exclusiveReading, this._language);\n container.appendChild(node);\n }\n\n container.dataset.count = `${exclusiveTerms.length + exclusiveReadings.length}`;\n container.dataset.termCount = `${exclusiveTerms.length}`;\n container.dataset.readingCount = `${exclusiveReadings.length}`;\n }\n\n private _createFrequencyGroup(\n details:\n | DictionaryDataUtil.DictionaryFrequency<DictionaryDataUtil.TermFrequency>\n | DictionaryDataUtil.DictionaryFrequency<DictionaryDataUtil.KanjiFrequency>,\n kanji: boolean,\n ): HTMLElement {\n const { dictionary, dictionaryAlias, frequencies, freqCount } = details;\n\n const node = this._instantiate('frequency-group-item');\n const body = this._querySelector(node, '.tag-body-content');\n\n const tagLabel = this._querySelector(node, '.tag-label-content');\n const tag = this._querySelector(node, '.tag');\n\n this._setTextContent(tagLabel, dictionaryAlias);\n\n const ii = frequencies.length;\n for (let i = 0; i < ii; ++i) {\n const item = frequencies[i];\n const itemNode = kanji\n ? this._createKanjiFrequency(\n item as DictionaryDataUtil.KanjiFrequency,\n dictionary,\n dictionaryAlias,\n freqCount?.toString(),\n )\n : this._createTermFrequency(\n item as DictionaryDataUtil.TermFrequency,\n dictionary,\n dictionaryAlias,\n freqCount?.toString(),\n );\n itemNode.dataset.index = `${i}`;\n body.appendChild(itemNode);\n }\n\n body.dataset.count = `${ii}`;\n node.dataset.count = `${ii}`;\n node.dataset.details = dictionary;\n tag.dataset.details = `${dictionary}\\nDictionary size: ${freqCount?.toString()}${kanji ? ' kanji' : ' terms'}`;\n return node;\n }\n\n private _createTermFrequency(\n details: DictionaryDataUtil.TermFrequency,\n dictionary: string,\n dictionaryAlias: string,\n freqCount: string | undefined,\n ): HTMLElement {\n const { term, reading, values } = details;\n const node = this._instantiate('term-frequency-item');\n const tagLabel = this._querySelector(node, '.tag-label-content');\n const tag = this._querySelector(node, '.tag');\n const disambiguationTerm = this._querySelector(node, '.frequency-disambiguation-term');\n const disambiguationReading = this._querySelector(node, '.frequency-disambiguation-reading');\n const frequencyValueList = this._querySelector(node, '.frequency-value-list');\n\n this._setTextContent(tagLabel, dictionaryAlias);\n this._setTextContent(disambiguationTerm, term, this._language);\n this._setTextContent(disambiguationReading, reading !== null ? reading : '', this._language);\n this._populateFrequencyValueList(frequencyValueList, values);\n\n node.dataset.term = term;\n if (typeof reading === 'string') {\n node.dataset.reading = reading;\n }\n node.dataset.hasReading = `${reading !== null}`;\n node.dataset.readingIsSame = `${reading === term}`;\n node.dataset.dictionary = dictionary;\n node.dataset.details = dictionary;\n tag.dataset.details = `${dictionary}\\nDictionary size: ${freqCount ?? ''} terms`;\n return node;\n }\n\n private _createKanjiFrequency(\n details: DictionaryDataUtil.KanjiFrequency,\n dictionary: string,\n dictionaryAlias: string,\n freqCount: string | undefined,\n ): HTMLElement {\n const { character, values } = details;\n const node = this._instantiate('kanji-frequency-item');\n const tagLabel = this._querySelector(node, '.tag-label-content');\n const tag = this._querySelector(node, '.tag');\n const frequencyValueList = this._querySelector(node, '.frequency-value-list');\n\n this._setTextContent(tagLabel, dictionaryAlias);\n this._populateFrequencyValueList(frequencyValueList, values);\n\n node.dataset.character = character;\n node.dataset.dictionary = dictionary;\n node.dataset.details = dictionary;\n tag.dataset.details = `${dictionary}\\nDictionary size: ${freqCount ?? ''} kanji`;\n\n return node;\n }\n\n private _populateFrequencyValueList(node: HTMLElement, values: DictionaryDataUtil.FrequencyValue[]): void {\n let fullFrequency = '';\n for (let i = 0, ii = values.length; i < ii; ++i) {\n const { frequency, displayValue } = values[i];\n const frequencyString = `${frequency}`;\n const text = displayValue !== null ? displayValue : `${frequency}`;\n\n if (i > 0) {\n const node2 = this._document.createElement('span');\n node2.className = 'frequency-value';\n node2.dataset.frequency = `${frequency}`;\n node2.textContent = ', ';\n node.appendChild(node2);\n fullFrequency += ', ';\n }\n\n const node2 = this._document.createElement('span');\n node2.className = 'frequency-value';\n node2.dataset.frequency = frequencyString;\n if (displayValue !== null) {\n node2.dataset.displayValue = `${displayValue}`;\n if (displayValue !== frequencyString) {\n node2.title = frequencyString;\n }\n }\n this._setTextContent(node2, text, this._language);\n node.appendChild(node2);\n\n fullFrequency += text;\n }\n\n node.dataset.frequency = fullFrequency;\n }\n\n private _appendKanjiLinks(container: HTMLElement, text: string): void {\n let part = '';\n for (const c of text) {\n if (isCodePointKanji(c.codePointAt(0) as number)) {\n if (part.length > 0) {\n container.appendChild(this._document.createTextNode(part));\n part = '';\n }\n\n const link = this._createKanjiLink(c);\n container.appendChild(link);\n } else {\n part += c;\n }\n }\n if (part.length > 0) {\n container.appendChild(this._document.createTextNode(part));\n }\n }\n\n private _appendMultiple<TItem, TExtraArg = void>(\n container: HTMLElement,\n createItem: (item: TItem, arg: TExtraArg) => Node | null,\n detailsArray: TItem[],\n arg?: TExtraArg,\n ): number {\n let count = 0;\n const ELEMENT_NODE = 1;\n if (Array.isArray(detailsArray)) {\n for (const details of detailsArray) {\n const item = createItem(details, arg as TExtraArg);\n if (item === null) {\n continue;\n }\n container.appendChild(item);\n if (item.nodeType === ELEMENT_NODE) {\n (item as HTMLElement).dataset.index = `${count}`;\n }\n ++count;\n }\n }\n\n container.dataset.count = `${count}`;\n\n return count;\n }\n\n private _appendFurigana(\n container: HTMLElement,\n term: string,\n reading: string,\n addText: (element: HTMLElement, text: string) => void,\n ): void {\n container.lang = this._language;\n const segments = distributeFurigana(term, reading);\n for (const { text, reading: furigana } of segments) {\n if (furigana) {\n const ruby = this._document.createElement('ruby');\n const rt = this._document.createElement('rt');\n addText(ruby, text);\n ruby.appendChild(rt);\n rt.appendChild(this._document.createTextNode(furigana));\n container.appendChild(ruby);\n } else {\n addText(container, text);\n }\n }\n }\n\n private _createDictionaryTag(dictionary: string): Dictionary.Tag {\n return this._createTagData(dictionary, 'dictionary');\n }\n\n private _setTextContent(node: HTMLElement, value: string, language?: string): void {\n this._setElementLanguage(node, language, value);\n node.textContent = value;\n }\n\n private _setMultilineTextContent(node: HTMLElement, value: string, language?: string): void {\n this._setElementLanguage(node, language, value);\n\n let start = 0;\n while (true) {\n const end = value.indexOf('\\n', start);\n if (end < 0) {\n break;\n }\n node.appendChild(this._document.createTextNode(value.substring(start, end)));\n node.appendChild(this._document.createElement('br'));\n start = end + 1;\n }\n\n if (start < value.length) {\n node.appendChild(this._document.createTextNode(start === 0 ? value : value.substring(start)));\n }\n }\n\n private _setElementLanguage(element: HTMLElement, language: string | undefined, content: string): void {\n if (typeof language === 'string') {\n element.lang = language;\n } else {\n const language2 = getLanguageFromText(content, this._language);\n if (language2 !== null) {\n element.lang = language2;\n }\n }\n }\n\n private _getPronunciationCategories(\n reading: string,\n termPronunciations: Dictionary.TermPronunciation[],\n wordClasses: string[],\n headwordIndex: number,\n ): string | null {\n if (termPronunciations.length === 0) {\n return null;\n }\n const isVerbOrAdjective = isNonNounVerbOrAdjective(wordClasses);\n const categories = new Set<PitchCategory>();\n for (const termPronunciation of termPronunciations) {\n if (termPronunciation.headwordIndex !== headwordIndex) {\n continue;\n }\n for (const pronunciation of termPronunciation.pronunciations) {\n if (pronunciation.type !== 'pitch-accent') {\n continue;\n }\n const category = getPitchCategory(reading, pronunciation.positions, isVerbOrAdjective);\n if (category !== null) {\n categories.add(category);\n }\n }\n }\n return categories.size > 0 ? [...categories].join(' ') : null;\n }\n\n private _instantiate(name: string): HTMLElement {\n return this._templates.instantiate(name);\n }\n\n private _querySelector(element: Element | DocumentFragment, selector: string): HTMLElement {\n const result = element.querySelector(selector);\n if (result === null) {\n throw new Error(`Failed to find element: ${selector}`);\n }\n return result as HTMLElement;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+
3
+ //#region src/util/errors.ts
4
+ /**
5
+ * Custom error class for yomitan-core which can contain extra data.
6
+ */
7
+ var YomitanError = class extends Error {
8
+ data;
9
+ constructor(message, data) {
10
+ super(message);
11
+ this.name = "YomitanError";
12
+ this.data = data;
13
+ }
14
+ };
15
+ /**
16
+ * Utility function to convert an unknown value to an error.
17
+ */
18
+ function toError(value) {
19
+ return value instanceof Error ? value : new Error(`${value}`);
20
+ }
21
+
22
+ //#endregion
23
+ Object.defineProperty(exports, 'YomitanError', {
24
+ enumerable: true,
25
+ get: function () {
26
+ return YomitanError;
27
+ }
28
+ });
29
+ Object.defineProperty(exports, 'toError', {
30
+ enumerable: true,
31
+ get: function () {
32
+ return toError;
33
+ }
34
+ });
35
+ //# sourceMappingURL=errors-BSezaJwm.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-BSezaJwm.cjs","names":["message: string","data?: unknown","value: unknown"],"sources":["../src/util/errors.ts"],"sourcesContent":["/**\n * Custom error class for yomitan-core which can contain extra data.\n */\nexport class YomitanError extends Error {\n public data: unknown;\n\n constructor(message: string, data?: unknown) {\n super(message);\n this.name = 'YomitanError';\n this.data = data;\n }\n}\n\n/**\n * Utility function to convert an unknown value to an error.\n */\nexport function toError(value: unknown): Error {\n return value instanceof Error ? value : new Error(`${value}`);\n}\n"],"mappings":";;;;;;AAGA,IAAa,eAAb,cAAkC,MAAM;CACpC,AAAO;CAEP,YAAYA,SAAiBC,MAAgB;AACzC,QAAM,QAAQ;AACd,OAAK,OAAO;AACZ,OAAK,OAAO;CACf;AACJ;;;;AAKD,SAAgB,QAAQC,OAAuB;AAC3C,QAAO,iBAAiB,QAAQ,QAAQ,IAAI,OAAO,EAAE,MAAM;AAC9D"}
@@ -0,0 +1,22 @@
1
+ //#region src/util/errors.ts
2
+ /**
3
+ * Custom error class for yomitan-core which can contain extra data.
4
+ */
5
+ var YomitanError = class extends Error {
6
+ data;
7
+ constructor(message, data) {
8
+ super(message);
9
+ this.name = "YomitanError";
10
+ this.data = data;
11
+ }
12
+ };
13
+ /**
14
+ * Utility function to convert an unknown value to an error.
15
+ */
16
+ function toError(value) {
17
+ return value instanceof Error ? value : new Error(`${value}`);
18
+ }
19
+
20
+ //#endregion
21
+ export { YomitanError, toError };
22
+ //# sourceMappingURL=errors-DuuDSO5N.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-DuuDSO5N.js","names":["message: string","data?: unknown","value: unknown"],"sources":["../src/util/errors.ts"],"sourcesContent":["/**\n * Custom error class for yomitan-core which can contain extra data.\n */\nexport class YomitanError extends Error {\n public data: unknown;\n\n constructor(message: string, data?: unknown) {\n super(message);\n this.name = 'YomitanError';\n this.data = data;\n }\n}\n\n/**\n * Utility function to convert an unknown value to an error.\n */\nexport function toError(value: unknown): Error {\n return value instanceof Error ? value : new Error(`${value}`);\n}\n"],"mappings":";;;;AAGA,IAAa,eAAb,cAAkC,MAAM;CACpC,AAAO;CAEP,YAAYA,SAAiBC,MAAgB;AACzC,QAAM,QAAQ;AACd,OAAK,OAAO;AACZ,OAAK,OAAO;CACf;AACJ;;;;AAKD,SAAgB,QAAQC,OAAuB;AAC3C,QAAO,iBAAiB,QAAQ,QAAQ,IAAI,OAAO,EAAE,MAAM;AAC9D"}
@@ -0,0 +1,3 @@
1
+ import { FrequencyRanker } from "./frequency-ranking-DEJMTMdg.js";
2
+
3
+ export { FrequencyRanker };
@@ -0,0 +1,3 @@
1
+ const require_frequency_ranking = require('./frequency-ranking-DVYxTXN-.cjs');
2
+
3
+ exports.FrequencyRanker = require_frequency_ranking.FrequencyRanker
@@ -0,0 +1,159 @@
1
+ //#region src/lookup/frequency-ranking.ts
2
+ /**
3
+ * Queries term frequency metadata from the database and computes
4
+ * aggregate frequency rankings across multiple dictionaries.
5
+ */
6
+ var FrequencyRanker = class {
7
+ _db;
8
+ _numberRegex;
9
+ constructor(db) {
10
+ this._db = db;
11
+ this._numberRegex = /[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?/;
12
+ }
13
+ /**
14
+ * Gets the frequency ranking for a term across all dictionaries that
15
+ * have frequency metadata for it.
16
+ *
17
+ * @param term The term to look up.
18
+ * @param dictionaries The set of dictionary names to query.
19
+ * @param reading Optional reading to filter frequency data. If not provided,
20
+ * all frequency entries for the term are included.
21
+ * @returns A FrequencyRanking object with per-dictionary frequencies and a harmonic mean.
22
+ */
23
+ async getFrequencyRanking(term, dictionaries, reading) {
24
+ const dictionarySet = new Set(dictionaries);
25
+ const metas = await this._db.findTermMetaBulk([term], dictionarySet);
26
+ const frequencyMap = new Map();
27
+ for (const meta of metas) {
28
+ if (meta.mode !== "freq") continue;
29
+ const freqMeta = meta;
30
+ const { data, dictionary } = freqMeta;
31
+ const hasReading = data !== null && typeof data === "object" && typeof data.reading === "string";
32
+ if (hasReading) {
33
+ const dataWithReading = data;
34
+ if (typeof reading === "string" && dataWithReading.reading !== reading) continue;
35
+ const { frequency, displayValue } = this._getFrequencyInfo(dataWithReading.frequency);
36
+ const existing = frequencyMap.get(dictionary);
37
+ if (typeof existing === "undefined" || frequency < existing.frequency) frequencyMap.set(dictionary, {
38
+ frequency,
39
+ displayValue
40
+ });
41
+ } else {
42
+ const { frequency, displayValue } = this._getFrequencyInfo(data);
43
+ const existing = frequencyMap.get(dictionary);
44
+ if (typeof existing === "undefined" || frequency < existing.frequency) frequencyMap.set(dictionary, {
45
+ frequency,
46
+ displayValue
47
+ });
48
+ }
49
+ }
50
+ const frequencies = [];
51
+ for (const [dictionary, { frequency, displayValue }] of frequencyMap.entries()) frequencies.push({
52
+ dictionary,
53
+ frequency,
54
+ displayValue
55
+ });
56
+ const harmonicMean = this._computeHarmonicMean(frequencies.map((f) => f.frequency));
57
+ return {
58
+ frequencies,
59
+ harmonicMean
60
+ };
61
+ }
62
+ /**
63
+ * Gets frequency rankings for multiple terms at once.
64
+ */
65
+ async getFrequencyRankingBulk(terms, dictionaries) {
66
+ const results = new Map();
67
+ const dictionarySet = new Set(dictionaries);
68
+ const metas = await this._db.findTermMetaBulk(terms, dictionarySet);
69
+ const termMetaMap = new Map();
70
+ for (const meta of metas) {
71
+ const term = terms[meta.index];
72
+ let termMetas = termMetaMap.get(term);
73
+ if (typeof termMetas === "undefined") {
74
+ termMetas = [];
75
+ termMetaMap.set(term, termMetas);
76
+ }
77
+ termMetas.push(meta);
78
+ }
79
+ for (const [term, termMetas] of termMetaMap.entries()) {
80
+ const frequencyMap = new Map();
81
+ for (const meta of termMetas) {
82
+ if (meta.mode !== "freq") continue;
83
+ const freqMeta = meta;
84
+ const { data, dictionary } = freqMeta;
85
+ const hasReading = data !== null && typeof data === "object" && typeof data.reading === "string";
86
+ const frequency = hasReading ? data.frequency : data;
87
+ const { frequency: freqValue, displayValue } = this._getFrequencyInfo(frequency);
88
+ const existing = frequencyMap.get(dictionary);
89
+ if (typeof existing === "undefined" || freqValue < existing.frequency) frequencyMap.set(dictionary, {
90
+ frequency: freqValue,
91
+ displayValue
92
+ });
93
+ }
94
+ const frequencies = [];
95
+ for (const [dictionary, { frequency, displayValue }] of frequencyMap.entries()) frequencies.push({
96
+ dictionary,
97
+ frequency,
98
+ displayValue
99
+ });
100
+ const harmonicMean = this._computeHarmonicMean(frequencies.map((f) => f.frequency));
101
+ results.set(term, {
102
+ frequencies,
103
+ harmonicMean
104
+ });
105
+ }
106
+ return results;
107
+ }
108
+ /**
109
+ * Computes the harmonic mean of positive frequency values.
110
+ */
111
+ _computeHarmonicMean(values) {
112
+ if (values.length === 0) return 0;
113
+ let sum = 0;
114
+ let count = 0;
115
+ for (const freq of values) {
116
+ if (freq <= 0) continue;
117
+ sum += 1 / freq;
118
+ count++;
119
+ }
120
+ return sum > 0 ? Math.round(count / sum) : 0;
121
+ }
122
+ /**
123
+ * Extracts numeric frequency value and display string from generic frequency data.
124
+ */
125
+ _getFrequencyInfo(frequency) {
126
+ let frequencyValue = 0;
127
+ let displayValue = null;
128
+ if (typeof frequency === "object" && frequency !== null) {
129
+ const { value: frequencyValue2, displayValue: displayValue2 } = frequency;
130
+ if (typeof frequencyValue2 === "number") frequencyValue = frequencyValue2;
131
+ if (typeof displayValue2 === "string") displayValue = displayValue2;
132
+ } else switch (typeof frequency) {
133
+ case "number":
134
+ frequencyValue = frequency;
135
+ break;
136
+ case "string":
137
+ displayValue = frequency;
138
+ frequencyValue = this._convertStringToNumber(frequency);
139
+ break;
140
+ }
141
+ return {
142
+ frequency: frequencyValue,
143
+ displayValue
144
+ };
145
+ }
146
+ /**
147
+ * Converts a string to a number by extracting the first numeric value.
148
+ */
149
+ _convertStringToNumber(value) {
150
+ const match = this._numberRegex.exec(value);
151
+ if (match === null) return 0;
152
+ const result = Number.parseFloat(match[0]);
153
+ return Number.isFinite(result) ? result : 0;
154
+ }
155
+ };
156
+
157
+ //#endregion
158
+ export { FrequencyRanker };
159
+ //# sourceMappingURL=frequency-ranking-DEJMTMdg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frequency-ranking-DEJMTMdg.js","names":["db: DictionaryDB","term: string","dictionaries: string[]","reading?: string","frequencies: { dictionary: string; frequency: number; displayValue: string | null }[]","terms: string[]","values: number[]","frequency: DictionaryData.GenericFrequencyData","displayValue: string | null","value: string"],"sources":["../src/lookup/frequency-ranking.ts"],"sourcesContent":["/*\n * Copyright (C) 2023-2025 Yomitan Authors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\nimport type { DictionaryDB } from '../database/dictionary-database';\nimport type * as DictionaryData from '../types/dictionary-data';\nimport type * as DictionaryDatabase from '../types/dictionary-database';\n\nexport interface FrequencyRanking {\n /** Per-dictionary frequency data. */\n frequencies: { dictionary: string; frequency: number; displayValue: string | null }[];\n /** The harmonic mean across all dictionaries with positive frequency. */\n harmonicMean: number;\n}\n\n/**\n * Queries term frequency metadata from the database and computes\n * aggregate frequency rankings across multiple dictionaries.\n */\nexport class FrequencyRanker {\n private _db: DictionaryDB;\n private _numberRegex: RegExp;\n\n constructor(db: DictionaryDB) {\n this._db = db;\n this._numberRegex = /[+-]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][+-]?\\d+)?/;\n }\n\n /**\n * Gets the frequency ranking for a term across all dictionaries that\n * have frequency metadata for it.\n *\n * @param term The term to look up.\n * @param dictionaries The set of dictionary names to query.\n * @param reading Optional reading to filter frequency data. If not provided,\n * all frequency entries for the term are included.\n * @returns A FrequencyRanking object with per-dictionary frequencies and a harmonic mean.\n */\n async getFrequencyRanking(term: string, dictionaries: string[], reading?: string): Promise<FrequencyRanking> {\n const dictionarySet = new Set(dictionaries);\n const metas = await this._db.findTermMetaBulk([term], dictionarySet);\n\n const frequencyMap = new Map<string, { frequency: number; displayValue: string | null }>();\n\n for (const meta of metas) {\n if (meta.mode !== 'freq') {\n continue;\n }\n\n const freqMeta = meta as DictionaryDatabase.TermMetaFrequency;\n const { data, dictionary } = freqMeta;\n\n const hasReading =\n data !== null &&\n typeof data === 'object' &&\n typeof (data as DictionaryData.TermMetaFrequencyDataWithReading).reading === 'string';\n\n if (hasReading) {\n const dataWithReading = data as DictionaryData.TermMetaFrequencyDataWithReading;\n if (typeof reading === 'string' && dataWithReading.reading !== reading) {\n continue;\n }\n const { frequency, displayValue } = this._getFrequencyInfo(dataWithReading.frequency);\n const existing = frequencyMap.get(dictionary);\n if (typeof existing === 'undefined' || frequency < existing.frequency) {\n frequencyMap.set(dictionary, { frequency, displayValue });\n }\n } else {\n const { frequency, displayValue } = this._getFrequencyInfo(data as DictionaryData.GenericFrequencyData);\n const existing = frequencyMap.get(dictionary);\n if (typeof existing === 'undefined' || frequency < existing.frequency) {\n frequencyMap.set(dictionary, { frequency, displayValue });\n }\n }\n }\n\n const frequencies: { dictionary: string; frequency: number; displayValue: string | null }[] = [];\n for (const [dictionary, { frequency, displayValue }] of frequencyMap.entries()) {\n frequencies.push({ dictionary, frequency, displayValue });\n }\n\n const harmonicMean = this._computeHarmonicMean(frequencies.map((f) => f.frequency));\n\n return { frequencies, harmonicMean };\n }\n\n /**\n * Gets frequency rankings for multiple terms at once.\n */\n async getFrequencyRankingBulk(terms: string[], dictionaries: string[]): Promise<Map<string, FrequencyRanking>> {\n const results = new Map<string, FrequencyRanking>();\n const dictionarySet = new Set(dictionaries);\n const metas = await this._db.findTermMetaBulk(terms, dictionarySet);\n\n // Group by term\n const termMetaMap = new Map<string, DictionaryDatabase.TermMeta[]>();\n for (const meta of metas) {\n const term = terms[meta.index];\n let termMetas = termMetaMap.get(term);\n if (typeof termMetas === 'undefined') {\n termMetas = [];\n termMetaMap.set(term, termMetas);\n }\n termMetas.push(meta);\n }\n\n for (const [term, termMetas] of termMetaMap.entries()) {\n const frequencyMap = new Map<string, { frequency: number; displayValue: string | null }>();\n\n for (const meta of termMetas) {\n if (meta.mode !== 'freq') {\n continue;\n }\n\n const freqMeta = meta as DictionaryDatabase.TermMetaFrequency;\n const { data, dictionary } = freqMeta;\n\n const hasReading =\n data !== null &&\n typeof data === 'object' &&\n typeof (data as DictionaryData.TermMetaFrequencyDataWithReading).reading === 'string';\n const frequency = hasReading\n ? (data as DictionaryData.TermMetaFrequencyDataWithReading).frequency\n : (data as DictionaryData.GenericFrequencyData);\n\n const { frequency: freqValue, displayValue } = this._getFrequencyInfo(frequency);\n const existing = frequencyMap.get(dictionary);\n if (typeof existing === 'undefined' || freqValue < existing.frequency) {\n frequencyMap.set(dictionary, { frequency: freqValue, displayValue });\n }\n }\n\n const frequencies: { dictionary: string; frequency: number; displayValue: string | null }[] = [];\n for (const [dictionary, { frequency, displayValue }] of frequencyMap.entries()) {\n frequencies.push({ dictionary, frequency, displayValue });\n }\n\n const harmonicMean = this._computeHarmonicMean(frequencies.map((f) => f.frequency));\n results.set(term, { frequencies, harmonicMean });\n }\n\n return results;\n }\n\n /**\n * Computes the harmonic mean of positive frequency values.\n */\n private _computeHarmonicMean(values: number[]): number {\n if (values.length === 0) {\n return 0;\n }\n let sum = 0;\n let count = 0;\n for (const freq of values) {\n if (freq <= 0) {\n continue;\n }\n sum += 1 / freq;\n count++;\n }\n return sum > 0 ? Math.round(count / sum) : 0;\n }\n\n /**\n * Extracts numeric frequency value and display string from generic frequency data.\n */\n private _getFrequencyInfo(frequency: DictionaryData.GenericFrequencyData): {\n frequency: number;\n displayValue: string | null;\n } {\n let frequencyValue = 0;\n let displayValue: string | null = null;\n if (typeof frequency === 'object' && frequency !== null) {\n const { value: frequencyValue2, displayValue: displayValue2 } = frequency;\n if (typeof frequencyValue2 === 'number') {\n frequencyValue = frequencyValue2;\n }\n if (typeof displayValue2 === 'string') {\n displayValue = displayValue2;\n }\n } else {\n switch (typeof frequency) {\n case 'number':\n frequencyValue = frequency;\n break;\n case 'string':\n displayValue = frequency;\n frequencyValue = this._convertStringToNumber(frequency);\n break;\n }\n }\n return { frequency: frequencyValue, displayValue };\n }\n\n /**\n * Converts a string to a number by extracting the first numeric value.\n */\n private _convertStringToNumber(value: string): number {\n const match = this._numberRegex.exec(value);\n if (match === null) {\n return 0;\n }\n const result = Number.parseFloat(match[0]);\n return Number.isFinite(result) ? result : 0;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+
3
+ //#region src/lookup/frequency-ranking.ts
4
+ /**
5
+ * Queries term frequency metadata from the database and computes
6
+ * aggregate frequency rankings across multiple dictionaries.
7
+ */
8
+ var FrequencyRanker = class {
9
+ _db;
10
+ _numberRegex;
11
+ constructor(db) {
12
+ this._db = db;
13
+ this._numberRegex = /[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?/;
14
+ }
15
+ /**
16
+ * Gets the frequency ranking for a term across all dictionaries that
17
+ * have frequency metadata for it.
18
+ *
19
+ * @param term The term to look up.
20
+ * @param dictionaries The set of dictionary names to query.
21
+ * @param reading Optional reading to filter frequency data. If not provided,
22
+ * all frequency entries for the term are included.
23
+ * @returns A FrequencyRanking object with per-dictionary frequencies and a harmonic mean.
24
+ */
25
+ async getFrequencyRanking(term, dictionaries, reading) {
26
+ const dictionarySet = new Set(dictionaries);
27
+ const metas = await this._db.findTermMetaBulk([term], dictionarySet);
28
+ const frequencyMap = new Map();
29
+ for (const meta of metas) {
30
+ if (meta.mode !== "freq") continue;
31
+ const freqMeta = meta;
32
+ const { data, dictionary } = freqMeta;
33
+ const hasReading = data !== null && typeof data === "object" && typeof data.reading === "string";
34
+ if (hasReading) {
35
+ const dataWithReading = data;
36
+ if (typeof reading === "string" && dataWithReading.reading !== reading) continue;
37
+ const { frequency, displayValue } = this._getFrequencyInfo(dataWithReading.frequency);
38
+ const existing = frequencyMap.get(dictionary);
39
+ if (typeof existing === "undefined" || frequency < existing.frequency) frequencyMap.set(dictionary, {
40
+ frequency,
41
+ displayValue
42
+ });
43
+ } else {
44
+ const { frequency, displayValue } = this._getFrequencyInfo(data);
45
+ const existing = frequencyMap.get(dictionary);
46
+ if (typeof existing === "undefined" || frequency < existing.frequency) frequencyMap.set(dictionary, {
47
+ frequency,
48
+ displayValue
49
+ });
50
+ }
51
+ }
52
+ const frequencies = [];
53
+ for (const [dictionary, { frequency, displayValue }] of frequencyMap.entries()) frequencies.push({
54
+ dictionary,
55
+ frequency,
56
+ displayValue
57
+ });
58
+ const harmonicMean = this._computeHarmonicMean(frequencies.map((f) => f.frequency));
59
+ return {
60
+ frequencies,
61
+ harmonicMean
62
+ };
63
+ }
64
+ /**
65
+ * Gets frequency rankings for multiple terms at once.
66
+ */
67
+ async getFrequencyRankingBulk(terms, dictionaries) {
68
+ const results = new Map();
69
+ const dictionarySet = new Set(dictionaries);
70
+ const metas = await this._db.findTermMetaBulk(terms, dictionarySet);
71
+ const termMetaMap = new Map();
72
+ for (const meta of metas) {
73
+ const term = terms[meta.index];
74
+ let termMetas = termMetaMap.get(term);
75
+ if (typeof termMetas === "undefined") {
76
+ termMetas = [];
77
+ termMetaMap.set(term, termMetas);
78
+ }
79
+ termMetas.push(meta);
80
+ }
81
+ for (const [term, termMetas] of termMetaMap.entries()) {
82
+ const frequencyMap = new Map();
83
+ for (const meta of termMetas) {
84
+ if (meta.mode !== "freq") continue;
85
+ const freqMeta = meta;
86
+ const { data, dictionary } = freqMeta;
87
+ const hasReading = data !== null && typeof data === "object" && typeof data.reading === "string";
88
+ const frequency = hasReading ? data.frequency : data;
89
+ const { frequency: freqValue, displayValue } = this._getFrequencyInfo(frequency);
90
+ const existing = frequencyMap.get(dictionary);
91
+ if (typeof existing === "undefined" || freqValue < existing.frequency) frequencyMap.set(dictionary, {
92
+ frequency: freqValue,
93
+ displayValue
94
+ });
95
+ }
96
+ const frequencies = [];
97
+ for (const [dictionary, { frequency, displayValue }] of frequencyMap.entries()) frequencies.push({
98
+ dictionary,
99
+ frequency,
100
+ displayValue
101
+ });
102
+ const harmonicMean = this._computeHarmonicMean(frequencies.map((f) => f.frequency));
103
+ results.set(term, {
104
+ frequencies,
105
+ harmonicMean
106
+ });
107
+ }
108
+ return results;
109
+ }
110
+ /**
111
+ * Computes the harmonic mean of positive frequency values.
112
+ */
113
+ _computeHarmonicMean(values) {
114
+ if (values.length === 0) return 0;
115
+ let sum = 0;
116
+ let count = 0;
117
+ for (const freq of values) {
118
+ if (freq <= 0) continue;
119
+ sum += 1 / freq;
120
+ count++;
121
+ }
122
+ return sum > 0 ? Math.round(count / sum) : 0;
123
+ }
124
+ /**
125
+ * Extracts numeric frequency value and display string from generic frequency data.
126
+ */
127
+ _getFrequencyInfo(frequency) {
128
+ let frequencyValue = 0;
129
+ let displayValue = null;
130
+ if (typeof frequency === "object" && frequency !== null) {
131
+ const { value: frequencyValue2, displayValue: displayValue2 } = frequency;
132
+ if (typeof frequencyValue2 === "number") frequencyValue = frequencyValue2;
133
+ if (typeof displayValue2 === "string") displayValue = displayValue2;
134
+ } else switch (typeof frequency) {
135
+ case "number":
136
+ frequencyValue = frequency;
137
+ break;
138
+ case "string":
139
+ displayValue = frequency;
140
+ frequencyValue = this._convertStringToNumber(frequency);
141
+ break;
142
+ }
143
+ return {
144
+ frequency: frequencyValue,
145
+ displayValue
146
+ };
147
+ }
148
+ /**
149
+ * Converts a string to a number by extracting the first numeric value.
150
+ */
151
+ _convertStringToNumber(value) {
152
+ const match = this._numberRegex.exec(value);
153
+ if (match === null) return 0;
154
+ const result = Number.parseFloat(match[0]);
155
+ return Number.isFinite(result) ? result : 0;
156
+ }
157
+ };
158
+
159
+ //#endregion
160
+ Object.defineProperty(exports, 'FrequencyRanker', {
161
+ enumerable: true,
162
+ get: function () {
163
+ return FrequencyRanker;
164
+ }
165
+ });
166
+ //# sourceMappingURL=frequency-ranking-DVYxTXN-.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frequency-ranking-DVYxTXN-.cjs","names":["db: DictionaryDB","term: string","dictionaries: string[]","reading?: string","frequencies: { dictionary: string; frequency: number; displayValue: string | null }[]","terms: string[]","values: number[]","frequency: DictionaryData.GenericFrequencyData","displayValue: string | null","value: string"],"sources":["../src/lookup/frequency-ranking.ts"],"sourcesContent":["/*\n * Copyright (C) 2023-2025 Yomitan Authors\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\nimport type { DictionaryDB } from '../database/dictionary-database';\nimport type * as DictionaryData from '../types/dictionary-data';\nimport type * as DictionaryDatabase from '../types/dictionary-database';\n\nexport interface FrequencyRanking {\n /** Per-dictionary frequency data. */\n frequencies: { dictionary: string; frequency: number; displayValue: string | null }[];\n /** The harmonic mean across all dictionaries with positive frequency. */\n harmonicMean: number;\n}\n\n/**\n * Queries term frequency metadata from the database and computes\n * aggregate frequency rankings across multiple dictionaries.\n */\nexport class FrequencyRanker {\n private _db: DictionaryDB;\n private _numberRegex: RegExp;\n\n constructor(db: DictionaryDB) {\n this._db = db;\n this._numberRegex = /[+-]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][+-]?\\d+)?/;\n }\n\n /**\n * Gets the frequency ranking for a term across all dictionaries that\n * have frequency metadata for it.\n *\n * @param term The term to look up.\n * @param dictionaries The set of dictionary names to query.\n * @param reading Optional reading to filter frequency data. If not provided,\n * all frequency entries for the term are included.\n * @returns A FrequencyRanking object with per-dictionary frequencies and a harmonic mean.\n */\n async getFrequencyRanking(term: string, dictionaries: string[], reading?: string): Promise<FrequencyRanking> {\n const dictionarySet = new Set(dictionaries);\n const metas = await this._db.findTermMetaBulk([term], dictionarySet);\n\n const frequencyMap = new Map<string, { frequency: number; displayValue: string | null }>();\n\n for (const meta of metas) {\n if (meta.mode !== 'freq') {\n continue;\n }\n\n const freqMeta = meta as DictionaryDatabase.TermMetaFrequency;\n const { data, dictionary } = freqMeta;\n\n const hasReading =\n data !== null &&\n typeof data === 'object' &&\n typeof (data as DictionaryData.TermMetaFrequencyDataWithReading).reading === 'string';\n\n if (hasReading) {\n const dataWithReading = data as DictionaryData.TermMetaFrequencyDataWithReading;\n if (typeof reading === 'string' && dataWithReading.reading !== reading) {\n continue;\n }\n const { frequency, displayValue } = this._getFrequencyInfo(dataWithReading.frequency);\n const existing = frequencyMap.get(dictionary);\n if (typeof existing === 'undefined' || frequency < existing.frequency) {\n frequencyMap.set(dictionary, { frequency, displayValue });\n }\n } else {\n const { frequency, displayValue } = this._getFrequencyInfo(data as DictionaryData.GenericFrequencyData);\n const existing = frequencyMap.get(dictionary);\n if (typeof existing === 'undefined' || frequency < existing.frequency) {\n frequencyMap.set(dictionary, { frequency, displayValue });\n }\n }\n }\n\n const frequencies: { dictionary: string; frequency: number; displayValue: string | null }[] = [];\n for (const [dictionary, { frequency, displayValue }] of frequencyMap.entries()) {\n frequencies.push({ dictionary, frequency, displayValue });\n }\n\n const harmonicMean = this._computeHarmonicMean(frequencies.map((f) => f.frequency));\n\n return { frequencies, harmonicMean };\n }\n\n /**\n * Gets frequency rankings for multiple terms at once.\n */\n async getFrequencyRankingBulk(terms: string[], dictionaries: string[]): Promise<Map<string, FrequencyRanking>> {\n const results = new Map<string, FrequencyRanking>();\n const dictionarySet = new Set(dictionaries);\n const metas = await this._db.findTermMetaBulk(terms, dictionarySet);\n\n // Group by term\n const termMetaMap = new Map<string, DictionaryDatabase.TermMeta[]>();\n for (const meta of metas) {\n const term = terms[meta.index];\n let termMetas = termMetaMap.get(term);\n if (typeof termMetas === 'undefined') {\n termMetas = [];\n termMetaMap.set(term, termMetas);\n }\n termMetas.push(meta);\n }\n\n for (const [term, termMetas] of termMetaMap.entries()) {\n const frequencyMap = new Map<string, { frequency: number; displayValue: string | null }>();\n\n for (const meta of termMetas) {\n if (meta.mode !== 'freq') {\n continue;\n }\n\n const freqMeta = meta as DictionaryDatabase.TermMetaFrequency;\n const { data, dictionary } = freqMeta;\n\n const hasReading =\n data !== null &&\n typeof data === 'object' &&\n typeof (data as DictionaryData.TermMetaFrequencyDataWithReading).reading === 'string';\n const frequency = hasReading\n ? (data as DictionaryData.TermMetaFrequencyDataWithReading).frequency\n : (data as DictionaryData.GenericFrequencyData);\n\n const { frequency: freqValue, displayValue } = this._getFrequencyInfo(frequency);\n const existing = frequencyMap.get(dictionary);\n if (typeof existing === 'undefined' || freqValue < existing.frequency) {\n frequencyMap.set(dictionary, { frequency: freqValue, displayValue });\n }\n }\n\n const frequencies: { dictionary: string; frequency: number; displayValue: string | null }[] = [];\n for (const [dictionary, { frequency, displayValue }] of frequencyMap.entries()) {\n frequencies.push({ dictionary, frequency, displayValue });\n }\n\n const harmonicMean = this._computeHarmonicMean(frequencies.map((f) => f.frequency));\n results.set(term, { frequencies, harmonicMean });\n }\n\n return results;\n }\n\n /**\n * Computes the harmonic mean of positive frequency values.\n */\n private _computeHarmonicMean(values: number[]): number {\n if (values.length === 0) {\n return 0;\n }\n let sum = 0;\n let count = 0;\n for (const freq of values) {\n if (freq <= 0) {\n continue;\n }\n sum += 1 / freq;\n count++;\n }\n return sum > 0 ? Math.round(count / sum) : 0;\n }\n\n /**\n * Extracts numeric frequency value and display string from generic frequency data.\n */\n private _getFrequencyInfo(frequency: DictionaryData.GenericFrequencyData): {\n frequency: number;\n displayValue: string | null;\n } {\n let frequencyValue = 0;\n let displayValue: string | null = null;\n if (typeof frequency === 'object' && frequency !== null) {\n const { value: frequencyValue2, displayValue: displayValue2 } = frequency;\n if (typeof frequencyValue2 === 'number') {\n frequencyValue = frequencyValue2;\n }\n if (typeof displayValue2 === 'string') {\n displayValue = displayValue2;\n }\n } else {\n switch (typeof frequency) {\n case 'number':\n frequencyValue = frequency;\n break;\n case 'string':\n displayValue = frequency;\n frequencyValue = this._convertStringToNumber(frequency);\n break;\n }\n }\n return { frequency: frequencyValue, displayValue };\n }\n\n /**\n * Converts a string to a number by extracting the first numeric value.\n */\n private _convertStringToNumber(value: string): number {\n const match = this._numberRegex.exec(value);\n if (match === null) {\n return 0;\n }\n const result = Number.parseFloat(match[0]);\n return Number.isFinite(result) ? result : 0;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import "./cjk-util-DubXBGDG.js";
2
+ import { distributeFurigana, distributeFuriganaInflected, generateFurigana } from "./furigana-B3-0y231.js";
3
+
4
+ export { generateFurigana };