@matinfo/vitepress-plugin-quiz 1.0.3 → 1.0.6

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.
@@ -1,76 +1,117 @@
1
- import { defineComponent as F, computed as _, ref as M, inject as $, watch as D, onMounted as X, openBlock as a, createElementBlock as o, normalizeClass as N, unref as g, createElementVNode as z, Fragment as q, renderList as R, toDisplayString as c, createTextVNode as V, createCommentVNode as I, withKeys as O, withModifiers as L, withDirectives as ee, vModelText as te, provide as E, normalizeStyle as re, renderSlot as ne } from "vue";
2
- const se = ".quiz-progress-bar{position:sticky;top:var(--vp-nav-height, 64px);z-index:20;display:flex;align-items:center;gap:12px;margin:-20px -24px 24px;padding:12px 24px;background:var(--vp-c-bg);border-bottom:1px solid var(--vp-c-divider)}@media(max-width:959px){.quiz-progress-bar{top:calc(var(--vp-nav-height, 64px) - 16px)}}.quiz-progress-track{flex:1;height:8px;background:var(--vp-c-bg-soft);border-radius:4px;overflow:hidden}.quiz-progress-fill{height:100%;background:var(--vp-c-brand-1);border-radius:4px;transition:width .35s ease}.quiz-progress-fill.complete{background:var(--vp-c-green-1, #10b981)}.quiz-progress-label{font-size:13px;color:var(--vp-c-text-2);white-space:nowrap}.quiz-question{border:1px solid var(--vp-c-divider);border-radius:8px;padding:20px 24px;margin-bottom:16px;background:var(--vp-c-bg);transition:border-color .2s}.quiz-question-title{font-weight:600;font-size:15px;margin:0 0 6px;padding:0 5px;color:var(--vp-c-text-1);float:none;width:auto}.quiz-hint{font-size:13px;color:var(--vp-c-text-3);margin:0 0 10px;font-style:italic}.quiz-answers{list-style:none;padding:0;margin:0}.quiz-answer{display:flex;align-items:baseline;gap:10px;padding:8px 12px;margin:4px 0;border:1px solid transparent;border-radius:6px;cursor:pointer;transition:background-color .15s,border-color .15s;user-select:none;font-size:14px;color:var(--vp-c-text-1)}.quiz-answer:hover:not(.correct):not(.wrong):not(.missed){background:var(--vp-c-bg-soft)}.quiz-answer.selected{border-color:var(--vp-c-brand-1);background:var(--vp-c-brand-soft)}.quiz-answer.correct{border-color:var(--vp-c-green-1, #10b981);background:var(--vp-c-green-soft, rgba(16, 185, 129, .12));cursor:default}.quiz-answer.wrong{border-color:var(--vp-c-red-1, #ef4444);background:var(--vp-c-red-soft, rgba(239, 68, 68, .12));cursor:default}.quiz-answer.missed{border-color:var(--vp-c-yellow-1, #f59e0b);background:var(--vp-c-yellow-soft, rgba(245, 158, 11, .1));cursor:default}.validated .quiz-answer{pointer-events:none}.quiz-indicator{flex-shrink:0;width:18px;text-align:center;font-size:15px;line-height:1}.quiz-empty{color:var(--vp-c-text-3)}.quiz-check{color:var(--vp-c-brand-1)}.quiz-answer.correct .quiz-check{color:var(--vp-c-green-1, #10b981)}.quiz-answer.wrong .quiz-check{color:var(--vp-c-red-1, #ef4444)}.quiz-answer-text code{font-family:var(--vp-font-family-mono);font-size:13px;padding:1px 5px;border-radius:4px;background:var(--vp-c-bg-soft);color:var(--vp-c-text-1)}.quiz-explanation{margin-top:12px;padding:10px 14px;border-left:3px solid var(--vp-c-brand-1);background:var(--vp-c-bg-soft);border-radius:0 6px 6px 0;font-size:13px;color:var(--vp-c-text-2)}.quiz-actions{display:flex;flex-wrap:wrap;align-items:center;gap:16px;margin-top:24px;padding-top:20px;border-top:1px solid var(--vp-c-divider)}.quiz-btn{display:inline-flex;align-items:center;justify-content:center;padding:10px 28px;font-size:14px;font-weight:600;border:1px solid transparent;border-radius:8px;cursor:pointer;transition:opacity .2s,background .2s}.quiz-btn:disabled{opacity:.45;cursor:not-allowed}.quiz-btn-validate{background:var(--vp-c-brand-1);color:var(--vp-c-white, #fff)}.quiz-btn-validate:hover:not(:disabled){opacity:.88}.quiz-btn-reset{background:var(--vp-c-bg-soft);border-color:var(--vp-c-divider);color:var(--vp-c-text-1)}.quiz-btn-reset:hover{background:var(--vp-c-bg-mute)}.quiz-score{display:flex;align-items:baseline;gap:8px}.quiz-score-value{font-size:22px;font-weight:700;color:var(--vp-c-brand-1)}.quiz-score-label{font-size:14px;color:var(--vp-c-text-2)}.quiz-input-wrapper{margin-top:8px}.quiz-input{width:100%;max-width:400px;padding:8px 12px;font-size:14px;font-family:var(--vp-font-family-mono);border:1px solid var(--vp-c-divider);border-radius:6px;background:var(--vp-c-bg);color:var(--vp-c-text-1);outline:none;transition:border-color .15s}.quiz-input:focus{border-color:var(--vp-c-brand-1)}.quiz-input:disabled{cursor:not-allowed;opacity:.8}.quiz-input.correct{border-color:var(--vp-c-green-1, #10b981);background:var(--vp-c-green-soft, rgba(16, 185, 129, .12))}.quiz-input.wrong{border-color:var(--vp-c-red-1, #ef4444);background:var(--vp-c-red-soft, rgba(239, 68, 68, .12))}.quiz-expected{margin-top:6px;font-size:13px;color:var(--vp-c-text-2)}.quiz-expected code{font-family:var(--vp-font-family-mono);font-size:13px;padding:1px 5px;border-radius:4px;background:var(--vp-c-bg-soft);color:var(--vp-c-green-1, #10b981)}";
3
- let j = !1;
4
- function ie() {
5
- if (typeof document > "u" || j) return;
1
+ import { defineComponent as F, computed as _, ref as M, inject as C, onUnmounted as X, watch as D, onMounted as ee, openBlock as a, createElementBlock as o, normalizeClass as R, unref as z, createElementVNode as w, Fragment as k, renderList as H, toDisplayString as p, createTextVNode as N, createCommentVNode as Q, withKeys as T, withModifiers as U, withDirectives as te, vModelText as ne, provide as E, normalizeStyle as re, renderSlot as se } from "vue";
2
+ const ie = ".quiz-progress-bar{position:sticky;top:var(--vp-nav-height, 64px);z-index:20;display:flex;align-items:center;gap:12px;margin:-20px -24px 24px;padding:12px 24px;background:var(--vp-c-bg);border-bottom:1px solid var(--vp-c-divider)}@media(max-width:959px){.quiz-progress-bar{top:calc(var(--vp-nav-height, 64px) - 16px)}}.quiz-progress-track{flex:1;height:8px;background:var(--vp-c-bg-soft);border-radius:4px;overflow:hidden}.quiz-progress-fill{height:100%;background:var(--vp-c-brand-1);border-radius:4px;transition:width .35s ease}.quiz-progress-fill.complete{background:var(--vp-c-green-1, #10b981)}.quiz-progress-label{font-size:13px;color:var(--vp-c-text-2);white-space:nowrap}.quiz-question{border:1px solid var(--vp-c-divider);border-radius:8px;padding:20px 24px;margin-bottom:16px;background:var(--vp-c-bg);transition:border-color .2s}.quiz-question-title{font-weight:600;font-size:15px;margin:0 0 6px;padding:0 5px;color:var(--vp-c-text-1);float:none;width:auto}.quiz-hint{font-size:13px;color:var(--vp-c-text-3);margin:0 0 10px;font-style:italic}.quiz-answers{list-style:none;padding:0;margin:0}.quiz-answer{display:flex;align-items:baseline;gap:10px;padding:8px 12px;margin:4px 0;border:1px solid transparent;border-radius:6px;cursor:pointer;transition:background-color .15s,border-color .15s;user-select:none;font-size:14px;color:var(--vp-c-text-1)}.quiz-answer:hover:not(.correct):not(.wrong):not(.missed){background:var(--vp-c-bg-soft)}.quiz-answer.selected{border-color:var(--vp-c-brand-1);background:var(--vp-c-brand-soft)}.quiz-answer.correct{border-color:var(--vp-c-green-1, #10b981);background:var(--vp-c-green-soft, rgba(16, 185, 129, .12));cursor:default}.quiz-answer.wrong{border-color:var(--vp-c-red-1, #ef4444);background:var(--vp-c-red-soft, rgba(239, 68, 68, .12));cursor:default}.quiz-answer.missed{border-color:var(--vp-c-yellow-1, #f59e0b);background:var(--vp-c-yellow-soft, rgba(245, 158, 11, .1));cursor:default}.validated .quiz-answer{pointer-events:none}.quiz-indicator{flex-shrink:0;width:18px;text-align:center;font-size:15px;line-height:1}.quiz-empty{color:var(--vp-c-text-3)}.quiz-check{color:var(--vp-c-brand-1)}.quiz-answer.correct .quiz-check{color:var(--vp-c-green-1, #10b981)}.quiz-answer.wrong .quiz-check{color:var(--vp-c-red-1, #ef4444)}.quiz-answer-text code{font-family:var(--vp-font-family-mono);font-size:13px;padding:1px 5px;border-radius:4px;background:var(--vp-c-bg-soft);color:var(--vp-c-text-1)}.quiz-explanation{margin-top:12px;padding:10px 14px;border-left:3px solid var(--vp-c-brand-1);background:var(--vp-c-bg-soft);border-radius:0 6px 6px 0;font-size:13px;color:var(--vp-c-text-2)}.quiz-actions{display:flex;flex-wrap:wrap;align-items:center;gap:16px;margin-top:24px;padding-top:20px;border-top:1px solid var(--vp-c-divider)}.quiz-btn{display:inline-flex;align-items:center;justify-content:center;padding:10px 28px;font-size:14px;font-weight:600;border:1px solid transparent;border-radius:8px;cursor:pointer;transition:opacity .2s,background .2s}.quiz-btn:disabled{opacity:.45;cursor:not-allowed}.quiz-btn-validate{background:var(--vp-c-brand-1);color:var(--vp-c-white, #fff)}.quiz-btn-validate:hover:not(:disabled){opacity:.88}.quiz-btn-reset{background:var(--vp-c-bg-soft);border-color:var(--vp-c-divider);color:var(--vp-c-text-1)}.quiz-btn-reset:hover{background:var(--vp-c-bg-mute)}.quiz-score{display:flex;align-items:baseline;gap:8px}.quiz-score-value{font-size:22px;font-weight:700;color:var(--vp-c-brand-1)}.quiz-score-label{font-size:14px;color:var(--vp-c-text-2)}.quiz-input-wrapper{margin-top:8px}.quiz-input{width:100%;max-width:400px;padding:8px 12px;font-size:14px;font-family:var(--vp-font-family-mono);border:1px solid var(--vp-c-divider);border-radius:6px;background:var(--vp-c-bg);color:var(--vp-c-text-1);outline:none;transition:border-color .15s}.quiz-input:focus{border-color:var(--vp-c-brand-1)}.quiz-input:disabled{cursor:not-allowed;opacity:.8}.quiz-input.correct{border-color:var(--vp-c-green-1, #10b981);background:var(--vp-c-green-soft, rgba(16, 185, 129, .12))}.quiz-input.wrong{border-color:var(--vp-c-red-1, #ef4444);background:var(--vp-c-red-soft, rgba(239, 68, 68, .12))}.quiz-expected{margin-top:6px;font-size:13px;color:var(--vp-c-text-2)}.quiz-expected code{font-family:var(--vp-font-family-mono);font-size:13px;padding:1px 5px;border-radius:4px;background:var(--vp-c-bg-soft);color:var(--vp-c-green-1, #10b981)}";
3
+ let K = !1;
4
+ function ae() {
5
+ if (typeof document > "u" || K) return;
6
6
  const e = "vitepress-plugin-quiz-styles";
7
7
  if (document.getElementById(e)) {
8
- j = !0;
8
+ K = !0;
9
9
  return;
10
10
  }
11
- const t = document.createElement("style");
12
- t.id = e, t.textContent = se, document.head.appendChild(t), j = !0;
11
+ const n = document.createElement("style");
12
+ n.id = e, n.textContent = ie, document.head.appendChild(n), K = !0;
13
13
  }
14
- const ae = /^:::quiz\s*$/, oe = /^:::\s*$/;
15
- function Fe(e) {
16
- const t = e.utils.escapeHtml;
14
+ const oe = /^:::quiz\s*$/, le = /^:::\s*$/, ue = /^([A-Za-z-]+):(.*)$/, ce = /* @__PURE__ */ new Set([
15
+ "question",
16
+ "answer",
17
+ "answer-correct",
18
+ "answer-input",
19
+ "explanation",
20
+ "explication",
21
+ "shuffle"
22
+ ]);
23
+ function Le(e) {
24
+ const n = e.utils.escapeHtml;
17
25
  e.block.ruler.before(
18
26
  "fence",
19
27
  "quiz",
20
- (r, u, n, w) => le(r, u, n, w, t),
28
+ (r, c, s, m) => pe(r, c, s, m, n),
21
29
  { alt: ["paragraph", "reference", "blockquote", "list"] }
22
- ), e.renderer.rules.quiz = (r, u) => r[u].content, e.core.ruler.push("quiz_page_wrap", (r) => {
23
- if (!r.tokens.some((v) => v.type === "quiz")) return;
24
- const n = new r.Token("html_block", "", 0);
25
- n.content = `<QuizPage>
26
- `, n.block = !0;
27
- const w = new r.Token("html_block", "", 0);
28
- w.content = `</QuizPage>
29
- `, w.block = !0, r.tokens.unshift(n), r.tokens.push(w);
30
+ ), e.renderer.rules.quiz = (r, c) => r[c].content, e.core.ruler.push("quiz_page_wrap", (r) => {
31
+ if (!r.tokens.some((d) => d.type === "quiz")) return;
32
+ const s = new r.Token("html_block", "", 0);
33
+ s.content = `<QuizPage>
34
+ `, s.block = !0;
35
+ const m = new r.Token("html_block", "", 0);
36
+ m.content = `</QuizPage>
37
+ `, m.block = !0, r.tokens.unshift(s), r.tokens.push(m);
30
38
  });
31
39
  }
32
- function le(e, t, r, u, n) {
33
- const w = e.bMarks[t] + e.tShift[t], v = e.eMarks[t], i = e.src.slice(w, v);
34
- if (!ae.test(i)) return !1;
35
- if (u) return !0;
36
- let x = t + 1, k = !1;
37
- for (; x < r; ) {
38
- const h = e.bMarks[x] + e.tShift[x], P = e.eMarks[x], S = e.src.slice(h, P);
39
- if (oe.test(S)) {
40
- k = !0;
40
+ function pe(e, n, r, c, s) {
41
+ if (e.sCount[n] - e.blkIndent >= 4) return !1;
42
+ const m = e.bMarks[n] + e.tShift[n], d = e.eMarks[n], v = e.src.slice(m, d);
43
+ if (!oe.test(v)) return !1;
44
+ if (c) return !0;
45
+ let h = n + 1, q = !1;
46
+ for (; h < r; ) {
47
+ const l = e.bMarks[h] + e.tShift[h], I = e.eMarks[h], A = e.src.slice(l, I);
48
+ if (le.test(A)) {
49
+ q = !0;
41
50
  break;
42
51
  }
43
- x++;
52
+ h++;
44
53
  }
45
- if (!k) return !1;
46
- const f = [];
47
- for (let h = t + 1; h < x; h++) {
48
- const P = e.bMarks[h] + e.tShift[h], S = e.eMarks[h];
49
- f.push(e.src.slice(P, S));
54
+ if (!q) return !1;
55
+ const x = [];
56
+ for (let l = n + 1; l < h; l++) {
57
+ const I = e.bMarks[l] + e.tShift[l], A = e.eMarks[l];
58
+ x.push(e.src.slice(I, A));
50
59
  }
51
- const m = ue(f);
52
- if (!m) return !1;
53
- const C = e.push("quiz", "", 0);
54
- return C.content = ce(m, n), C.map = [t, x + 1], C.block = !0, e.line = x + 1, !0;
60
+ const g = de(x);
61
+ if (g?.type === "choice" && !g.answers.some((l) => l.correct) && console.warn(
62
+ `[vitepress-plugin-quiz] :quiz block at line ${n + 1} has no 'answer-correct:'; it can never be answered correctly.`
63
+ ), !g)
64
+ return console.warn(
65
+ `[vitepress-plugin-quiz] Ignored invalid :::quiz block at line ${n + 1}: needs a 'question:' and at least one 'answer:'/'answer-correct:' or 'answer-input:'.`
66
+ ), !1;
67
+ const S = e.push("quiz", "", 0);
68
+ return S.content = ve(g, s), S.map = [n, h + 1], S.block = !0, e.line = h + 1, !0;
55
69
  }
56
- function ue(e) {
57
- let t = "";
70
+ function de(e) {
71
+ let n = "";
58
72
  const r = [];
59
- let u = "";
60
- const n = [];
61
- let w = !1;
73
+ let c = "";
74
+ const s = [];
75
+ let m = !1, d = null;
62
76
  for (const v of e) {
63
- const i = v.trim();
64
- i && (i.startsWith("question:") ? t = i.slice(9).trim() : i.startsWith("answer-correct:") ? r.push({ text: i.slice(15).trim(), correct: !0 }) : i.startsWith("answer-input:") ? n.push(i.slice(13).trim()) : i.startsWith("answer:") ? r.push({ text: i.slice(7).trim(), correct: !1 }) : i.startsWith("explanation:") || i.startsWith("explication:") ? u = i.slice(12).trim() : i.startsWith("shuffle:") && (w = i.slice(8).trim().toLowerCase() === "true"));
77
+ const h = v.trim();
78
+ if (!h) continue;
79
+ const q = ue.exec(h), x = q?.[1].toLowerCase();
80
+ if (!q || !x || !ce.has(x)) {
81
+ d?.(h);
82
+ continue;
83
+ }
84
+ const g = q[2].trim(), S = (l, I) => l ? `${l} ${I}` : I;
85
+ switch (x) {
86
+ case "question":
87
+ n = g, d = (l) => n = S(n, l);
88
+ break;
89
+ case "answer-correct":
90
+ case "answer": {
91
+ const l = { text: g, correct: x === "answer-correct" };
92
+ r.push(l), d = (I) => l.text = S(l.text, I);
93
+ break;
94
+ }
95
+ case "answer-input":
96
+ g && s.push(g), d = null;
97
+ break;
98
+ case "explanation":
99
+ case "explication":
100
+ c = g, d = (l) => c = S(c, l);
101
+ break;
102
+ case "shuffle":
103
+ m = g.toLowerCase() === "true", d = null;
104
+ break;
105
+ }
65
106
  }
66
- return t ? n.length > 0 ? { question: t, type: "input", answers: [], expected: n, explanation: u, shuffle: !1 } : r.length === 0 ? null : { question: t, type: "choice", answers: r, expected: [], explanation: u, shuffle: w } : null;
107
+ return n ? s.length > 0 ? { question: n, type: "input", answers: [], expected: s, explanation: c, shuffle: !1 } : r.length === 0 ? null : { question: n, type: "choice", answers: r, expected: [], explanation: c, shuffle: m } : null;
67
108
  }
68
- function ce(e, t) {
109
+ function ve(e, n) {
69
110
  const r = JSON.stringify(e);
70
- return `<QuizQuestion data-quiz="${t(r)}" />
111
+ return `<QuizQuestion data-quiz="${n(r)}" />
71
112
  `;
72
113
  }
73
- const U = {
114
+ const W = {
74
115
  en: {
75
116
  answered: "answered",
76
117
  validate: "Validate",
@@ -127,325 +168,342 @@ const U = {
127
168
  expectedAnswer: "Respuesta esperada:"
128
169
  }
129
170
  };
130
- function pe(e = "en") {
131
- return U[e] ?? U.en;
171
+ function fe(e = "en") {
172
+ return W[e] ?? W.en;
173
+ }
174
+ function j(e) {
175
+ const n = [], r = /(\*\*(?!\s)(.+?)\*\*)|(\*(?!\s)(.+?)(?<!\s)\*)|(`([^`]+)`)/g;
176
+ let c = 0, s;
177
+ for (; (s = r.exec(e)) !== null; )
178
+ s.index > c && n.push({ type: "text", value: e.slice(c, s.index) }), s[2] ? n.push({ type: "bold", value: s[2] }) : s[4] ? n.push({ type: "italic", value: s[4] }) : s[6] && n.push({ type: "code", value: s[6] }), c = r.lastIndex;
179
+ return c < e.length && n.push({ type: "text", value: e.slice(c) }), n;
132
180
  }
133
- function J(e) {
134
- const t = [], r = /(\*\*(.+?)\*\*)|(\*(.+?)\*)|(`([^`]+)`)/g;
135
- let u = 0, n;
136
- for (; (n = r.exec(e)) !== null; )
137
- n.index > u && t.push({ type: "text", value: e.slice(u, n.index) }), n[2] ? t.push({ type: "bold", value: n[2] }) : n[4] ? t.push({ type: "italic", value: n[4] }) : n[6] && t.push({ type: "code", value: n[6] }), u = r.lastIndex;
138
- return u < e.length && t.push({ type: "text", value: e.slice(u) }), t;
181
+ function Y(e) {
182
+ return e.normalize("NFD").replace(/\p{M}/gu, "").trim().replace(/\s+/g, " ").toLowerCase();
139
183
  }
140
- const de = ["aria-label"], ve = { class: "quiz-question-title" }, fe = { key: 0 }, he = { key: 1 }, ge = { key: 2 }, ze = {
184
+ const ge = ["aria-label"], xe = { class: "quiz-question-title" }, he = { key: 0 }, be = { key: 1 }, ze = { key: 2 }, we = {
141
185
  key: 0,
142
186
  class: "quiz-hint"
143
- }, be = ["aria-multiselectable"], xe = ["onClick", "aria-selected", "onKeydown"], we = {
187
+ }, qe = ["aria-multiselectable"], ye = ["onClick", "aria-selected", "onKeydown"], me = {
144
188
  class: "quiz-indicator",
145
189
  "aria-hidden": "true"
146
- }, qe = {
190
+ }, ke = {
147
191
  key: 0,
148
192
  class: "quiz-check"
149
- }, me = {
193
+ }, _e = {
150
194
  key: 1,
151
195
  class: "quiz-empty"
152
- }, ye = {
196
+ }, Se = {
153
197
  key: 0,
154
198
  class: "quiz-check"
155
- }, ke = {
199
+ }, Ie = {
156
200
  key: 1,
157
201
  class: "quiz-empty"
158
- }, _e = { class: "quiz-answer-text" }, Se = { key: 0 }, Ae = { key: 1 }, Qe = { key: 2 }, Ce = { class: "quiz-hint" }, $e = { class: "quiz-input-wrapper" }, Ie = ["disabled", "placeholder", "aria-label"], Me = {
202
+ }, Ae = { class: "quiz-answer-text" }, $e = { key: 0 }, Ce = { key: 1 }, Qe = { key: 2 }, Me = { class: "quiz-hint" }, Ee = { class: "quiz-input-wrapper" }, Pe = ["disabled", "placeholder", "aria-label"], He = {
159
203
  key: 0,
160
204
  class: "quiz-expected"
161
- }, Pe = {
205
+ }, Ne = {
162
206
  key: 2,
163
207
  class: "quiz-explanation",
164
208
  role: "note"
165
- }, Ee = { key: 0 }, He = { key: 1 }, Re = { key: 2 }, Ve = /* @__PURE__ */ F({
209
+ }, Re = { key: 0 }, Ve = { key: 1 }, Oe = { key: 2 }, Te = /* @__PURE__ */ F({
166
210
  __name: "QuizQuestion",
167
211
  props: {
168
212
  dataQuiz: { type: String, required: !0 }
169
213
  },
170
214
  setup(e) {
171
- const t = e, r = _(() => {
215
+ const n = e, r = _(() => {
172
216
  try {
173
- return JSON.parse(t.dataQuiz);
217
+ return JSON.parse(n.dataQuiz);
174
218
  } catch {
175
219
  return null;
176
220
  }
177
221
  });
178
- function u(p) {
179
- const l = [...p];
180
- for (let s = l.length - 1; s > 0; s--) {
181
- const y = Math.floor(Math.random() * (s + 1));
182
- [l[s], l[y]] = [l[y], l[s]];
222
+ function c(u) {
223
+ const i = [...u];
224
+ for (let t = i.length - 1; t > 0; t--) {
225
+ const y = Math.floor(Math.random() * (t + 1));
226
+ [i[t], i[y]] = [i[y], i[t]];
183
227
  }
184
- return l;
228
+ return i;
185
229
  }
186
- const n = M([]);
187
- function w() {
230
+ const s = M([]);
231
+ function m() {
188
232
  if (!r.value || r.value.type === "input") {
189
- n.value = [];
233
+ s.value = [];
190
234
  return;
191
235
  }
192
- const p = r.value.answers.map((l, s) => ({ ...l, originalIndex: s }));
193
- n.value = r.value.shuffle ? u(p) : p;
236
+ const u = r.value.answers.map((i, t) => ({ ...i, originalIndex: t }));
237
+ s.value = r.value.shuffle ? c(u) : u;
194
238
  }
195
- const v = _(() => r.value ? {
239
+ const d = _(() => r.value ? {
196
240
  ...r.value,
197
- answers: n.value
198
- } : null), i = _(() => r.value?.type === "input"), x = _(
199
- () => v.value && !i.value ? v.value.answers.filter((p) => p.correct).length : 0
200
- ), k = _(() => x.value > 1), f = M(/* @__PURE__ */ new Set()), m = M(""), C = $("quiz-register", null), h = $("quiz-validated", M(!1)), P = $("quiz-reset", M(0)), S = $("quiz-locale"), H = $("quiz-question-id", null), d = $("quiz-save-answer", null), b = $("quiz-get-answer", null), Q = H ? H() : null, B = _(() => i.value ? m.value.trim().length > 0 : f.value.size > 0), T = _(() => {
201
- if (!v.value || !B.value) return !1;
202
- if (i.value) {
203
- const l = m.value.trim().toLowerCase();
204
- return r.value.expected.some((s) => l === s.trim().toLowerCase());
241
+ answers: s.value
242
+ } : null), v = _(() => r.value?.type === "input"), h = _(
243
+ () => d.value && !v.value ? d.value.answers.filter((u) => u.correct).length : 0
244
+ ), q = _(() => h.value > 1), x = M(/* @__PURE__ */ new Set()), g = M(""), S = C("quiz-register", null), l = C("quiz-validated", M(!1)), I = C("quiz-reset", M(0)), A = C("quiz-locale"), P = C("quiz-question-id", null), f = C("quiz-save-answer", null), b = C("quiz-get-answer", null), $ = P ? P() : null, J = _(() => v.value ? g.value.trim().length > 0 : x.value.size > 0), V = _(() => {
245
+ if (!d.value || !J.value) return !1;
246
+ if (v.value) {
247
+ const i = Y(g.value);
248
+ return r.value.expected.some((t) => i === Y(t));
205
249
  }
206
- const p = new Set(
207
- v.value.answers.map((l, s) => l.correct ? s : -1).filter((l) => l >= 0)
250
+ const u = new Set(
251
+ r.value.answers.map((i, t) => i.correct ? t : -1).filter((i) => i >= 0)
208
252
  );
209
- if (f.value.size !== p.size) return !1;
210
- for (const l of f.value)
211
- if (!p.has(l)) return !1;
253
+ if (x.value.size !== u.size) return !1;
254
+ for (const i of x.value)
255
+ if (!u.has(i)) return !1;
212
256
  return !0;
213
257
  });
214
- C && C({ answered: B, isCorrect: T }), D(P, () => {
215
- f.value = /* @__PURE__ */ new Set(), m.value = "", w();
216
- }), X(() => {
217
- if (w(), b && Q !== null) {
218
- const p = b(Q);
219
- p && (p.type === "input" ? m.value = p.input : p.type === "choice" && (f.value = new Set(p.selected)));
258
+ if (S && r.value) {
259
+ const u = S({ answered: J, isCorrect: V });
260
+ X(u);
261
+ }
262
+ D(I, () => {
263
+ x.value = /* @__PURE__ */ new Set(), g.value = "", m();
264
+ }), ee(() => {
265
+ if (m(), b && $ !== null) {
266
+ const u = b($);
267
+ if (u) {
268
+ if (u.type === "input" && v.value && typeof u.input == "string")
269
+ g.value = u.input;
270
+ else if (u.type === "choice" && !v.value && Array.isArray(u.selected)) {
271
+ const i = r.value?.answers.length ?? 0;
272
+ x.value = new Set(
273
+ u.selected.filter((t) => Number.isInteger(t) && t >= 0 && t < i)
274
+ );
275
+ }
276
+ }
220
277
  }
221
278
  });
222
- function W(p) {
223
- if (h.value) return;
224
- const l = new Set(f.value);
225
- k.value ? l.has(p) ? l.delete(p) : l.add(p) : (l.clear(), l.add(p)), f.value = l, K();
279
+ function O(u) {
280
+ if (l.value) return;
281
+ const i = new Set(x.value);
282
+ q.value ? i.has(u) ? i.delete(u) : i.add(u) : (i.clear(), i.add(u)), x.value = i, B();
226
283
  }
227
- D(m, () => {
228
- h.value || K();
284
+ D(g, () => {
285
+ l.value || B();
229
286
  });
230
- function K() {
231
- !d || Q === null || (i.value ? d(Q, { type: "input", input: m.value }) : d(Q, { type: "choice", selected: [...f.value] }));
287
+ function B() {
288
+ !f || $ === null || (v.value ? f($, { type: "input", input: g.value }) : f($, { type: "choice", selected: [...x.value] }));
232
289
  }
233
- function G(p) {
234
- if (!h.value)
235
- return f.value.has(p) ? "quiz-answer selected" : "quiz-answer";
236
- const l = v.value.answers[p], s = f.value.has(p);
237
- return l.correct && s ? "quiz-answer correct" : l.correct && !s ? "quiz-answer missed" : !l.correct && s ? "quiz-answer wrong" : "quiz-answer";
290
+ function Z(u) {
291
+ const i = x.value.has(u.originalIndex);
292
+ return l.value ? u.correct && i ? "quiz-answer correct" : u.correct && !i ? "quiz-answer missed" : !u.correct && i ? "quiz-answer wrong" : "quiz-answer" : i ? "quiz-answer selected" : "quiz-answer";
238
293
  }
239
- const Y = _(() => h.value ? T.value ? "quiz-input correct" : "quiz-input wrong" : "quiz-input");
240
- return (p, l) => v.value ? (a(), o("fieldset", {
294
+ const G = _(() => l.value ? V.value ? "quiz-input correct" : "quiz-input wrong" : "quiz-input");
295
+ return (u, i) => d.value ? (a(), o("fieldset", {
241
296
  key: 0,
242
- class: N(["quiz-question", { validated: g(h) }]),
243
- "aria-label": v.value.question
297
+ class: R(["quiz-question", { validated: z(l) }]),
298
+ "aria-label": d.value.question
244
299
  }, [
245
- z("legend", ve, [
246
- (a(!0), o(q, null, R(g(J)(v.value.question), (s, y) => (a(), o(q, { key: y }, [
247
- s.type === "bold" ? (a(), o("strong", fe, c(s.value), 1)) : s.type === "italic" ? (a(), o("em", he, c(s.value), 1)) : s.type === "code" ? (a(), o("code", ge, c(s.value), 1)) : (a(), o(q, { key: 3 }, [
248
- V(c(s.value), 1)
300
+ w("legend", xe, [
301
+ (a(!0), o(k, null, H(z(j)(d.value.question), (t, y) => (a(), o(k, { key: y }, [
302
+ t.type === "bold" ? (a(), o("strong", he, p(t.value), 1)) : t.type === "italic" ? (a(), o("em", be, p(t.value), 1)) : t.type === "code" ? (a(), o("code", ze, p(t.value), 1)) : (a(), o(k, { key: 3 }, [
303
+ N(p(t.value), 1)
249
304
  ], 64))
250
305
  ], 64))), 128))
251
306
  ]),
252
- i.value ? I("", !0) : (a(), o(q, { key: 0 }, [
253
- k.value ? (a(), o("p", ze, c(g(S).multipleHint), 1)) : I("", !0),
254
- z("ul", {
307
+ v.value ? Q("", !0) : (a(), o(k, { key: 0 }, [
308
+ q.value ? (a(), o("p", we, p(z(A).multipleHint), 1)) : Q("", !0),
309
+ w("ul", {
255
310
  class: "quiz-answers",
256
311
  role: "listbox",
257
- "aria-multiselectable": k.value
312
+ "aria-multiselectable": q.value
258
313
  }, [
259
- (a(!0), o(q, null, R(v.value.answers, (s, y) => (a(), o("li", {
260
- key: s.originalIndex,
261
- class: N(G(y)),
262
- onClick: (A) => W(y),
314
+ (a(!0), o(k, null, H(d.value.answers, (t) => (a(), o("li", {
315
+ key: t.originalIndex,
316
+ class: R(Z(t)),
317
+ onClick: (y) => O(t.originalIndex),
263
318
  role: "option",
264
- "aria-selected": f.value.has(y),
319
+ "aria-selected": x.value.has(t.originalIndex),
265
320
  tabindex: "0",
266
321
  onKeydown: [
267
- O((A) => W(y), ["enter"]),
268
- O(L((A) => W(y), ["prevent"]), ["space"])
322
+ T((y) => O(t.originalIndex), ["enter"]),
323
+ T(U((y) => O(t.originalIndex), ["prevent"]), ["space"])
269
324
  ]
270
325
  }, [
271
- z("span", we, [
272
- k.value ? (a(), o(q, { key: 0 }, [
273
- f.value.has(y) ? (a(), o("span", qe, "✓")) : (a(), o("span", me, "☐"))
274
- ], 64)) : (a(), o(q, { key: 1 }, [
275
- f.value.has(y) ? (a(), o("span", ye, "●")) : (a(), o("span", ke, "○"))
326
+ w("span", me, [
327
+ q.value ? (a(), o(k, { key: 0 }, [
328
+ x.value.has(t.originalIndex) ? (a(), o("span", ke, "✓")) : (a(), o("span", _e, "☐"))
329
+ ], 64)) : (a(), o(k, { key: 1 }, [
330
+ x.value.has(t.originalIndex) ? (a(), o("span", Se, "●")) : (a(), o("span", Ie, "○"))
276
331
  ], 64))
277
332
  ]),
278
- z("span", _e, [
279
- (a(!0), o(q, null, R(g(J)(s.text), (A, Z) => (a(), o(q, { key: Z }, [
280
- A.type === "bold" ? (a(), o("strong", Se, c(A.value), 1)) : A.type === "italic" ? (a(), o("em", Ae, c(A.value), 1)) : A.type === "code" ? (a(), o("code", Qe, c(A.value), 1)) : (a(), o(q, { key: 3 }, [
281
- V(c(A.value), 1)
333
+ w("span", Ae, [
334
+ (a(!0), o(k, null, H(z(j)(t.text), (y, L) => (a(), o(k, { key: L }, [
335
+ y.type === "bold" ? (a(), o("strong", $e, p(y.value), 1)) : y.type === "italic" ? (a(), o("em", Ce, p(y.value), 1)) : y.type === "code" ? (a(), o("code", Qe, p(y.value), 1)) : (a(), o(k, { key: 3 }, [
336
+ N(p(y.value), 1)
282
337
  ], 64))
283
338
  ], 64))), 128))
284
339
  ])
285
- ], 42, xe))), 128))
286
- ], 8, be)
340
+ ], 42, ye))), 128))
341
+ ], 8, qe)
287
342
  ], 64)),
288
- i.value ? (a(), o(q, { key: 1 }, [
289
- z("p", Ce, c(g(S).inputHint), 1),
290
- z("div", $e, [
291
- ee(z("input", {
292
- "onUpdate:modelValue": l[0] || (l[0] = (s) => m.value = s),
293
- class: N(Y.value),
343
+ v.value ? (a(), o(k, { key: 1 }, [
344
+ w("p", Me, p(z(A).inputHint), 1),
345
+ w("div", Ee, [
346
+ te(w("input", {
347
+ "onUpdate:modelValue": i[0] || (i[0] = (t) => g.value = t),
348
+ class: R(G.value),
294
349
  type: "text",
295
- disabled: g(h),
296
- placeholder: g(S).inputPlaceholder,
297
- "aria-label": v.value.question,
350
+ disabled: z(l),
351
+ placeholder: z(A).inputPlaceholder,
352
+ "aria-label": d.value.question,
298
353
  autocomplete: "off",
299
354
  spellcheck: "false",
300
- onKeydown: l[1] || (l[1] = O(L(() => {
355
+ onKeydown: i[1] || (i[1] = T(U(() => {
301
356
  }, ["prevent"]), ["enter"]))
302
- }, null, 42, Ie), [
303
- [te, m.value]
357
+ }, null, 42, Pe), [
358
+ [ne, g.value]
304
359
  ]),
305
- g(h) && !T.value ? (a(), o("p", Me, [
306
- V(c(g(S).expectedAnswer) + " ", 1),
307
- z("code", null, c(r.value?.expected[0]), 1)
308
- ])) : I("", !0)
360
+ z(l) && !V.value ? (a(), o("p", He, [
361
+ N(p(z(A).expectedAnswer) + " ", 1),
362
+ w("code", null, p(r.value?.expected[0]), 1)
363
+ ])) : Q("", !0)
309
364
  ])
310
- ], 64)) : I("", !0),
311
- g(h) && v.value.explanation ? (a(), o("div", Pe, [
312
- z("strong", null, c(g(S).explanation), 1),
313
- (a(!0), o(q, null, R(g(J)(v.value.explanation), (s, y) => (a(), o(q, { key: y }, [
314
- s.type === "bold" ? (a(), o("strong", Ee, c(s.value), 1)) : s.type === "italic" ? (a(), o("em", He, c(s.value), 1)) : s.type === "code" ? (a(), o("code", Re, c(s.value), 1)) : (a(), o(q, { key: 3 }, [
315
- V(c(s.value), 1)
365
+ ], 64)) : Q("", !0),
366
+ z(l) && d.value.explanation ? (a(), o("div", Ne, [
367
+ w("strong", null, p(z(A).explanation), 1),
368
+ (a(!0), o(k, null, H(z(j)(d.value.explanation), (t, y) => (a(), o(k, { key: y }, [
369
+ t.type === "bold" ? (a(), o("strong", Re, p(t.value), 1)) : t.type === "italic" ? (a(), o("em", Ve, p(t.value), 1)) : t.type === "code" ? (a(), o("code", Oe, p(t.value), 1)) : (a(), o(k, { key: 3 }, [
370
+ N(p(t.value), 1)
316
371
  ], 64))
317
372
  ], 64))), 128))
318
- ])) : I("", !0)
319
- ], 10, de)) : I("", !0);
373
+ ])) : Q("", !0)
374
+ ], 10, ge)) : Q("", !0);
320
375
  }
321
- }), Ne = {
376
+ }), Ke = {
322
377
  class: "quiz-page",
323
378
  role: "region",
324
379
  "aria-label": "Quiz"
325
- }, Te = ["aria-valuenow", "aria-valuemax", "aria-label"], We = { class: "quiz-progress-track" }, Oe = {
380
+ }, je = ["aria-valuenow", "aria-valuemax", "aria-label"], Je = { class: "quiz-progress-track" }, Be = {
326
381
  class: "quiz-progress-label",
327
382
  "aria-live": "polite"
328
- }, je = { class: "quiz-actions" }, Je = ["disabled"], Be = ["aria-label"], Ke = { class: "quiz-score-value" }, De = { class: "quiz-score-label" }, Le = /* @__PURE__ */ F({
383
+ }, De = { class: "quiz-actions" }, Ue = ["disabled"], We = ["aria-label"], Ye = { class: "quiz-score-value" }, Fe = { class: "quiz-score-label" }, Ze = /* @__PURE__ */ F({
329
384
  __name: "QuizPage",
330
385
  setup(e) {
331
- const t = $("quiz-locale"), r = M([]), u = M(!1), n = typeof window < "u" ? "quiz-state:" + window.location.pathname : "";
332
- S();
333
- let w = 0;
334
- E("quiz-validated", u), E("quiz-register", (d) => {
335
- r.value.push(d);
336
- }), E("quiz-question-id", () => w++), E("quiz-save-answer", (d, b) => {
337
- if (n)
386
+ const n = C("quiz-locale"), r = M([]), c = M(!1), s = typeof window < "u" ? "quiz-state:" + window.location.pathname : "";
387
+ A();
388
+ let m = 0;
389
+ E("quiz-validated", c), E("quiz-register", (f) => (r.value.push(f), () => {
390
+ const b = r.value.indexOf(f);
391
+ b >= 0 && r.value.splice(b, 1);
392
+ })), E("quiz-question-id", () => m++), E("quiz-save-answer", (f, b) => {
393
+ if (s)
338
394
  try {
339
- sessionStorage.setItem(n + ":q" + d, JSON.stringify(b));
395
+ sessionStorage.setItem(s + ":q" + f, JSON.stringify(b));
340
396
  } catch {
341
397
  }
342
- }), E("quiz-get-answer", (d) => {
343
- if (!n) return null;
398
+ }), E("quiz-get-answer", (f) => {
399
+ if (!s) return null;
344
400
  try {
345
- const b = sessionStorage.getItem(n + ":q" + d);
401
+ const b = sessionStorage.getItem(s + ":q" + f);
346
402
  return b ? JSON.parse(b) : null;
347
403
  } catch {
348
404
  return null;
349
405
  }
350
406
  });
351
- const v = M(0);
352
- E("quiz-reset", v);
353
- const i = _(() => r.value.length), x = _(
354
- () => r.value.filter((d) => d.answered).length
355
- ), k = _(
356
- () => r.value.filter((d) => d.isCorrect).length
357
- ), f = _(() => x.value === i.value), m = _(
358
- () => i.value ? Math.round(x.value / i.value * 100) : 0
407
+ const d = M(0);
408
+ E("quiz-reset", d);
409
+ const v = _(() => r.value.length), h = _(
410
+ () => r.value.filter((f) => f.answered).length
411
+ ), q = _(
412
+ () => r.value.filter((f) => f.isCorrect).length
413
+ ), x = _(
414
+ () => v.value > 0 && h.value === v.value
415
+ ), g = _(
416
+ () => v.value ? Math.round(h.value / v.value * 100) : 0
359
417
  );
360
- function C() {
361
- u.value = !0, P();
418
+ function S() {
419
+ c.value = !0, I();
362
420
  }
363
- function h() {
364
- u.value = !1, v.value++, H();
421
+ function l() {
422
+ c.value = !1, d.value++, P();
365
423
  }
366
- function P() {
367
- if (n)
424
+ function I() {
425
+ if (s)
368
426
  try {
369
- const d = { validated: u.value, ts: Date.now() };
370
- sessionStorage.setItem(n, JSON.stringify(d));
427
+ const f = { validated: c.value, ts: Date.now() };
428
+ sessionStorage.setItem(s, JSON.stringify(f));
371
429
  } catch {
372
430
  }
373
431
  }
374
- function S() {
375
- if (n)
432
+ function A() {
433
+ if (s)
376
434
  try {
377
- const d = sessionStorage.getItem(n);
378
- if (!d) return;
379
- const b = JSON.parse(d);
380
- b && b.validated && (u.value = !0);
435
+ const f = sessionStorage.getItem(s);
436
+ if (!f) return;
437
+ const b = JSON.parse(f);
438
+ b && b.validated && (c.value = !0);
381
439
  } catch {
382
440
  }
383
441
  }
384
- function H() {
385
- if (n)
442
+ function P() {
443
+ if (s)
386
444
  try {
387
- const d = [];
445
+ const f = [];
388
446
  for (let b = 0; b < sessionStorage.length; b++) {
389
- const Q = sessionStorage.key(b);
390
- Q && Q.startsWith(n) && d.push(Q);
447
+ const $ = sessionStorage.key(b);
448
+ $ && $.startsWith(s) && f.push($);
391
449
  }
392
- d.forEach((b) => sessionStorage.removeItem(b));
450
+ f.forEach((b) => sessionStorage.removeItem(b));
393
451
  } catch {
394
452
  }
395
453
  }
396
- return (d, b) => (a(), o("div", Ne, [
397
- z("div", {
454
+ return (f, b) => (a(), o("div", Ke, [
455
+ w("div", {
398
456
  class: "quiz-progress-bar",
399
457
  role: "progressbar",
400
- "aria-valuenow": x.value,
458
+ "aria-valuenow": h.value,
401
459
  "aria-valuemin": 0,
402
- "aria-valuemax": i.value,
403
- "aria-label": x.value + " / " + i.value + " " + g(t).answered
460
+ "aria-valuemax": v.value,
461
+ "aria-label": h.value + " / " + v.value + " " + z(n).answered
404
462
  }, [
405
- z("div", We, [
406
- z("div", {
407
- class: N(["quiz-progress-fill", { complete: m.value === 100 }]),
408
- style: re({ width: m.value + "%" })
463
+ w("div", Je, [
464
+ w("div", {
465
+ class: R(["quiz-progress-fill", { complete: g.value === 100 }]),
466
+ style: re({ width: g.value + "%" })
409
467
  }, null, 6)
410
468
  ]),
411
- z("span", Oe, c(x.value) + " / " + c(i.value) + " " + c(g(t).answered), 1)
412
- ], 8, Te),
413
- ne(d.$slots, "default"),
414
- z("div", je, [
415
- u.value ? I("", !0) : (a(), o("button", {
469
+ w("span", Be, p(h.value) + " / " + p(v.value) + " " + p(z(n).answered), 1)
470
+ ], 8, je),
471
+ se(f.$slots, "default"),
472
+ w("div", De, [
473
+ c.value ? Q("", !0) : (a(), o("button", {
416
474
  key: 0,
417
475
  class: "quiz-btn quiz-btn-validate",
418
- disabled: !f.value,
419
- onClick: C
420
- }, c(g(t).validate), 9, Je)),
421
- u.value ? (a(), o(q, { key: 1 }, [
422
- z("div", {
476
+ disabled: !x.value,
477
+ onClick: S
478
+ }, p(z(n).validate), 9, Ue)),
479
+ c.value ? (a(), o(k, { key: 1 }, [
480
+ w("div", {
423
481
  class: "quiz-score",
424
482
  role: "status",
425
483
  "aria-live": "polite",
426
- "aria-label": k.value + " / " + i.value + " " + g(t).correctAnswers(k.value)
484
+ "aria-label": q.value + " / " + v.value + " " + z(n).correctAnswers(q.value)
427
485
  }, [
428
- z("span", Ke, c(k.value) + " / " + c(i.value), 1),
429
- z("span", De, c(g(t).correctAnswers(k.value)) + " (" + c(i.value ? Math.round(k.value / i.value * 100) : 0) + "%) ", 1)
430
- ], 8, Be),
431
- z("button", {
486
+ w("span", Ye, p(q.value) + " / " + p(v.value), 1),
487
+ w("span", Fe, p(z(n).correctAnswers(q.value)) + " (" + p(v.value ? Math.round(q.value / v.value * 100) : 0) + "%) ", 1)
488
+ ], 8, We),
489
+ w("button", {
432
490
  class: "quiz-btn quiz-btn-reset",
433
- onClick: h
434
- }, c(g(t).reset), 1)
435
- ], 64)) : I("", !0)
491
+ onClick: l
492
+ }, p(z(n).reset), 1)
493
+ ], 64)) : Q("", !0)
436
494
  ])
437
495
  ]));
438
496
  }
439
497
  });
440
- function Ge(e, t = "en") {
441
- ie(), e.provide("quiz-locale", pe(t)), e.component("QuizQuestion", Ve), e.component("QuizPage", Le);
498
+ function Xe(e, n = "en") {
499
+ ae(), e.provide("quiz-locale", fe(n)), e.component("QuizQuestion", Te), e.component("QuizPage", Ze);
442
500
  }
443
501
  export {
444
- Le as QuizPage,
445
- Ve as QuizQuestion,
446
- Ge as enhanceAppWithQuiz,
447
- pe as getLocale,
448
- U as locales,
449
- Fe as quizMarkdownPlugin
502
+ Ze as QuizPage,
503
+ Te as QuizQuestion,
504
+ Xe as enhanceAppWithQuiz,
505
+ fe as getLocale,
506
+ W as locales,
507
+ Le as quizMarkdownPlugin
450
508
  };
451
509
  //# sourceMappingURL=vitepress-plugin-quiz.js.map