yomitan-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +485 -0
- package/dist/anki-connect-BQyCGW3O.cjs +513 -0
- package/dist/anki-connect-BQyCGW3O.cjs.map +1 -0
- package/dist/anki-connect-CPPuhyiQ.js +6 -0
- package/dist/anki-connect-DbrQHphS.js +495 -0
- package/dist/anki-connect-DbrQHphS.js.map +1 -0
- package/dist/anki-connect-DcheJrp-.cjs +6 -0
- package/dist/anki.cjs +1758 -0
- package/dist/anki.cjs.map +1 -0
- package/dist/anki.d.cts +751 -0
- package/dist/anki.d.cts.map +1 -0
- package/dist/anki.d.ts +751 -0
- package/dist/anki.d.ts.map +1 -0
- package/dist/anki.js +1751 -0
- package/dist/anki.js.map +1 -0
- package/dist/audio-D9DvYyB7.d.cts +48 -0
- package/dist/audio-D9DvYyB7.d.cts.map +1 -0
- package/dist/audio-DQulUkDM.d.ts +48 -0
- package/dist/audio-DQulUkDM.d.ts.map +1 -0
- package/dist/audio-url-generator-BXvQaqUi.cjs +4 -0
- package/dist/audio-url-generator-Dy2hb2Mm.cjs +414 -0
- package/dist/audio-url-generator-Dy2hb2Mm.cjs.map +1 -0
- package/dist/audio-url-generator-Qi0rfzHz.js +4 -0
- package/dist/audio-url-generator-pFQAB5Nb.js +390 -0
- package/dist/audio-url-generator-pFQAB5Nb.js.map +1 -0
- package/dist/audio.cjs +7 -0
- package/dist/audio.d.cts +86 -0
- package/dist/audio.d.cts.map +1 -0
- package/dist/audio.d.ts +86 -0
- package/dist/audio.d.ts.map +1 -0
- package/dist/audio.js +4 -0
- package/dist/batch-processor-BR-gB3H3.js +84 -0
- package/dist/batch-processor-BR-gB3H3.js.map +1 -0
- package/dist/batch-processor-CSF1acTw.cjs +3 -0
- package/dist/batch-processor-DFqM_L-_.cjs +91 -0
- package/dist/batch-processor-DFqM_L-_.cjs.map +1 -0
- package/dist/batch-processor-Quo9jUyf.js +3 -0
- package/dist/chunk-BCwAaXi7.cjs +31 -0
- package/dist/cjk-util-Dp0ZU0sh.cjs +167 -0
- package/dist/cjk-util-Dp0ZU0sh.cjs.map +1 -0
- package/dist/cjk-util-DubXBGDG.js +94 -0
- package/dist/cjk-util-DubXBGDG.js.map +1 -0
- package/dist/core-BUpclilG.d.cts +102 -0
- package/dist/core-BUpclilG.d.cts.map +1 -0
- package/dist/core-DFUj5GtA.d.ts +102 -0
- package/dist/core-DFUj5GtA.d.ts.map +1 -0
- package/dist/database.cjs +7 -0
- package/dist/database.d.cts +4 -0
- package/dist/database.d.ts +4 -0
- package/dist/database.js +5 -0
- package/dist/dictionary-D7l-qFt1.d.cts +316 -0
- package/dist/dictionary-D7l-qFt1.d.cts.map +1 -0
- package/dist/dictionary-_vzfBLWi.d.ts +316 -0
- package/dist/dictionary-_vzfBLWi.d.ts.map +1 -0
- package/dist/dictionary-data-util-CHnRdYZ9.cjs +378 -0
- package/dist/dictionary-data-util-CHnRdYZ9.cjs.map +1 -0
- package/dist/dictionary-data-util-CfOLfEDE.js +323 -0
- package/dist/dictionary-data-util-CfOLfEDE.js.map +1 -0
- package/dist/dictionary-database-BDC2f9zc.d.ts +58 -0
- package/dist/dictionary-database-BDC2f9zc.d.ts.map +1 -0
- package/dist/dictionary-database-CU4TsvCC.js +393 -0
- package/dist/dictionary-database-CU4TsvCC.js.map +1 -0
- package/dist/dictionary-database-DsOi04Sg.d.cts +58 -0
- package/dist/dictionary-database-DsOi04Sg.d.cts.map +1 -0
- package/dist/dictionary-database-lvFvftnO.cjs +412 -0
- package/dist/dictionary-database-lvFvftnO.cjs.map +1 -0
- package/dist/dictionary-importer-BkQQSBhm.d.ts +237 -0
- package/dist/dictionary-importer-BkQQSBhm.d.ts.map +1 -0
- package/dist/dictionary-importer-Cen1z6co.js +1821 -0
- package/dist/dictionary-importer-Cen1z6co.js.map +1 -0
- package/dist/dictionary-importer-DYmmWmcX.cjs +8 -0
- package/dist/dictionary-importer-Da3AuTZw.d.cts +237 -0
- package/dist/dictionary-importer-Da3AuTZw.d.cts.map +1 -0
- package/dist/dictionary-importer-Dhn75iZ4.cjs +1834 -0
- package/dist/dictionary-importer-Dhn75iZ4.cjs.map +1 -0
- package/dist/dictionary-importer-xWkel0h-.js +8 -0
- package/dist/dictionary-update-checker-BNE4pGTx.js +4 -0
- package/dist/dictionary-update-checker-Byjvifd2.cjs +75 -0
- package/dist/dictionary-update-checker-Byjvifd2.cjs.map +1 -0
- package/dist/dictionary-update-checker-YdpalZ41.cjs +4 -0
- package/dist/dictionary-update-checker-kKukiovj.js +69 -0
- package/dist/dictionary-update-checker-kKukiovj.js.map +1 -0
- package/dist/display-generator-BGVWiI0t.js +746 -0
- package/dist/display-generator-BGVWiI0t.js.map +1 -0
- package/dist/display-generator-BMQmG5Ov.cjs +9 -0
- package/dist/display-generator-BxZ7mBjP.js +9 -0
- package/dist/display-generator-DyP-HNzP.cjs +758 -0
- package/dist/display-generator-DyP-HNzP.cjs.map +1 -0
- package/dist/errors-BSezaJwm.cjs +35 -0
- package/dist/errors-BSezaJwm.cjs.map +1 -0
- package/dist/errors-DuuDSO5N.js +22 -0
- package/dist/errors-DuuDSO5N.js.map +1 -0
- package/dist/frequency-ranking-BXjfhhUQ.js +3 -0
- package/dist/frequency-ranking-Cx1kkIrw.cjs +3 -0
- package/dist/frequency-ranking-DEJMTMdg.js +159 -0
- package/dist/frequency-ranking-DEJMTMdg.js.map +1 -0
- package/dist/frequency-ranking-DVYxTXN-.cjs +166 -0
- package/dist/frequency-ranking-DVYxTXN-.cjs.map +1 -0
- package/dist/furigana-5HK97CY8.js +4 -0
- package/dist/furigana-9bBI9-qe.d.ts +47 -0
- package/dist/furigana-9bBI9-qe.d.ts.map +1 -0
- package/dist/furigana-B3-0y231.js +471 -0
- package/dist/furigana-B3-0y231.js.map +1 -0
- package/dist/furigana-CjOhzvZt.d.cts +47 -0
- package/dist/furigana-CjOhzvZt.d.cts.map +1 -0
- package/dist/furigana-DpZLcues.cjs +609 -0
- package/dist/furigana-DpZLcues.cjs.map +1 -0
- package/dist/furigana-h3v2ub4-.cjs +4 -0
- package/dist/import.cjs +12 -0
- package/dist/import.d.cts +107 -0
- package/dist/import.d.cts.map +1 -0
- package/dist/import.d.ts +107 -0
- package/dist/import.d.ts.map +1 -0
- package/dist/import.js +9 -0
- package/dist/index.cjs +275 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +211 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +211 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +238 -0
- package/dist/index.js.map +1 -0
- package/dist/json-DGd-cunA.js +17 -0
- package/dist/json-DGd-cunA.js.map +1 -0
- package/dist/json-DKWp-B7Y.cjs +30 -0
- package/dist/json-DKWp-B7Y.cjs.map +1 -0
- package/dist/language-KN_u-nTR.d.ts +104 -0
- package/dist/language-KN_u-nTR.d.ts.map +1 -0
- package/dist/language-xAbQxgXc.d.cts +104 -0
- package/dist/language-xAbQxgXc.d.cts.map +1 -0
- package/dist/language.cjs +15626 -0
- package/dist/language.cjs.map +1 -0
- package/dist/language.d.cts +959 -0
- package/dist/language.d.cts.map +1 -0
- package/dist/language.d.ts +959 -0
- package/dist/language.d.ts.map +1 -0
- package/dist/language.js +15522 -0
- package/dist/language.js.map +1 -0
- package/dist/log-D8KtR3aP.cjs +67 -0
- package/dist/log-D8KtR3aP.cjs.map +1 -0
- package/dist/log-hgSll-dS.js +60 -0
- package/dist/log-hgSll-dS.js.map +1 -0
- package/dist/lookup.cjs +13 -0
- package/dist/lookup.d.cts +161 -0
- package/dist/lookup.d.cts.map +1 -0
- package/dist/lookup.d.ts +161 -0
- package/dist/lookup.d.ts.map +1 -0
- package/dist/lookup.js +10 -0
- package/dist/media-loader-BABA_E4W.js +3 -0
- package/dist/media-loader-Ce9cuANS.cjs +21 -0
- package/dist/media-loader-Ce9cuANS.cjs.map +1 -0
- package/dist/media-loader-qRti-Q6h.js +14 -0
- package/dist/media-loader-qRti-Q6h.js.map +1 -0
- package/dist/media-loader-xlUGaJrx.cjs +3 -0
- package/dist/multi-language-transformer-AlxOM6b3.js +637 -0
- package/dist/multi-language-transformer-AlxOM6b3.js.map +1 -0
- package/dist/multi-language-transformer-MdbQBBOt.cjs +685 -0
- package/dist/multi-language-transformer-MdbQBBOt.cjs.map +1 -0
- package/dist/multi-language-transformer-SEhcJXEB.d.ts +63 -0
- package/dist/multi-language-transformer-SEhcJXEB.d.ts.map +1 -0
- package/dist/multi-language-transformer-Ul9mbRce.d.cts +63 -0
- package/dist/multi-language-transformer-Ul9mbRce.d.cts.map +1 -0
- package/dist/pronunciation-generator-BtBc4q_V.js +397 -0
- package/dist/pronunciation-generator-BtBc4q_V.js.map +1 -0
- package/dist/pronunciation-generator-CBYdXYou.js +4 -0
- package/dist/pronunciation-generator-CFbZlf5J.cjs +445 -0
- package/dist/pronunciation-generator-CFbZlf5J.cjs.map +1 -0
- package/dist/pronunciation-generator-DOz9hEuk.cjs +4 -0
- package/dist/render.cjs +2796 -0
- package/dist/render.cjs.map +1 -0
- package/dist/render.d.cts +424 -0
- package/dist/render.d.cts.map +1 -0
- package/dist/render.d.ts +424 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +2777 -0
- package/dist/render.js.map +1 -0
- package/dist/sentence-parser-BPAJNzqW.js +126 -0
- package/dist/sentence-parser-BPAJNzqW.js.map +1 -0
- package/dist/sentence-parser-BVIOI64h.cjs +132 -0
- package/dist/sentence-parser-BVIOI64h.cjs.map +1 -0
- package/dist/sentence-parser-BoHO3cHn.js +5 -0
- package/dist/sentence-parser-DQVLSW0z.cjs +5 -0
- package/dist/structured-content-generator-BtOApkTW.cjs +4 -0
- package/dist/structured-content-generator-Bx62RYa8.js +4 -0
- package/dist/structured-content-generator-CLnybumI.js +276 -0
- package/dist/structured-content-generator-CLnybumI.js.map +1 -0
- package/dist/structured-content-generator-DrwkB0-k.cjs +282 -0
- package/dist/structured-content-generator-DrwkB0-k.cjs.map +1 -0
- package/dist/text-utilities-B7PIythe.js +8 -0
- package/dist/text-utilities-B7PIythe.js.map +1 -0
- package/dist/text-utilities-Del2Ivkg.cjs +15 -0
- package/dist/text-utilities-Del2Ivkg.cjs.map +1 -0
- package/dist/translator-CRPlPzqi.cjs +1545 -0
- package/dist/translator-CRPlPzqi.cjs.map +1 -0
- package/dist/translator-CWgG5drA.js +1539 -0
- package/dist/translator-CWgG5drA.js.map +1 -0
- package/dist/translator-CaGtJvnQ.cjs +6 -0
- package/dist/translator-Cc6OGxrW.d.ts +180 -0
- package/dist/translator-Cc6OGxrW.d.ts.map +1 -0
- package/dist/translator-CcA-s-W4.d.cts +180 -0
- package/dist/translator-CcA-s-W4.d.cts.map +1 -0
- package/dist/translator-CuJOTK6l.js +6 -0
- package/dist/utilities-C-lbZaJE.cjs +52 -0
- package/dist/utilities-C-lbZaJE.cjs.map +1 -0
- package/dist/utilities-bi3EF-q5.js +33 -0
- package/dist/utilities-bi3EF-q5.js.map +1 -0
- package/package.json +102 -0
|
@@ -0,0 +1,1821 @@
|
|
|
1
|
+
import { stringReverse } from "./utilities-bi3EF-q5.js";
|
|
2
|
+
import { YomitanError, toError } from "./errors-DuuDSO5N.js";
|
|
3
|
+
import { compareRevisions } from "./dictionary-data-util-CfOLfEDE.js";
|
|
4
|
+
import { parseJson } from "./json-DGd-cunA.js";
|
|
5
|
+
import { NoOpMediaLoader } from "./media-loader-qRti-Q6h.js";
|
|
6
|
+
import { BlobWriter, TextWriter, Uint8ArrayReader, ZipReader } from "@zip.js/zip.js";
|
|
7
|
+
import Ajv from "ajv";
|
|
8
|
+
|
|
9
|
+
//#region src/util/media-util.ts
|
|
10
|
+
/**
|
|
11
|
+
* Gets the file extension of a file path.
|
|
12
|
+
*/
|
|
13
|
+
function getFileNameExtension(path) {
|
|
14
|
+
const match = /\.[^./\\]*$/.exec(path);
|
|
15
|
+
return match !== null ? match[0] : "";
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Gets an image file's media type using a file path.
|
|
19
|
+
*/
|
|
20
|
+
function getImageMediaTypeFromFileName(path) {
|
|
21
|
+
switch (getFileNameExtension(path).toLowerCase()) {
|
|
22
|
+
case ".apng": return "image/apng";
|
|
23
|
+
case ".avif": return "image/avif";
|
|
24
|
+
case ".bmp": return "image/bmp";
|
|
25
|
+
case ".gif": return "image/gif";
|
|
26
|
+
case ".ico":
|
|
27
|
+
case ".cur": return "image/x-icon";
|
|
28
|
+
case ".jpg":
|
|
29
|
+
case ".jpeg":
|
|
30
|
+
case ".jfif":
|
|
31
|
+
case ".pjpeg":
|
|
32
|
+
case ".pjp": return "image/jpeg";
|
|
33
|
+
case ".png": return "image/png";
|
|
34
|
+
case ".svg": return "image/svg+xml";
|
|
35
|
+
case ".tif":
|
|
36
|
+
case ".tiff": return "image/tiff";
|
|
37
|
+
case ".webp": return "image/webp";
|
|
38
|
+
default: return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Gets the file extension for a corresponding image media type.
|
|
43
|
+
*/
|
|
44
|
+
function getFileExtensionFromImageMediaType(mediaType) {
|
|
45
|
+
switch (mediaType) {
|
|
46
|
+
case "image/apng": return ".apng";
|
|
47
|
+
case "image/avif": return ".avif";
|
|
48
|
+
case "image/bmp": return ".bmp";
|
|
49
|
+
case "image/gif": return ".gif";
|
|
50
|
+
case "image/x-icon": return ".ico";
|
|
51
|
+
case "image/jpeg": return ".jpeg";
|
|
52
|
+
case "image/png": return ".png";
|
|
53
|
+
case "image/svg+xml": return ".svg";
|
|
54
|
+
case "image/tiff": return ".tiff";
|
|
55
|
+
case "image/webp": return ".webp";
|
|
56
|
+
default: return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/import/schemas/dictionary-index-schema.json
|
|
62
|
+
var $id$7 = "dictionaryIndex";
|
|
63
|
+
var $schema$7 = "http://json-schema.org/draft-07/schema#";
|
|
64
|
+
var definitions$3 = { "isoLanguageCode": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"description": "ISO language code (ISO 639-1 where possible, ISO 639-3 otherwise).",
|
|
67
|
+
"pattern": "^[a-z]{2,3}$"
|
|
68
|
+
} };
|
|
69
|
+
var type$7 = "object";
|
|
70
|
+
var description$7 = "Index file containing information about the data contained in the dictionary.";
|
|
71
|
+
var required = ["title", "revision"];
|
|
72
|
+
var properties = {
|
|
73
|
+
"title": {
|
|
74
|
+
"type": "string",
|
|
75
|
+
"description": "Title of the dictionary."
|
|
76
|
+
},
|
|
77
|
+
"revision": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"description": "Revision of the dictionary. This value is displayed, and used to check for dictionary updates."
|
|
80
|
+
},
|
|
81
|
+
"minimumYomitanVersion": {
|
|
82
|
+
"type": "string",
|
|
83
|
+
"description": "Minimum version of Yomitan that is compatible with this dictionary."
|
|
84
|
+
},
|
|
85
|
+
"sequenced": {
|
|
86
|
+
"type": "boolean",
|
|
87
|
+
"default": false,
|
|
88
|
+
"description": "Whether or not this dictionary contains sequencing information for related terms."
|
|
89
|
+
},
|
|
90
|
+
"format": {
|
|
91
|
+
"type": "integer",
|
|
92
|
+
"description": "Format of data found in the JSON data files.",
|
|
93
|
+
"enum": [
|
|
94
|
+
1,
|
|
95
|
+
2,
|
|
96
|
+
3
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
"version": {
|
|
100
|
+
"type": "integer",
|
|
101
|
+
"description": "Alias for format.",
|
|
102
|
+
"enum": [
|
|
103
|
+
1,
|
|
104
|
+
2,
|
|
105
|
+
3
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
"author": {
|
|
109
|
+
"type": "string",
|
|
110
|
+
"description": "Creator of the dictionary."
|
|
111
|
+
},
|
|
112
|
+
"isUpdatable": {
|
|
113
|
+
"type": "boolean",
|
|
114
|
+
"const": true,
|
|
115
|
+
"description": "Whether this dictionary contains links to its latest version."
|
|
116
|
+
},
|
|
117
|
+
"indexUrl": {
|
|
118
|
+
"type": "string",
|
|
119
|
+
"description": "URL for the index file of the latest revision of the dictionary, used to check for updates."
|
|
120
|
+
},
|
|
121
|
+
"downloadUrl": {
|
|
122
|
+
"type": "string",
|
|
123
|
+
"description": "URL for the download of the latest revision of the dictionary."
|
|
124
|
+
},
|
|
125
|
+
"url": {
|
|
126
|
+
"type": "string",
|
|
127
|
+
"description": "URL for the source of the dictionary, displayed in the dictionary details."
|
|
128
|
+
},
|
|
129
|
+
"description": {
|
|
130
|
+
"type": "string",
|
|
131
|
+
"description": "Description of the dictionary data."
|
|
132
|
+
},
|
|
133
|
+
"attribution": {
|
|
134
|
+
"type": "string",
|
|
135
|
+
"description": "Attribution information for the dictionary data."
|
|
136
|
+
},
|
|
137
|
+
"sourceLanguage": {
|
|
138
|
+
"$ref": "#/definitions/isoLanguageCode",
|
|
139
|
+
"description": "Language of the terms in the dictionary."
|
|
140
|
+
},
|
|
141
|
+
"targetLanguage": {
|
|
142
|
+
"$ref": "#/definitions/isoLanguageCode",
|
|
143
|
+
"description": "Main language of the definitions in the dictionary."
|
|
144
|
+
},
|
|
145
|
+
"frequencyMode": {
|
|
146
|
+
"type": "string",
|
|
147
|
+
"enum": ["occurrence-based", "rank-based"]
|
|
148
|
+
},
|
|
149
|
+
"tagMeta": {
|
|
150
|
+
"type": "object",
|
|
151
|
+
"description": "Tag information for terms and kanji. This object is obsolete and individual tag files should be used instead.",
|
|
152
|
+
"additionalProperties": {
|
|
153
|
+
"type": "object",
|
|
154
|
+
"description": "Information about a single tag. The object key is the name of the tag.",
|
|
155
|
+
"properties": {
|
|
156
|
+
"category": {
|
|
157
|
+
"type": "string",
|
|
158
|
+
"description": "Category for the tag."
|
|
159
|
+
},
|
|
160
|
+
"order": {
|
|
161
|
+
"type": "number",
|
|
162
|
+
"description": "Sorting order for the tag."
|
|
163
|
+
},
|
|
164
|
+
"notes": {
|
|
165
|
+
"type": "string",
|
|
166
|
+
"description": "Notes for the tag."
|
|
167
|
+
},
|
|
168
|
+
"score": {
|
|
169
|
+
"type": "number",
|
|
170
|
+
"description": "Score used to determine popularity. Negative values are more rare and positive values are more frequent. This score is also used to sort search results."
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
"additionalProperties": false
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
var anyOf = [{ "required": ["format"] }, { "required": ["version"] }];
|
|
178
|
+
var dependencies = { "isUpdatable": ["indexUrl", "downloadUrl"] };
|
|
179
|
+
var dictionary_index_schema_default = {
|
|
180
|
+
$id: $id$7,
|
|
181
|
+
$schema: $schema$7,
|
|
182
|
+
definitions: definitions$3,
|
|
183
|
+
type: type$7,
|
|
184
|
+
description: description$7,
|
|
185
|
+
required,
|
|
186
|
+
properties,
|
|
187
|
+
anyOf,
|
|
188
|
+
dependencies
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
//#endregion
|
|
192
|
+
//#region src/import/schemas/dictionary-kanji-bank-v1-schema.json
|
|
193
|
+
var $id$6 = "dictionaryKanjiBankV1";
|
|
194
|
+
var $schema$6 = "http://json-schema.org/draft-07/schema#";
|
|
195
|
+
var type$6 = "array";
|
|
196
|
+
var description$6 = "Data file containing kanji information.";
|
|
197
|
+
var items$6 = {
|
|
198
|
+
"type": "array",
|
|
199
|
+
"description": "Information about a single kanji character.",
|
|
200
|
+
"minItems": 4,
|
|
201
|
+
"maxItems": 4,
|
|
202
|
+
"items": [
|
|
203
|
+
{
|
|
204
|
+
"type": "string",
|
|
205
|
+
"description": "Kanji character.",
|
|
206
|
+
"minLength": 1
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"type": "string",
|
|
210
|
+
"description": "String of space-separated onyomi readings for the kanji character. An empty string is treated as no readings."
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"type": "string",
|
|
214
|
+
"description": "String of space-separated kunyomi readings for the kanji character. An empty string is treated as no readings."
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"type": "string",
|
|
218
|
+
"description": "String of space-separated tags for the kanji character. An empty string is treated as no tags."
|
|
219
|
+
}
|
|
220
|
+
],
|
|
221
|
+
"additionalItems": {
|
|
222
|
+
"type": "string",
|
|
223
|
+
"description": "A meaning for the kanji character."
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
var dictionary_kanji_bank_v1_schema_default = {
|
|
227
|
+
$id: $id$6,
|
|
228
|
+
$schema: $schema$6,
|
|
229
|
+
type: type$6,
|
|
230
|
+
description: description$6,
|
|
231
|
+
items: items$6
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
//#endregion
|
|
235
|
+
//#region src/import/schemas/dictionary-kanji-bank-v3-schema.json
|
|
236
|
+
var $id$5 = "dictionaryKanjiBankV3";
|
|
237
|
+
var $schema$5 = "http://json-schema.org/draft-07/schema#";
|
|
238
|
+
var type$5 = "array";
|
|
239
|
+
var description$5 = "Data file containing kanji information.";
|
|
240
|
+
var items$5 = {
|
|
241
|
+
"type": "array",
|
|
242
|
+
"description": "Information about a single kanji character.",
|
|
243
|
+
"minItems": 6,
|
|
244
|
+
"maxItems": 6,
|
|
245
|
+
"additionalItems": false,
|
|
246
|
+
"items": [
|
|
247
|
+
{
|
|
248
|
+
"type": "string",
|
|
249
|
+
"description": "Kanji character.",
|
|
250
|
+
"minLength": 1
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"type": "string",
|
|
254
|
+
"description": "String of space-separated onyomi readings for the kanji character. An empty string is treated as no readings."
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"type": "string",
|
|
258
|
+
"description": "String of space-separated kunyomi readings for the kanji character. An empty string is treated as no readings."
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"type": "string",
|
|
262
|
+
"description": "String of space-separated tags for the kanji character. An empty string is treated as no tags."
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"type": "array",
|
|
266
|
+
"description": "Array of meanings for the kanji character.",
|
|
267
|
+
"items": {
|
|
268
|
+
"type": "string",
|
|
269
|
+
"description": "A meaning for the kanji character."
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
"type": "object",
|
|
274
|
+
"description": "Various stats for the kanji character.",
|
|
275
|
+
"additionalProperties": { "type": "string" }
|
|
276
|
+
}
|
|
277
|
+
]
|
|
278
|
+
};
|
|
279
|
+
var dictionary_kanji_bank_v3_schema_default = {
|
|
280
|
+
$id: $id$5,
|
|
281
|
+
$schema: $schema$5,
|
|
282
|
+
type: type$5,
|
|
283
|
+
description: description$5,
|
|
284
|
+
items: items$5
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
//#endregion
|
|
288
|
+
//#region src/import/schemas/dictionary-kanji-meta-bank-v3-schema.json
|
|
289
|
+
var $id$4 = "dictionaryKanjiMetaBankV3";
|
|
290
|
+
var $schema$4 = "http://json-schema.org/draft-07/schema#";
|
|
291
|
+
var definitions$2 = { "frequency": { "oneOf": [{ "type": ["string", "number"] }, {
|
|
292
|
+
"type": "object",
|
|
293
|
+
"additionalProperties": false,
|
|
294
|
+
"required": ["value"],
|
|
295
|
+
"properties": {
|
|
296
|
+
"value": { "type": "number" },
|
|
297
|
+
"displayValue": { "type": "string" }
|
|
298
|
+
}
|
|
299
|
+
}] } };
|
|
300
|
+
var type$4 = "array";
|
|
301
|
+
var description$4 = "Custom metadata for kanji characters.";
|
|
302
|
+
var items$4 = {
|
|
303
|
+
"type": "array",
|
|
304
|
+
"description": "Metadata about a single kanji character.",
|
|
305
|
+
"minItems": 3,
|
|
306
|
+
"maxItems": 3,
|
|
307
|
+
"additionalItems": false,
|
|
308
|
+
"items": [
|
|
309
|
+
{
|
|
310
|
+
"type": "string",
|
|
311
|
+
"minLength": 1
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
"type": "string",
|
|
315
|
+
"const": "freq",
|
|
316
|
+
"description": "Type of data. \"freq\" corresponds to frequency information."
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
"$ref": "#/definitions/frequency",
|
|
320
|
+
"description": "Data for the character."
|
|
321
|
+
}
|
|
322
|
+
]
|
|
323
|
+
};
|
|
324
|
+
var dictionary_kanji_meta_bank_v3_schema_default = {
|
|
325
|
+
$id: $id$4,
|
|
326
|
+
$schema: $schema$4,
|
|
327
|
+
definitions: definitions$2,
|
|
328
|
+
type: type$4,
|
|
329
|
+
description: description$4,
|
|
330
|
+
items: items$4
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
//#endregion
|
|
334
|
+
//#region src/import/schemas/dictionary-tag-bank-v3-schema.json
|
|
335
|
+
var $id$3 = "dictionaryTagBankV3";
|
|
336
|
+
var $schema$3 = "http://json-schema.org/draft-07/schema#";
|
|
337
|
+
var type$3 = "array";
|
|
338
|
+
var description$3 = "Data file containing tag information for terms and kanji.";
|
|
339
|
+
var items$3 = {
|
|
340
|
+
"type": "array",
|
|
341
|
+
"description": "Information about a single tag.",
|
|
342
|
+
"minItems": 5,
|
|
343
|
+
"maxItems": 5,
|
|
344
|
+
"additionalItems": false,
|
|
345
|
+
"items": [
|
|
346
|
+
{
|
|
347
|
+
"type": "string",
|
|
348
|
+
"description": "Tag name."
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
"type": "string",
|
|
352
|
+
"description": "Category for the tag."
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
"type": "number",
|
|
356
|
+
"description": "Sorting order for the tag."
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
"type": "string",
|
|
360
|
+
"description": "Notes for the tag."
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
"type": "number",
|
|
364
|
+
"description": "Score used to determine popularity. Negative values are more rare and positive values are more frequent. This score is also used to sort search results."
|
|
365
|
+
}
|
|
366
|
+
]
|
|
367
|
+
};
|
|
368
|
+
var dictionary_tag_bank_v3_schema_default = {
|
|
369
|
+
$id: $id$3,
|
|
370
|
+
$schema: $schema$3,
|
|
371
|
+
type: type$3,
|
|
372
|
+
description: description$3,
|
|
373
|
+
items: items$3
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
//#endregion
|
|
377
|
+
//#region src/import/schemas/dictionary-term-bank-v1-schema.json
|
|
378
|
+
var $id$2 = "dictionaryTermBankV1";
|
|
379
|
+
var $schema$2 = "http://json-schema.org/draft-07/schema#";
|
|
380
|
+
var type$2 = "array";
|
|
381
|
+
var description$2 = "Data file containing term information.";
|
|
382
|
+
var items$2 = {
|
|
383
|
+
"type": "array",
|
|
384
|
+
"description": "Information about a single term.",
|
|
385
|
+
"minItems": 5,
|
|
386
|
+
"maxItems": 5,
|
|
387
|
+
"items": [
|
|
388
|
+
{
|
|
389
|
+
"type": "string",
|
|
390
|
+
"description": "The text for the term."
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
"type": "string",
|
|
394
|
+
"description": "Reading of the term, or an empty string if the reading is the same as the term."
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
"type": ["string", "null"],
|
|
398
|
+
"description": "String of space-separated tags for the definition. An empty string is treated as no tags."
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
"type": "string",
|
|
402
|
+
"description": "String of space-separated rule identifiers for the definition which is used to validate delinflection. Valid rule identifiers are: v1: ichidan verb; v5: godan verb; vs: suru verb; vz: zuru verb; vk: kuru verb; adj-i: i-adjective. An empty string corresponds to words which aren't inflected, such as nouns."
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
"type": "number",
|
|
406
|
+
"description": "Score used to determine popularity. Negative values are more rare and positive values are more frequent. This score is also used to sort search results."
|
|
407
|
+
}
|
|
408
|
+
],
|
|
409
|
+
"additionalItems": {
|
|
410
|
+
"type": "string",
|
|
411
|
+
"description": "Single definition for the term."
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
var dictionary_term_bank_v1_schema_default = {
|
|
415
|
+
$id: $id$2,
|
|
416
|
+
$schema: $schema$2,
|
|
417
|
+
type: type$2,
|
|
418
|
+
description: description$2,
|
|
419
|
+
items: items$2
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
//#endregion
|
|
423
|
+
//#region src/import/schemas/dictionary-term-bank-v3-schema.json
|
|
424
|
+
var $id$1 = "dictionaryTermBankV3";
|
|
425
|
+
var $schema$1 = "http://json-schema.org/draft-07/schema#";
|
|
426
|
+
var definitions$1 = {
|
|
427
|
+
"structuredContent": { "oneOf": [
|
|
428
|
+
{
|
|
429
|
+
"type": "string",
|
|
430
|
+
"description": "Represents a text node."
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
"type": "array",
|
|
434
|
+
"items": {
|
|
435
|
+
"$ref": "#/definitions/structuredContent",
|
|
436
|
+
"description": "An array of child content."
|
|
437
|
+
}
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
"type": "object",
|
|
441
|
+
"oneOf": [
|
|
442
|
+
{
|
|
443
|
+
"type": "object",
|
|
444
|
+
"description": "Empty tags.",
|
|
445
|
+
"required": ["tag"],
|
|
446
|
+
"additionalProperties": false,
|
|
447
|
+
"properties": {
|
|
448
|
+
"tag": {
|
|
449
|
+
"type": "string",
|
|
450
|
+
"const": "br"
|
|
451
|
+
},
|
|
452
|
+
"data": { "$ref": "#/definitions/structuredContentData" }
|
|
453
|
+
}
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
"type": "object",
|
|
457
|
+
"description": "Generic container tags.",
|
|
458
|
+
"required": ["tag"],
|
|
459
|
+
"additionalProperties": false,
|
|
460
|
+
"properties": {
|
|
461
|
+
"tag": {
|
|
462
|
+
"type": "string",
|
|
463
|
+
"enum": [
|
|
464
|
+
"ruby",
|
|
465
|
+
"rt",
|
|
466
|
+
"rp",
|
|
467
|
+
"table",
|
|
468
|
+
"thead",
|
|
469
|
+
"tbody",
|
|
470
|
+
"tfoot",
|
|
471
|
+
"tr"
|
|
472
|
+
]
|
|
473
|
+
},
|
|
474
|
+
"content": { "$ref": "#/definitions/structuredContent" },
|
|
475
|
+
"data": { "$ref": "#/definitions/structuredContentData" },
|
|
476
|
+
"lang": {
|
|
477
|
+
"type": "string",
|
|
478
|
+
"description": "Defines the language of an element in the format defined by RFC 5646."
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
"type": "object",
|
|
484
|
+
"description": "Table tags.",
|
|
485
|
+
"required": ["tag"],
|
|
486
|
+
"additionalProperties": false,
|
|
487
|
+
"properties": {
|
|
488
|
+
"tag": {
|
|
489
|
+
"type": "string",
|
|
490
|
+
"enum": ["td", "th"]
|
|
491
|
+
},
|
|
492
|
+
"content": { "$ref": "#/definitions/structuredContent" },
|
|
493
|
+
"data": { "$ref": "#/definitions/structuredContentData" },
|
|
494
|
+
"colSpan": {
|
|
495
|
+
"type": "integer",
|
|
496
|
+
"minimum": 1
|
|
497
|
+
},
|
|
498
|
+
"rowSpan": {
|
|
499
|
+
"type": "integer",
|
|
500
|
+
"minimum": 1
|
|
501
|
+
},
|
|
502
|
+
"style": { "$ref": "#/definitions/structuredContentStyle" },
|
|
503
|
+
"lang": {
|
|
504
|
+
"type": "string",
|
|
505
|
+
"description": "Defines the language of an element in the format defined by RFC 5646."
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
"type": "object",
|
|
511
|
+
"description": "Container tags supporting configurable styles.",
|
|
512
|
+
"required": ["tag"],
|
|
513
|
+
"additionalProperties": false,
|
|
514
|
+
"properties": {
|
|
515
|
+
"tag": {
|
|
516
|
+
"type": "string",
|
|
517
|
+
"enum": [
|
|
518
|
+
"span",
|
|
519
|
+
"div",
|
|
520
|
+
"ol",
|
|
521
|
+
"ul",
|
|
522
|
+
"li",
|
|
523
|
+
"details",
|
|
524
|
+
"summary"
|
|
525
|
+
]
|
|
526
|
+
},
|
|
527
|
+
"content": { "$ref": "#/definitions/structuredContent" },
|
|
528
|
+
"data": { "$ref": "#/definitions/structuredContentData" },
|
|
529
|
+
"style": { "$ref": "#/definitions/structuredContentStyle" },
|
|
530
|
+
"title": {
|
|
531
|
+
"type": "string",
|
|
532
|
+
"description": "Hover text for the element."
|
|
533
|
+
},
|
|
534
|
+
"open": {
|
|
535
|
+
"type": "boolean",
|
|
536
|
+
"description": "Whether or not the details element is open by default."
|
|
537
|
+
},
|
|
538
|
+
"lang": {
|
|
539
|
+
"type": "string",
|
|
540
|
+
"description": "Defines the language of an element in the format defined by RFC 5646."
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
"type": "object",
|
|
546
|
+
"description": "Image tag.",
|
|
547
|
+
"required": ["tag", "path"],
|
|
548
|
+
"additionalProperties": false,
|
|
549
|
+
"properties": {
|
|
550
|
+
"tag": {
|
|
551
|
+
"type": "string",
|
|
552
|
+
"const": "img"
|
|
553
|
+
},
|
|
554
|
+
"data": { "$ref": "#/definitions/structuredContentData" },
|
|
555
|
+
"path": {
|
|
556
|
+
"type": "string",
|
|
557
|
+
"description": "Path to the image file in the archive."
|
|
558
|
+
},
|
|
559
|
+
"width": {
|
|
560
|
+
"type": "number",
|
|
561
|
+
"description": "Preferred width of the image.",
|
|
562
|
+
"minimum": 0
|
|
563
|
+
},
|
|
564
|
+
"height": {
|
|
565
|
+
"type": "number",
|
|
566
|
+
"description": "Preferred height of the image.",
|
|
567
|
+
"minimum": 0
|
|
568
|
+
},
|
|
569
|
+
"title": {
|
|
570
|
+
"type": "string",
|
|
571
|
+
"description": "Hover text for the image."
|
|
572
|
+
},
|
|
573
|
+
"alt": {
|
|
574
|
+
"type": "string",
|
|
575
|
+
"description": "Alt text for the image."
|
|
576
|
+
},
|
|
577
|
+
"description": {
|
|
578
|
+
"type": "string",
|
|
579
|
+
"description": "Description of the image."
|
|
580
|
+
},
|
|
581
|
+
"pixelated": {
|
|
582
|
+
"type": "boolean",
|
|
583
|
+
"description": "Whether or not the image should appear pixelated at sizes larger than the image's native resolution.",
|
|
584
|
+
"default": false
|
|
585
|
+
},
|
|
586
|
+
"imageRendering": {
|
|
587
|
+
"type": "string",
|
|
588
|
+
"description": "Controls how the image is rendered. The value of this field supersedes the pixelated field.",
|
|
589
|
+
"enum": [
|
|
590
|
+
"auto",
|
|
591
|
+
"pixelated",
|
|
592
|
+
"crisp-edges"
|
|
593
|
+
],
|
|
594
|
+
"default": "auto"
|
|
595
|
+
},
|
|
596
|
+
"appearance": {
|
|
597
|
+
"type": "string",
|
|
598
|
+
"description": "Controls the appearance of the image. The \"monochrome\" value will mask the opaque parts of the image using the current text color.",
|
|
599
|
+
"enum": ["auto", "monochrome"],
|
|
600
|
+
"default": "auto"
|
|
601
|
+
},
|
|
602
|
+
"background": {
|
|
603
|
+
"type": "boolean",
|
|
604
|
+
"description": "Whether or not a background color is displayed behind the image.",
|
|
605
|
+
"default": true
|
|
606
|
+
},
|
|
607
|
+
"collapsed": {
|
|
608
|
+
"type": "boolean",
|
|
609
|
+
"description": "Whether or not the image is collapsed by default.",
|
|
610
|
+
"default": false
|
|
611
|
+
},
|
|
612
|
+
"collapsible": {
|
|
613
|
+
"type": "boolean",
|
|
614
|
+
"description": "Whether or not the image can be collapsed.",
|
|
615
|
+
"default": false
|
|
616
|
+
},
|
|
617
|
+
"verticalAlign": {
|
|
618
|
+
"type": "string",
|
|
619
|
+
"description": "The vertical alignment of the image.",
|
|
620
|
+
"enum": [
|
|
621
|
+
"baseline",
|
|
622
|
+
"sub",
|
|
623
|
+
"super",
|
|
624
|
+
"text-top",
|
|
625
|
+
"text-bottom",
|
|
626
|
+
"middle",
|
|
627
|
+
"top",
|
|
628
|
+
"bottom"
|
|
629
|
+
]
|
|
630
|
+
},
|
|
631
|
+
"border": {
|
|
632
|
+
"type": "string",
|
|
633
|
+
"description": "Shorthand for border width, style, and color."
|
|
634
|
+
},
|
|
635
|
+
"borderRadius": {
|
|
636
|
+
"type": "string",
|
|
637
|
+
"description": "Roundness of the corners of the image's outer border edge."
|
|
638
|
+
},
|
|
639
|
+
"sizeUnits": {
|
|
640
|
+
"type": "string",
|
|
641
|
+
"description": "The units for the width and height.",
|
|
642
|
+
"enum": ["px", "em"]
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
"type": "object",
|
|
648
|
+
"description": "Link tag.",
|
|
649
|
+
"required": ["tag", "href"],
|
|
650
|
+
"additionalProperties": false,
|
|
651
|
+
"properties": {
|
|
652
|
+
"tag": {
|
|
653
|
+
"type": "string",
|
|
654
|
+
"const": "a"
|
|
655
|
+
},
|
|
656
|
+
"content": { "$ref": "#/definitions/structuredContent" },
|
|
657
|
+
"href": {
|
|
658
|
+
"type": "string",
|
|
659
|
+
"description": "The URL for the link. URLs starting with a ? are treated as internal links to other dictionary content.",
|
|
660
|
+
"pattern": "^(?:https?:|\\?)[\\w\\W]*"
|
|
661
|
+
},
|
|
662
|
+
"lang": {
|
|
663
|
+
"type": "string",
|
|
664
|
+
"description": "Defines the language of an element in the format defined by RFC 5646."
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
]
|
|
669
|
+
}
|
|
670
|
+
] },
|
|
671
|
+
"structuredContentData": {
|
|
672
|
+
"type": "object",
|
|
673
|
+
"description": "Generic data attributes that should be added to the element.",
|
|
674
|
+
"additionalProperties": { "type": "string" }
|
|
675
|
+
},
|
|
676
|
+
"structuredContentStyle": {
|
|
677
|
+
"type": "object",
|
|
678
|
+
"additionalProperties": false,
|
|
679
|
+
"properties": {
|
|
680
|
+
"fontStyle": {
|
|
681
|
+
"type": "string",
|
|
682
|
+
"enum": ["normal", "italic"],
|
|
683
|
+
"default": "normal"
|
|
684
|
+
},
|
|
685
|
+
"fontWeight": {
|
|
686
|
+
"type": "string",
|
|
687
|
+
"enum": ["normal", "bold"],
|
|
688
|
+
"default": "normal"
|
|
689
|
+
},
|
|
690
|
+
"fontSize": {
|
|
691
|
+
"type": "string",
|
|
692
|
+
"default": "medium"
|
|
693
|
+
},
|
|
694
|
+
"color": { "type": "string" },
|
|
695
|
+
"background": { "type": "string" },
|
|
696
|
+
"backgroundColor": { "type": "string" },
|
|
697
|
+
"textDecorationLine": { "oneOf": [{
|
|
698
|
+
"type": "string",
|
|
699
|
+
"enum": [
|
|
700
|
+
"none",
|
|
701
|
+
"underline",
|
|
702
|
+
"overline",
|
|
703
|
+
"line-through"
|
|
704
|
+
],
|
|
705
|
+
"default": "none"
|
|
706
|
+
}, {
|
|
707
|
+
"type": "array",
|
|
708
|
+
"items": {
|
|
709
|
+
"type": "string",
|
|
710
|
+
"enum": [
|
|
711
|
+
"underline",
|
|
712
|
+
"overline",
|
|
713
|
+
"line-through"
|
|
714
|
+
],
|
|
715
|
+
"default": "none"
|
|
716
|
+
}
|
|
717
|
+
}] },
|
|
718
|
+
"textDecorationStyle": {
|
|
719
|
+
"type": "string",
|
|
720
|
+
"enum": [
|
|
721
|
+
"solid",
|
|
722
|
+
"double",
|
|
723
|
+
"dotted",
|
|
724
|
+
"dashed",
|
|
725
|
+
"wavy"
|
|
726
|
+
],
|
|
727
|
+
"default": "solid"
|
|
728
|
+
},
|
|
729
|
+
"textDecorationColor": { "type": "string" },
|
|
730
|
+
"borderColor": { "type": "string" },
|
|
731
|
+
"borderStyle": { "type": "string" },
|
|
732
|
+
"borderRadius": { "type": "string" },
|
|
733
|
+
"borderWidth": { "type": "string" },
|
|
734
|
+
"clipPath": { "type": "string" },
|
|
735
|
+
"verticalAlign": {
|
|
736
|
+
"type": "string",
|
|
737
|
+
"enum": [
|
|
738
|
+
"baseline",
|
|
739
|
+
"sub",
|
|
740
|
+
"super",
|
|
741
|
+
"text-top",
|
|
742
|
+
"text-bottom",
|
|
743
|
+
"middle",
|
|
744
|
+
"top",
|
|
745
|
+
"bottom"
|
|
746
|
+
],
|
|
747
|
+
"default": "baseline"
|
|
748
|
+
},
|
|
749
|
+
"textAlign": {
|
|
750
|
+
"type": "string",
|
|
751
|
+
"enum": [
|
|
752
|
+
"start",
|
|
753
|
+
"end",
|
|
754
|
+
"left",
|
|
755
|
+
"right",
|
|
756
|
+
"center",
|
|
757
|
+
"justify",
|
|
758
|
+
"justify-all",
|
|
759
|
+
"match-parent"
|
|
760
|
+
],
|
|
761
|
+
"default": "start"
|
|
762
|
+
},
|
|
763
|
+
"textEmphasis": { "type": "string" },
|
|
764
|
+
"textShadow": { "type": "string" },
|
|
765
|
+
"margin": { "type": "string" },
|
|
766
|
+
"marginTop": {
|
|
767
|
+
"type": ["number", "string"],
|
|
768
|
+
"default": 0
|
|
769
|
+
},
|
|
770
|
+
"marginLeft": {
|
|
771
|
+
"type": ["number", "string"],
|
|
772
|
+
"default": 0
|
|
773
|
+
},
|
|
774
|
+
"marginRight": {
|
|
775
|
+
"type": ["number", "string"],
|
|
776
|
+
"default": 0
|
|
777
|
+
},
|
|
778
|
+
"marginBottom": {
|
|
779
|
+
"type": ["number", "string"],
|
|
780
|
+
"default": 0
|
|
781
|
+
},
|
|
782
|
+
"padding": { "type": "string" },
|
|
783
|
+
"paddingTop": { "type": "string" },
|
|
784
|
+
"paddingLeft": { "type": "string" },
|
|
785
|
+
"paddingRight": { "type": "string" },
|
|
786
|
+
"paddingBottom": { "type": "string" },
|
|
787
|
+
"wordBreak": {
|
|
788
|
+
"type": "string",
|
|
789
|
+
"enum": [
|
|
790
|
+
"normal",
|
|
791
|
+
"break-all",
|
|
792
|
+
"keep-all"
|
|
793
|
+
],
|
|
794
|
+
"default": "normal"
|
|
795
|
+
},
|
|
796
|
+
"whiteSpace": {
|
|
797
|
+
"type": "string",
|
|
798
|
+
"default": "normal"
|
|
799
|
+
},
|
|
800
|
+
"cursor": {
|
|
801
|
+
"type": "string",
|
|
802
|
+
"default": "auto"
|
|
803
|
+
},
|
|
804
|
+
"listStyleType": {
|
|
805
|
+
"type": "string",
|
|
806
|
+
"default": "disc"
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
};
|
|
811
|
+
var type$1 = "array";
|
|
812
|
+
var description$1 = "Data file containing term information.";
|
|
813
|
+
var items$1 = {
|
|
814
|
+
"type": "array",
|
|
815
|
+
"description": "Information about a single term.",
|
|
816
|
+
"minItems": 8,
|
|
817
|
+
"maxItems": 8,
|
|
818
|
+
"additionalItems": false,
|
|
819
|
+
"items": [
|
|
820
|
+
{
|
|
821
|
+
"type": "string",
|
|
822
|
+
"description": "The text for the term."
|
|
823
|
+
},
|
|
824
|
+
{
|
|
825
|
+
"type": "string",
|
|
826
|
+
"description": "Reading of the term, or an empty string if the reading is the same as the term."
|
|
827
|
+
},
|
|
828
|
+
{
|
|
829
|
+
"type": ["string", "null"],
|
|
830
|
+
"description": "String of space-separated tags for the definition. An empty string is treated as no tags."
|
|
831
|
+
},
|
|
832
|
+
{
|
|
833
|
+
"type": "string",
|
|
834
|
+
"description": "String of space-separated rule identifiers for the definition which is used to validate deinflection. An empty string should be used for words which aren't inflected."
|
|
835
|
+
},
|
|
836
|
+
{
|
|
837
|
+
"type": "number",
|
|
838
|
+
"description": "Score used to determine popularity. Negative values are more rare and positive values are more frequent. This score is also used to sort search results."
|
|
839
|
+
},
|
|
840
|
+
{
|
|
841
|
+
"type": "array",
|
|
842
|
+
"description": "Array of definitions for the term.",
|
|
843
|
+
"items": { "oneOf": [
|
|
844
|
+
{
|
|
845
|
+
"type": "string",
|
|
846
|
+
"description": "Single definition for the term."
|
|
847
|
+
},
|
|
848
|
+
{
|
|
849
|
+
"type": "object",
|
|
850
|
+
"description": "Single detailed definition for the term.",
|
|
851
|
+
"required": ["type"],
|
|
852
|
+
"properties": { "type": {
|
|
853
|
+
"type": "string",
|
|
854
|
+
"description": "The type of the data for this definition.",
|
|
855
|
+
"enum": [
|
|
856
|
+
"text",
|
|
857
|
+
"image",
|
|
858
|
+
"structured-content"
|
|
859
|
+
]
|
|
860
|
+
} },
|
|
861
|
+
"oneOf": [
|
|
862
|
+
{
|
|
863
|
+
"required": ["type", "text"],
|
|
864
|
+
"additionalProperties": false,
|
|
865
|
+
"properties": {
|
|
866
|
+
"type": {
|
|
867
|
+
"type": "string",
|
|
868
|
+
"const": "text"
|
|
869
|
+
},
|
|
870
|
+
"text": {
|
|
871
|
+
"type": "string",
|
|
872
|
+
"description": "Single definition for the term."
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
},
|
|
876
|
+
{
|
|
877
|
+
"required": ["type", "content"],
|
|
878
|
+
"additionalProperties": false,
|
|
879
|
+
"properties": {
|
|
880
|
+
"type": {
|
|
881
|
+
"type": "string",
|
|
882
|
+
"const": "structured-content"
|
|
883
|
+
},
|
|
884
|
+
"content": {
|
|
885
|
+
"$ref": "#/definitions/structuredContent",
|
|
886
|
+
"description": "Single definition for the term using a structured content object."
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
},
|
|
890
|
+
{
|
|
891
|
+
"required": ["type", "path"],
|
|
892
|
+
"additionalProperties": false,
|
|
893
|
+
"properties": {
|
|
894
|
+
"type": {
|
|
895
|
+
"type": "string",
|
|
896
|
+
"const": "image"
|
|
897
|
+
},
|
|
898
|
+
"path": {
|
|
899
|
+
"type": "string",
|
|
900
|
+
"description": "Path to the image file in the archive."
|
|
901
|
+
},
|
|
902
|
+
"width": {
|
|
903
|
+
"type": "integer",
|
|
904
|
+
"description": "Preferred width of the image.",
|
|
905
|
+
"minimum": 1
|
|
906
|
+
},
|
|
907
|
+
"height": {
|
|
908
|
+
"type": "integer",
|
|
909
|
+
"description": "Preferred height of the image.",
|
|
910
|
+
"minimum": 1
|
|
911
|
+
},
|
|
912
|
+
"title": {
|
|
913
|
+
"type": "string",
|
|
914
|
+
"description": "Hover text for the image."
|
|
915
|
+
},
|
|
916
|
+
"alt": {
|
|
917
|
+
"type": "string",
|
|
918
|
+
"description": "Alt text for the image."
|
|
919
|
+
},
|
|
920
|
+
"description": {
|
|
921
|
+
"type": "string",
|
|
922
|
+
"description": "Description of the image."
|
|
923
|
+
},
|
|
924
|
+
"pixelated": {
|
|
925
|
+
"type": "boolean",
|
|
926
|
+
"description": "Whether or not the image should appear pixelated at sizes larger than the image's native resolution.",
|
|
927
|
+
"default": false
|
|
928
|
+
},
|
|
929
|
+
"imageRendering": {
|
|
930
|
+
"type": "string",
|
|
931
|
+
"description": "Controls how the image is rendered. The value of this field supersedes the pixelated field.",
|
|
932
|
+
"enum": [
|
|
933
|
+
"auto",
|
|
934
|
+
"pixelated",
|
|
935
|
+
"crisp-edges"
|
|
936
|
+
],
|
|
937
|
+
"default": "auto"
|
|
938
|
+
},
|
|
939
|
+
"appearance": {
|
|
940
|
+
"type": "string",
|
|
941
|
+
"description": "Controls the appearance of the image. The \"monochrome\" value will mask the opaque parts of the image using the current text color.",
|
|
942
|
+
"enum": ["auto", "monochrome"],
|
|
943
|
+
"default": "auto"
|
|
944
|
+
},
|
|
945
|
+
"background": {
|
|
946
|
+
"type": "boolean",
|
|
947
|
+
"description": "Whether or not a background color is displayed behind the image.",
|
|
948
|
+
"default": true
|
|
949
|
+
},
|
|
950
|
+
"collapsed": {
|
|
951
|
+
"type": "boolean",
|
|
952
|
+
"description": "Whether or not the image is collapsed by default.",
|
|
953
|
+
"default": false
|
|
954
|
+
},
|
|
955
|
+
"collapsible": {
|
|
956
|
+
"type": "boolean",
|
|
957
|
+
"description": "Whether or not the image can be collapsed.",
|
|
958
|
+
"default": true
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
]
|
|
963
|
+
},
|
|
964
|
+
{
|
|
965
|
+
"type": "array",
|
|
966
|
+
"description": "Deinflection of the term to an uninflected term.",
|
|
967
|
+
"minItems": 2,
|
|
968
|
+
"maxItems": 2,
|
|
969
|
+
"items": [{
|
|
970
|
+
"type": "string",
|
|
971
|
+
"description": "The uninflected term."
|
|
972
|
+
}, {
|
|
973
|
+
"type": "array",
|
|
974
|
+
"description": "A chain of inflection rules that produced the inflected term",
|
|
975
|
+
"items": {
|
|
976
|
+
"type": "string",
|
|
977
|
+
"description": "A single inflection rule."
|
|
978
|
+
}
|
|
979
|
+
}]
|
|
980
|
+
}
|
|
981
|
+
] }
|
|
982
|
+
},
|
|
983
|
+
{
|
|
984
|
+
"type": "integer",
|
|
985
|
+
"description": "Sequence number for the term. Terms with the same sequence number can be shown together when the \"resultOutputMode\" option is set to \"merge\"."
|
|
986
|
+
},
|
|
987
|
+
{
|
|
988
|
+
"type": "string",
|
|
989
|
+
"description": "String of space-separated tags for the term. An empty string is treated as no tags."
|
|
990
|
+
}
|
|
991
|
+
]
|
|
992
|
+
};
|
|
993
|
+
var dictionary_term_bank_v3_schema_default = {
|
|
994
|
+
$id: $id$1,
|
|
995
|
+
$schema: $schema$1,
|
|
996
|
+
definitions: definitions$1,
|
|
997
|
+
type: type$1,
|
|
998
|
+
description: description$1,
|
|
999
|
+
items: items$1
|
|
1000
|
+
};
|
|
1001
|
+
|
|
1002
|
+
//#endregion
|
|
1003
|
+
//#region src/import/schemas/dictionary-term-meta-bank-v3-schema.json
|
|
1004
|
+
var $id = "dictionaryTermMetaBankV3";
|
|
1005
|
+
var $schema = "http://json-schema.org/draft-07/schema#";
|
|
1006
|
+
var definitions = { "frequency": { "oneOf": [{ "type": ["string", "number"] }, {
|
|
1007
|
+
"type": "object",
|
|
1008
|
+
"additionalProperties": false,
|
|
1009
|
+
"required": ["value"],
|
|
1010
|
+
"properties": {
|
|
1011
|
+
"value": { "type": "number" },
|
|
1012
|
+
"displayValue": { "type": "string" }
|
|
1013
|
+
}
|
|
1014
|
+
}] } };
|
|
1015
|
+
var type = "array";
|
|
1016
|
+
var description = "Custom metadata for terms.";
|
|
1017
|
+
var items = {
|
|
1018
|
+
"type": "array",
|
|
1019
|
+
"description": "Metadata about a single term.",
|
|
1020
|
+
"minItems": 3,
|
|
1021
|
+
"maxItems": 3,
|
|
1022
|
+
"additionalItems": false,
|
|
1023
|
+
"items": [
|
|
1024
|
+
{
|
|
1025
|
+
"type": "string",
|
|
1026
|
+
"description": "The text for the term."
|
|
1027
|
+
},
|
|
1028
|
+
{
|
|
1029
|
+
"type": "string",
|
|
1030
|
+
"enum": [
|
|
1031
|
+
"freq",
|
|
1032
|
+
"pitch",
|
|
1033
|
+
"ipa"
|
|
1034
|
+
],
|
|
1035
|
+
"description": "Type of data. \"freq\" corresponds to frequency information; \"pitch\" corresponds to pitch information. \"ipa\" corresponds to IPA transcription."
|
|
1036
|
+
},
|
|
1037
|
+
{ "description": "Data for the term." }
|
|
1038
|
+
],
|
|
1039
|
+
"oneOf": [
|
|
1040
|
+
{
|
|
1041
|
+
"minItems": 3,
|
|
1042
|
+
"maxItems": 3,
|
|
1043
|
+
"items": [
|
|
1044
|
+
{},
|
|
1045
|
+
{ "const": "freq" },
|
|
1046
|
+
{ "oneOf": [{
|
|
1047
|
+
"$ref": "#/definitions/frequency",
|
|
1048
|
+
"description": "Frequency information for the term."
|
|
1049
|
+
}, {
|
|
1050
|
+
"type": "object",
|
|
1051
|
+
"required": ["reading", "frequency"],
|
|
1052
|
+
"additionalProperties": false,
|
|
1053
|
+
"properties": {
|
|
1054
|
+
"reading": {
|
|
1055
|
+
"type": "string",
|
|
1056
|
+
"description": "Reading for the term."
|
|
1057
|
+
},
|
|
1058
|
+
"frequency": {
|
|
1059
|
+
"$ref": "#/definitions/frequency",
|
|
1060
|
+
"description": "Frequency information for the term."
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
}] }
|
|
1064
|
+
]
|
|
1065
|
+
},
|
|
1066
|
+
{
|
|
1067
|
+
"minItems": 3,
|
|
1068
|
+
"maxItems": 3,
|
|
1069
|
+
"items": [
|
|
1070
|
+
{},
|
|
1071
|
+
{ "const": "pitch" },
|
|
1072
|
+
{
|
|
1073
|
+
"type": "object",
|
|
1074
|
+
"description": "Pitch accent information for the term.",
|
|
1075
|
+
"required": ["reading", "pitches"],
|
|
1076
|
+
"additionalProperties": false,
|
|
1077
|
+
"properties": {
|
|
1078
|
+
"reading": {
|
|
1079
|
+
"type": "string",
|
|
1080
|
+
"description": "Reading for the term."
|
|
1081
|
+
},
|
|
1082
|
+
"pitches": {
|
|
1083
|
+
"type": "array",
|
|
1084
|
+
"description": "List of different pitch accent information for the term and reading combination.",
|
|
1085
|
+
"items": {
|
|
1086
|
+
"type": "object",
|
|
1087
|
+
"required": ["position"],
|
|
1088
|
+
"additionalProperties": false,
|
|
1089
|
+
"properties": {
|
|
1090
|
+
"position": { "oneOf": [{
|
|
1091
|
+
"type": "integer",
|
|
1092
|
+
"description": "Mora position of the pitch accent downstep. A value of 0 indicates that the word does not have a downstep (heiban).",
|
|
1093
|
+
"minimum": 0
|
|
1094
|
+
}, {
|
|
1095
|
+
"type": "string",
|
|
1096
|
+
"description": "Pitch level of each mora with H representing high and L representing low. For example: HHLL for a 4 mora word.",
|
|
1097
|
+
"pattern": "^[HL]+$"
|
|
1098
|
+
}] },
|
|
1099
|
+
"nasal": { "oneOf": [{
|
|
1100
|
+
"type": "integer",
|
|
1101
|
+
"description": "Position of a mora with nasal sound.",
|
|
1102
|
+
"minimum": 0
|
|
1103
|
+
}, {
|
|
1104
|
+
"type": "array",
|
|
1105
|
+
"description": "Positions of morae with nasal sound.",
|
|
1106
|
+
"items": {
|
|
1107
|
+
"type": "integer",
|
|
1108
|
+
"minimum": 0
|
|
1109
|
+
}
|
|
1110
|
+
}] },
|
|
1111
|
+
"devoice": { "oneOf": [{
|
|
1112
|
+
"type": "integer",
|
|
1113
|
+
"description": "Position of a mora with devoiced sound.",
|
|
1114
|
+
"minimum": 0
|
|
1115
|
+
}, {
|
|
1116
|
+
"type": "array",
|
|
1117
|
+
"description": "Positions of morae with devoiced sound.",
|
|
1118
|
+
"items": {
|
|
1119
|
+
"type": "integer",
|
|
1120
|
+
"minimum": 0
|
|
1121
|
+
}
|
|
1122
|
+
}] },
|
|
1123
|
+
"tags": {
|
|
1124
|
+
"type": "array",
|
|
1125
|
+
"description": "List of tags for this pitch accent.",
|
|
1126
|
+
"items": {
|
|
1127
|
+
"type": "string",
|
|
1128
|
+
"description": "Tag for this pitch accent. This typically corresponds to a certain type of part of speech."
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
]
|
|
1137
|
+
},
|
|
1138
|
+
{
|
|
1139
|
+
"minItems": 3,
|
|
1140
|
+
"maxItems": 3,
|
|
1141
|
+
"items": [
|
|
1142
|
+
{},
|
|
1143
|
+
{ "const": "ipa" },
|
|
1144
|
+
{
|
|
1145
|
+
"type": ["object"],
|
|
1146
|
+
"description": "IPA transcription information for the term.",
|
|
1147
|
+
"required": ["reading", "transcriptions"],
|
|
1148
|
+
"additionalProperties": false,
|
|
1149
|
+
"properties": {
|
|
1150
|
+
"reading": {
|
|
1151
|
+
"type": "string",
|
|
1152
|
+
"description": "Reading for the term."
|
|
1153
|
+
},
|
|
1154
|
+
"transcriptions": {
|
|
1155
|
+
"type": "array",
|
|
1156
|
+
"description": "List of different IPA transcription information for the term and reading combination.",
|
|
1157
|
+
"items": {
|
|
1158
|
+
"type": "object",
|
|
1159
|
+
"required": ["ipa"],
|
|
1160
|
+
"additionalProperties": false,
|
|
1161
|
+
"properties": {
|
|
1162
|
+
"ipa": {
|
|
1163
|
+
"type": "string",
|
|
1164
|
+
"description": "IPA transcription for the term."
|
|
1165
|
+
},
|
|
1166
|
+
"tags": {
|
|
1167
|
+
"type": "array",
|
|
1168
|
+
"description": "List of tags for this IPA transcription.",
|
|
1169
|
+
"items": {
|
|
1170
|
+
"type": "string",
|
|
1171
|
+
"description": "Tag for this IPA transcription."
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
]
|
|
1180
|
+
}
|
|
1181
|
+
]
|
|
1182
|
+
};
|
|
1183
|
+
var dictionary_term_meta_bank_v3_schema_default = {
|
|
1184
|
+
$id,
|
|
1185
|
+
$schema,
|
|
1186
|
+
definitions,
|
|
1187
|
+
type,
|
|
1188
|
+
description,
|
|
1189
|
+
items
|
|
1190
|
+
};
|
|
1191
|
+
|
|
1192
|
+
//#endregion
|
|
1193
|
+
//#region src/import/schema-validators.ts
|
|
1194
|
+
let _validators = null;
|
|
1195
|
+
/**
|
|
1196
|
+
* Returns compiled AJV schema validators for all dictionary data bank types.
|
|
1197
|
+
* Validators are compiled once on first call and cached for subsequent calls.
|
|
1198
|
+
*/
|
|
1199
|
+
function getSchemaValidators() {
|
|
1200
|
+
if (_validators !== null) return _validators;
|
|
1201
|
+
const ajv = new Ajv({ allowUnionTypes: true });
|
|
1202
|
+
_validators = {
|
|
1203
|
+
dictionaryIndex: ajv.compile(dictionary_index_schema_default),
|
|
1204
|
+
dictionaryTermBankV1: ajv.compile(dictionary_term_bank_v1_schema_default),
|
|
1205
|
+
dictionaryTermBankV3: ajv.compile(dictionary_term_bank_v3_schema_default),
|
|
1206
|
+
dictionaryTermMetaBankV3: ajv.compile(dictionary_term_meta_bank_v3_schema_default),
|
|
1207
|
+
dictionaryKanjiBankV1: ajv.compile(dictionary_kanji_bank_v1_schema_default),
|
|
1208
|
+
dictionaryKanjiBankV3: ajv.compile(dictionary_kanji_bank_v3_schema_default),
|
|
1209
|
+
dictionaryKanjiMetaBankV3: ajv.compile(dictionary_kanji_meta_bank_v3_schema_default),
|
|
1210
|
+
dictionaryTagBankV3: ajv.compile(dictionary_tag_bank_v3_schema_default)
|
|
1211
|
+
};
|
|
1212
|
+
return _validators;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
//#endregion
|
|
1216
|
+
//#region src/import/dictionary-importer.ts
|
|
1217
|
+
const INDEX_FILE_NAME = "index.json";
|
|
1218
|
+
var DictionaryImporterClass = class {
|
|
1219
|
+
_mediaLoader;
|
|
1220
|
+
_onProgress;
|
|
1221
|
+
_progressData;
|
|
1222
|
+
constructor(mediaLoader, onProgress) {
|
|
1223
|
+
this._mediaLoader = mediaLoader ?? new NoOpMediaLoader();
|
|
1224
|
+
this._onProgress = typeof onProgress === "function" ? onProgress : () => {};
|
|
1225
|
+
this._progressData = this._createProgressData();
|
|
1226
|
+
}
|
|
1227
|
+
async importDictionary(dictionaryDatabase, archiveContent, details) {
|
|
1228
|
+
if (!dictionaryDatabase) throw new Error("Invalid database");
|
|
1229
|
+
if (!dictionaryDatabase.isOpen) throw new Error("Database is not ready");
|
|
1230
|
+
const errors = [];
|
|
1231
|
+
const maxTransactionLength = 1e3;
|
|
1232
|
+
const bulkAddProgressAllowance = 1e3;
|
|
1233
|
+
const bulkAdd = async (objectStoreName, entries) => {
|
|
1234
|
+
const entryCount = entries.length;
|
|
1235
|
+
let progressIndexIncrease = bulkAddProgressAllowance / Math.ceil(entryCount / maxTransactionLength);
|
|
1236
|
+
if (entryCount < maxTransactionLength) progressIndexIncrease = bulkAddProgressAllowance;
|
|
1237
|
+
if (entryCount === 0) this._progressData.index += progressIndexIncrease;
|
|
1238
|
+
for (let i = 0; i < entryCount; i += maxTransactionLength) {
|
|
1239
|
+
const count = Math.min(maxTransactionLength, entryCount - i);
|
|
1240
|
+
try {
|
|
1241
|
+
await dictionaryDatabase.bulkAdd(objectStoreName, entries, i, count);
|
|
1242
|
+
} catch (e) {
|
|
1243
|
+
errors.push(toError(e));
|
|
1244
|
+
}
|
|
1245
|
+
this._progressData.index += progressIndexIncrease;
|
|
1246
|
+
this._progress();
|
|
1247
|
+
}
|
|
1248
|
+
};
|
|
1249
|
+
this._progressReset();
|
|
1250
|
+
const fileMap = await this._getFilesFromArchive(archiveContent);
|
|
1251
|
+
const index = await this._readAndValidateIndex(fileMap);
|
|
1252
|
+
const dictionaryTitle = index.title;
|
|
1253
|
+
const version = typeof index.format === "number" ? index.format : index.version;
|
|
1254
|
+
if (await dictionaryDatabase.dictionaryExists(dictionaryTitle)) return {
|
|
1255
|
+
errors: [new Error(`Dictionary ${dictionaryTitle} is already imported, skipped it.`)],
|
|
1256
|
+
result: null
|
|
1257
|
+
};
|
|
1258
|
+
this._progressNextStep(0);
|
|
1259
|
+
const dataBankSchemas = this._getDataBankSchemas(version);
|
|
1260
|
+
const queryDetails = [
|
|
1261
|
+
["termFiles", /^term_bank_(\d+)\.json$/],
|
|
1262
|
+
["termMetaFiles", /^term_meta_bank_(\d+)\.json$/],
|
|
1263
|
+
["kanjiFiles", /^kanji_bank_(\d+)\.json$/],
|
|
1264
|
+
["kanjiMetaFiles", /^kanji_meta_bank_(\d+)\.json$/],
|
|
1265
|
+
["tagFiles", /^tag_bank_(\d+)\.json$/]
|
|
1266
|
+
];
|
|
1267
|
+
const archiveFiles = Object.fromEntries(this._getArchiveFiles(fileMap, queryDetails));
|
|
1268
|
+
const termFiles = archiveFiles.termFiles;
|
|
1269
|
+
const termMetaFiles = archiveFiles.termMetaFiles;
|
|
1270
|
+
const kanjiFiles = archiveFiles.kanjiFiles;
|
|
1271
|
+
const kanjiMetaFiles = archiveFiles.kanjiMetaFiles;
|
|
1272
|
+
const tagFiles = archiveFiles.tagFiles;
|
|
1273
|
+
const prefixWildcardsSupported = !!details.prefixWildcardsSupported;
|
|
1274
|
+
this._progressNextStep(termFiles.length + termMetaFiles.length + kanjiFiles.length + kanjiMetaFiles.length + tagFiles.length);
|
|
1275
|
+
for (const termFile of termFiles) await this._validateFile(termFile, dataBankSchemas[0]);
|
|
1276
|
+
for (const termMetaFile of termMetaFiles) await this._validateFile(termMetaFile, dataBankSchemas[1]);
|
|
1277
|
+
for (const kanjiFile of kanjiFiles) await this._validateFile(kanjiFile, dataBankSchemas[2]);
|
|
1278
|
+
for (const kanjiMetaFile of kanjiMetaFiles) await this._validateFile(kanjiMetaFile, dataBankSchemas[3]);
|
|
1279
|
+
for (const tagFile of tagFiles) await this._validateFile(tagFile, dataBankSchemas[4]);
|
|
1280
|
+
this._progressNextStep((termFiles.length * 2 + termMetaFiles.length + kanjiFiles.length + kanjiMetaFiles.length + tagFiles.length) * bulkAddProgressAllowance);
|
|
1281
|
+
let importSuccess = false;
|
|
1282
|
+
const counts = {
|
|
1283
|
+
terms: { total: 0 },
|
|
1284
|
+
termMeta: { total: 0 },
|
|
1285
|
+
kanji: { total: 0 },
|
|
1286
|
+
kanjiMeta: { total: 0 },
|
|
1287
|
+
tagMeta: { total: 0 },
|
|
1288
|
+
media: { total: 0 }
|
|
1289
|
+
};
|
|
1290
|
+
const yomitanVersion = details.yomitanVersion;
|
|
1291
|
+
let summaryDetails = {
|
|
1292
|
+
prefixWildcardsSupported,
|
|
1293
|
+
counts,
|
|
1294
|
+
styles: "",
|
|
1295
|
+
yomitanVersion,
|
|
1296
|
+
importSuccess
|
|
1297
|
+
};
|
|
1298
|
+
let summary = this._createSummary(dictionaryTitle, version, index, summaryDetails);
|
|
1299
|
+
const primaryKey = await dictionaryDatabase.addWithResult("dictionaries", summary);
|
|
1300
|
+
try {
|
|
1301
|
+
const uniqueMediaPaths = new Set();
|
|
1302
|
+
for (const termFile of termFiles) {
|
|
1303
|
+
const requirements = [];
|
|
1304
|
+
let termList = await (version === 1 ? this._readFileSequence([termFile], this._convertTermBankEntryV1.bind(this), dictionaryTitle) : this._readFileSequence([termFile], this._convertTermBankEntryV3.bind(this), dictionaryTitle));
|
|
1305
|
+
if (prefixWildcardsSupported) for (const entry of termList) {
|
|
1306
|
+
entry.expressionReverse = stringReverse(entry.expression);
|
|
1307
|
+
entry.readingReverse = stringReverse(entry.reading);
|
|
1308
|
+
}
|
|
1309
|
+
for (let i = 0, ii = termList.length; i < ii; ++i) {
|
|
1310
|
+
const entry = termList[i];
|
|
1311
|
+
const glossaryList = entry.glossary;
|
|
1312
|
+
for (let j = 0, jj = glossaryList.length; j < jj; ++j) {
|
|
1313
|
+
const glossary = glossaryList[j];
|
|
1314
|
+
if (typeof glossary !== "object" || glossary === null || Array.isArray(glossary)) continue;
|
|
1315
|
+
glossaryList[j] = this._formatDictionaryTermGlossaryObject(glossary, entry, requirements);
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
const alreadyAddedRequirements = requirements.filter((x) => {
|
|
1319
|
+
return uniqueMediaPaths.has(x.source.path);
|
|
1320
|
+
});
|
|
1321
|
+
const notAddedRequirements = requirements.filter((x) => {
|
|
1322
|
+
return !uniqueMediaPaths.has(x.source.path);
|
|
1323
|
+
});
|
|
1324
|
+
for (const requirement of requirements) uniqueMediaPaths.add(requirement.source.path);
|
|
1325
|
+
await this._resolveAsyncRequirements(alreadyAddedRequirements, fileMap);
|
|
1326
|
+
let { media } = await this._resolveAsyncRequirements(notAddedRequirements, fileMap);
|
|
1327
|
+
await bulkAdd("media", media);
|
|
1328
|
+
counts.media.total += media.length;
|
|
1329
|
+
this._progress();
|
|
1330
|
+
await bulkAdd("terms", termList);
|
|
1331
|
+
counts.terms.total += termList.length;
|
|
1332
|
+
this._progress();
|
|
1333
|
+
termList = [];
|
|
1334
|
+
media = [];
|
|
1335
|
+
}
|
|
1336
|
+
for (const termMetaFile of termMetaFiles) {
|
|
1337
|
+
let termMetaList = await this._readFileSequence([termMetaFile], this._convertTermMetaBankEntry.bind(this), dictionaryTitle);
|
|
1338
|
+
await bulkAdd("termMeta", termMetaList);
|
|
1339
|
+
for (const [key, value] of Object.entries(this._getMetaCounts(termMetaList))) if (key in counts.termMeta) counts.termMeta[key] += value;
|
|
1340
|
+
else counts.termMeta[key] = value;
|
|
1341
|
+
this._progress();
|
|
1342
|
+
termMetaList = [];
|
|
1343
|
+
}
|
|
1344
|
+
for (const kanjiFile of kanjiFiles) {
|
|
1345
|
+
let kanjiList = await (version === 1 ? this._readFileSequence([kanjiFile], this._convertKanjiBankEntryV1.bind(this), dictionaryTitle) : this._readFileSequence([kanjiFile], this._convertKanjiBankEntryV3.bind(this), dictionaryTitle));
|
|
1346
|
+
await bulkAdd("kanji", kanjiList);
|
|
1347
|
+
counts.kanji.total += kanjiList.length;
|
|
1348
|
+
this._progress();
|
|
1349
|
+
kanjiList = [];
|
|
1350
|
+
}
|
|
1351
|
+
for (const kanjiMetaFile of kanjiMetaFiles) {
|
|
1352
|
+
let kanjiMetaList = await this._readFileSequence([kanjiMetaFile], this._convertKanjiMetaBankEntry.bind(this), dictionaryTitle);
|
|
1353
|
+
await bulkAdd("kanjiMeta", kanjiMetaList);
|
|
1354
|
+
for (const [key, value] of Object.entries(this._getMetaCounts(kanjiMetaList))) if (key in counts.kanjiMeta) counts.kanjiMeta[key] += value;
|
|
1355
|
+
else counts.kanjiMeta[key] = value;
|
|
1356
|
+
this._progress();
|
|
1357
|
+
kanjiMetaList = [];
|
|
1358
|
+
}
|
|
1359
|
+
for (const tagFile of tagFiles) {
|
|
1360
|
+
let tagList = await this._readFileSequence([tagFile], this._convertTagBankEntry.bind(this), dictionaryTitle);
|
|
1361
|
+
this._addOldIndexTags(index, tagList, dictionaryTitle);
|
|
1362
|
+
await bulkAdd("tagMeta", tagList);
|
|
1363
|
+
counts.tagMeta.total += tagList.length;
|
|
1364
|
+
this._progress();
|
|
1365
|
+
tagList = [];
|
|
1366
|
+
}
|
|
1367
|
+
importSuccess = true;
|
|
1368
|
+
} catch (e) {
|
|
1369
|
+
errors.push(toError(e));
|
|
1370
|
+
}
|
|
1371
|
+
this._progressNextStep(0);
|
|
1372
|
+
const stylesFileName = "styles.css";
|
|
1373
|
+
const stylesFile = fileMap.get(stylesFileName);
|
|
1374
|
+
let styles = "";
|
|
1375
|
+
if (typeof stylesFile !== "undefined") {
|
|
1376
|
+
styles = await this._getData(stylesFile, new TextWriter());
|
|
1377
|
+
const cssErrors = this._validateCss(styles);
|
|
1378
|
+
if (cssErrors.length > 0) return {
|
|
1379
|
+
errors: cssErrors,
|
|
1380
|
+
result: null
|
|
1381
|
+
};
|
|
1382
|
+
}
|
|
1383
|
+
summaryDetails = {
|
|
1384
|
+
prefixWildcardsSupported,
|
|
1385
|
+
counts,
|
|
1386
|
+
styles,
|
|
1387
|
+
yomitanVersion,
|
|
1388
|
+
importSuccess
|
|
1389
|
+
};
|
|
1390
|
+
summary = this._createSummary(dictionaryTitle, version, index, summaryDetails);
|
|
1391
|
+
await dictionaryDatabase.bulkUpdate("dictionaries", [{
|
|
1392
|
+
data: summary,
|
|
1393
|
+
primaryKey
|
|
1394
|
+
}], 0, 1);
|
|
1395
|
+
this._progress();
|
|
1396
|
+
return {
|
|
1397
|
+
result: summary,
|
|
1398
|
+
errors
|
|
1399
|
+
};
|
|
1400
|
+
}
|
|
1401
|
+
async _getFilesFromArchive(archiveContent) {
|
|
1402
|
+
const zipFileReader = new Uint8ArrayReader(new Uint8Array(archiveContent));
|
|
1403
|
+
const zipReader = new ZipReader(zipFileReader, { useWebWorkers: false });
|
|
1404
|
+
const zipEntries = await zipReader.getEntries();
|
|
1405
|
+
const fileMap = new Map();
|
|
1406
|
+
for (const entry of zipEntries) fileMap.set(entry.filename, entry);
|
|
1407
|
+
return fileMap;
|
|
1408
|
+
}
|
|
1409
|
+
_findRedundantDirectories(fileMap) {
|
|
1410
|
+
let indexPath = "";
|
|
1411
|
+
for (const file of fileMap) if (file[0].replace(/.*\//, "") === INDEX_FILE_NAME) indexPath = file[0];
|
|
1412
|
+
const redundantDirectoriesRegex = new RegExp(`.*(?=${INDEX_FILE_NAME.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})`);
|
|
1413
|
+
const redundantDirectories = indexPath.match(redundantDirectoriesRegex);
|
|
1414
|
+
return redundantDirectories ? redundantDirectories[0] : null;
|
|
1415
|
+
}
|
|
1416
|
+
async _readAndValidateIndex(fileMap) {
|
|
1417
|
+
const indexFile = fileMap.get(INDEX_FILE_NAME);
|
|
1418
|
+
if (typeof indexFile === "undefined") {
|
|
1419
|
+
const redundantDirectories = this._findRedundantDirectories(fileMap);
|
|
1420
|
+
if (redundantDirectories) throw new Error(`Dictionary index found nested in redundant directories: "${redundantDirectories}" when it must be in the archive\'s root directory`);
|
|
1421
|
+
throw new Error("No dictionary index found in archive");
|
|
1422
|
+
}
|
|
1423
|
+
const indexContent = await this._getData(indexFile, new TextWriter());
|
|
1424
|
+
const index = parseJson(indexContent);
|
|
1425
|
+
const ajvSchemas = getSchemaValidators();
|
|
1426
|
+
if (!ajvSchemas.dictionaryIndex(index)) throw this._formatAjvSchemaError(ajvSchemas.dictionaryIndex, INDEX_FILE_NAME);
|
|
1427
|
+
const validIndex = index;
|
|
1428
|
+
const version = typeof validIndex.format === "number" ? validIndex.format : validIndex.version;
|
|
1429
|
+
validIndex.version = version;
|
|
1430
|
+
const { title, revision } = validIndex;
|
|
1431
|
+
if (typeof version !== "number" || !title || !revision) throw new Error("Unrecognized dictionary format");
|
|
1432
|
+
return validIndex;
|
|
1433
|
+
}
|
|
1434
|
+
_createProgressData() {
|
|
1435
|
+
return {
|
|
1436
|
+
index: 0,
|
|
1437
|
+
count: 0
|
|
1438
|
+
};
|
|
1439
|
+
}
|
|
1440
|
+
_progressReset() {
|
|
1441
|
+
this._progressData = this._createProgressData();
|
|
1442
|
+
this._progress(true);
|
|
1443
|
+
}
|
|
1444
|
+
_progressNextStep(count) {
|
|
1445
|
+
this._progressData.index = 0;
|
|
1446
|
+
this._progressData.count = count;
|
|
1447
|
+
this._progress(true);
|
|
1448
|
+
}
|
|
1449
|
+
_progress(nextStep = false) {
|
|
1450
|
+
this._onProgress({
|
|
1451
|
+
...this._progressData,
|
|
1452
|
+
nextStep
|
|
1453
|
+
});
|
|
1454
|
+
}
|
|
1455
|
+
_createSummary(dictionaryTitle, version, index, details) {
|
|
1456
|
+
const indexSequenced = index.sequenced;
|
|
1457
|
+
const { prefixWildcardsSupported, counts, styles, importSuccess } = details;
|
|
1458
|
+
const summary = {
|
|
1459
|
+
title: dictionaryTitle,
|
|
1460
|
+
revision: index.revision,
|
|
1461
|
+
sequenced: typeof indexSequenced === "boolean" && indexSequenced,
|
|
1462
|
+
version,
|
|
1463
|
+
importDate: Date.now(),
|
|
1464
|
+
prefixWildcardsSupported,
|
|
1465
|
+
counts,
|
|
1466
|
+
styles,
|
|
1467
|
+
importSuccess
|
|
1468
|
+
};
|
|
1469
|
+
const { minimumYomitanVersion, author, url, description: description$8, attribution, frequencyMode, isUpdatable, sourceLanguage, targetLanguage } = index;
|
|
1470
|
+
if (typeof minimumYomitanVersion === "string") {
|
|
1471
|
+
if (details.yomitanVersion === "0.0.0.0") {} else if (compareRevisions(details.yomitanVersion, minimumYomitanVersion)) throw new Error(`Dictionary is incompatible with this version of Yomitan (${details.yomitanVersion}; minimum required: ${minimumYomitanVersion})`);
|
|
1472
|
+
summary.minimumYomitanVersion = minimumYomitanVersion;
|
|
1473
|
+
}
|
|
1474
|
+
if (typeof author === "string") summary.author = author;
|
|
1475
|
+
if (typeof url === "string") summary.url = url;
|
|
1476
|
+
if (typeof description$8 === "string") summary.description = description$8;
|
|
1477
|
+
if (typeof attribution === "string") summary.attribution = attribution;
|
|
1478
|
+
if (typeof frequencyMode === "string") summary.frequencyMode = frequencyMode;
|
|
1479
|
+
if (typeof sourceLanguage === "string") summary.sourceLanguage = sourceLanguage;
|
|
1480
|
+
if (typeof targetLanguage === "string") summary.targetLanguage = targetLanguage;
|
|
1481
|
+
if (typeof isUpdatable === "boolean") {
|
|
1482
|
+
const { indexUrl, downloadUrl } = index;
|
|
1483
|
+
if (!isUpdatable || !this._validateUrl(indexUrl) || !this._validateUrl(downloadUrl)) throw new Error("Invalid index data for updatable dictionary");
|
|
1484
|
+
summary.isUpdatable = isUpdatable;
|
|
1485
|
+
summary.indexUrl = indexUrl;
|
|
1486
|
+
summary.downloadUrl = downloadUrl;
|
|
1487
|
+
}
|
|
1488
|
+
return summary;
|
|
1489
|
+
}
|
|
1490
|
+
_validateUrl(string) {
|
|
1491
|
+
if (typeof string !== "string") return false;
|
|
1492
|
+
let url;
|
|
1493
|
+
try {
|
|
1494
|
+
url = new URL(string);
|
|
1495
|
+
} catch (_) {
|
|
1496
|
+
return false;
|
|
1497
|
+
}
|
|
1498
|
+
return url.protocol === "http:" || url.protocol === "https:";
|
|
1499
|
+
}
|
|
1500
|
+
_formatAjvSchemaError(schema, fileName) {
|
|
1501
|
+
const e = new YomitanError(`Dictionary has invalid data in '${fileName}' '${JSON.stringify(schema.errors)}'`);
|
|
1502
|
+
e.data = schema.errors;
|
|
1503
|
+
return e;
|
|
1504
|
+
}
|
|
1505
|
+
_getDataBankSchemas(version) {
|
|
1506
|
+
const termBank = version === 1 ? "dictionaryTermBankV1" : "dictionaryTermBankV3";
|
|
1507
|
+
const termMetaBank = "dictionaryTermMetaBankV3";
|
|
1508
|
+
const kanjiBank = version === 1 ? "dictionaryKanjiBankV1" : "dictionaryKanjiBankV3";
|
|
1509
|
+
const kanjiMetaBank = "dictionaryKanjiMetaBankV3";
|
|
1510
|
+
const tagBank = "dictionaryTagBankV3";
|
|
1511
|
+
return [
|
|
1512
|
+
termBank,
|
|
1513
|
+
termMetaBank,
|
|
1514
|
+
kanjiBank,
|
|
1515
|
+
kanjiMetaBank,
|
|
1516
|
+
tagBank
|
|
1517
|
+
];
|
|
1518
|
+
}
|
|
1519
|
+
_validateCss(css) {
|
|
1520
|
+
return css ? [] : [new Error("No styles found")];
|
|
1521
|
+
}
|
|
1522
|
+
_formatDictionaryTermGlossaryObject(data, entry, requirements) {
|
|
1523
|
+
switch (data.type) {
|
|
1524
|
+
case "text": return data.text;
|
|
1525
|
+
case "image": return this._formatDictionaryTermGlossaryImage(data, entry, requirements);
|
|
1526
|
+
case "structured-content": return this._formatStructuredContent(data, entry, requirements);
|
|
1527
|
+
default: throw new Error(`Unhandled data type: ${data.type}`);
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
_formatDictionaryTermGlossaryImage(data, entry, requirements) {
|
|
1531
|
+
const target = {
|
|
1532
|
+
type: "image",
|
|
1533
|
+
path: ""
|
|
1534
|
+
};
|
|
1535
|
+
requirements.push({
|
|
1536
|
+
type: "image",
|
|
1537
|
+
target,
|
|
1538
|
+
source: data,
|
|
1539
|
+
entry
|
|
1540
|
+
});
|
|
1541
|
+
return target;
|
|
1542
|
+
}
|
|
1543
|
+
_formatStructuredContent(data, entry, requirements) {
|
|
1544
|
+
const content = this._prepareStructuredContent(data.content, entry, requirements);
|
|
1545
|
+
return {
|
|
1546
|
+
type: "structured-content",
|
|
1547
|
+
content
|
|
1548
|
+
};
|
|
1549
|
+
}
|
|
1550
|
+
_prepareStructuredContent(content, entry, requirements) {
|
|
1551
|
+
if (typeof content === "string" || !(typeof content === "object" && content !== null)) return content;
|
|
1552
|
+
if (Array.isArray(content)) {
|
|
1553
|
+
for (let i = 0, ii = content.length; i < ii; ++i) content[i] = this._prepareStructuredContent(content[i], entry, requirements);
|
|
1554
|
+
return content;
|
|
1555
|
+
}
|
|
1556
|
+
const { tag } = content;
|
|
1557
|
+
switch (tag) {
|
|
1558
|
+
case "img": return this._prepareStructuredContentImage(content, entry, requirements);
|
|
1559
|
+
}
|
|
1560
|
+
const childContent = content.content;
|
|
1561
|
+
if (typeof childContent !== "undefined") content.content = this._prepareStructuredContent(childContent, entry, requirements);
|
|
1562
|
+
return content;
|
|
1563
|
+
}
|
|
1564
|
+
_prepareStructuredContentImage(content, entry, requirements) {
|
|
1565
|
+
const target = {
|
|
1566
|
+
tag: "img",
|
|
1567
|
+
path: ""
|
|
1568
|
+
};
|
|
1569
|
+
requirements.push({
|
|
1570
|
+
type: "structured-content-image",
|
|
1571
|
+
target,
|
|
1572
|
+
source: content,
|
|
1573
|
+
entry
|
|
1574
|
+
});
|
|
1575
|
+
return target;
|
|
1576
|
+
}
|
|
1577
|
+
async _resolveAsyncRequirements(requirements, fileMap) {
|
|
1578
|
+
const media = new Map();
|
|
1579
|
+
const context = {
|
|
1580
|
+
fileMap,
|
|
1581
|
+
media
|
|
1582
|
+
};
|
|
1583
|
+
for (const requirement of requirements) await this._resolveAsyncRequirement(context, requirement);
|
|
1584
|
+
return { media: [...media.values()] };
|
|
1585
|
+
}
|
|
1586
|
+
async _resolveAsyncRequirement(context, requirement) {
|
|
1587
|
+
switch (requirement.type) {
|
|
1588
|
+
case "image":
|
|
1589
|
+
await this._resolveDictionaryTermGlossaryImage(context, requirement.target, requirement.source, requirement.entry);
|
|
1590
|
+
break;
|
|
1591
|
+
case "structured-content-image":
|
|
1592
|
+
await this._resolveStructuredContentImage(context, requirement.target, requirement.source, requirement.entry);
|
|
1593
|
+
break;
|
|
1594
|
+
default: return;
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
async _resolveDictionaryTermGlossaryImage(context, target, source, entry) {
|
|
1598
|
+
await this._createImageData(context, target, source, entry);
|
|
1599
|
+
}
|
|
1600
|
+
async _resolveStructuredContentImage(context, target, source, entry) {
|
|
1601
|
+
const { verticalAlign, border, borderRadius, sizeUnits } = source;
|
|
1602
|
+
await this._createImageData(context, target, source, entry);
|
|
1603
|
+
if (typeof verticalAlign === "string") target.verticalAlign = verticalAlign;
|
|
1604
|
+
if (typeof border === "string") target.border = border;
|
|
1605
|
+
if (typeof borderRadius === "string") target.borderRadius = borderRadius;
|
|
1606
|
+
if (typeof sizeUnits === "string") target.sizeUnits = sizeUnits;
|
|
1607
|
+
}
|
|
1608
|
+
async _createImageData(context, target, source, entry) {
|
|
1609
|
+
const { path, width: preferredWidth, height: preferredHeight, title, alt, description: description$8, pixelated, imageRendering, appearance, background, collapsed, collapsible } = source;
|
|
1610
|
+
const { width, height } = await this._getImageMedia(context, path, entry);
|
|
1611
|
+
target.path = path;
|
|
1612
|
+
target.width = width;
|
|
1613
|
+
target.height = height;
|
|
1614
|
+
if (typeof preferredWidth === "number") target.preferredWidth = preferredWidth;
|
|
1615
|
+
if (typeof preferredHeight === "number") target.preferredHeight = preferredHeight;
|
|
1616
|
+
if (typeof title === "string") target.title = title;
|
|
1617
|
+
if (typeof alt === "string") target.alt = alt;
|
|
1618
|
+
if (typeof description$8 === "string") target.description = description$8;
|
|
1619
|
+
if (typeof pixelated === "boolean") target.pixelated = pixelated;
|
|
1620
|
+
if (typeof imageRendering === "string") target.imageRendering = imageRendering;
|
|
1621
|
+
if (typeof appearance === "string") target.appearance = appearance;
|
|
1622
|
+
if (typeof background === "boolean") target.background = background;
|
|
1623
|
+
if (typeof collapsed === "boolean") target.collapsed = collapsed;
|
|
1624
|
+
if (typeof collapsible === "boolean") target.collapsible = collapsible;
|
|
1625
|
+
}
|
|
1626
|
+
async _getImageMedia(context, path, entry) {
|
|
1627
|
+
const { media } = context;
|
|
1628
|
+
const { dictionary } = entry;
|
|
1629
|
+
const createError = (message) => {
|
|
1630
|
+
const { expression, reading } = entry;
|
|
1631
|
+
const readingSource = reading.length > 0 ? ` (${reading})` : "";
|
|
1632
|
+
return new Error(`${message} at path ${JSON.stringify(path)} for ${expression}${readingSource} in ${dictionary}`);
|
|
1633
|
+
};
|
|
1634
|
+
let mediaData = media.get(path);
|
|
1635
|
+
if (typeof mediaData !== "undefined") {
|
|
1636
|
+
if (getFileExtensionFromImageMediaType(mediaData.mediaType) === null) throw createError("Media file is not a valid image");
|
|
1637
|
+
return mediaData;
|
|
1638
|
+
}
|
|
1639
|
+
const file = context.fileMap.get(path);
|
|
1640
|
+
if (typeof file === "undefined") throw createError("Could not find image");
|
|
1641
|
+
let content = await (await this._getData(file, new BlobWriter())).arrayBuffer();
|
|
1642
|
+
const mediaType = getImageMediaTypeFromFileName(path);
|
|
1643
|
+
if (mediaType === null) throw createError("Could not determine media type for image");
|
|
1644
|
+
let width;
|
|
1645
|
+
let height;
|
|
1646
|
+
try {
|
|
1647
|
+
({content, width, height} = await this._mediaLoader.getImageDetails(content, mediaType));
|
|
1648
|
+
} catch (e) {
|
|
1649
|
+
throw createError("Could not load image");
|
|
1650
|
+
}
|
|
1651
|
+
mediaData = {
|
|
1652
|
+
dictionary,
|
|
1653
|
+
path,
|
|
1654
|
+
mediaType,
|
|
1655
|
+
width,
|
|
1656
|
+
height,
|
|
1657
|
+
content
|
|
1658
|
+
};
|
|
1659
|
+
media.set(path, mediaData);
|
|
1660
|
+
return mediaData;
|
|
1661
|
+
}
|
|
1662
|
+
_convertTermBankEntryV1(entry, dictionary) {
|
|
1663
|
+
let [expression, reading, definitionTags, rules, score, ...glossary] = entry;
|
|
1664
|
+
reading = reading.length > 0 ? reading : expression;
|
|
1665
|
+
return {
|
|
1666
|
+
expression,
|
|
1667
|
+
reading,
|
|
1668
|
+
definitionTags,
|
|
1669
|
+
rules,
|
|
1670
|
+
score,
|
|
1671
|
+
glossary,
|
|
1672
|
+
dictionary
|
|
1673
|
+
};
|
|
1674
|
+
}
|
|
1675
|
+
_convertTermBankEntryV3(entry, dictionary) {
|
|
1676
|
+
let [expression, reading, definitionTags, rules, score, glossary, sequence, termTags] = entry;
|
|
1677
|
+
reading = reading.length > 0 ? reading : expression;
|
|
1678
|
+
return {
|
|
1679
|
+
expression,
|
|
1680
|
+
reading,
|
|
1681
|
+
definitionTags,
|
|
1682
|
+
rules,
|
|
1683
|
+
score,
|
|
1684
|
+
glossary,
|
|
1685
|
+
sequence,
|
|
1686
|
+
termTags,
|
|
1687
|
+
dictionary
|
|
1688
|
+
};
|
|
1689
|
+
}
|
|
1690
|
+
_convertTermMetaBankEntry(entry, dictionary) {
|
|
1691
|
+
const [expression, mode, data] = entry;
|
|
1692
|
+
return {
|
|
1693
|
+
expression,
|
|
1694
|
+
mode,
|
|
1695
|
+
data,
|
|
1696
|
+
dictionary
|
|
1697
|
+
};
|
|
1698
|
+
}
|
|
1699
|
+
_convertKanjiBankEntryV1(entry, dictionary) {
|
|
1700
|
+
const [character, onyomi, kunyomi, tags, ...meanings] = entry;
|
|
1701
|
+
return {
|
|
1702
|
+
character,
|
|
1703
|
+
onyomi,
|
|
1704
|
+
kunyomi,
|
|
1705
|
+
tags,
|
|
1706
|
+
meanings,
|
|
1707
|
+
dictionary
|
|
1708
|
+
};
|
|
1709
|
+
}
|
|
1710
|
+
_convertKanjiBankEntryV3(entry, dictionary) {
|
|
1711
|
+
const [character, onyomi, kunyomi, tags, meanings, stats] = entry;
|
|
1712
|
+
return {
|
|
1713
|
+
character,
|
|
1714
|
+
onyomi,
|
|
1715
|
+
kunyomi,
|
|
1716
|
+
tags,
|
|
1717
|
+
meanings,
|
|
1718
|
+
stats,
|
|
1719
|
+
dictionary
|
|
1720
|
+
};
|
|
1721
|
+
}
|
|
1722
|
+
_convertKanjiMetaBankEntry(entry, dictionary) {
|
|
1723
|
+
const [character, mode, data] = entry;
|
|
1724
|
+
return {
|
|
1725
|
+
character,
|
|
1726
|
+
mode,
|
|
1727
|
+
data,
|
|
1728
|
+
dictionary
|
|
1729
|
+
};
|
|
1730
|
+
}
|
|
1731
|
+
_convertTagBankEntry(entry, dictionary) {
|
|
1732
|
+
const [name, category, order, notes, score] = entry;
|
|
1733
|
+
return {
|
|
1734
|
+
name,
|
|
1735
|
+
category,
|
|
1736
|
+
order,
|
|
1737
|
+
notes,
|
|
1738
|
+
score,
|
|
1739
|
+
dictionary
|
|
1740
|
+
};
|
|
1741
|
+
}
|
|
1742
|
+
_addOldIndexTags(index, results, dictionary) {
|
|
1743
|
+
const { tagMeta } = index;
|
|
1744
|
+
if (typeof tagMeta !== "object" || tagMeta === null) return;
|
|
1745
|
+
for (const [name, value] of Object.entries(tagMeta)) {
|
|
1746
|
+
const { category, order, notes, score } = value;
|
|
1747
|
+
results.push({
|
|
1748
|
+
name,
|
|
1749
|
+
category,
|
|
1750
|
+
order,
|
|
1751
|
+
notes,
|
|
1752
|
+
score,
|
|
1753
|
+
dictionary
|
|
1754
|
+
});
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
_getArchiveFiles(fileMap, queryDetails) {
|
|
1758
|
+
const results = new Map();
|
|
1759
|
+
for (const [fileType] of queryDetails) results.set(fileType, []);
|
|
1760
|
+
for (const [fileName, fileEntry] of fileMap.entries()) for (const [fileType, fileNameFormat] of queryDetails) {
|
|
1761
|
+
if (!fileNameFormat.test(fileName)) continue;
|
|
1762
|
+
const entries = results.get(fileType);
|
|
1763
|
+
if (typeof entries !== "undefined") {
|
|
1764
|
+
entries.push(fileEntry);
|
|
1765
|
+
break;
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
return results;
|
|
1769
|
+
}
|
|
1770
|
+
async _readFileSequence(files, convertEntry, dictionaryTitle) {
|
|
1771
|
+
const results = [];
|
|
1772
|
+
for (const file of files) {
|
|
1773
|
+
const content = await this._getData(file, new TextWriter());
|
|
1774
|
+
let entries;
|
|
1775
|
+
try {
|
|
1776
|
+
entries = parseJson(content);
|
|
1777
|
+
} catch (error) {
|
|
1778
|
+
if (error instanceof Error) throw new Error(`${error.message} in '${file.filename}'`);
|
|
1779
|
+
}
|
|
1780
|
+
if (Array.isArray(entries)) for (const entry of entries) results.push(convertEntry(entry, dictionaryTitle));
|
|
1781
|
+
}
|
|
1782
|
+
return results;
|
|
1783
|
+
}
|
|
1784
|
+
async _validateFile(file, schemaName) {
|
|
1785
|
+
const content = await this._getData(file, new TextWriter());
|
|
1786
|
+
let entries;
|
|
1787
|
+
try {
|
|
1788
|
+
entries = parseJson(content);
|
|
1789
|
+
} catch (error) {
|
|
1790
|
+
if (error instanceof Error) throw new Error(`${error.message} in '${file.filename}'`);
|
|
1791
|
+
}
|
|
1792
|
+
const ajvSchemas = getSchemaValidators();
|
|
1793
|
+
const schema = ajvSchemas[schemaName];
|
|
1794
|
+
if (!schema(entries)) throw this._formatAjvSchemaError(schema, file.filename);
|
|
1795
|
+
++this._progressData.index;
|
|
1796
|
+
this._progress();
|
|
1797
|
+
return true;
|
|
1798
|
+
}
|
|
1799
|
+
_getMetaCounts(metaList) {
|
|
1800
|
+
const countsMap = new Map();
|
|
1801
|
+
for (const { mode } of metaList) {
|
|
1802
|
+
let count = countsMap.get(mode);
|
|
1803
|
+
count = typeof count !== "undefined" ? count + 1 : 1;
|
|
1804
|
+
countsMap.set(mode, count);
|
|
1805
|
+
}
|
|
1806
|
+
const counts = { total: metaList.length };
|
|
1807
|
+
for (const [key, value] of countsMap.entries()) {
|
|
1808
|
+
if (Object.prototype.hasOwnProperty.call(counts, key)) continue;
|
|
1809
|
+
counts[key] = value;
|
|
1810
|
+
}
|
|
1811
|
+
return counts;
|
|
1812
|
+
}
|
|
1813
|
+
async _getData(entry, writer) {
|
|
1814
|
+
if (typeof entry.getData === "undefined") throw new Error(`Cannot read ${entry.filename}`);
|
|
1815
|
+
return await entry.getData(writer);
|
|
1816
|
+
}
|
|
1817
|
+
};
|
|
1818
|
+
|
|
1819
|
+
//#endregion
|
|
1820
|
+
export { DictionaryImporterClass, getSchemaValidators };
|
|
1821
|
+
//# sourceMappingURL=dictionary-importer-Cen1z6co.js.map
|