aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Yatskov <alex@foosoft.net>2016-12-22 18:50:58 -0800
committerAlex Yatskov <alex@foosoft.net>2016-12-22 18:50:58 -0800
commit39fa11f72bae62985ee5b27103e5959dab30316c (patch)
treee7fe89d18a2b0bfa892ede044d7e6dcc076bbf7b
parent5710dc55a73491a0be2259fbd21874bddda54877 (diff)
parent9d21f8a456530c29c7c03db4896562a4902f6f8a (diff)
Merge branch 'dev'
-rw-r--r--ext/bg/background.html2
-rw-r--r--ext/bg/data/deinflect.json2799
-rw-r--r--ext/bg/guide.html (renamed from ext/bg/import.html)28
-rw-r--r--ext/bg/img/paypal.gifbin0 -> 1714 bytes
-rw-r--r--ext/bg/js/database.js297
-rw-r--r--ext/bg/js/deinflector.js117
-rw-r--r--ext/bg/js/dictionary.js217
-rw-r--r--ext/bg/js/import.js36
-rw-r--r--ext/bg/js/options-form.js470
-rw-r--r--ext/bg/js/options.js2
-rw-r--r--ext/bg/js/templates.js118
-rw-r--r--ext/bg/js/translator.js199
-rw-r--r--ext/bg/js/util.js100
-rw-r--r--ext/bg/js/yomichan.js42
-rw-r--r--ext/bg/options.html84
-rw-r--r--ext/fg/css/frame.css12
-rw-r--r--ext/lib/dexie.min.js5
-rw-r--r--ext/manifest.json2
-rw-r--r--tmpl/dictionary.html26
-rw-r--r--tmpl/kanji-list.html10
-rw-r--r--tmpl/kanji.html8
-rw-r--r--tmpl/model.html18
-rw-r--r--tmpl/term-list.html10
-rw-r--r--tmpl/term.html12
24 files changed, 3919 insertions, 695 deletions
diff --git a/ext/bg/background.html b/ext/bg/background.html
index 1bb36cf8..49fc6d0f 100644
--- a/ext/bg/background.html
+++ b/ext/bg/background.html
@@ -9,7 +9,7 @@
<script src="js/ankinull.js"></script>
<script src="js/templates.js"></script>
<script src="js/util.js"></script>
- <script src="js/dictionary.js"></script>
+ <script src="js/database.js"></script>
<script src="js/deinflector.js"></script>
<script src="js/translator.js"></script>
<script src="js/options.js"></script>
diff --git a/ext/bg/data/deinflect.json b/ext/bg/data/deinflect.json
new file mode 100644
index 00000000..532f8e62
--- /dev/null
+++ b/ext/bg/data/deinflect.json
@@ -0,0 +1,2799 @@
+{
+ "-ba": [
+ {
+ "kanaIn": "えば",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "けば",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "げば",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "せば",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "てば",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ねば",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "べば",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "めば",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "れば",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1",
+ "v5",
+ "vk",
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "ければ",
+ "kanaOut": "い",
+ "rulesIn": [],
+ "rulesOut": [
+ "adj-i"
+ ]
+ }
+ ],
+ "-chau": [
+ {
+ "kanaIn": "ちゃう",
+ "kanaOut": "る",
+ "rulesIn": [
+ "v5"
+ ],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "いじゃう",
+ "kanaOut": "ぐ",
+ "rulesIn": [
+ "v5"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "いちゃう",
+ "kanaOut": "く",
+ "rulesIn": [
+ "v5"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きちゃう",
+ "kanaOut": "くる",
+ "rulesIn": [
+ "v5"
+ ],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "しちゃう",
+ "kanaOut": "す",
+ "rulesIn": [
+ "v5"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "しちゃう",
+ "kanaOut": "する",
+ "rulesIn": [
+ "v5"
+ ],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "っちゃう",
+ "kanaOut": "う",
+ "rulesIn": [
+ "v5"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "っちゃう",
+ "kanaOut": "く",
+ "rulesIn": [
+ "v5"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "っちゃう",
+ "kanaOut": "つ",
+ "rulesIn": [
+ "v5"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "っちゃう",
+ "kanaOut": "る",
+ "rulesIn": [
+ "v5"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "んじゃう",
+ "kanaOut": "ぬ",
+ "rulesIn": [
+ "v5"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "んじゃう",
+ "kanaOut": "ぶ",
+ "rulesIn": [
+ "v5"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "んじゃう",
+ "kanaOut": "む",
+ "rulesIn": [
+ "v5"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ }
+ ],
+ "-nasai": [
+ {
+ "kanaIn": "なさい",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "いなさい",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きなさい",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きなさい",
+ "kanaOut": "くる",
+ "rulesIn": [],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "ぎなさい",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "しなさい",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "しなさい",
+ "kanaOut": "する",
+ "rulesIn": [],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "ちなさい",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "になさい",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "びなさい",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "みなさい",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "りなさい",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ }
+ ],
+ "-sou": [
+ {
+ "kanaIn": "そう",
+ "kanaOut": "い",
+ "rulesIn": [],
+ "rulesOut": [
+ "adj-i"
+ ]
+ },
+ {
+ "kanaIn": "そう",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "いそう",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きそう",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きそう",
+ "kanaOut": "くる",
+ "rulesIn": [],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "ぎそう",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "しそう",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "しそう",
+ "kanaOut": "する",
+ "rulesIn": [],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "ちそう",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "にそう",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "びそう",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "みそう",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "りそう",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ }
+ ],
+ "-sugiru": [
+ {
+ "kanaIn": "すぎる",
+ "kanaOut": "い",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "adj-i"
+ ]
+ },
+ {
+ "kanaIn": "すぎる",
+ "kanaOut": "る",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "いすぎる",
+ "kanaOut": "う",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きすぎる",
+ "kanaOut": "く",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きすぎる",
+ "kanaOut": "くる",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "ぎすぎる",
+ "kanaOut": "ぐ",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "しすぎる",
+ "kanaOut": "す",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "しすぎる",
+ "kanaOut": "する",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "ちすぎる",
+ "kanaOut": "つ",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "にすぎる",
+ "kanaOut": "ぬ",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "びすぎる",
+ "kanaOut": "ぶ",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "みすぎる",
+ "kanaOut": "む",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "りすぎる",
+ "kanaOut": "る",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ }
+ ],
+ "-tai": [
+ {
+ "kanaIn": "たい",
+ "kanaOut": "る",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "いたい",
+ "kanaOut": "う",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きたい",
+ "kanaOut": "く",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きたい",
+ "kanaOut": "くる",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "ぎたい",
+ "kanaOut": "ぐ",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "したい",
+ "kanaOut": "す",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "したい",
+ "kanaOut": "する",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "ちたい",
+ "kanaOut": "つ",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "にたい",
+ "kanaOut": "ぬ",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "びたい",
+ "kanaOut": "ぶ",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "みたい",
+ "kanaOut": "む",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "りたい",
+ "kanaOut": "る",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ }
+ ],
+ "-tara": [
+ {
+ "kanaIn": "たら",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "いたら",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "いだら",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きたら",
+ "kanaOut": "くる",
+ "rulesIn": [],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "したら",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "したら",
+ "kanaOut": "する",
+ "rulesIn": [],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "ったら",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ったら",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ったら",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "んだら",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "んだら",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "んだら",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "かったら",
+ "kanaOut": "い",
+ "rulesIn": [],
+ "rulesOut": [
+ "adj-i"
+ ]
+ }
+ ],
+ "-tari": [
+ {
+ "kanaIn": "たり",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "いたり",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "いだり",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きたり",
+ "kanaOut": "くる",
+ "rulesIn": [],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "したり",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "したり",
+ "kanaOut": "する",
+ "rulesIn": [],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "ったり",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ったり",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ったり",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "んだり",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "んだり",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "んだり",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "かったり",
+ "kanaOut": "い",
+ "rulesIn": [],
+ "rulesOut": [
+ "adj-i"
+ ]
+ }
+ ],
+ "-te": [
+ {
+ "kanaIn": "て",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "いて",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "いで",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きて",
+ "kanaOut": "くる",
+ "rulesIn": [],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "くて",
+ "kanaOut": "い",
+ "rulesIn": [],
+ "rulesOut": [
+ "adj-i"
+ ]
+ },
+ {
+ "kanaIn": "して",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "して",
+ "kanaOut": "する",
+ "rulesIn": [],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "って",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "って",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "って",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "って",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "んで",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "んで",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "んで",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ }
+ ],
+ "-zu": [
+ {
+ "kanaIn": "ず",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "かず",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "がず",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "こず",
+ "kanaOut": "くる",
+ "rulesIn": [],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "さず",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "せず",
+ "kanaOut": "する",
+ "rulesIn": [],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "たず",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "なず",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ばず",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "まず",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "らず",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "わず",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ }
+ ],
+ "-nu": [
+ {
+ "kanaIn": "ぬ",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "かぬ",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "がぬ",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "こぬ",
+ "kanaOut": "くる",
+ "rulesIn": [],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "さぬ",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "せぬ",
+ "kanaOut": "する",
+ "rulesIn": [],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "たぬ",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "なぬ",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ばぬ",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "まぬ",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "らぬ",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "わぬ",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ }
+ ],
+ "adv": [
+ {
+ "kanaIn": "く",
+ "kanaOut": "い",
+ "rulesIn": [],
+ "rulesOut": [
+ "adj-i"
+ ]
+ }
+ ],
+ "causative": [
+ {
+ "kanaIn": "かせる",
+ "kanaOut": "く",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "がせる",
+ "kanaOut": "ぐ",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "させる",
+ "kanaOut": "する",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "させる",
+ "kanaOut": "る",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "たせる",
+ "kanaOut": "つ",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "なせる",
+ "kanaOut": "ぬ",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ばせる",
+ "kanaOut": "ぶ",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ませる",
+ "kanaOut": "む",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "らせる",
+ "kanaOut": "る",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "わせる",
+ "kanaOut": "う",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "こさせる",
+ "kanaOut": "くる",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "vk"
+ ]
+ }
+ ],
+ "imperative": [
+ {
+ "kanaIn": "い",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "え",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "け",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "げ",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "せ",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "て",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ね",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "べ",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "め",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "よ",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "れ",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ろ",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "こい",
+ "kanaOut": "くる",
+ "rulesIn": [],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "しろ",
+ "kanaOut": "する",
+ "rulesIn": [],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "せよ",
+ "kanaOut": "する",
+ "rulesIn": [],
+ "rulesOut": [
+ "vs"
+ ]
+ }
+ ],
+ "imperative negative": [
+ {
+ "kanaIn": "な",
+ "kanaOut": "",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1",
+ "v5",
+ "vk",
+ "vs"
+ ]
+ }
+ ],
+ "masu stem": [
+ {
+ "kanaIn": "い",
+ "kanaOut": "いる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "い",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "え",
+ "kanaOut": "える",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "き",
+ "kanaOut": "きる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "き",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ぎ",
+ "kanaOut": "ぎる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "ぎ",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "け",
+ "kanaOut": "ける",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "げ",
+ "kanaOut": "げる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "し",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "じ",
+ "kanaOut": "じる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "せ",
+ "kanaOut": "せる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "ぜ",
+ "kanaOut": "ぜる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "ち",
+ "kanaOut": "ちる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "ち",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "て",
+ "kanaOut": "てる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "で",
+ "kanaOut": "でる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "に",
+ "kanaOut": "にる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "に",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ね",
+ "kanaOut": "ねる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "ひ",
+ "kanaOut": "ひる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "び",
+ "kanaOut": "びる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "び",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "へ",
+ "kanaOut": "へる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "べ",
+ "kanaOut": "べる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "み",
+ "kanaOut": "みる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "み",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "め",
+ "kanaOut": "める",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "り",
+ "kanaOut": "りる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ },
+ {
+ "kanaIn": "り",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "れ",
+ "kanaOut": "れる",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1"
+ ]
+ }
+ ],
+ "negative": [
+ {
+ "kanaIn": "ない",
+ "kanaOut": "る",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "かない",
+ "kanaOut": "く",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "がない",
+ "kanaOut": "ぐ",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "くない",
+ "kanaOut": "い",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "adj-i"
+ ]
+ },
+ {
+ "kanaIn": "こない",
+ "kanaOut": "くる",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "さない",
+ "kanaOut": "す",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "しない",
+ "kanaOut": "する",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "たない",
+ "kanaOut": "つ",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "なない",
+ "kanaOut": "ぬ",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ばない",
+ "kanaOut": "ぶ",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "まない",
+ "kanaOut": "む",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "らない",
+ "kanaOut": "る",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "わない",
+ "kanaOut": "う",
+ "rulesIn": [
+ "adj-i"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ }
+ ],
+ "noun": [
+ {
+ "kanaIn": "さ",
+ "kanaOut": "い",
+ "rulesIn": [],
+ "rulesOut": [
+ "adj-i"
+ ]
+ }
+ ],
+ "passive": [
+ {
+ "kanaIn": "かれる",
+ "kanaOut": "く",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "がれる",
+ "kanaOut": "ぐ",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "される",
+ "kanaOut": "する",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "たれる",
+ "kanaOut": "つ",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "なれる",
+ "kanaOut": "ぬ",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ばれる",
+ "kanaOut": "ぶ",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "まれる",
+ "kanaOut": "む",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "われる",
+ "kanaOut": "う",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ }
+ ],
+ "passive or causative": [
+ {
+ "kanaIn": "される",
+ "kanaOut": "す",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ }
+ ],
+ "past": [
+ {
+ "kanaIn": "た",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "いた",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "いだ",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きた",
+ "kanaOut": "くる",
+ "rulesIn": [],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "した",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "した",
+ "kanaOut": "する",
+ "rulesIn": [],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "った",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "った",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "った",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "んだ",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "んだ",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "んだ",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "かった",
+ "kanaOut": "い",
+ "rulesIn": [],
+ "rulesOut": [
+ "adj-i"
+ ]
+ }
+ ],
+ "polite": [
+ {
+ "kanaIn": "ます",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "います",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きます",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きます",
+ "kanaOut": "くる",
+ "rulesIn": [],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "ぎます",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "します",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "します",
+ "kanaOut": "する",
+ "rulesIn": [],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "ちます",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "にます",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "びます",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "みます",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ります",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ }
+ ],
+ "polite negative": [
+ {
+ "kanaIn": "ません",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "いません",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きません",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きません",
+ "kanaOut": "くる",
+ "rulesIn": [],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "ぎません",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "しません",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "しません",
+ "kanaOut": "する",
+ "rulesIn": [],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "ちません",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "にません",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "びません",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "みません",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "りません",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "くありません",
+ "kanaOut": "い",
+ "rulesIn": [],
+ "rulesOut": [
+ "adj-i"
+ ]
+ }
+ ],
+ "polite past": [
+ {
+ "kanaIn": "ました",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "いました",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きました",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きました",
+ "kanaOut": "くる",
+ "rulesIn": [],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "ぎました",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "しました",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "しました",
+ "kanaOut": "する",
+ "rulesIn": [],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "ちました",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "にました",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "びました",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "みました",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "りました",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ }
+ ],
+ "polite past negative": [
+ {
+ "kanaIn": "ませんでした",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "いませんでした",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きませんでした",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きませんでした",
+ "kanaOut": "くる",
+ "rulesIn": [],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "ぎませんでした",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "しませんでした",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "しませんでした",
+ "kanaOut": "する",
+ "rulesIn": [],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "ちませんでした",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "にませんでした",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "びませんでした",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "みませんでした",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "りませんでした",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "くありませんでした",
+ "kanaOut": "い",
+ "rulesIn": [],
+ "rulesOut": [
+ "adj-i"
+ ]
+ }
+ ],
+ "polite volitional": [
+ {
+ "kanaIn": "ましょう",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "いましょう",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きましょう",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "きましょう",
+ "kanaOut": "くる",
+ "rulesIn": [],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "ぎましょう",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "しましょう",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "しましょう",
+ "kanaOut": "する",
+ "rulesIn": [],
+ "rulesOut": [
+ "vs"
+ ]
+ },
+ {
+ "kanaIn": "ちましょう",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "にましょう",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "びましょう",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "みましょう",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "りましょう",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ }
+ ],
+ "potential": [
+ {
+ "kanaIn": "える",
+ "kanaOut": "う",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ける",
+ "kanaOut": "く",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "げる",
+ "kanaOut": "ぐ",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "せる",
+ "kanaOut": "す",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "てる",
+ "kanaOut": "つ",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ねる",
+ "kanaOut": "ぬ",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "べる",
+ "kanaOut": "ぶ",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "める",
+ "kanaOut": "む",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "れる",
+ "kanaOut": "る",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v1",
+ "v5",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "これる",
+ "kanaOut": "くる",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "vk"
+ ]
+ }
+ ],
+ "potential or passive": [
+ {
+ "kanaIn": "られる",
+ "kanaOut": "る",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "v1",
+ "v5",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "こられる",
+ "kanaOut": "くる",
+ "rulesIn": [
+ "v1"
+ ],
+ "rulesOut": [
+ "vk"
+ ]
+ }
+ ],
+ "volitional": [
+ {
+ "kanaIn": "おう",
+ "kanaOut": "う",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "こう",
+ "kanaOut": "く",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ごう",
+ "kanaOut": "ぐ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "そう",
+ "kanaOut": "す",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "とう",
+ "kanaOut": "つ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "のう",
+ "kanaOut": "ぬ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "ぼう",
+ "kanaOut": "ぶ",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "もう",
+ "kanaOut": "む",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "よう",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v1",
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "ろう",
+ "kanaOut": "る",
+ "rulesIn": [],
+ "rulesOut": [
+ "v5"
+ ]
+ },
+ {
+ "kanaIn": "こよう",
+ "kanaOut": "くる",
+ "rulesIn": [],
+ "rulesOut": [
+ "vk"
+ ]
+ },
+ {
+ "kanaIn": "しよう",
+ "kanaOut": "する",
+ "rulesIn": [],
+ "rulesOut": [
+ "vs"
+ ]
+ }
+ ]
+}
diff --git a/ext/bg/import.html b/ext/bg/guide.html
index 7f30b491..d6809139 100644
--- a/ext/bg/import.html
+++ b/ext/bg/guide.html
@@ -2,14 +2,9 @@
<html lang="en">
<head>
<meta charset="UTF-8">
- <title>Yomichan Dictionary Import</title>
+ <title>Welcome to Yomichan!</title>
<link rel="stylesheet" type="text/css" href="../lib/bootstrap-3.3.6-dist/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="../lib/bootstrap-3.3.6-dist/css/bootstrap-theme.min.css">
- <style>
- div.alert {
- display: none;
- }
- </style>
</head>
<body>
<div class="container">
@@ -20,39 +15,22 @@
<p>Thank you for downloading this extension! I sincerely hope that it will assist you on your language learning journey.</p>
<div>
- <h2>Dictionary Import</h2>
-
- <p>
- Before it can be used for the first time, Yomichan must import the Japanese dictionary data included with this extension. This process can take a
- couple of minutes to finish so please be patient! Please do not completely exit out of your browser until this process completes.
- </p>
-
- <div class="progress">
- <div class="progress-bar progress-bar-striped" style="width: 0%"></div>
- </div>
-
- <div class="alert alert-success">Dictionary import complete!</div>
- </div>
-
- <div>
<h2>Quick Guide</h2>
<p>
Please read the steps outlined below to get quickly get up and running with Yomichan. For complete documentation,
- visit the <a href="https://foosoft.net/projects/yomichan-chrome/">official homepage</a>.
+ visit the <a href="https://foosoft.net/projects/yomichan-chrome/" target="_blank">official homepage</a>.
</p>
<ol>
<li>Left-click on the <img src="../img/icon16.png" alt> icon to enable or disable Yomichan for the current browser instance.</li>
<li>Right-click on the <img src="../img/icon16.png" alt> icon and select <em>Options</em> to open the Yomichan options page.</li>
+ <li>Import any dictionaries (bundled or custom) you wish to use for Kanji and term searches.</li>
<li>Hold down <kbd>Shift</kbd> (or the middle mouse button) as you hover over text to see term definitions.</li>
<li>Resize the definitions window by dragging the bottom-left corner inwards or outwards.</li>
<li>Click on Kanji in the definition window to view additional information about that character.</li>
</ol>
</div>
</div>
-
- <script src="../lib/jquery-2.2.2.min.js"></script>
- <script src="js/import.js"></script>
</body>
</html>
diff --git a/ext/bg/img/paypal.gif b/ext/bg/img/paypal.gif
new file mode 100644
index 00000000..43cef691
--- /dev/null
+++ b/ext/bg/img/paypal.gif
Binary files differ
diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js
new file mode 100644
index 00000000..7ad7d410
--- /dev/null
+++ b/ext/bg/js/database.js
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2016 Alex Yatskov <alex@foosoft.net>
+ * Author: Alex Yatskov <alex@foosoft.net>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+class Database {
+ constructor() {
+ this.db = null;
+ this.tagMetaCache = {};
+ }
+
+ prepare() {
+ if (this.db !== null) {
+ return Promise.reject('database already initialized');
+ }
+
+ this.db = new Dexie('dict');
+ this.db.version(1).stores({
+ terms: '++id,dictionary,expression,reading',
+ kanji: '++,dictionary,character',
+ tagMeta: '++,dictionary',
+ dictionaries: '++,title,version',
+ });
+
+ return this.db.open();
+ }
+
+ purge() {
+ if (this.db === null) {
+ return Promise.reject('database not initialized');
+ }
+
+ this.db.close();
+ return this.db.delete().then(() => {
+ this.db = null;
+ this.tagMetaCache = {};
+ return this.prepare();
+ });
+ }
+
+ findTerm(term, dictionaries) {
+ if (this.db === null) {
+ return Promise.reject('database not initialized');
+ }
+
+ const results = [];
+ return this.db.terms.where('expression').equals(term).or('reading').equals(term).each(row => {
+ if (dictionaries.includes(row.dictionary)) {
+ results.push({
+ expression: row.expression,
+ reading: row.reading,
+ tags: splitField(row.tags),
+ rules: splitField(row.rules),
+ glossary: row.glossary,
+ score: row.score,
+ dictionary: row.dictionary,
+ id: row.id
+ });
+ }
+ }).then(() => {
+ return this.cacheTagMeta(dictionaries);
+ }).then(() => {
+ for (const result of results) {
+ result.tagMeta = this.tagMetaCache[result.dictionary] || {};
+ }
+
+ return results;
+ });
+ }
+
+ findKanji(kanji, dictionaries) {
+ if (this.db === null) {
+ return Promise.reject('database not initialized');
+ }
+
+ const results = [];
+ return this.db.kanji.where('character').equals(kanji).each(row => {
+ if (dictionaries.includes(row.dictionary)) {
+ results.push({
+ character: row.character,
+ onyomi: splitField(row.onyomi),
+ kunyomi: splitField(row.kunyomi),
+ tags: splitField(row.tags),
+ glossary: row.meanings,
+ dictionary: row.dictionary
+ });
+ }
+ }).then(() => {
+ return this.cacheTagMeta(dictionaries);
+ }).then(() => {
+ for (const result of results) {
+ result.tagMeta = this.tagMetaCache[result.dictionary] || {};
+ }
+
+ return results;
+ });
+ }
+
+ cacheTagMeta(dictionaries) {
+ if (this.db === null) {
+ return Promise.reject('database not initialized');
+ }
+
+ const promises = [];
+ for (const dictionary of dictionaries) {
+ if (this.tagMetaCache[dictionary]) {
+ continue;
+ }
+
+ const tagMeta = {};
+ promises.push(
+ this.db.tagMeta.where('dictionary').equals(dictionary).each(row => {
+ tagMeta[row.name] = {category: row.category, notes: row.notes, order: row.order};
+ }).then(() => {
+ this.tagMetaCache[dictionary] = tagMeta;
+ })
+ );
+ }
+
+ return Promise.all(promises);
+ }
+
+ getDictionaries() {
+ if (this.db === null) {
+ return Promise.reject('database not initialized');
+ }
+
+ return this.db.dictionaries.toArray();
+ }
+
+ deleteDictionary(title, callback) {
+ if (this.db === null) {
+ return Promise.reject('database not initialized');
+ }
+
+ return this.db.dictionaries.where('title').equals(title).first(info => {
+ if (!info) {
+ return;
+ }
+
+ let termCounter = Promise.resolve(0);
+ if (info.hasTerms) {
+ termCounter = this.db.terms.where('dictionary').equals(title).count();
+ }
+
+ let kanjiCounter = Promise.resolve(0);
+ if (info.hasKanji) {
+ kanjiCounter = this.db.kanji.where('dictionary').equals(title).count();
+ }
+
+ return Promise.all([termCounter, kanjiCounter]).then(([termCount, kanjiCount]) => {
+ const rowLimit = 500;
+ const totalCount = termCount + kanjiCount;
+ let deletedCount = 0;
+
+ let termDeleter = Promise.resolve();
+ if (info.hasTerms) {
+ const termDeleterFunc = () => {
+ return this.db.terms.where('dictionary').equals(title).limit(rowLimit).delete().then(count => {
+ if (count === 0) {
+ return Promise.resolve();
+ }
+
+ deletedCount += count;
+ if (callback) {
+ callback(totalCount, deletedCount);
+ }
+
+ return termDeleterFunc();
+ });
+ };
+
+ termDeleter = termDeleterFunc();
+ }
+
+ let kanjiDeleter = Promise.resolve();
+ if (info.hasKanji) {
+ const kanjiDeleterFunc = () => {
+ return this.db.kanji.where('dictionary').equals(title).limit(rowLimit).delete().then(count => {
+ if (count === 0) {
+ return Promise.resolve();
+ }
+
+ deletedCount += count;
+ if (callback) {
+ callback(totalCount, deletedCount);
+ }
+
+ return kanjiDeleterFunc();
+ });
+ };
+
+ kanjiDeleter = kanjiDeleterFunc();
+ }
+
+ return Promise.all([termDeleter, kanjiDeleter]);
+ });
+ }).then(() => {
+ return this.db.tagMeta.where('dictionary').equals(title).delete();
+ }).then(() => {
+ return this.db.dictionaries.where('title').equals(title).delete();
+ }).then(() => {
+ delete this.cacheTagMeta[title];
+ });
+ }
+
+ importDictionary(indexUrl, callback) {
+ if (this.db === null) {
+ return Promise.reject('database not initialized');
+ }
+
+ let summary = null;
+ const indexLoaded = (title, version, tagMeta, hasTerms, hasKanji) => {
+ summary = {title, hasTerms, hasKanji, version};
+ return this.db.dictionaries.where('title').equals(title).count().then(count => {
+ if (count > 0) {
+ return Promise.reject(`dictionary "${title}" is already imported`);
+ }
+
+ return this.db.dictionaries.add({title, version, hasTerms, hasKanji}).then(() => {
+ const rows = [];
+ for (const tag in tagMeta || {}) {
+ const meta = tagMeta[tag];
+ const row = sanitizeTag({
+ name: tag,
+ category: meta.category,
+ notes: meta.notes,
+ order: meta.order,
+ dictionary: title
+ });
+
+ rows.push(row);
+ }
+
+ return this.db.tagMeta.bulkAdd(rows);
+ });
+ });
+ };
+
+ const termsLoaded = (title, entries, total, current) => {
+ const rows = [];
+ for (const [expression, reading, tags, rules, score, ...glossary] of entries) {
+ rows.push({
+ expression,
+ reading,
+ tags,
+ rules,
+ score,
+ glossary,
+ dictionary: title
+ });
+ }
+
+ return this.db.terms.bulkAdd(rows).then(() => {
+ if (callback) {
+ callback(total, current, indexUrl);
+ }
+ });
+ };
+
+ const kanjiLoaded = (title, entries, total, current) => {
+ const rows = [];
+ for (const [character, onyomi, kunyomi, tags, ...meanings] of entries) {
+ rows.push({
+ character,
+ onyomi,
+ kunyomi,
+ tags,
+ meanings,
+ dictionary: title
+ });
+ }
+
+ return this.db.kanji.bulkAdd(rows).then(() => {
+ if (callback) {
+ callback(total, current, indexUrl);
+ }
+ });
+ };
+
+ return importJsonDb(indexUrl, indexLoaded, termsLoaded, kanjiLoaded).then(() => summary);
+ }
+}
diff --git a/ext/bg/js/deinflector.js b/ext/bg/js/deinflector.js
index 1474e56d..6e480068 100644
--- a/ext/bg/js/deinflector.js
+++ b/ext/bg/js/deinflector.js
@@ -18,50 +18,47 @@
class Deinflection {
- constructor(term, tags=[], rule='') {
- this.children = [];
+ constructor(term, {rules=[], definitions=[], reason=''} = {}) {
this.term = term;
- this.tags = tags;
- this.rule = rule;
+ this.rules = rules;
+ this.definitions = definitions;
+ this.reason = reason;
+ this.children = [];
}
- validate(validator) {
- return validator(this.term).then(sets => {
- for (const tags of sets) {
- if (this.tags.length === 0) {
- return true;
- }
-
- for (const tag of this.tags) {
- if (tags.includes(tag)) {
- return true;
+ deinflect(definer, reasons) {
+ const define = () => {
+ return definer(this.term).then(definitions => {
+ if (this.rules.length === 0) {
+ this.definitions = definitions;
+ } else {
+ for (const rule of this.rules) {
+ for (const definition of definitions) {
+ if (definition.rules.includes(rule)) {
+ this.definitions.push(definition);
+ }
+ }
}
}
- }
-
- return false;
- });
- }
- deinflect(validator, rules) {
- const promises = [
- this.validate(validator).then(valid => {
- const child = new Deinflection(this.term, this.tags);
- this.children.push(child);
- })
- ];
-
- for (const rule in rules) {
- for (const variant of rules[rule]) {
- let allowed = this.tags.length === 0;
- for (const tag of this.tags) {
- if (variant.tagsIn.includes(tag)) {
- allowed = true;
- break;
+ return this.definitions.length > 0;
+ });
+ };
+
+ const promises = [];
+ for (const reason in reasons) {
+ for (const variant of reasons[reason]) {
+ let accept = this.rules.length === 0;
+ if (!accept) {
+ for (const rule of this.rules) {
+ if (variant.rulesIn.includes(rule)) {
+ accept = true;
+ break;
+ }
}
}
- if (!allowed || !this.term.endsWith(variant.kanaIn)) {
+ if (!accept || !this.term.endsWith(variant.kanaIn)) {
continue;
}
@@ -70,55 +67,61 @@ class Deinflection {
continue;
}
- const child = new Deinflection(term, variant.tagsOut, rule);
+ const child = new Deinflection(term, {reason, rules: variant.rulesOut});
promises.push(
- child.deinflect(validator, rules).then(valid => {
- if (valid) {
- this.children.push(child);
- }
- }
- ));
+ child.deinflect(definer, reasons).then(valid => valid && this.children.push(child))
+ );
}
}
- return Promise.all(promises).then(() => {
- return this.children.length > 0;
+ return Promise.all(promises).then(define).then(valid => {
+ if (valid && this.children.length > 0) {
+ const child = new Deinflection(this.term, {rules: this.rules, definitions: this.definitions});
+ this.children.push(child);
+ }
+
+ return valid || this.children.length > 0;
});
}
gather() {
if (this.children.length === 0) {
- return [{root: this.term, tags: this.tags, rules: []}];
+ return [{
+ source: this.term,
+ rules: this.rules,
+ definitions: this.definitions,
+ reasons: [this.reason]
+ }];
}
- const paths = [];
+ const results = [];
for (const child of this.children) {
- for (const path of child.gather()) {
- if (this.rule.length > 0) {
- path.rules.push(this.rule);
+ for (const result of child.gather()) {
+ if (this.reason.length > 0) {
+ result.reasons.push(this.reason);
}
- path.source = this.term;
- paths.push(path);
+ result.source = this.term;
+ results.push(result);
}
}
- return paths;
+ return results;
}
}
class Deinflector {
constructor() {
- this.rules = {};
+ this.reasons = {};
}
- setRules(rules) {
- this.rules = rules;
+ setReasons(reasons) {
+ this.reasons = reasons;
}
- deinflect(term, validator) {
+ deinflect(term, definer) {
const node = new Deinflection(term);
- return node.deinflect(validator, this.rules).then(success => success ? node.gather() : []);
+ return node.deinflect(definer, this.reasons).then(success => success ? node.gather() : []);
}
}
diff --git a/ext/bg/js/dictionary.js b/ext/bg/js/dictionary.js
deleted file mode 100644
index 1d54190e..00000000
--- a/ext/bg/js/dictionary.js
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2016 Alex Yatskov <alex@foosoft.net>
- * Author: Alex Yatskov <alex@foosoft.net>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-class Dictionary {
- constructor() {
- this.db = null;
- this.dbVer = 2;
- this.entities = null;
- }
-
- initDb() {
- if (this.db !== null) {
- return Promise.reject('database already initialized');
- }
-
- this.db = new Dexie('dict');
- this.db.version(1).stores({
- terms: '++id,expression,reading',
- entities: '++,name',
- kanji: '++,character',
- meta: 'name,value',
- });
- }
-
- prepareDb() {
- this.initDb();
-
- return this.db.meta.get('version').then(row => {
- return row ? row.value : 0;
- }).catch(() => {
- return 0;
- }).then(version => {
- if (this.dbVer === version) {
- return true;
- }
-
- const db = this.db;
- this.db.close();
- this.db = null;
-
- return db.delete().then(() => {
- this.initDb();
- return false;
- });
- });
- }
-
- sealDb() {
- if (this.db === null) {
- return Promise.reject('database not initialized');
- }
-
- return this.db.meta.put({name: 'version', value: this.dbVer});
- }
-
- findTerm(term) {
- if (this.db === null) {
- return Promise.reject('database not initialized');
- }
-
- const results = [];
- return this.db.terms.where('expression').equals(term).or('reading').equals(term).each(row => {
- results.push({
- expression: row.expression,
- reading: row.reading,
- tags: splitField(row.tags),
- glossary: row.glossary,
- id: row.id
- });
- }).then(() => {
- return this.getEntities();
- }).then(entities => {
- for (const result of results) {
- result.entities = entities;
- }
-
- return results;
- });
- }
-
- findKanji(kanji) {
- if (this.db === null) {
- return Promise.reject('database not initialized');
- }
-
- const results = [];
- return this.db.kanji.where('character').equals(kanji).each(row => {
- results.push({
- character: row.character,
- onyomi: splitField(row.onyomi),
- kunyomi: splitField(row.kunyomi),
- tags: splitField(row.tags),
- glossary: row.meanings
- });
- }).then(() => results);
- }
-
- getEntities(tags) {
- if (this.db === null) {
- return Promise.reject('database not initialized');
- }
-
- if (this.entities !== null) {
- return Promise.resolve(this.entities);
- }
-
- return this.db.entities.toArray(rows => {
- this.entities = {};
- for (const row of rows) {
- this.entities[row.name] = row.value;
- }
-
- return this.entities;
- });
- }
-
- importTermDict(indexUrl, callback) {
- if (this.db === null) {
- return Promise.reject('database not initialized');
- }
-
- const indexDir = indexUrl.slice(0, indexUrl.lastIndexOf('/'));
- return loadJson(indexUrl).then(index => {
- const entities = [];
- for (const [name, value] of index.ents) {
- entities.push({name, value});
- }
-
- return this.db.entities.bulkAdd(entities).then(() => {
- if (this.entities === null) {
- this.entities = {};
- }
-
- for (const entity of entities) {
- this.entities[entity.name] = entity.value;
- }
- }).then(() => {
- const loaders = [];
- for (let i = 1; i <= index.banks; ++i) {
- const bankUrl = `${indexDir}/bank_${i}.json`;
- loaders.push(() => {
- return loadJson(bankUrl).then(definitions => {
- const rows = [];
- for (const [expression, reading, tags, ...glossary] of definitions) {
- rows.push({expression, reading, tags, glossary});
- }
-
- return this.db.terms.bulkAdd(rows).then(() => {
- if (callback) {
- callback(i, index.banks, indexUrl);
- }
- });
- });
- });
- }
-
- let chain = Promise.resolve();
- for (const loader of loaders) {
- chain = chain.then(loader);
- }
-
- return chain;
- });
- });
- }
-
- importKanjiDict(indexUrl, callback) {
- if (this.db === null) {
- return Promise.reject('database not initialized');
- }
-
- const indexDir = indexUrl.slice(0, indexUrl.lastIndexOf('/'));
- return loadJson(indexUrl).then(index => {
- const loaders = [];
- for (let i = 1; i <= index.banks; ++i) {
- const bankUrl = `${indexDir}/bank_${i}.json`;
- loaders.push(() => {
- return loadJson(bankUrl).then(definitions => {
- const rows = [];
- for (const [character, onyomi, kunyomi, tags, ...meanings] of definitions) {
- rows.push({character, onyomi, kunyomi, tags, meanings});
- }
-
- return this.db.kanji.bulkAdd(rows).then(() => {
- if (callback) {
- callback(i, index.banks, indexUrl);
- }
- });
- });
- });
- }
-
- let chain = Promise.resolve();
- for (const loader of loaders) {
- chain = chain.then(loader);
- }
-
- return chain;
- });
- }
-}
diff --git a/ext/bg/js/import.js b/ext/bg/js/import.js
deleted file mode 100644
index 0601cb9f..00000000
--- a/ext/bg/js/import.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 Alex Yatskov <alex@foosoft.net>
- * Author: Alex Yatskov <alex@foosoft.net>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-function api_setProgress(progress) {
- $('.progress-bar').css('width', `${progress}%`);
-
- if (progress === 100.0) {
- $('.progress').hide();
- $('.alert').show();
- }
-}
-
-chrome.runtime.onMessage.addListener(({action, params}, sender, callback) => {
- const method = this['api_' + action];
- if (typeof(method) === 'function') {
- method.call(this, params);
- }
-
- callback();
-});
diff --git a/ext/bg/js/options-form.js b/ext/bg/js/options-form.js
index eb562142..fb81e83a 100644
--- a/ext/bg/js/options-form.js
+++ b/ext/bg/js/options-form.js
@@ -16,55 +16,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+//
+// General
+//
function yomichan() {
return chrome.extension.getBackgroundPage().yomichan;
}
-function anki() {
- return yomichan().anki;
-}
-
-function fieldsToDict(selection) {
- const result = {};
- selection.each((index, element) => {
- result[$(element).data('field')] = $(element).val();
- });
-
- return result;
-}
-
-function modelIdToFieldOptKey(id) {
- return {
- 'anki-term-model': 'ankiTermFields',
- 'anki-kanji-model': 'ankiKanjiFields'
- }[id];
-}
-
-function modelIdToMarkers(id) {
- return {
- 'anki-term-model': [
- 'audio',
- 'expression',
- 'expression-furigana',
- 'glossary',
- 'glossary-list',
- 'reading',
- 'sentence',
- 'tags',
- 'url'
- ],
- 'anki-kanji-model': [
- 'character',
- 'glossary',
- 'glossary-list',
- 'kunyomi',
- 'onyomi',
- 'url'
- ],
- }[id];
-}
-
function getFormValues() {
return loadOptions().then(optsOld => {
const optsNew = $.extend({}, optsOld);
@@ -91,6 +50,14 @@ function getFormValues() {
optsNew.ankiKanjiModel = $('#anki-kanji-model').val();
optsNew.ankiKanjiFields = fieldsToDict($('#kanji .anki-field-value'));
+ $('.dict-group').each((index, element) => {
+ const dictionary = $(element);
+ const title = dictionary.data('title');
+ const enableTerms = dictionary.find('.dict-enable-terms').prop('checked');
+ const enableKanji = dictionary.find('.dict-enable-kanji').prop('checked');
+ optsNew.dictionaries[title] = {enableTerms, enableKanji};
+ });
+
return {
optsNew: sanitizeOptions(optsNew),
optsOld: sanitizeOptions(optsOld)
@@ -120,43 +87,294 @@ function updateVisibility(opts) {
}
}
-function populateAnkiDeckAndModel(opts) {
- const ankiSpinner = $('#anki-spinner');
- ankiSpinner.show();
+$(document).ready(() => {
+ Handlebars.partials = Handlebars.templates;
+
+ loadOptions().then(opts => {
+ $('#activate-on-startup').prop('checked', opts.activateOnStartup);
+ $('#enable-audio-playback').prop('checked', opts.enableAudioPlayback);
+ $('#enable-soft-katakana-search').prop('checked', opts.enableSoftKatakanaSearch);
+ $('#show-advanced-options').prop('checked', opts.showAdvancedOptions);
+
+ $('#hold-shift-to-scan').prop('checked', opts.holdShiftToScan);
+ $('#select-matched-text').prop('checked', opts.selectMatchedText);
+ $('#scan-delay').val(opts.scanDelay);
+ $('#scan-length').val(opts.scanLength);
+
+ $('#anki-method').val(opts.ankiMethod);
+ $('#anki-username').val(opts.ankiUsername);
+ $('#anki-password').val(opts.ankiPassword);
+ $('#anki-card-tags').val(opts.ankiCardTags.join(' '));
+ $('#sentence-extent').val(opts.sentenceExtent);
+
+ $('input, select').not('.anki-model').change(onOptionsChanged);
+ $('.anki-model').change(onAnkiModelChanged);
+
+ $('#dict-purge').click(onDictionaryPurge);
+ $('#dict-importer a').click(onDictionarySetUrl);
+ $('#dict-import').click(onDictionaryImport);
+ $('#dict-url').on('input', onDictionaryUpdateUrl);
- const ankiFormat = $('#anki-format');
- ankiFormat.hide();
+ populateDictionaries(opts);
+ populateAnkiDeckAndModel(opts);
+ updateVisibility(opts);
+ });
+});
- const ankiDeck = $('.anki-deck');
- ankiDeck.find('option').remove();
+//
+// Dictionary
+//
- const ankiModel = $('.anki-model');
- ankiModel.find('option').remove();
+function database() {
+ return yomichan().translator.database;
+}
- return anki().getDeckNames().then(names => {
- names.forEach(name => ankiDeck.append($('<option/>', {value: name, text: name})));
- $('#anki-term-deck').val(opts.ankiTermDeck);
- $('#anki-kanji-deck').val(opts.ankiKanjiDeck);
+function showDictionaryError(error) {
+ const dialog = $('#dict-error');
+ if (error) {
+ dialog.show().find('span').text(error);
+ } else {
+ dialog.hide();
+ }
+}
+
+function showDictionarySpinner(show) {
+ const spinner = $('#dict-spinner');
+ if (show) {
+ spinner.show();
+ } else {
+ spinner.hide();
+ }
+}
+
+function populateDictionaries(opts) {
+ showDictionaryError(null);
+ showDictionarySpinner(true);
+
+ const dictGroups = $('#dict-groups').empty();
+ const dictWarning = $('#dict-warning').hide();
+
+ let dictCount = 0;
+ return database().getDictionaries().then(rows => {
+ rows.forEach(row => {
+ const dictOpts = opts.dictionaries[row.title] || {enableTerms: false, enableKanji: false};
+ const html = Handlebars.templates['dictionary.html']({
+ title: row.title,
+ version: row.version,
+ hasTerms: row.hasTerms,
+ hasKanji: row.hasKanji,
+ enableTerms: dictOpts.enableTerms,
+ enableKanji: dictOpts.enableKanji
+ });
+
+ dictGroups.append($(html));
+ ++dictCount;
+ });
+
+ $('.dict-enable-terms, .dict-enable-kanji').change(onOptionsChanged);
+ $('.dict-delete').click(onDictionaryDelete);
+ }).catch(error => {
+ showDictionaryError(error);
}).then(() => {
- return anki().getModelNames();
- }).then(names => {
- names.forEach(name => ankiModel.append($('<option/>', {value: name, text: name})));
- return populateAnkiFields($('#anki-term-model').val(opts.ankiTermModel), opts);
+ showDictionarySpinner(false);
+ if (dictCount === 0) {
+ dictWarning.show();
+ }
+ });
+}
+
+function onDictionaryPurge(e) {
+ e.preventDefault();
+
+ showDictionaryError(null);
+ showDictionarySpinner(true);
+
+ const dictControls = $('#dict-importer, #dict-groups').hide();
+ const dictProgress = $('#dict-purge-progress').show();
+
+ return database().purge().catch(error => {
+ showDictionaryError(error);
+ }).then(() => {
+ showDictionarySpinner(false);
+ dictControls.show();
+ dictProgress.hide();
+ return loadOptions().then(opts => populateDictionaries(opts));
+ });
+}
+
+function onDictionaryDelete() {
+ showDictionaryError(null);
+ showDictionarySpinner(true);
+
+ const dictGroup = $(this).closest('.dict-group');
+ const dictProgress = dictGroup.find('.dict-delete-progress').show();
+ const dictControls = dictGroup.find('.dict-group-controls').hide();
+ const setProgress = percent => {
+ dictProgress.find('.progress-bar').css('width', `${percent}%`);
+ };
+
+ setProgress(0.0);
+
+ database().deleteDictionary(dictGroup.data('title'), (total, current) => setProgress(current / total * 100.0)).catch(error => {
+ showDictionaryError(error);
}).then(() => {
- return populateAnkiFields($('#anki-kanji-model').val(opts.ankiKanjiModel), opts);
+ showDictionarySpinner(false);
+ dictProgress.hide();
+ dictControls.show();
+ return loadOptions().then(opts => populateDictionaries(opts));
+ });
+}
+
+function onDictionaryImport() {
+ showDictionaryError(null);
+ showDictionarySpinner(true);
+
+ const dictUrl = $('#dict-url');
+ const dictImporter = $('#dict-importer').hide();
+ const dictProgress = $('#dict-import-progress').show();
+ const setProgress = percent => {
+ dictProgress.find('.progress-bar').css('width', `${percent}%`);
+ };
+
+ setProgress(0.0);
+
+ loadOptions().then(opts => {
+ database().importDictionary(dictUrl.val(), (total, current) => setProgress(current / total * 100.0)).then(summary => {
+ opts.dictionaries[summary.title] = {enableTerms: summary.hasTerms, enableKanji: summary.hasKanji};
+ return saveOptions(opts).then(() => yomichan().setOptions(opts));
+ }).then(() => {
+ return populateDictionaries(opts);
+ }).catch(error => {
+ showDictionaryError(error);
+ }).then(() => {
+ showDictionarySpinner(false);
+ dictProgress.hide();
+ dictImporter.show();
+ dictUrl.val('');
+ dictUrl.trigger('input');
+ });
+ });
+}
+
+function onDictionarySetUrl(e) {
+ e.preventDefault();
+
+ const dictUrl = $('#dict-url');
+ const url = $(this).data('url');
+ if (url.includes('/')) {
+ dictUrl.val(url);
+ } else {
+ dictUrl.val(chrome.extension.getURL(`bg/data/${url}/index.json`));
+ }
+
+ dictUrl.trigger('input');
+}
+
+function onDictionaryUpdateUrl() {
+ $('#dict-import').prop('disabled', $(this).val().length === 0);
+}
+
+//
+// Anki
+//
+
+function anki() {
+ return yomichan().anki;
+}
+
+function showAnkiSpinner(show) {
+ const spinner = $('#anki-spinner');
+ if (show) {
+ spinner.show();
+ } else {
+ spinner.hide();
+ }
+}
+
+function showAnkiError(error) {
+ const dialog = $('#anki-error');
+ if (error) {
+ dialog.show().find('span').text(error);
+ }
+ else {
+ dialog.hide();
+ }
+}
+
+function fieldsToDict(selection) {
+ const result = {};
+ selection.each((index, element) => {
+ result[$(element).data('field')] = $(element).val();
+ });
+
+ return result;
+}
+
+function modelIdToFieldOptKey(id) {
+ return {
+ 'anki-term-model': 'ankiTermFields',
+ 'anki-kanji-model': 'ankiKanjiFields'
+ }[id];
+}
+
+function modelIdToMarkers(id) {
+ return {
+ 'anki-term-model': [
+ 'audio',
+ 'expression',
+ 'expression-furigana',
+ 'glossary',
+ 'glossary-list',
+ 'reading',
+ 'sentence',
+ 'tags',
+ 'url'
+ ],
+ 'anki-kanji-model': [
+ 'character',
+ 'glossary',
+ 'glossary-list',
+ 'kunyomi',
+ 'onyomi',
+ 'url'
+ ],
+ }[id];
+}
+
+function populateAnkiDeckAndModel(opts) {
+ showAnkiError(null);
+ showAnkiSpinner(true);
+
+ const ankiFormat = $('#anki-format').hide();
+
+ return Promise.all([anki().getDeckNames(), anki().getModelNames()]).then(([deckNames, modelNames]) => {
+ const ankiDeck = $('.anki-deck');
+ ankiDeck.find('option').remove();
+ deckNames.forEach(name => ankiDeck.append($('<option/>', {value: name, text: name})));
+
+ $('#anki-term-deck').val(opts.ankiTermDeck);
+ $('#anki-kanji-deck').val(opts.ankiKanjiDeck);
+
+ const ankiModel = $('.anki-model');
+ ankiModel.find('option').remove();
+ modelNames.forEach(name => ankiModel.append($('<option/>', {value: name, text: name})));
+
+ return Promise.all([
+ populateAnkiFields($('#anki-term-model').val(opts.ankiTermModel), opts),
+ populateAnkiFields($('#anki-kanji-model').val(opts.ankiKanjiModel), opts)
+ ]);
}).then(() => {
- $('#anki-error').hide();
ankiFormat.show();
}).catch(error => {
- $('#anki-error').show().find('span').text(error);
+ showAnkiError(error);
}).then(() => {
- ankiSpinner.hide();
+ showAnkiSpinner(false);
});
}
function populateAnkiFields(element, opts) {
- const table = element.closest('.tab-pane').find('.anki-fields');
- table.find('tbody').remove();
+ const tab = element.closest('.tab-pane');
+ const container = tab.find('tbody').empty();
const modelName = element.val();
if (modelName === null) {
@@ -168,41 +386,37 @@ function populateAnkiFields(element, opts) {
const markers = modelIdToMarkers(modelId);
return anki().getModelFieldNames(modelName).then(names => {
- const tbody = $('<tbody>');
names.forEach(name => {
- const button = $('<button>', {type: 'button', class: 'btn btn-default dropdown-toggle'});
- button.attr('data-toggle', 'dropdown').dropdown();
-
- const markerItems = $('<ul>', {class: 'dropdown-menu dropdown-menu-right'});
- for (const marker of markers) {
- const link = $('<a>', {href: '#'}).text(`{${marker}}`);
- link.click(e => {
- e.preventDefault();
- link.closest('.input-group').find('.anki-field-value').val(link.text()).trigger('change');
- });
- markerItems.append($('<li>').append(link));
- }
+ const html = Handlebars.templates['model.html']({name, markers, value: opts[optKey][name] || ''});
+ container.append($(html));
+ });
- const groupBtn = $('<div>', {class: 'input-group-btn'});
- groupBtn.append(button.append($('<span>', {class: 'caret'})));
- groupBtn.append(markerItems);
+ tab.find('.anki-field-value').change(onOptionsChanged);
+ tab.find('.marker-link').click(e => {
+ e.preventDefault();
+ const link = e.target;
+ $(link).closest('.input-group').find('.anki-field-value').val(`{${link.text}}`).trigger('change');
+ });
+ });
+}
- const group = $('<div>', {class: 'input-group'});
- group.append($('<input>', {
- type: 'text',
- class: 'anki-field-value form-control',
- value: opts[optKey][name] || ''
- }).data('field', name).change(onOptionsChanged));
- group.append(groupBtn);
+function onAnkiModelChanged(e) {
+ if (!e.originalEvent) {
+ return;
+ }
- const row = $('<tr>');
- row.append($('<td>', {class: 'col-sm-2'}).text(name));
- row.append($('<td>', {class: 'col-sm-10'}).append(group));
+ showAnkiError(null);
+ showAnkiSpinner(true);
- tbody.append(row);
+ getFormValues().then(({optsNew, optsOld}) => {
+ optsNew[modelIdToFieldOptKey($(this).id)] = {};
+ populateAnkiFields($(this), optsNew).then(() => {
+ saveOptions(optsNew).then(() => yomichan().setOptions(optsNew));
+ }).catch(error => {
+ showAnkiError(error);
+ }).then(() => {
+ showAnkiSpinner(false);
});
-
- table.append(tbody);
});
}
@@ -212,7 +426,7 @@ function onOptionsChanged(e) {
}
getFormValues().then(({optsNew, optsOld}) => {
- saveOptions(optsNew).then(() => {
+ return saveOptions(optsNew).then(() => {
yomichan().setOptions(optsNew);
updateVisibility(optsNew);
@@ -221,60 +435,18 @@ function onOptionsChanged(e) {
optsNew.ankiPassword !== optsOld.ankiPassword;
if (loginChanged && optsNew.ankiMethod === 'ankiweb') {
- anki().logout().then(() => populateAnkiDeckAndModel(optsNew)).catch(error => {
- $('#anki-error').show().find('span').text(error);
- });
+ showAnkiError(null);
+ showAnkiSpinner(true);
+ return anki().logout().then(() => populateAnkiDeckAndModel(optsNew));
} else if (loginChanged || optsNew.ankiMethod !== optsOld.ankiMethod) {
- populateAnkiDeckAndModel(optsNew);
+ showAnkiError(null);
+ showAnkiSpinner(true);
+ return populateAnkiDeckAndModel(optsNew);
}
});
+ }).catch(error => {
+ showAnkiError(error);
+ }).then(() => {
+ showAnkiSpinner(false);
});
}
-
-function onAnkiModelChanged(e) {
- if (!e.originalEvent) {
- return;
- }
-
- getFormValues().then(({optsNew, optsOld}) => {
- optsNew[modelIdToFieldOptKey($(this).id)] = {};
-
- const ankiSpinner = $('#anki-spinner');
- ankiSpinner.show();
-
- populateAnkiFields($(this), optsNew).then(() => {
- saveOptions(optsNew).then(() => yomichan().setOptions(optsNew));
- }).catch(error => {
- $('#anki-error').show().find('span').text(error);
- }).then(() => {
- $('#anki-error').hide();
- ankiSpinner.hide();
- });
- });
-}
-
-$(document).ready(() => {
- loadOptions().then(opts => {
- $('#activate-on-startup').prop('checked', opts.activateOnStartup);
- $('#enable-audio-playback').prop('checked', opts.enableAudioPlayback);
- $('#enable-soft-katakana-search').prop('checked', opts.enableSoftKatakanaSearch);
- $('#show-advanced-options').prop('checked', opts.showAdvancedOptions);
-
- $('#hold-shift-to-scan').prop('checked', opts.holdShiftToScan);
- $('#select-matched-text').prop('checked', opts.selectMatchedText);
- $('#scan-delay').val(opts.scanDelay);
- $('#scan-length').val(opts.scanLength);
-
- $('#anki-method').val(opts.ankiMethod);
- $('#anki-username').val(opts.ankiUsername);
- $('#anki-password').val(opts.ankiPassword);
- $('#anki-card-tags').val(opts.ankiCardTags.join(' '));
- $('#sentence-extent').val(opts.sentenceExtent);
-
- $('input, select').not('.anki-model').change(onOptionsChanged);
- $('.anki-model').change(onAnkiModelChanged);
-
- populateAnkiDeckAndModel(opts);
- updateVisibility(opts);
- });
-});
diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js
index 15288afc..28448b96 100644
--- a/ext/bg/js/options.js
+++ b/ext/bg/js/options.js
@@ -28,6 +28,8 @@ function sanitizeOptions(options) {
scanDelay: 15,
scanLength: 20,
+ dictionaries: {},
+
ankiMethod: 'disabled',
ankiUsername: '',
ankiPassword: '',
diff --git a/ext/bg/js/templates.js b/ext/bg/js/templates.js
index 70920cec..1480bb17 100644
--- a/ext/bg/js/templates.js
+++ b/ext/bg/js/templates.js
@@ -1,5 +1,36 @@
(function() {
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
+templates['dictionary.html'] = template({"1":function(container,depth0,helpers,partials,data) {
+ return "disabled";
+},"3":function(container,depth0,helpers,partials,data) {
+ return "checked";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+ var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return "<div class=\"dict-group well well-sm\" data-title=\""
+ + alias4(((helper = (helper = helpers.title || (depth0 != null ? depth0.title : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"title","hash":{},"data":data}) : helper)))
+ + "\">\n <h4><span class=\"text-muted glyphicon glyphicon-book\"></span> "
+ + alias4(((helper = (helper = helpers.title || (depth0 != null ? depth0.title : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"title","hash":{},"data":data}) : helper)))
+ + " <small>v."
+ + alias4(((helper = (helper = helpers.version || (depth0 != null ? depth0.version : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"version","hash":{},"data":data}) : helper)))
+ + "</small></h4>\n\n <!-- <div class=\"row\"> -->\n <!-- <div class=\"col-xs-8\"> -->\n <!-- <h4><span class=\"text-muted glyphicon glyphicon-book\"></span> "
+ + alias4(((helper = (helper = helpers.title || (depth0 != null ? depth0.title : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"title","hash":{},"data":data}) : helper)))
+ + " <small>v."
+ + alias4(((helper = (helper = helpers.version || (depth0 != null ? depth0.version : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"version","hash":{},"data":data}) : helper)))
+ + "</small></h4> -->\n <!-- </div> -->\n <!-- <div class=\"col-xs-4 text-right disabled\"> -->\n <!-- <button type=\"button\" class=\"dict-group-controls dict-delete btn btn-danger\">Delete</button> -->\n <!-- </div> -->\n <!-- </div> -->\n\n <div class=\"dict-delete-progress\">\n Dictionary data is being deleted, please be patient...\n <div class=\"progress\">\n <div class=\"progress-bar progress-bar-striped progress-bar-danger\" style=\"width: 0%\"></div>\n </div>\n </div>\n\n <div class=\"checkbox dict-group-controls "
+ + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.hasTerms : depth0),{"name":"unless","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + "\">\n <label><input type=\"checkbox\" class=\"dict-enable-terms\" "
+ + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.hasTerms : depth0),{"name":"unless","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + " "
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.enableTerms : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + "> Enable term search</label>\n </div>\n <div class=\"checkbox dict-group-controls "
+ + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.hasKanji : depth0),{"name":"unless","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + "\">\n <label><input type=\"checkbox\" class=\"dict-enable-kanji\" "
+ + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.hasKanji : depth0),{"name":"unless","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + " "
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.enableKanji : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + "> Enable Kanji search</label>\n </div>\n</div>\n";
+},"useData":true});
templates['footer.html'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var helper;
@@ -39,16 +70,28 @@ templates['kanji.html'] = template({"1":function(container,depth0,helpers,partia
var helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
return " <span class=\"tag tag-"
- + alias4(((helper = (helper = helpers["class"] || (depth0 != null ? depth0["class"] : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"class","hash":{},"data":data}) : helper)))
+ + alias4(((helper = (helper = helpers.category || (depth0 != null ? depth0.category : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"category","hash":{},"data":data}) : helper)))
+ "\" title=\""
- + alias4(((helper = (helper = helpers.desc || (depth0 != null ? depth0.desc : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"desc","hash":{},"data":data}) : helper)))
+ + alias4(((helper = (helper = helpers.notes || (depth0 != null ? depth0.notes : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"notes","hash":{},"data":data}) : helper)))
+ "\">"
+ alias4(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data}) : helper)))
+ "</span>\n";
},"8":function(container,depth0,helpers,partials,data) {
+ var stack1;
+
+ return " <ol>\n"
+ + ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.glossary : depth0),{"name":"each","hash":{},"fn":container.program(9, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + " </ol>\n";
+},"9":function(container,depth0,helpers,partials,data) {
return " <li><span>"
+ container.escapeExpression(container.lambda(depth0, depth0))
+ "</span></li>\n";
+},"11":function(container,depth0,helpers,partials,data) {
+ var stack1;
+
+ return " <p>\n "
+ + container.escapeExpression(container.lambda(((stack1 = (depth0 != null ? depth0.glossary : depth0)) != null ? stack1["0"] : stack1), depth0))
+ + "\n </p>\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
@@ -64,9 +107,9 @@ templates['kanji.html'] = template({"1":function(container,depth0,helpers,partia
+ ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.onyomi : depth0),{"name":"each","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ " </td>\n </tr>\n </table>\n </div>\n\n <div class=\"kanji-tags\">\n"
+ ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.tags : depth0),{"name":"each","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
- + " </div>\n\n <div class=\"kanji-glossary\">\n <ol>\n"
- + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.glossary : depth0),{"name":"each","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
- + " </ol>\n </div>\n</div>\n";
+ + " </div>\n\n <div class=\"kanji-glossary\">\n"
+ + ((stack1 = helpers["if"].call(alias1,((stack1 = (depth0 != null ? depth0.glossary : depth0)) != null ? stack1["1"] : stack1),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.program(11, data, 0),"data":data})) != null ? stack1 : "")
+ + " </div>\n</div>\n";
},"useData":true});
templates['kanji-link.html'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var helper;
@@ -78,14 +121,37 @@ templates['kanji-link.html'] = template({"compiler":[7,">= 4.0.0"],"main":functi
templates['kanji-list.html'] = template({"1":function(container,depth0,helpers,partials,data,blockParams,depths) {
var stack1;
- return ((stack1 = container.invokePartial(partials["kanji.html"],depth0,{"name":"kanji.html","hash":{"sequence":(depths[1] != null ? depths[1].sequence : depths[1]),"options":(depths[1] != null ? depths[1].options : depths[1]),"root":(depths[1] != null ? depths[1].root : depths[1]),"addable":(depths[1] != null ? depths[1].addable : depths[1])},"data":data,"helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "");
+ return ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.definitions : depth0),{"name":"each","hash":{},"fn":container.program(2, data, 0, blockParams, depths),"inverse":container.noop,"data":data})) != null ? stack1 : "");
+},"2":function(container,depth0,helpers,partials,data,blockParams,depths) {
+ var stack1;
+
+ return ((stack1 = container.invokePartial(partials["kanji.html"],depth0,{"name":"kanji.html","hash":{"sequence":(depths[1] != null ? depths[1].sequence : depths[1]),"options":(depths[1] != null ? depths[1].options : depths[1]),"root":(depths[1] != null ? depths[1].root : depths[1]),"addable":(depths[1] != null ? depths[1].addable : depths[1])},"data":data,"indent":" ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "");
+},"4":function(container,depth0,helpers,partials,data) {
+ return " <p>No results found</p>\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data,blockParams,depths) {
var stack1;
return ((stack1 = container.invokePartial(partials["header.html"],depth0,{"name":"header.html","data":data,"helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
- + ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.definitions : depth0),{"name":"each","hash":{},"fn":container.program(1, data, 0, blockParams, depths),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.definitions : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0, blockParams, depths),"inverse":container.program(4, data, 0, blockParams, depths),"data":data})) != null ? stack1 : "")
+ ((stack1 = container.invokePartial(partials["footer.html"],depth0,{"name":"footer.html","data":data,"helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "");
},"usePartial":true,"useData":true,"useDepths":true});
+templates['model.html'] = template({"1":function(container,depth0,helpers,partials,data) {
+ return " <li><a class=\"marker-link\" href=\"#\">"
+ + container.escapeExpression(container.lambda(depth0, depth0))
+ + "</a></li>\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+ var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return "<tr>\n <td class=\"col-sm-2\">"
+ + alias4(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data}) : helper)))
+ + "</td>\n <td class=\"col-sm-10\">\n <div class=\"input-group\">\n <input type=\"text\" class=\"anki-field-value form-control\" data-field=\""
+ + alias4(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data}) : helper)))
+ + "\" value=\""
+ + alias4(((helper = (helper = helpers.value || (depth0 != null ? depth0.value : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"value","hash":{},"data":data}) : helper)))
+ + "\">\n <div class=\"input-group-btn\">\n <button type=\"button\" class=\"btn btn-default dropdown-toggle\" data-toggle=\"dropdown\">\n <span class=\"caret\"></span>\n </button>\n <ul class=\"dropdown-menu dropdown-menu-right\">\n"
+ + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.markers : depth0),{"name":"each","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + " </ul>\n </div>\n </div>\n </td>\n</tr>\n";
+},"useData":true});
templates['term.html'] = template({"1":function(container,depth0,helpers,partials,data) {
var helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
@@ -129,7 +195,7 @@ templates['term.html'] = template({"1":function(container,depth0,helpers,partial
},"10":function(container,depth0,helpers,partials,data) {
var stack1;
- return " <span class=\"rule\">"
+ return " <span class=\"reasons\">"
+ container.escapeExpression(container.lambda(depth0, depth0))
+ "</span> "
+ ((stack1 = helpers.unless.call(depth0 != null ? depth0 : {},(data && data.last),{"name":"unless","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
@@ -140,16 +206,28 @@ templates['term.html'] = template({"1":function(container,depth0,helpers,partial
var helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
return " <span class=\"tag tag-"
- + alias4(((helper = (helper = helpers["class"] || (depth0 != null ? depth0["class"] : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"class","hash":{},"data":data}) : helper)))
+ + alias4(((helper = (helper = helpers.category || (depth0 != null ? depth0.category : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"category","hash":{},"data":data}) : helper)))
+ "\" title=\""
- + alias4(((helper = (helper = helpers.desc || (depth0 != null ? depth0.desc : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"desc","hash":{},"data":data}) : helper)))
+ + alias4(((helper = (helper = helpers.notes || (depth0 != null ? depth0.notes : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"notes","hash":{},"data":data}) : helper)))
+ "\">"
+ alias4(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data}) : helper)))
+ "</span>\n";
},"15":function(container,depth0,helpers,partials,data) {
+ var stack1;
+
+ return " <ol>\n"
+ + ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.glossary : depth0),{"name":"each","hash":{},"fn":container.program(16, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + " </ol>\n";
+},"16":function(container,depth0,helpers,partials,data) {
return " <li><span>"
+ container.escapeExpression(container.lambda(depth0, depth0))
+ "</span></li>\n";
+},"18":function(container,depth0,helpers,partials,data) {
+ var stack1;
+
+ return " <p>"
+ + container.escapeExpression(container.lambda(((stack1 = (depth0 != null ? depth0.glossary : depth0)) != null ? stack1["0"] : stack1), depth0))
+ + "</p>\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : {};
@@ -160,23 +238,29 @@ templates['term.html'] = template({"1":function(container,depth0,helpers,partial
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.addable : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ " </div>\n\n"
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.reading : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.program(8, data, 0),"data":data})) != null ? stack1 : "")
- + "\n <div class=\"term-rules\">\n"
- + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.rules : depth0),{"name":"each","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + "\n <div class=\"term-reasons\">\n"
+ + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.reasons : depth0),{"name":"each","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ " </div>\n\n <div class=\"term-tags\">\n"
+ ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.tags : depth0),{"name":"each","hash":{},"fn":container.program(13, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
- + " </div>\n\n <div class=\"term-glossary\">\n <ol>\n"
- + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.glossary : depth0),{"name":"each","hash":{},"fn":container.program(15, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
- + " </ol>\n </div>\n</div>\n";
+ + " </div>\n\n <div class=\"term-glossary\">\n"
+ + ((stack1 = helpers["if"].call(alias1,((stack1 = (depth0 != null ? depth0.glossary : depth0)) != null ? stack1["1"] : stack1),{"name":"if","hash":{},"fn":container.program(15, data, 0),"inverse":container.program(18, data, 0),"data":data})) != null ? stack1 : "")
+ + " </div>\n</div>\n";
},"useData":true});
templates['term-list.html'] = template({"1":function(container,depth0,helpers,partials,data,blockParams,depths) {
var stack1;
- return ((stack1 = container.invokePartial(partials["term.html"],depth0,{"name":"term.html","hash":{"sequence":(depths[1] != null ? depths[1].sequence : depths[1]),"options":(depths[1] != null ? depths[1].options : depths[1]),"root":(depths[1] != null ? depths[1].root : depths[1]),"addable":(depths[1] != null ? depths[1].addable : depths[1])},"data":data,"helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "");
+ return ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.definitions : depth0),{"name":"each","hash":{},"fn":container.program(2, data, 0, blockParams, depths),"inverse":container.noop,"data":data})) != null ? stack1 : "");
+},"2":function(container,depth0,helpers,partials,data,blockParams,depths) {
+ var stack1;
+
+ return ((stack1 = container.invokePartial(partials["term.html"],depth0,{"name":"term.html","hash":{"sequence":(depths[1] != null ? depths[1].sequence : depths[1]),"options":(depths[1] != null ? depths[1].options : depths[1]),"root":(depths[1] != null ? depths[1].root : depths[1]),"addable":(depths[1] != null ? depths[1].addable : depths[1])},"data":data,"indent":" ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "");
+},"4":function(container,depth0,helpers,partials,data) {
+ return " <p>No results found</p>\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data,blockParams,depths) {
var stack1;
return ((stack1 = container.invokePartial(partials["header.html"],depth0,{"name":"header.html","data":data,"helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
- + ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.definitions : depth0),{"name":"each","hash":{},"fn":container.program(1, data, 0, blockParams, depths),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.definitions : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0, blockParams, depths),"inverse":container.program(4, data, 0, blockParams, depths),"data":data})) != null ? stack1 : "")
+ ((stack1 = container.invokePartial(partials["footer.html"],depth0,{"name":"footer.html","data":data,"helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "");
},"usePartial":true,"useData":true,"useDepths":true});
})(); \ No newline at end of file
diff --git a/ext/bg/js/translator.js b/ext/bg/js/translator.js
index 44f37e31..f29b90c9 100644
--- a/ext/bg/js/translator.js
+++ b/ext/bg/js/translator.js
@@ -20,96 +20,33 @@
class Translator {
constructor() {
this.loaded = false;
- this.tagMeta = null;
- this.dictionary = new Dictionary();
+ this.ruleMeta = null;
+ this.database = new Database();
this.deinflector = new Deinflector();
}
- loadData(callback) {
+ prepare() {
if (this.loaded) {
return Promise.resolve();
}
- return loadJson('bg/data/rules.json').then(rules => {
- this.deinflector.setRules(rules);
- return loadJson('bg/data/tags.json');
- }).then(tagMeta => {
- this.tagMeta = tagMeta;
- return this.dictionary.prepareDb();
- }).then(exists => {
- if (exists) {
- return;
- }
-
- if (callback) {
- callback({state: 'begin', progress: 0});
- }
-
- const banks = {};
- const bankCallback = (loaded, total, indexUrl) => {
- banks[indexUrl] = {loaded, total};
-
- let percent = 0.0;
- for (const url in banks) {
- percent += banks[url].loaded / banks[url].total;
- }
+ const promises = [
+ loadJsonInt('bg/data/deinflect.json'),
+ this.database.prepare()
+ ];
- percent /= 3.0;
-
- if (callback) {
- callback({state: 'update', progress: Math.ceil(100.0 * percent)});
- }
- };
-
- return Promise.all([
- this.dictionary.importTermDict('bg/data/edict/index.json', bankCallback),
- this.dictionary.importTermDict('bg/data/enamdict/index.json', bankCallback),
- this.dictionary.importKanjiDict('bg/data/kanjidic/index.json', bankCallback),
- ]).then(() => {
- return this.dictionary.sealDb();
- }).then(() => {
- if (callback) {
- callback({state: 'end', progress: 100.0});
- }
- });
- }).then(() => {
+ return Promise.all(promises).then(([reasons]) => {
+ this.deinflector.setReasons(reasons);
this.loaded = true;
});
}
- findTermGroups(text) {
- const deinflectGroups = {};
- const deinflectPromises = [];
-
- for (let i = text.length; i > 0; --i) {
- deinflectPromises.push(
- this.deinflector.deinflect(text.slice(0, i), term => {
- return this.dictionary.findTerm(term).then(definitions => definitions.map(definition => definition.tags));
- }).then(deinflects => {
- const processPromises = [];
- for (const deinflect of deinflects) {
- processPromises.push(this.processTerm(
- deinflectGroups,
- deinflect.source,
- deinflect.tags,
- deinflect.rules,
- deinflect.root
- ));
- }
-
- return Promise.all(processPromises);
- })
- );
- }
-
- return Promise.all(deinflectPromises).then(() => deinflectGroups);
- }
-
- findTerm(text, enableSoftKatakanaSearch) {
- return this.findTermGroups(text).then(groups => {
+ findTerm(text, dictionaries, enableSoftKatakanaSearch) {
+ const cache = {};
+ return this.findDeinflectionGroups(text, dictionaries, cache).then(groups => {
const textHiragana = wanakana._katakanaToHiragana(text);
if (text !== textHiragana && enableSoftKatakanaSearch) {
- return this.findTermGroups(textHiragana).then(groupsHiragana => {
+ return this.findDeinflectionGroups(textHiragana, dictionaries, cache).then(groupsHiragana => {
for (const key in groupsHiragana) {
groups[key] = groups[key] || groupsHiragana[key];
}
@@ -137,13 +74,11 @@ class Translator {
});
}
- findKanji(text) {
- const processed = {};
- const promises = [];
-
+ findKanji(text, dictionaries) {
+ const processed = {}, promises = [];
for (const c of text) {
if (!processed[c]) {
- promises.push(this.dictionary.findKanji(c).then((definitions) => definitions));
+ promises.push(this.database.findKanji(c, dictionaries));
processed[c] = true;
}
}
@@ -151,73 +86,53 @@ class Translator {
return Promise.all(promises).then(sets => this.processKanji(sets.reduce((a, b) => a.concat(b), [])));
}
- processTerm(groups, source, tags, rules, root) {
- return this.dictionary.findTerm(root).then(definitions => {
- for (const definition of definitions) {
- if (definition.id in groups) {
- continue;
- }
-
- let matched = tags.length === 0;
- for (const tag of tags) {
- if (definition.tags.includes(tag)) {
- matched = true;
- break;
- }
- }
-
- if (!matched) {
- continue;
- }
-
- const tagItems = [];
- for (const tag of definition.tags) {
- const tagItem = {
- name: tag,
- class: 'default',
- order: Number.MAX_SAFE_INTEGER,
- score: 0,
- desc: definition.entities[tag] || '',
- };
-
- applyTagMeta(tagItem, this.tagMeta);
- tagItems.push(tagItem);
- }
-
- let score = 0;
- for (const tagItem of tagItems) {
- score += tagItem.score;
- }
-
- groups[definition.id] = {
- score,
- source,
- rules,
- expression: definition.expression,
- reading: definition.reading,
- glossary: definition.glossary,
- tags: sortTags(tagItems)
- };
+ findDeinflectionGroups(text, dictionaries, cache) {
+ const definer = term => {
+ if (cache.hasOwnProperty(term)) {
+ return Promise.resolve(cache[term]);
}
- });
+
+ return this.database.findTerm(term, dictionaries).then(definitions => cache[term] = definitions);
+ };
+
+ const groups = {}, promises = [];
+ for (let i = text.length; i > 0; --i) {
+ promises.push(
+ this.deinflector.deinflect(text.slice(0, i), definer).then(deinflections => {
+ for (const deinflection of deinflections) {
+ this.processDeinflection(groups, deinflection);
+ }
+ })
+ );
+ }
+
+ return Promise.all(promises).then(() => groups);
}
- processKanji(definitions) {
+ processDeinflection(groups, {source, rules, reasons, definitions}, dictionaries) {
for (const definition of definitions) {
- const tagItems = [];
- for (const tag of definition.tags) {
- const tagItem = {
- name: tag,
- class: 'default',
- order: Number.MAX_SAFE_INTEGER,
- desc: '',
- };
-
- applyTagMeta(tagItem, this.tagMeta);
- tagItems.push(tagItem);
+ if (definition.id in groups) {
+ continue;
}
- definition.tags = sortTags(tagItems);
+ const tags = definition.tags.map(tag => buildTag(tag, definition.tagMeta));
+ groups[definition.id] = {
+ source,
+ reasons,
+ score: definition.score,
+ dictionary: definition.dictionary,
+ expression: definition.expression,
+ reading: definition.reading,
+ glossary: definition.glossary,
+ tags: sortTags(tags)
+ };
+ }
+ }
+
+ processKanji(definitions) {
+ for (const definition of definitions) {
+ const tags = definition.tags.map(tag => buildTag(tag, definition.tagMeta));
+ definition.tags = sortTags(tags);
}
return definitions;
diff --git a/ext/bg/js/util.js b/ext/bg/js/util.js
index 4e0cc671..a0fca270 100644
--- a/ext/bg/js/util.js
+++ b/ext/bg/js/util.js
@@ -39,19 +39,11 @@ function promiseCallback(promise, callback) {
return promise.then(result => {
callback({result});
}).catch(error => {
+ console.log(error);
callback({error});
});
}
-function loadJson(url) {
- return new Promise((resolve, reject) => {
- const xhr = new XMLHttpRequest();
- xhr.addEventListener('load', () => resolve(JSON.parse(xhr.responseText)));
- xhr.open('GET', chrome.extension.getURL(url));
- xhr.send();
- });
-}
-
function sortTags(tags) {
return tags.sort((v1, v2) => {
const order1 = v1.order;
@@ -92,8 +84,8 @@ function sortTermDefs(definitions) {
return 1;
}
- const rl1 = v1.rules.length;
- const rl2 = v2.rules.length;
+ const rl1 = v1.reasons.length;
+ const rl2 = v2.reasons.length;
if (rl1 < rl2) {
return -1;
} else if (rl1 > rl2) {
@@ -104,15 +96,97 @@ function sortTermDefs(definitions) {
});
}
-function applyTagMeta(tag, meta) {
- const symbol = tag.name.split(':')[0];
+function buildTag(name, meta) {
+ const tag = {name};
+ const symbol = name.split(':')[0];
for (const prop in meta[symbol] || {}) {
tag[prop] = meta[symbol][prop];
}
+ return sanitizeTag(tag);
+}
+
+function sanitizeTag(tag) {
+ tag.name = tag.name || 'untitled';
+ tag.category = tag.category || 'default';
+ tag.notes = tag.notes || '';
+ tag.order = tag.order || 0;
return tag;
}
function splitField(field) {
return field.length === 0 ? [] : field.split(' ');
}
+
+function loadJson(url) {
+ return new Promise((resolve, reject) => {
+ const xhr = new XMLHttpRequest();
+ xhr.addEventListener('load', () => resolve(xhr.responseText));
+ xhr.addEventListener('error', () => reject('failed to execute network request'));
+ xhr.open('GET', url);
+ xhr.send();
+ }).then(responseText => {
+ try {
+ return JSON.parse(responseText);
+ }
+ catch (e) {
+ return Promise.reject('invalid JSON response');
+ }
+ });
+}
+
+function loadJsonInt(url) {
+ return loadJson(chrome.extension.getURL(url));
+}
+
+function importJsonDb(indexUrl, indexLoaded, termsLoaded, kanjiLoaded) {
+ const indexDir = indexUrl.slice(0, indexUrl.lastIndexOf('/'));
+ return loadJson(indexUrl).then(index => {
+ if (!index.title || !index.version) {
+ return Promise.reject('unrecognized dictionary format');
+ }
+
+ if (indexLoaded !== null) {
+ return indexLoaded(
+ index.title,
+ index.version,
+ index.tagMeta,
+ index.termBanks > 0,
+ index.kanjiBanks > 0
+ ).then(() => index);
+ }
+
+ return index;
+ }).then(index => {
+ const loaders = [];
+ const banksTotal = index.termBanks + index.kanjiBanks;
+ let banksLoaded = 0;
+
+ for (let i = 1; i <= index.termBanks; ++i) {
+ const bankUrl = `${indexDir}/term_bank_${i}.json`;
+ loaders.push(() => loadJson(bankUrl).then(entries => termsLoaded(
+ index.title,
+ entries,
+ banksTotal,
+ banksLoaded++
+ )));
+ }
+
+ for (let i = 1; i <= index.kanjiBanks; ++i) {
+ const bankUrl = `${indexDir}/kanji_bank_${i}.json`;
+ loaders.push(() => loadJson(bankUrl).then(entries => kanjiLoaded(
+ index.title,
+ entries,
+ banksTotal,
+ banksLoaded++
+ )));
+ }
+
+ let chain = Promise.resolve();
+ for (const loader of loaders) {
+ chain = chain.then(loader);
+ }
+
+ return chain;
+ });
+}
diff --git a/ext/bg/js/yomichan.js b/ext/bg/js/yomichan.js
index 7bca579d..e8956057 100644
--- a/ext/bg/js/yomichan.js
+++ b/ext/bg/js/yomichan.js
@@ -25,11 +25,11 @@ class Yomichan {
this.translator = new Translator();
this.anki = new AnkiNull();
this.options = null;
- this.importTabId = null;
this.setState('disabled');
chrome.runtime.onMessage.addListener(this.onMessage.bind(this));
chrome.browserAction.onClicked.addListener(this.onBrowserAction.bind(this));
+ chrome.runtime.onInstalled.addListener(this.onInstalled.bind(this));
loadOptions().then(opts => {
this.setOptions(opts);
@@ -39,17 +39,9 @@ class Yomichan {
});
}
- onImport({state, progress}) {
- if (state === 'begin') {
- chrome.tabs.create({url: chrome.extension.getURL('bg/import.html')}, tab => this.importTabId = tab.id);
- }
-
- if (this.importTabId !== null) {
- this.tabInvoke(this.importTabId, 'setProgress', progress);
- }
-
- if (state === 'end') {
- this.importTabId = null;
+ onInstalled(details) {
+ if (details.reason === 'install') {
+ chrome.tabs.create({url: chrome.extension.getURL('bg/guide.html')});
}
}
@@ -91,7 +83,7 @@ class Yomichan {
break;
case 'loading':
chrome.browserAction.setBadgeText({text: '...'});
- this.translator.loadData(this.onImport.bind(this)).then(() => this.setState('enabled'));
+ this.translator.prepare().then(this.setState('enabled'));
break;
}
@@ -239,11 +231,31 @@ class Yomichan {
}
api_findKanji({text, callback}) {
- promiseCallback(this.translator.findKanji(text), callback);
+ const dictionaries = [];
+ for (const title in this.options.dictionaries) {
+ if (this.options.dictionaries[title].enableKanji) {
+ dictionaries.push(title);
+ }
+ }
+
+ promiseCallback(
+ this.translator.findKanji(text, dictionaries),
+ callback
+ );
}
api_findTerm({text, callback}) {
- promiseCallback(this.translator.findTerm(text, this.options.enableSoftKatakanaSearch), callback);
+ const dictionaries = [];
+ for (const title in this.options.dictionaries) {
+ if (this.options.dictionaries[title].enableTerms) {
+ dictionaries.push(title);
+ }
+ }
+
+ promiseCallback(
+ this.translator.findTerm(text, dictionaries, this.options.enableSoftKatakanaSearch),
+ callback
+ );
}
api_renderText({template, data, callback}) {
diff --git a/ext/bg/options.html b/ext/bg/options.html
index 42029727..7ad5ea5c 100644
--- a/ext/bg/options.html
+++ b/ext/bg/options.html
@@ -6,7 +6,9 @@
<link rel="stylesheet" type="text/css" href="../lib/bootstrap-3.3.6-dist/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="../lib/bootstrap-3.3.6-dist/css/bootstrap-theme.min.css">
<style>
- #anki-spinner, #anki-general, #anki-error, #options-advanced {
+ #anki-spinner, #anki-general, #anki-error,
+ #dict-spinner, #dict-error, #dict-warning, #dict-purge-progress, #dict-import-progress, .dict-delete-progress,
+ #options-advanced {
display: none;
}
@@ -64,10 +66,69 @@
<div>
<div>
+ <img src="img/spinner.gif" class="pull-right" id="dict-spinner" alt>
+ <h3>Dictionaries</h3>
+ </div>
+
+ <p class="help-block">
+ Yomichan can utilize both bundled and custom (see the <a href="https://foosoft.net/projects/yomichan-import">Yomichan Import</a>
+ page for details) dictionaries. You can disable dictionaries that you no longer wish to use, or you can simply
+ <a href="#" id="dict-purge">purge the database</a> to delete everything. Please make sure to wait for import
+ and delete operations to complete before closing this page.
+ </p>
+
+ <div id="dict-purge-progress" class="text-danger">Dictionary data is being purged, please be patient...</div>
+
+ <div class="alert alert-warning" id="dict-warning">
+ <strong>Warning:</strong>
+ <span>No dictionaries found, use the importer below to install packaged and external dictionaries</span>
+ </div>
+
+ <div class="alert alert-danger" id="dict-error">
+ <strong>Error:</strong>
+ <span></span>
+ </div>
+
+ <div id="dict-groups"></div>
+
+ <div id="dict-import-progress">
+ Dictionary data is being imported, please be patient...
+ <div class="progress">
+ <div class="progress-bar progress-bar-striped" style="width: 0%"></div>
+ </div>
+ </div>
+
+ <div class="input-group" id="dict-importer">
+ <div class="input-group-btn">
+ <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
+ <ul class="dropdown-menu">
+ <li><a href="#" data-url="edict">JMdict</a></li>
+ <li><a href="#" data-url="enamdict">JMnedict</a></li>
+ <li><a href="#" data-url="kanjidic">KANJIDIC2</a></li>
+ <li role="separator" class="divider"></li>
+ <li><a href="#" data-url="http://localhost:9876/index.json">Local dictionary</a></li>
+ </ul>
+ </div>
+ <input type="text" id="dict-url" class="form-control" placeholder="Dictionary import URL">
+ <div class="input-group-btn">
+ <button type="button" id="dict-import" class="btn btn-primary" disabled>Import</button>
+ </div>
+ </div>
+ </div>
+
+ <div>
+ <div>
<img src="img/spinner.gif" class="pull-right" id="anki-spinner" alt>
<h3>Anki Options</h3>
</div>
+ <p class="help-block">
+ Yomichan features automatic flashcard creation for <a href="http://ankisrs.net/">Anki</a>, a free application
+ designed to help you retain knowledge. While the <a href="https://foosoft.net/projects/anki-connect/">AnkiConnect</a> plugin
+ offers the best experience, it is also possible to create flashcards through <a href="https://ankiweb.net/">AnkiWeb</a>,
+ provided you already have an account.
+ </p>
+
<div class="alert alert-danger" id="anki-error">
<strong>Error:</strong>
<span></span>
@@ -80,12 +141,6 @@
<option value="ankiconnect">AnkiConnect (requires the AnkiConnect plugin)</option>
<option value="ankiweb">AnkiWeb (requires an account on AnkiWeb)</option>
</select>
- <p class="help-block">
- Yomichan features automatic flashcard creation for <a href="http://ankisrs.net/">Anki</a>, a free application
- designed to help you retain knowledge. While the <a href="https://foosoft.net/projects/anki-connect/">AnkiConnect</a> plugin
- offers the best experience, it is also possible to create flashcards through <a href="https://ankiweb.net/">AnkiWeb</a>,
- provided you already have an account.
- </p>
</div>
<div id="anki-general">
@@ -158,6 +213,19 @@
</div>
</div>
</div>
+
+ <div>
+ <h3>Support Development</h3>
+
+ <p class="help-block">
+ If you find Yomichan useful, please consider making a small donation as a way to show your appreciation for the countless hours
+ that I have devoted to this extension. Seeing that people care about my work is great motivation for continuing to
+ improve Yomichan!
+ </p>
+ <p>
+ <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4DBTN9A3CUAFN"><img src="img/paypal.gif" alt></a>
+ </p>
+ </div>
</div>
<div class="pull-right">
@@ -167,6 +235,8 @@
<script src="../lib/jquery-2.2.2.min.js"></script>
<script src="../lib/bootstrap-3.3.6-dist/js/bootstrap.min.js"></script>
+ <script src="../lib/handlebars.min.js"></script>
+ <script src="js/templates.js"></script>
<script src="js/options.js"></script>
<script src="js/options-form.js"></script>
</body>
diff --git a/ext/fg/css/frame.css b/ext/fg/css/frame.css
index e7b5dedc..d519d4b7 100644
--- a/ext/fg/css/frame.css
+++ b/ext/fg/css/frame.css
@@ -100,7 +100,7 @@ body {
text-decoration: none;
}
-.term-rules {
+.term-reasons {
color: #777;
display: inline-block;
}
@@ -117,6 +117,11 @@ body {
color: #000;
}
+.term-glossary p {
+ overflow-x: auto;
+ white-space: pre;
+}
+
/* kanji styles */
.kanji-glyph {
@@ -153,3 +158,8 @@ body {
.kanji-glossary li span {
color: #000;
}
+
+.kanji-glossary p {
+ overflow-x: auto;
+ white-space: pre;
+}
diff --git a/ext/lib/dexie.min.js b/ext/lib/dexie.min.js
index 8b87e378..62b12442 100644
--- a/ext/lib/dexie.min.js
+++ b/ext/lib/dexie.min.js
@@ -1,3 +1,2 @@
-!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):n.Dexie=t()}(this,function(){"use strict";function n(n,t){In=n,An=t}function t(){if(En)try{throw t.arguments,new Error}catch(n){return n}return new Error}function e(n,t){var e=n.stack;return e?(t=t||0,0===e.indexOf(n.name)&&(t+=(n.name+n.message).split("\n").length),e.split("\n").slice(t).filter(An).map(function(n){return"\n"+n}).join("")):""}function r(){}function i(n){return n}function o(n,t){return null==n||n===i?t:function(e){return t(n(e))}}function u(n,t){return function(){n.apply(this,arguments),t.apply(this,arguments)}}function a(n,t){return n===r?t:function(){var e=n.apply(this,arguments);void 0!==e&&(arguments[0]=e);var r=this.onsuccess,i=this.onerror;this.onsuccess=null,this.onerror=null;var o=t.apply(this,arguments);return r&&(this.onsuccess=this.onsuccess?u(r,this.onsuccess):r),i&&(this.onerror=this.onerror?u(i,this.onerror):i),void 0!==o?o:e}}function c(n,t){return n===r?t:function(){n.apply(this,arguments);var e=this.onsuccess,r=this.onerror;this.onsuccess=this.onerror=null,t.apply(this,arguments),e&&(this.onsuccess=this.onsuccess?u(e,this.onsuccess):e),r&&(this.onerror=this.onerror?u(r,this.onerror):r)}}function s(n,t){return n===r?t:function(e){var r=n.apply(this,arguments);h(e,r);var i=this.onsuccess,o=this.onerror;this.onsuccess=null,this.onerror=null;var a=t.apply(this,arguments);return i&&(this.onsuccess=this.onsuccess?u(i,this.onsuccess):i),o&&(this.onerror=this.onerror?u(o,this.onerror):o),void 0===r?void 0===a?void 0:a:h(r,a)}}function f(n,t){return n===r?t:function(){return t.apply(this,arguments)===!1?!1:n.apply(this,arguments)}}function l(n,t){return n===r?t:function(){var e=n.apply(this,arguments);if(e&&"function"==typeof e.then){for(var r=this,i=arguments.length,o=new Array(i);i--;)o[i]=arguments[i];return e.then(function(){return t.apply(r,o)})}return t.apply(this,arguments)}}function h(n,t){return"object"!=typeof t?n:(Cn(t).forEach(function(e){n[e]=t[e]}),n)}function d(n,t){return Dn.call(n,t)}function p(n,t){"function"==typeof t&&(t=t(Pn(n))),Cn(t).forEach(function(e){v(n,e,t[e])})}function v(n,t,e,r){Object.defineProperty(n,t,h(e&&d(e,"get")&&"function"==typeof e.get?{get:e.get,set:e.set,configurable:!0}:{value:e,configurable:!0,writable:!0},r))}function y(n){return{from:function(t){return n.prototype=Object.create(t.prototype),v(n.prototype,"constructor",n),{extend:p.bind(null,n.prototype)}}}}function m(n,t){var e,r=Sn(n,t);return r||(e=Pn(n))&&m(e,t)}function g(n,t,e){return Tn.call(n,t,e)}function b(n,t){return t(n)}function _(n){var t=setTimeout(n,1e3);clearTimeout(t)}function w(n){if(!n)throw new Ln.Internal("Assertion failed")}function k(n){jn.setImmediate?setImmediate(n):setTimeout(n,0)}function x(n,t){return n.reduce(function(n,e,r){var i=t(e,r);return i&&(n[i[0]]=i[1]),n},{})}function I(n,t){return function(){try{n.apply(this,arguments)}catch(e){t(e)}}}function A(n,t,e){try{n.apply(null,e)}catch(r){t&&t(r)}}function E(n,t){var e=U.reject(n);return t?e.uncaught(t):e}function C(n,t){if(d(n,t))return n[t];if(!t)return n;if("string"!=typeof t){for(var e=[],r=0,i=t.length;i>r;++r){var o=C(n,t[r]);e.push(o)}return e}var u=t.indexOf(".");if(-1!==u){var a=n[t.substr(0,u)];return void 0===a?void 0:C(a,t.substr(u+1))}}function O(n,t,e){if(n&&void 0!==t&&!("isFrozen"in Object&&Object.isFrozen(n)))if("string"!=typeof t&&"length"in t){w("string"!=typeof e&&"length"in e);for(var r=0,i=t.length;i>r;++r)O(n,t[r],e[r])}else{var o=t.indexOf(".");if(-1!==o){var u=t.substr(0,o),a=t.substr(o+1);if(""===a)void 0===e?delete n[u]:n[u]=e;else{var c=n[u];c||(c=n[u]={}),O(c,a,e)}}else void 0===e?delete n[t]:n[t]=e}}function j(n,t){"string"==typeof t?O(n,t,void 0):"length"in t&&[].map.call(t,function(t){O(n,t,void 0)})}function P(n){var t={};for(var e in n)d(n,e)&&(t[e]=n[e]);return t}function D(n){if(!n||"object"!=typeof n)return n;var t;if(On(n)){t=[];for(var e=0,r=n.length;r>e;++e)t.push(D(n[e]))}else if(n instanceof Date)t=new Date,t.setTime(n.getTime());else{t=n.constructor?Object.create(n.constructor.prototype):{};for(var i in n)d(n,i)&&(t[i]=D(n[i]))}return t}function S(n,t,e,r){return e=e||{},r=r||"",Cn(n).forEach(function(i){if(d(t,i)){var o=n[i],u=t[i];"object"==typeof o&&"object"==typeof u&&o&&u&&o.constructor===u.constructor?S(o,u,e,r+i+"."):o!==u&&(e[r+i]=t[i])}else e[r+i]=void 0}),Cn(t).forEach(function(i){d(n,i)||(e[r+i]=t[i])}),e}function T(n){var t,e,r,i;if(1===arguments.length){if(On(n))return n.slice();if(this===Mn&&"string"==typeof n)return[n];if(i=Bn(n)){for(e=[];r=i.next(),!r.done;)e.push(r.value);return e}if(null==n)return[n];if(t=n.length,"number"==typeof t){for(e=new Array(t);t--;)e[t]=n[t];return e}return[n]}for(t=arguments.length,e=new Array(t);t--;)e[t]=arguments[t];return e}function K(n){return Nn.apply([],n)}function B(n,e){this._e=t(),this.name=n,this.message=e}function M(n,t){return n+". Errors: "+t.map(function(n){return n.toString()}).filter(function(n,t,e){return e.indexOf(n)===t}).join("\n")}function N(n,e,r,i){this._e=t(),this.failures=e,this.failedKeys=i,this.successCount=r}function q(n,e){this._e=t(),this.name="BulkError",this.failures=e,this.message=M(n,e)}function F(n,t){if(!n||n instanceof B||n instanceof TypeError||n instanceof SyntaxError||!n.name||!Wn[n.name])return n;var e=new Wn[n.name](t||n.message,n);return"stack"in n&&v(e,"stack",{get:function(){return this.inner.stack}}),e}function R(n){function t(n,t,i){if("object"==typeof n)return e(n);t||(t=f),i||(i=r);var a={subscribers:[],fire:i,subscribe:function(n){-1===a.subscribers.indexOf(n)&&(a.subscribers.push(n),a.fire=t(a.fire,n))},unsubscribe:function(n){a.subscribers=a.subscribers.filter(function(t){return t!==n}),a.fire=a.subscribers.reduce(t,i)}};return o[n]=u[n]=a,a}function e(n){Cn(n).forEach(function(e){var r=n[e];if(On(r))t(e,n[e][0],n[e][1]);else{if("asap"!==r)throw new Ln.InvalidArgument("Invalid event config");var o=t(e,i,function(){for(var n=arguments.length,t=new Array(n);n--;)t[n]=arguments[n];o.subscribers.forEach(function(n){k(function(){n.apply(null,t)})})})}})}var o={},u=function(t,e){if(e){for(var r=arguments.length,i=new Array(r-1);--r;)i[r-1]=arguments[r];return o[t].subscribe.apply(null,i),n}return"string"==typeof t?o[t]:void 0};u.addEventType=t;for(var a=1,c=arguments.length;c>a;++a)t(arguments[a]);return u}function U(n){if("object"!=typeof this)throw new TypeError("Promises must be constructed via new");this._listeners=[],this.onuncatched=r,this._lib=!1;var e=this._PSD=ut;if(In&&(this._stackHolder=t(),this._prev=null,this._numPrev=0,Q(this,rt)),"function"!=typeof n){if(n!==Gn)throw new TypeError("Not a function");return this._state=arguments[1],this._value=arguments[2],void(this._state===!1&&L(this,this._value))}this._state=null,this._value=null,++e.ref,V(this,n)}function z(n,t,e,r){this.onFulfilled="function"==typeof n?n:null,this.onRejected="function"==typeof t?t:null,this.resolve=e,this.reject=r,this.psd=ut}function V(n,t){try{t(function(t){if(null===n._state){if(t===n)throw new TypeError("A promise cannot be resolved with itself.");var e=n._lib&&$();t&&"function"==typeof t.then?V(n,function(n,e){t instanceof U?t._then(n,e):t.then(n,e)}):(n._state=!0,n._value=t,W(n)),e&&X()}},L.bind(null,n))}catch(e){L(n,e)}}function L(n,t){if(et.push(t),null===n._state){var e=n._lib&&$();t=it(t),n._state=!1,n._value=t,In&&null!==t&&"object"==typeof t&&!t._promise&&A(function(){var e=m(t,"stack");t._promise=n,v(t,"stack",{get:function(){return Yn?e&&(e.get?e.get.apply(t):e.value):n.stack}})}),tn(n),W(n),e&&X()}}function W(n){var t=n._listeners;n._listeners=[];for(var e=0,r=t.length;r>e;++e)H(n,t[e]);var i=n._PSD;--i.ref||i.finalize(),0===ct&&(++ct,Xn(function(){0===--ct&&Z()},[]))}function H(n,t){if(null===n._state)return void n._listeners.push(t);var e=n._state?t.onFulfilled:t.onRejected;if(null===e)return(n._state?t.resolve:t.reject)(n._value);var r=t.psd;++r.ref,++ct,Xn(G,[e,n,t])}function G(n,t,e){var r=ut,i=e.psd;try{i!==r&&(ut=i),rt=t;var o,u=t._value;t._state?o=n(u):(et.length&&(et=[]),o=n(u),-1===et.indexOf(u)&&en(t)),e.resolve(o)}catch(a){e.reject(a)}finally{i!==r&&(ut=r),rt=null,0===--ct&&Z(),--i.ref||i.finalize()}}function J(n,t,r){if(t.length===r)return t;var i="";if(n._state===!1){var o,u,a=n._value;null!=a?(o=a.name||"Error",u=a.message||a,i=e(a,0)):(o=a,u=""),t.push(o+(u?": "+u:"")+i)}return In&&(i=e(n._stackHolder,2),i&&-1===t.indexOf(i)&&t.push(i),n._prev&&J(n._prev,t,r)),t}function Q(n,t){var e=t?t._numPrev+1:0;Jn>e&&(n._prev=t,n._numPrev=e)}function Y(){$()&&X()}function $(){var n=Zn;return Zn=!1,nt=!1,n}function X(){var n,t,e;do for(;at.length>0;)for(n=at,at=[],e=n.length,t=0;e>t;++t){var r=n[t];r[0].apply(null,r[1])}while(at.length>0);Zn=!0,nt=!0}function Z(){var n=tt;tt=[],n.forEach(function(n){n._PSD.onunhandled.call(null,n._value,n)});for(var t=st.slice(0),e=t.length;e;)t[--e]()}function nn(n){function t(){n(),st.splice(st.indexOf(t),1)}st.push(t),++ct,Xn(function(){0===--ct&&Z()},[])}function tn(n){tt.some(function(t){return t._value===n._value})||tt.push(n)}function en(n){for(var t=tt.length;t;)if(tt[--t]._value===n._value)return void tt.splice(t,1)}function rn(n){console.warn("Unhandled rejection: "+(n.stack||n))}function on(n){return new U(Gn,!1,n)}function un(n,t){var e=ut;return function(){var r=$(),i=ut;try{return i!==e&&(ut=e),n.apply(this,arguments)}catch(o){t&&t(o)}finally{i!==e&&(ut=i),r&&X()}}}function an(n,t,e,r){var i=ut,o=Object.create(i);o.parent=i,o.ref=0,o.global=!1,++i.ref,o.finalize=function(){--this.parent.ref||this.parent.finalize()};var u=cn(o,n,t,e,r);return 0===o.ref&&o.finalize(),u}function cn(n,t,e,r,i){var o=ut;try{return n!==o&&(ut=n),t(e,r,i)}finally{n!==o&&(ut=o)}}function sn(n,t){var e;try{e=t.onuncatched(n)}catch(r){}if(e!==!1)try{U.on.error.fire(n,t)}catch(r){}}function fn(n,e){function u(){et.on("versionchange",function(n){n.newVersion>0?console.warn("Another connection wants to upgrade database '"+et.name+"'. Closing db now to resume the upgrade."):console.warn("Another connection wants to delete database '"+et.name+"'. Closing db now to resume the delete request."),et.close()}),et.on("blocked",function(n){!n.newVersion||n.newVersion<n.oldVersion?console.warn("Dexie.delete('"+et.name+"') was blocked"):console.warn("Upgrade '"+et.name+"' blocked by other connection holding version "+n.oldVersion/10)})}function f(n){this._cfg={version:n,storesSource:null,dbschema:{},tables:{},contentUpgrade:null},this.stores({})}function m(n,t,e){var r=et._createTransaction(tt,Jn,Hn);r.create(t),r._completion["catch"](e);var i=r._reject.bind(r);an(function(){ut.trans=r,0===n?(Cn(Hn).forEach(function(n){B(t,n,Hn[n].primKey,Hn[n].indexes)}),U.follow(function(){return et.on.populate.fire(r)})["catch"](i)):k(n,r,t)["catch"](i)})}function k(n,t,e){function r(){return i.length?U.resolve(i.shift()(t.idbtrans)).then(r):U.resolve()}var i=[],o=Gn.filter(function(t){return t._cfg.version===n})[0];if(!o)throw new Ln.Upgrade("Dexie specification of currently installed DB version is missing");Hn=et._dbSchema=o._cfg.dbschema;var u=!1,a=Gn.filter(function(t){return t._cfg.version>n});return a.forEach(function(n){i.push(function(){var r=Hn,i=n._cfg.dbschema;Tn(r,e),Tn(i,e),Hn=et._dbSchema=i;var o=j(r,i);return o.add.forEach(function(n){B(e,n[0],n[1].primKey,n[1].indexes)}),o.change.forEach(function(n){if(n.recreate)throw new Ln.Upgrade("Not yet support for changing primary key");var t=e.objectStore(n.name);n.add.forEach(function(n){z(t,n)}),n.change.forEach(function(n){t.deleteIndex(n.name),z(t,n)}),n.del.forEach(function(n){t.deleteIndex(n)})}),n._cfg.contentUpgrade?(u=!0,U.follow(function(){n._cfg.contentUpgrade(t)})):void 0}),i.push(function(t){if(u&&!mt){var e=n._cfg.dbschema;F(e,t)}})}),r().then(function(){M(Hn,e)})}function j(n,t){var e={del:[],add:[],change:[]};for(var r in n)t[r]||e.del.push(r);for(r in t){var i=n[r],o=t[r];if(i){var u={name:r,def:o,recreate:!1,del:[],add:[],change:[]};if(i.primKey.src!==o.primKey.src)u.recreate=!0,e.change.push(u);else{var a=i.idxByName,c=o.idxByName;for(var s in a)c[s]||u.del.push(s);for(s in c){var f=a[s],l=c[s];f?f.src!==l.src&&u.change.push(l):u.add.push(l)}(u.del.length>0||u.add.length>0||u.change.length>0)&&e.change.push(u)}}else e.add.push([r,o])}return e}function B(n,t,e,r){var i=n.db.createObjectStore(t,e.keyPath?{keyPath:e.keyPath,autoIncrement:e.auto}:{autoIncrement:e.auto});return r.forEach(function(n){z(i,n)}),i}function M(n,t){Cn(n).forEach(function(e){t.db.objectStoreNames.contains(e)||B(t,e,n[e].primKey,n[e].indexes)})}function F(n,t){for(var e=0;e<t.db.objectStoreNames.length;++e){var r=t.db.objectStoreNames[e];null==n[r]&&t.db.deleteObjectStore(r)}}function z(n,t){n.createIndex(t.name,t.keyPath,{unique:t.unique,multiEntry:t.multi})}function V(n){return et.on.error.fire(n)}function L(n,t,e){if(Zn||ut.letThrough){var i=et._createTransaction(n,t,Hn);return i._promise(n,function(n,t){an(function(){ut.trans=i,e(n,t,i)})}).then(function(n){return i._completion.then(function(){return n})})}if(!Xn){if(!zn)return E(new Ln.DatabaseClosed,V);et.open()["catch"](r)}return rt.then(function(){return L(n,t,e)})}function W(n,t,e){this.name=n,this.schema=t,this.hook=Qn[n]?Qn[n].hook:R(null,{creating:[a,r],reading:[o,i],updating:[s,r],deleting:[c,r]}),this._collClass=e||$}function H(n,t,e){W.call(this,n,t,e||Z)}function G(n,t,e){return(e?yn:vn)(function(e){n.push(e),t&&t()})}function J(n,t,e,r,i){return new U(function(o,u){var a=e.length,c=a-1;if(0===a)return o();if(r){var s,f=yn(u),l=pn(null);A(function(){for(var r=0;a>r;++r){s={onsuccess:null,onerror:null};var u=e[r];i.call(s,u[0],u[1],t);var h=n["delete"](u[0]);h._hookCtx=s,h.onerror=f,r===c?h.onsuccess=pn(o):h.onsuccess=l}},function(n){throw s.onerror&&s.onerror(n),n})}else for(var h=0;a>h;++h){var d=n["delete"](e[h]);d.onerror=un(vn(u)),h===c&&(d.onsuccess=un(function(){return o()}))}}).uncaught(V)}function Q(n,t,e,r){var i=this;this.db=et,this.mode=n,this.storeNames=t,this.idbtrans=null,this.on=R(this,"complete","error","abort"),this.parent=r||null,this.active=!0,this._tables=null,this._reculock=0,this._blockedFuncs=[],this._psd=null,this._dbschema=e,this._resolve=null,this._reject=null,this._completion=new U(function(n,t){i._resolve=n,i._reject=t}).uncaught(V),this._completion.then(function(){i.on.complete.fire()},function(n){return i.on.error.fire(n),i.parent?i.parent._reject(n):i.active&&i.idbtrans&&i.idbtrans.abort(),i.active=!1,E(n)})}function Y(n,t,e){this._ctx={table:n,index:":id"===t?null:t,collClass:n._collClass,or:e}}function $(n,t){var e=null,r=null;if(t)try{e=t()}catch(i){r=i}var o=n._ctx,u=o.table;this._ctx={table:u,index:o.index,isPrimKey:!o.index||u.schema.primKey.keyPath&&o.index===u.schema.primKey.name,range:e,keysOnly:!1,dir:"next",unique:"",algorithm:null,filter:null,replayFilter:null,justLimit:!0,isMatch:null,offset:0,limit:1/0,error:r,or:o.or,valueMapper:u.hook.reading.fire}}function X(n,t){return!(n.filter||n.algorithm||n.or)&&(t?n.justLimit:!n.replayFilter)}function Z(){$.apply(this,arguments)}function nn(n,t){return n._cfg.version-t._cfg.version}function tn(n,t,e,r){t.forEach(function(t){var i=et._tableFactory(e,r[t]);n.forEach(function(n){t in n||(n[t]=i)})})}function en(n){n.forEach(function(n){for(var t in n)n[t]instanceof W&&delete n[t]})}function rn(n,t,e,r,i,o){var u=o?function(n,t,r){return e(o(n),t,r)}:e,a=un(u,i);n.onerror||(n.onerror=vn(i)),t?n.onsuccess=I(function(){var e=n.result;if(e){var o=function(){e["continue"]()};t(e,function(n){o=n},r,i)&&a(e.value,e,function(n){o=n}),o()}else r()},i):n.onsuccess=I(function(){var t=n.result;if(t){var e=function(){t["continue"]()};a(t.value,t,function(n){e=n}),e()}else r()},i)}function on(n){var t=[];return n.split(",").forEach(function(n){n=n.trim();var e=n.replace(/([&*]|\+\+)/g,""),r=/^\[/.test(e)?e.match(/^\[(.*)\]$/)[1].split("+"):e;t.push(new _n(e,r||null,/\&/.test(n),/\*/.test(n),/\+\+/.test(n),On(r),/\./.test(n)))}),t}function cn(n,t){return Vn.cmp(n,t)}function sn(n,t){return cn(n,t)<0?n:t}function ln(n,t){return cn(n,t)>0?n:t}function An(n,t){return Vn.cmp(n,t)}function En(n,t){return Vn.cmp(t,n)}function jn(n,t){return t>n?-1:n===t?0:1}function Pn(n,t){return n>t?-1:n===t?0:1}function Dn(n,t){return n?t?function(){return n.apply(this,arguments)&&t.apply(this,arguments)}:n:t}function Sn(){if(et.verno=Yn.version/10,et._dbSchema=Hn={},Jn=g(Yn.objectStoreNames,0),0!==Jn.length){var n=Yn.transaction(kn(Jn),"readonly");Jn.forEach(function(t){for(var e=n.objectStore(t),r=e.keyPath,i=r&&"string"==typeof r&&-1!==r.indexOf("."),o=new _n(r,r||"",!1,!1,!!e.autoIncrement,r&&"string"!=typeof r,i),u=[],a=0;a<e.indexNames.length;++a){var c=e.index(e.indexNames[a]);r=c.keyPath,i=r&&"string"==typeof r&&-1!==r.indexOf(".");var s=new _n(c.name,r,!!c.unique,!!c.multiEntry,!1,r&&"string"!=typeof r,i);u.push(s)}Hn[t]=new wn(t,o,u,{})}),tn([Qn,Q.prototype],Cn(Hn),tt,Hn)}}function Tn(n,t){for(var e=t.db.objectStoreNames,r=0;r<e.length;++r){var i=e[r],o=t.objectStore(i);qn="getAll"in o;for(var u=0;u<o.indexNames.length;++u){var a=o.indexNames[u],c=o.index(a).keyPath,s="string"==typeof c?c:"["+g(c).join("+")+"]";if(n[i]){var f=n[i].idxByName[s];f&&(f.name=a)}}}}function Kn(n){et.on("blocked").fire(n),vt.filter(function(n){return n.name===et.name&&n!==et&&!n._vcFired}).map(function(t){return t.on("versionchange").fire(n)})}var Bn,Nn,qn,Fn=fn.dependencies,Rn=h({addons:fn.addons,autoOpen:!0,indexedDB:Fn.indexedDB,IDBKeyRange:Fn.IDBKeyRange},e),Un=Rn.addons,zn=Rn.autoOpen,Vn=Rn.indexedDB,Wn=Rn.IDBKeyRange,Hn=this._dbSchema={},Gn=[],Jn=[],Qn={},Yn=null,$n=null,Xn=!1,Zn=!1,nt="readonly",tt="readwrite",et=this,rt=new U(function(n){Bn=n}),it=new U(function(n,t){Nn=t}),ot=!0,at=!!xn(Vn);this.version=function(n){if(Yn||Xn)throw new Ln.Schema("Cannot add version when database is open");this.verno=Math.max(this.verno,n);var t=Gn.filter(function(t){return t._cfg.version===n})[0];return t?t:(t=new f(n),Gn.push(t),Gn.sort(nn),t)},h(f.prototype,{stores:function(n){this._cfg.storesSource=this._cfg.storesSource?h(this._cfg.storesSource,n):n;var t={};Gn.forEach(function(n){h(t,n._cfg.storesSource)});var e=this._cfg.dbschema={};return this._parseStoresSpec(t,e),Hn=et._dbSchema=e,en([Qn,et,Q.prototype]),tn([Qn,et,Q.prototype,this._cfg.tables],Cn(e),tt,e),Jn=Cn(e),this},upgrade:function(n){var t=this;return _t(function(){n(et._createTransaction(tt,Cn(t._cfg.dbschema),t._cfg.dbschema))}),this._cfg.contentUpgrade=n,this},_parseStoresSpec:function(n,t){Cn(n).forEach(function(e){if(null!==n[e]){var r={},i=on(n[e]),o=i.shift();if(o.multi)throw new Ln.Schema("Primary key cannot be multi-valued");o.keyPath&&O(r,o.keyPath,o.auto?0:o.keyPath),i.forEach(function(n){if(n.auto)throw new Ln.Schema("Only primary key can be marked as autoIncrement (++)");if(!n.keyPath)throw new Ln.Schema("Index must have a name and cannot be an empty string");O(r,n.keyPath,n.compound?n.keyPath.map(function(){return""}):"")}),t[e]=new wn(e,o,i,r)}})}}),this._allTables=Qn,this._tableFactory=function(n,t){return n===nt?new W(t.name,t,$):new H(t.name,t)},this._createTransaction=function(n,t,e,r){return new Q(n,t,e,r)},this._whenReady=function(n){return new U(wt||Zn||ut.letThrough?n:function(t,e){if(!Xn){if(!zn)return void e(new Ln.DatabaseClosed);et.open()["catch"](r)}rt.then(function(){n(t,e)})}).uncaught(V)},this.verno=0,this.open=function(){if(Xn||Yn)return rt.then(function(){return $n?E($n,V):et});In&&(it._stackHolder=t()),Xn=!0,$n=null,Zn=!1;var e=Bn,r=null;return U.race([it,new U(function(t,e){if(_(function(){return t()}),Gn.length>0&&(ot=!1),!Vn)throw new Ln.MissingAPI("indexedDB API not found. If using IE10+, make sure to run your code on a server URL (not locally). If using old Safari versions, make sure to include indexedDB polyfill.");var i=ot?Vn.open(n):Vn.open(n,Math.round(10*et.verno));if(!i)throw new Ln.MissingAPI("IndexedDB API not available");i.onerror=un(vn(e)),i.onblocked=un(Kn),i.onupgradeneeded=un(function(t){if(r=i.transaction,ot&&!et._allowEmptyDB){i.onerror=mn,r.abort(),i.result.close();var o=Vn.deleteDatabase(n);o.onsuccess=o.onerror=un(function(){e(new Ln.NoSuchDatabase("Database "+n+" doesnt exist"))})}else{r.onerror=un(vn(e));var u=t.oldVersion>Math.pow(2,62)?0:t.oldVersion;m(u/10,r,e,i)}},e),i.onsuccess=un(function(){if(r=null,Yn=i.result,vt.push(et),ot)Sn();else if(Yn.objectStoreNames.length>0)try{Tn(Hn,Yn.transaction(kn(Yn.objectStoreNames),nt))}catch(e){}Yn.onversionchange=un(function(n){et._vcFired=!0,et.on("versionchange").fire(n)}),at||gn(function(t){return-1===t.indexOf(n)?t.push(n):void 0}),t()},e)})]).then(function(){return fn.vip(et.on.ready.fire)}).then(function(){return Xn=!1,et})["catch"](function(n){try{r&&r.abort()}catch(t){}return Xn=!1,et.close(),$n=n,E($n,V)})["finally"](function(){Zn=!0,e()})},this.close=function(){var n=vt.indexOf(et);if(n>=0&&vt.splice(n,1),Yn){try{Yn.close()}catch(t){}Yn=null}zn=!1,$n=new Ln.DatabaseClosed,Xn&&Nn($n),rt=new U(function(n){Bn=n}),it=new U(function(n,t){Nn=t})},this["delete"]=function(){var t=arguments.length>0;return new U(function(e,r){function i(){et.close();var t=Vn.deleteDatabase(n);t.onsuccess=un(function(){at||gn(function(t){var e=t.indexOf(n);return e>=0?t.splice(e,1):void 0}),e()}),t.onerror=un(vn(r)),t.onblocked=Kn}if(t)throw new Ln.InvalidArgument("Arguments not allowed in db.delete()");Xn?rt.then(i):i()}).uncaught(V)},this.backendDB=function(){return Yn},this.isOpen=function(){return null!==Yn},this.hasFailed=function(){return null!==$n},this.dynamicallyOpened=function(){return ot},this.name=n,v(this,"tables",{get:function(){return Cn(Qn).map(function(n){return Qn[n]})}}),this.on=R(this,"error","populate","blocked","versionchange",{ready:[l,r]}),this.on.ready.subscribe=b(this.on.ready.subscribe,function(n){return function(t,e){fn.vip(function(){n(t),e||n(function r(){et.on.ready.unsubscribe(t),et.on.ready.unsubscribe(r)})})}}),_t(function(){et.on("populate").fire(et._createTransaction(tt,Jn,Hn)),et.on("error").fire(new Error)}),this.transaction=function(n,t,e){function r(t){var r=ut;t(U.resolve().then(function(){return an(function(){ut.transless=ut.transless||r;var t=et._createTransaction(n,s,Hn,a);ut.trans=t,a?t.idbtrans=a.idbtrans:t.create();var i=s.map(function(n){return t.tables[n]});i.push(t);var o;return U.follow(function(){if(o=e.apply(t,i))if("function"==typeof o.next&&"function"==typeof o["throw"])o=bn(o);else if("function"==typeof o.then&&!d(o,"_PSD"))throw new Ln.IncompatiblePromise("Incompatible Promise returned from transaction scope (read more at http://tinyurl.com/znyqjqc). Transaction scope: "+e.toString())}).uncaught(V).then(function(){return a&&t._resolve(),t._completion}).then(function(){return o})["catch"](function(n){return t._reject(n),E(n)})})}))}var i=arguments.length;if(2>i)throw new Ln.InvalidArgument("Too few arguments");for(var o=new Array(i-1);--i;)o[i-1]=arguments[i];e=o.pop();var u=K(o),a=ut.trans;a&&a.db===et&&-1===n.indexOf("!")||(a=null);var c=-1!==n.indexOf("?");n=n.replace("!","").replace("?","");try{var s=u.map(function(n){var t=n instanceof W?n.name:n;if("string"!=typeof t)throw new TypeError("Invalid table argument to Dexie.transaction(). Only Table or String are allowed");return t});if("r"==n||n==nt)n=nt;else{if("rw"!=n&&n!=tt)throw new Ln.InvalidArgument("Invalid transaction mode: "+n);n=tt}if(a){if(a.mode===nt&&n===tt){if(!c)throw new Ln.SubTransaction("Cannot enter a sub-transaction with READWRITE mode when parent transaction is READONLY");a=null}a&&s.forEach(function(n){if(!d(a.tables,n)){if(!c)throw new Ln.SubTransaction("Table "+n+" not included in parent transaction.");a=null}})}}catch(f){return a?a._promise(null,function(n,t){t(f)}):E(f,V)}return a?a._promise(n,r,"lock"):et._whenReady(r)},this.table=function(n){if(wt&&ot)return new H(n);if(!d(Qn,n))throw new Ln.InvalidTable("Table "+n+" does not exist");return Qn[n]},p(W.prototype,{_trans:function(n,t,e){var r=ut.trans;return r&&r.db===et?r._promise(n,t,e):L(n,[this.name],t)},_idbstore:function(n,t,e){function r(n,e,r){t(n,e,r.idbtrans.objectStore(o),r)}if(wt)return new U(t);var i=ut.trans,o=this.name;return i&&i.db===et?i._promise(n,r,e):L(n,[this.name],r)},get:function(n,t){var e=this;return this._idbstore(nt,function(t,r,i){wt&&t(e.schema.instanceTemplate);var o=i.get(n);o.onerror=vn(r),o.onsuccess=function(){t(e.hook.reading.fire(o.result))}}).then(t)},where:function(n){return new Y(this,n)},count:function(n){return this.toCollection().count(n)},offset:function(n){return this.toCollection().offset(n)},limit:function(n){return this.toCollection().limit(n)},reverse:function(){return this.toCollection().reverse()},filter:function(n){return this.toCollection().and(n)},each:function(n){return this.toCollection().each(n)},toArray:function(n){return this.toCollection().toArray(n)},orderBy:function(n){return new this._collClass(new Y(this,n))},toCollection:function(){return new this._collClass(new Y(this))},mapToClass:function(n,t){this.schema.mappedClass=n;var e=Object.create(n.prototype);t&&hn(e,t),this.schema.instanceTemplate=e;var r=function(t){if(!t)return t;var e=Object.create(n.prototype);for(var r in t)d(t,r)&&(e[r]=t[r]);return e};return this.schema.readHook&&this.hook.reading.unsubscribe(this.schema.readHook),this.schema.readHook=r,this.hook("reading",r),n},defineClass:function(n){return this.mapToClass(fn.defineClass(n),n)}}),y(H).from(W).extend({bulkDelete:function(n){return this.hook.deleting.fire===r?this._idbstore(tt,function(t,e,i,o){t(J(i,o,n,!1,r))}):this.where(":id").anyOf(n)["delete"]().then(function(){})},bulkPut:function(n,t){var e=this;return this._idbstore(tt,function(i,o,u){if(!u.keyPath&&!e.schema.primKey.auto&&!t)throw new Ln.InvalidArgument("bulkPut() with non-inbound keys requires keys array in second argument");if(u.keyPath&&t)throw new Ln.InvalidArgument("bulkPut(): keys argument invalid on tables with inbound keys");if(t&&t.length!==n.length)throw new Ln.InvalidArgument("Arguments objects and keys must have the same length");if(0===n.length)return i();var a,c,s=function(n){0===f.length?i(n):o(new q(e.name+".bulkPut(): "+f.length+" of "+l+" operations failed",f))},f=[],l=n.length,h=e;if(e.hook.creating.fire===r&&e.hook.updating.fire===r){c=G(f);for(var d=0,p=n.length;p>d;++d)a=t?u.put(n[d],t[d]):u.put(n[d]),a.onerror=c;a.onerror=G(f,s),a.onsuccess=dn(s)}else{var v=t||u.keyPath&&n.map(function(n){return C(n,u.keyPath)}),y=v&&x(v,function(t,e){return null!=t&&[t,n[e]]}),m=v?h.where(":id").anyOf(v.filter(function(n){return null!=n})).modify(function(){this.value=y[this.primKey],y[this.primKey]=null})["catch"](N,function(n){f=n.failures}).then(function(){for(var e=[],r=t&&[],i=v.length-1;i>=0;--i){var o=v[i];(null==o||y[o])&&(e.push(n[i]),t&&r.push(o),null!=o&&(y[o]=null))}return e.reverse(),t&&r.reverse(),h.bulkAdd(e,r)}).then(function(n){var t=v[v.length-1];return null!=t?t:n}):h.bulkAdd(n);m.then(s)["catch"](q,function(n){f=f.concat(n.failures),s()})["catch"](o)}},"locked")},bulkAdd:function(n,t){var e=this,i=this.hook.creating.fire;return this._idbstore(tt,function(o,u,a,c){function s(n){0===d.length?o(n):u(new q(e.name+".bulkAdd(): "+d.length+" of "+p+" operations failed",d))}if(!a.keyPath&&!e.schema.primKey.auto&&!t)throw new Ln.InvalidArgument("bulkAdd() with non-inbound keys requires keys array in second argument");if(a.keyPath&&t)throw new Ln.InvalidArgument("bulkAdd(): keys argument invalid on tables with inbound keys");if(t&&t.length!==n.length)throw new Ln.InvalidArgument("Arguments objects and keys must have the same length");if(0===n.length)return o();var f,l,h,d=[],p=n.length;if(i!==r){var v,y=a.keyPath;l=G(d,null,!0),h=pn(null),A(function(){for(var e=0,r=n.length;r>e;++e){v={onerror:null,onsuccess:null};var o=t&&t[e],u=n[e],s=t?o:y?C(u,y):void 0,d=i.call(v,s,u,c);null==s&&null!=d&&(y?(u=D(u),O(u,y,d)):o=d),f=null!=o?a.add(u,o):a.add(u),f._hookCtx=v,r-1>e&&(f.onerror=l,v.onsuccess&&(f.onsuccess=h))}},function(n){throw v.onerror&&v.onerror(n),n}),f.onerror=G(d,s,!0),f.onsuccess=pn(s)}else{l=G(d);for(var m=0,g=n.length;g>m;++m)f=t?a.add(n[m],t[m]):a.add(n[m]),f.onerror=l;f.onerror=G(d,s),f.onsuccess=dn(s)}})},add:function(n,t){var e=this.hook.creating.fire;return this._idbstore(tt,function(i,o,u,a){var c={onsuccess:null,onerror:null};if(e!==r){var s=null!=t?t:u.keyPath?C(n,u.keyPath):void 0,f=e.call(c,s,n,a);null==s&&null!=f&&(u.keyPath?O(n,u.keyPath,f):t=f)}try{var l=null!=t?u.add(n,t):u.add(n);l._hookCtx=c,l.onerror=yn(o),l.onsuccess=pn(function(t){var e=u.keyPath;e&&O(n,e,t),i(t)})}catch(h){throw c.onerror&&c.onerror(h),h}})},put:function(n,t){var e=this,i=this.hook.creating.fire,o=this.hook.updating.fire;return i!==r||o!==r?this._trans(tt,function(r,i,o){var u=void 0!==t?t:e.schema.primKey.keyPath&&C(n,e.schema.primKey.keyPath);null==u?o.tables[e.name].add(n).then(r,i):(o._lock(),n=D(n),o.tables[e.name].where(":id").equals(u).modify(function(){this.value=n}).then(function(r){return 0===r?o.tables[e.name].add(n,t):u})["finally"](function(){o._unlock()}).then(r,i))}):this._idbstore(tt,function(e,r,i){var o=void 0!==t?i.put(n,t):i.put(n);o.onerror=vn(r),o.onsuccess=function(t){var r=i.keyPath;r&&O(n,r,t.target.result),e(o.result)}})},"delete":function(n){return this.hook.deleting.subscribers.length?this.where(":id").equals(n)["delete"]():this._idbstore(tt,function(t,e,r){var i=r["delete"](n);i.onerror=vn(e),i.onsuccess=function(){t(i.result)}})},clear:function(){return this.hook.deleting.subscribers.length?this.toCollection()["delete"]():this._idbstore(tt,function(n,t,e){var r=e.clear();r.onerror=vn(t),r.onsuccess=function(){n(r.result)}})},update:function(n,t){if("object"!=typeof t||On(t))throw new Ln.InvalidArgument("Modifications must be an object.");if("object"!=typeof n||On(n))return this.where(":id").equals(n).modify(t);Cn(t).forEach(function(e){O(n,e,t[e])});var e=C(n,this.schema.primKey.keyPath);return void 0===e?E(new Ln.InvalidArgument("Given object does not contain its primary key"),V):this.where(":id").equals(e).modify(t)}}),p(Q.prototype,{_lock:function(){return w(!ut.global),++this._reculock,1!==this._reculock||ut.global||(ut.lockOwnerFor=this),this},_unlock:function(){if(w(!ut.global),0===--this._reculock)for(ut.global||(ut.lockOwnerFor=null);this._blockedFuncs.length>0&&!this._locked();){var n=this._blockedFuncs.shift();try{n()}catch(t){}}return this},_locked:function(){return this._reculock&&ut.lockOwnerFor!==this},create:function(n){var t=this;if(w(!this.idbtrans),!n&&!Yn)switch($n&&$n.name){case"DatabaseClosedError":throw new Ln.DatabaseClosed($n);case"MissingAPIError":throw new Ln.MissingAPI($n.message,$n);default:throw new Ln.OpenFailed($n)}if(!this.active)throw new Ln.TransactionInactive;return w(null===this._completion._state),n=this.idbtrans=n||Yn.transaction(kn(this.storeNames),this.mode),n.onerror=un(function(e){mn(e),t._reject(n.error)}),n.onabort=un(function(n){mn(n),t.active&&t._reject(new Ln.Abort),t.active=!1,t.on("abort").fire(n)}),n.oncomplete=un(function(){t.active=!1,t._resolve()}),this},_promise:function(n,t,e){var r=this;return an(function(){var i;return r._locked()?i=new U(function(i,o){r._blockedFuncs.push(function(){r._promise(n,t,e).then(i,o)})}):(i=r.active?new U(function(i,o){if(n===tt&&r.mode!==tt)throw new Ln.ReadOnly("Transaction is readonly");!r.idbtrans&&n&&r.create(),e&&r._lock(),t(i,o,r)}):E(new Ln.TransactionInactive),r.active&&e&&i["finally"](function(){r._unlock()})),i._lib=!0,i.uncaught(V)})},abort:function(){this.active&&this._reject(new Ln.Abort),this.active=!1},tables:{get:function(){return this._tables?this._tables:this._tables=x(this.storeNames,function(n){return[n,Qn[n]]})}},complete:function(n){return this.on("complete",n)},error:function(n){return this.on("error",n)},table:function(n){if(-1===this.storeNames.indexOf(n))throw new Ln.InvalidTable("Table "+n+" not in transaction");return Qn[n]}}),p(Y.prototype,function(){function n(n,t,e){var r=n instanceof Y?new n._ctx.collClass(n):n;return r._ctx.error=e?new e(t):new TypeError(t),
-r}function t(n){return new n._ctx.collClass(n,function(){return Wn.only("")}).limit(0)}function e(n){return"next"===n?function(n){return n.toUpperCase()}:function(n){return n.toLowerCase()}}function r(n){return"next"===n?function(n){return n.toLowerCase()}:function(n){return n.toUpperCase()}}function i(n,t,e,r,i,o){for(var u=Math.min(n.length,r.length),a=-1,c=0;u>c;++c){var s=t[c];if(s!==r[c])return i(n[c],e[c])<0?n.substr(0,c)+e[c]+e.substr(c+1):i(n[c],r[c])<0?n.substr(0,c)+r[c]+e.substr(c+1):a>=0?n.substr(0,a)+t[a]+e.substr(a+1):null;i(n[c],s)<0&&(a=c)}return u<r.length&&"next"===o?n+e.substr(n.length):u<n.length&&"prev"===o?n.substr(0,e.length):0>a?null:n.substr(0,a)+r[a]+e.substr(a+1)}function o(t,o,u,a){function c(n){s=e(n),f=r(n),l="next"===n?jn:Pn;var t=u.map(function(n){return{lower:f(n),upper:s(n)}}).sort(function(n,t){return l(n.lower,t.lower)});h=t.map(function(n){return n.upper}),d=t.map(function(n){return n.lower}),p=n,v="next"===n?"":a}var s,f,l,h,d,p,v,y=u.length;if(!u.every(function(n){return"string"==typeof n}))return n(t,pt);c("next");var m=new t._ctx.collClass(t,function(){return Wn.bound(h[0],d[y-1]+a)});m._ondirectionchange=function(n){c(n)};var g=0;return m._addAlgorithm(function(n,t,e){var r=n.key;if("string"!=typeof r)return!1;var u=f(r);if(o(u,d,g))return!0;for(var a=null,c=g;y>c;++c){var s=i(r,u,h[c],d[c],l,p);null===s&&null===a?g=c+1:(null===a||l(a,s)>0)&&(a=s)}return t(null!==a?function(){n["continue"](a+v)}:e),!1}),m}return{between:function(e,r,i,o){i=i!==!1,o=o===!0;try{return cn(e,r)>0||0===cn(e,r)&&(i||o)&&(!i||!o)?t(this):new this._ctx.collClass(this,function(){return Wn.bound(e,r,!i,!o)})}catch(u){return n(this,dt)}},equals:function(n){return new this._ctx.collClass(this,function(){return Wn.only(n)})},above:function(n){return new this._ctx.collClass(this,function(){return Wn.lowerBound(n,!0)})},aboveOrEqual:function(n){return new this._ctx.collClass(this,function(){return Wn.lowerBound(n)})},below:function(n){return new this._ctx.collClass(this,function(){return Wn.upperBound(n,!0)})},belowOrEqual:function(n){return new this._ctx.collClass(this,function(){return Wn.upperBound(n)})},startsWith:function(t){return"string"!=typeof t?n(this,pt):this.between(t,t+lt,!0,!0)},startsWithIgnoreCase:function(n){return""===n?this.startsWith(n):o(this,function(n,t){return 0===n.indexOf(t[0])},[n],lt)},equalsIgnoreCase:function(n){return o(this,function(n,t){return n===t[0]},[n],"")},anyOfIgnoreCase:function(){var n=T.apply(Mn,arguments);return 0===n.length?t(this):o(this,function(n,t){return-1!==t.indexOf(n)},n,"")},startsWithAnyOfIgnoreCase:function(){var n=T.apply(Mn,arguments);return 0===n.length?t(this):o(this,function(n,t){return t.some(function(t){return 0===n.indexOf(t)})},n,lt)},anyOf:function(){var e=T.apply(Mn,arguments),r=An;try{e.sort(r)}catch(i){return n(this,dt)}if(0===e.length)return t(this);var o=new this._ctx.collClass(this,function(){return Wn.bound(e[0],e[e.length-1])});o._ondirectionchange=function(n){r="next"===n?An:En,e.sort(r)};var u=0;return o._addAlgorithm(function(n,t,i){for(var o=n.key;r(o,e[u])>0;)if(++u,u===e.length)return t(i),!1;return 0===r(o,e[u])?!0:(t(function(){n["continue"](e[u])}),!1)}),o},notEqual:function(n){return this.inAnyRange([[-(1/0),n],[n,ht]],{includeLowers:!1,includeUppers:!1})},noneOf:function(){var t=T.apply(Mn,arguments);if(0===t.length)return new this._ctx.collClass(this);try{t.sort(An)}catch(e){return n(this,dt)}var r=t.reduce(function(n,t){return n?n.concat([[n[n.length-1][1],t]]):[[-(1/0),t]]},null);return r.push([t[t.length-1],ht]),this.inAnyRange(r,{includeLowers:!1,includeUppers:!1})},inAnyRange:function(e,r){function i(n,t){for(var e=0,r=n.length;r>e;++e){var i=n[e];if(cn(t[0],i[1])<0&&cn(t[1],i[0])>0){i[0]=sn(i[0],t[0]),i[1]=ln(i[1],t[1]);break}}return e===r&&n.push(t),n}function o(n,t){return l(n[0],t[0])}function u(n){return!p(n)&&!v(n)}var a=this._ctx;if(0===e.length)return t(this);if(!e.every(function(n){return void 0!==n[0]&&void 0!==n[1]&&An(n[0],n[1])<=0}))return n(this,"First argument to inAnyRange() must be an Array of two-value Arrays [lower,upper] where upper must not be lower than lower",Ln.InvalidArgument);var c,s=!r||r.includeLowers!==!1,f=r&&r.includeUppers===!0,l=An;try{c=e.reduce(i,[]),c.sort(o)}catch(h){return n(this,dt)}var d=0,p=f?function(n){return An(n,c[d][1])>0}:function(n){return An(n,c[d][1])>=0},v=s?function(n){return En(n,c[d][0])>0}:function(n){return En(n,c[d][0])>=0},y=p,m=new a.collClass(this,function(){return Wn.bound(c[0][0],c[c.length-1][1],!s,!f)});return m._ondirectionchange=function(n){"next"===n?(y=p,l=An):(y=v,l=En),c.sort(o)},m._addAlgorithm(function(n,t,e){for(var r=n.key;y(r);)if(++d,d===c.length)return t(e),!1;return u(r)?!0:0===cn(r,c[d][1])||0===cn(r,c[d][0])?!1:(t(function(){l===An?n["continue"](c[d][0]):n["continue"](c[d][1])}),!1)}),m},startsWithAnyOf:function(){var e=T.apply(Mn,arguments);return e.every(function(n){return"string"==typeof n})?0===e.length?t(this):this.inAnyRange(e.map(function(n){return[n,n+lt]})):n(this,"startsWithAnyOf() only works with strings")}}}),p($.prototype,function(){function n(n,t){n.filter=Dn(n.filter,t)}function t(n,t,e){var r=n.replayFilter;n.replayFilter=r?function(){return Dn(r(),t())}:t,n.justLimit=e&&!r}function e(n,t){n.isMatch=Dn(n.isMatch,t)}function r(n,t){if(n.isPrimKey)return t;var e=n.table.schema.idxByName[n.index];if(!e)throw new Ln.Schema("KeyPath "+n.index+" on object store "+t.name+" is not indexed");return t.index(e.name)}function o(n,t){var e=r(n,t);return n.keysOnly&&"openKeyCursor"in e?e.openKeyCursor(n.range||null,n.dir+n.unique):e.openCursor(n.range||null,n.dir+n.unique)}function u(n,t,e,r,i){var u=n.replayFilter?Dn(n.filter,n.replayFilter()):n.filter;n.or?function(){function a(){2===++f&&e()}function c(n,e,i){if(!u||u(e,i,a,r)){var o=e.primaryKey.toString();d(s,o)||(s[o]=!0,t(n,e,i))}}var s={},f=0;n.or._iterate(c,a,r,i),rn(o(n,i),n.algorithm,c,a,r,!n.keysOnly&&n.valueMapper)}():rn(o(n,i),Dn(n.algorithm,u),t,e,r,!n.keysOnly&&n.valueMapper)}function a(n){return n.table.schema.instanceTemplate}return{_read:function(n,t){var e=this._ctx;return e.error?e.table._trans(null,function(n,t){t(e.error)}):e.table._idbstore(nt,n).then(t)},_write:function(n){var t=this._ctx;return t.error?t.table._trans(null,function(n,e){e(t.error)}):t.table._idbstore(tt,n,"locked")},_addAlgorithm:function(n){var t=this._ctx;t.algorithm=Dn(t.algorithm,n)},_iterate:function(n,t,e,r){return u(this._ctx,n,t,e,r)},clone:function(n){var t=Object.create(this.constructor.prototype),e=Object.create(this._ctx);return n&&h(e,n),t._ctx=e,t},raw:function(){return this._ctx.valueMapper=null,this},each:function(n){var t=this._ctx;if(wt){var e=a(t),r=t.table.schema.primKey.keyPath,i=C(e,t.index?t.table.schema.idxByName[t.index].keyPath:r),o=C(e,r);n(e,{key:i,primaryKey:o})}return this._read(function(e,r,i){u(t,n,e,r,i)})},count:function(n){if(wt)return U.resolve(0).then(n);var t=this._ctx;if(X(t,!0))return this._read(function(n,e,i){var o=r(t,i),u=t.range?o.count(t.range):o.count();u.onerror=vn(e),u.onsuccess=function(e){n(Math.min(e.target.result,t.limit))}},n);var e=0;return this._read(function(n,r,i){u(t,function(){return++e,!1},function(){n(e)},r,i)},n)},sortBy:function(n,t){function e(n,t){return t?e(n[i[t]],t-1):n[o]}function r(n,t){var r=e(n,u),i=e(t,u);return i>r?-a:r>i?a:0}var i=n.split(".").reverse(),o=i[0],u=i.length-1,a="next"===this._ctx.dir?1:-1;return this.toArray(function(n){return n.sort(r)}).then(t)},toArray:function(n){var t=this._ctx;return this._read(function(n,e,o){if(wt&&n([a(t)]),qn&&"next"===t.dir&&X(t,!0)&&t.limit>0){var c=t.table.hook.reading.fire,s=r(t,o),f=t.limit<1/0?s.getAll(t.range,t.limit):s.getAll(t.range);f.onerror=vn(e),f.onsuccess=c===i?dn(n):un(dn(function(t){n(t.map(c))}))}else{var l=[];u(t,function(n){l.push(n)},function(){n(l)},e,o)}},n)},offset:function(n){var e=this._ctx;return 0>=n?this:(e.offset+=n,X(e)?t(e,function(){var t=n;return function(n,e){return 0===t?!0:1===t?(--t,!1):(e(function(){n.advance(t),t=0}),!1)}}):t(e,function(){var t=n;return function(){return--t<0}}),this)},limit:function(n){return this._ctx.limit=Math.min(this._ctx.limit,n),t(this._ctx,function(){var t=n;return function(n,e,r){return--t<=0&&e(r),t>=0}},!0),this},until:function(t,e){var r=this._ctx;return wt&&t(a(r)),n(this._ctx,function(n,r,i){return t(n.value)?(r(i),e):!0}),this},first:function(n){return this.limit(1).toArray(function(n){return n[0]}).then(n)},last:function(n){return this.reverse().first(n)},filter:function(t){return wt&&t(a(this._ctx)),n(this._ctx,function(n){return t(n.value)}),e(this._ctx,t),this},and:function(n){return this.filter(n)},or:function(n){return new Y(this._ctx.table,n,this)},reverse:function(){return this._ctx.dir="prev"===this._ctx.dir?"next":"prev",this._ondirectionchange&&this._ondirectionchange(this._ctx.dir),this},desc:function(){return this.reverse()},eachKey:function(n){var t=this._ctx;return t.keysOnly=!t.isMatch,this.each(function(t,e){n(e.key,e)})},eachUniqueKey:function(n){return this._ctx.unique="unique",this.eachKey(n)},eachPrimaryKey:function(n){var t=this._ctx;return t.keysOnly=!t.isMatch,this.each(function(t,e){n(e.primaryKey,e)})},keys:function(n){var t=this._ctx;t.keysOnly=!t.isMatch;var e=[];return this.each(function(n,t){e.push(t.key)}).then(function(){return e}).then(n)},primaryKeys:function(n){var t=this._ctx;if(qn&&"next"===t.dir&&X(t,!0)&&t.limit>0)return this._read(function(n,e,i){var o=r(t,i),u=t.limit<1/0?o.getAllKeys(t.range,t.limit):o.getAllKeys(t.range);u.onerror=vn(e),u.onsuccess=dn(n)}).then(n);t.keysOnly=!t.isMatch;var e=[];return this.each(function(n,t){e.push(t.primaryKey)}).then(function(){return e}).then(n)},uniqueKeys:function(n){return this._ctx.unique="unique",this.keys(n)},firstKey:function(n){return this.limit(1).keys(function(n){return n[0]}).then(n)},lastKey:function(n){return this.reverse().firstKey(n)},distinct:function(){var t=this._ctx,e=t.index&&t.table.schema.idxByName[t.index];if(!e||!e.multi)return this;var r={};return n(this._ctx,function(n){var t=n.primaryKey.toString(),e=d(r,t);return r[t]=!0,!e}),this}}}),y(Z).from($).extend({modify:function(n){var t=this,e=this._ctx,i=e.table.hook,o=i.updating.fire,u=i.deleting.fire;return wt&&"function"==typeof n&&n.call({value:e.table.schema.instanceTemplate},e.table.schema.instanceTemplate),this._write(function(e,i,a,c){function s(n,t){function e(n){return w.push(n),k.push(r.primKey),l(),!0}x=t.primaryKey;var r={primKey:t.primaryKey,value:n,onsuccess:null,onerror:null};if(p.call(r,n,r)!==!1){var i=!d(r,"value");++g,A(function(){var n=i?t["delete"]():t.update(r.value);n._hookCtx=r,n.onerror=yn(e),n.onsuccess=pn(function(){++b,l()})},e)}else r.onsuccess&&r.onsuccess(r.value)}function f(n){return n&&(w.push(n),k.push(x)),i(new N("Error modifying one or more objects",w,b,k))}function l(){_&&b+w.length===g&&(w.length>0?f():e(b))}var p;if("function"==typeof n)p=o===r&&u===r?n:function(t){var e=D(t);if(n.call(this,t,this)===!1)return!1;if(d(this,"value")){var r=S(e,this.value),i=o.call(this,r,this.primKey,e,c);i&&(t=this.value,Cn(i).forEach(function(n){O(t,n,i[n])}))}else u.call(this,this.primKey,t,c)};else if(o===r){var v=Cn(n),y=v.length;p=function(t){for(var e=!1,r=0;y>r;++r){var i=v[r],o=n[i];C(t,i)!==o&&(O(t,i,o),e=!0)}return e}}else{var m=n;n=P(m),p=function(t){var e=!1,r=o.call(this,n,this.primKey,D(t),c);return r&&h(n,r),Cn(n).forEach(function(r){var i=n[r];C(t,r)!==i&&(O(t,r,i),e=!0)}),r&&(n=P(m)),e}}var g=0,b=0,_=!1,w=[],k=[],x=null;t.clone().raw()._iterate(s,function(){_=!0,l()},f,a)})},"delete":function(){var n=this,t=this._ctx,e=t.range,i=t.table.hook.deleting.fire,o=i!==r;if(!o&&X(t)&&(t.isPrimKey&&!gt||!e))return this._write(function(n,t,r){var i=vn(t),o=e?r.count(e):r.count();o.onerror=i,o.onsuccess=function(){var u=o.result;A(function(){var t=e?r["delete"](e):r.clear();t.onerror=i,t.onsuccess=function(){return n(u)}},function(n){return t(n)})}});var u=o?2e3:1e4;return this._write(function(e,r,a,c){var s=0,f=n.clone({keysOnly:!t.isMatch&&!o}).distinct().limit(u).raw(),l=[],h=function(){return f.each(o?function(n,t){l.push([t.primaryKey,t.value])}:function(n,t){l.push(t.primaryKey)}).then(function(){return o?l.sort(function(n,t){return An(n[0],t[0])}):l.sort(An),J(a,c,l,o,i)}).then(function(){var n=l.length;return s+=n,l=[],u>n?s:h()})};e(h())})}}),h(this,{Collection:$,Table:W,Transaction:Q,Version:f,WhereClause:Y,WriteableCollection:Z,WriteableTable:H}),u(),Un.forEach(function(n){n(et)})}function ln(n){if("function"==typeof n)return new n;if(On(n))return[ln(n[0])];if(n&&"object"==typeof n){var t={};return hn(t,n),t}return n}function hn(n,t){return Cn(t).forEach(function(e){var r=ln(t[e]);n[e]=r}),n}function dn(n){return function(t){n(t.target.result)}}function pn(n){return un(function(t){var e=t.target,r=e.result,i=e._hookCtx,o=i&&i.onsuccess;o&&o(r),n&&n(r)},n)}function vn(n){return function(t){return mn(t),n(t.target.error),!1}}function yn(n){return un(function(t){var e=t.target,r=e.error,i=e._hookCtx,o=i&&i.onerror;return o&&o(r),mn(t),n(r),!1})}function mn(n){n.stopPropagation&&n.stopPropagation(),n.preventDefault&&n.preventDefault()}function gn(n){var t,e=fn.dependencies.localStorage;if(!e)return n([]);try{t=JSON.parse(e.getItem("Dexie.DatabaseNames")||"[]")}catch(r){t=[]}n(t)&&e.setItem("Dexie.DatabaseNames",JSON.stringify(t))}function bn(n){function t(n){return function(t){var e=n(t),r=e.value;return e.done?r:r&&"function"==typeof r.then?r.then(i,o):On(r)?U.all(r).then(i,o):i(r)}}var e=function(t){return n.next(t)},r=function(t){return n["throw"](t)},i=t(e),o=t(r);return t(e)()}function _n(n,t,e,r,i,o,u){this.name=n,this.keyPath=t,this.unique=e,this.multi=r,this.auto=i,this.compound=o,this.dotted=u;var a="string"==typeof t?t:t&&"["+[].join.call(t,"+")+"]";this.src=(e?"&":"")+(r?"*":"")+(i?"++":"")+a}function wn(n,t,e,r){this.name=n,this.primKey=t||new _n,this.indexes=e||[new _n],this.instanceTemplate=r,this.mappedClass=null,this.idxByName=x(e,function(n){return[n.name,n]})}function kn(n){return 1===n.length?n[0]:n}function xn(n){var t=n&&(n.getDatabaseNames||n.webkitGetDatabaseNames);return t&&t.bind(n)}var In="undefined"!=typeof location&&/^(http|https):\/\/(localhost|127\.0\.0\.1)/.test(location.href),An=function(){return!0},En=!new Error("").stack,Cn=Object.keys,On=Array.isArray,jn="undefined"!=typeof self?self:"undefined"!=typeof window?window:global,Pn=Object.getPrototypeOf,Dn={}.hasOwnProperty,Sn=Object.getOwnPropertyDescriptor,Tn=[].slice,Kn="undefined"!=typeof Symbol&&Symbol.iterator,Bn=Kn?function(n){var t;return null!=n&&(t=n[Kn])&&t.apply(n)}:function(){return null},Mn={},Nn=[].concat,qn=["Modify","Bulk","OpenFailed","VersionChange","Schema","Upgrade","InvalidTable","MissingAPI","NoSuchDatabase","InvalidArgument","SubTransaction","Unsupported","Internal","DatabaseClosed","IncompatiblePromise"],Fn=["Unknown","Constraint","Data","TransactionInactive","ReadOnly","Version","NotFound","InvalidState","InvalidAccess","Abort","Timeout","QuotaExceeded","Syntax","DataClone"],Rn=qn.concat(Fn),Un={VersionChanged:"Database version changed by other database connection",DatabaseClosed:"Database has been closed",Abort:"Transaction aborted",TransactionInactive:"Transaction has already completed or failed"};y(B).from(Error).extend({stack:{get:function(){return this._stack||(this._stack=this.name+": "+this.message+e(this._e,2))}},toString:function(){return this.name+": "+this.message}}),y(N).from(B),y(q).from(B);var zn=Rn.reduce(function(n,t){return n[t]=t+"Error",n},{}),Vn=B,Ln=Rn.reduce(function(n,e){function r(n,r){this._e=t(),this.name=i,n?"string"==typeof n?(this.message=n,this.inner=r||null):"object"==typeof n&&(this.message=n.name+" "+n.message,this.inner=n):(this.message=Un[e]||i,this.inner=null)}var i=e+"Error";return y(r).from(Vn),n[e]=r,n},{});Ln.Syntax=SyntaxError,Ln.Type=TypeError,Ln.Range=RangeError;var Wn=Fn.reduce(function(n,t){return n[t+"Error"]=Ln[t],n},{}),Hn=Rn.reduce(function(n,t){return-1===["Syntax","Type","Range"].indexOf(t)&&(n[t+"Error"]=Ln[t]),n},{});Hn.ModifyError=N,Hn.DexieError=B,Hn.BulkError=q;var Gn={},Jn=100,Qn=20,Yn=!1,$n="undefined"==typeof setImmediate?function(){setTimeout(Y,0)}:setImmediate.bind(null,Y),Xn=function(n,t){at.push([n,t]),nt&&($n(),nt=!1)},Zn=!0,nt=!0,tt=[],et=[],rt=null,it=i,ot={global:!0,ref:0,unhandleds:[],onunhandled:sn,finalize:function(){this.unhandleds.forEach(function(n){try{sn(n[0],n[1])}catch(t){}})}},ut=ot,at=[],ct=0,st=[];p(U.prototype,{then:function(n,t){var e=this,r=new U(function(r,i){H(e,new z(n,t,r,i))});return In&&(!this._prev||null===this._state)&&Q(r,this),r},_then:function(n,t){H(this,new z(null,null,n,t))},"catch":function(n){if(1===arguments.length)return this.then(null,n);var t=arguments[0],e=arguments[1];return"function"==typeof t?this.then(null,function(n){return n instanceof t?e(n):on(n)}):this.then(null,function(n){return n&&n.name===t?e(n):on(n)})},"finally":function(n){return this.then(function(t){return n(),t},function(t){return n(),on(t)})},uncaught:function(n){var t=this;return this.onuncatched=f(this.onuncatched,n),this._state===!1&&-1===tt.indexOf(this)&&tt.some(function(n,e,r){return n._value===t._value&&(r[e]=t)}),this},stack:{get:function(){if(this._stack)return this._stack;try{Yn=!0;var n=J(this,[],Qn),t=n.join("\nFrom previous: ");return null!==this._state&&(this._stack=t),t}finally{Yn=!1}}}}),p(U,{all:function(){var n=T.apply(null,arguments);return new U(function(t,e){0===n.length&&t([]);var r=n.length;n.forEach(function(i,o){return U.resolve(i).then(function(e){n[o]=e,--r||t(n)},e)})})},resolve:function(n){return n&&"function"==typeof n.then?n:new U(Gn,!0,n)},reject:on,race:function(){var n=T.apply(null,arguments);return new U(function(t,e){n.map(function(n){return U.resolve(n).then(t,e)})})},PSD:{get:function(){return ut},set:function(n){return ut=n}},newPSD:an,usePSD:cn,scheduler:{get:function(){return Xn},set:function(n){Xn=n}},rejectionMapper:{get:function(){return it},set:function(n){it=n}},follow:function(n){return new U(function(t,e){return an(function(t,e){var r=ut;r.unhandleds=[],r.onunhandled=e,r.finalize=u(function(){var n=this;nn(function(){0===n.unhandleds.length?t():e(n.unhandleds[0])})},r.finalize),n()},t,e)})},on:R(null,{error:[f,rn]})}),_(function(){Xn=function(n,t){setTimeout(function(){n.apply(null,t)},0)}});var ft="1.4.1",lt=String.fromCharCode(65535),ht=function(){try{return IDBKeyRange.only([[]]),[[]]}catch(n){return lt}}(),dt="Invalid key provided. Keys must be of type string, number, Date or Array<string | number | Date>.",pt="String expected.",vt=[],yt="undefined"!=typeof navigator&&/(MSIE|Trident|Edge)/.test(navigator.userAgent),mt=yt,gt=yt,bt=function(n){return!/(dexie\.js|dexie\.min\.js)/.test(n)};n(In,bt);var _t=function(){},wt=!1,kt=jn.idbModules&&jn.idbModules.shimIndexedDB?jn.idbModules:{};return p(fn,Hn),p(fn,{"delete":function(n){var t=new fn(n),e=t["delete"]();return e.onblocked=function(n){return t.on("blocked",n),this},e},exists:function(n){return new fn(n).open().then(function(n){return n.close(),!0})["catch"](fn.NoSuchDatabaseError,function(){return!1})},getDatabaseNames:function(n){return new U(function(n,t){var e=xn(indexedDB);if(e){var r=e();r.onsuccess=function(t){n(g(t.target.result,0))},r.onerror=vn(t)}else gn(function(t){return n(t),!1})}).then(n)},defineClass:function(n){function t(t){t?h(this,t):wt&&hn(this,n)}return t},applyStructure:hn,ignoreTransaction:function(n){return ut.trans?cn(ut.transless,n):n()},vip:function(n){return an(function(){return ut.letThrough=!0,n()})},async:function(n){return function(){try{var t=bn(n.apply(this,arguments));return t&&"function"==typeof t.then?t:U.resolve(t)}catch(e){return E(e)}}},spawn:function(n,t,e){try{var r=bn(n.apply(e,t||[]));return r&&"function"==typeof r.then?r:U.resolve(r)}catch(i){return E(i)}},currentTransaction:{get:function(){return ut.trans||null}},Promise:U,debug:{get:function(){return In},set:function(t){n(t,"dexie"===t?function(){return!0}:bt)}},derive:y,extend:h,props:p,override:b,Events:R,events:R,getByKeyPath:C,setByKeyPath:O,delByKeyPath:j,shallowClone:P,deepClone:D,getObjectDiff:S,asap:k,maxKey:ht,addons:[],connections:vt,MultiModifyError:Ln.Modify,errnames:zn,IndexSpec:_n,TableSchema:wn,dependencies:{indexedDB:kt.shimIndexedDB||jn.indexedDB||jn.mozIndexedDB||jn.webkitIndexedDB||jn.msIndexedDB,IDBKeyRange:kt.IDBKeyRange||jn.IDBKeyRange||jn.webkitIDBKeyRange},semVer:ft,version:ft.split(".").map(function(n){return parseInt(n)}).reduce(function(n,t,e){return n+t/Math.pow(10,2*e)}),fakeAutoComplete:_t,"default":fn}),A(function(){fn.dependencies.localStorage=null!=("undefined"!=typeof chrome&&null!==chrome?chrome.storage:void 0)?null:jn.localStorage}),U.rejectionMapper=F,_(function(){fn.fakeAutoComplete=_t=_,fn.fake=wt=!0}),fn});
-//# sourceMappingURL=dist/dexie.min.js.map \ No newline at end of file
+!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.Dexie=b()}(this,function(){"use strict";function d(b,c){return"object"!=typeof c?b:(a(c).forEach(function(a){b[a]=c[a]}),b)}function g(a,b){return f.call(a,b)}function h(b,c){"function"==typeof c&&(c=c(e(b))),a(c).forEach(function(a){j(b,a,c[a])})}function j(a,b,c,e){i(a,b,d(c&&g(c,"get")&&"function"==typeof c.get?{get:c.get,set:c.set,configurable:!0}:{value:c,configurable:!0,writable:!0},e))}function k(a){return{from:function(b){return a.prototype=Object.create(b.prototype),j(a.prototype,"constructor",a),{extend:h.bind(null,a.prototype)}}}}function m(a,b){var d,c=l(a,b);return c||(d=e(a))&&m(d,b)}function o(a,b,c){return n.call(a,b,c)}function p(a,b){return b(a)}function q(a){var b=setTimeout(a,1e3);clearTimeout(b)}function r(a){if(!a)throw new Error("Assertion Failed")}function s(a){c.setImmediate?setImmediate(a):setTimeout(a,0)}function t(a,b){return a.reduce(function(a,c,d){var e=b(c,d);return e&&(a[e[0]]=e[1]),a},{})}function u(a,b){return function(){try{a.apply(this,arguments)}catch(a){b(a)}}}function v(a,b,c){try{a.apply(null,c)}catch(a){b&&b(a)}}function w(a,b){if(g(a,b))return a[b];if(!b)return a;if("string"!=typeof b){for(var c=[],d=0,e=b.length;d<e;++d){var f=w(a,b[d]);c.push(f)}return c}var h=b.indexOf(".");if(h!==-1){var i=a[b.substr(0,h)];return void 0===i?void 0:w(i,b.substr(h+1))}}function x(a,b,c){if(a&&void 0!==b&&!("isFrozen"in Object&&Object.isFrozen(a)))if("string"!=typeof b&&"length"in b){r("string"!=typeof c&&"length"in c);for(var d=0,e=b.length;d<e;++d)x(a,b[d],c[d])}else{var f=b.indexOf(".");if(f!==-1){var g=b.substr(0,f),h=b.substr(f+1);if(""===h)void 0===c?delete a[g]:a[g]=c;else{var i=a[g];i||(i=a[g]={}),x(i,h,c)}}else void 0===c?delete a[b]:a[b]=c}}function y(a,b){"string"==typeof b?x(a,b,void 0):"length"in b&&[].map.call(b,function(b){x(a,b,void 0)})}function z(a){var b={};for(var c in a)g(a,c)&&(b[c]=a[c]);return b}function A(a){if(!a||"object"!=typeof a)return a;var c;if(b(a)){c=[];for(var d=0,e=a.length;d<e;++d)c.push(A(a[d]))}else if(a instanceof Date)c=new Date,c.setTime(a.getTime());else{c=a.constructor?Object.create(a.constructor.prototype):{};for(var f in a)g(a,f)&&(c[f]=A(a[f]))}return c}function B(b,c,d,e){return d=d||{},e=e||"",a(b).forEach(function(a){if(g(c,a)){var f=b[a],h=c[a];"object"==typeof f&&"object"==typeof h&&f&&h&&f.constructor===h.constructor?B(f,h,d,e+a+"."):f!==h&&(d[e+a]=c[a])}else d[e+a]=void 0}),a(c).forEach(function(a){g(b,a)||(d[e+a]=c[a])}),d}function F(a){var c,d,e,f;if(1===arguments.length){if(b(a))return a.slice();if(this===E&&"string"==typeof a)return[a];if(f=D(a)){for(d=[];e=f.next(),!e.done;)d.push(e.value);return d}if(null==a)return[a];if(c=a.length,"number"==typeof c){for(d=new Array(c);c--;)d[c]=a[c];return d}return[a]}for(c=arguments.length,d=new Array(c);c--;)d[c]=arguments[c];return d}function H(a){return G.apply([],a)}function J(a,b){I=a,K=b}function M(){if(L)try{throw M.arguments,new Error}catch(a){return a}return new Error}function N(a,b){var c=a.stack;return c?(b=b||0,0===c.indexOf(a.name)&&(b+=(a.name+a.message).split("\n").length),c.split("\n").slice(b).filter(K).map(function(a){return"\n"+a}).join("")):""}function O(a,b){return function(){return console.warn(a+" is deprecated. See https://github.com/dfahlander/Dexie.js/wiki/Deprecations. "+N(M(),1)),b.apply(this,arguments)}}function T(a,b){this._e=M(),this.name=a,this.message=b}function U(a,b){return a+". Errors: "+b.map(function(a){return a.toString()}).filter(function(a,b,c){return c.indexOf(a)===b}).join("\n")}function V(a,b,c,d){this._e=M(),this.failures=b,this.failedKeys=d,this.successCount=c}function W(a,b){this._e=M(),this.name="BulkError",this.failures=b,this.message=U(a,b)}function _(a,b){if(!a||a instanceof T||a instanceof TypeError||a instanceof SyntaxError||!a.name||!$[a.name])return a;var c=new $[a.name](b||a.message,a);return"stack"in a&&j(c,"stack",{get:function(){return this.inner.stack}}),c}function ba(){}function ca(a){return a}function da(a,b){return null==a||a===ca?b:function(c){return b(a(c))}}function ea(a,b){return function(){a.apply(this,arguments),b.apply(this,arguments)}}function fa(a,b){return a===ba?b:function(){var c=a.apply(this,arguments);void 0!==c&&(arguments[0]=c);var d=this.onsuccess,e=this.onerror;this.onsuccess=null,this.onerror=null;var f=b.apply(this,arguments);return d&&(this.onsuccess=this.onsuccess?ea(d,this.onsuccess):d),e&&(this.onerror=this.onerror?ea(e,this.onerror):e),void 0!==f?f:c}}function ga(a,b){return a===ba?b:function(){a.apply(this,arguments);var c=this.onsuccess,d=this.onerror;this.onsuccess=this.onerror=null,b.apply(this,arguments),c&&(this.onsuccess=this.onsuccess?ea(c,this.onsuccess):c),d&&(this.onerror=this.onerror?ea(d,this.onerror):d)}}function ha(a,b){return a===ba?b:function(c){var e=a.apply(this,arguments);d(c,e);var f=this.onsuccess,g=this.onerror;this.onsuccess=null,this.onerror=null;var h=b.apply(this,arguments);return f&&(this.onsuccess=this.onsuccess?ea(f,this.onsuccess):f),g&&(this.onerror=this.onerror?ea(g,this.onerror):g),void 0===e?void 0===h?void 0:h:d(e,h)}}function ia(a,b){return a===ba?b:function(){return b.apply(this,arguments)!==!1&&a.apply(this,arguments)}}function ja(a,b){return a===ba?b:function(){var c=a.apply(this,arguments);if(c&&"function"==typeof c.then){for(var d=this,e=arguments.length,f=new Array(e);e--;)f[e]=arguments[e];return c.then(function(){return b.apply(d,f)})}return b.apply(this,arguments)}}function Ja(a){if("object"!=typeof this)throw new TypeError("Promises must be constructed via new");this._listeners=[],this.onuncatched=ba,this._lib=!1;var b=this._PSD=Fa;if(I&&(this._stackHolder=M(),this._prev=null,this._numPrev=0,Sa(this,Ca)),"function"!=typeof a){if(a!==ka)throw new TypeError("Not a function");return this._state=arguments[1],this._value=arguments[2],void(this._state===!1&&Na(this,this._value))}this._state=null,this._value=null,++b.ref,Ma(this,a)}function La(a,b,c,d,e){this.onFulfilled="function"==typeof a?a:null,this.onRejected="function"==typeof b?b:null,this.resolve=c,this.reject=d,this.psd=e}function Ma(a,b){try{b(function(b){if(null===a._state){if(b===a)throw new TypeError("A promise cannot be resolved with itself.");var c=a._lib&&Ua();b&&"function"==typeof b.then?Ma(a,function(a,c){b instanceof Ja?b._then(a,c):b.then(a,c)}):(a._state=!0,a._value=b,Oa(a)),c&&Va()}},Na.bind(null,a))}catch(b){Na(a,b)}}function Na(a,b){if(Ba.push(b),null===a._state){var c=a._lib&&Ua();b=Da(b),a._state=!1,a._value=b,I&&null!==b&&"object"==typeof b&&!b._promise&&v(function(){var c=m(b,"stack");b._promise=a,j(b,"stack",{get:function(){return va?c&&(c.get?c.get.apply(b):c.value):a.stack}})}),Ya(a),Oa(a),c&&Va()}}function Oa(a){var b=a._listeners;a._listeners=[];for(var c=0,d=b.length;c<d;++c)Pa(a,b[c]);var e=a._PSD;--e.ref||e.finalize(),0===Ha&&(++Ha,xa(function(){0===--Ha&&Wa()},[]))}function Pa(a,b){if(null===a._state)return void a._listeners.push(b);var c=a._state?b.onFulfilled:b.onRejected;return null===c?(a._state?b.resolve:b.reject)(a._value):(++b.psd.ref,++Ha,void xa(Qa,[c,a,b]))}function Qa(a,b,c){try{Ca=b;var d,e=b._value;b._state?d=a(e):(Ba.length&&(Ba=[]),d=a(e),Ba.indexOf(e)===-1&&Za(b)),c.resolve(d)}catch(a){c.reject(a)}finally{Ca=null,0===--Ha&&Wa(),--c.psd.ref||c.psd.finalize()}}function Ra(a,b,c){if(b.length===c)return b;var d="";if(a._state===!1){var f,g,e=a._value;null!=e?(f=e.name||"Error",g=e.message||e,d=N(e,0)):(f=e,g=""),b.push(f+(g?": "+g:"")+d)}return I&&(d=N(a._stackHolder,2),d&&b.indexOf(d)===-1&&b.push(d),a._prev&&Ra(a._prev,b,c)),b}function Sa(a,b){var c=b?b._numPrev+1:0;c<la&&(a._prev=b,a._numPrev=c)}function Ta(){Ua()&&Va()}function Ua(){var a=ya;return ya=!1,za=!1,a}function Va(){var a,b,c;do for(;Ga.length>0;)for(a=Ga,Ga=[],c=a.length,b=0;b<c;++b){var d=a[b];d[0].apply(null,d[1])}while(Ga.length>0);ya=!0,za=!0}function Wa(){var a=Aa;Aa=[],a.forEach(function(a){a._PSD.onunhandled.call(null,a._value,a)});for(var b=Ia.slice(0),c=b.length;c;)b[--c]()}function Xa(a){function b(){a(),Ia.splice(Ia.indexOf(b),1)}Ia.push(b),++Ha,xa(function(){0===--Ha&&Wa()},[])}function Ya(a){Aa.some(function(b){return b._value===a._value})||Aa.push(a)}function Za(a){for(var b=Aa.length;b;)if(Aa[--b]._value===a._value)return void Aa.splice(b,1)}function $a(a){return new Ja(ka,!1,a)}function _a(a,b){var c=Fa;return function(){var d=Ua(),e=Fa;try{return mb(c,!0),a.apply(this,arguments)}catch(a){b&&b(a)}finally{mb(e,!1),d&&Va()}}}function gb(a,b,c,e){var f=Fa,g=Object.create(f);g.parent=f,g.ref=0,g.global=!1,g.id=++fb;var h=Ea.env;g.env=sa?{Promise:Ja,all:Ja.all,race:Ja.race,resolve:Ja.resolve,reject:Ja.reject,nthen:rb(h.nthen,g),gthen:rb(h.gthen,g)}:{},b&&d(g,b),++f.ref,g.finalize=function(){--this.parent.ref||this.parent.finalize()};var i=ob(g,a,c,e);return 0===g.ref&&g.finalize(),i}function hb(){return ab.id||(ab.id=++bb),++ab.awaits,ab.echoes+=na,ab.id}function ib(a){!ab.awaits||a&&a!==ab.id||(0===--ab.awaits&&(ab.id=0),ab.echoes=ab.awaits*na)}function jb(a){return ab.echoes&&a&&a.constructor===ta?(hb(),a.then(function(a){return ib(),a},function(a){return ib(),ub(a)})):a}function kb(a){++eb,ab.echoes&&0!==--ab.echoes||(ab.echoes=ab.id=0),cb.push(Fa),mb(a,!0)}function lb(){var a=cb[cb.length-1];cb.pop(),mb(a,!1)}function mb(a,b){var d=Fa;if((b?!ab.echoes||db++&&a===Fa:!db||--db&&a===Fa)||pb(b?kb.bind(null,a):lb),a!==Fa){Fa=a,d===Ea&&(Ea.env=nb());var e=Ea.env.Promise;if(e){var f=a.env;qa.then=f.nthen,e.prototype.then=f.gthen,(d.global||a.global)&&(c.Promise=f.Promise,e.all=f.all,e.race=f.race,e.resolve=f.resolve,e.reject=f.reject)}}}function nb(){var a=c.Promise;return a?{Promise:a,all:a.all,race:a.race,resolve:a.resolve,reject:a.reject,nthen:qa.then,gthen:a.prototype.then}:{}}function ob(a,b,c,d,e){var f=Fa;try{return mb(a,!0),b(c,d,e)}finally{mb(f,!1)}}function pb(a){sa.call(pa,a)}function qb(a,b,c){return"function"!=typeof a?a:function(){var d=Fa;c&&hb(),mb(b,!0);try{return a.apply(this,arguments)}finally{mb(d,!1)}}}function rb(a,b){return function(c,d){return a.call(this,qb(c,b,!1),qb(d,b,!1))}}function tb(a,b){var e;try{e=b.onuncatched(a)}catch(a){}if(e!==!1)try{var f,g={promise:b,reason:a};if(c.document&&document.createEvent?(f=document.createEvent("Event"),f.initEvent(sb,!0,!0),d(f,g)):c.CustomEvent&&(f=new CustomEvent(sb,{detail:g}),d(f,g)),f&&c.dispatchEvent&&(dispatchEvent(f),!c.PromiseRejectionEvent&&c.onunhandledrejection))try{c.onunhandledrejection(f)}catch(a){}f.defaultPrevented||console.warn("Unhandled rejection: "+(a.stack||a))}catch(a){}}function vb(c){function h(a,b,c){if("object"==typeof a)return i(a);b||(b=ia),c||(c=ba);var f={subscribers:[],fire:c,subscribe:function(a){f.subscribers.indexOf(a)===-1&&(f.subscribers.push(a),f.fire=b(f.fire,a))},unsubscribe:function(a){f.subscribers=f.subscribers.filter(function(b){return b!==a}),f.fire=f.subscribers.reduce(b,c)}};return d[a]=e[a]=f,f}function i(c){a(c).forEach(function(a){var d=c[a];if(b(d))h(a,c[a][0],c[a][1]);else{if("asap"!==d)throw new Z.InvalidArgument("Invalid event config");var e=h(a,ca,function(){for(var b=arguments.length,c=new Array(b);b--;)c[b]=arguments[b];e.subscribers.forEach(function(a){s(function(){a.apply(null,c)})})})}})}var d={},e=function(a,b){if(b){for(var e=arguments.length,f=new Array(e-1);--e;)f[e-1]=arguments[e];return d[a].subscribe.apply(null,f),c}if("string"==typeof a)return d[a]};e.addEventType=h;for(var f=1,g=arguments.length;f<g;++f)h(arguments[f]);return e}function Gb(c,e){function _(){Q.on("versionchange",function(a){a.newVersion>0?console.warn("Another connection wants to upgrade database '"+Q.name+"'. Closing db now to resume the upgrade."):console.warn("Another connection wants to delete database '"+Q.name+"'. Closing db now to resume the delete request."),Q.close()}),Q.on("blocked",function(a){!a.newVersion||a.newVersion<a.oldVersion?console.warn("Dexie.delete('"+Q.name+"') was blocked"):console.warn("Upgrade '"+Q.name+"' blocked by other connection holding version "+a.oldVersion/10)})}function aa(a){this._cfg={version:a,storesSource:null,dbschema:{},tables:{},contentUpgrade:null},this.stores({})}function ea(b,c,d){var e=Q._createTransaction(P,C,s);e.create(c),e._completion.catch(d);var f=e._reject.bind(e);gb(function(){Fa.trans=e,0===b?(a(s).forEach(function(a){la(c,a,s[a].primKey,s[a].indexes)}),Ja.follow(function(){return Q.on.populate.fire(e)}).catch(f)):ia(b,e,c).catch(f)})}function ia(a,b,c){function h(){return d.length?Ja.resolve(d.shift()(b.idbtrans)).then(h):Ja.resolve()}var d=[],e=y.filter(function(b){return b._cfg.version===a})[0];if(!e)throw new Z.Upgrade("Dexie specification of currently installed DB version is missing");s=Q._dbSchema=e._cfg.dbschema;var f=!1,g=y.filter(function(b){return b._cfg.version>a});return g.forEach(function(a){d.push(function(){var d=s,e=a._cfg.dbschema;Qa(d,c),Qa(e,c),s=Q._dbSchema=e;var g=ka(d,e);if(g.add.forEach(function(a){la(c,a[0],a[1].primKey,a[1].indexes)}),g.change.forEach(function(a){if(a.recreate)throw new Z.Upgrade("Not yet support for changing primary key");var b=c.objectStore(a.name);a.add.forEach(function(a){oa(b,a)}),a.change.forEach(function(a){b.deleteIndex(a.name),oa(b,a)}),a.del.forEach(function(a){b.deleteIndex(a)})}),a._cfg.contentUpgrade)return f=!0,Ja.follow(function(){a._cfg.contentUpgrade(b)})}),d.push(function(b){if(!f||!Db){var c=a._cfg.dbschema;na(c,b)}})}),h().then(function(){ma(s,c)})}function ka(a,b){var c={del:[],add:[],change:[]};for(var d in a)b[d]||c.del.push(d);for(d in b){var e=a[d],f=b[d];if(e){var g={name:d,def:f,recreate:!1,del:[],add:[],change:[]};if(e.primKey.src!==f.primKey.src)g.recreate=!0,c.change.push(g);else{var h=e.idxByName,i=f.idxByName;for(var j in h)i[j]||g.del.push(j);for(j in i){var k=h[j],l=i[j];k?k.src!==l.src&&g.change.push(l):g.add.push(l)}(g.del.length>0||g.add.length>0||g.change.length>0)&&c.change.push(g)}}else c.add.push([d,f])}return c}function la(a,b,c,d){var e=a.db.createObjectStore(b,c.keyPath?{keyPath:c.keyPath,autoIncrement:c.auto}:{autoIncrement:c.auto});return d.forEach(function(a){oa(e,a)}),e}function ma(b,c){a(b).forEach(function(a){c.db.objectStoreNames.contains(a)||la(c,a,b[a].primKey,b[a].indexes)})}function na(a,b){for(var c=0;c<b.db.objectStoreNames.length;++c){var d=b.db.objectStoreNames[c];null==a[d]&&b.db.deleteObjectStore(d)}}function oa(a,b){a.createIndex(b.name,b.keyPath,{unique:b.unique,multiEntry:b.multi})}function pa(a,b,c){if(L||Fa.letThrough){var d=Q._createTransaction(a,b,s).create();return d._promise(a,function(a,b){return gb(function(){return Fa.trans=d,c(a,b,d)})}).then(function(a){return d._completion.then(function(){return a})})}if(!K){if(!l)return ub(new Z.DatabaseClosed);Q.open().catch(ba)}return S.then(function(){return pa(a,b,c)})}function qa(a,b,c){var d=arguments.length;if(d<2)throw new Z.InvalidArgument("Too few arguments");for(var e=new Array(d-1);--d;)e[d-1]=arguments[d];c=e.pop();var f=H(e);return[a,f,c]}function ra(a,b){this.name=a,this.schema=b,this.hook=D[a]?D[a].hook:vb(null,{creating:[fa,ba],reading:[da,ca],updating:[ha,ba],deleting:[ga,ba]})}function sa(a,b,c){return(c?Ob:Mb)(function(c){a.push(c),b&&b()})}function va(a,b,c,d,e){return new Ja(function(f,g){var h=c.length,i=h-1;if(0===h)return f();if(d){var l,m=Ob(g),n=Lb(null);v(function(){for(var d=0;d<h;++d){l={onsuccess:null,onerror:null};var g=c[d];e.call(l,g[0],g[1],b);var j=a.delete(g[0]);j._hookCtx=l,j.onerror=m,d===i?j.onsuccess=Lb(f):j.onsuccess=n}},function(a){throw l.onerror&&l.onerror(a),a})}else for(var j=0;j<h;++j){var k=a.delete(c[j]);k.onerror=Mb(g),j===i&&(k.onsuccess=_a(function(){return f()}))}})}function wa(a,b,c,d){var e=this;this.db=Q,this.mode=a,this.storeNames=b,this.idbtrans=null,this.on=vb(this,"complete","error","abort"),this.parent=d||null,this.active=!0,this._tables=null,this._reculock=0,this._blockedFuncs=[],this._psd=null,this._dbschema=c,this._resolve=null,this._reject=null,this._completion=new Ja(function(a,b){e._resolve=a,e._reject=b}),this._completion.then(function(){e.on.complete.fire()},function(a){return e.on.error.fire(a),e.parent?e.parent._reject(a):e.active&&e.idbtrans&&e.idbtrans.abort(),e.active=!1,ub(a)})}function xa(a,b,c){this._ctx={table:a,index:":id"===b?null:b,or:c}}function ya(a,b){var c=null,d=null;if(b)try{c=b()}catch(a){d=a}var e=a._ctx,f=e.table;this._ctx={table:f,index:e.index,isPrimKey:!e.index||f.schema.primKey.keyPath&&e.index===f.schema.primKey.name,range:c,keysOnly:!1,dir:"next",unique:"",algorithm:null,filter:null,replayFilter:null,justLimit:!0,isMatch:null,offset:0,limit:1/0,error:d,or:e.or,valueMapper:f.hook.reading.fire}}function za(a,b){return!(a.filter||a.algorithm||a.or)&&(b?a.justLimit:!a.replayFilter)}function Aa(a,b){return a._cfg.version-b._cfg.version}function Ba(a,b,c){b.forEach(function(b){var d=Q._tableFactory(P,c[b]);a.forEach(function(a){b in a||(a[b]=d)})})}function Ca(a){a.forEach(function(a){for(var b in a)a[b]instanceof ra&&delete a[b]})}function Da(a,b,c,d,e,f){var g=f?function(a,b,d){return c(f(a),b,d)}:c,h=_a(g,e);a.onerror||(a.onerror=Mb(e)),b?a.onsuccess=u(function(){var f=a.result;if(f){var g=function(){f.continue()};b(f,function(a){g=a},d,e)&&h(f.value,f,function(a){g=a}),g()}else d()},e):a.onsuccess=u(function(){var c=a.result;if(c){var e=function(){c.continue()};h(c.value,c,function(a){e=a}),e()}else d()},e)}function Ea(a){var c=[];return a.split(",").forEach(function(a){a=a.trim();var d=a.replace(/([&*]|\+\+)/g,""),e=/^\[/.test(d)?d.match(/^\[(.*)\]$/)[1].split("+"):d;c.push(new Sb(d,e||null,/\&/.test(a),/\*/.test(a),/\+\+/.test(a),b(e),/\./.test(a)))}),c}function Ga(a,b){return m.cmp(a,b)}function Ha(a,b){return Ga(a,b)<0?a:b}function Ia(a,b){return Ga(a,b)>0?a:b}function Ka(a,b){return m.cmp(a,b)}function La(a,b){return m.cmp(b,a)}function Ma(a,b){return a<b?-1:a===b?0:1}function Na(a,b){return a>b?-1:a===b?0:1}function Oa(a,b){return a?b?function(){return a.apply(this,arguments)&&b.apply(this,arguments)}:a:b}function Pa(){if(Q.verno=G.version/10,Q._dbSchema=s={},C=o(G.objectStoreNames,0),0!==C.length){var b=G.transaction(Vb(C),"readonly");C.forEach(function(a){for(var c=b.objectStore(a),d=c.keyPath,e=d&&"string"==typeof d&&d.indexOf(".")!==-1,f=new Sb(d,d||"",!1,!1,!!c.autoIncrement,d&&"string"!=typeof d,e),g=[],h=0;h<c.indexNames.length;++h){var i=c.index(c.indexNames[h]);d=i.keyPath,e=d&&"string"==typeof d&&d.indexOf(".")!==-1;var j=new Sb(i.name,d,!!i.unique,!!i.multiEntry,!1,d&&"string"!=typeof d,e);g.push(j)}s[a]=new Tb(a,f,g,{})}),Ba([D],a(s),s)}}function Qa(a,b){for(var c=b.db.objectStoreNames,d=0;d<c.length;++d){var e=c[d],f=b.objectStore(e);$="getAll"in f;for(var g=0;g<f.indexNames.length;++g){var h=f.indexNames[g],i=f.index(h).keyPath,j="string"==typeof i?i:"["+o(i).join("+")+"]";if(a[e]){var k=a[e].idxByName[j];k&&(k.name=h)}}}}function Ra(a){Q.on("blocked").fire(a),Bb.filter(function(a){return a.name===Q.name&&a!==Q&&!a._vcFired}).map(function(b){return b.on("versionchange").fire(a)})}var R,T,$,f=Gb.dependencies,i=d({addons:Gb.addons,autoOpen:!0,indexedDB:f.indexedDB,IDBKeyRange:f.IDBKeyRange},e),k=i.addons,l=i.autoOpen,m=i.indexedDB,n=i.IDBKeyRange,s=this._dbSchema={},y=[],C=[],D={},G=null,J=null,K=!1,L=!1,N="readonly",P="readwrite",Q=this,S=new Ja(function(a){R=a}),U=new Ja(function(a,b){T=b}),X=!0,Y=!!Wb(m);this.version=function(a){if(G||K)throw new Z.Schema("Cannot add version when database is open");this.verno=Math.max(this.verno,a);var b=y.filter(function(b){return b._cfg.version===a})[0];return b?b:(b=new aa(a),y.push(b),y.sort(Aa),b)},d(aa.prototype,{stores:function(b){this._cfg.storesSource=this._cfg.storesSource?d(this._cfg.storesSource,b):b;var c={};y.forEach(function(a){d(c,a._cfg.storesSource)});var e=this._cfg.dbschema={};return this._parseStoresSpec(c,e),s=Q._dbSchema=e,Ca([D,Q,wa.prototype]),Ba([D,Q,wa.prototype,this._cfg.tables],a(e),e),C=a(e),this},upgrade:function(b){var c=this;return Hb(function(){b(Q._createTransaction(P,a(c._cfg.dbschema),c._cfg.dbschema))}),this._cfg.contentUpgrade=b,this},_parseStoresSpec:function(b,c){a(b).forEach(function(a){if(null!==b[a]){var d={},e=Ea(b[a]),f=e.shift();if(f.multi)throw new Z.Schema("Primary key cannot be multi-valued");f.keyPath&&x(d,f.keyPath,f.auto?0:f.keyPath),e.forEach(function(a){if(a.auto)throw new Z.Schema("Only primary key can be marked as autoIncrement (++)");if(!a.keyPath)throw new Z.Schema("Index must have a name and cannot be an empty string");x(d,a.keyPath,a.compound?a.keyPath.map(function(){return""}):"")}),c[a]=new Tb(a,f,e,d)}})}}),this._allTables=D,this._tableFactory=function(b,c){return new ra(c.name,c)},this._createTransaction=function(a,b,c,d){return new wa(a,b,c,d)},this._whenReady=function(a){return new Ja(Ib||L||Fa.letThrough?a:function(b,c){if(!K){if(!l)return void c(new Z.DatabaseClosed);Q.open().catch(ba)}S.then(function(){a(b,c)})})},this.verno=0,this.open=function(){if(K||G)return S.then(function(){return J?ub(J):Q});I&&(U._stackHolder=M()),K=!0,J=null,L=!1;var a=R,b=null;return Ja.race([U,new Ja(function(a,d){if(q(function(){return a()}),y.length>0&&(X=!1),!m)throw new Z.MissingAPI("indexedDB API not found. If using IE10+, make sure to run your code on a server URL (not locally). If using old Safari versions, make sure to include indexedDB polyfill.");var e=X?m.open(c):m.open(c,Math.round(10*Q.verno));if(!e)throw new Z.MissingAPI("IndexedDB API not available");e.onerror=Mb(d),e.onblocked=_a(Ra),e.onupgradeneeded=_a(function(a){if(b=e.transaction,X&&!Q._allowEmptyDB){e.onerror=Pb,b.abort(),e.result.close();var f=m.deleteDatabase(c);f.onsuccess=f.onerror=_a(function(){d(new Z.NoSuchDatabase("Database "+c+" doesnt exist"))})}else{b.onerror=Mb(d);var g=a.oldVersion>Math.pow(2,62)?0:a.oldVersion;ea(g/10,b,d,e)}},d),e.onsuccess=_a(function(){if(b=null,G=e.result,Bb.push(Q),X)Pa();else if(G.objectStoreNames.length>0)try{Qa(s,G.transaction(Vb(G.objectStoreNames),N))}catch(a){}G.onversionchange=_a(function(a){Q._vcFired=!0,Q.on("versionchange").fire(a)}),Y||Qb(function(a){if(a.indexOf(c)===-1)return a.push(c)}),a()},d)})]).then(function(){return Gb.vip(Q.on.ready.fire)}).then(function(){return K=!1,Q}).catch(function(a){try{b&&b.abort()}catch(a){}return K=!1,Q.close(),J=a,ub(J)}).finally(function(){L=!0,a()})},this.close=function(){var a=Bb.indexOf(Q);if(a>=0&&Bb.splice(a,1),G){try{G.close()}catch(a){}G=null}l=!1,J=new Z.DatabaseClosed,K&&T(J),S=new Ja(function(a){R=a}),U=new Ja(function(a,b){T=b})},this.delete=function(){var a=arguments.length>0;return new Ja(function(b,d){function e(){Q.close();var a=m.deleteDatabase(c);a.onsuccess=_a(function(){Y||Qb(function(a){var b=a.indexOf(c);if(b>=0)return a.splice(b,1)}),b()}),a.onerror=Mb(d),a.onblocked=Ra}if(a)throw new Z.InvalidArgument("Arguments not allowed in db.delete()");K?S.then(e):e()})},this.backendDB=function(){return G},this.isOpen=function(){return null!==G},this.hasFailed=function(){return null!==J},this.dynamicallyOpened=function(){return X},this.name=c,j(this,"tables",{get:function(){return a(D).map(function(a){return D[a]})}}),this.on=vb(this,"populate","blocked","versionchange",{ready:[ja,ba]}),this.on.ready.subscribe=p(this.on.ready.subscribe,function(a){return function(b,c){Gb.vip(function(){L?(J||Ja.resolve().then(b),c&&a(b)):(a(b),c||a(function a(){Q.on.ready.unsubscribe(b),Q.on.ready.unsubscribe(a)}))})}}),Hb(function(){Q.on("populate").fire(Q._createTransaction(P,C,s))}),this.transaction=function(){var a=qa.apply(this,arguments);return this._transaction.apply(this,a)},this._transaction=function(a,b,c){function g(b){var e=Fa;b(Ja.resolve().then(function(){var b=Fa.transless||e,g=Q._createTransaction(a,f,s,d),h={trans:g,transless:b};d?g.idbtrans=d.idbtrans:g.create(),c.constructor===ua&&hb();var i,j=Ja.follow(function(){if(i=c.call(g,g))if(i.constructor===ta){var a=ib.bind(null,null);i.then(a,a)}else"function"==typeof i.next&&"function"==typeof i.throw&&(i=Rb(i))},h);return Ja.resolve(i).finally(function(){if(!g.active)throw new Z.PrematureCommit("Transaction committed too early. See http://bit.ly/2eVASrf")}).then(function(a){return j.then(function(){d&&g._resolve()}).then(function(){return g._completion}).then(function(){return a})}).catch(function(a){return g._reject(a),ub(a)})}))}var d=Fa.trans;d&&d.db===Q&&a.indexOf("!")===-1||(d=null);var e=a.indexOf("?")!==-1;a=a.replace("!","").replace("?","");try{var f=b.map(function(a){var b=a instanceof ra?a.name:a;if("string"!=typeof b)throw new TypeError("Invalid table argument to Dexie.transaction(). Only Table or String are allowed");return b});if("r"==a||a==N)a=N;else{if("rw"!=a&&a!=P)throw new Z.InvalidArgument("Invalid transaction mode: "+a);a=P}if(d){if(d.mode===N&&a===P){if(!e)throw new Z.SubTransaction("Cannot enter a sub-transaction with READWRITE mode when parent transaction is READONLY");d=null}d&&f.forEach(function(a){if(d&&d.storeNames.indexOf(a)===-1){if(!e)throw new Z.SubTransaction("Table "+a+" not included in parent transaction.");d=null}})}}catch(a){return d?d._promise(null,function(b,c){c(a)}):ub(a)}return d?d._promise(a,g,"lock"):Q._whenReady(g)},this.table=function(a){if(Ib&&X)return new ra(a);if(!g(D,a))throw new Z.InvalidTable("Table "+a+" does not exist");return D[a]},h(ra.prototype,{_trans:function(b,c,d){var e=Fa.trans;return e&&e.db===Q?e._promise(b,c,d):pa(b,[this.name],c)},_idbstore:function(b,c,d){function g(a,b,d){c(a,b,d.idbtrans.objectStore(f),d)}if(Ib)return new Ja(c);var e=Fa.trans,f=this.name;return e&&e.db===Q?e._promise(b,g,d):pa(b,[this.name],g)},get:function(a,b){var c=this;return this._idbstore(N,function(b,d,e){Ib&&b(c.schema.instanceTemplate);var f=e.get(a);f.onerror=Mb(d),f.onsuccess=_a(function(){b(c.hook.reading.fire(f.result))},d)}).then(b)},where:function(a){return new xa(this,a)},count:function(a){return this.toCollection().count(a)},offset:function(a){return this.toCollection().offset(a)},limit:function(a){return this.toCollection().limit(a)},reverse:function(){return this.toCollection().reverse()},filter:function(a){return this.toCollection().and(a)},each:function(a){return this.toCollection().each(a)},toArray:function(a){return this.toCollection().toArray(a)},orderBy:function(a){return new ya(new xa(this,a))},toCollection:function(){return new ya(new xa(this))},mapToClass:function(a,b){this.schema.mappedClass=a;var c=Object.create(a.prototype);b&&Kb(c,b),this.schema.instanceTemplate=c;var d=function(b){if(!b)return b;var c=Object.create(a.prototype);for(var d in b)if(g(b,d))try{c[d]=b[d]}catch(a){}return c};return this.schema.readHook&&this.hook.reading.unsubscribe(this.schema.readHook),this.schema.readHook=d,this.hook("reading",d),a},defineClass:function(a){return this.mapToClass(Gb.defineClass(a),a)},bulkDelete:function(a){return this.hook.deleting.fire===ba?this._idbstore(P,function(b,c,d,e){b(va(d,e,a,!1,ba))}):this.where(":id").anyOf(a).delete().then(function(){})},bulkPut:function(a,b){var c=this;return this._idbstore(P,function(d,e,f){if(!f.keyPath&&!c.schema.primKey.auto&&!b)throw new Z.InvalidArgument("bulkPut() with non-inbound keys requires keys array in second argument");if(f.keyPath&&b)throw new Z.InvalidArgument("bulkPut(): keys argument invalid on tables with inbound keys");if(b&&b.length!==a.length)throw new Z.InvalidArgument("Arguments objects and keys must have the same length");if(0===a.length)return d();var h,j,g=function(a){0===i.length?d(a):e(new W(c.name+".bulkPut(): "+i.length+" of "+k+" operations failed",i))},i=[],k=a.length,l=c;if(c.hook.creating.fire===ba&&c.hook.updating.fire===ba){j=sa(i);for(var m=0,n=a.length;m<n;++m)h=b?f.put(a[m],b[m]):f.put(a[m]),h.onerror=j;h.onerror=sa(i,g),h.onsuccess=Nb(g)}else{var o=b||f.keyPath&&a.map(function(a){return w(a,f.keyPath)}),p=o&&t(o,function(b,c){return null!=b&&[b,a[c]]}),q=o?l.where(":id").anyOf(o.filter(function(a){return null!=a})).modify(function(){this.value=p[this.primKey],p[this.primKey]=null}).catch(V,function(a){i=a.failures}).then(function(){for(var c=[],d=b&&[],e=o.length-1;e>=0;--e){var f=o[e];(null==f||p[f])&&(c.push(a[e]),b&&d.push(f),null!=f&&(p[f]=null))}return c.reverse(),b&&d.reverse(),l.bulkAdd(c,d)}).then(function(a){var b=o[o.length-1];return null!=b?b:a}):l.bulkAdd(a);q.then(g).catch(W,function(a){i=i.concat(a.failures),g()}).catch(e)}},"locked")},bulkAdd:function(a,b){var c=this,d=this.hook.creating.fire;return this._idbstore(P,function(e,f,g,h){function i(a){0===k.length?e(a):f(new W(c.name+".bulkAdd(): "+k.length+" of "+n+" operations failed",k))}if(!g.keyPath&&!c.schema.primKey.auto&&!b)throw new Z.InvalidArgument("bulkAdd() with non-inbound keys requires keys array in second argument");if(g.keyPath&&b)throw new Z.InvalidArgument("bulkAdd(): keys argument invalid on tables with inbound keys");if(b&&b.length!==a.length)throw new Z.InvalidArgument("Arguments objects and keys must have the same length");if(0===a.length)return e();var j,l,m,k=[],n=a.length;if(d!==ba){var p,o=g.keyPath;l=sa(k,null,!0),m=Lb(null),v(function(){for(var c=0,e=a.length;c<e;++c){p={onerror:null,onsuccess:null};var f=b&&b[c],i=a[c],k=b?f:o?w(i,o):void 0,n=d.call(p,k,i,h);null==k&&null!=n&&(o?(i=A(i),x(i,o,n)):f=n),j=null!=f?g.add(i,f):g.add(i),j._hookCtx=p,c<e-1&&(j.onerror=l,p.onsuccess&&(j.onsuccess=m))}},function(a){throw p.onerror&&p.onerror(a),a}),j.onerror=sa(k,i,!0),j.onsuccess=Lb(i)}else{l=sa(k);for(var q=0,r=a.length;q<r;++q)j=b?g.add(a[q],b[q]):g.add(a[q]),j.onerror=l;j.onerror=sa(k,i),j.onsuccess=Nb(i)}})},add:function(a,b){var c=this.hook.creating.fire;return this._idbstore(P,function(d,e,f,g){var h={onsuccess:null,onerror:null};if(c!==ba){var i=null!=b?b:f.keyPath?w(a,f.keyPath):void 0,j=c.call(h,i,a,g);null==i&&null!=j&&(f.keyPath?x(a,f.keyPath,j):b=j)}try{var k=null!=b?f.add(a,b):f.add(a);k._hookCtx=h,k.onerror=Ob(e),k.onsuccess=Lb(function(b){var c=f.keyPath;c&&x(a,c,b),d(b)})}catch(a){throw h.onerror&&h.onerror(a),a}})},put:function(a,b){var c=this,d=this.hook.creating.fire,e=this.hook.updating.fire;if(d!==ba||e!==ba){var f=this.schema.primKey.keyPath,g=void 0!==b?b:f&&w(a,f);return null==g?this.add(a):(a=A(a),this._trans(P,function(){return c.where(":id").equals(g).modify(function(){this.value=a}).then(function(d){return 0===d?c.add(a,b):g})},"locked"))}return this._idbstore(P,function(c,d,e){var f=void 0!==b?e.put(a,b):e.put(a);f.onerror=Mb(d),f.onsuccess=_a(function(b){var d=e.keyPath;d&&x(a,d,b.target.result),c(f.result)})})},delete:function(a){return this.hook.deleting.subscribers.length?this.where(":id").equals(a).delete():this._idbstore(P,function(b,c,d){var e=d.delete(a);e.onerror=Mb(c),e.onsuccess=_a(function(){b(e.result)})})},clear:function(){return this.hook.deleting.subscribers.length?this.toCollection().delete():this._idbstore(P,function(a,b,c){var d=c.clear();d.onerror=Mb(b),d.onsuccess=_a(function(){a(d.result)})})},update:function(c,d){if("object"!=typeof d||b(d))throw new Z.InvalidArgument("Modifications must be an object.");if("object"!=typeof c||b(c))return this.where(":id").equals(c).modify(d);a(d).forEach(function(a){x(c,a,d[a])});var e=w(c,this.schema.primKey.keyPath);return void 0===e?ub(new Z.InvalidArgument("Given object does not contain its primary key")):this.where(":id").equals(e).modify(d)}}),h(wa.prototype,{_lock:function(){return r(!Fa.global),++this._reculock,1!==this._reculock||Fa.global||(Fa.lockOwnerFor=this),this},_unlock:function(){if(r(!Fa.global),0===--this._reculock)for(Fa.global||(Fa.lockOwnerFor=null);this._blockedFuncs.length>0&&!this._locked();){var a=this._blockedFuncs.shift();try{ob(a[1],a[0])}catch(a){}}return this},_locked:function(){return this._reculock&&Fa.lockOwnerFor!==this},create:function(a){var b=this;if(!this.mode)return this;if(r(!this.idbtrans),!a&&!G)switch(J&&J.name){case"DatabaseClosedError":throw new Z.DatabaseClosed(J);case"MissingAPIError":throw new Z.MissingAPI(J.message,J);default:throw new Z.OpenFailed(J)}if(!this.active)throw new Z.TransactionInactive;return r(null===this._completion._state),a=this.idbtrans=a||G.transaction(Vb(this.storeNames),this.mode),
+a.onerror=_a(function(c){Pb(c),b._reject(a.error)}),a.onabort=_a(function(a){Pb(a),b.active&&b._reject(new Z.Abort),b.active=!1,b.on("abort").fire(a)}),a.oncomplete=_a(function(){b.active=!1,b._resolve()}),this},_promise:function(a,b,c){var d=this;if(a===P&&this.mode!==P)return ub(new Z.ReadOnly("Transaction is readonly"));if(!this.active)return ub(new Z.TransactionInactive);if(this._locked())return new Ja(function(e,f){d._blockedFuncs.push([function(){d._promise(a,b,c).then(e,f)},Fa])});if(c)return gb(function(){var a=new Ja(function(a,c){d._lock();var e=b(a,c,d);e&&e.then&&e.then(a,c)});return a.finally(function(){return d._unlock()}),a._lib=!0,a});var e=new Ja(function(a,c){var e=b(a,c,d);e&&e.then&&e.then(a,c)});return e._lib=!0,e},abort:function(){this.active&&this._reject(new Z.Abort),this.active=!1},tables:{get:O("Transaction.tables",function(){return D})},table:O("Transaction.table()",function(a){return D[a]})}),h(xa.prototype,function(){function a(a,b,c){var d=a instanceof xa?new ya(a):a;return d._ctx.error=c?new c(b):new TypeError(b),d}function b(a){return new ya(a,function(){return n.only("")}).limit(0)}function c(a){return"next"===a?function(a){return a.toUpperCase()}:function(a){return a.toLowerCase()}}function d(a){return"next"===a?function(a){return a.toLowerCase()}:function(a){return a.toUpperCase()}}function e(a,b,c,d,e,f){for(var g=Math.min(a.length,d.length),h=-1,i=0;i<g;++i){var j=b[i];if(j!==d[i])return e(a[i],c[i])<0?a.substr(0,i)+c[i]+c.substr(i+1):e(a[i],d[i])<0?a.substr(0,i)+d[i]+c.substr(i+1):h>=0?a.substr(0,h)+b[h]+c.substr(h+1):null;e(a[i],j)<0&&(h=i)}return g<d.length&&"next"===f?a+c.substr(a.length):g<a.length&&"prev"===f?a.substr(0,c.length):h<0?null:a.substr(0,h)+d[h]+c.substr(h+1)}function f(b,f,g,h){function r(a){i=c(a),j=d(a),k="next"===a?Ma:Na;var b=g.map(function(a){return{lower:j(a),upper:i(a)}}).sort(function(a,b){return k(a.lower,b.lower)});l=b.map(function(a){return a.upper}),m=b.map(function(a){return a.lower}),o=a,p="next"===a?"":h}var i,j,k,l,m,o,p,q=g.length;if(!g.every(function(a){return"string"==typeof a}))return a(b,Ab);r("next");var s=new ya(b,function(){return n.bound(l[0],m[q-1]+h)});s._ondirectionchange=function(a){r(a)};var t=0;return s._addAlgorithm(function(a,b,c){var d=a.key;if("string"!=typeof d)return!1;var g=j(d);if(f(g,m,t))return!0;for(var h=null,i=t;i<q;++i){var n=e(d,g,l[i],m[i],k,o);null===n&&null===h?t=i+1:(null===h||k(h,n)>0)&&(h=n)}return b(null!==h?function(){a.continue(h+p)}:c),!1}),s}return{between:function(c,d,e,f){e=e!==!1,f=f===!0;try{return Ga(c,d)>0||0===Ga(c,d)&&(e||f)&&(!e||!f)?b(this):new ya(this,function(){return n.bound(c,d,!e,!f)})}catch(b){return a(this,zb)}},equals:function(a){return new ya(this,function(){return n.only(a)})},above:function(a){return new ya(this,function(){return n.lowerBound(a,!0)})},aboveOrEqual:function(a){return new ya(this,function(){return n.lowerBound(a)})},below:function(a){return new ya(this,function(){return n.upperBound(a,!0)})},belowOrEqual:function(a){return new ya(this,function(){return n.upperBound(a)})},startsWith:function(b){return"string"!=typeof b?a(this,Ab):this.between(b,b+xb,!0,!0)},startsWithIgnoreCase:function(a){return""===a?this.startsWith(a):f(this,function(a,b){return 0===a.indexOf(b[0])},[a],xb)},equalsIgnoreCase:function(a){return f(this,function(a,b){return a===b[0]},[a],"")},anyOfIgnoreCase:function(){var a=F.apply(E,arguments);return 0===a.length?b(this):f(this,function(a,b){return b.indexOf(a)!==-1},a,"")},startsWithAnyOfIgnoreCase:function(){var a=F.apply(E,arguments);return 0===a.length?b(this):f(this,function(a,b){return b.some(function(b){return 0===a.indexOf(b)})},a,xb)},anyOf:function(){var c=F.apply(E,arguments),d=Ka;try{c.sort(d)}catch(b){return a(this,zb)}if(0===c.length)return b(this);var e=new ya(this,function(){return n.bound(c[0],c[c.length-1])});e._ondirectionchange=function(a){d="next"===a?Ka:La,c.sort(d)};var f=0;return e._addAlgorithm(function(a,b,e){for(var g=a.key;d(g,c[f])>0;)if(++f,f===c.length)return b(e),!1;return 0===d(g,c[f])||(b(function(){a.continue(c[f])}),!1)}),e},notEqual:function(a){return this.inAnyRange([[-(1/0),a],[a,yb]],{includeLowers:!1,includeUppers:!1})},noneOf:function(){var b=F.apply(E,arguments);if(0===b.length)return new ya(this);try{b.sort(Ka)}catch(b){return a(this,zb)}var c=b.reduce(function(a,b){return a?a.concat([[a[a.length-1][1],b]]):[[-(1/0),b]]},null);return c.push([b[b.length-1],yb]),this.inAnyRange(c,{includeLowers:!1,includeUppers:!1})},inAnyRange:function(c,d){function g(a,b){for(var c=0,d=a.length;c<d;++c){var e=a[c];if(Ga(b[0],e[1])<0&&Ga(b[1],e[0])>0){e[0]=Ha(e[0],b[0]),e[1]=Ia(e[1],b[1]);break}}return c===d&&a.push(b),a}function i(a,b){return h(a[0],b[0])}function o(a){return!l(a)&&!m(a)}if(0===c.length)return b(this);if(!c.every(function(a){return void 0!==a[0]&&void 0!==a[1]&&Ka(a[0],a[1])<=0}))return a(this,"First argument to inAnyRange() must be an Array of two-value Arrays [lower,upper] where upper must not be lower than lower",Z.InvalidArgument);var j,e=!d||d.includeLowers!==!1,f=d&&d.includeUppers===!0,h=Ka;try{j=c.reduce(g,[]),j.sort(i)}catch(b){return a(this,zb)}var k=0,l=f?function(a){return Ka(a,j[k][1])>0}:function(a){return Ka(a,j[k][1])>=0},m=e?function(a){return La(a,j[k][0])>0}:function(a){return La(a,j[k][0])>=0},p=l,q=new ya(this,function(){return n.bound(j[0][0],j[j.length-1][1],!e,!f)});return q._ondirectionchange=function(a){"next"===a?(p=l,h=Ka):(p=m,h=La),j.sort(i)},q._addAlgorithm(function(a,b,c){for(var d=a.key;p(d);)if(++k,k===j.length)return b(c),!1;return!!o(d)||0!==Ga(d,j[k][1])&&0!==Ga(d,j[k][0])&&(b(function(){h===Ka?a.continue(j[k][0]):a.continue(j[k][1])}),!1)}),q},startsWithAnyOf:function(){var c=F.apply(E,arguments);return c.every(function(a){return"string"==typeof a})?0===c.length?b(this):this.inAnyRange(c.map(function(a){return[a,a+xb]})):a(this,"startsWithAnyOf() only works with strings")}}}),h(ya.prototype,function(){function b(a,b){a.filter=Oa(a.filter,b)}function c(a,b,c){var d=a.replayFilter;a.replayFilter=d?function(){return Oa(d(),b())}:b,a.justLimit=c&&!d}function e(a,b){a.isMatch=Oa(a.isMatch,b)}function f(a,b){if(a.isPrimKey)return b;var c=a.table.schema.idxByName[a.index];if(!c)throw new Z.Schema("KeyPath "+a.index+" on object store "+b.name+" is not indexed");return b.index(c.name)}function h(a,b){var c=f(a,b);return a.keysOnly&&"openKeyCursor"in c?c.openKeyCursor(a.range||null,a.dir+a.unique):c.openCursor(a.range||null,a.dir+a.unique)}function i(a,b,c,d,e){var f=a.replayFilter?Oa(a.filter,a.replayFilter()):a.filter;a.or?function(){function k(){2===++j&&c()}function l(a,c,e){if(!f||f(c,e,k,d)){var h=c.primaryKey.toString();g(i,h)||(i[h]=!0,b(a,c,e))}}var i={},j=0;a.or._iterate(l,k,d,e),Da(h(a,e),a.algorithm,l,k,d,!a.keysOnly&&a.valueMapper)}():Da(h(a,e),Oa(a.algorithm,f),b,c,d,!a.keysOnly&&a.valueMapper)}function j(a){return a.table.schema.instanceTemplate}return{_read:function(a,b){var c=this._ctx;return c.error?c.table._trans(null,function(b,d){d(c.error)}):c.table._idbstore(N,a).then(b)},_write:function(a){var b=this._ctx;return b.error?b.table._trans(null,function(c,d){d(b.error)}):b.table._idbstore(P,a,"locked")},_addAlgorithm:function(a){var b=this._ctx;b.algorithm=Oa(b.algorithm,a)},_iterate:function(a,b,c,d){return i(this._ctx,a,b,c,d)},clone:function(a){var b=Object.create(this.constructor.prototype),c=Object.create(this._ctx);return a&&d(c,a),b._ctx=c,b},raw:function(){return this._ctx.valueMapper=null,this},each:function(a){var b=this._ctx;if(Ib){var c=j(b),d=b.table.schema.primKey.keyPath,e=w(c,b.index?b.table.schema.idxByName[b.index].keyPath:d),f=w(c,d);a(c,{key:e,primaryKey:f})}return this._read(function(c,d,e){i(b,a,c,d,e)})},count:function(a){if(Ib)return Ja.resolve(0).then(a);var b=this._ctx;if(za(b,!0))return this._read(function(a,c,d){var e=f(b,d),g=b.range?e.count(b.range):e.count();g.onerror=Mb(c),g.onsuccess=function(c){a(Math.min(c.target.result,b.limit))}},a);var c=0;return this._read(function(a,d,e){i(b,function(){return++c,!1},function(){a(c)},d,e)},a)},sortBy:function(a,b){function f(a,b){return b?f(a[c[b]],b-1):a[d]}function h(a,b){var c=f(a,e),d=f(b,e);return c<d?-g:c>d?g:0}var c=a.split(".").reverse(),d=c[0],e=c.length-1,g="next"===this._ctx.dir?1:-1;return this.toArray(function(a){return a.sort(h)}).then(b)},toArray:function(a){var b=this._ctx;return this._read(function(a,c,d){if(Ib&&a([j(b)]),$&&"next"===b.dir&&za(b,!0)&&b.limit>0){var e=b.table.hook.reading.fire,g=f(b,d),h=b.limit<1/0?g.getAll(b.range,b.limit):g.getAll(b.range);h.onerror=Mb(c),h.onsuccess=Nb(e===ca?a:function(b){try{a(b.map(e))}catch(a){c(a)}})}else{var k=[];i(b,function(a){k.push(a)},function(){a(k)},c,d)}},a)},offset:function(a){var b=this._ctx;return a<=0?this:(b.offset+=a,za(b)?c(b,function(){var b=a;return function(a,c){return 0===b||(1===b?(--b,!1):(c(function(){a.advance(b),b=0}),!1))}}):c(b,function(){var b=a;return function(){return--b<0}}),this)},limit:function(a){return this._ctx.limit=Math.min(this._ctx.limit,a),c(this._ctx,function(){var b=a;return function(a,c,d){return--b<=0&&c(d),b>=0}},!0),this},until:function(a,c){var d=this._ctx;return Ib&&a(j(d)),b(this._ctx,function(b,d,e){return!a(b.value)||(d(e),c)}),this},first:function(a){return this.limit(1).toArray(function(a){return a[0]}).then(a)},last:function(a){return this.reverse().first(a)},filter:function(a){return Ib&&a(j(this._ctx)),b(this._ctx,function(b){return a(b.value)}),e(this._ctx,a),this},and:function(a){return this.filter(a)},or:function(a){return new xa(this._ctx.table,a,this)},reverse:function(){return this._ctx.dir="prev"===this._ctx.dir?"next":"prev",this._ondirectionchange&&this._ondirectionchange(this._ctx.dir),this},desc:function(){return this.reverse()},eachKey:function(a){var b=this._ctx;return b.keysOnly=!b.isMatch,this.each(function(b,c){a(c.key,c)})},eachUniqueKey:function(a){return this._ctx.unique="unique",this.eachKey(a)},eachPrimaryKey:function(a){var b=this._ctx;return b.keysOnly=!b.isMatch,this.each(function(b,c){a(c.primaryKey,c)})},keys:function(a){var b=this._ctx;b.keysOnly=!b.isMatch;var c=[];return this.each(function(a,b){c.push(b.key)}).then(function(){return c}).then(a)},primaryKeys:function(a){var b=this._ctx;if($&&"next"===b.dir&&za(b,!0)&&b.limit>0)return this._read(function(a,c,d){var e=f(b,d),g=b.limit<1/0?e.getAllKeys(b.range,b.limit):e.getAllKeys(b.range);g.onerror=Mb(c),g.onsuccess=Nb(a)}).then(a);b.keysOnly=!b.isMatch;var c=[];return this.each(function(a,b){c.push(b.primaryKey)}).then(function(){return c}).then(a)},uniqueKeys:function(a){return this._ctx.unique="unique",this.keys(a)},firstKey:function(a){return this.limit(1).keys(function(a){return a[0]}).then(a)},lastKey:function(a){return this.reverse().firstKey(a)},distinct:function(){var a=this._ctx,c=a.index&&a.table.schema.idxByName[a.index];if(!c||!c.multi)return this;var d={};return b(this._ctx,function(a){var b=a.primaryKey.toString(),c=g(d,b);return d[b]=!0,!c}),this},modify:function(b){var c=this,e=this._ctx,f=e.table.hook,h=f.updating.fire,i=f.deleting.fire;return Ib&&"function"==typeof b&&b.call({value:e.table.schema.instanceTemplate},e.table.schema.instanceTemplate),this._write(function(e,f,j,k){function y(a,b){function d(a){return s.push(a),t.push(c.primKey),D(),!0}u=b.primaryKey;var c={primKey:b.primaryKey,value:a,onsuccess:null,onerror:null};if(l.call(c,a,c)!==!1){var e=!g(c,"value");++p,v(function(){var a=e?b.delete():b.update(c.value);a._hookCtx=c,a.onerror=Ob(d),a.onsuccess=Lb(function(){++q,D()})},d)}else c.onsuccess&&c.onsuccess(c.value)}function C(a){return a&&(s.push(a),t.push(u)),f(new V("Error modifying one or more objects",s,q,t))}function D(){r&&q+s.length===p&&(s.length>0?C():e(q))}var l;if("function"==typeof b)l=h===ba&&i===ba?b:function(c){var d=A(c);if(b.call(this,c,this)===!1)return!1;if(g(this,"value")){var e=B(d,this.value),f=h.call(this,e,this.primKey,d,k);f&&(c=this.value,a(f).forEach(function(a){x(c,a,f[a])}))}else i.call(this,this.primKey,c,k)};else if(h===ba){var m=a(b),n=m.length;l=function(a){for(var c=!1,d=0;d<n;++d){var e=m[d],f=b[e];w(a,e)!==f&&(x(a,e,f),c=!0)}return c}}else{var o=b;b=z(o),l=function(c){var e=!1,f=h.call(this,b,this.primKey,A(c),k);return f&&d(b,f),a(b).forEach(function(a){var d=b[a];w(c,a)!==d&&(x(c,a,d),e=!0)}),f&&(b=z(o)),e}}var p=0,q=0,r=!1,s=[],t=[],u=null;c.clone().raw()._iterate(y,function(){r=!0,D()},C,j)})},delete:function(){var a=this,b=this._ctx,c=b.range,d=b.table.hook.deleting.fire,e=d!==ba;if(!e&&za(b)&&(b.isPrimKey&&!Eb||!c))return this._write(function(a,b,d){var e=Mb(b),f=c?d.count(c):d.count();f.onerror=e,f.onsuccess=function(){var g=f.result;v(function(){var b=c?d.delete(c):d.clear();b.onerror=e,b.onsuccess=function(){return a(g)}},function(a){return b(a)})}});var f=e?2e3:1e4;return this._write(function(c,g,h,i){var j=0,k=a.clone({keysOnly:!b.isMatch&&!e}).distinct().limit(f).raw(),l=[],m=function(){return k.each(e?function(a,b){l.push([b.primaryKey,b.value])}:function(a,b){l.push(b.primaryKey)}).then(function(){return e?l.sort(function(a,b){return Ka(a[0],b[0])}):l.sort(Ka),va(h,i,l,e,d)}).then(function(){var a=l.length;return j+=a,l=[],a<f?j:m()})};c(m())})}}}),d(this,{Collection:ya,Table:ra,Transaction:wa,Version:aa,WhereClause:xa}),_(),k.forEach(function(a){a(Q)})}function Jb(a){if("function"==typeof a)return new a;if(b(a))return[Jb(a[0])];if(a&&"object"==typeof a){var c={};return Kb(c,a),c}return a}function Kb(b,c){return a(c).forEach(function(a){var d=Jb(c[a]);b[a]=d}),b}function Lb(a){return _a(function(b){var c=b.target,d=c.result,e=c._hookCtx,f=e&&e.onsuccess;f&&f(d),a&&a(d)},a)}function Mb(a){return _a(function(b){return Pb(b),a(b.target.error),!1})}function Nb(a){return _a(function(b){a(b.target.result)})}function Ob(a){return _a(function(b){var c=b.target,d=c.error,e=c._hookCtx,f=e&&e.onerror;return f&&f(d),Pb(b),a(d),!1})}function Pb(a){a.stopPropagation&&a.stopPropagation(),a.preventDefault&&a.preventDefault()}function Qb(a){var b,c=Gb.dependencies.localStorage;if(!c)return a([]);try{b=JSON.parse(c.getItem("Dexie.DatabaseNames")||"[]")}catch(a){b=[]}a(b)&&c.setItem("Dexie.DatabaseNames",JSON.stringify(b))}function Rb(a){function g(a){return function(c){var d=a(c),g=d.value;return d.done?g:g&&"function"==typeof g.then?g.then(e,f):b(g)?Ja.all(g).then(e,f):e(g)}}var c=function(b){return a.next(b)},d=function(b){return a.throw(b)},e=g(c),f=g(d);return g(c)()}function Sb(a,b,c,d,e,f,g){this.name=a,this.keyPath=b,this.unique=c,this.multi=d,this.auto=e,this.compound=f,this.dotted=g;var h="string"==typeof b?b:b&&"["+[].join.call(b,"+")+"]";this.src=(c?"&":"")+(d?"*":"")+(e?"++":"")+h}function Tb(a,b,c,d){this.name=a,this.primKey=b||new Sb,this.indexes=c||[new Sb],this.instanceTemplate=d,this.mappedClass=null,this.idxByName=t(c,function(a){return[a.name,a]})}function Vb(a){return 1===a.length?a[0]:a}function Wb(a){var b=a&&(a.getDatabaseNames||a.webkitGetDatabaseNames);return b&&b.bind(a)}var a=Object.keys,b=Array.isArray,c="undefined"!=typeof self?self:"undefined"!=typeof window?window:global,e=Object.getPrototypeOf,f={}.hasOwnProperty,i=Object.defineProperty,l=Object.getOwnPropertyDescriptor,n=[].slice,C="undefined"!=typeof Symbol&&Symbol.iterator,D=C?function(a){var b;return null!=a&&(b=a[C])&&b.apply(a)}:function(){return null},E={},G=[].concat,I="undefined"!=typeof location&&/^(http|https):\/\/(localhost|127\.0\.0\.1)/.test(location.href),K=function(){return!0},L=!new Error("").stack,P=["Modify","Bulk","OpenFailed","VersionChange","Schema","Upgrade","InvalidTable","MissingAPI","NoSuchDatabase","InvalidArgument","SubTransaction","Unsupported","Internal","DatabaseClosed","PrematureCommit","ForeignAwait"],Q=["Unknown","Constraint","Data","TransactionInactive","ReadOnly","Version","NotFound","InvalidState","InvalidAccess","Abort","Timeout","QuotaExceeded","Syntax","DataClone"],R=P.concat(Q),S={VersionChanged:"Database version changed by other database connection",DatabaseClosed:"Database has been closed",Abort:"Transaction aborted",TransactionInactive:"Transaction has already completed or failed"};k(T).from(Error).extend({stack:{get:function(){return this._stack||(this._stack=this.name+": "+this.message+N(this._e,2))}},toString:function(){return this.name+": "+this.message}}),k(V).from(T),k(W).from(T);var X=R.reduce(function(a,b){return a[b]=b+"Error",a},{}),Y=T,Z=R.reduce(function(a,b){function d(a,d){this._e=M(),this.name=c,a?"string"==typeof a?(this.message=a,this.inner=d||null):"object"==typeof a&&(this.message=a.name+" "+a.message,this.inner=a):(this.message=S[b]||c,this.inner=null)}var c=b+"Error";return k(d).from(Y),a[b]=d,a},{});Z.Syntax=SyntaxError,Z.Type=TypeError,Z.Range=RangeError;var $=Q.reduce(function(a,b){return a[b+"Error"]=Z[b],a},{}),aa=R.reduce(function(a,b){return["Syntax","Type","Range"].indexOf(b)===-1&&(a[b+"Error"]=Z[b]),a},{});aa.ModifyError=V,aa.DexieError=T,aa.BulkError=W;var ka={},la=100,ma=20,na=7,oa=function(){try{return new Function("let F=async ()=>{},p=F();return [p,Object.getPrototypeOf(p),Promise.resolve(),F.constructor];")()}catch(b){var a=c.Promise;return a?[a.resolve(),a.prototype,a.resolve()]:[]}}(),pa=oa[0],qa=oa[1],ra=oa[2],sa=qa&&qa.then,ta=pa&&pa.constructor,ua=oa[3],va=!1,wa=ra?function(){ra.then(Ta)}:c.setImmediate?setImmediate.bind(null,Ta):c.MutationObserver?function(){var a=document.createElement("div");new MutationObserver(function(){Ta(),a=null}).observe(a,{attributes:!0}),a.setAttribute("i","1")}:function(){setTimeout(Ta,0)},xa=function(a,b){Ga.push([a,b]),za&&(wa(),za=!1)},ya=!0,za=!0,Aa=[],Ba=[],Ca=null,Da=ca,Ea={id:"global",global:!0,ref:0,unhandleds:[],onunhandled:tb,pgp:!1,env:{},finalize:function(){this.unhandleds.forEach(function(a){try{tb(a[0],a[1])}catch(a){}})}},Fa=Ea,Ga=[],Ha=0,Ia=[],Ka={get:function(){function c(c,d){var e=this,f=!a.global&&(a!==Fa||b!==eb);f&&ib();var g=new Ja(function(b,g){Pa(e,new La(qb(c,a,f),qb(d,a,f),b,g,a))});return I&&(!this._prev||null===this._state)&&Sa(g,this),g}var a=Fa,b=eb;return c._tQzo=!0,c},set:function(a){j(this,"then",a&&a._tQzo?Ka:{get:function(){return a},set:Ka.set})}};h(Ja.prototype,{then:Ka,_then:function(a,b){Pa(this,new La(null,null,a,b,Fa))},catch:function(a){if(1===arguments.length)return this.then(null,a);var b=arguments[0],c=arguments[1];return"function"==typeof b?this.then(null,function(a){return a instanceof b?c(a):$a(a)}):this.then(null,function(a){return a&&a.name===b?c(a):$a(a)})},finally:function(a){return this.then(function(b){return a(),b},function(b){return a(),$a(b)})},stack:{get:function(){if(this._stack)return this._stack;try{va=!0;var a=Ra(this,[],ma),b=a.join("\nFrom previous: ");return null!==this._state&&(this._stack=b),b}finally{va=!1}}}}),Ea.env=nb(),h(Ja,{all:function(){var a=F.apply(null,arguments).map(jb);return new Ja(function(b,c){0===a.length&&b([]);var d=a.length;a.forEach(function(e,f){return Ja.resolve(e).then(function(c){a[f]=c,--d||b(a)},c)})})},resolve:function(a){return a instanceof Ja?a:a&&"function"==typeof a.then?new Ja(function(b,c){a.then(b,c)}):new Ja(ka,!0,a)},reject:$a,race:function(){var a=F.apply(null,arguments).map(jb);return new Ja(function(b,c){a.map(function(a){return Ja.resolve(a).then(b,c)})})},PSD:{get:function(){return Fa},set:function(a){return Fa=a}},newPSD:gb,usePSD:ob,scheduler:{get:function(){return xa},set:function(a){xa=a}},rejectionMapper:{get:function(){return Da},set:function(a){Da=a}},follow:function(a,b){return new Ja(function(c,d){return gb(function(b,c){var d=Fa;d.unhandleds=[],d.onunhandled=c,d.finalize=ea(function(){var a=this;Xa(function(){0===a.unhandleds.length?b():c(a.unhandleds[0])})},d.finalize),a()},b,c,d)})}});var ab={awaits:0,echoes:0,id:0},bb=0,cb=[],db=0,eb=0,fb=0,sb="unhandledrejection";q(function(){xa=function(a,b){setTimeout(function(){a.apply(null,b)},0)}});var ub=Ja.reject,wb="2.0.0-beta.4",xb=String.fromCharCode(65535),yb=function(){try{return IDBKeyRange.only([[]]),[[]]}catch(a){return xb}}(),zb="Invalid key provided. Keys must be of type string, number, Date or Array<string | number | Date>.",Ab="String expected.",Bb=[],Cb="undefined"!=typeof navigator&&/(MSIE|Trident|Edge)/.test(navigator.userAgent),Db=Cb,Eb=Cb,Fb=function(a){return!/(dexie\.js|dexie\.min\.js)/.test(a)};J(I,Fb);var Hb=function(){},Ib=!1,Ub=c.idbModules&&c.idbModules.shimIndexedDB?c.idbModules:{};return h(Gb,aa),h(Gb,{delete:function(a){var b=new Gb(a),c=b.delete();return c.onblocked=function(a){return b.on("blocked",a),this},c},exists:function(a){return new Gb(a).open().then(function(a){return a.close(),!0}).catch(Gb.NoSuchDatabaseError,function(){return!1})},getDatabaseNames:function(a){return new Ja(function(a,b){var c=Wb(indexedDB);if(c){var d=c();d.onsuccess=function(b){a(o(b.target.result,0))},d.onerror=Mb(b)}else Qb(function(b){return a(b),!1})}).then(a)},defineClass:function(a){function b(b){b?d(this,b):Ib&&Kb(this,a)}return b},applyStructure:Kb,ignoreTransaction:function(a){return Fa.trans?ob(Fa.transless,a):a()},vip:function(a){return gb(function(){return Fa.letThrough=!0,a()})},async:function(a){return function(){try{var b=Rb(a.apply(this,arguments));return b&&"function"==typeof b.then?b:Ja.resolve(b)}catch(a){return ub(a)}}},spawn:function(a,b,c){try{var d=Rb(a.apply(c,b||[]));return d&&"function"==typeof d.then?d:Ja.resolve(d)}catch(a){return ub(a)}},currentTransaction:{get:function(){return Fa.trans||null}},Promise:Ja,debug:{get:function(){return I},set:function(a){J(a,"dexie"===a?function(){return!0}:Fb)}},derive:k,extend:d,props:h,override:p,Events:vb,getByKeyPath:w,setByKeyPath:x,delByKeyPath:y,shallowClone:z,deepClone:A,getObjectDiff:B,asap:s,maxKey:yb,addons:[],connections:Bb,MultiModifyError:Z.Modify,errnames:X,IndexSpec:Sb,TableSchema:Tb,dependencies:{indexedDB:Ub.shimIndexedDB||c.indexedDB||c.mozIndexedDB||c.webkitIndexedDB||c.msIndexedDB,IDBKeyRange:Ub.IDBKeyRange||c.IDBKeyRange||c.webkitIDBKeyRange},semVer:wb,version:wb.split(".").map(function(a){return parseInt(a)}).reduce(function(a,b,c){return a+b/Math.pow(10,2*c)}),fakeAutoComplete:Hb,default:Gb}),v(function(){Gb.dependencies.localStorage=null!=("undefined"!=typeof chrome&&null!==chrome?chrome.storage:void 0)?null:c.localStorage}),Ja.rejectionMapper=_,q(function(){Gb.fakeAutoComplete=Hb=q,Gb.fake=Ib=!0}),Gb}); \ No newline at end of file
diff --git a/ext/manifest.json b/ext/manifest.json
index 68357363..42972c73 100644
--- a/ext/manifest.json
+++ b/ext/manifest.json
@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "Yomichan",
- "version": "0.997",
+ "version": "0.998",
"description": "Japanese dictionary with Anki integration",
"icons": {"16": "img/icon16.png", "48": "img/icon48.png", "128": "img/icon128.png"},
diff --git a/tmpl/dictionary.html b/tmpl/dictionary.html
new file mode 100644
index 00000000..af0a6d28
--- /dev/null
+++ b/tmpl/dictionary.html
@@ -0,0 +1,26 @@
+<div class="dict-group well well-sm" data-title="{{title}}">
+ <h4><span class="text-muted glyphicon glyphicon-book"></span> {{title}} <small>v.{{version}}</small></h4>
+
+ <!-- <div class="row"> -->
+ <!-- <div class="col-xs-8"> -->
+ <!-- <h4><span class="text-muted glyphicon glyphicon-book"></span> {{title}} <small>v.{{version}}</small></h4> -->
+ <!-- </div> -->
+ <!-- <div class="col-xs-4 text-right disabled"> -->
+ <!-- <button type="button" class="dict-group-controls dict-delete btn btn-danger">Delete</button> -->
+ <!-- </div> -->
+ <!-- </div> -->
+
+ <div class="dict-delete-progress">
+ Dictionary data is being deleted, please be patient...
+ <div class="progress">
+ <div class="progress-bar progress-bar-striped progress-bar-danger" style="width: 0%"></div>
+ </div>
+ </div>
+
+ <div class="checkbox dict-group-controls {{#unless hasTerms}}disabled{{/unless}}">
+ <label><input type="checkbox" class="dict-enable-terms" {{#unless hasTerms}}disabled{{/unless}} {{#if enableTerms}}checked{{/if}}> Enable term search</label>
+ </div>
+ <div class="checkbox dict-group-controls {{#unless hasKanji}}disabled{{/unless}}">
+ <label><input type="checkbox" class="dict-enable-kanji" {{#unless hasKanji}}disabled{{/unless}} {{#if enableKanji}}checked{{/if}}> Enable Kanji search</label>
+ </div>
+</div>
diff --git a/tmpl/kanji-list.html b/tmpl/kanji-list.html
index d418eafd..af38d485 100644
--- a/tmpl/kanji-list.html
+++ b/tmpl/kanji-list.html
@@ -1,5 +1,9 @@
{{> header.html}}
-{{#each definitions}}
-{{> kanji.html addable=../addable root=../root options=../options sequence=../sequence}}
-{{/each}}
+{{#if definitions}}
+ {{#each definitions}}
+ {{> kanji.html addable=../addable root=../root options=../options sequence=../sequence}}
+ {{/each}}
+{{else}}
+ <p>No results found</p>
+{{/if}}
{{> footer.html}}
diff --git a/tmpl/kanji.html b/tmpl/kanji.html
index daa825be..e22dd660 100644
--- a/tmpl/kanji.html
+++ b/tmpl/kanji.html
@@ -30,15 +30,21 @@
<div class="kanji-tags">
{{#each tags}}
- <span class="tag tag-{{class}}" title="{{desc}}">{{name}}</span>
+ <span class="tag tag-{{category}}" title="{{notes}}">{{name}}</span>
{{/each}}
</div>
<div class="kanji-glossary">
+ {{#if glossary.[1]}}
<ol>
{{#each glossary}}
<li><span>{{.}}</span></li>
{{/each}}
</ol>
+ {{else}}
+ <p>
+ {{glossary.[0]}}
+ </p>
+ {{/if}}
</div>
</div>
diff --git a/tmpl/model.html b/tmpl/model.html
new file mode 100644
index 00000000..94772316
--- /dev/null
+++ b/tmpl/model.html
@@ -0,0 +1,18 @@
+<tr>
+ <td class="col-sm-2">{{name}}</td>
+ <td class="col-sm-10">
+ <div class="input-group">
+ <input type="text" class="anki-field-value form-control" data-field="{{name}}" value="{{value}}">
+ <div class="input-group-btn">
+ <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
+ <span class="caret"></span>
+ </button>
+ <ul class="dropdown-menu dropdown-menu-right">
+ {{#each markers}}
+ <li><a class="marker-link" href="#">{{.}}</a></li>
+ {{/each}}
+ </ul>
+ </div>
+ </div>
+ </td>
+</tr>
diff --git a/tmpl/term-list.html b/tmpl/term-list.html
index d0b060c8..2088ac71 100644
--- a/tmpl/term-list.html
+++ b/tmpl/term-list.html
@@ -1,5 +1,9 @@
{{> header.html}}
-{{#each definitions}}
-{{> term.html addable=../addable root=../root options=../options sequence=../sequence}}
-{{/each}}
+{{#if definitions}}
+ {{#each definitions}}
+ {{> term.html addable=../addable root=../root options=../options sequence=../sequence}}
+ {{/each}}
+{{else}}
+ <p>No results found</p>
+{{/if}}
{{> footer.html}}
diff --git a/tmpl/term.html b/tmpl/term.html
index 7d60e42a..e4a0d02b 100644
--- a/tmpl/term.html
+++ b/tmpl/term.html
@@ -15,23 +15,27 @@
<div class="term-expression">{{#kanjiLinks}}{{expression}}{{/kanjiLinks}}</div>
{{/if}}
- <div class="term-rules">
- {{#each rules}}
- <span class="rule">{{.}}</span> {{#unless @last}}&laquo;{{/unless}}
+ <div class="term-reasons">
+ {{#each reasons}}
+ <span class="reasons">{{.}}</span> {{#unless @last}}&laquo;{{/unless}}
{{/each}}
</div>
<div class="term-tags">
{{#each tags}}
- <span class="tag tag-{{class}}" title="{{desc}}">{{name}}</span>
+ <span class="tag tag-{{category}}" title="{{notes}}">{{name}}</span>
{{/each}}
</div>
<div class="term-glossary">
+ {{#if glossary.[1]}}
<ol>
{{#each glossary}}
<li><span>{{.}}</span></li>
{{/each}}
</ol>
+ {{else}}
+ <p>{{glossary.[0]}}</p>
+ {{/if}}
</div>
</div>