cognikit 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +10 -0
- package/dist/client.js +4601 -0
- package/dist/client.js.map +7 -0
- package/dist/index.d.ts +9 -4
- package/dist/index.js +2075 -1992
- package/dist/index.js.map +4 -4
- package/dist/interactions/categorize-the-words/static.d.ts +1 -1
- package/dist/interactions/fill-blanks/static.d.ts +1 -1
- package/dist/interactions/mark-the-words/static.d.ts +1 -1
- package/dist/interactions/text-transformation/static.d.ts +1 -1
- package/dist/shared/config.d.ts +18 -0
- package/dist/shared/icons.d.ts +3 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/managers/SoundManager.d.ts +1 -2
- package/dist/shared/ssr.d.ts +1 -0
- package/package.json +10 -5
- package/public/app.js +13713 -0
- package/public/app.js.map +7 -0
- package/public/assets/audio/failure.mp3 +0 -0
- package/public/assets/audio/flip.mp3 +0 -0
- package/public/assets/audio/low-time.mp3 +0 -0
- package/public/assets/audio/plus.mp3 +0 -0
- package/public/assets/audio/pop.mp3 +0 -0
- package/public/assets/audio/start.mp3 +0 -0
- package/public/assets/audio/success.mp3 +0 -0
- package/public/assets/eduguiders-logo.png +0 -0
- package/public/assets/icons/audio.svg +83 -0
- package/public/assets/icons/data.svg +2 -0
- package/public/assets/icons/down.svg +2 -0
- package/public/assets/icons/drag-horizontal-svgrepo-com.svg +4 -0
- package/public/assets/icons/drag-vertical-svgrepo-com.svg +4 -0
- package/public/assets/icons/error.svg +2 -0
- package/public/assets/icons/eye-disabled.svg +8 -0
- package/public/assets/icons/eye.svg +5 -0
- package/public/assets/icons/image-picture-svgrepo-com-dark.svg +17 -0
- package/public/assets/icons/image.svg +17 -0
- package/public/assets/icons/link.svg +5 -0
- package/public/assets/icons/repeat.svg +7 -0
- package/public/assets/icons/star.svg +4 -0
- package/public/assets/icons/up.svg +2 -0
- package/public/assets/icons/video.svg +6 -0
- package/public/assets/images/pointing-hand.svg +1 -0
- package/public/examples/chip.html +495 -0
- package/public/index.html +754 -0
- package/public/scalable-bare.html +432 -0
- package/public/tables-demo.html +534 -0
- package/public/text-interactions-demo.html +604 -0
|
@@ -0,0 +1,754 @@
|
|
|
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, maximum-scale=5.0, user-scalable=yes, viewport-fit=cover">
|
|
6
|
+
<meta name="mobile-web-app-capable" content="yes">
|
|
7
|
+
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
8
|
+
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
|
9
|
+
<meta name="theme-color" content="#f7f9fc">
|
|
10
|
+
<title>CogniKit - Beta Interaction Playground</title>
|
|
11
|
+
<style>
|
|
12
|
+
* {
|
|
13
|
+
margin: 0;
|
|
14
|
+
padding: 0;
|
|
15
|
+
box-sizing: border-box;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
html, body {
|
|
19
|
+
width: 100%;
|
|
20
|
+
height: 100%;
|
|
21
|
+
overflow: hidden;
|
|
22
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
23
|
+
-webkit-font-smoothing: antialiased;
|
|
24
|
+
-moz-osx-font-smoothing: grayscale;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
:root {
|
|
28
|
+
--edu-bg: 247 249 252;
|
|
29
|
+
--edu-card: 255 255 255;
|
|
30
|
+
--edu-ink: 31 41 55;
|
|
31
|
+
--edu-second-ink: 71 85 105;
|
|
32
|
+
--edu-third-ink: 100 116 139;
|
|
33
|
+
--edu-inverted-ink: 248 250 252;
|
|
34
|
+
--edu-success: 22 163 74;
|
|
35
|
+
--edu-error: 220 38 38;
|
|
36
|
+
--edu-warning: 255 222 33;
|
|
37
|
+
--edu-neutral: 14 165 233;
|
|
38
|
+
--edu-first-accent: 49 120 198;
|
|
39
|
+
--edu-second-accent: 245 158 11;
|
|
40
|
+
--edu-third-accent: 236 72 153;
|
|
41
|
+
--edu-border: 229 231 235;
|
|
42
|
+
--edu-muted: 243 244 246;
|
|
43
|
+
--edu-radius: 0.375rem;
|
|
44
|
+
--edu-shadow-color: 0 0 0;
|
|
45
|
+
--edu-pad: 1rem;
|
|
46
|
+
--edu-mar: 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
body {
|
|
50
|
+
background: rgb(var(--edu-bg));
|
|
51
|
+
display: flex;
|
|
52
|
+
flex-direction: column;
|
|
53
|
+
height: 100vh;
|
|
54
|
+
height: 100dvh;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* Header */
|
|
58
|
+
.header {
|
|
59
|
+
display: flex;
|
|
60
|
+
align-items: center;
|
|
61
|
+
justify-content: space-between;
|
|
62
|
+
padding: 1rem 1.5rem;
|
|
63
|
+
background: rgb(var(--edu-card));
|
|
64
|
+
border-bottom: 2px solid rgb(var(--edu-border));
|
|
65
|
+
box-shadow: 0 2px 8px rgba(var(--edu-shadow-color), 0.05);
|
|
66
|
+
flex-shrink: 0;
|
|
67
|
+
z-index: 100;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.header h1 {
|
|
71
|
+
font-size: 1.25rem;
|
|
72
|
+
color: rgb(var(--edu-ink));
|
|
73
|
+
font-weight: 700;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.header-controls {
|
|
77
|
+
display: flex;
|
|
78
|
+
gap: 0.75rem;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.icon-button {
|
|
82
|
+
background: rgb(var(--edu-card));
|
|
83
|
+
border: 2px solid rgb(var(--edu-border));
|
|
84
|
+
border-radius: 8px;
|
|
85
|
+
width: 44px;
|
|
86
|
+
height: 44px;
|
|
87
|
+
display: flex;
|
|
88
|
+
align-items: center;
|
|
89
|
+
justify-content: center;
|
|
90
|
+
cursor: pointer;
|
|
91
|
+
transition: all 0.2s;
|
|
92
|
+
color: rgb(var(--edu-ink));
|
|
93
|
+
font-size: 1.2rem;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.icon-button:hover {
|
|
97
|
+
border-color: rgb(var(--edu-first-accent));
|
|
98
|
+
background: rgba(var(--edu-first-accent), 0.1);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.icon-button:active {
|
|
102
|
+
transform: scale(0.95);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* Main viewport */
|
|
106
|
+
.main-viewport {
|
|
107
|
+
flex: 1;
|
|
108
|
+
display: flex;
|
|
109
|
+
align-items: center;
|
|
110
|
+
justify-content: center;
|
|
111
|
+
padding: 1.5rem;
|
|
112
|
+
overflow: hidden;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.interaction-container {
|
|
116
|
+
width: 100%;
|
|
117
|
+
height: 100%;
|
|
118
|
+
max-width: 1200px;
|
|
119
|
+
display: flex;
|
|
120
|
+
flex-direction: column;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
edu-window {
|
|
124
|
+
width: 100%;
|
|
125
|
+
height: 100%;
|
|
126
|
+
display: block;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* Modal */
|
|
130
|
+
.modal-overlay {
|
|
131
|
+
position: fixed;
|
|
132
|
+
top: 0;
|
|
133
|
+
left: 0;
|
|
134
|
+
right: 0;
|
|
135
|
+
bottom: 0;
|
|
136
|
+
background: rgba(0, 0, 0, 0.5);
|
|
137
|
+
backdrop-filter: blur(4px);
|
|
138
|
+
display: none;
|
|
139
|
+
align-items: center;
|
|
140
|
+
justify-content: center;
|
|
141
|
+
z-index: 1000;
|
|
142
|
+
padding: 1rem;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.modal-overlay.active {
|
|
146
|
+
display: flex;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.modal {
|
|
150
|
+
background: rgb(var(--edu-card));
|
|
151
|
+
border-radius: 16px;
|
|
152
|
+
box-shadow: 0 20px 60px rgba(var(--edu-shadow-color), 0.3);
|
|
153
|
+
max-width: 600px;
|
|
154
|
+
width: 100%;
|
|
155
|
+
max-height: 90vh;
|
|
156
|
+
max-height: 90dvh;
|
|
157
|
+
overflow: hidden;
|
|
158
|
+
display: flex;
|
|
159
|
+
flex-direction: column;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.modal-header {
|
|
163
|
+
padding: 1.5rem;
|
|
164
|
+
border-bottom: 2px solid rgb(var(--edu-border));
|
|
165
|
+
display: flex;
|
|
166
|
+
align-items: center;
|
|
167
|
+
justify-content: space-between;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.modal-header h2 {
|
|
171
|
+
font-size: 1.25rem;
|
|
172
|
+
color: rgb(var(--edu-ink));
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.modal-close {
|
|
176
|
+
background: none;
|
|
177
|
+
border: none;
|
|
178
|
+
font-size: 1.5rem;
|
|
179
|
+
cursor: pointer;
|
|
180
|
+
color: rgb(var(--edu-second-ink));
|
|
181
|
+
width: 32px;
|
|
182
|
+
height: 32px;
|
|
183
|
+
display: flex;
|
|
184
|
+
align-items: center;
|
|
185
|
+
justify-content: center;
|
|
186
|
+
border-radius: 6px;
|
|
187
|
+
transition: all 0.2s;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.modal-close:hover {
|
|
191
|
+
background: rgba(var(--edu-error), 0.1);
|
|
192
|
+
color: rgb(var(--edu-error));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.modal-body {
|
|
196
|
+
padding: 1.5rem;
|
|
197
|
+
overflow-y: auto;
|
|
198
|
+
flex: 1;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.form-group {
|
|
202
|
+
margin-bottom: 1.5rem;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.form-group label {
|
|
206
|
+
display: block;
|
|
207
|
+
font-weight: 600;
|
|
208
|
+
color: rgb(var(--edu-ink));
|
|
209
|
+
margin-bottom: 0.5rem;
|
|
210
|
+
font-size: 0.95rem;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.form-group select,
|
|
214
|
+
.form-group input,
|
|
215
|
+
.form-group textarea {
|
|
216
|
+
width: 100%;
|
|
217
|
+
padding: 0.75rem;
|
|
218
|
+
border: 2px solid rgb(var(--edu-border));
|
|
219
|
+
border-radius: 8px;
|
|
220
|
+
background: rgb(var(--edu-bg));
|
|
221
|
+
color: rgb(var(--edu-ink));
|
|
222
|
+
font-size: 0.95rem;
|
|
223
|
+
font-family: inherit;
|
|
224
|
+
transition: all 0.2s;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.form-group textarea {
|
|
228
|
+
font-family: 'Monaco', 'Courier New', monospace;
|
|
229
|
+
min-height: 150px;
|
|
230
|
+
resize: vertical;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.form-group select:focus,
|
|
234
|
+
.form-group input:focus,
|
|
235
|
+
.form-group textarea:focus {
|
|
236
|
+
outline: none;
|
|
237
|
+
border-color: rgb(var(--edu-first-accent));
|
|
238
|
+
background: rgb(var(--edu-card));
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.modal-footer {
|
|
242
|
+
padding: 1.5rem;
|
|
243
|
+
border-top: 2px solid rgb(var(--edu-border));
|
|
244
|
+
display: flex;
|
|
245
|
+
gap: 1rem;
|
|
246
|
+
justify-content: flex-end;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.btn {
|
|
250
|
+
padding: 0.75rem 1.5rem;
|
|
251
|
+
border-radius: 8px;
|
|
252
|
+
border: 2px solid rgb(var(--edu-border));
|
|
253
|
+
background: rgb(var(--edu-card));
|
|
254
|
+
color: rgb(var(--edu-ink));
|
|
255
|
+
font-weight: 600;
|
|
256
|
+
font-size: 0.95rem;
|
|
257
|
+
cursor: pointer;
|
|
258
|
+
transition: all 0.2s;
|
|
259
|
+
min-height: 44px;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.btn:hover {
|
|
263
|
+
border-color: rgb(var(--edu-first-accent));
|
|
264
|
+
background: rgba(var(--edu-first-accent), 0.1);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.btn:active {
|
|
268
|
+
transform: scale(0.98);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.btn-primary {
|
|
272
|
+
background: rgb(var(--edu-first-accent));
|
|
273
|
+
border-color: rgb(var(--edu-first-accent));
|
|
274
|
+
color: rgb(var(--edu-inverted-ink));
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.btn-primary:hover {
|
|
278
|
+
opacity: 0.9;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.form-help {
|
|
282
|
+
font-size: 0.85rem;
|
|
283
|
+
color: rgb(var(--edu-second-ink));
|
|
284
|
+
margin-top: 0.5rem;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/* Fullscreen mode */
|
|
288
|
+
body.fullscreen .header {
|
|
289
|
+
display: none;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
body.fullscreen .main-viewport {
|
|
293
|
+
padding: 0;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
body.fullscreen .interaction-container {
|
|
297
|
+
max-width: none;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/* Mobile styles */
|
|
301
|
+
@media (max-width: 768px) {
|
|
302
|
+
.header {
|
|
303
|
+
padding: 0.75rem 1rem;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.header h1 {
|
|
307
|
+
font-size: 1rem;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.icon-button {
|
|
311
|
+
width: 40px;
|
|
312
|
+
height: 40px;
|
|
313
|
+
font-size: 1rem;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.main-viewport {
|
|
317
|
+
padding: 1rem;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.modal {
|
|
321
|
+
border-radius: 12px;
|
|
322
|
+
max-height: 95vh;
|
|
323
|
+
max-height: 95dvh;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.modal-header,
|
|
327
|
+
.modal-body,
|
|
328
|
+
.modal-footer {
|
|
329
|
+
padding: 1rem;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.form-group textarea {
|
|
333
|
+
min-height: 120px;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
@media (max-width: 480px) {
|
|
338
|
+
.main-viewport {
|
|
339
|
+
padding: 0.5rem;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
.modal-footer {
|
|
343
|
+
flex-direction: column;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.btn {
|
|
347
|
+
width: 100%;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
</style>
|
|
351
|
+
</head>
|
|
352
|
+
<body>
|
|
353
|
+
<!-- Header -->
|
|
354
|
+
<div class="header">
|
|
355
|
+
<h1>🎯 CogniKit Beta</h1>
|
|
356
|
+
<div class="header-controls">
|
|
357
|
+
<button class="icon-button" id="settings-btn" title="Settings">⚙️</button>
|
|
358
|
+
<button class="icon-button" id="config-btn" title="Configure Interaction">🎨</button>
|
|
359
|
+
<button class="icon-button" id="fullscreen-btn" title="Toggle Fullscreen">⛶</button>
|
|
360
|
+
</div>
|
|
361
|
+
</div>
|
|
362
|
+
|
|
363
|
+
<!-- Main Viewport -->
|
|
364
|
+
<div class="main-viewport">
|
|
365
|
+
<div class="interaction-container">
|
|
366
|
+
<edu-window id="interaction-viewport"></edu-window>
|
|
367
|
+
</div>
|
|
368
|
+
</div>
|
|
369
|
+
|
|
370
|
+
<!-- Settings Modal -->
|
|
371
|
+
<div class="modal-overlay" id="settings-modal">
|
|
372
|
+
<div class="modal">
|
|
373
|
+
<div class="modal-header">
|
|
374
|
+
<h2>⚙️ Settings</h2>
|
|
375
|
+
<button class="modal-close" id="settings-close">×</button>
|
|
376
|
+
</div>
|
|
377
|
+
<div class="modal-body">
|
|
378
|
+
<div class="form-group">
|
|
379
|
+
<label for="variant-select">Variant Style</label>
|
|
380
|
+
<select id="variant-select">
|
|
381
|
+
<option value="elegant" selected>Elegant</option>
|
|
382
|
+
<option value="playful">Playful</option>
|
|
383
|
+
<option value="outline">Outline</option>
|
|
384
|
+
<option value="letter">Letter</option>
|
|
385
|
+
<option value="sign">Sign</option>
|
|
386
|
+
<option value="minimal">Minimal</option>
|
|
387
|
+
<option value="glass">Glass</option>
|
|
388
|
+
<option value="card">Card</option>
|
|
389
|
+
<option value="empty">Empty</option>
|
|
390
|
+
</select>
|
|
391
|
+
</div>
|
|
392
|
+
|
|
393
|
+
<div class="form-group">
|
|
394
|
+
<label for="theme-select">Theme</label>
|
|
395
|
+
<select id="theme-select">
|
|
396
|
+
<option value="light" selected>Light</option>
|
|
397
|
+
<option value="dark">Dark</option>
|
|
398
|
+
<option value="dark-blue">Dark Blue</option>
|
|
399
|
+
</select>
|
|
400
|
+
<div class="form-help">Theme switching not yet implemented</div>
|
|
401
|
+
</div>
|
|
402
|
+
|
|
403
|
+
<div class="form-group">
|
|
404
|
+
<label for="accent-color">Accent Color</label>
|
|
405
|
+
<input type="color" id="accent-color" value="#67CB90">
|
|
406
|
+
<div class="form-help">Color customization not yet implemented</div>
|
|
407
|
+
</div>
|
|
408
|
+
</div>
|
|
409
|
+
<div class="modal-footer">
|
|
410
|
+
<button class="btn" id="settings-cancel">Cancel</button>
|
|
411
|
+
<button class="btn btn-primary" id="settings-apply">Apply</button>
|
|
412
|
+
</div>
|
|
413
|
+
</div>
|
|
414
|
+
</div>
|
|
415
|
+
|
|
416
|
+
<!-- Configuration Modal -->
|
|
417
|
+
<div class="modal-overlay" id="config-modal">
|
|
418
|
+
<div class="modal">
|
|
419
|
+
<div class="modal-header">
|
|
420
|
+
<h2>🎨 Configure Interaction</h2>
|
|
421
|
+
<button class="modal-close" id="config-close">×</button>
|
|
422
|
+
</div>
|
|
423
|
+
<div class="modal-body">
|
|
424
|
+
<div class="form-group">
|
|
425
|
+
<label for="interaction-type">Interaction Type</label>
|
|
426
|
+
<select id="interaction-type">
|
|
427
|
+
<option value="SequentialClassification">Sequential Classification</option>
|
|
428
|
+
<option value="SimultaneousAssociation">Simultaneous Association</option>
|
|
429
|
+
<option value="OpenClassification">Open Classification</option>
|
|
430
|
+
<option value="RankOrder">Rank Order</option>
|
|
431
|
+
<option value="ListRecall">List Recall</option>
|
|
432
|
+
<option value="MCQ" selected>MCQ/MRQ</option>
|
|
433
|
+
</select>
|
|
434
|
+
</div>
|
|
435
|
+
|
|
436
|
+
<div class="form-group">
|
|
437
|
+
<label for="interaction-heading">Heading</label>
|
|
438
|
+
<input type="text" id="interaction-heading" value="Butterfly Life Cycle" placeholder="Enter heading...">
|
|
439
|
+
</div>
|
|
440
|
+
|
|
441
|
+
<div class="form-group">
|
|
442
|
+
<label for="interaction-timer">Timer (seconds)</label>
|
|
443
|
+
<input type="number" id="interaction-timer" value="120" min="0" placeholder="0 for no timer">
|
|
444
|
+
</div>
|
|
445
|
+
|
|
446
|
+
<div class="form-group">
|
|
447
|
+
<label for="data-json">Data (JSON)</label>
|
|
448
|
+
<textarea id="data-json" placeholder="Enter JSON data...">{
|
|
449
|
+
"type": "seriation",
|
|
450
|
+
"items": ["Egg", "Caterpillar", "Chrysalis", "Butterfly", "@:butterfly"]
|
|
451
|
+
}</textarea>
|
|
452
|
+
<div class="form-help">Must be valid JSON format</div>
|
|
453
|
+
</div>
|
|
454
|
+
|
|
455
|
+
<div class="form-group">
|
|
456
|
+
<label for="assets-yaml">Assets (YAML)</label>
|
|
457
|
+
<textarea id="assets-yaml" placeholder="Enter YAML assets...">butterfly:
|
|
458
|
+
type: image
|
|
459
|
+
url: https://images.unsplash.com/photo-1533048324814-79b0a31982f1?q=80&w=768</textarea>
|
|
460
|
+
<div class="form-help">Optional. Leave empty if no assets needed</div>
|
|
461
|
+
</div>
|
|
462
|
+
</div>
|
|
463
|
+
<div class="modal-footer">
|
|
464
|
+
<button class="btn" id="config-cancel">Cancel</button>
|
|
465
|
+
<button class="btn btn-primary" id="config-apply">Render Interaction</button>
|
|
466
|
+
</div>
|
|
467
|
+
</div>
|
|
468
|
+
</div>
|
|
469
|
+
|
|
470
|
+
<script type="module">
|
|
471
|
+
import {
|
|
472
|
+
OpenClassification,
|
|
473
|
+
SequentialClassification,
|
|
474
|
+
SimultaneousAssociation,
|
|
475
|
+
RankOrder,
|
|
476
|
+
ListRecall,
|
|
477
|
+
MCQ,
|
|
478
|
+
parseYamlAssets,
|
|
479
|
+
validateAndNormalizeAssets
|
|
480
|
+
} from './app.js';
|
|
481
|
+
|
|
482
|
+
// State
|
|
483
|
+
let currentVariant = 'elegant';
|
|
484
|
+
let currentInteraction = null;
|
|
485
|
+
|
|
486
|
+
// DOM Elements
|
|
487
|
+
const viewport = document.getElementById('interaction-viewport');
|
|
488
|
+
const settingsBtn = document.getElementById('settings-btn');
|
|
489
|
+
const configBtn = document.getElementById('config-btn');
|
|
490
|
+
const fullscreenBtn = document.getElementById('fullscreen-btn');
|
|
491
|
+
const settingsModal = document.getElementById('settings-modal');
|
|
492
|
+
const configModal = document.getElementById('config-modal');
|
|
493
|
+
|
|
494
|
+
// Modal Controls
|
|
495
|
+
const settingsClose = document.getElementById('settings-close');
|
|
496
|
+
const settingsCancel = document.getElementById('settings-cancel');
|
|
497
|
+
const settingsApply = document.getElementById('settings-apply');
|
|
498
|
+
const configClose = document.getElementById('config-close');
|
|
499
|
+
const configCancel = document.getElementById('config-cancel');
|
|
500
|
+
const configApply = document.getElementById('config-apply');
|
|
501
|
+
|
|
502
|
+
// Form Elements
|
|
503
|
+
const variantSelect = document.getElementById('variant-select');
|
|
504
|
+
const accentColor = document.getElementById('accent-color');
|
|
505
|
+
const interactionType = document.getElementById('interaction-type');
|
|
506
|
+
const interactionHeading = document.getElementById('interaction-heading');
|
|
507
|
+
const interactionTimer = document.getElementById('interaction-timer');
|
|
508
|
+
const dataJson = document.getElementById('data-json');
|
|
509
|
+
const assetsYaml = document.getElementById('assets-yaml');
|
|
510
|
+
|
|
511
|
+
// Modal Management
|
|
512
|
+
function openModal(modal) {
|
|
513
|
+
modal.classList.add('active');
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
function closeModal(modal) {
|
|
517
|
+
modal.classList.remove('active');
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
accentColor.addEventListener('change', (e) => {
|
|
521
|
+
const color = e.target.value;
|
|
522
|
+
// Convert hex to RGB
|
|
523
|
+
const r = parseInt(color.substr(1, 2), 16);
|
|
524
|
+
const g = parseInt(color.substr(3, 2), 16);
|
|
525
|
+
const b = parseInt(color.substr(5, 2), 16);
|
|
526
|
+
document.documentElement.style.setProperty('--edu-first-accent', `${r} ${g} ${b}`);
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
// Event Listeners - Modal Toggles
|
|
530
|
+
settingsBtn.addEventListener('click', () => openModal(settingsModal));
|
|
531
|
+
configBtn.addEventListener('click', () => openModal(configModal));
|
|
532
|
+
|
|
533
|
+
settingsClose.addEventListener('click', () => closeModal(settingsModal));
|
|
534
|
+
settingsCancel.addEventListener('click', () => closeModal(settingsModal));
|
|
535
|
+
|
|
536
|
+
configClose.addEventListener('click', () => closeModal(configModal));
|
|
537
|
+
configCancel.addEventListener('click', () => closeModal(configModal));
|
|
538
|
+
|
|
539
|
+
// Close modal on overlay click
|
|
540
|
+
settingsModal.addEventListener('click', (e) => {
|
|
541
|
+
if (e.target === settingsModal) closeModal(settingsModal);
|
|
542
|
+
});
|
|
543
|
+
configModal.addEventListener('click', (e) => {
|
|
544
|
+
if (e.target === configModal) closeModal(configModal);
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
// Settings Apply
|
|
548
|
+
settingsApply.addEventListener('click', () => {
|
|
549
|
+
currentVariant = variantSelect.value;
|
|
550
|
+
if (viewport) {
|
|
551
|
+
currentInteraction.onVariantChange(currentVariant);
|
|
552
|
+
viewport.setAttribute('variant', currentVariant);
|
|
553
|
+
}
|
|
554
|
+
closeModal(settingsModal);
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
// Fullscreen Toggle
|
|
558
|
+
fullscreenBtn.addEventListener('click', () => {
|
|
559
|
+
document.body.classList.toggle('fullscreen');
|
|
560
|
+
fullscreenBtn.textContent = document.body.classList.contains('fullscreen') ? '⛶' : '⛶';
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
// Interaction Type Data Templates
|
|
564
|
+
const dataTemplates = {
|
|
565
|
+
SequentialClassification: {
|
|
566
|
+
data: {
|
|
567
|
+
type: 'classification',
|
|
568
|
+
categories: [
|
|
569
|
+
{ label: 'Ocean', items: ['Dolphin', 'Shark', 'Octopus'] },
|
|
570
|
+
{ label: 'Land', items: ['Lion', 'Elephant', 'Tiger'] },
|
|
571
|
+
{ label: 'Air', items: ['Eagle', 'Parrot', 'Hawk'] }
|
|
572
|
+
]
|
|
573
|
+
},
|
|
574
|
+
assets: ''
|
|
575
|
+
},
|
|
576
|
+
SimultaneousAssociation: {
|
|
577
|
+
data: {
|
|
578
|
+
type: 'association',
|
|
579
|
+
pairs: [
|
|
580
|
+
{ left: 'Dog', right: 'Barks' },
|
|
581
|
+
{ left: 'Cat', right: 'Meows' },
|
|
582
|
+
{ left: 'Bird', right: 'Chirps' },
|
|
583
|
+
{ left: '@:cow', right: 'Moos' },
|
|
584
|
+
{ left: 'Lion', right: 'Roars' }
|
|
585
|
+
],
|
|
586
|
+
distractors: ['quacks', 'oinks']
|
|
587
|
+
},
|
|
588
|
+
assets: 'cow:\n type: image\n url: https://images.unsplash.com/photo-1595365691689-6b7b4e1970cf?q=80&w=765&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'
|
|
589
|
+
},
|
|
590
|
+
OpenClassification: {
|
|
591
|
+
data: {
|
|
592
|
+
type: 'classification',
|
|
593
|
+
categories: [
|
|
594
|
+
{ label: 'Mammals', items: ['Dog', 'Cat', 'Elephant', 'wolf'] },
|
|
595
|
+
{ label: 'Birds', items: ['Eagle', 'Sparrow'] }
|
|
596
|
+
],
|
|
597
|
+
distractors: ['Rock', 'Cloud']
|
|
598
|
+
},
|
|
599
|
+
assets: ''
|
|
600
|
+
},
|
|
601
|
+
RankOrder: {
|
|
602
|
+
data: {
|
|
603
|
+
type: 'seriation',
|
|
604
|
+
items: ['Bronze Age', 'Iron Age', 'Middle Ages', 'Renaissance', 'Industrial Revolution', 'Information Age']
|
|
605
|
+
},
|
|
606
|
+
assets: ''
|
|
607
|
+
},
|
|
608
|
+
ListRecall: {
|
|
609
|
+
data: {
|
|
610
|
+
type: 'seriation',
|
|
611
|
+
items: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
|
|
612
|
+
},
|
|
613
|
+
assets: ''
|
|
614
|
+
},
|
|
615
|
+
MCQ: {
|
|
616
|
+
data: {
|
|
617
|
+
type: 'recognition',
|
|
618
|
+
data: [
|
|
619
|
+
{
|
|
620
|
+
question: '@:paris',
|
|
621
|
+
correctOptions: ['Paris'],
|
|
622
|
+
options: ['Paris', 'London', 'Berlin', 'Madrid']
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
question: 'Which of these are programming languages?',
|
|
626
|
+
correctOptions: ['Python', 'JavaScript', 'Java'],
|
|
627
|
+
options: ['Python', 'JavaScript', 'Java', 'HTML', 'CSS']
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
question: '@:exampleHtml',
|
|
631
|
+
correctOptions: ['4'],
|
|
632
|
+
options: ['3', '4', '5', '6']
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
question: '@:ocean',
|
|
636
|
+
correctOptions: ['Ocean'],
|
|
637
|
+
options: ['Volcano', 'Desert', 'Forest', 'Ocean']
|
|
638
|
+
},
|
|
639
|
+
{
|
|
640
|
+
question: '@:laugh',
|
|
641
|
+
correctOptions: ["laughing"],
|
|
642
|
+
options: ['Crying', 'Shouting', 'Laughing']
|
|
643
|
+
}
|
|
644
|
+
]
|
|
645
|
+
},
|
|
646
|
+
assets:
|
|
647
|
+
`
|
|
648
|
+
paris:\n type: image\n url: https://plus.unsplash.com/premium_photo-1718035557075-5111d9d906d2?q=80&w=1171&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\n dialog: true
|
|
649
|
+
exampleHtml:
|
|
650
|
+
type: html
|
|
651
|
+
content: <div style="padding:1rem;"><h3>Rich HTML Question</h3><p>What is <strong>2 + 2</strong>?</p><ul><li>Addition</li><li>Basic math</li></ul></div>
|
|
652
|
+
dialog: true
|
|
653
|
+
|
|
654
|
+
ocean:\n type: video\n url: https://www.pexels.com/download/video/6548176\n dialog: false
|
|
655
|
+
|
|
656
|
+
laugh:\n type: audio\n url: https://www.soundjay.com/human/sounds/man-laughing-01.mp3\n dialog: true
|
|
657
|
+
`
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
|
|
661
|
+
dataJson.value = JSON.stringify(dataTemplates[interactionType.value].data);
|
|
662
|
+
assetsYaml.value = dataTemplates[interactionType.value].assets;
|
|
663
|
+
|
|
664
|
+
// Update form when interaction type changes
|
|
665
|
+
interactionType.addEventListener('change', (e) => {
|
|
666
|
+
const template = dataTemplates[e.target.value];
|
|
667
|
+
if (template) {
|
|
668
|
+
// Convert Map to object for JSON serialization
|
|
669
|
+
let dataToSerialize = template.data;
|
|
670
|
+
if (template.data.answerKey instanceof Map) {
|
|
671
|
+
dataToSerialize = {
|
|
672
|
+
...template.data,
|
|
673
|
+
answerKey: Object.fromEntries(template.data.answerKey)
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
dataJson.value = JSON.stringify(dataToSerialize, null, 2);
|
|
677
|
+
assetsYaml.value = template.assets;
|
|
678
|
+
}
|
|
679
|
+
});
|
|
680
|
+
|
|
681
|
+
// Render Interaction
|
|
682
|
+
configApply.addEventListener('click', () => {
|
|
683
|
+
try {
|
|
684
|
+
let data = JSON.parse(dataJson.value);
|
|
685
|
+
|
|
686
|
+
if (data.answerKey && typeof data.answerKey === 'object') {
|
|
687
|
+
data.answerKey = new Map(Object.entries(data.answerKey));
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
let assets = null;
|
|
691
|
+
const yamlContent = assetsYaml.value.trim();
|
|
692
|
+
if (yamlContent) {
|
|
693
|
+
const parsedAssets = parseYamlAssets(yamlContent);
|
|
694
|
+
assets = validateAndNormalizeAssets(parsedAssets);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
const config = {
|
|
698
|
+
variant: currentVariant,
|
|
699
|
+
shuffle: true,
|
|
700
|
+
animationsEnabled: true,
|
|
701
|
+
prompt: "Complete the quizz",
|
|
702
|
+
promptData: "https://plus.unsplash.com/premium_photo-1718035557075-5111d9d906d2?q=80&w=1171&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
|
|
703
|
+
promptModality: 'image',
|
|
704
|
+
timer: 60,
|
|
705
|
+
attemptLimit: 2
|
|
706
|
+
};
|
|
707
|
+
|
|
708
|
+
const type = interactionType.value;
|
|
709
|
+
let interaction;
|
|
710
|
+
|
|
711
|
+
switch (type) {
|
|
712
|
+
case 'SequentialClassification':
|
|
713
|
+
interaction = new SequentialClassification(data, config, assets);
|
|
714
|
+
break;
|
|
715
|
+
case 'SimultaneousAssociation':
|
|
716
|
+
interaction = new SimultaneousAssociation(data, config, assets);
|
|
717
|
+
break;
|
|
718
|
+
case 'OpenClassification':
|
|
719
|
+
interaction = new OpenClassification(data, config, assets);
|
|
720
|
+
break;
|
|
721
|
+
case 'RankOrder':
|
|
722
|
+
interaction = new RankOrder(data, config, assets);
|
|
723
|
+
break;
|
|
724
|
+
case 'ListRecall':
|
|
725
|
+
interaction = new ListRecall(data, config, assets);
|
|
726
|
+
break;
|
|
727
|
+
case 'MCQ':
|
|
728
|
+
interaction = new MCQ(data, config, assets);
|
|
729
|
+
break;
|
|
730
|
+
default:
|
|
731
|
+
throw new Error('Unknown interaction type');
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// Clear any previous state and set up new interaction
|
|
735
|
+
// The shell now reads everything from interaction.config
|
|
736
|
+
viewport.setInteraction(interaction);
|
|
737
|
+
|
|
738
|
+
currentInteraction = interaction;
|
|
739
|
+
closeModal(configModal);
|
|
740
|
+
|
|
741
|
+
console.log('✅ Interaction rendered successfully');
|
|
742
|
+
} catch (error) {
|
|
743
|
+
console.error('❌ Error rendering interaction:', error);
|
|
744
|
+
alert('Error: ' + error.message);
|
|
745
|
+
}
|
|
746
|
+
});
|
|
747
|
+
|
|
748
|
+
// Initialize with default interaction
|
|
749
|
+
window.addEventListener('DOMContentLoaded', () => {
|
|
750
|
+
configApply.click();
|
|
751
|
+
});
|
|
752
|
+
</script>
|
|
753
|
+
</body>
|
|
754
|
+
</html>
|