summaryrefslogtreecommitdiff
path: root/ext/data
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2021-02-12 19:56:24 -0500
committerGitHub <noreply@github.com>2021-02-12 19:56:24 -0500
commit2b4af57bd764ee07ed1d7db8e2985e34ba7ef8ea (patch)
tree06af52cf528773838c1144a323e74c93ddebdf45 /ext/data
parent37f916171812afe22f1b435d9e06b52af5d8292a (diff)
Move data folder (#1371)
* Move handlebars template files * Move schema files
Diffstat (limited to 'ext/data')
-rw-r--r--ext/data/schemas/custom-audio-list-schema.json33
-rw-r--r--ext/data/schemas/dictionary-index-schema.json85
-rw-r--r--ext/data/schemas/dictionary-kanji-bank-v1-schema.json33
-rw-r--r--ext/data/schemas/dictionary-kanji-bank-v3-schema.json44
-rw-r--r--ext/data/schemas/dictionary-kanji-meta-bank-v3-schema.json25
-rw-r--r--ext/data/schemas/dictionary-tag-bank-v3-schema.json32
-rw-r--r--ext/data/schemas/dictionary-term-bank-v1-schema.json36
-rw-r--r--ext/data/schemas/dictionary-term-bank-v3-schema.json125
-rw-r--r--ext/data/schemas/dictionary-term-meta-bank-v3-schema.json105
-rw-r--r--ext/data/schemas/options-schema.json1101
-rw-r--r--ext/data/templates/anki-field-templates-upgrade-v2.handlebars109
-rw-r--r--ext/data/templates/anki-field-templates-upgrade-v4.handlebars9
-rw-r--r--ext/data/templates/anki-field-templates-upgrade-v6.handlebars25
-rw-r--r--ext/data/templates/anki-field-templates-upgrade-v8.handlebars131
-rw-r--r--ext/data/templates/default-anki-field-templates.handlebars344
15 files changed, 2237 insertions, 0 deletions
diff --git a/ext/data/schemas/custom-audio-list-schema.json b/ext/data/schemas/custom-audio-list-schema.json
new file mode 100644
index 00000000..2cb3ca78
--- /dev/null
+++ b/ext/data/schemas/custom-audio-list-schema.json
@@ -0,0 +1,33 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "type": "object",
+ "required": [
+ "type",
+ "audioSources"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "type": "string",
+ "const": "audioSourceList"
+ },
+ "audioSources": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "url"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/ext/data/schemas/dictionary-index-schema.json b/ext/data/schemas/dictionary-index-schema.json
new file mode 100644
index 00000000..09cff711
--- /dev/null
+++ b/ext/data/schemas/dictionary-index-schema.json
@@ -0,0 +1,85 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "type": "object",
+ "description": "Index file containing information about the data contained in the dictionary.",
+ "required": [
+ "title",
+ "revision"
+ ],
+ "properties": {
+ "title": {
+ "type": "string",
+ "description": "Title of the dictionary."
+ },
+ "revision": {
+ "type": "string",
+ "description": "Revision of the dictionary. This value is only used for displaying information."
+ },
+ "sequenced": {
+ "type": "boolean",
+ "default": false,
+ "description": "Whether or not this dictionary can be used as the primary dictionary. Primary dictionaries typically contain term/expression definitions."
+ },
+ "format": {
+ "type": "integer",
+ "description": "Format of data found in the JSON data files.",
+ "enum": [1, 2, 3]
+ },
+ "version": {
+ "type": "integer",
+ "description": "Alias for format.",
+ "enum": [1, 2, 3]
+ },
+ "author": {
+ "type": "string",
+ "description": "Creator of the dictionary."
+ },
+ "url": {
+ "type": "string",
+ "description": "URL for the source of the dictionary."
+ },
+ "description": {
+ "type": "string",
+ "description": "Description of the dictionary data."
+ },
+ "attribution": {
+ "type": "string",
+ "description": "Attribution information for the dictionary data."
+ },
+ "tagMeta": {
+ "type": "object",
+ "description": "Tag information for terms and kanji. This object is obsolete and individual tag files should be used instead.",
+ "additionalProperties": {
+ "type": "object",
+ "description": "Information about a single tag. The object key is the name of the tag.",
+ "properties": {
+ "category": {
+ "type": "string",
+ "description": "Category for the tag."
+ },
+ "order": {
+ "type": "number",
+ "description": "Sorting order for the tag."
+ },
+ "notes": {
+ "type": "string",
+ "description": "Notes for the tag."
+ },
+ "score": {
+ "type": "number",
+ "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."
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "required": ["format"]
+ },
+ {
+ "required": ["version"]
+ }
+ ]
+} \ No newline at end of file
diff --git a/ext/data/schemas/dictionary-kanji-bank-v1-schema.json b/ext/data/schemas/dictionary-kanji-bank-v1-schema.json
new file mode 100644
index 00000000..6dad5a7a
--- /dev/null
+++ b/ext/data/schemas/dictionary-kanji-bank-v1-schema.json
@@ -0,0 +1,33 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "type": "array",
+ "description": "Data file containing kanji information.",
+ "additionalItems": {
+ "type": "array",
+ "description": "Information about a single kanji character.",
+ "minItems": 4,
+ "items": [
+ {
+ "type": "string",
+ "description": "Kanji character.",
+ "minLength": 1
+ },
+ {
+ "type": "string",
+ "description": "String of space-separated onyomi readings for the kanji character. An empty string is treated as no readings."
+ },
+ {
+ "type": "string",
+ "description": "String of space-separated kunyomi readings for the kanji character. An empty string is treated as no readings."
+ },
+ {
+ "type": "string",
+ "description": "String of space-separated tags for the kanji character. An empty string is treated as no tags."
+ }
+ ],
+ "additionalItems": {
+ "type": "string",
+ "description": "A meaning for the kanji character."
+ }
+ }
+} \ No newline at end of file
diff --git a/ext/data/schemas/dictionary-kanji-bank-v3-schema.json b/ext/data/schemas/dictionary-kanji-bank-v3-schema.json
new file mode 100644
index 00000000..a5b82039
--- /dev/null
+++ b/ext/data/schemas/dictionary-kanji-bank-v3-schema.json
@@ -0,0 +1,44 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "type": "array",
+ "description": "Data file containing kanji information.",
+ "additionalItems": {
+ "type": "array",
+ "description": "Information about a single kanji character.",
+ "minItems": 6,
+ "items": [
+ {
+ "type": "string",
+ "description": "Kanji character.",
+ "minLength": 1
+ },
+ {
+ "type": "string",
+ "description": "String of space-separated onyomi readings for the kanji character. An empty string is treated as no readings."
+ },
+ {
+ "type": "string",
+ "description": "String of space-separated kunyomi readings for the kanji character. An empty string is treated as no readings."
+ },
+ {
+ "type": "string",
+ "description": "String of space-separated tags for the kanji character. An empty string is treated as no tags."
+ },
+ {
+ "type": "array",
+ "description": "Array of meanings for the kanji character.",
+ "items": {
+ "type": "string",
+ "description": "A meaning for the kanji character."
+ }
+ },
+ {
+ "type": "object",
+ "description": "Various stats for the kanji character.",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+} \ No newline at end of file
diff --git a/ext/data/schemas/dictionary-kanji-meta-bank-v3-schema.json b/ext/data/schemas/dictionary-kanji-meta-bank-v3-schema.json
new file mode 100644
index 00000000..62479026
--- /dev/null
+++ b/ext/data/schemas/dictionary-kanji-meta-bank-v3-schema.json
@@ -0,0 +1,25 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "type": "array",
+ "description": "Custom metadata for kanji characters.",
+ "additionalItems": {
+ "type": "array",
+ "description": "Metadata about a single kanji character.",
+ "minItems": 3,
+ "items": [
+ {
+ "type": "string",
+ "minLength": 1
+ },
+ {
+ "type": "string",
+ "enum": ["freq"],
+ "description": "Type of data. \"freq\" corresponds to frequency information."
+ },
+ {
+ "type": ["string", "number"],
+ "description": "Data for the character."
+ }
+ ]
+ }
+} \ No newline at end of file
diff --git a/ext/data/schemas/dictionary-tag-bank-v3-schema.json b/ext/data/schemas/dictionary-tag-bank-v3-schema.json
new file mode 100644
index 00000000..ee5ca64d
--- /dev/null
+++ b/ext/data/schemas/dictionary-tag-bank-v3-schema.json
@@ -0,0 +1,32 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "type": "array",
+ "description": "Data file containing tag information for terms and kanji.",
+ "additionalItems": {
+ "type": "array",
+ "description": "Information about a single tag.",
+ "minItems": 5,
+ "items": [
+ {
+ "type": "string",
+ "description": "Tag name."
+ },
+ {
+ "type": "string",
+ "description": "Category for the tag."
+ },
+ {
+ "type": "number",
+ "description": "Sorting order for the tag."
+ },
+ {
+ "type": "string",
+ "description": "Notes for the tag."
+ },
+ {
+ "type": "number",
+ "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."
+ }
+ ]
+ }
+} \ No newline at end of file
diff --git a/ext/data/schemas/dictionary-term-bank-v1-schema.json b/ext/data/schemas/dictionary-term-bank-v1-schema.json
new file mode 100644
index 00000000..6ffb26e6
--- /dev/null
+++ b/ext/data/schemas/dictionary-term-bank-v1-schema.json
@@ -0,0 +1,36 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "type": "array",
+ "description": "Data file containing term and expression information.",
+ "additionalItems": {
+ "type": "array",
+ "description": "Information about a single term/expression.",
+ "minItems": 5,
+ "items": [
+ {
+ "type": "string",
+ "description": "Term or expression."
+ },
+ {
+ "type": "string",
+ "description": "Reading of the term/expression, or an empty string if the reading is the same as the term/expression."
+ },
+ {
+ "type": ["string", "null"],
+ "description": "String of space-separated tags for the definition. An empty string is treated as no tags."
+ },
+ {
+ "type": "string",
+ "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; vk: kuru verb; adj-i: i-adjective. An empty string corresponds to words which aren't inflected, such as nouns."
+ },
+ {
+ "type": "number",
+ "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."
+ }
+ ],
+ "additionalItems": {
+ "type": "string",
+ "description": "Single definition for the term/expression."
+ }
+ }
+} \ No newline at end of file
diff --git a/ext/data/schemas/dictionary-term-bank-v3-schema.json b/ext/data/schemas/dictionary-term-bank-v3-schema.json
new file mode 100644
index 00000000..4790e561
--- /dev/null
+++ b/ext/data/schemas/dictionary-term-bank-v3-schema.json
@@ -0,0 +1,125 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "type": "array",
+ "description": "Data file containing term and expression information.",
+ "additionalItems": {
+ "type": "array",
+ "description": "Information about a single term/expression.",
+ "minItems": 8,
+ "items": [
+ {
+ "type": "string",
+ "description": "Term or expression."
+ },
+ {
+ "type": "string",
+ "description": "Reading of the term/expression, or an empty string if the reading is the same as the term/expression."
+ },
+ {
+ "type": ["string", "null"],
+ "description": "String of space-separated tags for the definition. An empty string is treated as no tags."
+ },
+ {
+ "type": "string",
+ "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; vk: kuru verb; adj-i: i-adjective. An empty string corresponds to words which aren't inflected, such as nouns."
+ },
+ {
+ "type": "number",
+ "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."
+ },
+ {
+ "type": "array",
+ "description": "Array of definitions for the term/expression.",
+ "items": {
+ "oneOf": [
+ {
+ "type": "string",
+ "description": "Single definition for the term/expression."
+ },
+ {
+ "type": "object",
+ "description": "Single detailed definition for the term/expression.",
+ "required": [
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "The type of the data for this definition.",
+ "enum": ["text", "image"]
+ }
+ },
+ "oneOf": [
+ {
+ "required": [
+ "type",
+ "text"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": ["text"]
+ },
+ "text": {
+ "type": "string",
+ "description": "Single definition for the term/expression."
+ }
+ }
+ },
+ {
+ "required": [
+ "type",
+ "path"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": ["image"]
+ },
+ "path": {
+ "type": "string",
+ "description": "Path to the image file in the archive."
+ },
+ "width": {
+ "type": "integer",
+ "description": "Preferred width of the image.",
+ "minimum": 1
+ },
+ "height": {
+ "type": "integer",
+ "description": "Preferred width of the image.",
+ "minimum": 1
+ },
+ "title": {
+ "type": "string",
+ "description": "Hover text for the image."
+ },
+ "description": {
+ "type": "string",
+ "description": "Description of the image."
+ },
+ "pixelated": {
+ "type": "boolean",
+ "description": "Whether or not the image should appear pixelated at sizes larger than the image's native resolution.",
+ "default": false
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "type": "integer",
+ "description": "Sequence number for the term/expression. Terms/expressions with the same sequence number can be shown together when the \"resultOutputMode\" option is set to \"merge\"."
+ },
+ {
+ "type": "string",
+ "description": "String of space-separated tags for the term/expression. An empty string is treated as no tags."
+ }
+ ]
+ }
+} \ No newline at end of file
diff --git a/ext/data/schemas/dictionary-term-meta-bank-v3-schema.json b/ext/data/schemas/dictionary-term-meta-bank-v3-schema.json
new file mode 100644
index 00000000..ffffb546
--- /dev/null
+++ b/ext/data/schemas/dictionary-term-meta-bank-v3-schema.json
@@ -0,0 +1,105 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "type": "array",
+ "description": "Custom metadata for terms/expressions.",
+ "additionalItems": {
+ "type": "array",
+ "description": "Metadata about a single term/expression.",
+ "minItems": 3,
+ "items": [
+ {
+ "type": "string",
+ "description": "Term or expression."
+ },
+ {
+ "type": "string",
+ "enum": ["freq", "pitch"],
+ "description": "Type of data. \"freq\" corresponds to frequency information; \"pitch\" corresponds to pitch information."
+ },
+ {
+ "description": "Data for the term/expression."
+ }
+ ],
+ "oneOf": [
+ {
+ "items": [
+ {},
+ {"enum": ["freq"]},
+ {
+ "oneOf": [
+ {
+ "type": ["string", "number"],
+ "description": "Frequency information for the term or expression."
+ },
+ {
+ "type": ["object"],
+ "required": [
+ "reading",
+ "frequency"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "reading": {
+ "type": "string",
+ "description": "Reading for the term or expression."
+ },
+ "frequency": {
+ "type": ["string", "number"],
+ "description": "Frequency information for the term or expression."
+ }
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "items": [
+ {},
+ {"enum": ["pitch"]},
+ {
+ "type": ["object"],
+ "description": "Pitch accent information for the term or expression.",
+ "required": [
+ "reading",
+ "pitches"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "reading": {
+ "type": "string",
+ "description": "Reading for the term or expression."
+ },
+ "pitches": {
+ "type": "array",
+ "description": "List of different pitch accent information for the term and reading combination.",
+ "additionalItems": {
+ "type": "object",
+ "required": [
+ "position"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "position": {
+ "type": "integer",
+ "description": "Mora position of the pitch accent downstep. A value of 0 indicates that the word does not have a downstep (heiban).",
+ "minimum": 0
+ },
+ "tags": {
+ "type": "array",
+ "description": "List of tags for this pitch accent.",
+ "items": {
+ "type": "string",
+ "description": "Tag for this pitch accent. This typically corresponds to a certain type of part of speech."
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+} \ No newline at end of file
diff --git a/ext/data/schemas/options-schema.json b/ext/data/schemas/options-schema.json
new file mode 100644
index 00000000..f4f5d0ca
--- /dev/null
+++ b/ext/data/schemas/options-schema.json
@@ -0,0 +1,1101 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "type": "object",
+ "required": [
+ "version",
+ "profiles",
+ "profileCurrent",
+ "global"
+ ],
+ "properties": {
+ "version": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "profiles": {
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "conditionGroups",
+ "options"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "default": "Default"
+ },
+ "conditionGroups": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "conditions"
+ ],
+ "properties": {
+ "conditions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "type",
+ "operator",
+ "value"
+ ],
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "operator": {
+ "type": "string"
+ },
+ "value": {}
+ }
+ }
+ }
+ }
+ }
+ },
+ "options": {
+ "type": "object",
+ "required": [
+ "general",
+ "popupWindow",
+ "audio",
+ "scanning",
+ "translation",
+ "dictionaries",
+ "parsing",
+ "anki",
+ "sentenceParsing",
+ "inputs",
+ "clipboard"
+ ],
+ "properties": {
+ "general": {
+ "type": "object",
+ "required": [
+ "enable",
+ "resultOutputMode",
+ "debugInfo",
+ "maxResults",
+ "showAdvanced",
+ "popupDisplayMode",
+ "popupWidth",
+ "popupHeight",
+ "popupHorizontalOffset",
+ "popupVerticalOffset",
+ "popupHorizontalOffset2",
+ "popupVerticalOffset2",
+ "popupHorizontalTextPosition",
+ "popupVerticalTextPosition",
+ "popupScalingFactor",
+ "popupScaleRelativeToPageZoom",
+ "popupScaleRelativeToVisualViewport",
+ "showGuide",
+ "compactTags",
+ "glossaryLayoutMode",
+ "mainDictionary",
+ "popupTheme",
+ "popupOuterTheme",
+ "customPopupCss",
+ "customPopupOuterCss",
+ "enableWanakana",
+ "showPitchAccentDownstepNotation",
+ "showPitchAccentPositionNotation",
+ "showPitchAccentGraph",
+ "showIframePopupsInRootFrame",
+ "useSecurePopupFrameUrl",
+ "usePopupShadowDom",
+ "usePopupWindow",
+ "popupCurrentIndicatorMode",
+ "popupActionBarVisibility",
+ "popupActionBarLocation"
+ ],
+ "properties": {
+ "enable": {
+ "type": "boolean",
+ "default": true
+ },
+ "resultOutputMode": {
+ "type": "string",
+ "enum": ["group", "merge", "split"],
+ "default": "group"
+ },
+ "debugInfo": {
+ "type": "boolean",
+ "default": false
+ },
+ "maxResults": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 32
+ },
+ "showAdvanced": {
+ "type": "boolean",
+ "default": false
+ },
+ "popupDisplayMode": {
+ "type": "string",
+ "enum": ["default", "full-width"],
+ "default": "default"
+ },
+ "popupWidth": {
+ "type": "number",
+ "minimum": 0,
+ "default": 400
+ },
+ "popupHeight": {
+ "type": "number",
+ "minimum": 0,
+ "default": 250
+ },
+ "popupHorizontalOffset": {
+ "type": "number",
+ "default": 0
+ },
+ "popupVerticalOffset": {
+ "type": "number",
+ "default": 10
+ },
+ "popupHorizontalOffset2": {
+ "type": "number",
+ "default": 10
+ },
+ "popupVerticalOffset2": {
+ "type": "number",
+ "default": 0
+ },
+ "popupHorizontalTextPosition": {
+ "type": "string",
+ "enum": ["below", "above"],
+ "default": "below"
+ },
+ "popupVerticalTextPosition": {
+ "type": "string",
+ "enum": ["default", "before", "after", "left", "right"],
+ "default": "before"
+ },
+ "popupScalingFactor": {
+ "type": "number",
+ "default": 1
+ },
+ "popupScaleRelativeToPageZoom": {
+ "type": "boolean",
+ "default": false
+ },
+ "popupScaleRelativeToVisualViewport": {
+ "type": "boolean",
+ "default": true
+ },
+ "showGuide": {
+ "type": "boolean",
+ "default": true
+ },
+ "compactTags": {
+ "type": "boolean",
+ "default": false
+ },
+ "glossaryLayoutMode": {
+ "type": "string",
+ "enum": ["default", "compact"],
+ "default": "default"
+ },
+ "mainDictionary": {
+ "type": "string"
+ },
+ "popupTheme": {
+ "type": "string",
+ "enum": ["default", "dark"],
+ "default": "default"
+ },
+ "popupOuterTheme": {
+ "type": "string",
+ "enum": ["default", "dark", "auto"],
+ "default": "default"
+ },
+ "customPopupCss": {
+ "type": "string",
+ "default": ""
+ },
+ "customPopupOuterCss": {
+ "type": "string",
+ "default": ""
+ },
+ "enableWanakana": {
+ "type": "boolean",
+ "default": true
+ },
+ "showPitchAccentDownstepNotation": {
+ "type": "boolean",
+ "default": true
+ },
+ "showPitchAccentPositionNotation": {
+ "type": "boolean",
+ "default": true
+ },
+ "showPitchAccentGraph": {
+ "type": "boolean",
+ "default": false
+ },
+ "showIframePopupsInRootFrame": {
+ "type": "boolean",
+ "default": false
+ },
+ "useSecurePopupFrameUrl": {
+ "type": "boolean",
+ "default": true
+ },
+ "usePopupShadowDom": {
+ "type": "boolean",
+ "default": true
+ },
+ "usePopupWindow": {
+ "type": "boolean",
+ "default": false
+ },
+ "popupCurrentIndicatorMode": {
+ "type": "string",
+ "enum": ["none", "asterisk", "triangle", "bar-left", "bar-right", "dot-left", "dot-right"],
+ "default": "triangle"
+ },
+ "popupActionBarVisibility": {
+ "type": "string",
+ "enum": ["auto", "always"],
+ "default": "auto"
+ },
+ "popupActionBarLocation": {
+ "type": "string",
+ "enum": ["left", "right", "top", "bottom"],
+ "default": "top"
+ }
+ }
+ },
+ "popupWindow": {
+ "type": "object",
+ "required": [
+ "width",
+ "height",
+ "left",
+ "top",
+ "useLeft",
+ "useTop",
+ "windowType",
+ "windowState"
+ ],
+ "properties": {
+ "width": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 400
+ },
+ "height": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 250
+ },
+ "left": {
+ "type": "integer",
+ "default": 0
+ },
+ "top": {
+ "type": "integer",
+ "default": 0
+ },
+ "useLeft": {
+ "type": "boolean",
+ "default": false
+ },
+ "useTop": {
+ "type": "boolean",
+ "default": false
+ },
+ "windowType": {
+ "type": "string",
+ "enum": ["normal", "popup"],
+ "default": "popup"
+ },
+ "windowState": {
+ "type": "string",
+ "enum": ["normal", "maximized", "fullscreen"],
+ "default": "normal"
+ }
+ }
+ },
+ "audio": {
+ "type": "object",
+ "required": [
+ "enabled",
+ "sources",
+ "volume",
+ "autoPlay",
+ "customSourceUrl",
+ "customSourceType",
+ "textToSpeechVoice"
+ ],
+ "properties": {
+ "enabled": {
+ "type": "boolean",
+ "default": true
+ },
+ "sources": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "jpod101",
+ "jpod101-alternate",
+ "jisho",
+ "text-to-speech",
+ "text-to-speech-reading",
+ "custom"
+ ],
+ "default": "jpod101"
+ },
+ "default": [
+ "jpod101"
+ ]
+ },
+ "volume": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 100,
+ "default": 100
+ },
+ "autoPlay": {
+ "type": "boolean",
+ "default": false
+ },
+ "customSourceUrl": {
+ "type": "string",
+ "default": ""
+ },
+ "customSourceType": {
+ "type": "string",
+ "enum": ["audio", "json"],
+ "default": "audio"
+ },
+ "textToSpeechVoice": {
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "scanning": {
+ "type": "object",
+ "required": [
+ "inputs",
+ "preventMiddleMouse",
+ "touchInputEnabled",
+ "pointerEventsEnabled",
+ "selectText",
+ "alphanumeric",
+ "autoHideResults",
+ "delay",
+ "hideDelay",
+ "length",
+ "deepDomScan",
+ "popupNestingMaxDepth",
+ "enablePopupSearch",
+ "enableOnPopupExpressions",
+ "enableOnSearchPage",
+ "enableSearchTags",
+ "layoutAwareScan"
+ ],
+ "properties": {
+ "inputs": {
+ "type": "array",
+ "default": [
+ {
+ "include": "shift",
+ "exclude": "mouse0",
+ "types": {
+ "mouse": true,
+ "touch": false,
+ "pen": false
+ },
+ "options": {
+ "showAdvanced": false,
+ "searchTerms": true,
+ "searchKanji": true,
+ "scanOnTouchMove": true,
+ "scanOnPenHover": true,
+ "scanOnPenPress": true,
+ "scanOnPenRelease": false,
+ "preventTouchScrolling": false
+ }
+ },
+ {
+ "include": "",
+ "exclude": "",
+ "types": {
+ "mouse": false,
+ "touch": true,
+ "pen": true
+ },
+ "options": {
+ "showAdvanced": false,
+ "searchTerms": true,
+ "searchKanji": true,
+ "scanOnTouchMove": true,
+ "scanOnPenHover": true,
+ "scanOnPenPress": true,
+ "scanOnPenRelease": false,
+ "preventTouchScrolling": true
+ }
+ }
+ ],
+ "items": {
+ "required": [
+ "include",
+ "exclude",
+ "types",
+ "options"
+ ],
+ "properties": {
+ "include": {
+ "type": "string",
+ "default": "shift"
+ },
+ "exclude": {
+ "type": "string",
+ "default": ""
+ },
+ "types": {
+ "type": "object",
+ "required": [
+ "mouse",
+ "touch",
+ "pen"
+ ],
+ "properties": {
+ "mouse": {
+ "type": "boolean",
+ "default": true
+ },
+ "touch": {
+ "type": "boolean",
+ "default": true
+ },
+ "pen": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "options": {
+ "type": "object",
+ "required": [
+ "showAdvanced",
+ "searchTerms",
+ "searchKanji",
+ "scanOnTouchMove",
+ "scanOnPenHover",
+ "scanOnPenPress",
+ "scanOnPenRelease",
+ "preventTouchScrolling"
+ ],
+ "properties": {
+ "showAdvanced": {
+ "type": "boolean",
+ "default": false
+ },
+ "searchTerms": {
+ "type": "boolean",
+ "default": true
+ },
+ "searchKanji": {
+ "type": "boolean",
+ "default": true
+ },
+ "scanOnTouchMove": {
+ "type": "boolean",
+ "default": true
+ },
+ "scanOnPenHover": {
+ "type": "boolean",
+ "default": true
+ },
+ "scanOnPenPress": {
+ "type": "boolean",
+ "default": true
+ },
+ "scanOnPenRelease": {
+ "type": "boolean",
+ "default": false
+ },
+ "preventTouchScrolling": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ }
+ },
+ "preventMiddleMouse": {
+ "type": "object",
+ "required": [
+ "onWebPages",
+ "onPopupPages",
+ "onSearchPages",
+ "onSearchQuery"
+ ],
+ "properties": {
+ "onWebPages": {
+ "type": "boolean",
+ "default": false
+ },
+ "onPopupPages": {
+ "type": "boolean",
+ "default": false
+ },
+ "onSearchPages": {
+ "type": "boolean",
+ "default": false
+ },
+ "onSearchQuery": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "touchInputEnabled": {
+ "type": "boolean",
+ "default": true
+ },
+ "pointerEventsEnabled": {
+ "type": "boolean",
+ "default": false
+ },
+ "selectText": {
+ "type": "boolean",
+ "default": true
+ },
+ "alphanumeric": {
+ "type": "boolean",
+ "default": true
+ },
+ "autoHideResults": {
+ "type": "boolean",
+ "default": false
+ },
+ "delay": {
+ "type": "number",
+ "minimum": 0,
+ "default": 20
+ },
+ "hideDelay": {
+ "type": "number",
+ "minimum": 0,
+ "default": 0
+ },
+ "length": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 10
+ },
+ "deepDomScan": {
+ "type": "boolean",
+ "default": false
+ },
+ "popupNestingMaxDepth": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "enablePopupSearch": {
+ "type": "boolean",
+ "default": false
+ },
+ "enableOnPopupExpressions": {
+ "type": "boolean",
+ "default": false
+ },
+ "enableOnSearchPage": {
+ "type": "boolean",
+ "default": true
+ },
+ "enableSearchTags": {
+ "type": "boolean",
+ "default": false
+ },
+ "layoutAwareScan": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "translation": {
+ "type": "object",
+ "required": [
+ "convertHalfWidthCharacters",
+ "convertNumericCharacters",
+ "convertAlphabeticCharacters",
+ "convertHiraganaToKatakana",
+ "convertKatakanaToHiragana",
+ "collapseEmphaticSequences",
+ "textReplacements"
+ ],
+ "properties": {
+ "convertHalfWidthCharacters": {
+ "type": "string",
+ "enum": ["false", "true", "variant"],
+ "default": "false"
+ },
+ "convertNumericCharacters": {
+ "type": "string",
+ "enum": ["false", "true", "variant"],
+ "default": "false"
+ },
+ "convertAlphabeticCharacters": {
+ "type": "string",
+ "enum": ["false", "true", "variant"],
+ "default": "false"
+ },
+ "convertHiraganaToKatakana": {
+ "type": "string",
+ "enum": ["false", "true", "variant"],
+ "default": "false"
+ },
+ "convertKatakanaToHiragana": {
+ "type": "string",
+ "enum": ["false", "true", "variant"],
+ "default": "variant"
+ },
+ "collapseEmphaticSequences": {
+ "type": "string",
+ "enum": ["false", "true", "full"],
+ "default": "false"
+ },
+ "textReplacements": {
+ "type": "object",
+ "required": [
+ "searchOriginal",
+ "groups"
+ ],
+ "properties": {
+ "searchOriginal": {
+ "type": "boolean",
+ "default": true
+ },
+ "groups": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": {
+ "required": [
+ "pattern",
+ "ignoreCase",
+ "replacement"
+ ],
+ "properties": {
+ "pattern": {
+ "type": "string",
+ "default": ""
+ },
+ "ignoreCase": {
+ "type": "boolean",
+ "default": false
+ },
+ "replacement": {
+ "type": "string",
+ "default": ""
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dictionaries": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "object",
+ "required": [
+ "priority",
+ "enabled",
+ "allowSecondarySearches"
+ ],
+ "properties": {
+ "priority": {
+ "type": "number",
+ "default": 0
+ },
+ "enabled": {
+ "type": "boolean",
+ "default": true
+ },
+ "allowSecondarySearches": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ },
+ "parsing": {
+ "type": "object",
+ "required": [
+ "enableScanningParser",
+ "enableMecabParser",
+ "selectedParser",
+ "termSpacing",
+ "readingMode"
+ ],
+ "properties": {
+ "enableScanningParser": {
+ "type": "boolean",
+ "default": true
+ },
+ "enableMecabParser": {
+ "type": "boolean",
+ "default": false
+ },
+ "selectedParser": {
+ "type": ["string", "null"],
+ "default": null
+ },
+ "termSpacing": {
+ "type": "boolean",
+ "default": true
+ },
+ "readingMode": {
+ "type": "string",
+ "enum": ["hiragana", "katakana", "romaji", "none"],
+ "default": "hiragana"
+ }
+ }
+ },
+ "anki": {
+ "type": "object",
+ "required": [
+ "enable",
+ "server",
+ "tags",
+ "screenshot",
+ "terms",
+ "kanji",
+ "duplicateScope",
+ "checkForDuplicates",
+ "fieldTemplates",
+ "suspendNewCards"
+ ],
+ "properties": {
+ "enable": {
+ "type": "boolean",
+ "default": false
+ },
+ "server": {
+ "type": "string",
+ "default": "http://127.0.0.1:8765"
+ },
+ "tags": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [
+ "yomichan"
+ ]
+ },
+ "screenshot": {
+ "type": "object",
+ "required": [
+ "format",
+ "quality"
+ ],
+ "properties": {
+ "format": {
+ "type": "string",
+ "enum": ["png", "jpeg"],
+ "default": "png"
+ },
+ "quality": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 100,
+ "default": 92
+ }
+ }
+ },
+ "terms": {
+ "type": "object",
+ "required": [
+ "deck",
+ "model",
+ "fields"
+ ],
+ "properties": {
+ "deck": {
+ "type": "string",
+ "default": ""
+ },
+ "model": {
+ "type": "string",
+ "default": ""
+ },
+ "fields": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string",
+ "default": ""
+ }
+ }
+ }
+ },
+ "kanji": {
+ "type": "object",
+ "required": [
+ "deck",
+ "model",
+ "fields"
+ ],
+ "properties": {
+ "deck": {
+ "type": "string",
+ "default": ""
+ },
+ "model": {
+ "type": "string",
+ "default": ""
+ },
+ "fields": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string",
+ "default": ""
+ }
+ }
+ }
+ },
+ "duplicateScope": {
+ "type": "string",
+ "default": "collection",
+ "enum": ["collection", "deck", "deck-root"]
+ },
+ "checkForDuplicates": {
+ "type": "boolean",
+ "default": true
+ },
+ "fieldTemplates": {
+ "type": ["string", "null"],
+ "default": null
+ },
+ "suspendNewCards": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "sentenceParsing": {
+ "type": "object",
+ "required": [
+ "scanExtent",
+ "enableTerminationCharacters",
+ "terminationCharacters"
+ ],
+ "properties": {
+ "scanExtent": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 200
+ },
+ "enableTerminationCharacters": {
+ "type": "boolean",
+ "default": true
+ },
+ "terminationCharacters": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "enabled",
+ "character1",
+ "character2",
+ "includeCharacterAtStart",
+ "includeCharacterAtEnd"
+ ],
+ "properties": {
+ "enabled": {
+ "type": "boolean",
+ "default": true
+ },
+ "character1": {
+ "type": "string",
+ "default": "\"",
+ "minLength": 1,
+ "maxLength": 1
+ },
+ "character2": {
+ "type": ["string", "null"],
+ "default": "\"",
+ "minLength": 1,
+ "maxLength": 1
+ },
+ "includeCharacterAtStart": {
+ "type": "boolean",
+ "default": false
+ },
+ "includeCharacterAtEnd": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "default": [
+ {"enabled": true, "character1": "「", "character2": "」", "includeCharacterAtStart": false, "includeCharacterAtEnd": false},
+ {"enabled": true, "character1": "『", "character2": "』", "includeCharacterAtStart": false, "includeCharacterAtEnd": false},
+ {"enabled": true, "character1": "\"", "character2": "\"", "includeCharacterAtStart": false, "includeCharacterAtEnd": false},
+ {"enabled": true, "character1": "'", "character2": "'", "includeCharacterAtStart": false, "includeCharacterAtEnd": false},
+ {"enabled": true, "character1": ".", "character2": null, "includeCharacterAtStart": false, "includeCharacterAtEnd": true},
+ {"enabled": true, "character1": "!", "character2": null, "includeCharacterAtStart": false, "includeCharacterAtEnd": true},
+ {"enabled": true, "character1": "?", "character2": null, "includeCharacterAtStart": false, "includeCharacterAtEnd": true},
+ {"enabled": true, "character1": ".", "character2": null, "includeCharacterAtStart": false, "includeCharacterAtEnd": true},
+ {"enabled": true, "character1": "。", "character2": null, "includeCharacterAtStart": false, "includeCharacterAtEnd": true},
+ {"enabled": true, "character1": "!", "character2": null, "includeCharacterAtStart": false, "includeCharacterAtEnd": true},
+ {"enabled": true, "character1": "?", "character2": null, "includeCharacterAtStart": false, "includeCharacterAtEnd": true},
+ {"enabled": true, "character1": "…", "character2": null, "includeCharacterAtStart": false, "includeCharacterAtEnd": true}
+ ]
+ }
+ }
+ },
+ "inputs": {
+ "type": "object",
+ "required": [
+ "hotkeys"
+ ],
+ "properties": {
+ "hotkeys": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": [
+ "action",
+ "key",
+ "modifiers",
+ "scopes",
+ "enabled"
+ ],
+ "properties": {
+ "action": {
+ "type": "string",
+ "default": ""
+ },
+ "key": {
+ "type": ["string", "null"],
+ "default": null
+ },
+ "modifiers": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": ["alt", "ctrl", "shift", "meta"],
+ "default": "alt"
+ }
+ },
+ "scopes": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": ["popup", "search", "web"],
+ "default": "popup"
+ },
+ "default": ["popup", "search"]
+ },
+ "enabled": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "default": [
+ {"action": "close", "key": "Escape", "modifiers": [], "scopes": ["popup"], "enabled": true},
+ {"action": "focusSearchBox", "key": "Escape", "modifiers": [], "scopes": ["search"], "enabled": true},
+ {"action": "previousEntry3", "key": "PageUp", "modifiers": ["alt"], "scopes": ["popup", "search"], "enabled": true},
+ {"action": "nextEntry3", "key": "PageDown", "modifiers": ["alt"], "scopes": ["popup", "search"], "enabled": true},
+ {"action": "lastEntry", "key": "End", "modifiers": ["alt"], "scopes": ["popup", "search"], "enabled": true},
+ {"action": "firstEntry", "key": "Home", "modifiers": ["alt"], "scopes": ["popup", "search"], "enabled": true},
+ {"action": "previousEntry", "key": "ArrowUp", "modifiers": ["alt"], "scopes": ["popup", "search"], "enabled": true},
+ {"action": "nextEntry", "key": "ArrowDown", "modifiers": ["alt"], "scopes": ["popup", "search"], "enabled": true},
+ {"action": "historyBackward", "key": "KeyB", "modifiers": ["alt"], "scopes": ["popup", "search"], "enabled": true},
+ {"action": "historyForward", "key": "KeyF", "modifiers": ["alt"], "scopes": ["popup", "search"], "enabled": true},
+ {"action": "addNoteKanji", "key": "KeyK", "modifiers": ["alt"], "scopes": ["popup", "search"], "enabled": true},
+ {"action": "addNoteTermKanji", "key": "KeyE", "modifiers": ["alt"], "scopes": ["popup", "search"], "enabled": true},
+ {"action": "addNoteTermKana", "key": "KeyR", "modifiers": ["alt"], "scopes": ["popup", "search"], "enabled": true},
+ {"action": "playAudio", "key": "KeyP", "modifiers": ["alt"], "scopes": ["popup", "search"], "enabled": true},
+ {"action": "viewNote", "key": "KeyV", "modifiers": ["alt"], "scopes": ["popup", "search"], "enabled": true},
+ {"action": "copyHostSelection", "key": "KeyC", "modifiers": ["ctrl"], "scopes": ["popup"], "enabled": true}
+ ]
+ }
+ }
+ },
+ "clipboard": {
+ "type": "object",
+ "required": [
+ "enableBackgroundMonitor",
+ "enableSearchPageMonitor",
+ "autoSearchContent",
+ "maximumSearchLength"
+ ],
+ "properties": {
+ "enableBackgroundMonitor": {
+ "type": "boolean",
+ "default": false
+ },
+ "enableSearchPageMonitor": {
+ "type": "boolean",
+ "default": false
+ },
+ "autoSearchContent": {
+ "type": "boolean",
+ "default": true
+ },
+ "maximumSearchLength": {
+ "type": "integer",
+ "default": 1000,
+ "minimum": 0
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "profileCurrent": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "global": {
+ "type": "object",
+ "required": [
+ "database",
+ "useSettingsV2"
+ ],
+ "properties": {
+ "database": {
+ "type": "object",
+ "required": [
+ "prefixWildcardsSupported"
+ ],
+ "properties": {
+ "prefixWildcardsSupported": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "useSettingsV2": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+}
diff --git a/ext/data/templates/anki-field-templates-upgrade-v2.handlebars b/ext/data/templates/anki-field-templates-upgrade-v2.handlebars
new file mode 100644
index 00000000..c018094e
--- /dev/null
+++ b/ext/data/templates/anki-field-templates-upgrade-v2.handlebars
@@ -0,0 +1,109 @@
+{{! Pitch Accents }}
+{{#*inline "pitch-accent-item-downstep-notation"}}
+ {{~#scope~}}
+ <span>
+ {{~#set "style1a"~}}display:inline-block;position:relative;{{~/set~}}
+ {{~#set "style1b"~}}padding-right:0.1em;margin-right:0.1em;{{~/set~}}
+ {{~#set "style2a"~}}display:block;user-select:none;pointer-events:none;position:absolute;top:0.1em;left:0;right:0;height:0;border-top:0.1em solid;{{~/set~}}
+ {{~#set "style2b"~}}right:-0.1em;height:0.4em;border-right:0.1em solid;{{~/set~}}
+ {{~#each (getKanaMorae reading)~}}
+ {{~#set "style1"}}{{#get "style1a"}}{{/get}}{{/set~}}
+ {{~#set "style2"}}{{/set~}}
+ {{~#if (isMoraPitchHigh @index ../position)}}
+ {{~#set "style2"}}{{#get "style2a"}}{{/get}}{{/set~}}
+ {{~#if (op "!" (isMoraPitchHigh (op "+" @index 1) ../position))~}}
+ {{~#set "style1" (op "+" (get "style1") (get "style1b"))}}{{/set~}}
+ {{~#set "style2" (op "+" (get "style2") (get "style2b"))}}{{/set~}}
+ {{~/if~}}
+ {{~/if~}}
+ <span style="{{#get "style1"}}{{/get}}">{{{.}}}<span style="{{#get "style2"}}{{/get}}"></span></span>
+ {{~/each~}}
+ </span>
+ {{~/scope~}}
+{{/inline}}
+
+{{#*inline "pitch-accent-item-graph-position-x"}}{{#op "+" 25 (op "*" index 50)}}{{/op}}{{/inline}}
+{{#*inline "pitch-accent-item-graph-position-y"}}{{#op "+" 25 (op "?:" (isMoraPitchHigh index position) 0 50)}}{{/op}}{{/inline}}
+{{#*inline "pitch-accent-item-graph-position"}}{{> pitch-accent-item-graph-position-x index=index position=position}} {{> pitch-accent-item-graph-position-y index=index position=position}}{{/inline}}
+{{#*inline "pitch-accent-item-graph"}}
+ {{~#scope~}}
+ {{~#set "morae" (getKanaMorae reading)}}{{/set~}}
+ {{~#set "morae-count" (property (get "morae") "length")}}{{/set~}}
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {{#op "+" 50 (op "*" 50 (get "morae-count"))}}{{/op}} 100" style="display:inline-block;height:2em;">
+ <defs>
+ <g id="term-pitch-accent-graph-dot"><circle cx="0" cy="0" r="15" style="fill:#000;stroke:#000;stroke-width:5;" /></g>
+ <g id="term-pitch-accent-graph-dot-downstep"><circle cx="0" cy="0" r="15" style="fill:none;stroke:#000;stroke-width:5;" /><circle cx="0" cy="0" r="5" style="fill:none;stroke:#000;stroke-width:5;" /></g>
+ <g id="term-pitch-accent-graph-triangle"><path d="M0 13 L15 -13 L-15 -13 Z" style="fill:none;stroke:#000;stroke-width:5;" /></g>
+ </defs>
+ <path style="fill:none;stroke:#000;stroke-width:5;" d="
+ {{~#set "cmd" "M"}}{{/set~}}
+ {{~#each (get "morae")~}}
+ {{~#get "cmd"}}{{/get~}}
+ {{~> pitch-accent-item-graph-position index=@index position=../position~}}
+ {{~#set "cmd" "L"}}{{/set~}}
+ {{~/each~}}
+ "></path>
+ <path style="fill:none;stroke:#000;stroke-width:5;stroke-dasharray:5 5;" d="M{{> pitch-accent-item-graph-position index=(op "-" (get "morae-count") 1) position=position}} L{{> pitch-accent-item-graph-position index=(get "morae-count") position=position}}"></path>
+ {{#each (get "morae")}}
+ <use href="{{#if (op "&&" (isMoraPitchHigh @index ../position) (op "!" (isMoraPitchHigh (op "+" @index 1) ../position)))}}#term-pitch-accent-graph-dot-downstep{{else}}#term-pitch-accent-graph-dot{{/if}}" x="{{> pitch-accent-item-graph-position-x index=@index position=../position}}" y="{{> pitch-accent-item-graph-position-y index=@index position=../position}}"></use>
+ {{/each}}
+ <use href="#term-pitch-accent-graph-triangle" x="{{> pitch-accent-item-graph-position-x index=(get "morae-count") position=position}}" y="{{> pitch-accent-item-graph-position-y index=(get "morae-count") position=position}}"></use>
+</svg>
+ {{~/scope~}}
+{{/inline}}
+
+{{#*inline "pitch-accent-item-position"~}}
+ <span>[{{position}}]</span>
+{{~/inline}}
+
+{{#*inline "pitch-accent-item"}}
+ {{~#if (op "==" format "downstep-notation")~}}
+ {{~> pitch-accent-item-downstep-notation~}}
+ {{~else if (op "==" format "graph")~}}
+ {{~> pitch-accent-item-graph~}}
+ {{~else if (op "==" format "position")~}}
+ {{~> pitch-accent-item-position~}}
+ {{~/if~}}
+{{/inline}}
+
+{{#*inline "pitch-accent-item-disambiguation"}}
+ {{~#scope~}}
+ {{~#set "exclusive" (spread exclusiveExpressions exclusiveReadings)}}{{/set~}}
+ {{~#if (op ">" (property (get "exclusive") "length") 0)~}}
+ {{~#set "separator" ""~}}{{/set~}}
+ <em>({{#each (get "exclusive")~}}
+ {{~#get "separator"}}{{/get~}}{{{.}}}
+ {{~/each}} only) </em>
+ {{~/if~}}
+ {{~/scope~}}
+{{/inline}}
+
+{{#*inline "pitch-accent-list"}}
+ {{~#if (op ">" pitchCount 0)~}}
+ {{~#if (op ">" pitchCount 1)~}}<ol>{{~/if~}}
+ {{~#each pitches~}}
+ {{~#each pitches~}}
+ {{~#if (op ">" ../../pitchCount 1)~}}<li>{{~/if~}}
+ {{~> pitch-accent-item-disambiguation~}}
+ {{~> pitch-accent-item format=../../format~}}
+ {{~#if (op ">" ../../pitchCount 1)~}}</li>{{~/if~}}
+ {{~/each~}}
+ {{~/each~}}
+ {{~#if (op ">" pitchCount 1)~}}</ol>{{~/if~}}
+ {{~else~}}
+ No pitch accent data
+ {{~/if~}}
+{{/inline}}
+
+{{#*inline "pitch-accents"}}
+ {{~> pitch-accent-list format='downstep-notation'~}}
+{{/inline}}
+
+{{#*inline "pitch-accent-graphs"}}
+ {{~> pitch-accent-list format='graph'~}}
+{{/inline}}
+
+{{#*inline "pitch-accent-positions"}}
+ {{~> pitch-accent-list format='position'~}}
+{{/inline}}
+{{! End Pitch Accents }}
diff --git a/ext/data/templates/anki-field-templates-upgrade-v4.handlebars b/ext/data/templates/anki-field-templates-upgrade-v4.handlebars
new file mode 100644
index 00000000..dc88395a
--- /dev/null
+++ b/ext/data/templates/anki-field-templates-upgrade-v4.handlebars
@@ -0,0 +1,9 @@
+{{#*inline "clipboard-image"}}
+ {{~#if definition.clipboardImageFileName~}}
+ <img src="{{definition.clipboardImageFileName}}" />
+ {{~/if~}}
+{{/inline}}
+
+{{#*inline "clipboard-text"}}
+ {{~#if definition.clipboardText~}}{{definition.clipboardText}}{{~/if~}}
+{{/inline}}
diff --git a/ext/data/templates/anki-field-templates-upgrade-v6.handlebars b/ext/data/templates/anki-field-templates-upgrade-v6.handlebars
new file mode 100644
index 00000000..809423ce
--- /dev/null
+++ b/ext/data/templates/anki-field-templates-upgrade-v6.handlebars
@@ -0,0 +1,25 @@
+{{#*inline "conjugation"}}
+ {{~#if definition.reasons~}}
+ {{~#each definition.reasons~}}
+ {{~#if (op ">" @index 0)}} « {{/if~}}
+ {{.}}
+ {{~/each~}}
+ {{~/if~}}
+{{/inline}}
+
+{{#*inline "frequencies"}}
+ {{~#if (op ">" definition.frequencies.length 0)~}}
+ <ul style="text-align: left;">
+ {{~#each definition.frequencies~}}
+ <li>
+ {{~#if (op "!==" ../definition.type "kanji")~}}
+ {{~#if (op "||" (op ">" ../uniqueExpressions.length 1) (op ">" ../uniqueReadings.length 1))~}}(
+ {{~#furigana expression reading~}}{{~/furigana~}}
+ ) {{/if~}}
+ {{~/if~}}
+ {{~dictionary}}: {{frequency~}}
+ </li>
+ {{~/each~}}
+ </ul>
+ {{~/if~}}
+{{/inline}}
diff --git a/ext/data/templates/anki-field-templates-upgrade-v8.handlebars b/ext/data/templates/anki-field-templates-upgrade-v8.handlebars
new file mode 100644
index 00000000..b3aed45f
--- /dev/null
+++ b/ext/data/templates/anki-field-templates-upgrade-v8.handlebars
@@ -0,0 +1,131 @@
+{{#*inline "stroke-count"}}
+ {{~#scope~}}
+ {{~#set "found" false}}{{/set~}}
+ {{~#each definition.stats.misc~}}
+ {{~#if (op "===" name "strokes")~}}
+ {{~#set "found" true}}{{/set~}}
+ Stroke count: {{value}}
+ {{~/if~}}
+ {{~/each~}}
+ {{~#if (op "!" (get "found"))~}}
+ Stroke count: Unknown
+ {{~/if~}}
+ {{~/scope~}}
+{{/inline}}
+
+{{<<<<<<<}}
+{{#*inline "glossary-single"}}
+ {{~#unless brief~}}
+ {{~#scope~}}
+ {{~#set "any" false}}{{/set~}}
+ {{~#if definitionTags~}}{{#each definitionTags~}}
+ {{~#if (op "||" (op "!" ../data.compactTags) (op "!" redundant))~}}
+ {{~#if (get "any")}}, {{else}}<i>({{/if~}}
+ {{name}}
+ {{~#set "any" true}}{{/set~}}
+ {{~/if~}}
+ {{~/each~}}
+ {{~#if (get "any")}})</i> {{/if~}}
+ {{~/if~}}
+ {{~/scope~}}
+ {{~#if only~}}({{#each only}}{{{.}}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}
+ {{~/unless~}}
+ {{~#if glossary.[1]~}}
+ {{~#if compactGlossaries~}}
+ {{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{#unless @last}} | {{/unless}}{{/each}}
+ {{~else~}}
+ <ul>{{#each glossary}}<li>{{#multiLine}}{{.}}{{/multiLine}}</li>{{/each}}</ul>
+ {{~/if~}}
+ {{~else~}}
+ {{~#multiLine}}{{glossary.[0]}}{{/multiLine~}}
+ {{~/if~}}
+{{/inline}}
+{{=======}}
+{{#*inline "glossary-single"}}
+ {{~#unless brief~}}
+ {{~#scope~}}
+ {{~#set "any" false}}{{/set~}}
+ {{~#each definitionTags~}}
+ {{~#if (op "||" (op "!" @root.compactTags) (op "!" redundant))~}}
+ {{~#if (get "any")}}, {{else}}<i>({{/if~}}
+ {{name}}
+ {{~#set "any" true}}{{/set~}}
+ {{~/if~}}
+ {{~/each~}}
+ {{~#unless noDictionaryTag~}}
+ {{~#if (op "||" (op "!" @root.compactTags) (op "!==" dictionary (get "previousDictionary")))~}}
+ {{~#if (get "any")}}, {{else}}<i>({{/if~}}
+ {{dictionary}}
+ {{~#set "any" true}}{{/set~}}
+ {{~/if~}}
+ {{~/unless~}}
+ {{~#if (get "any")}})</i> {{/if~}}
+ {{~/scope~}}
+ {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}
+ {{~/unless~}}
+ {{~#if (op "<=" glossary.length 1)~}}
+ {{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{/each}}
+ {{~else if @root.compactGlossaries~}}
+ {{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{#unless @last}} | {{/unless}}{{/each}}
+ {{~else~}}
+ <ul>{{#each glossary}}<li>{{#multiLine}}{{.}}{{/multiLine}}</li>{{/each}}</ul>
+ {{~/if~}}
+ {{~#set "previousDictionary" dictionary~}}{{~/set~}}
+{{/inline}}
+{{>>>>>>>}}
+
+{{<<<<<<<}}
+{{#*inline "glossary"}}
+ <div style="text-align: left;">
+ {{~#if modeKanji~}}
+ {{~#if definition.glossary.[1]~}}
+ <ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol>
+ {{~else~}}
+ {{definition.glossary.[0]}}
+ {{~/if~}}
+ {{~else~}}
+ {{~#if group~}}
+ {{~#if definition.definitions.[1]~}}
+ <ol>{{#each definition.definitions}}<li>{{> glossary-single brief=../brief compactGlossaries=../compactGlossaries data=../.}}</li>{{/each}}</ol>
+ {{~else~}}
+ {{~> glossary-single definition.definitions.[0] brief=brief compactGlossaries=compactGlossaries data=.~}}
+ {{~/if~}}
+ {{~else if merge~}}
+ {{~#if definition.definitions.[1]~}}
+ <ol>{{#each definition.definitions}}<li>{{> glossary-single brief=../brief compactGlossaries=../compactGlossaries data=../.}}</li>{{/each}}</ol>
+ {{~else~}}
+ {{~> glossary-single definition.definitions.[0] brief=brief compactGlossaries=compactGlossaries data=.~}}
+ {{~/if~}}
+ {{~else~}}
+ {{~> glossary-single definition brief=brief compactGlossaries=compactGlossaries data=.~}}
+ {{~/if~}}
+ {{~/if~}}
+ </div>
+{{/inline}}
+{{=======}}
+{{~#*inline "glossary"~}}
+ <div style="text-align: left;">
+ {{~#scope~}}
+ {{~#if (op "===" definition.type "term")~}}
+ {{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
+ {{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
+ {{~#if (op ">" definition.definitions.length 1)~}}
+ <ol>{{~#each definition.definitions~}}<li>{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}</li>{{~/each~}}</ol>
+ {{~else~}}
+ {{~#each definition.definitions~}}{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/each~}}
+ {{~/if~}}
+ {{~else if (op "===" definition.type "kanji")~}}
+ {{~#if (op ">" definition.glossary.length 1)~}}
+ <ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol>
+ {{~else~}}
+ {{~#each definition.glossary~}}{{.}}{{~/each~}}
+ {{~/if~}}
+ {{~/if~}}
+ {{~/scope~}}
+ </div>
+{{~/inline~}}
+
+{{#*inline "glossary-no-dictionary"}}
+ {{~> glossary noDictionaryTag=true ~}}
+{{/inline}}
+{{>>>>>>>}}
diff --git a/ext/data/templates/default-anki-field-templates.handlebars b/ext/data/templates/default-anki-field-templates.handlebars
new file mode 100644
index 00000000..0f390e8d
--- /dev/null
+++ b/ext/data/templates/default-anki-field-templates.handlebars
@@ -0,0 +1,344 @@
+{{#*inline "glossary-single"}}
+ {{~#unless brief~}}
+ {{~#scope~}}
+ {{~#set "any" false}}{{/set~}}
+ {{~#each definitionTags~}}
+ {{~#if (op "||" (op "!" @root.compactTags) (op "!" redundant))~}}
+ {{~#if (get "any")}}, {{else}}<i>({{/if~}}
+ {{name}}
+ {{~#set "any" true}}{{/set~}}
+ {{~/if~}}
+ {{~/each~}}
+ {{~#unless noDictionaryTag~}}
+ {{~#if (op "||" (op "!" @root.compactTags) (op "!==" dictionary (get "previousDictionary")))~}}
+ {{~#if (get "any")}}, {{else}}<i>({{/if~}}
+ {{dictionary}}
+ {{~#set "any" true}}{{/set~}}
+ {{~/if~}}
+ {{~/unless~}}
+ {{~#if (get "any")}})</i> {{/if~}}
+ {{~/scope~}}
+ {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}}
+ {{~/unless~}}
+ {{~#if (op "<=" glossary.length 1)~}}
+ {{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{/each}}
+ {{~else if @root.compactGlossaries~}}
+ {{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{#unless @last}} | {{/unless}}{{/each}}
+ {{~else~}}
+ <ul>{{#each glossary}}<li>{{#multiLine}}{{.}}{{/multiLine}}</li>{{/each}}</ul>
+ {{~/if~}}
+ {{~#set "previousDictionary" dictionary~}}{{~/set~}}
+{{/inline}}
+
+{{#*inline "audio"}}
+ {{~#if definition.audioFileName~}}
+ [sound:{{definition.audioFileName}}]
+ {{~/if~}}
+{{/inline}}
+
+{{#*inline "character"}}
+ {{~definition.character~}}
+{{/inline}}
+
+{{#*inline "dictionary"}}
+ {{~definition.dictionary~}}
+{{/inline}}
+
+{{#*inline "expression"}}
+ {{~#if merge~}}
+ {{~#if modeTermKana~}}
+ {{~#each definition.reading~}}
+ {{{.}}}
+ {{~#unless @last}}、{{/unless~}}
+ {{~else~}}
+ {{~#each definition.expression~}}
+ {{{.}}}
+ {{~#unless @last}}、{{/unless~}}
+ {{~/each~}}
+ {{~/each~}}
+ {{~else~}}
+ {{~#each definition.expression~}}
+ {{{.}}}
+ {{~#unless @last}}、{{/unless~}}
+ {{~/each~}}
+ {{~/if~}}
+ {{~else~}}
+ {{~#if modeTermKana~}}
+ {{~#if definition.reading~}}
+ {{definition.reading}}
+ {{~else~}}
+ {{definition.expression}}
+ {{~/if~}}
+ {{~else~}}
+ {{definition.expression}}
+ {{~/if~}}
+ {{~/if~}}
+{{/inline}}
+
+{{#*inline "furigana"}}
+ {{~#if merge~}}
+ {{~#each definition.expressions~}}
+ <span class="expression-{{termFrequency}}">{{~#furigana}}{{{.}}}{{/furigana~}}</span>
+ {{~#unless @last}}、{{/unless~}}
+ {{~/each~}}
+ {{~else~}}
+ {{#furigana}}{{{definition}}}{{/furigana}}
+ {{~/if~}}
+{{/inline}}
+
+{{#*inline "furigana-plain"}}
+ {{~#if merge~}}
+ {{~#each definition.expressions~}}
+ <span class="expression-{{termFrequency}}">{{~#furiganaPlain}}{{{.}}}{{/furiganaPlain~}}</span>
+ {{~#unless @last}}、{{/unless~}}
+ {{~/each~}}
+ {{~else~}}
+ {{#furiganaPlain}}{{{definition}}}{{/furiganaPlain}}
+ {{~/if~}}
+{{/inline}}
+
+{{~#*inline "glossary"~}}
+ <div style="text-align: left;">
+ {{~#scope~}}
+ {{~#if (op "===" definition.type "term")~}}
+ {{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}}
+ {{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}}
+ {{~#if (op ">" definition.definitions.length 1)~}}
+ <ol>{{~#each definition.definitions~}}<li>{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}</li>{{~/each~}}</ol>
+ {{~else~}}
+ {{~#each definition.definitions~}}{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/each~}}
+ {{~/if~}}
+ {{~else if (op "===" definition.type "kanji")~}}
+ {{~#if (op ">" definition.glossary.length 1)~}}
+ <ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol>
+ {{~else~}}
+ {{~#each definition.glossary~}}{{.}}{{~/each~}}
+ {{~/if~}}
+ {{~/if~}}
+ {{~/scope~}}
+ </div>
+{{~/inline~}}
+
+{{#*inline "glossary-no-dictionary"}}
+ {{~> glossary noDictionaryTag=true ~}}
+{{/inline}}
+
+{{#*inline "glossary-brief"}}
+ {{~> glossary brief=true ~}}
+{{/inline}}
+
+{{#*inline "kunyomi"}}
+ {{~#each definition.kunyomi}}{{.}}{{#unless @last}}, {{/unless}}{{/each~}}
+{{/inline}}
+
+{{#*inline "onyomi"}}
+ {{~#each definition.onyomi}}{{.}}{{#unless @last}}, {{/unless}}{{/each~}}
+{{/inline}}
+
+{{#*inline "reading"}}
+ {{~#unless modeTermKana~}}
+ {{~#if merge~}}
+ {{~#each definition.reading~}}
+ {{{.}}}
+ {{~#unless @last}}、{{/unless~}}
+ {{~/each~}}
+ {{~else~}}
+ {{~definition.reading~}}
+ {{~/if~}}
+ {{~/unless~}}
+{{/inline}}
+
+{{#*inline "sentence"}}
+ {{~#if definition.cloze}}{{definition.cloze.sentence}}{{/if~}}
+{{/inline}}
+
+{{#*inline "cloze-prefix"}}
+ {{~#if definition.cloze}}{{definition.cloze.prefix}}{{/if~}}
+{{/inline}}
+
+{{#*inline "cloze-body"}}
+ {{~#if definition.cloze}}{{definition.cloze.body}}{{/if~}}
+{{/inline}}
+
+{{#*inline "cloze-suffix"}}
+ {{~#if definition.cloze}}{{definition.cloze.suffix}}{{/if~}}
+{{/inline}}
+
+{{#*inline "tags"}}
+ {{~#mergeTags definition group merge}}{{this}}{{/mergeTags~}}
+{{/inline}}
+
+{{#*inline "url"}}
+ <a href="{{definition.url}}">{{definition.url}}</a>
+{{/inline}}
+
+{{#*inline "screenshot"}}
+ <img src="{{definition.screenshotFileName}}" />
+{{/inline}}
+
+{{#*inline "document-title"}}
+ {{~context.document.title~}}
+{{/inline}}
+
+{{! Pitch Accents }}
+{{#*inline "pitch-accent-item-downstep-notation"}}
+ {{~#scope~}}
+ <span>
+ {{~#set "style1a"~}}display:inline-block;position:relative;{{~/set~}}
+ {{~#set "style1b"~}}padding-right:0.1em;margin-right:0.1em;{{~/set~}}
+ {{~#set "style2a"~}}display:block;user-select:none;pointer-events:none;position:absolute;top:0.1em;left:0;right:0;height:0;border-top:0.1em solid;{{~/set~}}
+ {{~#set "style2b"~}}right:-0.1em;height:0.4em;border-right:0.1em solid;{{~/set~}}
+ {{~#each (getKanaMorae reading)~}}
+ {{~#set "style1"}}{{#get "style1a"}}{{/get}}{{/set~}}
+ {{~#set "style2"}}{{/set~}}
+ {{~#if (isMoraPitchHigh @index ../position)}}
+ {{~#set "style2"}}{{#get "style2a"}}{{/get}}{{/set~}}
+ {{~#if (op "!" (isMoraPitchHigh (op "+" @index 1) ../position))~}}
+ {{~#set "style1" (op "+" (get "style1") (get "style1b"))}}{{/set~}}
+ {{~#set "style2" (op "+" (get "style2") (get "style2b"))}}{{/set~}}
+ {{~/if~}}
+ {{~/if~}}
+ <span style="{{#get "style1"}}{{/get}}">{{{.}}}<span style="{{#get "style2"}}{{/get}}"></span></span>
+ {{~/each~}}
+ </span>
+ {{~/scope~}}
+{{/inline}}
+
+{{#*inline "pitch-accent-item-graph-position-x"}}{{#op "+" 25 (op "*" index 50)}}{{/op}}{{/inline}}
+{{#*inline "pitch-accent-item-graph-position-y"}}{{#op "+" 25 (op "?:" (isMoraPitchHigh index position) 0 50)}}{{/op}}{{/inline}}
+{{#*inline "pitch-accent-item-graph-position"}}{{> pitch-accent-item-graph-position-x index=index position=position}} {{> pitch-accent-item-graph-position-y index=index position=position}}{{/inline}}
+{{#*inline "pitch-accent-item-graph"}}
+ {{~#scope~}}
+ {{~#set "morae" (getKanaMorae reading)}}{{/set~}}
+ {{~#set "morae-count" (property (get "morae") "length")}}{{/set~}}
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {{#op "+" 50 (op "*" 50 (get "morae-count"))}}{{/op}} 100" style="display:inline-block;height:2em;">
+ <defs>
+ <g id="term-pitch-accent-graph-dot"><circle cx="0" cy="0" r="15" style="fill:#000;stroke:#000;stroke-width:5;" /></g>
+ <g id="term-pitch-accent-graph-dot-downstep"><circle cx="0" cy="0" r="15" style="fill:none;stroke:#000;stroke-width:5;" /><circle cx="0" cy="0" r="5" style="fill:none;stroke:#000;stroke-width:5;" /></g>
+ <g id="term-pitch-accent-graph-triangle"><path d="M0 13 L15 -13 L-15 -13 Z" style="fill:none;stroke:#000;stroke-width:5;" /></g>
+ </defs>
+ <path style="fill:none;stroke:#000;stroke-width:5;" d="
+ {{~#set "cmd" "M"}}{{/set~}}
+ {{~#each (get "morae")~}}
+ {{~#get "cmd"}}{{/get~}}
+ {{~> pitch-accent-item-graph-position index=@index position=../position~}}
+ {{~#set "cmd" "L"}}{{/set~}}
+ {{~/each~}}
+ "></path>
+ <path style="fill:none;stroke:#000;stroke-width:5;stroke-dasharray:5 5;" d="M{{> pitch-accent-item-graph-position index=(op "-" (get "morae-count") 1) position=position}} L{{> pitch-accent-item-graph-position index=(get "morae-count") position=position}}"></path>
+ {{#each (get "morae")}}
+ <use href="{{#if (op "&&" (isMoraPitchHigh @index ../position) (op "!" (isMoraPitchHigh (op "+" @index 1) ../position)))}}#term-pitch-accent-graph-dot-downstep{{else}}#term-pitch-accent-graph-dot{{/if}}" x="{{> pitch-accent-item-graph-position-x index=@index position=../position}}" y="{{> pitch-accent-item-graph-position-y index=@index position=../position}}"></use>
+ {{/each}}
+ <use href="#term-pitch-accent-graph-triangle" x="{{> pitch-accent-item-graph-position-x index=(get "morae-count") position=position}}" y="{{> pitch-accent-item-graph-position-y index=(get "morae-count") position=position}}"></use>
+</svg>
+ {{~/scope~}}
+{{/inline}}
+
+{{#*inline "pitch-accent-item-position"~}}
+ <span>[{{position}}]</span>
+{{~/inline}}
+
+{{#*inline "pitch-accent-item"}}
+ {{~#if (op "==" format "downstep-notation")~}}
+ {{~> pitch-accent-item-downstep-notation~}}
+ {{~else if (op "==" format "graph")~}}
+ {{~> pitch-accent-item-graph~}}
+ {{~else if (op "==" format "position")~}}
+ {{~> pitch-accent-item-position~}}
+ {{~/if~}}
+{{/inline}}
+
+{{#*inline "pitch-accent-item-disambiguation"}}
+ {{~#scope~}}
+ {{~#set "exclusive" (spread exclusiveExpressions exclusiveReadings)}}{{/set~}}
+ {{~#if (op ">" (property (get "exclusive") "length") 0)~}}
+ {{~#set "separator" ""~}}{{/set~}}
+ <em>({{#each (get "exclusive")~}}
+ {{~#get "separator"}}{{/get~}}{{{.}}}
+ {{~/each}} only) </em>
+ {{~/if~}}
+ {{~/scope~}}
+{{/inline}}
+
+{{#*inline "pitch-accent-list"}}
+ {{~#if (op ">" pitchCount 0)~}}
+ {{~#if (op ">" pitchCount 1)~}}<ol>{{~/if~}}
+ {{~#each pitches~}}
+ {{~#each pitches~}}
+ {{~#if (op ">" ../../pitchCount 1)~}}<li>{{~/if~}}
+ {{~> pitch-accent-item-disambiguation~}}
+ {{~> pitch-accent-item format=../../format~}}
+ {{~#if (op ">" ../../pitchCount 1)~}}</li>{{~/if~}}
+ {{~/each~}}
+ {{~/each~}}
+ {{~#if (op ">" pitchCount 1)~}}</ol>{{~/if~}}
+ {{~else~}}
+ No pitch accent data
+ {{~/if~}}
+{{/inline}}
+
+{{#*inline "pitch-accents"}}
+ {{~> pitch-accent-list format='downstep-notation'~}}
+{{/inline}}
+
+{{#*inline "pitch-accent-graphs"}}
+ {{~> pitch-accent-list format='graph'~}}
+{{/inline}}
+
+{{#*inline "pitch-accent-positions"}}
+ {{~> pitch-accent-list format='position'~}}
+{{/inline}}
+{{! End Pitch Accents }}
+
+{{#*inline "clipboard-image"}}
+ {{~#if definition.clipboardImageFileName~}}
+ <img src="{{definition.clipboardImageFileName}}" />
+ {{~/if~}}
+{{/inline}}
+
+{{#*inline "clipboard-text"}}
+ {{~#if definition.clipboardText~}}{{definition.clipboardText}}{{~/if~}}
+{{/inline}}
+
+{{#*inline "conjugation"}}
+ {{~#if definition.reasons~}}
+ {{~#each definition.reasons~}}
+ {{~#if (op ">" @index 0)}} « {{/if~}}
+ {{.}}
+ {{~/each~}}
+ {{~/if~}}
+{{/inline}}
+
+{{#*inline "frequencies"}}
+ {{~#if (op ">" definition.frequencies.length 0)~}}
+ <ul style="text-align: left;">
+ {{~#each definition.frequencies~}}
+ <li>
+ {{~#if (op "!==" ../definition.type "kanji")~}}
+ {{~#if (op "||" (op ">" ../uniqueExpressions.length 1) (op ">" ../uniqueReadings.length 1))~}}(
+ {{~#furigana expression reading~}}{{~/furigana~}}
+ ) {{/if~}}
+ {{~/if~}}
+ {{~dictionary}}: {{frequency~}}
+ </li>
+ {{~/each~}}
+ </ul>
+ {{~/if~}}
+{{/inline}}
+
+{{#*inline "stroke-count"}}
+ {{~#scope~}}
+ {{~#set "found" false}}{{/set~}}
+ {{~#each definition.stats.misc~}}
+ {{~#if (op "===" name "strokes")~}}
+ {{~#set "found" true}}{{/set~}}
+ Stroke count: {{value}}
+ {{~/if~}}
+ {{~/each~}}
+ {{~#if (op "!" (get "found"))~}}
+ Stroke count: Unknown
+ {{~/if~}}
+ {{~/scope~}}
+{{/inline}}
+
+{{~> (lookup . "marker") ~}}