GameSentenceMiner 2.15.10__py3-none-any.whl → 2.15.12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. GameSentenceMiner/anki.py +31 -0
  2. GameSentenceMiner/ocr/owocr_helper.py +5 -5
  3. GameSentenceMiner/web/static/css/kanji-grid.css +107 -0
  4. GameSentenceMiner/web/static/css/search.css +14 -0
  5. GameSentenceMiner/web/static/css/shared.css +932 -0
  6. GameSentenceMiner/web/static/css/stats.css +499 -0
  7. GameSentenceMiner/web/static/js/anki_stats.js +84 -0
  8. GameSentenceMiner/web/static/js/database.js +541 -0
  9. GameSentenceMiner/web/static/js/kanji-grid.js +203 -0
  10. GameSentenceMiner/web/static/js/search.js +273 -0
  11. GameSentenceMiner/web/static/js/shared.js +506 -0
  12. GameSentenceMiner/web/static/js/stats.js +1427 -0
  13. GameSentenceMiner/web/templates/anki_stats.html +205 -0
  14. GameSentenceMiner/web/templates/components/navigation.html +16 -0
  15. GameSentenceMiner/web/templates/components/theme-styles.html +128 -0
  16. GameSentenceMiner/web/templates/stats.html +4 -0
  17. GameSentenceMiner/web/texthooking_page.py +50 -0
  18. {gamesentenceminer-2.15.10.dist-info → gamesentenceminer-2.15.12.dist-info}/METADATA +1 -1
  19. {gamesentenceminer-2.15.10.dist-info → gamesentenceminer-2.15.12.dist-info}/RECORD +23 -11
  20. GameSentenceMiner/web/templates/text_replacements.html +0 -449
  21. {gamesentenceminer-2.15.10.dist-info → gamesentenceminer-2.15.12.dist-info}/WHEEL +0 -0
  22. {gamesentenceminer-2.15.10.dist-info → gamesentenceminer-2.15.12.dist-info}/entry_points.txt +0 -0
  23. {gamesentenceminer-2.15.10.dist-info → gamesentenceminer-2.15.12.dist-info}/licenses/LICENSE +0 -0
  24. {gamesentenceminer-2.15.10.dist-info → gamesentenceminer-2.15.12.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,205 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Anki vs GSM Kanji Stats</title>
7
+ <!-- Include Chart.js from a CDN -->
8
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
9
+
10
+ <!-- Include shared theme styles -->
11
+ {% include 'components/theme-styles.html' %}
12
+
13
+ <!-- Include shared CSS -->
14
+ <link rel="stylesheet" href="/static/css/shared.css">
15
+
16
+ <!-- Include stats-specific CSS -->
17
+ <link rel="stylesheet" href="/static/css/stats.css">
18
+
19
+ <!-- Include shared kanji grid CSS -->
20
+ <link rel="stylesheet" href="/static/css/kanji-grid.css">
21
+ </head>
22
+ <body>
23
+
24
+ <div class="container">
25
+ <h1>Anki & GSM Kanji Statistics</h1>
26
+ <div style="text-align: center;">
27
+ <p>Must have <a href="https://ankiweb.net/shared/info/2055492159">AnkiConnect</a></p>
28
+ </div>
29
+
30
+ <!-- Include shared navigation -->
31
+ {% include 'components/navigation.html' %}
32
+
33
+ <!-- Dashboard Statistics Sections -->
34
+ <div class="dashboard-container">
35
+ <!-- Missing High-Frequency Kanji Card -->
36
+ <div class="dashboard-card current-game" id="missingKanjiCard">
37
+ <div class="dashboard-card-header">
38
+ <div>
39
+ <h3 class="dashboard-card-title">
40
+ <span class="dashboard-card-icon">🈚</span>
41
+ Missing High-Frequency Kanji
42
+ </h3>
43
+ <p class="dashboard-card-subtitle">Kanji seen often in GSM but not present in your Anki collection</p>
44
+ </div>
45
+ <div class="dashboard-streak-indicator" id="missingKanjiStreak" style="display: none;">
46
+ <span id="missingStreakValue">0</span> to learn
47
+ </div>
48
+ </div>
49
+
50
+ <div class="dashboard-stats-grid" id="missingKanjiStats">
51
+ <div class="dashboard-stat-item tooltip" data-tooltip="Number of high-frequency kanji missing from Anki">
52
+ <span class="dashboard-stat-value" id="missingKanjiCount">-</span>
53
+ <span class="dashboard-stat-label">Missing Kanji</span>
54
+ </div>
55
+ <div class="dashboard-stat-item tooltip" data-tooltip="Total kanji in your Anki collection">
56
+ <span class="dashboard-stat-value" id="ankiTotalKanji">-</span>
57
+ <span class="dashboard-stat-label">Kanji in Anki</span>
58
+ </div>
59
+ <div class="dashboard-stat-item tooltip" data-tooltip="Total unique kanji seen in GSM">
60
+ <span class="dashboard-stat-value" id="gsmTotalKanji">-</span>
61
+ <span class="dashboard-stat-label">Kanji in GSM</span>
62
+ </div>
63
+ <div class="dashboard-stat-item tooltip" data-tooltip="Percentage of GSM kanji covered by Anki">
64
+ <span class="dashboard-stat-value" id="ankiCoverage">-</span>
65
+ <span class="dashboard-stat-label">Coverage %</span>
66
+ </div>
67
+ </div>
68
+
69
+ <div class="dashboard-progress-section">
70
+ <div class="dashboard-progress-title">Missing Kanji Grid</div>
71
+ <div id="missingKanjiGridContainer">
72
+ <div id="missingKanjiGrid" class="kanji-grid"></div>
73
+ <div class="kanji-legend">
74
+ <span>Rarely Seen</span>
75
+ <div class="kanji-legend-item" style="background-color: #ebedf0;" title="No encounters"></div>
76
+ <div class="kanji-legend-item" style="background-color: #e6342e;" title="Seen once"></div>
77
+ <div class="kanji-legend-item" style="background-color: #e6dc2e;" title="Occasionally seen"></div>
78
+ <div class="kanji-legend-item" style="background-color: #3be62f;" title="Frequently seen"></div>
79
+ <div class="kanji-legend-item" style="background-color: #2ee6e0;" title="Most frequently seen"></div>
80
+ <span>Frequently Seen</span>
81
+ </div>
82
+ </div>
83
+ </div>
84
+ </div>
85
+
86
+ </div>
87
+
88
+ <!-- Loading/Error states for dashboard -->
89
+ <div class="dashboard-loading" id="ankiStatsLoading" style="display: none;">
90
+ <div class="spinner"></div>
91
+ <span>Loading Anki statistics...</span>
92
+ </div>
93
+
94
+ <div class="dashboard-error" id="ankiStatsError" style="display: none;">
95
+ <div class="dashboard-error-icon">⚠️</div>
96
+ <div class="dashboard-error-message">Failed to load Anki statistics</div>
97
+ <button class="dashboard-retry-btn" data-action="loadAnkiStats">Retry</button>
98
+ </div>
99
+
100
+
101
+ <!-- Settings Modal -->
102
+ <div id="ankiSettingsModal" class="modal">
103
+ <div class="modal-content">
104
+ <div class="modal-header">
105
+ <h3>Anki Statistics Settings</h3>
106
+ <span class="close-btn" id="closeAnkiSettingsModal">&times;</span>
107
+ </div>
108
+ <div class="modal-body">
109
+ <p style="color: var(--text-secondary); margin-bottom: 20px;">
110
+ Configure how Anki statistics and kanji analysis are calculated.
111
+ </p>
112
+
113
+ <form id="ankiSettingsForm">
114
+ <div style="margin-bottom: 20px;">
115
+ <label for="frequencyThreshold" style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
116
+ Minimum Frequency Threshold
117
+ </label>
118
+ <input
119
+ type="number"
120
+ id="frequencyThreshold"
121
+ name="frequency_threshold"
122
+ min="1"
123
+ max="1000"
124
+ style="width: 100%; padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;"
125
+ placeholder="10"
126
+ >
127
+ <small style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
128
+ Minimum times a kanji must appear in GSM to be considered for analysis (1-1000)
129
+ </small>
130
+ </div>
131
+
132
+ <div style="margin-bottom: 20px;">
133
+ <label for="coverageTarget" style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
134
+ Coverage Target (%)
135
+ </label>
136
+ <input
137
+ type="number"
138
+ id="coverageTarget"
139
+ name="coverage_target"
140
+ min="50"
141
+ max="100"
142
+ style="width: 100%; padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;"
143
+ placeholder="95"
144
+ >
145
+ <small style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
146
+ Target percentage coverage for Anki collection (50-100%)
147
+ </small>
148
+ </div>
149
+
150
+ <div style="margin-bottom: 20px;">
151
+ <label for="learningGoal" style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
152
+ Daily Learning Goal
153
+ </label>
154
+ <input
155
+ type="number"
156
+ id="learningGoal"
157
+ name="learning_goal"
158
+ min="1"
159
+ max="50"
160
+ style="width: 100%; padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;"
161
+ placeholder="5"
162
+ >
163
+ <small style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
164
+ Target number of new kanji to learn per day (1-50)
165
+ </small>
166
+ </div>
167
+
168
+ <div style="margin-bottom: 20px;">
169
+ <label for="priorityMode" style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
170
+ Priority Mode
171
+ </label>
172
+ <select
173
+ id="priorityMode"
174
+ name="priority_mode"
175
+ style="width: 100%; padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;"
176
+ >
177
+ <option value="frequency">By Frequency</option>
178
+ <option value="jlpt">By JLPT Level</option>
179
+ <option value="grade">By School Grade</option>
180
+ <option value="mixed">Mixed Approach</option>
181
+ </select>
182
+ <small style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
183
+ How to prioritize kanji for learning recommendations
184
+ </small>
185
+ </div>
186
+ </form>
187
+
188
+ <div id="ankiSettingsError" style="display: none; background: var(--danger-color); color: white; padding: 10px; border-radius: 5px; margin-bottom: 15px; font-size: 14px;"></div>
189
+ <div id="ankiSettingsSuccess" style="display: none; background: var(--success-color); color: white; padding: 10px; border-radius: 5px; margin-bottom: 15px; font-size: 14px;"></div>
190
+ </div>
191
+ <div class="modal-footer">
192
+ <button id="cancelAnkiSettingsBtn" class="cancel-btn">Cancel</button>
193
+ <button id="saveAnkiSettingsBtn" class="confirm-delete-btn">Save Settings</button>
194
+ </div>
195
+ </div>
196
+ </div>
197
+ </div>
198
+
199
+ <!-- Include shared JavaScript first (required dependency for anki_stats.js) -->
200
+ <script src="/static/js/shared.js"></script>
201
+ <script src="/static/js/kanji-grid.js"></script>
202
+ <script src="/static/js/anki_stats.js"></script>
203
+
204
+ </body>
205
+ </html>
@@ -0,0 +1,16 @@
1
+ <!-- Navigation Component -->
2
+ <div class="navigation" style="display: flex; justify-content: center; align-items: center; margin-bottom: 30px; padding: 15px; background: var(--bg-secondary); border-radius: 8px; box-shadow: 0 2px 8px var(--shadow-color); border: 1px solid var(--border-color);">
3
+ <div style="display: flex; gap: 15px;">
4
+ <a href="/" class="nav-link">Home</a>
5
+ <a href="/stats" class="nav-link">Statistics</a>
6
+ <a href="/search" class="nav-link">Search</a>
7
+ <a href="/database" class="nav-link">Database Management</a>
8
+ <a href="/anki_stats" class="nav-link">Anki Stats</a>
9
+ </div>
10
+ <button class="theme-toggle" id="settingsToggle" title="Settings">
11
+ <span id="settingsIcon">⚙️</span>
12
+ </button>
13
+ <button class="theme-toggle" id="themeToggle" title="Toggle dark mode">
14
+ <span id="themeIcon">🌙</span>
15
+ </button>
16
+ </div>
@@ -0,0 +1,128 @@
1
+ <!-- Theme Styles Component -->
2
+ <style>
3
+ :root {
4
+ /* Light theme colors */
5
+ --bg-primary: #f8f9fa;
6
+ --bg-secondary: #ffffff;
7
+ --bg-tertiary: #e9ecef;
8
+ --text-primary: #212529;
9
+ --text-secondary: #495057;
10
+ --text-tertiary: #6c757d;
11
+ --border-color: #dee2e6;
12
+ --shadow-color: rgba(0, 0, 0, 0.08);
13
+ --accent-color: #007bff;
14
+ --success-color: #28a745;
15
+ --warning-color: #ffc107;
16
+ --danger-color: #dc3545;
17
+ --info-color: #17a2b8;
18
+ }
19
+
20
+ [data-theme="dark"] {
21
+ /* Dark theme colors */
22
+ --bg-primary: #1a1a1a;
23
+ --bg-secondary: #2d2d2d;
24
+ --bg-tertiary: #3a3a3a;
25
+ --text-primary: #e1e1e1;
26
+ --text-secondary: #b8b8b8;
27
+ --text-tertiary: #8a8a8a;
28
+ --border-color: #404040;
29
+ --shadow-color: rgba(0, 0, 0, 0.3);
30
+ --accent-color: #4dabf7;
31
+ --success-color: #51cf66;
32
+ --warning-color: #ffd43b;
33
+ --danger-color: #ff6b6b;
34
+ --info-color: #22b8cf;
35
+ }
36
+
37
+ @media (prefers-color-scheme: dark) {
38
+ :root:not([data-theme="light"]) {
39
+ /* Auto dark mode colors */
40
+ --bg-primary: #1a1a1a;
41
+ --bg-secondary: #2d2d2d;
42
+ --bg-tertiary: #3a3a3a;
43
+ --text-primary: #e1e1e1;
44
+ --text-secondary: #b8b8b8;
45
+ --text-tertiary: #8a8a8a;
46
+ --border-color: #404040;
47
+ --shadow-color: rgba(0, 0, 0, 0.3);
48
+ --accent-color: #4dabf7;
49
+ --success-color: #51cf66;
50
+ --warning-color: #ffd43b;
51
+ --danger-color: #ff6b6b;
52
+ --info-color: #22b8cf;
53
+ }
54
+ }
55
+
56
+ /* Dark mode toggle button */
57
+ .theme-toggle {
58
+ background: var(--bg-tertiary);
59
+ border: 2px solid var(--border-color);
60
+ border-radius: 50%;
61
+ width: 40px;
62
+ height: 40px;
63
+ display: flex;
64
+ align-items: center;
65
+ justify-content: center;
66
+ cursor: pointer;
67
+ transition: all 0.3s ease;
68
+ color: var(--text-primary);
69
+ font-size: 18px;
70
+ margin-left: 15px;
71
+ }
72
+
73
+ .theme-toggle:hover {
74
+ background: var(--bg-primary);
75
+ transform: scale(1.1);
76
+ }
77
+
78
+ .theme-toggle:active {
79
+ transform: scale(0.95);
80
+ }
81
+
82
+ /* Navigation styles */
83
+ .nav-link {
84
+ display: inline-block;
85
+ padding: 8px 16px;
86
+ background-color: var(--bg-tertiary);
87
+ color: var(--text-primary);
88
+ text-decoration: none;
89
+ border-radius: 5px;
90
+ transition: all 0.3s ease;
91
+ border: 1px solid var(--border-color);
92
+ }
93
+
94
+ .nav-link:hover {
95
+ background-color: var(--accent-color);
96
+ color: var(--bg-secondary);
97
+ transform: translateY(-1px);
98
+ }
99
+
100
+ .navigation .nav-link:hover {
101
+ background-color: var(--accent-color) !important;
102
+ color: var(--bg-secondary) !important;
103
+ }
104
+
105
+ @media (max-width: 768px) {
106
+ .navigation {
107
+ padding: 10px;
108
+ flex-direction: column;
109
+ gap: 10px;
110
+ }
111
+
112
+ .navigation > div {
113
+ flex-direction: column;
114
+ gap: 10px;
115
+ }
116
+
117
+ .navigation .nav-link {
118
+ display: block !important;
119
+ text-align: center;
120
+ width: 100%;
121
+ }
122
+
123
+ .theme-toggle {
124
+ margin-left: 0;
125
+ align-self: center;
126
+ }
127
+ }
128
+ </style>
@@ -15,6 +15,9 @@
15
15
 
16
16
  <!-- Include stats-specific CSS -->
17
17
  <link rel="stylesheet" href="/static/css/stats.css">
18
+
19
+ <!-- Include shared kanji grid CSS -->
20
+ <link rel="stylesheet" href="/static/css/kanji-grid.css">
18
21
  </head>
19
22
  <body>
20
23
 
@@ -324,6 +327,7 @@
324
327
 
325
328
  <!-- Include shared JavaScript first (required dependency for stats.js) -->
326
329
  <script src="/static/js/shared.js"></script>
330
+ <script src="/static/js/kanji-grid.js"></script>
327
331
  <script src="/static/js/stats.js"></script>
328
332
 
329
333
  </body>
@@ -263,12 +263,62 @@ def stats():
263
263
  """Renders the stats page."""
264
264
  return render_template('stats.html')
265
265
 
266
+ @app.route('/api/anki_stats')
267
+ def api_anki_stats():
268
+ """
269
+ API endpoint to provide Anki vs GSM kanji stats for the frontend.
270
+ Returns:
271
+ {
272
+ "missing_kanji": [ { "kanji": "漢", "frequency": 42 }, ... ],
273
+ "anki_kanji_count": 123,
274
+ "gsm_kanji_count": 456,
275
+ "coverage_percent": 27.0
276
+ }
277
+ """
278
+ from GameSentenceMiner.anki import get_all_anki_first_field_kanji
279
+ from GameSentenceMiner.web.stats import calculate_kanji_frequency, is_kanji
280
+ from GameSentenceMiner.util.db import GameLinesTable
281
+
282
+ # Get all GSM lines and calculate kanji frequency
283
+ all_lines = GameLinesTable.all()
284
+ gsm_kanji_stats = calculate_kanji_frequency(all_lines)
285
+ gsm_kanji_list = gsm_kanji_stats.get("kanji_data", [])
286
+ gsm_kanji_set = set([k["kanji"] for k in gsm_kanji_list])
287
+
288
+ # Get all kanji in Anki (first field only)
289
+ anki_kanji_set = get_all_anki_first_field_kanji()
290
+
291
+ # Find missing kanji (in GSM but not in Anki)
292
+ missing_kanji = [
293
+ {"kanji": k["kanji"], "frequency": k["frequency"]}
294
+ for k in gsm_kanji_list if k["kanji"] not in anki_kanji_set
295
+ ]
296
+
297
+ # Sort missing kanji by frequency descending
298
+ missing_kanji.sort(key=lambda x: x["frequency"], reverse=True)
299
+
300
+ # Coverage stats
301
+ anki_kanji_count = len(anki_kanji_set)
302
+ gsm_kanji_count = len(gsm_kanji_set)
303
+ coverage_percent = (anki_kanji_count / gsm_kanji_count * 100) if gsm_kanji_count else 0.0
304
+
305
+ return jsonify({
306
+ "missing_kanji": missing_kanji,
307
+ "anki_kanji_count": anki_kanji_count,
308
+ "gsm_kanji_count": gsm_kanji_count,
309
+ "coverage_percent": round(coverage_percent, 1)
310
+ })
266
311
 
267
312
  @app.route('/search')
268
313
  def search():
269
314
  """Renders the search page."""
270
315
  return render_template('search.html')
271
316
 
317
+ @app.route('/anki_stats')
318
+ def anki_stats():
319
+ """Renders the Anki statistics page."""
320
+ return render_template('anki_stats.html')
321
+
272
322
 
273
323
  def get_selected_lines():
274
324
  return [item.line for item in event_manager if item.checked]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GameSentenceMiner
3
- Version: 2.15.10
3
+ Version: 2.15.12
4
4
  Summary: A tool for mining sentences from games. Update: Overlay?
5
5
  Author-email: Beangate <bpwhelan95@gmail.com>
6
6
  License: MIT License
@@ -1,5 +1,5 @@
1
1
  GameSentenceMiner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- GameSentenceMiner/anki.py,sha256=SYU3gKf3RNad0dkW__8LxcGVQVallWVnscSwdD1579E,25162
2
+ GameSentenceMiner/anki.py,sha256=rm9JuRP-1Eba2wcVQ2PZUMB5P9UMEZ99Fh371K0Qfhk,26319
3
3
  GameSentenceMiner/config_gui.py,sha256=i79PrY2pP8_VKvIL7uoDv5cgHvCCQBIe0mS_YnX2AVg,140792
4
4
  GameSentenceMiner/gametext.py,sha256=fgBgLchezpauWELE9Y5G3kVCLfAneD0X4lJFoI3FYbs,10351
5
5
  GameSentenceMiner/gsm.py,sha256=t2GAhMwVEHUzCdqM4tIgAzBUvNmt_Gec515iePacD6k,31945
@@ -22,7 +22,7 @@ GameSentenceMiner/ocr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
22
22
  GameSentenceMiner/ocr/gsm_ocr_config.py,sha256=Ov04c-nKzh3sADxO-5JyZWVe4DlrHM9edM9tc7-97Jo,5970
23
23
  GameSentenceMiner/ocr/ocrconfig.py,sha256=_tY8mjnzHMJrLS8E5pHqYXZjMuLoGKYgJwdhYgN-ny4,6466
24
24
  GameSentenceMiner/ocr/owocr_area_selector.py,sha256=Rm1_nuZotJhfOfoJ_3mesh9udtOBjYqKhnAvSief6fo,29181
25
- GameSentenceMiner/ocr/owocr_helper.py,sha256=LoGKfVd1PL8R9UgOA_S1TiKT1i_b3Yb8quWl5ls1MEI,31689
25
+ GameSentenceMiner/ocr/owocr_helper.py,sha256=wsI9HaDFcP9is71wf0YoLjf-FjgQ2Dps-e1e-l-HDl0,31722
26
26
  GameSentenceMiner/ocr/ss_picker.py,sha256=0IhxUdaKruFpZyBL-8SpxWg7bPrlGpy3lhTcMMZ5rwo,5224
27
27
  GameSentenceMiner/owocr/owocr/__init__.py,sha256=87hfN5u_PbL_onLfMACbc0F5j4KyIK9lKnRCj6oZgR0,49
28
28
  GameSentenceMiner/owocr/owocr/__main__.py,sha256=XQaqZY99EKoCpU-gWQjNbTs7Kg17HvBVE7JY8LqIE0o,157
@@ -60,7 +60,7 @@ GameSentenceMiner/web/database_api.py,sha256=kcyTWPuw_qtrK5qBzCFTIP0tqIvPmL-NEti
60
60
  GameSentenceMiner/web/events.py,sha256=6Vyz5c9MdpMIa7Zqljqhap2XFQnAVYJ0CdQV64TSZsA,5119
61
61
  GameSentenceMiner/web/service.py,sha256=YZchmScTn7AX_GkwV1ULEK6qjdOnJcpc3qfMwDf7cUE,5363
62
62
  GameSentenceMiner/web/stats.py,sha256=daSSxWlumAyqVVtX10qHESF-tZYwCcFMp8qZA5AE0nI,22066
63
- GameSentenceMiner/web/texthooking_page.py,sha256=hkKu3SIi0V-wktiKhFhQEnhJe6PUWVZs_FSa1-wOYFQ,11134
63
+ GameSentenceMiner/web/texthooking_page.py,sha256=gKCajF_SrIXdiLOTMxtSziXuQ7T4I7B0iBKqIhcN_Og,12943
64
64
  GameSentenceMiner/web/websockets.py,sha256=IwwQo6VtgPqeOuc-datgfJyLpX3LwB2MISDqA6EkiSA,4131
65
65
  GameSentenceMiner/web/static/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
66
  GameSentenceMiner/web/static/apple-touch-icon.png,sha256=OcMI8af_68DA_tweOsQ5LytTyMwm7-hPW07IfrOVgEs,46132
@@ -71,16 +71,28 @@ GameSentenceMiner/web/static/site.webmanifest,sha256=kaeNT-FjFt-T7JGzOhXH7YSqsrD
71
71
  GameSentenceMiner/web/static/style.css,sha256=bPZK0NVMuyRl5NNDuT7ZTzVLKlvSsdmeVHmAW4y5FM0,7001
72
72
  GameSentenceMiner/web/static/web-app-manifest-192x192.png,sha256=EfSNnBmsSaLfESbkGfYwbKzcjKOdzuWo18ABADfN974,51117
73
73
  GameSentenceMiner/web/static/web-app-manifest-512x512.png,sha256=wyqgCWCrLEUxSRXmaA3iJEESd-vM-ZmlTtZFBY4V8Pk,230819
74
+ GameSentenceMiner/web/static/css/kanji-grid.css,sha256=UnzDypDD4H_iuKUs9oPtOMvaSfNdLdnzkw36XTo9SEc,2364
75
+ GameSentenceMiner/web/static/css/search.css,sha256=x06xsErfThUpE1NAG4CA2sCPSZ-ofNWEI_ekV2Ok5hY,253
76
+ GameSentenceMiner/web/static/css/shared.css,sha256=oxY16CiAliGhsPV82TGZXUM08oT2rJRqGHMYrsWZKGM,17214
77
+ GameSentenceMiner/web/static/css/stats.css,sha256=UEaRk8k2LrhiMIfuwwFwx26txzRV1w76pOhT-4WoREM,9558
78
+ GameSentenceMiner/web/static/js/anki_stats.js,sha256=wZfr9vXGF--OTXOszjB3XX1pI2RrMBxGHoGwGvJ20xg,3171
79
+ GameSentenceMiner/web/static/js/database.js,sha256=-SjMmhXzU8a3QNGrwGtJCu55ZXXfkBxlYSkySEBdclU,22097
80
+ GameSentenceMiner/web/static/js/kanji-grid.js,sha256=rUa8_TGFm4Z8CtURoAlZjCN032PLe0YmHvN52S4_sE0,7181
81
+ GameSentenceMiner/web/static/js/search.js,sha256=nXvHZelCQQlTWJwaF_j3RnU5v_JFVIDQSEtnauDy8lg,9484
82
+ GameSentenceMiner/web/static/js/shared.js,sha256=cblau-bQM1sdpBLtb4I0VTTxwrmYkwfn1IvUjBAEssY,16147
83
+ GameSentenceMiner/web/static/js/stats.js,sha256=_B5QQWv1Wxx8fPyX4VDmTxs31Ds1EmX0XERt2uJj_9M,60882
84
+ GameSentenceMiner/web/templates/anki_stats.html,sha256=XXONeWFhMA6KZQx0gBJyxDKxLnX1zYTGoGhZlC7kbpA,10784
74
85
  GameSentenceMiner/web/templates/database.html,sha256=iEJWQvvH_RGWmHuFx0iwNeamBV5FoVxZgFKgfm-4zc4,13582
75
86
  GameSentenceMiner/web/templates/index.html,sha256=LqXZx7-NE42pXSpHNZ3To680rD-vt9wEJoFYBlgp1qU,216923
76
87
  GameSentenceMiner/web/templates/search.html,sha256=Fat3hOjQwkYBbdFhgWzRzZ5iEB78-2_0LpT7uK2aURE,3701
77
- GameSentenceMiner/web/templates/stats.html,sha256=I-3eb2521r7fvDHfCktOB79fhWj2_2lcjFJi9qWAbgA,16668
78
- GameSentenceMiner/web/templates/text_replacements.html,sha256=rB6mUvzzdbAlNV0dEukZlec0sXgRarBZw8Qh_eWRErE,16694
88
+ GameSentenceMiner/web/templates/stats.html,sha256=jXHhp4fcSHgZ5kNGaFX5ArCf-4WCsktrw3uvV7lctPI,16827
79
89
  GameSentenceMiner/web/templates/utility.html,sha256=KtqnZUMAYs5XsEdC9Tlsd40NKAVic0mu6sh-ReMDJpU,16940
90
+ GameSentenceMiner/web/templates/components/navigation.html,sha256=wxhz-T6ZQYoJmjONvrfeTm1XFlTA2O-RhKJgBd9zjrU,906
91
+ GameSentenceMiner/web/templates/components/theme-styles.html,sha256=hiq3zdJljpRjQO1iUA7gfFKwXebltG-IWW-gnKS4GHA,3439
80
92
  GameSentenceMiner/wip/__init___.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
- gamesentenceminer-2.15.10.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
82
- gamesentenceminer-2.15.10.dist-info/METADATA,sha256=T-Ik7ri7Xjt4D_J-Yd3fOVK0yf_rOrIe-oChyHlgOA8,7349
83
- gamesentenceminer-2.15.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
84
- gamesentenceminer-2.15.10.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
85
- gamesentenceminer-2.15.10.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
86
- gamesentenceminer-2.15.10.dist-info/RECORD,,
93
+ gamesentenceminer-2.15.12.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
94
+ gamesentenceminer-2.15.12.dist-info/METADATA,sha256=StS9TlSdTLtyMG_nIMeqgL4WeRsjRK8HhZ7R8d1Cc3w,7349
95
+ gamesentenceminer-2.15.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
96
+ gamesentenceminer-2.15.12.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
97
+ gamesentenceminer-2.15.12.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
98
+ gamesentenceminer-2.15.12.dist-info/RECORD,,