hyperbook 0.113.0 → 0.113.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.
Files changed (56) hide show
  1. package/README.md +18 -3
  2. package/dist/asset-manifest.json +9 -9
  3. package/dist/assets/directive-bitflow/{EditorElement-zyz99U6n.js → EditorElement-CE3Yr86b.js} +155 -155
  4. package/dist/assets/directive-bitflow/{ReportElements-BnX14NtV.js → ReportElements-eYGRtw6N.js} +1 -1
  5. package/dist/assets/directive-bitflow/{bitLoaders-DIGwTcpd.js → bitLoaders-CxvZkGrY.js} +1138 -1073
  6. package/dist/assets/directive-bitflow/editor.js +3 -3
  7. package/dist/assets/directive-bitflow/flow.js +3 -3
  8. package/dist/assets/directive-bitflow/{index-IQHOi2fr.js → index-88c3K20U.js} +31 -31
  9. package/dist/assets/directive-bitflow/{index-Bqf-kixT.js → index-B61LKxr1.js} +45 -45
  10. package/dist/assets/directive-bitflow/{index-CFcRAa3F.js → index-BG0PL-Z6.js} +30 -30
  11. package/dist/assets/directive-bitflow/{index-B3jMTk1o.js → index-BNdpL6Ss.js} +78 -78
  12. package/dist/assets/directive-bitflow/{index-Fq7njn6_.js → index-BO-d4HVC.js} +48 -48
  13. package/dist/assets/directive-bitflow/{index-Bf_NXJjq.js → index-BZhNY0lo.js} +12 -12
  14. package/dist/assets/directive-bitflow/{index-COndsSPW.js → index-BadyFTU5.js} +8 -8
  15. package/dist/assets/directive-bitflow/{index-CvCZVgKv.js → index-BlT1EcFH.js} +34 -34
  16. package/dist/assets/directive-bitflow/{index-CW9iev-_.js → index-BuQ-K_tR.js} +7 -7
  17. package/dist/assets/directive-bitflow/{index-DjWNEPDL.js → index-Bw0pL0hW.js} +28 -28
  18. package/dist/assets/directive-bitflow/{index-BQ5h4nDN.js → index-BwBVUdJ9.js} +94 -94
  19. package/dist/assets/directive-bitflow/{index-CjscG0z6.js → index-BydYlLy4.js} +73 -73
  20. package/dist/assets/directive-bitflow/{index-BpG316Ls.js → index-C7RJxxAx.js} +63 -63
  21. package/dist/assets/directive-bitflow/{index-eN2S_MLj.js → index-CERSJ9uS.js} +70 -70
  22. package/dist/assets/directive-bitflow/{index-DtsDy2By.js → index-CLHtOGrW.js} +11 -11
  23. package/dist/assets/directive-bitflow/{index-Bf_FQRbK.js → index-CWe2GjBK.js} +14 -14
  24. package/dist/assets/directive-bitflow/{index-CzdZQibq.js → index-CfKpkSVC.js} +72 -72
  25. package/dist/assets/directive-bitflow/{index-Fr7yl4Vn.js → index-CjKhq7gY.js} +23 -23
  26. package/dist/assets/directive-bitflow/{index-DoKlIgCD.js → index-Cm4w1Zyc.js} +38 -38
  27. package/dist/assets/directive-bitflow/{index-D5yZNeIg.js → index-D0U3nepG.js} +52 -52
  28. package/dist/assets/directive-bitflow/{index-C5czXkRd.js → index-D4PdXMcj.js} +33 -33
  29. package/dist/assets/directive-bitflow/{index-BLcJNyog.js → index-D9LOuqr2.js} +99 -99
  30. package/dist/assets/directive-bitflow/{index-BIJ7VfD2.js → index-DIb3CXwC.js} +42 -42
  31. package/dist/assets/directive-bitflow/{index-CZyaFdD2.js → index-DQP0cUsP.js} +70 -70
  32. package/dist/assets/directive-bitflow/{index-ChgzyMHe.js → index-DUOrQfVe.js} +27 -27
  33. package/dist/assets/directive-bitflow/{index-kRpwcprB.js → index-DW3cUBvZ.js} +1 -1
  34. package/dist/assets/directive-bitflow/{index-C_ZTSeqv.js → index-DYWo0PUv.js} +24 -24
  35. package/dist/assets/directive-bitflow/{index-xapm2BQE.js → index-D_QhyFcx.js} +101 -91
  36. package/dist/assets/directive-bitflow/{index-BdBBCZSy.js → index-Dn5hHVuT.js} +226 -193
  37. package/dist/assets/directive-bitflow/{index-D7m-hJZ9.js → index-DruC5d43.js} +69 -69
  38. package/dist/assets/directive-bitflow/{index-e_8twLaN.js → index-EKIgFddO.js} +105 -105
  39. package/dist/assets/directive-bitflow/{index-8jTO-NJA.js → index-HXNGIC7K.js} +70 -70
  40. package/dist/assets/directive-bitflow/{index-DnVYIuen.js → index-ISbOe239.js} +42 -42
  41. package/dist/assets/directive-bitflow/{index-cnRM_JDB.js → index-IsMJtrUT.js} +31 -31
  42. package/dist/assets/directive-bitflow/{index-B7Z6Q-PQ.js → index-TUXuIR22.js} +6 -6
  43. package/dist/assets/directive-bitflow/{index-CK1UMcfT.js → index-WbE9UOFa.js} +24 -24
  44. package/dist/assets/directive-bitflow/{index-YPMWh-1B.js → index-d5ebPDeY.js} +13 -13
  45. package/dist/assets/directive-bitflow/{index-NyNuXp4C.js → index-ledofrbo.js} +33 -33
  46. package/dist/assets/directive-bitflow/{index-BseSaQlX.js → index-oNmOArKu.js} +1 -1
  47. package/dist/assets/directive-bitflow/{index-ivI25bnR.js → index-rp4UTV85.js} +84 -84
  48. package/dist/assets/directive-bitflow/{index-XxGfBwJe.js → index-xTX3CXJW.js} +23 -23
  49. package/dist/assets/directive-bitflow/index.js +6 -6
  50. package/dist/assets/directive-bitflow/katex-DSLAjWZH-CHGN3Pr6.js +11314 -0
  51. package/dist/assets/directive-bitflow/katex-Dv-tcU2S-Dv-tcU2S.js +4 -0
  52. package/dist/assets/directive-bitflow/report.js +1 -1
  53. package/dist/assets/directive-bitflow/{shareableReport-ArQU1XjG.js → shareableReport-vjEU4OvA.js} +2 -2
  54. package/dist/index.js +6351 -3340
  55. package/dist/schemas/hyperbook.schema.json +4 -4
  56. package/package.json +5 -5
@@ -1,6 +1,6 @@
1
- import { L as K, a4 as j, ac as pe, ad as re, a9 as E, a2 as N, P as J, a as v, j as r, b as $, aa as he, s as fe } from "./dom-uYx_3K1r.js";
2
- import { v as Q, e as ee, _ as te, A as W, M as G, P as we, E as ge, s as me, L as xe, t as ve, R as Ce } from "./bitLoaders-DIGwTcpd.js";
3
- const ye = K({
1
+ import { L as K, a4 as j, ac as fe, ad as ae, a9 as R, ao as we, a6 as J, a2 as N, P as Q, a as v, j as r, b as E, aa as me, s as ge } from "./dom-uYx_3K1r.js";
2
+ import { e as ee, P as te, i as le, g as W, F as G, M as re, B as xe, y as ve, U as Ce, r as ye, H as ke } from "./bitLoaders-CxvZkGrY.js";
3
+ const Le = K({
4
4
  /** Stable across edits, so a target or a startColor keeps pointing at the
5
5
  * same colour even after the author renames it or moves it in the list. */
6
6
  id: N().min(1),
@@ -12,11 +12,11 @@ const ye = K({
12
12
  }), P = [
13
13
  { id: "white", color: "#ffffff", label: "0" },
14
14
  { id: "black", color: "#000000", label: "1" }
15
- ], ke = K({
15
+ ], je = K({
16
16
  instruction: N().default(""),
17
- rows: J().int().min(1).max(32).default(5),
18
- columns: J().int().min(1).max(32).default(5),
19
- palette: j(ye).min(1).default(() => P.map((e) => ({ ...e }))),
17
+ rows: Q().int().min(1).max(32).default(5),
18
+ columns: Q().int().min(1).max(32).default(5),
19
+ palette: j(Le).min(1).default(() => P.map((e) => ({ ...e }))),
20
20
  /** The picture the learner must match, as palette ids, rows by columns. */
21
21
  target: j(j(N())).default([]),
22
22
  /**
@@ -24,26 +24,33 @@ const ye = K({
24
24
  * nothing is locked — kept as "no array" rather than "an array of every
25
25
  * cell false" so an untouched task costs nothing to store.
26
26
  */
27
- given: j(j(E())).default([]),
27
+ given: j(j(R())).default([]),
28
28
  /** The palette id every free cell starts as, before the learner paints
29
29
  * anything. */
30
30
  startColor: N().default(() => P[0].id),
31
31
  /** Row and column numbers along the edges. */
32
- showCoordinates: E().default(!0),
32
+ showCoordinates: R().default(!0),
33
+ /**
34
+ * The number the first row and column are called by, along the edges and
35
+ * in each cell's accessible name. 1 is how a picture is counted; 0 is how
36
+ * a program indexes it, so a grid beside `bild[zeile][spalte]` or
37
+ * `grid[row][col]` names its cells the way the code does.
38
+ */
39
+ firstIndex: we([J(0), J(1)]).default(1),
33
40
  /** Each palette entry's label drawn inside its cells — useful for a PBM
34
41
  * grid of 0s and 1s, where the colour alone is easy to misread. */
35
- showLabels: E().default(!1),
36
- partialCredit: E().default(!0),
37
- evaluation: pe.default(re)
42
+ showLabels: R().default(!1),
43
+ partialCredit: R().default(!0),
44
+ evaluation: fe.default(ae)
38
45
  }).check((e) => {
39
- const { palette: i, rows: d, columns: o, target: t, given: n, startColor: c } = e.value, f = i.map((h) => h.id);
46
+ const { palette: a, rows: d, columns: o, target: t, given: n, startColor: c } = e.value, f = a.map((p) => p.id);
40
47
  if (new Set(f).size !== f.length && e.issues.push({
41
48
  code: "custom",
42
- input: i,
49
+ input: a,
43
50
  path: ["palette"],
44
51
  message: "Each colour needs its own id."
45
52
  }), e.value.evaluation.mode === "auto") {
46
- if (t.length !== d || t.some((h) => h.length !== o)) {
53
+ if (t.length !== d || t.some((p) => p.length !== o)) {
47
54
  e.issues.push({
48
55
  code: "custom",
49
56
  input: t,
@@ -52,12 +59,12 @@ const ye = K({
52
59
  });
53
60
  return;
54
61
  }
55
- t.some((h) => h.some((C) => !f.includes(C))) && e.issues.push({
62
+ t.some((p) => p.some((C) => !f.includes(C))) && e.issues.push({
56
63
  code: "custom",
57
64
  input: t,
58
65
  path: ["target"],
59
66
  message: "The picture uses a colour that is not in the palette."
60
- }), n.length > 0 && (n.length !== d || n.some((h) => h.length !== o)) && e.issues.push({
67
+ }), n.length > 0 && (n.length !== d || n.some((p) => p.length !== o)) && e.issues.push({
61
68
  code: "custom",
62
69
  input: n,
63
70
  path: ["given"],
@@ -74,45 +81,45 @@ const ye = K({
74
81
  * from a smaller grid the author has since resized is padded back out by
75
82
  * `effectiveCells` at read time instead of being rewritten. */
76
83
  cells: j(j(N())).default([])
77
- }), U = (e, i, d) => e.given[i]?.[d] === !0, le = (e, i) => e.palette.find((d) => d.id === i), Le = (e, i) => Array.from(
84
+ }), V = (e, a, d) => e.given[a]?.[d] === !0, ie = (e, a) => e.palette.find((d) => d.id === a), Ne = (e, a) => Array.from(
78
85
  { length: e.rows },
79
86
  (d, o) => Array.from(
80
87
  { length: e.columns },
81
- (t, n) => U(e, o, n) ? e.target[o]?.[n] ?? e.startColor : i?.[o]?.[n] ?? e.startColor
88
+ (t, n) => V(e, o, n) ? e.target[o]?.[n] ?? e.startColor : a?.[o]?.[n] ?? e.startColor
82
89
  )
83
- ), je = (e) => Array.from(
90
+ ), Pe = (e) => Array.from(
84
91
  { length: e.rows },
85
92
  () => Array.from({ length: e.columns }, () => e.startColor)
86
- ), Ne = (e, i, d, o) => {
93
+ ), ze = (e, a, d, o) => {
87
94
  const t = e.map((n) => [...n]);
88
- return t[i] = [...t[i] ?? []], t[i][d] = o, t;
89
- }, H = (e, i, d, o) => Array.from(
90
- { length: i },
95
+ return t[a] = [...t[a] ?? []], t[a][d] = o, t;
96
+ }, A = (e, a, d, o) => Array.from(
97
+ { length: a },
91
98
  (t, n) => Array.from({ length: d }, (c, f) => e[n]?.[f] ?? o)
92
- ), Pe = (e) => {
93
- const i = e.replace("#", ""), d = parseInt(i.slice(0, 2), 16), o = parseInt(i.slice(2, 4), 16), t = parseInt(i.slice(4, 6), 16);
99
+ ), He = (e) => {
100
+ const a = e.replace("#", ""), d = parseInt(a.slice(0, 2), 16), o = parseInt(a.slice(2, 4), 16), t = parseInt(a.slice(4, 6), 16);
94
101
  return (0.299 * d + 0.587 * o + 0.114 * t) / 255 > 0.6 ? "#000000" : "#ffffff";
95
- }, ae = (e, i) => Array.from(
102
+ }, oe = (e, a) => Array.from(
96
103
  { length: e.rows },
97
104
  (d, o) => Array.from({ length: e.columns }, (t, n) => {
98
- if (U(e, o, n)) return !1;
99
- const c = i?.cells?.[o]?.[n] ?? e.startColor, f = e.target[o]?.[n] ?? e.startColor;
105
+ if (V(e, o, n)) return !1;
106
+ const c = a?.cells?.[o]?.[n] ?? e.startColor, f = e.target[o]?.[n] ?? e.startColor;
100
107
  return c !== f;
101
108
  })
102
- ), Ae = (e, i) => {
103
- const d = ae(e, i);
109
+ ), Ae = (e, a) => {
110
+ const d = oe(e, a);
104
111
  let o = 0, t = 0;
105
112
  for (let n = 0; n < e.rows; n++)
106
113
  for (let c = 0; c < e.columns; c++)
107
- U(e, n, c) || (t += 1, d[n][c] || (o += 1));
114
+ V(e, n, c) || (t += 1, d[n][c] || (o += 1));
108
115
  return e.partialCredit ? { earned: o, possible: t } : { earned: t > 0 && o === t ? 1 : 0, possible: t > 0 ? 1 : 0 };
109
- }, ze = ({
116
+ }, Be = ({
110
117
  data: e,
111
- answer: i
118
+ answer: a
112
119
  }) => {
113
120
  if (e.evaluation.mode === "skip")
114
121
  return { state: "unknown", allowRetry: !1 };
115
- const d = Ae(e, i);
122
+ const d = Ae(e, a);
116
123
  return {
117
124
  state: d.possible > 0 && d.earned === d.possible ? "correct" : "wrong",
118
125
  score: d,
@@ -121,10 +128,10 @@ const ye = K({
121
128
  // So the learner's own grid can mark the cells it got wrong once
122
129
  // checked, without recomputing the comparison from a raw answer the
123
130
  // Task component would otherwise have no reason to hold onto.
124
- wrong: ae(e, i)
131
+ wrong: oe(e, a)
125
132
  }
126
133
  };
127
- }, _ = {
134
+ }, U = {
128
135
  en: {
129
136
  name: "Pixel grid",
130
137
  description: "A grid the learner paints from a palette, marked cell by cell against the picture.",
@@ -153,7 +160,7 @@ const ye = K({
153
160
  colorFallback: "Farbe {number}",
154
161
  clear: "Leeren"
155
162
  }
156
- }, He = '.bitflow-pixelgrid-palette{display:flex;flex-wrap:wrap;gap:var(--bitflow-space-xxsmall)}.bitflow-pixelgrid-swatch{display:inline-flex;align-items:center;gap:var(--bitflow-space-xxsmall);padding:var(--bitflow-space-xxsmall) var(--bitflow-space-xsmall);min-height:44px;border:var(--bitflow-border-width) solid var(--bitflow-color-border);border-radius:var(--bitflow-radius-standard);cursor:pointer;font-size:var(--bitflow-font-size-small)}.bitflow-pixelgrid-swatch:has(:checked){border-color:var(--bitflow-color-primary);border-width:calc(var(--bitflow-border-width) * 1.5)}.bitflow-pixelgrid-swatch:has(:focus-visible){box-shadow:var(--bitflow-shadow-outline)}.bitflow-pixelgrid-swatch-fill{width:1.5rem;height:1.5rem;border-radius:var(--bitflow-radius-small);border:1px solid var(--bitflow-color-border);flex:none}.bitflow-pixelgrid-table{display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto auto;width:min(100%,calc(var(--bitflow-pixelgrid-columns, 5) * 3rem))}.bitflow-pixelgrid-table:not(.bitflow-pixelgrid-coords){grid-template-columns:1fr;grid-template-rows:1fr}.bitflow-pixelgrid-corner{grid-column:1;grid-row:1}.bitflow-pixelgrid-colheads{grid-column:2;grid-row:1;display:flex}.bitflow-pixelgrid-colheads span{flex:1 1 0;min-width:0;text-align:center}.bitflow-pixelgrid-rowheads{grid-column:1;grid-row:2;display:flex;flex-direction:column}.bitflow-pixelgrid-rowheads span{flex:1 1 0;min-height:0;display:flex;align-items:center}.bitflow-pixelgrid-corner,.bitflow-pixelgrid-colheads span,.bitflow-pixelgrid-rowheads span{font-size:11px;font-variant-numeric:tabular-nums;color:var(--bitflow-color-text-muted);padding-inline:2px;-webkit-user-select:none;user-select:none}.bitflow-pixelgrid-grid{grid-column:2;grid-row:2;display:flex;flex-direction:column;border:var(--bitflow-border-width) solid var(--bitflow-color-border);border-radius:var(--bitflow-radius-standard);overflow:hidden;touch-action:none;cursor:crosshair}.bitflow-pixelgrid-table:not(.bitflow-pixelgrid-coords) .bitflow-pixelgrid-grid{grid-column:1;grid-row:1}.bitflow-pixelgrid-grid:focus-visible{outline:none;box-shadow:var(--bitflow-shadow-outline)}.bitflow-pixelgrid-row{display:flex}.bitflow-pixelgrid-cell{position:relative;display:flex;align-items:center;justify-content:center;flex:1 1 0;min-width:0;aspect-ratio:1;container-type:inline-size;outline:1px solid var(--bitflow-color-border);outline-offset:-1px}.bitflow-pixelgrid-label{font-family:var(--bitflow-font-family-mono);font-size:55cqw;line-height:1}.bitflow-pixelgrid-cell-cursor{box-shadow:inset 0 0 0 2px var(--bitflow-color-primary);z-index:1}.bitflow-pixelgrid-cell-given{box-shadow:inset 0 0 0 2px #fff,inset 0 0 0 4px #000}.bitflow-pixelgrid-cell-cursor.bitflow-pixelgrid-cell-given{box-shadow:inset 0 0 0 2px var(--bitflow-color-primary),inset 0 0 0 4px #fff,inset 0 0 0 6px #000}.bitflow-pixelgrid-cell-wrong:after{content:"";position:absolute;inset:0;background-image:repeating-linear-gradient(45deg,rgba(0,0,0,.45) 0 3px,transparent 3px 9px),repeating-linear-gradient(45deg,rgba(255,255,255,.45) 4.5px 7.5px,transparent 7.5px 9px)}.bitflow-pixelgrid-palette-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--bitflow-space-xsmall)}.bitflow-pixelgrid-color-input{flex:none;width:2.5rem;height:44px;padding:2px;border:var(--bitflow-border-width) solid var(--bitflow-color-border);border-radius:var(--bitflow-radius-standard);background:var(--bitflow-color-surface)}.bitflow-pixelgrid-palette-row>.bitflow-input{flex:1 1 10rem;min-width:0}.bitflow-pixelgrid-size{width:var(--bitflow-pixelgrid-size-width, 6rem)}', Be = {
163
+ }, Me = '.bitflow-pixelgrid-palette{display:flex;flex-wrap:wrap;gap:var(--bitflow-space-xxsmall)}.bitflow-pixelgrid-swatch{display:inline-flex;align-items:center;gap:var(--bitflow-space-xxsmall);padding:var(--bitflow-space-xxsmall) var(--bitflow-space-xsmall);min-height:44px;border:var(--bitflow-border-width) solid var(--bitflow-color-border);border-radius:var(--bitflow-radius-standard);cursor:pointer;font-size:var(--bitflow-font-size-small)}.bitflow-pixelgrid-swatch:has(:checked){border-color:var(--bitflow-color-primary);border-width:calc(var(--bitflow-border-width) * 1.5)}.bitflow-pixelgrid-swatch:has(:focus-visible){box-shadow:var(--bitflow-shadow-outline)}.bitflow-pixelgrid-swatch-fill{width:1.5rem;height:1.5rem;border-radius:var(--bitflow-radius-small);border:1px solid var(--bitflow-color-border);flex:none}.bitflow-pixelgrid-table{display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto auto;width:min(100%,calc(var(--bitflow-pixelgrid-columns, 5) * 3rem))}.bitflow-pixelgrid-table:not(.bitflow-pixelgrid-coords){grid-template-columns:1fr;grid-template-rows:1fr}.bitflow-pixelgrid-corner{grid-column:1;grid-row:1}.bitflow-pixelgrid-colheads{grid-column:2;grid-row:1;display:flex}.bitflow-pixelgrid-colheads span{flex:1 1 0;min-width:0;text-align:center}.bitflow-pixelgrid-rowheads{grid-column:1;grid-row:2;display:flex;flex-direction:column}.bitflow-pixelgrid-rowheads span{flex:1 1 0;min-height:0;display:flex;align-items:center}.bitflow-pixelgrid-corner,.bitflow-pixelgrid-colheads span,.bitflow-pixelgrid-rowheads span{font-size:11px;font-variant-numeric:tabular-nums;color:var(--bitflow-color-text-muted);padding-inline:2px;-webkit-user-select:none;user-select:none}.bitflow-pixelgrid-grid{grid-column:2;grid-row:2;display:flex;flex-direction:column;border:var(--bitflow-border-width) solid var(--bitflow-color-border);border-radius:var(--bitflow-radius-standard);overflow:hidden;touch-action:none;cursor:crosshair}.bitflow-pixelgrid-table:not(.bitflow-pixelgrid-coords) .bitflow-pixelgrid-grid{grid-column:1;grid-row:1}.bitflow-pixelgrid-grid:focus-visible{outline:none;box-shadow:var(--bitflow-shadow-outline)}.bitflow-pixelgrid-row{display:flex}.bitflow-pixelgrid-cell{position:relative;display:flex;align-items:center;justify-content:center;flex:1 1 0;min-width:0;aspect-ratio:1;container-type:inline-size;outline:1px solid var(--bitflow-color-border);outline-offset:-1px}.bitflow-pixelgrid-label{font-family:var(--bitflow-font-family-mono);font-size:55cqw;line-height:1}.bitflow-pixelgrid-cell-cursor{box-shadow:inset 0 0 0 2px var(--bitflow-color-primary);z-index:1}.bitflow-pixelgrid-cell-given{box-shadow:inset 0 0 0 2px #fff,inset 0 0 0 4px #000}.bitflow-pixelgrid-cell-cursor.bitflow-pixelgrid-cell-given{box-shadow:inset 0 0 0 2px var(--bitflow-color-primary),inset 0 0 0 4px #fff,inset 0 0 0 6px #000}.bitflow-pixelgrid-cell-wrong:after{content:"";position:absolute;inset:0;background-image:repeating-linear-gradient(45deg,rgba(0,0,0,.45) 0 3px,transparent 3px 9px),repeating-linear-gradient(45deg,rgba(255,255,255,.45) 4.5px 7.5px,transparent 7.5px 9px)}.bitflow-pixelgrid-palette-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--bitflow-space-xsmall)}.bitflow-pixelgrid-color-input{flex:none;width:2.5rem;height:44px;padding:2px;border:var(--bitflow-border-width) solid var(--bitflow-color-border);border-radius:var(--bitflow-radius-standard);background:var(--bitflow-color-surface)}.bitflow-pixelgrid-palette-row>.bitflow-input{flex:1 1 10rem;min-width:0}.bitflow-pixelgrid-size{width:var(--bitflow-pixelgrid-size-width, 6rem)}', Se = {
157
164
  en: {
158
165
  instructionLabel: "Instruction",
159
166
  instructionHint: "Shown above the grid. Markdown is allowed — a PBM listing reads well in a code block.",
@@ -182,6 +189,10 @@ const ye = K({
182
189
  startColorHint: "What every unlocked cell looks like before the learner paints it.",
183
190
  showCoordinatesLabel: "Show row and column numbers",
184
191
  showCoordinatesHint: "Along the edges of the grid.",
192
+ firstIndexLabel: "Count rows and columns from",
193
+ firstIndexHint: "Used along the edges and in each cell's name for screen readers. Choose 0 when the grid stands beside code that indexes an array, so row 0 here is row 0 there.",
194
+ firstIndexOne: "1, as a picture is counted",
195
+ firstIndexZero: "0, as an array is indexed",
185
196
  showLabelsLabel: "Show colour labels in the cells",
186
197
  showLabelsHint: "Useful for a PBM grid of 0s and 1s, where the colour alone is easy to misread.",
187
198
  partialCreditLabel: "Give partial credit",
@@ -220,6 +231,10 @@ const ye = K({
220
231
  startColorHint: "Wie jede ungesperrte Zelle aussieht, bevor sie bemalt wird.",
221
232
  showCoordinatesLabel: "Zeilen- und Spaltennummern anzeigen",
222
233
  showCoordinatesHint: "An den Rändern des Rasters.",
234
+ firstIndexLabel: "Zeilen und Spalten zählen ab",
235
+ firstIndexHint: "Gilt für die Nummern am Rand und für den Namen jeder Zelle im Screenreader. Wähle 0, wenn das Raster neben Code steht, der ein Feld indiziert – dann ist Zeile 0 hier auch Zeile 0 dort.",
236
+ firstIndexOne: "1, wie man ein Bild abzählt",
237
+ firstIndexZero: "0, wie man ein Feld indiziert",
223
238
  showLabelsLabel: "Farbbeschriftungen in den Zellen anzeigen",
224
239
  showLabelsHint: "Nützlich für ein PBM-Raster aus Nullen und Einsen, bei dem die Farbe allein leicht misszuverstehen ist.",
225
240
  partialCreditLabel: "Teilpunkte vergeben",
@@ -232,22 +247,22 @@ const ye = K({
232
247
  }
233
248
  };
234
249
  class B extends Error {
235
- constructor(i, d = {}) {
236
- super(i), this.key = i, this.vars = d;
250
+ constructor(a, d = {}) {
251
+ super(a), this.key = a, this.vars = d;
237
252
  }
238
253
  key;
239
254
  vars;
240
255
  }
241
- const Me = (e) => {
242
- const i = e.split(`
256
+ const Ie = (e) => {
257
+ const a = e.split(`
243
258
  `).map((c) => c.replace(/#.*/, "")).join(`
244
259
  `).split(/\s+/).filter((c) => c.length > 0);
245
- if (i[0] !== "P1")
260
+ if (a[0] !== "P1")
246
261
  throw new B("pbmNoMagic");
247
- const d = Number(i[1]), o = Number(i[2]);
262
+ const d = Number(a[1]), o = Number(a[2]);
248
263
  if (!Number.isInteger(d) || !Number.isInteger(o) || d <= 0 || o <= 0)
249
264
  throw new B("pbmBadSize");
250
- const t = i.slice(3).join("").split("");
265
+ const t = a.slice(3).join("").split("");
251
266
  if (t.length !== o * d)
252
267
  throw new B("pbmCount", {
253
268
  expected: o * d,
@@ -258,8 +273,8 @@ const Me = (e) => {
258
273
  const n = [];
259
274
  for (let c = 0; c < o; c++) {
260
275
  const f = [];
261
- for (let h = 0; h < d; h++) {
262
- const C = t[c * d + h];
276
+ for (let p = 0; p < d; p++) {
277
+ const C = t[c * d + p];
263
278
  if (C !== "0" && C !== "1")
264
279
  throw new B("pbmBadValue", { value: C });
265
280
  f.push(C === "1" ? "black" : "white");
@@ -267,98 +282,102 @@ const Me = (e) => {
267
282
  n.push(f);
268
283
  }
269
284
  return { rows: o, columns: d, cells: n };
270
- }, ie = ({
285
+ }, ne = ({
271
286
  data: e,
272
- cells: i,
287
+ cells: a,
273
288
  locale: d,
274
289
  readonly: o,
275
290
  given: t,
276
291
  wrong: n,
277
292
  onChange: c,
278
293
  lockGiven: f = !0,
279
- toggleGiven: h = !1,
294
+ toggleGiven: p = !1,
280
295
  onToggleGiven: C,
281
296
  hint: Z,
282
297
  showClear: M = !0
283
298
  }) => {
284
- const w = (s, a) => $(_, s, d, a), [x, A] = v.useState({ row: 0, column: 0 }), [I, D] = v.useState(
299
+ const w = (s, i) => E(U, s, d, i), [x, z] = v.useState({ row: 0, column: 0 }), [$, O] = v.useState(
285
300
  e.palette[0]?.id ?? ""
286
- ), [O, T] = v.useState(""), l = v.useId(), u = v.useRef(null), b = v.useRef(i), m = v.useRef(!1), y = v.useRef(null), z = e.palette.find((s) => s.id === I)?.id ?? e.palette[0]?.id ?? "", V = (s, a) => {
287
- const p = le(e, s);
288
- return p?.label || p?.id || w("colorFallback", { number: a + 1 });
289
- }, Y = (s) => {
290
- D(s);
291
- const a = e.palette.findIndex((p) => p.id === s);
292
- T(w("selectedColor", { color: V(s, a) }));
293
- }, S = (s, a) => {
301
+ ), [D, S] = v.useState(""), l = v.useId(), u = v.useRef(null), b = v.useRef(a), g = v.useRef(!1), y = v.useRef(null), H = e.palette.find((s) => s.id === $)?.id ?? e.palette[0]?.id ?? "", Y = (s, i) => {
302
+ const h = ie(e, s);
303
+ return h?.label || h?.id || w("colorFallback", { number: i + 1 });
304
+ }, X = (s) => {
305
+ O(s);
306
+ const i = e.palette.findIndex((h) => h.id === s);
307
+ S(w("selectedColor", { color: Y(s, i) }));
308
+ }, I = (s, i) => {
294
309
  if (o) return;
295
- if (h) {
296
- C?.(s, a);
310
+ if (p) {
311
+ C?.(s, i);
297
312
  return;
298
313
  }
299
- if (f && (t?.[s]?.[a] ?? !1)) return;
300
- m.current || (b.current = i);
301
- const p = Ne(b.current, s, a, z);
302
- b.current = p, c?.(p);
303
- }, X = (s, a) => {
304
- const p = u.current?.getBoundingClientRect();
305
- if (!p || p.width === 0) return;
306
- const g = Math.floor((s - p.left) / p.width * e.columns), k = Math.floor((a - p.top) / p.height * e.rows);
307
- if (!(k < 0 || g < 0 || k >= e.rows || g >= e.columns))
308
- return { row: k, column: g };
309
- }, de = (s) => {
314
+ if (f && (t?.[s]?.[i] ?? !1)) return;
315
+ g.current || (b.current = a);
316
+ const h = ze(b.current, s, i, H);
317
+ b.current = h, c?.(h);
318
+ }, q = (s, i) => {
319
+ const h = u.current?.getBoundingClientRect();
320
+ if (!h || h.width === 0) return;
321
+ const m = Math.floor((s - h.left) / h.width * e.columns), k = Math.floor((i - h.top) / h.height * e.rows);
322
+ if (!(k < 0 || m < 0 || k >= e.rows || m >= e.columns))
323
+ return { row: k, column: m };
324
+ }, ue = (s) => {
310
325
  if (o || s.button !== 0) return;
311
- const a = X(s.clientX, s.clientY);
312
- a && (s.preventDefault(), u.current?.focus(), m.current = !0, b.current = i, y.current = a, A(a), S(a.row, a.column));
326
+ const i = q(s.clientX, s.clientY);
327
+ i && (s.preventDefault(), u.current?.focus(), g.current = !0, b.current = a, y.current = i, z(i), I(i.row, i.column));
313
328
  };
314
- me((s) => {
315
- if (!m.current) return;
316
- const a = X(s.clientX, s.clientY);
317
- a && (y.current && y.current.row === a.row && y.current.column === a.column || (y.current = a, A(a), S(a.row, a.column)));
329
+ ve((s) => {
330
+ if (!g.current) return;
331
+ const i = q(s.clientX, s.clientY);
332
+ i && (y.current && y.current.row === i.row && y.current.column === i.column || (y.current = i, z(i), I(i.row, i.column)));
318
333
  }, () => {
319
- m.current = !1;
334
+ g.current = !1;
320
335
  });
321
- const R = (s, a) => {
322
- A((p) => ({
323
- row: Math.min(e.rows - 1, Math.max(0, p.row + s)),
324
- column: Math.min(e.columns - 1, Math.max(0, p.column + a))
336
+ const T = (s, i) => {
337
+ z((h) => ({
338
+ row: Math.min(e.rows - 1, Math.max(0, h.row + s)),
339
+ column: Math.min(e.columns - 1, Math.max(0, h.column + i))
325
340
  }));
326
- }, ce = (s) => {
341
+ }, be = (s) => {
327
342
  if (o) return;
328
- if (/^[1-9]$/.test(s.key) && !h) {
329
- const p = e.palette[Number(s.key) - 1];
330
- p && (s.preventDefault(), Y(p.id));
343
+ if (/^[1-9]$/.test(s.key) && !p) {
344
+ const h = e.palette[Number(s.key) - 1];
345
+ h && (s.preventDefault(), X(h.id));
331
346
  return;
332
347
  }
333
- const a = {
334
- ArrowRight: () => R(0, 1),
335
- ArrowLeft: () => R(0, -1),
336
- ArrowDown: () => R(1, 0),
337
- ArrowUp: () => R(-1, 0),
338
- Enter: () => S(x.row, x.column),
339
- " ": () => S(x.row, x.column)
348
+ const i = {
349
+ ArrowRight: () => T(0, 1),
350
+ ArrowLeft: () => T(0, -1),
351
+ ArrowDown: () => T(1, 0),
352
+ ArrowUp: () => T(-1, 0),
353
+ Enter: () => I(x.row, x.column),
354
+ " ": () => I(x.row, x.column)
340
355
  }[s.key];
341
- a && (s.preventDefault(), a());
342
- }, ue = (s, a) => {
343
- const p = i[s]?.[a], g = e.palette.findIndex((L) => L.id === p), k = [w("cellAt", { color: V(p, g), row: s + 1, column: a + 1 })];
344
- return t?.[s]?.[a] && k.push(w("given")), n?.[s]?.[a] && k.push(w("wrong")), k.join(". ");
356
+ i && (s.preventDefault(), i());
357
+ }, he = (s, i) => {
358
+ const h = a[s]?.[i], m = e.palette.findIndex((L) => L.id === h), k = [w("cellAt", {
359
+ color: Y(h, m),
360
+ row: s + e.firstIndex,
361
+ column: i + e.firstIndex
362
+ })];
363
+ return t?.[s]?.[i] && k.push(w("given")), n?.[s]?.[i] && k.push(w("wrong")), k.join(". ");
345
364
  };
346
365
  return /* @__PURE__ */ r.jsxs("div", { className: "bitflow-stack-small bitflow-stack", children: [
347
- !o && !h && /* @__PURE__ */ r.jsx(
366
+ !o && !p && /* @__PURE__ */ r.jsx(
348
367
  "div",
349
368
  {
350
369
  className: "bitflow-pixelgrid-palette",
351
370
  role: "group",
352
371
  "aria-label": w("pickColor"),
353
- children: e.palette.map((s, a) => /* @__PURE__ */ r.jsxs("label", { className: "bitflow-pixelgrid-swatch", children: [
372
+ children: e.palette.map((s, i) => /* @__PURE__ */ r.jsxs("label", { className: "bitflow-pixelgrid-swatch", children: [
354
373
  /* @__PURE__ */ r.jsx(
355
374
  "input",
356
375
  {
357
376
  type: "radio",
358
377
  name: l,
359
378
  className: "bitflow-visually-hidden",
360
- checked: z === s.id,
361
- onChange: () => Y(s.id)
379
+ checked: H === s.id,
380
+ onChange: () => X(s.id)
362
381
  }
363
382
  ),
364
383
  /* @__PURE__ */ r.jsx(
@@ -370,8 +389,8 @@ const Me = (e) => {
370
389
  }
371
390
  ),
372
391
  /* @__PURE__ */ r.jsxs("span", { children: [
373
- s.label || w("colorFallback", { number: a + 1 }),
374
- a < 9 ? ` (${a + 1})` : ""
392
+ s.label || w("colorFallback", { number: i + 1 }),
393
+ i < 9 ? ` (${i + 1})` : ""
375
394
  ] })
376
395
  ] }, s.id))
377
396
  }
@@ -385,8 +404,8 @@ const Me = (e) => {
385
404
  children: [
386
405
  e.showCoordinates && /* @__PURE__ */ r.jsxs(r.Fragment, { children: [
387
406
  /* @__PURE__ */ r.jsx("div", { className: "bitflow-pixelgrid-corner", "aria-hidden": "true" }),
388
- /* @__PURE__ */ r.jsx("div", { className: "bitflow-pixelgrid-colheads", "aria-hidden": "true", children: Array.from({ length: e.columns }, (s, a) => /* @__PURE__ */ r.jsx("span", { children: a + 1 }, a)) }),
389
- /* @__PURE__ */ r.jsx("div", { className: "bitflow-pixelgrid-rowheads", "aria-hidden": "true", children: Array.from({ length: e.rows }, (s, a) => /* @__PURE__ */ r.jsx("span", { children: a + 1 }, a)) })
407
+ /* @__PURE__ */ r.jsx("div", { className: "bitflow-pixelgrid-colheads", "aria-hidden": "true", children: Array.from({ length: e.columns }, (s, i) => /* @__PURE__ */ r.jsx("span", { children: i + e.firstIndex }, i)) }),
408
+ /* @__PURE__ */ r.jsx("div", { className: "bitflow-pixelgrid-rowheads", "aria-hidden": "true", children: Array.from({ length: e.rows }, (s, i) => /* @__PURE__ */ r.jsx("span", { children: i + e.firstIndex }, i)) })
390
409
  ] }),
391
410
  /* @__PURE__ */ r.jsx(
392
411
  "div",
@@ -397,53 +416,53 @@ const Me = (e) => {
397
416
  "aria-label": w("gridLabel"),
398
417
  tabIndex: o ? -1 : 0,
399
418
  "aria-activedescendant": `${l}-${x.row}-${x.column}`,
400
- onPointerDown: de,
401
- onKeyDown: ce,
402
- children: Array.from({ length: e.rows }, (s, a) => /* @__PURE__ */ r.jsx("div", { role: "row", className: "bitflow-pixelgrid-row", children: Array.from({ length: e.columns }, (p, g) => {
403
- const k = i[a]?.[g], L = le(e, k), be = t?.[a]?.[g] ?? !1, q = n?.[a]?.[g] ?? !1, F = ["bitflow-pixelgrid-cell"];
404
- return be && F.push("bitflow-pixelgrid-cell-given"), q && F.push("bitflow-pixelgrid-cell-wrong"), x.row === a && x.column === g && F.push("bitflow-pixelgrid-cell-cursor"), /* @__PURE__ */ r.jsxs(
419
+ onPointerDown: ue,
420
+ onKeyDown: be,
421
+ children: Array.from({ length: e.rows }, (s, i) => /* @__PURE__ */ r.jsx("div", { role: "row", className: "bitflow-pixelgrid-row", children: Array.from({ length: e.columns }, (h, m) => {
422
+ const k = a[i]?.[m], L = ie(e, k), pe = t?.[i]?.[m] ?? !1, _ = n?.[i]?.[m] ?? !1, F = ["bitflow-pixelgrid-cell"];
423
+ return pe && F.push("bitflow-pixelgrid-cell-given"), _ && F.push("bitflow-pixelgrid-cell-wrong"), x.row === i && x.column === m && F.push("bitflow-pixelgrid-cell-cursor"), /* @__PURE__ */ r.jsxs(
405
424
  "span",
406
425
  {
407
- id: `${l}-${a}-${g}`,
426
+ id: `${l}-${i}-${m}`,
408
427
  role: "gridcell",
409
428
  className: F.join(" "),
410
429
  style: { background: L?.color ?? "transparent" },
411
- "aria-label": ue(a, g),
430
+ "aria-label": he(i, m),
412
431
  children: [
413
432
  e.showLabels && L && /* @__PURE__ */ r.jsx(
414
433
  "span",
415
434
  {
416
435
  className: "bitflow-pixelgrid-label",
417
- style: { color: Pe(L.color) },
436
+ style: { color: He(L.color) },
418
437
  "aria-hidden": "true",
419
438
  children: L.label || L.id
420
439
  }
421
440
  ),
422
- q && /* @__PURE__ */ r.jsx("span", { className: "bitflow-visually-hidden", children: w("wrong") })
441
+ _ && /* @__PURE__ */ r.jsx("span", { className: "bitflow-visually-hidden", children: w("wrong") })
423
442
  ]
424
443
  },
425
- g
444
+ m
426
445
  );
427
- }) }, a))
446
+ }) }, i))
428
447
  }
429
448
  )
430
449
  ]
431
450
  }
432
451
  ),
433
- !o && !h && M && /* @__PURE__ */ r.jsx("div", { className: "bitflow-row", children: /* @__PURE__ */ r.jsx(
452
+ !o && !p && M && /* @__PURE__ */ r.jsx("div", { className: "bitflow-row", children: /* @__PURE__ */ r.jsx(
434
453
  "button",
435
454
  {
436
455
  type: "button",
437
456
  className: "bitflow-button bitflow-button-secondary",
438
- onClick: () => c?.(je(e)),
457
+ onClick: () => c?.(Pe(e)),
439
458
  children: w("clear")
440
459
  }
441
460
  ) }),
442
- /* @__PURE__ */ r.jsx("div", { className: "bitflow-visually-hidden", role: "status", "aria-live": "polite", children: O })
461
+ /* @__PURE__ */ r.jsx("div", { className: "bitflow-visually-hidden", role: "status", "aria-live": "polite", children: D })
443
462
  ] });
444
463
  }, Te = ({
445
464
  data: e,
446
- answer: i,
465
+ answer: a,
447
466
  result: d,
448
467
  readonly: o,
449
468
  locale: t,
@@ -451,12 +470,12 @@ const Me = (e) => {
451
470
  }) => {
452
471
  const c = d?.detail?.wrong;
453
472
  return /* @__PURE__ */ r.jsxs("div", { className: "bitflow-stack", children: [
454
- /* @__PURE__ */ r.jsx(xe, { markdown: e.instruction }),
473
+ /* @__PURE__ */ r.jsx(Ce, { markdown: e.instruction }),
455
474
  /* @__PURE__ */ r.jsx(
456
- ie,
475
+ ne,
457
476
  {
458
477
  data: e,
459
- cells: Le(e, i?.cells),
478
+ cells: Ne(e, a?.cells),
460
479
  given: e.given,
461
480
  wrong: c,
462
481
  locale: t,
@@ -465,39 +484,39 @@ const Me = (e) => {
465
484
  }
466
485
  )
467
486
  ] });
468
- }, oe = 1, ne = 32, Se = (e) => Math.min(ne, Math.max(oe, Math.round(e))), Re = (e) => {
469
- for (let i = e.length + 1; ; i++) {
470
- const d = `color-${i}`;
487
+ }, se = 1, de = 32, Fe = (e) => Math.min(de, Math.max(se, Math.round(e))), Re = (e) => {
488
+ for (let a = e.length + 1; ; a++) {
489
+ const d = `color-${a}`;
471
490
  if (!e.some((o) => o.id === d)) return d;
472
491
  }
473
- }, Fe = ({
492
+ }, Ge = ({
474
493
  data: e,
475
- locale: i,
494
+ locale: a,
476
495
  onChange: d,
477
496
  errors: o
478
497
  }) => {
479
- const t = (l, u) => $(Be, l, i, u), n = (l) => d({ ...e, ...l }), [c, f] = v.useState(!1), [h, C] = v.useState(""), [Z, M] = v.useState(void 0), w = H(e.target, e.rows, e.columns, e.startColor), x = (l, u) => n({
498
+ const t = (l, u) => E(Se, l, a, u), n = (l) => d({ ...e, ...l }), [c, f] = v.useState(!1), [p, C] = v.useState(""), [Z, M] = v.useState(void 0), w = A(e.target, e.rows, e.columns, e.startColor), x = (l, u) => n({
480
499
  rows: l,
481
500
  columns: u,
482
- target: H(e.target, l, u, e.startColor),
483
- given: e.given.length > 0 ? H(e.given, l, u, !1) : []
484
- }), A = (l, u) => n({
501
+ target: A(e.target, l, u, e.startColor),
502
+ given: e.given.length > 0 ? A(e.given, l, u, !1) : []
503
+ }), z = (l, u) => n({
485
504
  palette: e.palette.map(
486
505
  (b) => b.id === l ? { ...b, ...u } : b
487
506
  )
488
- }), I = (l) => {
489
- const u = e.palette.filter((m) => m.id !== l), b = u[0]?.id ?? "";
507
+ }), $ = (l) => {
508
+ const u = e.palette.filter((g) => g.id !== l), b = u[0]?.id ?? "";
490
509
  n({
491
510
  palette: u,
492
- target: e.target.map((m) => m.map((y) => y === l ? b : y)),
511
+ target: e.target.map((g) => g.map((y) => y === l ? b : y)),
493
512
  startColor: e.startColor === l ? b : e.startColor
494
513
  });
495
- }, D = (l, u) => {
496
- const b = e.given.length > 0 ? H(e.given, e.rows, e.columns, !1) : H([], e.rows, e.columns, !1);
497
- b[l] = [...b[l]], b[l][u] = !b[l][u], n({ given: b.some((m) => m.includes(!0)) ? b : [] });
498
- }, O = () => {
514
+ }, O = (l, u) => {
515
+ const b = e.given.length > 0 ? A(e.given, e.rows, e.columns, !1) : A([], e.rows, e.columns, !1);
516
+ b[l] = [...b[l]], b[l][u] = !b[l][u], n({ given: b.some((g) => g.includes(!0)) ? b : [] });
517
+ }, D = () => {
499
518
  try {
500
- const l = Me(h);
519
+ const l = Ie(p);
501
520
  M(void 0), n({
502
521
  rows: l.rows,
503
522
  columns: l.columns,
@@ -511,24 +530,24 @@ const Me = (e) => {
511
530
  l instanceof B ? t(l.key, l.vars) : String(l)
512
531
  );
513
532
  }
514
- }, T = (l, u, b) => /* @__PURE__ */ r.jsx(ve, { label: l, children: (m) => /* @__PURE__ */ r.jsx(
533
+ }, S = (l, u, b) => /* @__PURE__ */ r.jsx(ye, { label: l, children: (g) => /* @__PURE__ */ r.jsx(
515
534
  "input",
516
535
  {
517
- ...m,
536
+ ...g,
518
537
  type: "number",
519
538
  className: "bitflow-input bitflow-pixelgrid-size",
520
- min: oe,
521
- max: ne,
539
+ min: se,
540
+ max: de,
522
541
  value: u,
523
542
  onChange: (y) => {
524
- const z = Number(y.target.value);
525
- Number.isFinite(z) && z > 0 && b(Se(z));
543
+ const H = Number(y.target.value);
544
+ Number.isFinite(H) && H > 0 && b(Fe(H));
526
545
  }
527
546
  }
528
547
  ) });
529
548
  return /* @__PURE__ */ r.jsxs("div", { className: "bitflow-stack", children: [
530
549
  /* @__PURE__ */ r.jsx(
531
- Q,
550
+ ee,
532
551
  {
533
552
  label: t("instructionLabel"),
534
553
  hint: t("instructionHint"),
@@ -541,22 +560,22 @@ const Me = (e) => {
541
560
  /* @__PURE__ */ r.jsx("legend", { className: "bitflow-label", children: t("sizeLabel") }),
542
561
  /* @__PURE__ */ r.jsx("span", { className: "bitflow-hint", children: t("sizeHint") }),
543
562
  /* @__PURE__ */ r.jsxs("div", { className: "bitflow-row", children: [
544
- T(t("rowsLabel"), e.rows, (l) => x(l, e.columns)),
545
- T(
563
+ S(t("rowsLabel"), e.rows, (l) => x(l, e.columns)),
564
+ S(
546
565
  t("columnsLabel"),
547
566
  e.columns,
548
567
  (l) => x(e.rows, l)
549
568
  )
550
569
  ] })
551
570
  ] }),
552
- /* @__PURE__ */ r.jsx(ee, { summary: t("importSummary"), children: /* @__PURE__ */ r.jsxs("div", { className: "bitflow-stack-small bitflow-stack", children: [
571
+ /* @__PURE__ */ r.jsx(te, { summary: t("importSummary"), children: /* @__PURE__ */ r.jsxs("div", { className: "bitflow-stack-small bitflow-stack", children: [
553
572
  /* @__PURE__ */ r.jsx(
554
- Q,
573
+ ee,
555
574
  {
556
575
  label: t("importTextareaLabel"),
557
576
  hint: t("importHint"),
558
577
  rows: 6,
559
- value: h,
578
+ value: p,
560
579
  error: Z,
561
580
  onChange: C
562
581
  }
@@ -566,7 +585,7 @@ const Me = (e) => {
566
585
  {
567
586
  type: "button",
568
587
  className: "bitflow-button bitflow-button-secondary",
569
- onClick: O,
588
+ onClick: D,
570
589
  children: t("importButton")
571
590
  }
572
591
  ) })
@@ -574,7 +593,7 @@ const Me = (e) => {
574
593
  /* @__PURE__ */ r.jsxs("fieldset", { className: "bitflow-field", children: [
575
594
  /* @__PURE__ */ r.jsx("legend", { className: "bitflow-label", children: t("paletteLabel") }),
576
595
  /* @__PURE__ */ r.jsx("span", { className: "bitflow-hint", children: t("paletteHint") }),
577
- te(o, "palette") && /* @__PURE__ */ r.jsx("span", { className: "bitflow-field-error", role: "alert", children: te(o, "palette") }),
596
+ le(o, "palette") && /* @__PURE__ */ r.jsx("span", { className: "bitflow-field-error", role: "alert", children: le(o, "palette") }),
578
597
  e.palette.map((l, u) => /* @__PURE__ */ r.jsxs("div", { className: "bitflow-pixelgrid-palette-row", children: [
579
598
  /* @__PURE__ */ r.jsx(
580
599
  "input",
@@ -583,7 +602,7 @@ const Me = (e) => {
583
602
  className: "bitflow-pixelgrid-color-input",
584
603
  value: l.color,
585
604
  "aria-label": t("colorSwatchOf", { position: u + 1 }),
586
- onChange: (b) => A(l.id, { color: b.target.value })
605
+ onChange: (b) => z(l.id, { color: b.target.value })
587
606
  }
588
607
  ),
589
608
  /* @__PURE__ */ r.jsx(
@@ -594,7 +613,7 @@ const Me = (e) => {
594
613
  value: l.label,
595
614
  placeholder: t("colorLabelPlaceholder"),
596
615
  "aria-label": t("colorLabelOf", { position: u + 1 }),
597
- onChange: (b) => A(l.id, { label: b.target.value })
616
+ onChange: (b) => z(l.id, { label: b.target.value })
598
617
  }
599
618
  ),
600
619
  /* @__PURE__ */ r.jsx(
@@ -604,7 +623,7 @@ const Me = (e) => {
604
623
  className: "bitflow-button bitflow-button-quiet",
605
624
  disabled: e.palette.length <= 1,
606
625
  "aria-label": t("removeColorOf", { position: u + 1 }),
607
- onClick: () => I(l.id),
626
+ onClick: () => $(l.id),
608
627
  children: "✕"
609
628
  }
610
629
  )
@@ -638,22 +657,22 @@ const Me = (e) => {
638
657
  }
639
658
  ),
640
659
  /* @__PURE__ */ r.jsx(
641
- ie,
660
+ ne,
642
661
  {
643
662
  data: e,
644
663
  cells: w,
645
664
  given: e.given,
646
- locale: i,
665
+ locale: a,
647
666
  lockGiven: !1,
648
667
  toggleGiven: c,
649
- onToggleGiven: D,
668
+ onToggleGiven: O,
650
669
  hint: c ? t("markGivenHowTo") : void 0,
651
670
  onChange: (l) => n({ target: l })
652
671
  }
653
672
  )
654
673
  ] }),
655
674
  /* @__PURE__ */ r.jsx(
656
- we,
675
+ re,
657
676
  {
658
677
  label: t("startColorLabel"),
659
678
  hint: t("startColorHint"),
@@ -666,7 +685,7 @@ const Me = (e) => {
666
685
  onChange: (l) => n({ startColor: l })
667
686
  }
668
687
  ),
669
- /* @__PURE__ */ r.jsxs(ee, { summary: t("advanced"), children: [
688
+ /* @__PURE__ */ r.jsxs(te, { summary: t("advanced"), children: [
670
689
  /* @__PURE__ */ r.jsx(
671
690
  G,
672
691
  {
@@ -676,6 +695,19 @@ const Me = (e) => {
676
695
  onChange: (l) => n({ showCoordinates: l })
677
696
  }
678
697
  ),
698
+ /* @__PURE__ */ r.jsx(
699
+ re,
700
+ {
701
+ label: t("firstIndexLabel"),
702
+ hint: t("firstIndexHint"),
703
+ value: String(e.firstIndex),
704
+ options: [
705
+ { value: "1", label: t("firstIndexOne") },
706
+ { value: "0", label: t("firstIndexZero") }
707
+ ],
708
+ onChange: (l) => n({ firstIndex: l === "0" ? 0 : 1 })
709
+ }
710
+ ),
679
711
  /* @__PURE__ */ r.jsx(
680
712
  G,
681
713
  {
@@ -695,26 +727,26 @@ const Me = (e) => {
695
727
  }
696
728
  ),
697
729
  /* @__PURE__ */ r.jsx(
698
- ge,
730
+ xe,
699
731
  {
700
732
  evaluation: e.evaluation,
701
- locale: i,
733
+ locale: a,
702
734
  onChange: (l) => n({ evaluation: l })
703
735
  }
704
736
  )
705
737
  ] })
706
738
  ] });
707
- }, se = "task-pixel-grid";
708
- he({
709
- type: se,
739
+ }, ce = "task-pixel-grid";
740
+ me({
741
+ type: ce,
710
742
  kind: "task",
711
- schema: ke,
712
- evaluate: ze,
743
+ schema: je,
744
+ evaluate: Be,
713
745
  Task: Te,
714
- Form: Fe,
746
+ Form: Ge,
715
747
  info: (e) => ({
716
- name: $(_, "name", e),
717
- description: $(_, "description", e)
748
+ name: E(U, "name", e),
749
+ description: E(U, "description", e)
718
750
  }),
719
751
  defaultData: () => ({
720
752
  instruction: "",
@@ -728,34 +760,35 @@ he({
728
760
  given: [],
729
761
  startColor: P[0].id,
730
762
  showCoordinates: !0,
763
+ firstIndex: 1,
731
764
  showLabels: !1,
732
765
  partialCredit: !0,
733
- evaluation: re()
766
+ evaluation: ae()
734
767
  })
735
768
  });
736
- Ce(se);
737
- fe("bitflow-styles-task-pixel-grid", He);
769
+ ke(ce);
770
+ ge("bitflow-styles-task-pixel-grid", Me);
738
771
  export {
739
772
  $e as AnswerSchema,
740
773
  P as DEFAULT_PALETTE,
741
- ke as DataSchema,
742
- Fe as Form,
743
- ye as PaletteEntrySchema,
774
+ je as DataSchema,
775
+ Ge as Form,
776
+ Le as PaletteEntrySchema,
744
777
  B as PbmError,
745
- ie as PixelGrid,
746
- se as TYPE,
778
+ ne as PixelGrid,
779
+ ce as TYPE,
747
780
  Te as Task,
748
- je as blankCells,
749
- Pe as contrastColor,
750
- Le as effectiveCells,
751
- ze as evaluate,
752
- Be as formMessages,
753
- U as isGiven,
754
- _ as messages,
755
- Ne as paintCell,
756
- le as paletteEntry,
757
- Me as parsePbm,
758
- H as resizeGrid,
781
+ Pe as blankCells,
782
+ He as contrastColor,
783
+ Ne as effectiveCells,
784
+ Be as evaluate,
785
+ Se as formMessages,
786
+ V as isGiven,
787
+ U as messages,
788
+ ze as paintCell,
789
+ ie as paletteEntry,
790
+ Ie as parsePbm,
791
+ A as resizeGrid,
759
792
  Ae as scoreOf,
760
- ae as wrongCells
793
+ oe as wrongCells
761
794
  };