@pie-element/venn-classification 0.1.1-next.0 → 0.1.1-next.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/author/index.js +25242 -16259
- package/dist/author/index.js.map +1 -1
- package/dist/browser/VennClassification-DtwuotJl.js +3419 -0
- package/dist/browser/VennClassification-DtwuotJl.js.map +1 -0
- package/dist/browser/author/index.js +22126 -0
- package/dist/browser/author/index.js.map +1 -0
- package/dist/browser/controller/index.js +2 -0
- package/dist/browser/controller-Dt0dg5dA.js +249 -0
- package/dist/browser/controller-Dt0dg5dA.js.map +1 -0
- package/dist/browser/delivery/index.js +36 -0
- package/dist/browser/delivery/index.js.map +1 -0
- package/dist/delivery/index.js +15 -8
- package/dist/delivery/index.js.map +1 -1
- package/dist/index.iife.js +4 -4
- package/dist/index.js +15 -8
- package/dist/index.js.map +1 -1
- package/dist/runtime-support.js +2 -2
- package/dist/runtime-support.js.map +1 -1
- package/package.json +12 -3
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, o as d, p as f, r as p, s as m, t as h, u as g } from "../controller-Dt0dg5dA.js";
|
|
2
|
+
export { h as SUPPORTED_CIRCLE_COUNTS, u as buildPreviewSession, i as composeRegionLabel, p as createCorrectResponseSession, s as createDefaultModel, f as enumerateRegions, t as getCorrectnessMap, l as getRegionLabel, d as getTileCorrectness, m as isComplete, n as model, o as normalizeRegion, c as normalizeSession, g as outcome, a as regionKey, e as regionsEqual, r as validate };
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
//#region src/controller/region.ts
|
|
2
|
+
function e(e) {
|
|
3
|
+
return !e || e.length === 0 ? "" : [...e].sort((e, t) => e - t).join(",");
|
|
4
|
+
}
|
|
5
|
+
function t(e) {
|
|
6
|
+
return !e || e.length === 0 ? [] : [...e].sort((e, t) => e - t);
|
|
7
|
+
}
|
|
8
|
+
function n(e, n) {
|
|
9
|
+
if (!e || !n) return !e == !n && (e?.length ?? 0) === (n?.length ?? 0);
|
|
10
|
+
if (e.length !== n.length) return !1;
|
|
11
|
+
let r = t(e), i = t(n);
|
|
12
|
+
for (let e = 0; e < r.length; e++) if (r[e] !== i[e]) return !1;
|
|
13
|
+
return !0;
|
|
14
|
+
}
|
|
15
|
+
function r(e) {
|
|
16
|
+
let t = [], n = 1 << e;
|
|
17
|
+
for (let r = 0; r < n; r++) {
|
|
18
|
+
let n = [];
|
|
19
|
+
for (let t = 0; t < e; t++) r & 1 << t && n.push(t);
|
|
20
|
+
t.push(n);
|
|
21
|
+
}
|
|
22
|
+
return t;
|
|
23
|
+
}
|
|
24
|
+
function i(e, n) {
|
|
25
|
+
let r = t(n), i = r.map((t) => e[t]?.label ?? `Set ${t + 1}`), a = e.length;
|
|
26
|
+
return r.length === 0 ? a === 2 ? `Neither ${e[0]?.label ?? "Set 1"} nor ${e[1]?.label ?? "Set 2"}` : `None of ${e.map((e, t) => e?.label ?? `Set ${t + 1}`).join(", ")}` : r.length === 1 ? `${i[0]} only` : i.join(" and ");
|
|
27
|
+
}
|
|
28
|
+
function a(t, n) {
|
|
29
|
+
let r = e(n), a = t.regionLabels?.[r];
|
|
30
|
+
return typeof a == "string" && a.trim().length > 0 ? a : i(t.circles ?? [], n);
|
|
31
|
+
}
|
|
32
|
+
var o = {
|
|
33
|
+
model: {
|
|
34
|
+
id: "1",
|
|
35
|
+
element: "venn-classification",
|
|
36
|
+
prompt: "<p>Sort each tile into the correct region of the Venn diagram.</p>",
|
|
37
|
+
promptEnabled: !0,
|
|
38
|
+
circles: [{ label: "Set A" }, { label: "Set B" }],
|
|
39
|
+
tiles: [],
|
|
40
|
+
regionLabels: {},
|
|
41
|
+
scoringPolicy: "partialPerTile"
|
|
42
|
+
},
|
|
43
|
+
configuration: {
|
|
44
|
+
prompt: {
|
|
45
|
+
label: "Prompt",
|
|
46
|
+
settings: !0
|
|
47
|
+
},
|
|
48
|
+
scoringPolicy: {
|
|
49
|
+
label: "Scoring policy",
|
|
50
|
+
settings: !0
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}, s = new Set([2]), c = (e) => !!e && typeof e == "object" && !Array.isArray(e) && Object.keys(e).length === 0;
|
|
54
|
+
function l(e) {
|
|
55
|
+
return String(e ?? "").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
56
|
+
}
|
|
57
|
+
function u(e = {}) {
|
|
58
|
+
let t = {
|
|
59
|
+
...o.model,
|
|
60
|
+
...e
|
|
61
|
+
};
|
|
62
|
+
return (!Array.isArray(t.circles) || t.circles.length === 0) && (t.circles = o.model.circles.map((e) => ({ ...e }))), Array.isArray(t.tiles) || (t.tiles = []), (!t.regionLabels || typeof t.regionLabels != "object") && (t.regionLabels = {}), t.scoringPolicy !== "allOrNothing" && t.scoringPolicy !== "partialPerTile" && (t.scoringPolicy = "partialPerTile"), t;
|
|
63
|
+
}
|
|
64
|
+
function d(e, n) {
|
|
65
|
+
let r = { ...e || {} }, i = e?.placements ?? {}, a = {};
|
|
66
|
+
for (let [e, n] of Object.entries(i)) n == null ? a[e] = null : Array.isArray(n) ? a[e] = t(n) : a[e] = null;
|
|
67
|
+
if (n?.tiles) for (let e of n.tiles) e.id in a || (a[e.id] = null);
|
|
68
|
+
return r.placements = a, r.completed = f(n, {
|
|
69
|
+
...r,
|
|
70
|
+
placements: a
|
|
71
|
+
}), r;
|
|
72
|
+
}
|
|
73
|
+
function f(e, t) {
|
|
74
|
+
if (!e || !Array.isArray(e.tiles) || e.tiles.length === 0) return !1;
|
|
75
|
+
let n = t?.placements ?? {};
|
|
76
|
+
for (let t of e.tiles) if (n[t.id] == null) return !1;
|
|
77
|
+
return !0;
|
|
78
|
+
}
|
|
79
|
+
function p(e, t) {
|
|
80
|
+
return t == null ? "unanswered" : n(e.correctRegion, t) ? "correct" : "incorrect";
|
|
81
|
+
}
|
|
82
|
+
function m(e, t) {
|
|
83
|
+
let n = {}, r = t?.placements ?? {};
|
|
84
|
+
for (let t of e.tiles ?? []) n[t.id] = p(t, r[t.id] ?? null);
|
|
85
|
+
return n;
|
|
86
|
+
}
|
|
87
|
+
function h(e, t, r = {}) {
|
|
88
|
+
return new Promise((i) => {
|
|
89
|
+
if (!t || c(t) || !t.placements || Object.keys(t.placements).length === 0) {
|
|
90
|
+
i({
|
|
91
|
+
score: 0,
|
|
92
|
+
empty: !0
|
|
93
|
+
});
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (r.mode !== "evaluate") {
|
|
97
|
+
i({
|
|
98
|
+
score: void 0,
|
|
99
|
+
completed: void 0
|
|
100
|
+
});
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
let a = u(e || void 0), o = a.tiles || [];
|
|
104
|
+
if (o.length === 0) {
|
|
105
|
+
i({
|
|
106
|
+
score: 0,
|
|
107
|
+
empty: !0
|
|
108
|
+
});
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
let s = t.placements || {}, l = 0, d = 0;
|
|
112
|
+
for (let e of o) {
|
|
113
|
+
let t = s[e.id];
|
|
114
|
+
t != null && (d += 1, n(e.correctRegion, t) && (l += 1));
|
|
115
|
+
}
|
|
116
|
+
if (d === 0) {
|
|
117
|
+
i({
|
|
118
|
+
score: 0,
|
|
119
|
+
empty: !0
|
|
120
|
+
});
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if ((a.scoringPolicy === "allOrNothing" ? "allOrNothing" : "partialPerTile") == "allOrNothing") {
|
|
124
|
+
i({ score: +(l === o.length) });
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
i({ score: l / o.length });
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function g(e, n, r = {}) {
|
|
131
|
+
return new Promise((i) => {
|
|
132
|
+
let a = u(e || void 0), o = r || {}, s = {
|
|
133
|
+
prompt: a.promptEnabled === !1 ? null : a.prompt ?? null,
|
|
134
|
+
circles: a.circles.map((e) => ({ label: e?.label ?? "" })),
|
|
135
|
+
tiles: a.tiles.map((e) => {
|
|
136
|
+
let n = String(e.imageUrl ?? "").trim(), r = n.length > 0 ? {
|
|
137
|
+
imageUrl: n,
|
|
138
|
+
imageAlt: String(e.imageAlt ?? "").trim()
|
|
139
|
+
} : {};
|
|
140
|
+
return {
|
|
141
|
+
id: e.id,
|
|
142
|
+
label: e.label ?? "",
|
|
143
|
+
...r,
|
|
144
|
+
...o.mode === "evaluate" ? { correctRegion: t(e.correctRegion) } : {}
|
|
145
|
+
};
|
|
146
|
+
}),
|
|
147
|
+
regionLabels: { ...a.regionLabels || {} },
|
|
148
|
+
scoringPolicy: a.scoringPolicy ?? "partialPerTile",
|
|
149
|
+
disabled: o.mode !== "gather",
|
|
150
|
+
mode: o.mode,
|
|
151
|
+
env: o
|
|
152
|
+
};
|
|
153
|
+
if (o.mode === "evaluate") {
|
|
154
|
+
let e = {};
|
|
155
|
+
for (let n of a.tiles) e[n.id] = t(n.correctRegion);
|
|
156
|
+
s.correctRegionsById = e, s.correctness = m(a, n);
|
|
157
|
+
}
|
|
158
|
+
if (o.role === "instructor" && (o.mode === "view" || o.mode === "evaluate")) {
|
|
159
|
+
let e = a;
|
|
160
|
+
s.teacherInstructions = e.teacherInstructionsEnabled ? e.teacherInstructions ?? null : null;
|
|
161
|
+
} else s.teacherInstructions = null;
|
|
162
|
+
i(s);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
function _(e, n = {}) {
|
|
166
|
+
return new Promise((r) => {
|
|
167
|
+
if (n.mode === "evaluate" || n.role !== "instructor") {
|
|
168
|
+
r(null);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
let i = u(e || void 0), a = {};
|
|
172
|
+
for (let e of i.tiles) a[e.id] = t(e.correctRegion);
|
|
173
|
+
r({
|
|
174
|
+
id: "1",
|
|
175
|
+
element: "venn-classification",
|
|
176
|
+
placements: a,
|
|
177
|
+
completed: !0
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
function v(e, n = {}) {
|
|
182
|
+
let r = {}, i = e || {};
|
|
183
|
+
if (i.promptEnabled) {
|
|
184
|
+
let e = (i.prompt ?? "").trim();
|
|
185
|
+
(!e || e === "<p></p>") && (r.prompt = "Prompt is required when prompt is enabled");
|
|
186
|
+
}
|
|
187
|
+
let a = Array.isArray(i.circles) ? i.circles : [];
|
|
188
|
+
if (!s.has(a.length)) r.circles = `Venn classification currently supports ${[...s].sort((e, t) => e - t).join(" or ")} circles (got ${a.length})`;
|
|
189
|
+
else for (let e = 0; e < a.length; e++) if (!(a[e]?.label ?? "").trim()) {
|
|
190
|
+
r.circles = `Circle ${e + 1} needs a label`;
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
let o = Array.isArray(i.tiles) ? i.tiles : [];
|
|
194
|
+
if (o.length < 1) r.tiles = "At least one tile is required";
|
|
195
|
+
else {
|
|
196
|
+
let e = /* @__PURE__ */ new Set();
|
|
197
|
+
for (let n = 0; n < o.length; n++) {
|
|
198
|
+
let i = o[n];
|
|
199
|
+
if (!i?.id) {
|
|
200
|
+
r.tiles = `Tile ${n + 1} is missing an id`;
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
if (e.has(i.id)) {
|
|
204
|
+
r.tiles = `Tile id "${i.id}" appears more than once`;
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
e.add(i.id);
|
|
208
|
+
let s = l(i.label), c = String(i.imageUrl ?? "").trim(), u = String(i.imageAlt ?? "").trim();
|
|
209
|
+
if (!s && !c) {
|
|
210
|
+
r.tiles = `Tile "${i.id}" needs a label or an image URL`;
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
if (c && !u) {
|
|
214
|
+
r.tiles = `Tile "${i.id}": when an image URL is set, short alt text is required for accessibility`;
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
let d = i.correctRegion;
|
|
218
|
+
if (!Array.isArray(d)) {
|
|
219
|
+
r.tiles = `Tile "${i.id}" is missing correctRegion`;
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
let f = t(d);
|
|
223
|
+
if (new Set(f).size !== f.length) {
|
|
224
|
+
r.tiles = `Tile "${i.id}" correctRegion has duplicate indexes`;
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
let p = f.find((e) => !Number.isInteger(e) || e < 0 || e >= a.length);
|
|
228
|
+
if (p !== void 0) {
|
|
229
|
+
r.tiles = `Tile "${i.id}" correctRegion index ${p} is out of range for ${a.length} circles`;
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return i.scoringPolicy !== void 0 && i.scoringPolicy !== "allOrNothing" && i.scoringPolicy !== "partialPerTile" && (r.scoringPolicy = "Scoring policy must be \"allOrNothing\" or \"partialPerTile\""), r;
|
|
235
|
+
}
|
|
236
|
+
function y(e) {
|
|
237
|
+
let n = u(e || void 0), r = {};
|
|
238
|
+
for (let e of n.tiles) r[e.id] = t(e.correctRegion);
|
|
239
|
+
return {
|
|
240
|
+
id: "preview",
|
|
241
|
+
element: "venn-classification",
|
|
242
|
+
placements: r,
|
|
243
|
+
completed: !0
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
//#endregion
|
|
247
|
+
export { n as _, m as a, g as c, v as d, i as f, e as g, t as h, u as i, d as l, a as m, y as n, p as o, r as p, _ as r, f as s, s as t, h as u };
|
|
248
|
+
|
|
249
|
+
//# sourceMappingURL=controller-Dt0dg5dA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller-Dt0dg5dA.js","names":[],"sources":["../../src/controller/region.ts","../../src/controller/defaults.ts","../../src/controller/index.ts"],"sourcesContent":["/**\n * Region helpers for the venn-classification controller.\n *\n * A region is a sorted-ascending array of circle indexes. These helpers deal\n * with keying, labelling, and equality in a layout-agnostic way so that both\n * the controller (for scoring / validation) and delivery (for rendering)\n * can share them.\n */\n\nimport type { Region, VennCircle, VennModel } from '../types.js';\n\n/**\n * Returns the canonical region key: sorted-ascending indexes joined by commas.\n * Outside / \"neither\" region is the empty string.\n */\nexport function regionKey(region: Region | null | undefined): string {\n if (!region || region.length === 0) return '';\n return [...region].sort((a, b) => a - b).join(',');\n}\n\n/** Return a fresh sorted-ascending copy of a region. */\nexport function normalizeRegion(region: Region | null | undefined): Region {\n if (!region || region.length === 0) return [];\n return [...region].sort((a, b) => a - b);\n}\n\nexport function regionsEqual(a: Region | null | undefined, b: Region | null | undefined): boolean {\n if (!a || !b) return !a === !b && (a?.length ?? 0) === (b?.length ?? 0);\n if (a.length !== b.length) return false;\n const sa = normalizeRegion(a);\n const sb = normalizeRegion(b);\n for (let i = 0; i < sa.length; i++) {\n if (sa[i] !== sb[i]) return false;\n }\n return true;\n}\n\n/**\n * Enumerate every valid region for a given number of circles.\n * Returns an array of `Region` covering the powerset of `[0..n)`, starting\n * with the outside region (`[]`). Order:\n * 2-set: [], [0], [1], [0,1] (4 regions)\n * 3-set: [], [0], [1], [2], [0,1], [0,2], [1,2], [0,1,2] (8 regions)\n */\nexport function enumerateRegions(circleCount: number): Region[] {\n const regions: Region[] = [];\n const total = 1 << circleCount;\n for (let mask = 0; mask < total; mask++) {\n const r: Region = [];\n for (let i = 0; i < circleCount; i++) {\n if (mask & (1 << i)) r.push(i);\n }\n regions.push(r);\n }\n return regions;\n}\n\n/**\n * Auto-compose the accessible/visible label for a region from the circle labels.\n *\n * 2-set:\n * [] -> \"Neither X nor Y\"\n * [i] -> \"<label(i)> only\"\n * [0,1] -> \"<X> and <Y>\"\n *\n * 3-set (data shape supported; delivery layout ships in v2):\n * [] -> \"None of X, Y, Z\"\n * [i] -> \"<label(i)> only\"\n * [0,1] -> \"<X> and <Y>\"\n * [0,1,2] -> \"<X> and <Y> and <Z>\"\n */\nexport function composeRegionLabel(circles: VennCircle[], region: Region): string {\n const norm = normalizeRegion(region);\n const labels = norm.map((i) => circles[i]?.label ?? `Set ${i + 1}`);\n const circleCount = circles.length;\n\n if (norm.length === 0) {\n if (circleCount === 2) {\n const a = circles[0]?.label ?? 'Set 1';\n const b = circles[1]?.label ?? 'Set 2';\n return `Neither ${a} nor ${b}`;\n }\n const all = circles.map((c, i) => c?.label ?? `Set ${i + 1}`).join(', ');\n return `None of ${all}`;\n }\n\n if (norm.length === 1) {\n return `${labels[0]} only`;\n }\n\n return labels.join(' and ');\n}\n\n/**\n * Resolve the label for a region, preferring an author-supplied override from\n * `model.regionLabels` keyed by region-key, falling back to the auto-composed\n * label.\n */\nexport function getRegionLabel(\n model: Pick<VennModel, 'circles' | 'regionLabels'>,\n region: Region\n): string {\n const key = regionKey(region);\n const override = model.regionLabels?.[key];\n if (typeof override === 'string' && override.trim().length > 0) {\n return override;\n }\n return composeRegionLabel(model.circles ?? [], region);\n}\n","import type { VennModel } from '../types.js';\n\nconst model: VennModel = {\n id: '1',\n element: 'venn-classification',\n prompt: '<p>Sort each tile into the correct region of the Venn diagram.</p>',\n promptEnabled: true,\n circles: [{ label: 'Set A' }, { label: 'Set B' }],\n tiles: [],\n regionLabels: {},\n scoringPolicy: 'partialPerTile',\n};\n\nexport default {\n model,\n configuration: {\n prompt: {\n label: 'Prompt',\n settings: true,\n },\n scoringPolicy: {\n label: 'Scoring policy',\n settings: true,\n },\n },\n};\n","import defaults from './defaults.js';\nimport { normalizeRegion, regionsEqual } from './region.js';\nimport type {\n Region,\n ScoringPolicy,\n VennModel,\n VennSession,\n VennTile,\n VennViewModel,\n} from '../types.js';\n\nexport {\n composeRegionLabel,\n enumerateRegions,\n getRegionLabel,\n normalizeRegion,\n regionKey,\n regionsEqual,\n} from './region.js';\nexport type {\n Region,\n ScoringPolicy,\n VennCircle,\n VennModel,\n VennSession,\n VennTile,\n VennViewModel,\n} from '../types.js';\n\n/**\n * Circle counts that the v1 delivery surface will actually lay out.\n * The data model is N-generic; widening to 3-set delivery is a one-line change\n * plus the 3-set layout/picker once that work ships.\n */\nexport const SUPPORTED_CIRCLE_COUNTS = new Set<number>([2]);\n\nconst isEmptyObject = (value: unknown): boolean =>\n !!value &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n Object.keys(value as Record<string, unknown>).length === 0;\n\nfunction tilePlainLabel(label: unknown): string {\n return String(label ?? '')\n .replace(/<[^>]+>/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nexport function createDefaultModel(model: Partial<VennModel> = {}): VennModel {\n const merged: VennModel = {\n ...(defaults.model as VennModel),\n ...model,\n };\n if (!Array.isArray(merged.circles) || merged.circles.length === 0) {\n merged.circles = (defaults.model as VennModel).circles.map((c) => ({ ...c }));\n }\n if (!Array.isArray(merged.tiles)) {\n merged.tiles = [];\n }\n if (!merged.regionLabels || typeof merged.regionLabels !== 'object') {\n merged.regionLabels = {};\n }\n if (merged.scoringPolicy !== 'allOrNothing' && merged.scoringPolicy !== 'partialPerTile') {\n merged.scoringPolicy = 'partialPerTile';\n }\n return merged;\n}\n\n/**\n * Return a session whose `placements` map has an entry for every authored tile.\n * Unknown placement keys are preserved (so hosts that round-trip extra keys\n * don't lose them), and arrays are normalized to sorted-ascending.\n */\nexport function normalizeSession(\n session: VennSession | null | undefined,\n model?: VennModel\n): VennSession {\n const base: VennSession = { ...(session || {}) };\n const inputPlacements = (session?.placements ?? {}) as Record<string, Region | null>;\n const placements: Record<string, Region | null> = {};\n\n for (const [k, v] of Object.entries(inputPlacements)) {\n if (v === null || v === undefined) {\n placements[k] = null;\n } else if (Array.isArray(v)) {\n placements[k] = normalizeRegion(v);\n } else {\n placements[k] = null;\n }\n }\n\n if (model?.tiles) {\n for (const tile of model.tiles) {\n if (!(tile.id in placements)) {\n placements[tile.id] = null;\n }\n }\n }\n\n base.placements = placements;\n base.completed = isComplete(model, { ...base, placements });\n return base;\n}\n\n/**\n * True iff every authored tile has a non-null placement.\n * Intentionally permissive about unauthored placement keys: they don't\n * contribute to completeness.\n */\nexport function isComplete(\n model: VennModel | null | undefined,\n session: VennSession | null | undefined\n): boolean {\n if (!model || !Array.isArray(model.tiles) || model.tiles.length === 0) return false;\n const placements = session?.placements ?? {};\n for (const tile of model.tiles) {\n const p = placements[tile.id];\n if (p === null || p === undefined) return false;\n }\n return true;\n}\n\nexport type Correctness = 'correct' | 'incorrect' | 'unanswered';\n\n/** Per-tile correctness verdict. */\nexport function getTileCorrectness(\n tile: VennTile,\n placement: Region | null | undefined\n): Correctness {\n if (placement === null || placement === undefined) return 'unanswered';\n return regionsEqual(tile.correctRegion, placement) ? 'correct' : 'incorrect';\n}\n\n/** Map tile id -> correctness, for convenience in delivery `evaluate` mode. */\nexport function getCorrectnessMap(\n model: VennModel,\n session: VennSession | null | undefined\n): Record<string, Correctness> {\n const out: Record<string, Correctness> = {};\n const placements = session?.placements ?? {};\n for (const tile of model.tiles ?? []) {\n out[tile.id] = getTileCorrectness(tile, placements[tile.id] ?? null);\n }\n return out;\n}\n\nexport function outcome(\n question: VennModel | null | undefined,\n session: VennSession | null | undefined,\n env: { mode?: string } = {}\n): Promise<{ score?: number; empty?: boolean; completed?: boolean }> {\n return new Promise((resolve) => {\n if (\n !session ||\n isEmptyObject(session) ||\n !session.placements ||\n Object.keys(session.placements).length === 0\n ) {\n resolve({ score: 0, empty: true });\n return;\n }\n\n if (env.mode !== 'evaluate') {\n resolve({ score: undefined, completed: undefined });\n return;\n }\n\n const model = createDefaultModel((question as VennModel) || undefined);\n const tiles = model.tiles || [];\n if (tiles.length === 0) {\n resolve({ score: 0, empty: true });\n return;\n }\n\n const placements = session.placements || {};\n let correct = 0;\n let answered = 0;\n for (const tile of tiles) {\n const p = placements[tile.id];\n if (p === null || p === undefined) continue;\n answered += 1;\n if (regionsEqual(tile.correctRegion, p)) correct += 1;\n }\n\n if (answered === 0) {\n resolve({ score: 0, empty: true });\n return;\n }\n\n const policy: ScoringPolicy =\n model.scoringPolicy === 'allOrNothing' ? 'allOrNothing' : 'partialPerTile';\n if (policy === 'allOrNothing') {\n resolve({ score: correct === tiles.length ? 1 : 0 });\n return;\n }\n\n resolve({ score: correct / tiles.length });\n });\n}\n\n/**\n * Build the view model consumed by the delivery Svelte component.\n * Strips `correctRegion` from `tiles` unless the host is in `evaluate` mode so\n * authored answers don't leak in `gather`.\n */\nexport function model(\n question: VennModel | null | undefined,\n session: VennSession | null | undefined,\n env: { mode?: string; role?: string; [key: string]: unknown } = {}\n): Promise<VennViewModel> {\n return new Promise((resolve) => {\n const normalizedQuestion = createDefaultModel((question as VennModel) || undefined);\n const safeEnv = env || {};\n\n const out: VennViewModel = {\n prompt:\n normalizedQuestion.promptEnabled === false ? null : (normalizedQuestion.prompt ?? null),\n circles: normalizedQuestion.circles.map((c) => ({ label: c?.label ?? '' })),\n tiles: normalizedQuestion.tiles.map((t) => {\n const imageUrl = String(t.imageUrl ?? '').trim();\n const imageFields =\n imageUrl.length > 0 ? { imageUrl, imageAlt: String(t.imageAlt ?? '').trim() } : {};\n return {\n id: t.id,\n label: t.label ?? '',\n ...imageFields,\n ...(safeEnv.mode === 'evaluate'\n ? { correctRegion: normalizeRegion(t.correctRegion) }\n : {}),\n };\n }),\n regionLabels: { ...(normalizedQuestion.regionLabels || {}) },\n scoringPolicy: normalizedQuestion.scoringPolicy ?? 'partialPerTile',\n disabled: safeEnv.mode !== 'gather',\n mode: safeEnv.mode,\n env: safeEnv,\n };\n\n if (safeEnv.mode === 'evaluate') {\n const correctRegionsById: Record<string, Region> = {};\n for (const tile of normalizedQuestion.tiles) {\n correctRegionsById[tile.id] = normalizeRegion(tile.correctRegion);\n }\n out.correctRegionsById = correctRegionsById;\n out.correctness = getCorrectnessMap(normalizedQuestion, session);\n }\n\n const isInstructor = safeEnv.role === 'instructor';\n if (isInstructor && (safeEnv.mode === 'view' || safeEnv.mode === 'evaluate')) {\n const anyQ = normalizedQuestion as unknown as {\n teacherInstructionsEnabled?: boolean;\n teacherInstructions?: string;\n };\n out.teacherInstructions = anyQ.teacherInstructionsEnabled\n ? (anyQ.teacherInstructions ?? null)\n : null;\n } else {\n out.teacherInstructions = null;\n }\n\n resolve(out);\n });\n}\n\nexport function createCorrectResponseSession(\n question: VennModel | null | undefined,\n env: { mode?: string; role?: string } = {}\n): Promise<VennSession | null> {\n return new Promise((resolve) => {\n if (env.mode === 'evaluate' || env.role !== 'instructor') {\n resolve(null);\n return;\n }\n const model = createDefaultModel((question as VennModel) || undefined);\n const placements: Record<string, Region> = {};\n for (const tile of model.tiles) {\n placements[tile.id] = normalizeRegion(tile.correctRegion);\n }\n resolve({\n id: '1',\n element: 'venn-classification',\n placements,\n completed: true,\n });\n });\n}\n\n/**\n * Shallow model validation for authoring surfaces. Returns a map of\n * `{field: message}`; an empty map means \"valid enough to save\".\n */\nexport function validate(\n model: VennModel | null | undefined,\n _config: unknown = {}\n): Record<string, string> {\n const errors: Record<string, string> = {};\n const m = (model || {}) as VennModel;\n\n if (m.promptEnabled) {\n const p = (m.prompt ?? '').trim();\n if (!p || p === '<p></p>') {\n errors.prompt = 'Prompt is required when prompt is enabled';\n }\n }\n\n const circles = Array.isArray(m.circles) ? m.circles : [];\n if (!SUPPORTED_CIRCLE_COUNTS.has(circles.length)) {\n const supported = [...SUPPORTED_CIRCLE_COUNTS].sort((a, b) => a - b).join(' or ');\n errors.circles = `Venn classification currently supports ${supported} circles (got ${circles.length})`;\n } else {\n for (let i = 0; i < circles.length; i++) {\n const label = (circles[i]?.label ?? '').trim();\n if (!label) {\n errors.circles = `Circle ${i + 1} needs a label`;\n break;\n }\n }\n }\n\n const tiles = Array.isArray(m.tiles) ? m.tiles : [];\n if (tiles.length < 1) {\n errors.tiles = 'At least one tile is required';\n } else {\n const seen = new Set<string>();\n for (let i = 0; i < tiles.length; i++) {\n const tile = tiles[i];\n if (!tile?.id) {\n errors.tiles = `Tile ${i + 1} is missing an id`;\n break;\n }\n if (seen.has(tile.id)) {\n errors.tiles = `Tile id \"${tile.id}\" appears more than once`;\n break;\n }\n seen.add(tile.id);\n\n const labelPlain = tilePlainLabel(tile.label);\n const imageUrl = String(tile.imageUrl ?? '').trim();\n const imageAlt = String(tile.imageAlt ?? '').trim();\n if (!labelPlain && !imageUrl) {\n errors.tiles = `Tile \"${tile.id}\" needs a label or an image URL`;\n break;\n }\n if (imageUrl && !imageAlt) {\n errors.tiles = `Tile \"${tile.id}\": when an image URL is set, short alt text is required for accessibility`;\n break;\n }\n\n const region = tile.correctRegion;\n if (!Array.isArray(region)) {\n errors.tiles = `Tile \"${tile.id}\" is missing correctRegion`;\n break;\n }\n\n const sorted = normalizeRegion(region);\n // Must be sorted ascending by convention, with unique in-range indexes.\n const unique = new Set(sorted);\n if (unique.size !== sorted.length) {\n errors.tiles = `Tile \"${tile.id}\" correctRegion has duplicate indexes`;\n break;\n }\n const outOfRange = sorted.find(\n (idx) => !Number.isInteger(idx) || idx < 0 || idx >= circles.length\n );\n if (outOfRange !== undefined) {\n errors.tiles = `Tile \"${tile.id}\" correctRegion index ${outOfRange} is out of range for ${circles.length} circles`;\n break;\n }\n }\n }\n\n if (\n m.scoringPolicy !== undefined &&\n m.scoringPolicy !== 'allOrNothing' &&\n m.scoringPolicy !== 'partialPerTile'\n ) {\n errors.scoringPolicy = 'Scoring policy must be \"allOrNothing\" or \"partialPerTile\"';\n }\n\n return errors;\n}\n\n/**\n * Helper for authoring-time previews: build a session that places each tile in\n * its authored correct region. Used by the authoring live preview so authors\n * see the intended final state of the diagram.\n */\nexport function buildPreviewSession(model: VennModel | null | undefined): VennSession {\n const m = createDefaultModel(model || undefined);\n const placements: Record<string, Region> = {};\n for (const tile of m.tiles) {\n placements[tile.id] = normalizeRegion(tile.correctRegion);\n }\n return {\n id: 'preview',\n element: 'venn-classification',\n placements,\n completed: true,\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { i as e, r as t, t as n } from "../VennClassification-DtwuotJl.js";
|
|
2
|
+
import { s as r } from "../controller-Dt0dg5dA.js";
|
|
3
|
+
//#region src/delivery/index.ts
|
|
4
|
+
var i = n.element, a = class extends i {
|
|
5
|
+
_internalSession = null;
|
|
6
|
+
_model = null;
|
|
7
|
+
_isComplete = () => r(this._model, this._internalSession);
|
|
8
|
+
_dispatchModelSet = () => {
|
|
9
|
+
this.dispatchEvent(new t(this.tagName.toLowerCase(), this._isComplete(), this._model !== void 0));
|
|
10
|
+
};
|
|
11
|
+
_dispatchSessionChanged = () => {
|
|
12
|
+
this.dispatchEvent(new e(this.tagName.toLowerCase(), this._isComplete()));
|
|
13
|
+
};
|
|
14
|
+
set model(e) {
|
|
15
|
+
this._model = e, super.model = e, this._dispatchModelSet();
|
|
16
|
+
}
|
|
17
|
+
get model() {
|
|
18
|
+
return this._model;
|
|
19
|
+
}
|
|
20
|
+
set session(e) {
|
|
21
|
+
e !== this._internalSession && (this._internalSession = e, super.session = e, this._dispatchSessionChanged());
|
|
22
|
+
}
|
|
23
|
+
get session() {
|
|
24
|
+
return this._internalSession;
|
|
25
|
+
}
|
|
26
|
+
onSessionChange = (e) => {
|
|
27
|
+
this._internalSession = e, super.session = e, this._dispatchSessionChanged();
|
|
28
|
+
};
|
|
29
|
+
connectedCallback() {
|
|
30
|
+
super.connectedCallback(), this.onSessionChange = this.onSessionChange;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
//#endregion
|
|
34
|
+
export { a as default };
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/delivery/index.ts"],"sourcesContent":["import VennClassificationComponent from './VennClassification.svelte';\nimport { isComplete as isControllerComplete } from '../controller/index.js';\nimport { ModelSetEvent, SessionChangedEvent } from '@pie-lib/delivery-events-svelte';\n\nconst SvelteElementClass = (VennClassificationComponent as any).element;\n\nclass VennClassificationElement extends SvelteElementClass {\n _internalSession: any = null;\n _model: any = null;\n\n _isComplete = () => {\n return isControllerComplete(this._model, this._internalSession);\n };\n\n _dispatchModelSet = () => {\n this.dispatchEvent(\n new ModelSetEvent(this.tagName.toLowerCase(), this._isComplete(), this._model !== undefined)\n );\n };\n\n _dispatchSessionChanged = () => {\n this.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), this._isComplete()));\n };\n\n set model(m: any) {\n this._model = m;\n super.model = m;\n this._dispatchModelSet();\n }\n\n get model() {\n return this._model;\n }\n\n set session(s: any) {\n // Avoid redundant reactive loops: if the incoming session is structurally\n // identical to the last one we saw, skip the update.\n if (s === this._internalSession) return;\n this._internalSession = s;\n super.session = s;\n this._dispatchSessionChanged();\n }\n\n get session() {\n return this._internalSession;\n }\n\n onSessionChange = (updatedSession: any) => {\n this._internalSession = updatedSession;\n super.session = updatedSession;\n this._dispatchSessionChanged();\n };\n\n connectedCallback() {\n super.connectedCallback();\n (this as any).onSessionChange = this.onSessionChange;\n }\n}\n\nexport default VennClassificationElement;\n"],"mappings":";;;AAIA,IAAM,IAAsB,EAAoC,SAE1D,IAAN,cAAwC,EAAmB;CACzD,mBAAwB;CACxB,SAAc;CAEd,oBACS,EAAqB,KAAK,QAAQ,KAAK,gBAAgB;CAGhE,0BAA0B;EACxB,KAAK,cACH,IAAI,EAAc,KAAK,QAAQ,YAAY,GAAG,KAAK,YAAY,GAAG,KAAK,WAAW,KAAA,CAAS,CAC7F;CACF;CAEA,gCAAgC;EAC9B,KAAK,cAAc,IAAI,EAAoB,KAAK,QAAQ,YAAY,GAAG,KAAK,YAAY,CAAC,CAAC;CAC5F;CAEA,IAAI,MAAM,GAAQ;EAGhB,AAFA,KAAK,SAAS,GACd,MAAM,QAAQ,GACd,KAAK,kBAAkB;CACzB;CAEA,IAAI,QAAQ;EACV,OAAO,KAAK;CACd;CAEA,IAAI,QAAQ,GAAQ;EAGd,MAAM,KAAK,qBACf,KAAK,mBAAmB,GACxB,MAAM,UAAU,GAChB,KAAK,wBAAwB;CAC/B;CAEA,IAAI,UAAU;EACZ,OAAO,KAAK;CACd;CAEA,mBAAmB,MAAwB;EAGzC,AAFA,KAAK,mBAAmB,GACxB,MAAM,UAAU,GAChB,KAAK,wBAAwB;CAC/B;CAEA,oBAAoB;EAElB,AADA,MAAM,kBAAkB,GACxB,KAAc,kBAAkB,KAAK;CACvC;AACF"}
|
package/dist/delivery/index.js
CHANGED
|
@@ -5345,7 +5345,7 @@ function r$1({ sourceEl: t, fallbackSelector: r, component: i, complete: a, sess
|
|
|
5345
5345
|
//#region ../../shared/math-rendering-mathjax/dist/index.js
|
|
5346
5346
|
var e = "https://cdn.jsdelivr.net/npm/mathjax@4/tex-chtml.js", t = null;
|
|
5347
5347
|
function n(n) {
|
|
5348
|
-
return typeof window > "u" || window.MathJax?.
|
|
5348
|
+
return typeof window > "u" || window.MathJax?.typesetPromise ? Promise.resolve() : t || (t = new Promise((t, r) => {
|
|
5349
5349
|
let { useSingleDollar: i = !1, accessibility: a = !0, loadFonts: o = !0, srcUrl: s } = n, c = {
|
|
5350
5350
|
loader: { load: a ? ["a11y/assistive-mml"] : [] },
|
|
5351
5351
|
tex: {
|
|
@@ -5399,17 +5399,24 @@ function i(e = {}) {
|
|
|
5399
5399
|
await window.MathJax.typesetPromise([t]), r();
|
|
5400
5400
|
};
|
|
5401
5401
|
}
|
|
5402
|
-
var o = null;
|
|
5403
|
-
function
|
|
5404
|
-
return
|
|
5402
|
+
var o = "@pie-lib/math-rendering", s = null;
|
|
5403
|
+
function c() {
|
|
5404
|
+
return s || (s = i({
|
|
5405
5405
|
accessibility: !0,
|
|
5406
5406
|
useSingleDollar: !0
|
|
5407
|
-
})),
|
|
5407
|
+
})), s;
|
|
5408
5408
|
}
|
|
5409
|
-
|
|
5409
|
+
function l() {
|
|
5410
|
+
if (typeof window > "u") return null;
|
|
5411
|
+
let e = window[o];
|
|
5412
|
+
return typeof e?.renderMath == "function" ? e : null;
|
|
5413
|
+
}
|
|
5414
|
+
var u = async (e) => {
|
|
5410
5415
|
if (typeof window > "u") return;
|
|
5411
5416
|
let t = typeof e == "string", n;
|
|
5412
|
-
|
|
5417
|
+
t ? (n = document.createElement("div"), n.innerHTML = e) : n = e || document.body;
|
|
5418
|
+
let r = l();
|
|
5419
|
+
return r ? await r.renderMath?.(n) : await c()(n), t ? n.innerHTML : void 0;
|
|
5413
5420
|
};
|
|
5414
5421
|
//#endregion
|
|
5415
5422
|
//#region src/delivery/tile-accessible-name.ts
|
|
@@ -6275,7 +6282,7 @@ function VennClassification($$anchor, $$props) {
|
|
|
6275
6282
|
function typeset() {
|
|
6276
6283
|
if (!containerEl) return;
|
|
6277
6284
|
try {
|
|
6278
|
-
|
|
6285
|
+
u(containerEl);
|
|
6279
6286
|
} catch (err) {
|
|
6280
6287
|
console.warn("venn-classification: MathJax render failed", err);
|
|
6281
6288
|
}
|