yomitan-core 1.0.1 → 1.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 (87) hide show
  1. package/README.md +17 -6
  2. package/dist/anki.cjs +2 -2
  3. package/dist/anki.js +2 -2
  4. package/dist/{display-generator-D_BNq27-.cjs → display-generator-BegC-lK-.cjs} +3 -3
  5. package/dist/{display-generator-CyzsQ0gI.js → display-generator-CEJQTOYP.js} +3 -3
  6. package/dist/{display-generator-lVhYMgbS.cjs → display-generator-CSWA_AMa.cjs} +24 -3
  7. package/dist/display-generator-CSWA_AMa.cjs.map +1 -0
  8. package/dist/{display-generator-Bp6tf6lY.js → display-generator-vxdAYHeK.js} +24 -3
  9. package/dist/display-generator-vxdAYHeK.js.map +1 -0
  10. package/dist/{furigana-CI6LUA-6.js → furigana-BpFJbm9M.js} +2 -2
  11. package/dist/{furigana-CI6LUA-6.js.map → furigana-BpFJbm9M.js.map} +1 -1
  12. package/dist/furigana-C3JCmlrA.js +5 -0
  13. package/dist/{furigana-BnY7-dJ-.cjs → furigana-dSFngFbc.cjs} +2 -2
  14. package/dist/{furigana-BnY7-dJ-.cjs.map → furigana-dSFngFbc.cjs.map} +1 -1
  15. package/dist/furigana-q-DH5eJV.cjs +5 -0
  16. package/dist/index.cjs +14 -7
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +3 -3
  19. package/dist/index.d.cts.map +1 -1
  20. package/dist/index.d.ts +3 -3
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +14 -7
  23. package/dist/index.js.map +1 -1
  24. package/dist/{japanese-BVV1Ctk-.cjs → japanese-C83fmEfb.cjs} +1 -1
  25. package/dist/{japanese-BVV1Ctk-.cjs.map → japanese-C83fmEfb.cjs.map} +1 -1
  26. package/dist/{japanese-DhmmW35J.js → japanese-CKPyY5k_.js} +1 -1
  27. package/dist/{japanese-DhmmW35J.js.map → japanese-CKPyY5k_.js.map} +1 -1
  28. package/dist/language.cjs +11 -11
  29. package/dist/language.d.cts +41 -3
  30. package/dist/language.d.cts.map +1 -1
  31. package/dist/language.d.ts +41 -3
  32. package/dist/language.d.ts.map +1 -1
  33. package/dist/language.js +4 -4
  34. package/dist/lookup.cjs +4 -4
  35. package/dist/lookup.d.cts +5 -78
  36. package/dist/lookup.d.cts.map +1 -1
  37. package/dist/lookup.d.ts +5 -78
  38. package/dist/lookup.d.ts.map +1 -1
  39. package/dist/lookup.js +4 -4
  40. package/dist/multi-language-transformer-DvjBcuyp.js +12503 -0
  41. package/dist/multi-language-transformer-DvjBcuyp.js.map +1 -0
  42. package/dist/{multi-language-transformer-B2133Zg_.cjs → multi-language-transformer-N66Mmb2E.cjs} +9614 -5
  43. package/dist/multi-language-transformer-N66Mmb2E.cjs.map +1 -0
  44. package/dist/render.cjs +674 -546
  45. package/dist/render.cjs.map +1 -1
  46. package/dist/render.d.cts +67 -4
  47. package/dist/render.d.cts.map +1 -1
  48. package/dist/render.d.ts +67 -4
  49. package/dist/render.d.ts.map +1 -1
  50. package/dist/render.js +671 -547
  51. package/dist/render.js.map +1 -1
  52. package/dist/{translator-TiTDVbmS.d.cts → sentence-parser-BQpu2oSA.d.cts} +80 -4
  53. package/dist/sentence-parser-BQpu2oSA.d.cts.map +1 -0
  54. package/dist/{sentence-parser-sx7y6Oyh.js → sentence-parser-C8OC1Ix_.js} +18 -42
  55. package/dist/sentence-parser-C8OC1Ix_.js.map +1 -0
  56. package/dist/sentence-parser-CUoYJvJv.cjs +5 -0
  57. package/dist/sentence-parser-DG_7Th_q.js +5 -0
  58. package/dist/{translator-CYvGmODX.d.ts → sentence-parser-DnY0NA5g.d.ts} +80 -4
  59. package/dist/sentence-parser-DnY0NA5g.d.ts.map +1 -0
  60. package/dist/{sentence-parser-DUQJ3cTT.cjs → sentence-parser-ZSC_ntAi.cjs} +18 -42
  61. package/dist/sentence-parser-ZSC_ntAi.cjs.map +1 -0
  62. package/dist/translator-B5InyZJa.js +7 -0
  63. package/dist/{translator-CrDE1UJW.js → translator-COZI9EQT.js} +2 -2
  64. package/dist/{translator-CrDE1UJW.js.map → translator-COZI9EQT.js.map} +1 -1
  65. package/dist/{translator-B1uTusjx.cjs → translator-CYvu9gr1.cjs} +2 -2
  66. package/dist/{translator-B1uTusjx.cjs.map → translator-CYvu9gr1.cjs.map} +1 -1
  67. package/dist/translator-DAL8ugoC.cjs +7 -0
  68. package/package.json +1 -1
  69. package/dist/display-generator-Bp6tf6lY.js.map +0 -1
  70. package/dist/display-generator-lVhYMgbS.cjs.map +0 -1
  71. package/dist/furigana-cpPhFnBv.cjs +0 -5
  72. package/dist/furigana-kZjqnnFC.js +0 -5
  73. package/dist/japanese-DdsS8rT1.d.ts +0 -41
  74. package/dist/japanese-DdsS8rT1.d.ts.map +0 -1
  75. package/dist/japanese-DgmP3i76.d.cts +0 -41
  76. package/dist/japanese-DgmP3i76.d.cts.map +0 -1
  77. package/dist/multi-language-transformer-B2133Zg_.cjs.map +0 -1
  78. package/dist/multi-language-transformer-BkwMTV2g.js +0 -2893
  79. package/dist/multi-language-transformer-BkwMTV2g.js.map +0 -1
  80. package/dist/sentence-parser-B-gM8mKk.js +0 -5
  81. package/dist/sentence-parser-Cp3cm_QU.cjs +0 -5
  82. package/dist/sentence-parser-DUQJ3cTT.cjs.map +0 -1
  83. package/dist/sentence-parser-sx7y6Oyh.js.map +0 -1
  84. package/dist/translator-BiTHo9Nm.js +0 -7
  85. package/dist/translator-CYvGmODX.d.ts.map +0 -1
  86. package/dist/translator-TiTDVbmS.d.cts.map +0 -1
  87. package/dist/translator-Y7Haj_qJ.cjs +0 -7
package/README.md CHANGED
@@ -310,20 +310,31 @@ const fields = await anki.getModelFieldNames('Basic');
310
310
  import { parseHTML } from 'linkedom';
311
311
  import {
312
312
  DisplayGenerator,
313
- HtmlTemplateCollection,
314
313
  DISPLAY_TEMPLATES,
315
314
  DISPLAY_CSS,
315
+ NoOpContentManager,
316
+ applyExtensionDisplayDefaults,
317
+ applyPopupTheme,
316
318
  } from 'yomitan-core/render';
317
319
 
318
- const { document } = parseHTML('<!DOCTYPE html><html><body></body></html>');
320
+ const { document } = parseHTML('<!DOCTYPE html><html><head></head><body></body></html>');
321
+ applyExtensionDisplayDefaults(document.documentElement);
322
+
323
+ // Optional: control popup body theme mode (light | dark | browser | site).
324
+ applyPopupTheme(document.documentElement, {theme: 'dark'});
325
+ // Equivalent examples:
326
+ // applyPopupTheme(document.documentElement, {theme: 'browser'});
327
+ // applyPopupTheme(document.documentElement, {theme: 'site', siteTheme: 'light'});
319
328
 
320
- const templates = new HtmlTemplateCollection();
321
- templates.loadFromString(DISPLAY_TEMPLATES, document);
329
+ const style = document.createElement('style');
330
+ style.textContent = DISPLAY_CSS; // Includes display + structured content + pronunciation styles; uses data-theme for popup body theme
331
+ document.head.appendChild(style);
322
332
 
323
- const generator = new DisplayGenerator(document, templates);
333
+ const generator = new DisplayGenerator(document, new NoOpContentManager(), DISPLAY_TEMPLATES);
324
334
 
325
335
  // Render a term entry to DOM nodes
326
- const node = generator.createTermEntry(dictionaryEntry);
336
+ const node = generator.createTermEntry(dictionaryEntry, dictionaryInfo);
337
+ // Dictionary-specific styles.css from imported dictionaries are injected automatically per entry.
327
338
  console.log(node.outerHTML);
328
339
  ```
329
340
 
package/dist/anki.cjs CHANGED
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  const require_utilities = require('./utilities-C-lbZaJE.cjs');
3
3
  require('./cjk-util-Dp0ZU0sh.cjs');
4
- const require_japanese = require('./japanese-BVV1Ctk-.cjs');
4
+ const require_japanese = require('./japanese-C83fmEfb.cjs');
5
5
  const require_errors = require('./errors-ZI2FcGUl.cjs');
6
6
  const require_dictionary_data_util = require('./dictionary-data-util-BY_72f3u.cjs');
7
7
  require('./json-CyQBn52D.cjs');
8
- require('./furigana-BnY7-dJ-.cjs');
8
+ require('./furigana-dSFngFbc.cjs');
9
9
  const require_anki_connect = require('./anki-connect-B_YpChhu.cjs');
10
10
 
11
11
  //#region src/anki/anki-note-builder.ts
package/dist/anki.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { deferPromise } from "./utilities-bi3EF-q5.js";
2
2
  import "./cjk-util-DubXBGDG.js";
3
- import { distributeFurigana } from "./japanese-DhmmW35J.js";
3
+ import { distributeFurigana } from "./japanese-CKPyY5k_.js";
4
4
  import { YomitanError } from "./errors-D2JfYV-C.js";
5
5
  import { getDisambiguations, getGroupedPronunciations, getPronunciationsOfType, getTermFrequency, groupTermTags, isNonNounVerbOrAdjective } from "./dictionary-data-util-CKDT7n2t.js";
6
6
  import "./json-DTq_IXXF.js";
7
- import "./furigana-CI6LUA-6.js";
7
+ import "./furigana-BpFJbm9M.js";
8
8
  import { AnkiConnect, cloneFieldMarkerPattern, getRootDeckName } from "./anki-connect-697E04LF.js";
9
9
 
10
10
  //#region src/anki/anki-note-builder.ts
@@ -1,9 +1,9 @@
1
1
  require('./cjk-util-Dp0ZU0sh.cjs');
2
- require('./japanese-BVV1Ctk-.cjs');
2
+ require('./japanese-C83fmEfb.cjs');
3
3
  require('./dictionary-data-util-BY_72f3u.cjs');
4
- require('./furigana-BnY7-dJ-.cjs');
4
+ require('./furigana-dSFngFbc.cjs');
5
5
  require('./text-utilities-CFDC9Bkr.cjs');
6
- const require_display_generator = require('./display-generator-lVhYMgbS.cjs');
6
+ const require_display_generator = require('./display-generator-CSWA_AMa.cjs');
7
7
  require('./pronunciation-generator-B8y__W7I.cjs');
8
8
  require('./structured-content-generator-C5Hhaurz.cjs');
9
9
 
@@ -1,9 +1,9 @@
1
1
  import "./cjk-util-DubXBGDG.js";
2
- import "./japanese-DhmmW35J.js";
2
+ import "./japanese-CKPyY5k_.js";
3
3
  import "./dictionary-data-util-CKDT7n2t.js";
4
- import "./furigana-CI6LUA-6.js";
4
+ import "./furigana-BpFJbm9M.js";
5
5
  import "./text-utilities-D5eno9GK.js";
6
- import { DisplayGenerator } from "./display-generator-Bp6tf6lY.js";
6
+ import { DisplayGenerator } from "./display-generator-vxdAYHeK.js";
7
7
  import "./pronunciation-generator-cNtAQi5s.js";
8
8
  import "./structured-content-generator-aJieXElq.js";
9
9
 
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_japanese = require('./japanese-BVV1Ctk-.cjs');
2
+ const require_japanese = require('./japanese-C83fmEfb.cjs');
3
3
  const require_dictionary_data_util = require('./dictionary-data-util-BY_72f3u.cjs');
4
4
  const require_text_utilities = require('./text-utilities-CFDC9Bkr.cjs');
5
5
  const require_pronunciation_generator = require('./pronunciation-generator-B8y__W7I.cjs');
@@ -27,7 +27,9 @@ var HtmlTemplateCollection = class {
27
27
  * @param html - The HTML string containing `<template>` elements.
28
28
  */
29
29
  loadFromString(html) {
30
- const parser = new this._document.defaultView.DOMParser();
30
+ const DOMParserConstructor = this._document.defaultView?.DOMParser ?? globalThis.DOMParser;
31
+ if (typeof DOMParserConstructor !== "function") throw new Error("DOMParser is unavailable for HtmlTemplateCollection.");
32
+ const parser = new DOMParserConstructor();
31
33
  const templatesDocument = parser.parseFromString(html, "text/html");
32
34
  this.load(templatesDocument);
33
35
  }
@@ -229,6 +231,8 @@ var DisplayGenerator = class {
229
231
  definitionsContainer.appendChild(node2);
230
232
  }
231
233
  definitionsContainer.dataset.count = `${definitions.length}`;
234
+ const dictionaryScopedStyleNode = this._createDictionaryScopedStyleNode(definitions, dictionaryInfo);
235
+ if (dictionaryScopedStyleNode !== null) node.appendChild(dictionaryScopedStyleNode);
232
236
  return node;
233
237
  }
234
238
  /**
@@ -371,6 +375,23 @@ var DisplayGenerator = class {
371
375
  this._appendMultiple(entriesContainer, this._createTermDefinitionEntry.bind(this), entries, dictionary);
372
376
  return node;
373
377
  }
378
+ _createDictionaryScopedStyleNode(definitions, dictionaryInfo) {
379
+ const usedDictionaries = new Set();
380
+ for (const { dictionary } of definitions) usedDictionaries.add(dictionary);
381
+ let scopedCss = "";
382
+ for (const dictionary of usedDictionaries) {
383
+ const info = dictionaryInfo.find(({ title }) => title === dictionary);
384
+ const styles = info?.styles?.trim() ?? "";
385
+ if (styles.length === 0) continue;
386
+ const escapedTitle = dictionary.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"");
387
+ scopedCss += `\n[data-dictionary="${escapedTitle}"] {${styles}\n}`;
388
+ }
389
+ if (scopedCss.length === 0) return null;
390
+ const node = this._document.createElement("style");
391
+ node.className = "dictionary-entry-styles";
392
+ node.textContent = scopedCss;
393
+ return node;
394
+ }
374
395
  _createTermDefinitionEntry(entry, dictionary) {
375
396
  switch (typeof entry) {
376
397
  case "string": return this._createTermDefinitionEntryText(entry);
@@ -755,4 +776,4 @@ Object.defineProperty(exports, 'HtmlTemplateCollection', {
755
776
  return HtmlTemplateCollection;
756
777
  }
757
778
  });
758
- //# sourceMappingURL=display-generator-lVhYMgbS.cjs.map
779
+ //# sourceMappingURL=display-generator-CSWA_AMa.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display-generator-CSWA_AMa.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>","definitions: Dictionary.TermDefinition[]","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 DOMParserConstructor =\n (this._document.defaultView as unknown as { DOMParser?: typeof DOMParser } | null)?.DOMParser ??\n globalThis.DOMParser;\n if (typeof DOMParserConstructor !== 'function') {\n throw new Error('DOMParser is unavailable for HtmlTemplateCollection.');\n }\n const parser = new DOMParserConstructor();\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 const dictionaryScopedStyleNode = this._createDictionaryScopedStyleNode(definitions, dictionaryInfo);\n if (dictionaryScopedStyleNode !== null) {\n node.appendChild(dictionaryScopedStyleNode);\n }\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 _createDictionaryScopedStyleNode(\n definitions: Dictionary.TermDefinition[],\n dictionaryInfo: DictionaryImporter.Summary[],\n ): HTMLStyleElement | null {\n const usedDictionaries = new Set<string>();\n for (const { dictionary } of definitions) {\n usedDictionaries.add(dictionary);\n }\n\n let scopedCss = '';\n for (const dictionary of usedDictionaries) {\n const info = dictionaryInfo.find(({ title }) => title === dictionary);\n const styles = info?.styles?.trim() ?? '';\n if (styles.length === 0) {\n continue;\n }\n\n // Match extension behavior: scope dictionary CSS to entry elements using data-dictionary.\n const escapedTitle = dictionary.replaceAll('\\\\', '\\\\\\\\').replaceAll('\"', '\\\\\"');\n scopedCss += `\\n[data-dictionary=\"${escapedTitle}\"] {${styles}\\n}`;\n }\n\n if (scopedCss.length === 0) {\n return null;\n }\n\n const node = this._document.createElement('style');\n node.className = 'dictionary-entry-styles';\n node.textContent = scopedCss;\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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"}
@@ -1,4 +1,4 @@
1
- import { distributeFurigana } from "./japanese-DhmmW35J.js";
1
+ import { distributeFurigana } from "./japanese-CKPyY5k_.js";
2
2
  import { getDisambiguations, getGroupedPronunciations, getTermFrequency, groupKanjiFrequencies, groupTermFrequencies, groupTermTags, isNonNounVerbOrAdjective } from "./dictionary-data-util-CKDT7n2t.js";
3
3
  import { getLanguageFromText } from "./text-utilities-D5eno9GK.js";
4
4
  import { PronunciationGenerator, getKanaMorae, getPitchCategory, isCodePointKanji } from "./pronunciation-generator-cNtAQi5s.js";
@@ -26,7 +26,9 @@ var HtmlTemplateCollection = class {
26
26
  * @param html - The HTML string containing `<template>` elements.
27
27
  */
28
28
  loadFromString(html) {
29
- const parser = new this._document.defaultView.DOMParser();
29
+ const DOMParserConstructor = this._document.defaultView?.DOMParser ?? globalThis.DOMParser;
30
+ if (typeof DOMParserConstructor !== "function") throw new Error("DOMParser is unavailable for HtmlTemplateCollection.");
31
+ const parser = new DOMParserConstructor();
30
32
  const templatesDocument = parser.parseFromString(html, "text/html");
31
33
  this.load(templatesDocument);
32
34
  }
@@ -228,6 +230,8 @@ var DisplayGenerator = class {
228
230
  definitionsContainer.appendChild(node2);
229
231
  }
230
232
  definitionsContainer.dataset.count = `${definitions.length}`;
233
+ const dictionaryScopedStyleNode = this._createDictionaryScopedStyleNode(definitions, dictionaryInfo);
234
+ if (dictionaryScopedStyleNode !== null) node.appendChild(dictionaryScopedStyleNode);
231
235
  return node;
232
236
  }
233
237
  /**
@@ -370,6 +374,23 @@ var DisplayGenerator = class {
370
374
  this._appendMultiple(entriesContainer, this._createTermDefinitionEntry.bind(this), entries, dictionary);
371
375
  return node;
372
376
  }
377
+ _createDictionaryScopedStyleNode(definitions, dictionaryInfo) {
378
+ const usedDictionaries = new Set();
379
+ for (const { dictionary } of definitions) usedDictionaries.add(dictionary);
380
+ let scopedCss = "";
381
+ for (const dictionary of usedDictionaries) {
382
+ const info = dictionaryInfo.find(({ title }) => title === dictionary);
383
+ const styles = info?.styles?.trim() ?? "";
384
+ if (styles.length === 0) continue;
385
+ const escapedTitle = dictionary.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"");
386
+ scopedCss += `\n[data-dictionary="${escapedTitle}"] {${styles}\n}`;
387
+ }
388
+ if (scopedCss.length === 0) return null;
389
+ const node = this._document.createElement("style");
390
+ node.className = "dictionary-entry-styles";
391
+ node.textContent = scopedCss;
392
+ return node;
393
+ }
373
394
  _createTermDefinitionEntry(entry, dictionary) {
374
395
  switch (typeof entry) {
375
396
  case "string": return this._createTermDefinitionEntryText(entry);
@@ -743,4 +764,4 @@ var DisplayGenerator = class {
743
764
 
744
765
  //#endregion
745
766
  export { DisplayGenerator, HtmlTemplateCollection };
746
- //# sourceMappingURL=display-generator-Bp6tf6lY.js.map
767
+ //# sourceMappingURL=display-generator-vxdAYHeK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display-generator-vxdAYHeK.js","names":["doc: Document","html: string","source: Document","name: string","template: HTMLTemplateElement","removeNodes: Node[]","doc: Document","contentManager: ContentManager","templateHtml: string","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>","definitions: Dictionary.TermDefinition[]","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 DOMParserConstructor =\n (this._document.defaultView as unknown as { DOMParser?: typeof DOMParser } | null)?.DOMParser ??\n globalThis.DOMParser;\n if (typeof DOMParserConstructor !== 'function') {\n throw new Error('DOMParser is unavailable for HtmlTemplateCollection.');\n }\n const parser = new DOMParserConstructor();\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 const dictionaryScopedStyleNode = this._createDictionaryScopedStyleNode(definitions, dictionaryInfo);\n if (dictionaryScopedStyleNode !== null) {\n node.appendChild(dictionaryScopedStyleNode);\n }\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 _createDictionaryScopedStyleNode(\n definitions: Dictionary.TermDefinition[],\n dictionaryInfo: DictionaryImporter.Summary[],\n ): HTMLStyleElement | null {\n const usedDictionaries = new Set<string>();\n for (const { dictionary } of definitions) {\n usedDictionaries.add(dictionary);\n }\n\n let scopedCss = '';\n for (const dictionary of usedDictionaries) {\n const info = dictionaryInfo.find(({ title }) => title === dictionary);\n const styles = info?.styles?.trim() ?? '';\n if (styles.length === 0) {\n continue;\n }\n\n // Match extension behavior: scope dictionary CSS to entry elements using data-dictionary.\n const escapedTitle = dictionary.replaceAll('\\\\', '\\\\\\\\').replaceAll('\"', '\\\\\"');\n scopedCss += `\\n[data-dictionary=\"${escapedTitle}\"] {${styles}\\n}`;\n }\n\n if (scopedCss.length === 0) {\n return null;\n }\n\n const node = this._document.createElement('style');\n node.className = 'dictionary-entry-styles';\n node.textContent = scopedCss;\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":";;;;;;;;;;;;AAuBA,IAAa,yBAAb,MAAoC;CAChC,AAAQ;CACR,AAAQ;;;;;CAMR,YAAYA,KAAe;AACvB,OAAK,aAAa,IAAI;AACtB,OAAK,YAAY;CACpB;;;;;CAMD,eAAeC,MAAoB;EAC/B,MAAM,uBACD,KAAK,UAAU,aAAoE,aACpF,WAAW;AACf,aAAW,yBAAyB,WAChC,OAAM,IAAI,MAAM;EAEpB,MAAM,SAAS,IAAI;EACnB,MAAM,oBAAoB,OAAO,gBAAgB,MAAM,YAAY;AACnE,OAAK,KAAK,kBAAkB;CAC/B;;;;;CAMD,KAAKC,QAAwB;EACzB,MAAM,UAAU;AAChB,OAAK,MAAM,YAAY,MAAM,KAAK,OAAO,iBAAiB,WAAW,CAAC,EAA2B;GAC7F,MAAM,QAAQ,QAAQ,KAAK,SAAS,GAAG;AACvC,OAAI,UAAU,KACV;AAEJ,QAAK,iBAAiB,SAAS;AAC/B,QAAK,WAAW,IAAI,MAAM,IAAI,SAAS;EAC1C;CACJ;;;;;;;CAQD,YAAYC,MAA2B;EACnC,MAAM,EAAE,mBAAmB,GAAG,KAAK,mBAAmB,KAAK;AAC3D,MAAI,sBAAsB,KACtB,OAAM,IAAI,OAAO,2CAA2C,KAAK;AAErE,SAAO,KAAK,UAAU,WAAW,mBAAmB,KAAK;CAC5D;;;;;;CAOD,oBAAoBA,MAAgC;AAChD,SAAO,KAAK,UAAU,WAAW,KAAK,mBAAmB,KAAK,EAAE,KAAK;CACxE;;;;;;;CAQD,mBAAmBA,MAAgC;EAC/C,MAAM,WAAW,KAAK,WAAW,IAAI,KAAK;AAC1C,aAAW,aAAa,YACpB,OAAM,IAAI,OAAO,2BAA2B,KAAK;AAErD,SAAO,SAAS;CACnB;;;;CAKD,kBAAyD;AACrD,SAAO,KAAK,WAAW,QAAQ;CAClC;CAID,AAAQ,iBAAiBC,UAAqC;AAC1D,MAAI,SAAS,QAAQ,yBAAyB,OAC1C,MAAK,sBAAsB,SAAS;CAE3C;CAED,AAAQ,sBAAsBA,UAAqC;EAC/D,MAAM,EAAE,SAAS,GAAG;EACpB,MAAM,EAAE,WAAW,GAAG,KAAK,UAAU,cAC9B,KAAK,UAAU,YAAiD,OACjE,EAAE,WAAW,EAAG;EACtB,MAAM,WAAW,KAAK,UAAU;GAAmB;GAAS;;CAA6B;EACzF,MAAMC,cAAsB,CAAE;AAC9B,SAAO,MAAM;GACT,MAAM,OAAO,SAAS,UAAU;AAChC,OAAI,SAAS,KACT;AAEJ,OAAI,KAAK,aAAa,aAAa,CAAC,KAAK,aAAa,IAAI,MAAM,CAAC,WAAW,EACxE,aAAY,KAAK,KAAK;EAE7B;AACD,OAAK,MAAM,QAAQ,aAAa;GAC5B,MAAM,EAAE,YAAY,GAAG;AACvB,OAAI,eAAe,KACf,YAAW,YAAY,KAAK;EAEnC;CACJ;AACJ;;;;;;;;;ACjGD,IAAa,mBAAb,MAA8B;CAC1B,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ;;;;;;;CAQR,YAAYC,KAAeC,gBAAgCC,cAAsB;AAC7E,OAAK,YAAY;AACjB,OAAK,kBAAkB;AACvB,OAAK,aAAa,IAAI,uBAAuB;AAC7C,OAAK,WAAW,eAAe,aAAa;AAC5C,OAAK,8BAA8B,IAAI,2BAA2B,KAAK,iBAAiB;AACxF,OAAK,0BAA0B,IAAI,uBAAuB;AAC1D,OAAK,YAAY;CACpB;;CAGD,IAAI,iBAAiC;AACjC,SAAO,KAAK;CACf;CAED,IAAI,eAAeD,gBAAgC;AAC/C,OAAK,kBAAkB;CAC1B;;;;;CAMD,eAAeE,UAAwB;AACnC,OAAK,YAAY;CACpB;;;;;;;CAQD,gBACIC,iBACAC,gBACW;EACX,MAAM,OAAO,KAAK,aAAa,aAAa;EAE5C,MAAM,qBAAqB,KAAK,eAAe,MAAM,iBAAiB;EACtE,MAAM,gCAAgC,KAAK,eAAe,MAAM,0BAA0B;EAC1F,MAAM,iCAAiC,KAAK,eAAe,MAAM,4BAA4B;EAC7F,MAAM,8BAA8B,KAAK,eAAe,MAAM,wBAAwB;EACtF,MAAM,uBAAuB,KAAK,eAAe,MAAM,mBAAmB;EAC1E,MAAM,wBAAwB,KAAK,eAAe,MAAM,0BAA0B;EAElF,MAAM,EAAE,WAAW,MAAM,+BAA+B,aAAa,aAAa,gBAAgB,GAC9F;EACJ,MAAM,wBAAwB,yBAAyB,gBAAgB;EACvE,MAAM,qBAAqB,sBAAsB,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,eAAe,QAAQ,EAAE;EACjG,MAAM,qBAAqB,qBAAqB,iBAAiB,eAAe;EAChF,MAAM,WAAW,cAAc,gBAAgB;EAE/C,MAAM,cAAc,IAAI;EACxB,MAAM,iBAAiB,IAAI;EAC3B,MAAM,oBAAoB,IAAI;AAC9B,OAAK,MAAM,EAAE,MAAM,SAAS,SAAS,IAAI,WAAW;AAChD,eAAY,IAAI,KAAK;AACrB,kBAAe,IAAI,QAAQ;AAC3B,QAAK,MAAM,EAAE,WAAW,WAAW,IAAI,SAAS;AAC5C,SAAK,UACD;AAEJ,sBAAkB,IAAI,UAAU;GACnC;EACJ;AAED,OAAK,QAAQ,SAAS;AACtB,OAAK,QAAQ,iBAAiB,EAAE,UAAU,OAAO;AACjD,OAAK,QAAQ,mBAAmB,EAAE,YAAY,OAAO;AACrD,OAAK,QAAQ,gCAAgC,EAAE,sBAAsB,OAAO;AAC5E,OAAK,QAAQ,sBAAsB,EAAE,mBAAmB;AACxD,OAAK,QAAQ,mBAAmB,EAAE,YAAY,KAAK;AACnD,OAAK,QAAQ,sBAAsB,EAAE,eAAe,KAAK;AACzD,OAAK,QAAQ,kBAAkB,EAAE,YAAY,OAAO;AACpD,OAAK,QAAQ,yBAAyB,EAAE,mBAAmB,OAAO;AAClE,OAAK,QAAQ,oBAAoB,CAAC,GAAG,iBAAkB,EAAC,KAAK,IAAI;AAEjE,OAAK,IAAI,IAAI,GAAG,KAAK,UAAU,QAAQ,IAAI,IAAI,EAAE,GAAG;GAChD,MAAM,QAAQ,KAAK,oBAAoB,UAAU,IAAI,GAAG,eAAe;AACvE,SAAM,QAAQ,SAAS,EAAE,EAAE;AAC3B,sBAAmB,YAAY,MAAM;EACxC;AACD,qBAAmB,QAAQ,SAAS,EAAE,UAAU,OAAO;AAEvD,OAAK,gBACD,+BACA,KAAK,2BAA2B,KAAK,KAAK,EAC1C,8BACH;AACD,OAAK,gBACD,6BACA,KAAK,sBAAsB,KAAK,KAAK,EACrC,oBACA,MACH;AACD,OAAK,gBACD,gCACA,KAAK,4BAA4B,KAAK,KAAK,EAC3C,sBACH;AACD,OAAK,gBAAgB,uBAAuB,KAAK,eAAe,KAAK,KAAK,EAAE,UAAU,UAAU,OAAO;AAEvG,OAAK,MAAM,QAAQ,YACf,uBAAsB,YAAY,KAAK,iBAAiB,KAAK,CAAC;AAElE,OAAK,MAAM,WAAW,gBAAgB;AAClC,OAAI,YAAY,IAAI,QAAQ,CACxB;AAEJ,yBAAsB,YAAY,KAAK,iBAAiB,QAAQ,CAAC;EACpE;EAGD,MAAM,gBAAgB,KAAK,qBAAqB,GAAG;AACnD,OAAK,IAAI,IAAI,GAAG,KAAK,YAAY,QAAQ,IAAI,IAAI,EAAE,GAAG;GAClD,MAAM,aAAa,YAAY;GAC/B,MAAM,EAAE,YAAY,iBAAiB,GAAG;AAExC,OAAI,cAAc,aAAa,SAAS,WAAW,CAC/C,eAAc,YAAY;QACvB;AACH,kBAAc,YAAY;AAC1B,kBAAc,aAAa,KAAK,WAAW;AAC3C,kBAAc,OAAO;AACrB,kBAAc,UAAU,CAAC,UAAW;IAEpC,MAAM,wBAAwB,eAAe,KAAK,CAAC,EAAE,OAAO,KAAK,UAAU,WAAW;AACtF,QAAI,uBAAuB;KACvB,MAAMC,yBAAmC,CAAE;AAC3C,4BAAuB,KAAK,sBAAsB,MAAM;AACxD,SAAI,sBAAsB,OACtB,wBAAuB,MAAM,UAAU,sBAAsB,OAAO,EAAE;AAE1E,SAAI,sBAAsB,YACtB,wBAAuB,MAAM,eAAe,sBAAsB,YAAY,EAAE;AAEpF,SAAI,sBAAsB,IACtB,wBAAuB,MAAM,OAAO,sBAAsB,IAAI,EAAE;KAGpE,MAAM,aAAa,uBAAuB,QAAQ,OAAO;AACzD,SAAI,yBAA4B,aAAa,EACzC,wBAAuB,MAAM,cAAc,WAAW,UAAU,CAAC,EAAE;AAGvE,mBAAc,UAAU;IAC3B;GACJ;GAED,MAAM,QAAQ,KAAK,sBAAsB,YAAY,eAAe,WAAW,aAAa,eAAe;AAC3G,SAAM,QAAQ,SAAS,EAAE,EAAE;AAC3B,wBAAqB,YAAY,MAAM;EAC1C;AACD,uBAAqB,QAAQ,SAAS,EAAE,YAAY,OAAO;EAE3D,MAAM,4BAA4B,KAAK,iCAAiC,aAAa,eAAe;AACpG,MAAI,8BAA8B,KAC9B,MAAK,YAAY,0BAA0B;AAG/C,SAAO;CACV;;;;;;;CAQD,iBACIC,iBACAF,gBACW;EACX,MAAM,OAAO,KAAK,aAAa,cAAc;AAC7C,OAAK,QAAQ,aAAa,gBAAgB;EAE1C,MAAM,iBAAiB,KAAK,eAAe,MAAM,eAAe;EAChE,MAAM,8BAA8B,KAAK,eAAe,MAAM,wBAAwB;EACtF,MAAM,eAAe,KAAK,eAAe,MAAM,kBAAkB;EACjE,MAAM,uBAAuB,KAAK,eAAe,MAAM,oBAAoB;EAC3E,MAAM,2BAA2B,KAAK,eAAe,MAAM,0BAA0B;EACrF,MAAM,4BAA4B,KAAK,eAAe,MAAM,2BAA2B;EACvF,MAAM,sBAAsB,KAAK,eAAe,MAAM,oBAAoB;EAC1E,MAAM,2BAA2B,KAAK,eAAe,MAAM,yBAAyB;EACpF,MAAM,sBAAsB,KAAK,eAAe,MAAM,oBAAoB;EAC1E,MAAM,6BAA6B,KAAK,eAAe,MAAM,4BAA4B;AAEzF,OAAK,gBAAgB,gBAAgB,gBAAgB,WAAW,KAAK,UAAU;AAC/E,MAAI,KAAK,cAAc,KACnB,gBAAe,MAAM,aAAa;EAEtC,MAAM,qBAAqB,sBAAsB,gBAAgB,aAAa,eAAe;EAE7F,MAAM,gBAAgB,KAAK,qBAAqB,GAAG;AACnD,gBAAc,OAAO,gBAAgB;AACrC,gBAAc,UAAU,CAAC,gBAAgB,UAAW;EACpD,MAAM,wBAAwB,eAAe,KAAK,CAAC,EAAE,OAAO,KAAK,UAAU,gBAAgB,WAAW;AACtG,MAAI,uBAAuB;GACvB,MAAMC,yBAAmC,CAAE;AAC3C,0BAAuB,KAAK,sBAAsB,MAAM;AACxD,OAAI,sBAAsB,OACtB,wBAAuB,MAAM,UAAU,sBAAsB,OAAO,EAAE;AAE1E,OAAI,sBAAsB,YACtB,wBAAuB,MAAM,eAAe,sBAAsB,YAAY,EAAE;AAEpF,OAAI,sBAAsB,IACtB,wBAAuB,MAAM,OAAO,sBAAsB,IAAI,EAAE;GAGpE,MAAM,aAAa,uBAAuB,QAAQ,OAAO;AACzD,OAAI,yBAA4B,aAAa,EACzC,wBAAuB,MAAM,eAAe,WAAW,UAAU,CAAC,EAAE;AAGxE,iBAAc,UAAU;EAC3B;AAED,OAAK,gBACD,6BACA,KAAK,sBAAsB,KAAK,KAAK,EACrC,oBACA,KACH;AACD,OAAK,gBAAgB,cAAc,KAAK,WAAW,KAAK,KAAK,EAAE,CAAC,GAAG,gBAAgB,MAAM,aAAc,EAAC;AACxG,OAAK,gBAAgB,sBAAsB,KAAK,uBAAuB,KAAK,KAAK,EAAE,gBAAgB,YAAY;AAC/G,OAAK,gBAAgB,0BAA0B,KAAK,oBAAoB,KAAK,KAAK,EAAE,gBAAgB,OAAO;AAC3G,OAAK,gBAAgB,2BAA2B,KAAK,oBAAoB,KAAK,KAAK,EAAE,gBAAgB,QAAQ;AAE7G,sBAAoB,YAAY,KAAK,sBAAsB,gBAAgB,MAAM,KAAK,CAAC;AACvF,2BAAyB,YAAY,KAAK,sBAAsB,gBAAgB,MAAM,MAAM,CAAC;AAC7F,sBAAoB,YAAY,KAAK,sBAAsB,gBAAgB,MAAM,KAAK,CAAC;AACvF,6BAA2B,YAAY,KAAK,sBAAsB,gBAAgB,MAAM,MAAM,CAAC;AAE/F,SAAO;CACV;;;;CAKD,gCAA6C;AACzC,SAAO,KAAK,aAAa,sBAAsB;CAClD;;;;;CAMD,oBAAoBE,MAA2B;AAC3C,SAAO,KAAK,aAAa,KAAK;CACjC;;;;;CAMD,4BAA4BA,MAAgC;AACxD,SAAO,KAAK,WAAW,oBAAoB,KAAK;CACnD;CAID,AAAQ,oBACJC,UACAC,eACAC,gBACW;EACX,MAAM,EAAE,MAAM,SAAS,MAAM,SAAS,GAAG;EAEzC,IAAI,eAAe;EACnB,MAAM,aAAa,IAAI;EACvB,MAAM,eAAe,IAAI;AACzB,OAAK,MAAM,EAAE,WAAW,aAAa,WAAW,IAAI,SAAS;AACzD,OAAI,UACA,gBAAe;AAEnB,cAAW,IAAI,UAAU;AACzB,gBAAa,IAAI,YAAY;EAChC;EAED,MAAM,OAAO,KAAK,aAAa,WAAW;EAE1C,MAAM,gBAAgB,KAAK,eAAe,MAAM,iBAAiB;AAEjE,OAAK,QAAQ,aAAa,EAAE,aAAa;AACzC,OAAK,QAAQ,iBAAiB,EAAE,YAAY,KAAK;AACjD,OAAK,QAAQ,YAAY,iBAAiB,KAAK;AAC/C,OAAK,QAAQ,aAAa,CAAC,GAAG,UAAW,EAAC,KAAK,IAAI;AACnD,OAAK,QAAQ,eAAe,CAAC,GAAG,YAAa,EAAC,KAAK,IAAI;EAEvD,MAAM,EAAE,aAAa,GAAG;EACxB,MAAM,0BAA0B,KAAK,4BACjC,SACA,gBACA,aACA,cACH;AACD,MAAI,4BAA4B,KAC5B,MAAK,QAAQ,0BAA0B;AAE3C,MAAI,YAAY,SAAS,EACrB,MAAK,QAAQ,cAAc,YAAY,KAAK,IAAI;EAGpD,MAAM,kBAAkB,KAAK,eAAe,MAAM,oBAAoB;AACtE,OAAK,gBAAgB,iBAAiB,QAAQ;AAE9C,OAAK,gBAAgB,eAAe,MAAM,SAAS,KAAK,kBAAkB,KAAK,KAAK,CAAC;AAErF,SAAO;CACV;CAED,AAAQ,2BACJC,qBACkB;EAClB,MAAM,EAAE,QAAQ,iBAAiB,GAAG;AACpC,OAAK,MAAM,QAAQ,gBAAgB,IAAI,gBAAgB,WAAW,EAC9D,QAAO;EAEX,MAAM,WAAW,KAAK,aAAa,wBAAwB;EAE3D,MAAM,aAAa,KAAK,yBAAyB,OAAO;AACxD,WAAS,YAAY,WAAW;AAEhC,OAAK,gBAAgB,UAAU,KAAK,sBAAsB,KAAK,KAAK,EAAE,gBAAgB;AACtF,SAAO;CACV;CAED,AAAQ,yBAAyBC,QAAkD;EAC/E,MAAM,OAAO,KAAK,UAAU,cAAc,OAAO;AACjD,OAAK,UAAU,IAAI,yBAAyB;AAC5C,OAAK,QAAQ,mBAAmB;AAChC,UAAQ,QAAR;GACI,KAAK;AACD,SAAK,QAAQ;AACb,WAAO;GACX,KAAK;AACD,SAAK,QAAQ;AACb,WAAO;GACX,KAAK;AACD,SAAK,QAAQ;AACb,WAAO;EACd;CACJ;CAED,AAAQ,sBAAsBC,YAAyD;EACnF,MAAM,EAAE,MAAM,aAAa,GAAG;EAC9B,MAAM,WAAW,KAAK,WAAW,oBAAoB,aAAa;EAClE,MAAM,OAAO,KAAK,eAAe,UAAU,cAAc;AACzD,OAAK,gBAAgB,MAAM,KAAK;AAChC,MAAI,YACA,MAAK,QAAQ;AAEjB,OAAK,QAAQ,SAAS;AACtB,SAAO;CACV;CAED,AAAQ,sBACJC,YACAC,eACAC,WACAC,aACAC,gBACW;EACX,MAAM,EAAE,YAAY,MAAM,iBAAiB,SAAS,GAAG;EACvD,MAAM,kBAAkB,mBAAmB,WAAW,iBAAiB,aAAa,eAAe;EAEnG,MAAM,OAAO,KAAK,aAAa,kBAAkB;EAEjD,MAAM,mBAAmB,KAAK,eAAe,MAAM,uBAAuB;EAC1E,MAAM,oBAAoB,KAAK,eAAe,MAAM,kCAAkC;EACtF,MAAM,mBAAmB,KAAK,eAAe,MAAM,cAAc;AAEjE,OAAK,QAAQ,aAAa;AAE1B,OAAK,gBAAgB,kBAAkB,KAAK,WAAW,KAAK,KAAK,EAAE,CAAC,GAAG,MAAM,aAAc,EAAC;AAC5F,OAAK,gBAAgB,mBAAmB,KAAK,0BAA0B,KAAK,KAAK,EAAE,gBAAgB;AACnG,OAAK,gBAAgB,kBAAkB,KAAK,2BAA2B,KAAK,KAAK,EAAE,SAAS,WAAW;AACvG,SAAO;CACV;CAED,AAAQ,iCACJC,aACAf,gBACuB;EACvB,MAAM,mBAAmB,IAAI;AAC7B,OAAK,MAAM,EAAE,YAAY,IAAI,YACzB,kBAAiB,IAAI,WAAW;EAGpC,IAAI,YAAY;AAChB,OAAK,MAAM,cAAc,kBAAkB;GACvC,MAAM,OAAO,eAAe,KAAK,CAAC,EAAE,OAAO,KAAK,UAAU,WAAW;GACrE,MAAM,SAAS,MAAM,QAAQ,MAAM,IAAI;AACvC,OAAI,OAAO,WAAW,EAClB;GAIJ,MAAM,eAAe,WAAW,WAAW,MAAM,OAAO,CAAC,WAAW,MAAK,OAAM;AAC/E,iBAAc,sBAAsB,aAAa,MAAM,OAAO;EACjE;AAED,MAAI,UAAU,WAAW,EACrB,QAAO;EAGX,MAAM,OAAO,KAAK,UAAU,cAAc,QAAQ;AAClD,OAAK,YAAY;AACjB,OAAK,cAAc;AACnB,SAAO;CACV;CAED,AAAQ,2BACJgB,OACAC,YACkB;AAClB,iBAAe,OAAf;GACI,KAAK,SACD,QAAO,KAAK,+BAA+B,MAAM;GACrD,KAAK,UAAU;AACX,YAAQ,MAAM,MAAd;KACI,KAAK,QACD,QAAO,KAAK,gCAAgC,OAAO,WAAW;KAClE,KAAK,qBACD,QAAO,KAAK,4CAA4C,MAAM,SAAS,WAAW;KACtF,KAAK,OACD;IACP;AACD;GACH;EACJ;AACD,SAAO;CACV;CAED,AAAQ,+BAA+BC,MAA2B;EAC9D,MAAM,OAAO,KAAK,aAAa,aAAa;EAC5C,MAAM,YAAY,KAAK,eAAe,MAAM,iBAAiB;AAC7D,OAAK,yBAAyB,WAAW,KAAK;AAC9C,SAAO;CACV;CAED,AAAQ,gCAAgCC,MAAwCF,YAAiC;EAC7G,MAAM,EAAE,aAAa,GAAG;EAExB,MAAM,OAAO,KAAK,aAAa,aAAa;EAE5C,MAAM,mBAAmB,KAAK,eAAe,MAAM,iBAAiB;EACpE,MAAM,QAAQ,KAAK,4BAA4B,sBAAsB,MAAM,WAAW;AACtF,mBAAiB,YAAY,MAAM;AAEnC,aAAW,gBAAgB,UAAU;GACjC,MAAM,WAAW,KAAK,WAAW,oBAAoB,+BAA+B;GACpF,MAAM,YAAY,KAAK,eAAe,UAAU,2BAA2B;AAC3E,QAAK,yBAAyB,WAAW,YAAY;AACrD,oBAAiB,YAAY,SAAS;EACzC;AAED,SAAO;CACV;CAED,AAAQ,4CACJG,SACAH,YACW;EACX,MAAM,OAAO,KAAK,aAAa,aAAa;EAC5C,MAAM,mBAAmB,KAAK,eAAe,MAAM,iBAAiB;AACpE,OAAK,4BAA4B,wBAAwB,kBAAkB,SAAS,WAAW;AAC/F,SAAO;CACV;CAED,AAAQ,0BAA0BI,gBAAqC;EACnE,MAAM,OAAO,KAAK,aAAa,4BAA4B;AAC3D,OAAK,QAAQ,OAAO;AACpB,OAAK,gBAAgB,MAAM,gBAAgB,KAAK,UAAU;AAC1D,SAAO;CACV;CAED,AAAQ,iBAAiBC,WAAsC;EAC3D,MAAM,OAAO,KAAK,UAAU,cAAc,IAAI;AAC9C,OAAK,YAAY;AACjB,OAAK,gBAAgB,MAAM,WAAW,KAAK,UAAU;AACrD,SAAO;CACV;CAED,AAAQ,uBAAuBJ,MAA2B;EACtD,MAAM,OAAO,KAAK,aAAa,mBAAmB;EAClD,MAAM,YAAY,KAAK,eAAe,MAAM,uBAAuB;AACnE,OAAK,yBAAyB,WAAW,KAAK;AAC9C,SAAO;CACV;CAED,AAAQ,oBAAoBK,SAA8B;EACtD,MAAM,OAAO,KAAK,aAAa,gBAAgB;AAC/C,OAAK,gBAAgB,MAAM,SAAS,KAAK,UAAU;AACnD,SAAO;CACV;CAED,AAAQ,sBAAsBC,SAA8C;EACxE,MAAM,OAAO,KAAK,aAAa,mBAAmB;EAClD,MAAM,YAAY,KAAK,eAAe,MAAM,yBAAyB;EAErE,MAAM,QAAQ,KAAK,gBAAgB,WAAW,KAAK,0BAA0B,KAAK,KAAK,EAAE,QAAQ;AACjG,MAAI,UAAU,GAAG;GACb,MAAM,IAAI,KAAK,gCAAgC;AAC/C,aAAU,YAAY,EAAE;EAC3B;AAED,SAAO;CACV;CAED,AAAQ,0BAA0BC,SAA4C;EAC1E,MAAM,EAAE,SAAS,MAAM,OAAO,GAAG;EACjC,MAAM,OAAO,KAAK,aAAa,wBAAwB;EACvD,MAAM,WAAW,KAAK,eAAe,MAAM,gCAAgC;EAC3E,MAAM,YAAY,KAAK,eAAe,MAAM,+BAA+B;AAC3E,OAAK,gBAAgB,UAAU,QAAQ,SAAS,IAAI,UAAU,KAAK;AACnE,OAAK,gBAAgB,kBAAkB,UAAU,WAAW,SAAS,EAAE,MAAM,EAAE;AAC/E,SAAO;CACV;CAED,AAAQ,iCAA8C;AAClD,SAAO,KAAK,aAAa,yBAAyB;CACrD;CAED,AAAQ,WAAWC,KAAkC;EACjD,MAAM,EAAE,SAAS,MAAM,UAAU,WAAW,GAAG;EAC/C,MAAM,OAAO,KAAK,aAAa,MAAM;EAErC,MAAM,QAAQ,KAAK,eAAe,MAAM,qBAAqB;EAE7D,MAAM,gBAAgB,QAAQ,KAAK,KAAK;AAExC,OAAK,QAAQ;AACb,OAAK,gBAAgB,OAAO,KAAK;AACjC,OAAK,QAAQ,UAAU,cAAc,SAAS,IAAI,gBAAgB;AAClE,OAAK,QAAQ,WAAW;AACxB,MAAI,UACA,MAAK,QAAQ,YAAY;AAG7B,SAAO;CACV;CAED,AAAQ,eAAeC,SAAsCC,oBAAyC;EAClG,MAAM,EAAE,KAAK,iBAAiB,GAAG;EACjC,MAAM,OAAO,KAAK,WAAW,IAAI;AACjC,OAAK,QAAQ,YAAY,gBAAgB,KAAK,IAAI;AAClD,OAAK,QAAQ,sBAAsB,EAAE,mBAAmB;AACxD,OAAK,QAAQ,wBAAwB,EAAE,gBAAgB,OAAO;AAC9D,OAAK,QAAQ,0BAA0B,EAAE,KAAK,IAAI,GAAG,qBAAqB,gBAAgB,OAAO,CAAC;AAClG,SAAO;CACV;CAED,AAAQ,eAAezB,MAAc0B,UAAkC;AACnE,SAAO;GACH;GACA;GACA,OAAO;GACP,OAAO;GACP,SAAS,CAAE;GACX,cAAc,CAAE;GAChB,WAAW;EACd;CACJ;CAED,AAAQ,iBAAiBX,MAA2B;AAChD,SAAO,KAAK,WAAW,KAAK,eAAe,MAAM,SAAS,CAAC;CAC9D;CAED,AAAQ,4BAA4BY,SAA0E;EAC1G,MAAM,EAAE,YAAY,iBAAiB,gBAAgB,GAAG;EAExD,MAAM,OAAO,KAAK,aAAa,sBAAsB;AACrD,OAAK,QAAQ,aAAa;AAC1B,OAAK,QAAQ,sBAAsB;AACnC,OAAK,QAAQ,uBAAuB,EAAE,eAAe,OAAO;EAE5D,MAAM,KAAK,KAAK,eAAe,MAAM,gCAAgC;EACrE,MAAM,MAAM,KAAK,WAAW,KAAK,eAAe,iBAAiB,2BAA2B,CAAC;AAC7F,MAAI,QAAQ,UAAU;AACtB,KAAG,YAAY,IAAI;EAEnB,IAAI,UAAU;AACd,OAAK,MAAM,EACP,eAAe,EAAE,MAAM,EAC1B,IAAI,eACD,KAAI,KAAK,SAAS,GAAG;AACjB,aAAU;AACV;EACH;EAGL,MAAM,IAAI,KAAK,eAAe,MAAM,sBAAsB;AAC1D,IAAE,QAAQ,WAAW,EAAE,QAAQ;AAC/B,OAAK,gBAAgB,GAAG,KAAK,qBAAqB,KAAK,KAAK,EAAE,eAAe;AAE7E,SAAO;CACV;CAED,AAAQ,qBAAqBC,SAA+D;EACxF,MAAM,EAAE,eAAe,GAAG;AAC1B,UAAQ,cAAc,MAAtB;GACI,KAAK,eACD,QAAO,KAAK,gCAAgC,eAAe,QAAQ;GACvE,KAAK,yBACD,QAAO,KAAK,0CAA0C,eAAe,QAAQ;EACpF;CACJ;CAED,AAAQ,0CACJC,eACAD,SACW;EACX,MAAM,EAAE,KAAK,MAAM,GAAG;EACtB,MAAM,EAAE,gBAAgB,mBAAmB,GAAG;EAE9C,MAAM,OAAO,KAAK,aAAa,gBAAgB;AAE/C,OAAK,QAAQ,oBAAoB,cAAc;AAC/C,OAAK,QAAQ,YAAY,EAAE,KAAK,OAAO;EAEvC,IAAI,IAAI,KAAK,eAAe,MAAM,0BAA0B;AAC5D,OAAK,gBAAgB,GAAG,KAAK,WAAW,KAAK,KAAK,EAAE,KAAK;AAEzD,MAAI,KAAK,eAAe,MAAM,qCAAqC;AACnE,OAAK,oCAAoC,GAAG,gBAAgB,kBAAkB;AAE9E,MAAI,KAAK,eAAe,MAAM,gCAAgC;AAC9D,OAAK,gBAAgB,GAAG,IAAI;AAE5B,SAAO;CACV;CAED,AAAQ,gCACJE,aACAF,SACW;EACX,MAAM,EAAE,WAAW,gBAAgB,kBAAkB,MAAM,GAAG;EAC9D,MAAM,EAAE,SAAS,gBAAgB,mBAAmB,GAAG;EACvD,MAAM,QAAQ,aAAa,QAAQ;EAEnC,MAAM,OAAO,KAAK,aAAa,gBAAgB;AAE/C,OAAK,QAAQ,+BAA+B,EAAE,UAAU;AACxD,OAAK,QAAQ,oBAAoB,YAAY;AAC7C,MAAI,eAAe,SAAS,EACxB,MAAK,QAAQ,oBAAoB,eAAe,KAAK,IAAI;AAE7D,MAAI,iBAAiB,SAAS,EAC1B,MAAK,QAAQ,sBAAsB,iBAAiB,KAAK,IAAI;AAEjE,OAAK,QAAQ,YAAY,EAAE,KAAK,OAAO;EAEvC,IAAI,IAAI,KAAK,eAAe,MAAM,0BAA0B;AAC5D,OAAK,gBAAgB,GAAG,KAAK,WAAW,KAAK,KAAK,EAAE,KAAK;AAEzD,MAAI,KAAK,eAAe,MAAM,qCAAqC;AACnE,OAAK,oCAAoC,GAAG,gBAAgB,kBAAkB;AAE9E,MAAI,KAAK,eAAe,MAAM,6CAA6C;AAC3E,IAAE,YAAY,KAAK,wBAAwB,oCAAoC,UAAU,CAAC;AAE1F,MAAI,KAAK,eAAe,MAAM,gCAAgC;AAC9D,IAAE,OAAO,KAAK;AACd,IAAE,YACE,KAAK,wBAAwB,wBAAwB,OAAO,WAAW,gBAAgB,iBAAiB,CAC3G;AAED,MAAI,KAAK,eAAe,MAAM,iCAAiC;AAC/D,IAAE,YAAY,KAAK,wBAAwB,yBAAyB,OAAO,UAAU,CAAC;AAEtF,SAAO;CACV;CAED,AAAQ,oCACJG,WACAC,gBACAC,mBACI;EACJ,MAAM,eAAe;AACrB,OAAK,MAAM,QAAQ,gBAAgB;GAC/B,MAAM,OAAO,KAAK,aAAa,aAAa;AAC5C,QAAK,QAAQ,OAAO;AACpB,QAAK,gBAAgB,MAAM,MAAM,KAAK,UAAU;AAChD,aAAU,YAAY,KAAK;EAC9B;AAED,OAAK,MAAM,oBAAoB,mBAAmB;GAC9C,MAAM,OAAO,KAAK,aAAa,aAAa;AAC5C,QAAK,QAAQ,OAAO;AACpB,QAAK,gBAAgB,MAAM,kBAAkB,KAAK,UAAU;AAC5D,aAAU,YAAY,KAAK;EAC9B;AAED,YAAU,QAAQ,SAAS,EAAE,eAAe,SAAS,kBAAkB,OAAO;AAC9E,YAAU,QAAQ,aAAa,EAAE,eAAe,OAAO;AACvD,YAAU,QAAQ,gBAAgB,EAAE,kBAAkB,OAAO;CAChE;CAED,AAAQ,sBACJC,SAGAC,OACW;EACX,MAAM,EAAE,YAAY,iBAAiB,aAAa,WAAW,GAAG;EAEhE,MAAM,OAAO,KAAK,aAAa,uBAAuB;EACtD,MAAM,OAAO,KAAK,eAAe,MAAM,oBAAoB;EAE3D,MAAM,WAAW,KAAK,eAAe,MAAM,qBAAqB;EAChE,MAAM,MAAM,KAAK,eAAe,MAAM,OAAO;AAE7C,OAAK,gBAAgB,UAAU,gBAAgB;EAE/C,MAAM,KAAK,YAAY;AACvB,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,EAAE,GAAG;GACzB,MAAM,OAAO,YAAY;GACzB,MAAM,WAAW,QACX,KAAK,sBACD,MACA,YACA,iBACA,WAAW,UAAU,CACxB,GACD,KAAK,qBACD,MACA,YACA,iBACA,WAAW,UAAU,CACxB;AACP,YAAS,QAAQ,SAAS,EAAE,EAAE;AAC9B,QAAK,YAAY,SAAS;EAC7B;AAED,OAAK,QAAQ,SAAS,EAAE,GAAG;AAC3B,OAAK,QAAQ,SAAS,EAAE,GAAG;AAC3B,OAAK,QAAQ,UAAU;AACvB,MAAI,QAAQ,WAAW,EAAE,WAAW,qBAAqB,WAAW,UAAU,CAAC,EAAE,QAAQ,WAAW,SAAS;AAC7G,SAAO;CACV;CAED,AAAQ,qBACJC,SACAtB,YACAuB,iBACAC,WACW;EACX,MAAM,EAAE,MAAM,SAAS,QAAQ,GAAG;EAClC,MAAM,OAAO,KAAK,aAAa,sBAAsB;EACrD,MAAM,WAAW,KAAK,eAAe,MAAM,qBAAqB;EAChE,MAAM,MAAM,KAAK,eAAe,MAAM,OAAO;EAC7C,MAAM,qBAAqB,KAAK,eAAe,MAAM,iCAAiC;EACtF,MAAM,wBAAwB,KAAK,eAAe,MAAM,oCAAoC;EAC5F,MAAM,qBAAqB,KAAK,eAAe,MAAM,wBAAwB;AAE7E,OAAK,gBAAgB,UAAU,gBAAgB;AAC/C,OAAK,gBAAgB,oBAAoB,MAAM,KAAK,UAAU;AAC9D,OAAK,gBAAgB,uBAAuB,YAAY,OAAO,UAAU,IAAI,KAAK,UAAU;AAC5F,OAAK,4BAA4B,oBAAoB,OAAO;AAE5D,OAAK,QAAQ,OAAO;AACpB,aAAW,YAAY,SACnB,MAAK,QAAQ,UAAU;AAE3B,OAAK,QAAQ,cAAc,EAAE,YAAY,KAAK;AAC9C,OAAK,QAAQ,iBAAiB,EAAE,YAAY,KAAK;AACjD,OAAK,QAAQ,aAAa;AAC1B,OAAK,QAAQ,UAAU;AACvB,MAAI,QAAQ,WAAW,EAAE,WAAW,qBAAqB,aAAa,GAAG;AACzE,SAAO;CACV;CAED,AAAQ,sBACJC,SACAzB,YACAuB,iBACAC,WACW;EACX,MAAM,EAAE,WAAW,QAAQ,GAAG;EAC9B,MAAM,OAAO,KAAK,aAAa,uBAAuB;EACtD,MAAM,WAAW,KAAK,eAAe,MAAM,qBAAqB;EAChE,MAAM,MAAM,KAAK,eAAe,MAAM,OAAO;EAC7C,MAAM,qBAAqB,KAAK,eAAe,MAAM,wBAAwB;AAE7E,OAAK,gBAAgB,UAAU,gBAAgB;AAC/C,OAAK,4BAA4B,oBAAoB,OAAO;AAE5D,OAAK,QAAQ,YAAY;AACzB,OAAK,QAAQ,aAAa;AAC1B,OAAK,QAAQ,UAAU;AACvB,MAAI,QAAQ,WAAW,EAAE,WAAW,qBAAqB,aAAa,GAAG;AAEzE,SAAO;CACV;CAED,AAAQ,4BAA4BE,MAAmBC,QAAmD;EACtG,IAAI,gBAAgB;AACpB,OAAK,IAAI,IAAI,GAAG,KAAK,OAAO,QAAQ,IAAI,IAAI,EAAE,GAAG;GAC7C,MAAM,EAAE,WAAW,cAAc,GAAG,OAAO;GAC3C,MAAM,mBAAmB,EAAE,UAAU;GACrC,MAAM,OAAO,iBAAiB,OAAO,gBAAgB,EAAE,UAAU;AAEjE,OAAI,IAAI,GAAG;IACP,MAAMC,UAAQ,KAAK,UAAU,cAAc,OAAO;AAClD,YAAM,YAAY;AAClB,YAAM,QAAQ,aAAa,EAAE,UAAU;AACvC,YAAM,cAAc;AACpB,SAAK,YAAYA,QAAM;AACvB,qBAAiB;GACpB;GAED,MAAM,QAAQ,KAAK,UAAU,cAAc,OAAO;AAClD,SAAM,YAAY;AAClB,SAAM,QAAQ,YAAY;AAC1B,OAAI,iBAAiB,MAAM;AACvB,UAAM,QAAQ,gBAAgB,EAAE,aAAa;AAC7C,QAAI,iBAAiB,gBACjB,OAAM,QAAQ;GAErB;AACD,QAAK,gBAAgB,OAAO,MAAM,KAAK,UAAU;AACjD,QAAK,YAAY,MAAM;AAEvB,oBAAiB;EACpB;AAED,OAAK,QAAQ,YAAY;CAC5B;CAED,AAAQ,kBAAkBX,WAAwBhB,MAAoB;EAClE,IAAI,OAAO;AACX,OAAK,MAAM,KAAK,KACZ,KAAI,iBAAiB,EAAE,YAAY,EAAE,CAAW,EAAE;AAC9C,OAAI,KAAK,SAAS,GAAG;AACjB,cAAU,YAAY,KAAK,UAAU,eAAe,KAAK,CAAC;AAC1D,WAAO;GACV;GAED,MAAM,OAAO,KAAK,iBAAiB,EAAE;AACrC,aAAU,YAAY,KAAK;EAC9B,MACG,SAAQ;AAGhB,MAAI,KAAK,SAAS,EACd,WAAU,YAAY,KAAK,UAAU,eAAe,KAAK,CAAC;CAEjE;CAED,AAAQ,gBACJgB,WACAY,YACAC,cACAC,KACM;EACN,IAAI,QAAQ;EACZ,MAAM,eAAe;AACrB,MAAI,MAAM,QAAQ,aAAa,CAC3B,MAAK,MAAM,WAAW,cAAc;GAChC,MAAM,OAAO,WAAW,SAAS,IAAiB;AAClD,OAAI,SAAS,KACT;AAEJ,aAAU,YAAY,KAAK;AAC3B,OAAI,KAAK,aAAa,aAClB,CAAC,KAAqB,QAAQ,SAAS,EAAE,MAAM;AAEnD,KAAE;EACL;AAGL,YAAU,QAAQ,SAAS,EAAE,MAAM;AAEnC,SAAO;CACV;CAED,AAAQ,gBACJd,WACAe,MACA1B,SACA2B,SACI;AACJ,YAAU,OAAO,KAAK;EACtB,MAAM,WAAW,mBAAmB,MAAM,QAAQ;AAClD,OAAK,MAAM,EAAE,MAAM,SAAS,UAAU,IAAI,SACtC,KAAI,UAAU;GACV,MAAM,OAAO,KAAK,UAAU,cAAc,OAAO;GACjD,MAAM,KAAK,KAAK,UAAU,cAAc,KAAK;AAC7C,WAAQ,MAAM,KAAK;AACnB,QAAK,YAAY,GAAG;AACpB,MAAG,YAAY,KAAK,UAAU,eAAe,SAAS,CAAC;AACvD,aAAU,YAAY,KAAK;EAC9B,MACG,SAAQ,WAAW,KAAK;CAGnC;CAED,AAAQ,qBAAqBjC,YAAoC;AAC7D,SAAO,KAAK,eAAe,YAAY,aAAa;CACvD;CAED,AAAQ,gBAAgB0B,MAAmBQ,OAAeC,UAAyB;AAC/E,OAAK,oBAAoB,MAAM,UAAU,MAAM;AAC/C,OAAK,cAAc;CACtB;CAED,AAAQ,yBAAyBT,MAAmBQ,OAAeC,UAAyB;AACxF,OAAK,oBAAoB,MAAM,UAAU,MAAM;EAE/C,IAAI,QAAQ;AACZ,SAAO,MAAM;GACT,MAAM,MAAM,MAAM,QAAQ,MAAM,MAAM;AACtC,OAAI,MAAM,EACN;AAEJ,QAAK,YAAY,KAAK,UAAU,eAAe,MAAM,UAAU,OAAO,IAAI,CAAC,CAAC;AAC5E,QAAK,YAAY,KAAK,UAAU,cAAc,KAAK,CAAC;AACpD,WAAQ,MAAM;EACjB;AAED,MAAI,QAAQ,MAAM,OACd,MAAK,YAAY,KAAK,UAAU,eAAe,UAAU,IAAI,QAAQ,MAAM,UAAU,MAAM,CAAC,CAAC;CAEpG;CAED,AAAQ,oBAAoBC,SAAsBC,UAA8BC,SAAuB;AACnG,aAAW,aAAa,SACpB,SAAQ,OAAO;OACZ;GACH,MAAM,YAAY,oBAAoB,SAAS,KAAK,UAAU;AAC9D,OAAI,cAAc,KACd,SAAQ,OAAO;EAEtB;CACJ;CAED,AAAQ,4BACJhC,SACAiC,oBACAC,aACApD,eACa;AACb,MAAI,mBAAmB,WAAW,EAC9B,QAAO;EAEX,MAAM,oBAAoB,yBAAyB,YAAY;EAC/D,MAAM,aAAa,IAAI;AACvB,OAAK,MAAM,qBAAqB,oBAAoB;AAChD,OAAI,kBAAkB,kBAAkB,cACpC;AAEJ,QAAK,MAAM,iBAAiB,kBAAkB,gBAAgB;AAC1D,QAAI,cAAc,SAAS,eACvB;IAEJ,MAAM,WAAW,iBAAiB,SAAS,cAAc,WAAW,kBAAkB;AACtF,QAAI,aAAa,KACb,YAAW,IAAI,SAAS;GAE/B;EACJ;AACD,SAAO,WAAW,OAAO,IAAI,CAAC,GAAG,UAAW,EAAC,KAAK,IAAI,GAAG;CAC5D;CAED,AAAQ,aAAaF,MAA2B;AAC5C,SAAO,KAAK,WAAW,YAAY,KAAK;CAC3C;CAED,AAAQ,eAAeuD,SAAqCC,UAA+B;EACvF,MAAM,SAAS,QAAQ,cAAc,SAAS;AAC9C,MAAI,WAAW,KACX,OAAM,IAAI,OAAO,0BAA0B,SAAS;AAExD,SAAO;CACV;AACJ"}
@@ -1,4 +1,4 @@
1
- import { distributeFurigana } from "./japanese-DhmmW35J.js";
1
+ import { distributeFurigana } from "./japanese-CKPyY5k_.js";
2
2
 
3
3
  //#region src/language/ja/furigana.ts
4
4
  function generateFurigana(text, reading) {
@@ -7,4 +7,4 @@ function generateFurigana(text, reading) {
7
7
 
8
8
  //#endregion
9
9
  export { generateFurigana };
10
- //# sourceMappingURL=furigana-CI6LUA-6.js.map
10
+ //# sourceMappingURL=furigana-BpFJbm9M.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"furigana-CI6LUA-6.js","names":["text: string","reading: string"],"sources":["../src/language/ja/furigana.ts"],"sourcesContent":["export type { FuriganaSegment } from './japanese';\nexport { distributeFurigana, distributeFuriganaInflected } from './japanese';\n\nimport { distributeFurigana } from './japanese';\nimport type { FuriganaSegment } from './japanese';\n\nexport function generateFurigana(text: string, reading: string): FuriganaSegment[] {\n return distributeFurigana(text, reading);\n}\n"],"mappings":";;;AAMA,SAAgB,iBAAiBA,MAAcC,SAAoC;AAC/E,QAAO,mBAAmB,MAAM,QAAQ;AAC3C"}
1
+ {"version":3,"file":"furigana-BpFJbm9M.js","names":["text: string","reading: string"],"sources":["../src/language/ja/furigana.ts"],"sourcesContent":["export type { FuriganaSegment } from './japanese';\nexport { distributeFurigana, distributeFuriganaInflected } from './japanese';\n\nimport { distributeFurigana } from './japanese';\nimport type { FuriganaSegment } from './japanese';\n\nexport function generateFurigana(text: string, reading: string): FuriganaSegment[] {\n return distributeFurigana(text, reading);\n}\n"],"mappings":";;;AAMA,SAAgB,iBAAiBA,MAAcC,SAAoC;AAC/E,QAAO,mBAAmB,MAAM,QAAQ;AAC3C"}
@@ -0,0 +1,5 @@
1
+ import "./cjk-util-DubXBGDG.js";
2
+ import { distributeFurigana, distributeFuriganaInflected } from "./japanese-CKPyY5k_.js";
3
+ import { generateFurigana } from "./furigana-BpFJbm9M.js";
4
+
5
+ export { generateFurigana };
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_japanese = require('./japanese-BVV1Ctk-.cjs');
2
+ const require_japanese = require('./japanese-C83fmEfb.cjs');
3
3
 
4
4
  //#region src/language/ja/furigana.ts
5
5
  function generateFurigana(text, reading) {
@@ -13,4 +13,4 @@ Object.defineProperty(exports, 'generateFurigana', {
13
13
  return generateFurigana;
14
14
  }
15
15
  });
16
- //# sourceMappingURL=furigana-BnY7-dJ-.cjs.map
16
+ //# sourceMappingURL=furigana-dSFngFbc.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"furigana-BnY7-dJ-.cjs","names":["text: string","reading: string"],"sources":["../src/language/ja/furigana.ts"],"sourcesContent":["export type { FuriganaSegment } from './japanese';\nexport { distributeFurigana, distributeFuriganaInflected } from './japanese';\n\nimport { distributeFurigana } from './japanese';\nimport type { FuriganaSegment } from './japanese';\n\nexport function generateFurigana(text: string, reading: string): FuriganaSegment[] {\n return distributeFurigana(text, reading);\n}\n"],"mappings":";;;;AAMA,SAAgB,iBAAiBA,MAAcC,SAAoC;AAC/E,QAAO,oCAAmB,MAAM,QAAQ;AAC3C"}
1
+ {"version":3,"file":"furigana-dSFngFbc.cjs","names":["text: string","reading: string"],"sources":["../src/language/ja/furigana.ts"],"sourcesContent":["export type { FuriganaSegment } from './japanese';\nexport { distributeFurigana, distributeFuriganaInflected } from './japanese';\n\nimport { distributeFurigana } from './japanese';\nimport type { FuriganaSegment } from './japanese';\n\nexport function generateFurigana(text: string, reading: string): FuriganaSegment[] {\n return distributeFurigana(text, reading);\n}\n"],"mappings":";;;;AAMA,SAAgB,iBAAiBA,MAAcC,SAAoC;AAC/E,QAAO,oCAAmB,MAAM,QAAQ;AAC3C"}
@@ -0,0 +1,5 @@
1
+ require('./cjk-util-Dp0ZU0sh.cjs');
2
+ const require_japanese = require('./japanese-C83fmEfb.cjs');
3
+ const require_furigana = require('./furigana-dSFngFbc.cjs');
4
+
5
+ exports.generateFurigana = require_furigana.generateFurigana