eyeling 1.16.3 → 1.16.4

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 (45) hide show
  1. package/README.md +0 -1
  2. package/package.json +2 -3
  3. package/arctifacts/README.md +0 -59
  4. package/arctifacts/ackermann.html +0 -678
  5. package/arctifacts/auroracare.html +0 -1297
  6. package/arctifacts/bike-trip.html +0 -752
  7. package/arctifacts/binomial-theorem.html +0 -631
  8. package/arctifacts/bmi.html +0 -511
  9. package/arctifacts/building-performance.html +0 -750
  10. package/arctifacts/clinical-care.html +0 -726
  11. package/arctifacts/collatz.html +0 -403
  12. package/arctifacts/complex.html +0 -321
  13. package/arctifacts/control-system.html +0 -482
  14. package/arctifacts/delfour.html +0 -849
  15. package/arctifacts/earthquake-epicenter.html +0 -982
  16. package/arctifacts/eco-route.html +0 -662
  17. package/arctifacts/euclid-infinitude.html +0 -564
  18. package/arctifacts/euler-identity.html +0 -667
  19. package/arctifacts/exoplanet-transit.html +0 -1000
  20. package/arctifacts/faltings-theorem.html +0 -1046
  21. package/arctifacts/fibonacci.html +0 -299
  22. package/arctifacts/fundamental-theorem-arithmetic.html +0 -398
  23. package/arctifacts/godel-numbering.html +0 -743
  24. package/arctifacts/gps-bike.html +0 -759
  25. package/arctifacts/gps-clinical-bench.html +0 -792
  26. package/arctifacts/graph-french.html +0 -449
  27. package/arctifacts/grass-molecular.html +0 -592
  28. package/arctifacts/group-theory.html +0 -740
  29. package/arctifacts/health-info.html +0 -833
  30. package/arctifacts/kaprekar-constant.html +0 -576
  31. package/arctifacts/lee.html +0 -805
  32. package/arctifacts/linked-lists.html +0 -502
  33. package/arctifacts/lldm.html +0 -612
  34. package/arctifacts/matrix-multiplication.html +0 -502
  35. package/arctifacts/matrix.html +0 -651
  36. package/arctifacts/newton-raphson.html +0 -944
  37. package/arctifacts/peano-factorial.html +0 -456
  38. package/arctifacts/pi.html +0 -363
  39. package/arctifacts/polynomial.html +0 -646
  40. package/arctifacts/prime.html +0 -366
  41. package/arctifacts/pythagorean-theorem.html +0 -468
  42. package/arctifacts/rest-path.html +0 -469
  43. package/arctifacts/roots-of-unity.html +0 -363
  44. package/arctifacts/turing.html +0 -409
  45. package/arctifacts/wind-turbines.html +0 -726
@@ -1,631 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>Sum of All Binomial Coefficients</title>
7
- <style>
8
- :root {
9
- --bg: #f7f9fc;
10
- --card: #ffffff;
11
- --text: #0f172a;
12
- --muted: #475569;
13
- --accent: #2563eb;
14
- --good: #16a34a;
15
- --bad: #dc2626;
16
- --border: #e2e8f0;
17
- --chip: #eef2ff;
18
- --code: #111827;
19
- }
20
- html,
21
- body {
22
- background: var(--bg);
23
- color: var(--text);
24
- font-family:
25
- ui-sans-serif,
26
- system-ui,
27
- -apple-system,
28
- Segoe UI,
29
- Roboto,
30
- Helvetica,
31
- Arial,
32
- 'Apple Color Emoji',
33
- 'Segoe UI Emoji';
34
- }
35
- * {
36
- box-sizing: border-box;
37
- }
38
- .container {
39
- max-width: 960px;
40
- margin: 24px auto;
41
- padding: 0 16px;
42
- }
43
- header {
44
- display: flex;
45
- flex-direction: column;
46
- gap: 8px;
47
- margin-bottom: 16px;
48
- }
49
- h1 {
50
- font-size: 1.8rem;
51
- margin: 0;
52
- letter-spacing: -0.02em;
53
- }
54
- .subtitle {
55
- color: var(--muted);
56
- }
57
- .card {
58
- background: var(--card);
59
- border: 1px solid var(--border);
60
- border-radius: 16px;
61
- padding: 16px;
62
- box-shadow: 0 6px 20px rgba(2, 6, 23, 0.05);
63
- }
64
- .stack {
65
- display: flex;
66
- flex-direction: column;
67
- gap: 16px;
68
- }
69
- .pill {
70
- display: inline-flex;
71
- align-items: center;
72
- gap: 8px;
73
- padding: 4px 10px;
74
- background: var(--chip);
75
- color: #1e3a8a;
76
- border-radius: 999px;
77
- font-size: 12px;
78
- font-weight: 600;
79
- border: 1px solid #c7d2fe;
80
- }
81
- .row {
82
- display: flex;
83
- gap: 12px;
84
- align-items: center;
85
- }
86
- input[type='number'] {
87
- width: 160px;
88
- padding: 10px 12px;
89
- border-radius: 10px;
90
- border: 1px solid var(--border);
91
- background: #fbfdff;
92
- }
93
- button {
94
- appearance: none;
95
- border: none;
96
- background: var(--accent);
97
- color: white;
98
- padding: 10px 14px;
99
- border-radius: 12px;
100
- font-weight: 700;
101
- cursor: pointer;
102
- box-shadow: 0 4px 14px rgba(37, 99, 235, 0.25);
103
- }
104
- button.secondary {
105
- background: #0ea5e9;
106
- }
107
- button.ghost {
108
- background: transparent;
109
- color: var(--accent);
110
- border: 1px solid var(--accent);
111
- }
112
- button:disabled {
113
- opacity: 0.6;
114
- cursor: not-allowed;
115
- }
116
- .grid {
117
- display: grid;
118
- grid-template-columns: 1fr;
119
- gap: 16px;
120
- }
121
- .muted {
122
- color: var(--muted);
123
- }
124
- .mono {
125
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
126
- color: var(--code);
127
- word-break: break-word;
128
- overflow-wrap: anywhere;
129
- white-space: normal;
130
- }
131
- .kpi {
132
- display: flex;
133
- gap: 16px;
134
- flex-wrap: wrap;
135
- }
136
- .kpi .card {
137
- padding: 12px 14px;
138
- }
139
- .k {
140
- font-weight: 700;
141
- }
142
- .v {
143
- font-variant-numeric: tabular-nums;
144
- }
145
- .list {
146
- display: flex;
147
- flex-direction: column;
148
- gap: 12px;
149
- }
150
- .term {
151
- padding: 10px;
152
- background: #f8fafc;
153
- border: 1px dashed var(--border);
154
- border-radius: 12px;
155
- }
156
- details {
157
- border: 1px solid var(--border);
158
- border-radius: 12px;
159
- padding: 10px 12px;
160
- background: #fafcff;
161
- }
162
- details summary {
163
- cursor: pointer;
164
- font-weight: 700;
165
- color: #0b3eaa;
166
- }
167
- .badge {
168
- padding: 2px 8px;
169
- border-radius: 999px;
170
- font-weight: 700;
171
- font-size: 12px;
172
- border: 1px solid #cbd5e1;
173
- background: #f1f5f9;
174
- color: #0f172a;
175
- }
176
- .ok {
177
- background: #dcfce7;
178
- color: #166534;
179
- border: 1px solid #86efac;
180
- }
181
- .fail {
182
- background: #fee2e2;
183
- color: #991b1b;
184
- border: 1px solid #fecaca;
185
- }
186
- .harness {
187
- border-left: 6px solid #c7d2fe;
188
- }
189
- .h-title {
190
- display: flex;
191
- align-items: center;
192
- justify-content: space-between;
193
- gap: 8px;
194
- }
195
- .small {
196
- font-size: 12px;
197
- }
198
- code {
199
- background: #f1f5f9;
200
- padding: 2px 6px;
201
- border-radius: 6px;
202
- }
203
- footer {
204
- color: var(--muted);
205
- font-size: 12px;
206
- text-align: center;
207
- margin: 16px 0 40px;
208
- }
209
- .divider {
210
- height: 1px;
211
- background: var(--border);
212
- margin: -4px 0 8px;
213
- }
214
- .chips {
215
- display: flex;
216
- flex-wrap: wrap;
217
- gap: 8px;
218
- }
219
- .chips .badge {
220
- word-break: break-all;
221
- overflow-wrap: anywhere;
222
- white-space: normal;
223
- }
224
- .kpi .card .v {
225
- word-break: break-word;
226
- overflow-wrap: anywhere;
227
- }
228
- .row {
229
- min-width: 0;
230
- }
231
- </style>
232
- </head>
233
- <body>
234
- <div class="container stack">
235
- <header class="card stack">
236
- <div class="row" style="justify-content: space-between; align-items: flex-start; width: 100%">
237
- <div>
238
- <h1>Sum of all binomial coefficients</h1>
239
- </div>
240
- </div>
241
- <span class="badge">Problem: B(n) = Σₖ₌₀ⁿ C(n,k)</span>
242
- <p class="muted">
243
- Give a non‑negative integer <em>n</em>. This page states the closed form of <span class="mono">B(n)</span>,
244
- explains why it is true in mathematical English, and verifies it with a built‑in test harness.
245
- </p>
246
- </header>
247
-
248
- <!-- INPUT -->
249
- <section class="card stack" id="input-card">
250
- <h2 style="margin: 0">Input</h2>
251
- <div class="divider"></div>
252
- <div class="row">
253
- <label class="mono">n = </label>
254
- <input id="nInput" type="number" min="0" step="1" value="4000" />
255
- <button type="button" id="solve">Evaluate B(n)</button>
256
- <button type="button" id="clear">Clear</button>
257
- </div>
258
- <p class="small muted">
259
- Constraints: n ∈ ℕ, typically n ≤ 1000 for display. All arithmetic uses exact <code>BigInt</code>.
260
- </p>
261
- </section>
262
-
263
- <!-- OUTPUT -->
264
- <section class="card stack" id="output-card" aria-live="polite">
265
- <h2 style="margin: 0">Output</h2>
266
- <div class="divider"></div>
267
-
268
- <!-- Answer KPIs -->
269
- <section class="stack">
270
- <div class="kpi">
271
- <div class="card">
272
- <div class="k">Answer</div>
273
- <div id="answer" class="v mono">—</div>
274
- </div>
275
- <div class="card">
276
- <div class="k">Closed form</div>
277
- <div id="closed" class="v mono">B(n) = 2^n</div>
278
- </div>
279
- <div class="card">
280
- <div class="k">Σ C(n,k)</div>
281
- <div id="sumRow" class="v mono">—</div>
282
- </div>
283
- <div class="card">
284
- <div class="k">Row length</div>
285
- <div id="rowLen" class="v mono">—</div>
286
- </div>
287
- </div>
288
- </section>
289
-
290
- <!-- Reason Why (mathematical English) -->
291
- <section class="stack">
292
- <h3 style="margin: 0">Reason Why</h3>
293
- <div class="list">
294
- <div class="term">
295
- <strong>Algebraic.</strong> The binomial theorem states
296
- <span class="mono">(x + y)^n = Σₖ C(n,k) x^{n−k} y^k</span>. Substituting
297
- <span class="mono">x = y = 1</span> gives <span class="mono">2^n = Σₖ C(n,k)</span>. Hence
298
- <span class="mono">B(n) = 2^n</span>.
299
- </div>
300
- <div class="term">
301
- <strong>Combinatorial.</strong> Each term <span class="mono">C(n,k)</span> counts the
302
- <span class="mono">k</span>‑element subsets of an <span class="mono">n</span>‑set. Summing over all
303
- <span class="mono">k</span> counts every subset exactly once, so the total is the number of all subsets,
304
- namely <span class="mono">2^n</span>.
305
- </div>
306
- <div class="term">
307
- <strong>Symmetry check.</strong> Because <span class="mono">C(n,k) = C(n,n−k)</span>, the partial sums are
308
- pairwise matched; the extremes satisfy <span class="mono">C(n,0)=C(n,n)=1</span>.
309
- </div>
310
- </div>
311
- <details>
312
- <summary>Show coefficients C(n,k)</summary>
313
- <div id="row" class="chips mono"></div>
314
- </details>
315
- </section>
316
-
317
- <!-- Check (harness) for the user's n -->
318
- <section class="stack">
319
- <h3 style="margin: 0">Check (harness)</h3>
320
- <div id="checks" class="list"></div>
321
- </section>
322
- </section>
323
-
324
- <!-- PRELOADED HARNESS CASES (≥ 6) -->
325
- <section class="card stack harness" id="preloaded">
326
- <div class="h-title">
327
- <h2 style="margin: 0">Preloaded Checks (harness)</h2>
328
- <div class="row">
329
- <button id="runAll">Run all</button>
330
- <button class="ghost" id="clearHarness">Clear results</button>
331
- </div>
332
- </div>
333
- <p class="small muted">
334
- Each block recomputes <span class="mono">B(n)</span> two ways (<span class="mono">Σ C(n,k)</span> vs
335
- <span class="mono">2^n</span>) and asserts they agree. One case is intentionally invalid.
336
- </p>
337
- <div id="harnesses" class="stack"></div>
338
- </section>
339
-
340
- <footer>
341
- <div>Built as a self‑checking artifact: program → <em>Answer</em>, <em>Reason Why</em>, <em>Check</em>.</div>
342
- <div class="small">This page performs only on‑device computation.</div>
343
- </footer>
344
- </div>
345
-
346
- <script>
347
- // ---------- BigInt helpers ----------
348
- const ZERO = 0n,
349
- ONE = 1n,
350
- TWO = 2n;
351
- const toBig = (x) => {
352
- try {
353
- return BigInt(x);
354
- } catch {
355
- return null;
356
- }
357
- };
358
- const isNonNegInt = (b) => b !== null && b >= 0n;
359
-
360
- // fast power: a^e for BigInt
361
- function pow(a, e) {
362
- let base = a,
363
- exp = e,
364
- res = 1n;
365
- while (exp > 0n) {
366
- if (exp & 1n) res *= base;
367
- base *= base;
368
- exp >>= 1n;
369
- }
370
- return res;
371
- }
372
-
373
- // compute the nth binomial row [C(n,0),...,C(n,n)] as BigInts
374
- function binomRow(n) {
375
- const N = Number(n);
376
- const row = new Array(N + 1);
377
- row[0] = 1n;
378
- for (let k = 1; k <= N; k++) {
379
- // C(n,k) = C(n,k-1) * (n-k+1)/k
380
- const prev = row[k - 1];
381
- const num = n - BigInt(k) + 1n; // BigInt
382
- const den = BigInt(k);
383
- row[k] = (prev * num) / den; // exact division for binomial coefficients
384
- }
385
- return row;
386
- }
387
-
388
- function sumRow(row) {
389
- return row.reduce((acc, v) => acc + v, 0n);
390
- }
391
-
392
- // ---------- UI helpers ----------
393
- const el = (tag, attrs = {}, children = []) => {
394
- const node = document.createElement(tag);
395
- Object.entries(attrs).forEach(([k, v]) => {
396
- if (k === 'class') node.className = v;
397
- else if (k === 'html') node.innerHTML = v;
398
- else if (k.startsWith('on')) node.addEventListener(k.slice(2).toLowerCase(), v);
399
- else node.setAttribute(k, v);
400
- });
401
- children.forEach((c) => node.appendChild(typeof c === 'string' ? document.createTextNode(c) : c));
402
- return node;
403
- };
404
-
405
- function renderChips(div, row) {
406
- div.replaceChildren(...row.map((v, k) => el('span', { class: 'badge' }, [`C(n,${k})=${v.toString()}`])));
407
- }
408
-
409
- function renderChecks(n, row, sum, pow2) {
410
- const checks = document.getElementById('checks');
411
- const list = [];
412
-
413
- const eq = sum === pow2;
414
- list.push(
415
- el('div', { class: 'row' }, [
416
- el('span', { class: 'badge ' + (eq ? 'ok' : 'fail') }, [eq ? 'PASS' : 'FAIL']),
417
- document.createTextNode(' Equality '),
418
- el('span', { class: 'mono' }, ['Σ C(n,k) = 2^n']),
419
- ]),
420
- );
421
-
422
- const ends = row.length >= 1 && row[0] === 1n && row[row.length - 1] === 1n;
423
- list.push(
424
- el('div', { class: 'row' }, [
425
- el('span', { class: 'badge ' + (ends ? 'ok' : 'fail') }, [ends ? 'PASS' : 'FAIL']),
426
- el('span', { class: 'mono' }, ['C(n,0)=C(n,n)=1']),
427
- ]),
428
- );
429
-
430
- const sym = row.every((v, i) => v === row[row.length - 1 - i]);
431
- list.push(
432
- el('div', { class: 'row' }, [
433
- el('span', { class: 'badge ' + (sym ? 'ok' : 'fail') }, [sym ? 'PASS' : 'FAIL']),
434
- el('span', { class: 'mono' }, ['Symmetry C(n,k)=C(n,n−k)']),
435
- ]),
436
- );
437
-
438
- const lenOk = row.length === Number(n) + 1;
439
- list.push(
440
- el('div', { class: 'row' }, [
441
- el('span', { class: 'badge ' + (lenOk ? 'ok' : 'fail') }, [lenOk ? 'PASS' : 'FAIL']),
442
- el('span', { class: 'mono' }, ['Row length n+1']),
443
- ]),
444
- );
445
-
446
- // middle (when n even)
447
- if (n % 2n === 0n) {
448
- const mid = row[Number(n / 2n)];
449
- const midOk = typeof mid !== 'undefined' && mid >= 1n;
450
- list.push(
451
- el('div', { class: 'row' }, [
452
- el('span', { class: 'badge ' + (midOk ? 'ok' : 'fail') }, [midOk ? 'PASS' : 'FAIL']),
453
- el('span', { class: 'mono' }, ['Central coefficient ≥ 1']),
454
- ]),
455
- );
456
- }
457
-
458
- // Pascal identity spot-check (random k)
459
- if (row.length > 2) {
460
- const k = Math.min(2, row.length - 2);
461
- const lhs = row[k];
462
- const rhs = row[k - 1] + row[k + 1] * 0n + (row[k - 1] + row[k]) - row[k - 1]; // keep code simple, see below
463
- }
464
-
465
- list.push(
466
- el('div', { class: 'row' }, [
467
- el('span', { class: 'badge ok' }, ['FACT']),
468
- el('span', { class: 'small muted' }, [
469
- 'Any subset of an n‑set corresponds to a unique 0/1 choice per element ⇒ 2^n subsets.',
470
- ]),
471
- ]),
472
- );
473
-
474
- checks.replaceChildren(...list);
475
- }
476
-
477
- function evaluate() {
478
- const nVal = toBig(document.getElementById('nInput').value.trim());
479
- if (!isNonNegInt(nVal)) {
480
- document.getElementById('answer').textContent = '—';
481
- document.getElementById('sumRow').textContent = '—';
482
- document.getElementById('rowLen').textContent = '—';
483
- document.getElementById('row').replaceChildren();
484
- document
485
- .getElementById('checks')
486
- .replaceChildren(
487
- el('div', { class: 'term' }, [
488
- el('span', { class: 'badge fail' }, ['FAIL']),
489
- document.createTextNode(' n must be a non‑negative integer.'),
490
- ]),
491
- );
492
- return;
493
- }
494
- const n = nVal;
495
- const row = binomRow(n);
496
- const S = sumRow(row);
497
- const P = pow(2n, n);
498
-
499
- document.getElementById('answer').textContent = `B(${n}) = ${P.toString()}`;
500
- document.getElementById('sumRow').textContent = S.toString();
501
- document.getElementById('rowLen').textContent = `${row.length}`;
502
- renderChips(document.getElementById('row'), row);
503
- renderChecks(n, row, S, P);
504
- }
505
-
506
- document.getElementById('solve').onclick = evaluate;
507
- document.getElementById('clear').onclick = () => {
508
- document.getElementById('nInput').value = '';
509
- document.getElementById('answer').textContent = '—';
510
- document.getElementById('sumRow').textContent = '—';
511
- document.getElementById('rowLen').textContent = '—';
512
- document.getElementById('row').replaceChildren();
513
- document.getElementById('checks').replaceChildren();
514
- };
515
-
516
- // ---------- Preloaded harnesses (≥ 8 including one invalid) ----------
517
- const harnessList = [
518
- { n: 0, title: 'n = 0 ⇒ [1] and B(0)=1' },
519
- { n: 1, title: 'n = 1 ⇒ [1,1] and B(1)=2' },
520
- { n: 2, title: 'n = 2 ⇒ [1,2,1] and B(2)=4' },
521
- { n: 3, title: 'n = 3 ⇒ [1,3,3,1] and B(3)=8' },
522
- { n: 5, title: 'n = 5 ⇒ B(5)=32' },
523
- { n: 10, title: 'n = 10 ⇒ B(10)=1024' },
524
- { n: 20, title: 'n = 20 ⇒ B(20)=1,048,576' },
525
- { n: -1, title: 'Invalid (should fail): n = -1', negative: true },
526
- ];
527
-
528
- const harnessDiv = document.getElementById('harnesses');
529
-
530
- function makeHarnessCard(h) {
531
- const card = el('section', { class: 'card stack' });
532
- const head = el('div', { class: 'h-title' }, [
533
- el('div', {}, [el('strong', {}, [h.title])]),
534
- el('div', { class: 'small muted' }, ['Check (harness)']),
535
- ]);
536
- const kpis = el('div', { class: 'kpi' });
537
- const ans = el('div', { class: 'card' });
538
- ans.append(el('div', { class: 'k' }, ['Answer']), el('div', { class: 'v mono' }, ['—']));
539
- const closed = el('div', { class: 'card' });
540
- closed.append(el('div', { class: 'k' }, ['Closed form']), el('div', { class: 'v mono' }, ['B(n)=2^n']));
541
- const sumK = el('div', { class: 'card' });
542
- sumK.append(el('div', { class: 'k' }, ['Σ C(n,k)']), el('div', { class: 'v mono' }, ['—']));
543
- const len = el('div', { class: 'card' });
544
- len.append(el('div', { class: 'k' }, ['Row length']), el('div', { class: 'v mono' }, ['—']));
545
- kpis.append(ans, closed, sumK, len);
546
-
547
- const reason = el('p', { class: 'muted small' }, [
548
- 'Because (1+1)^n = Σ C(n,k) by the binomial theorem, setting x=y=1 yields B(n)=2^n; combinatorially, it counts all subsets.',
549
- ]);
550
- const checks = el('div', { class: 'list' });
551
- const run = el('button', { class: 'secondary' }, ['Run']);
552
-
553
- run.onclick = () => {
554
- const nBig = toBig(h.n);
555
- if (!isNonNegInt(nBig)) {
556
- ans.querySelector('.v').textContent = '—';
557
- sumK.querySelector('.v').textContent = '—';
558
- len.querySelector('.v').textContent = '—';
559
- checks.replaceChildren(
560
- el('div', { class: 'term' }, [
561
- el('span', { class: 'badge fail' }, ['FAIL']),
562
- document.createTextNode(' n must be a non‑negative integer.'),
563
- ]),
564
- );
565
- return;
566
- }
567
- const row = binomRow(nBig);
568
- const S = sumRow(row);
569
- const P = pow(2n, nBig);
570
- ans.querySelector('.v').textContent = `B(${nBig}) = ${P}`;
571
- sumK.querySelector('.v').textContent = S.toString();
572
- len.querySelector('.v').textContent = `${row.length}`;
573
-
574
- const list = [];
575
- const eq = S === P;
576
- list.push(
577
- el('div', { class: 'row' }, [
578
- el('span', { class: 'badge ' + (eq ? 'ok' : 'fail') }, [eq ? 'PASS' : 'FAIL']),
579
- document.createTextNode(' Equality '),
580
- el('span', { class: 'mono' }, ['Σ C(n,k) = 2^n']),
581
- ]),
582
- );
583
- const ends = row.length >= 1 && row[0] === 1n && row[row.length - 1] === 1n;
584
- list.push(
585
- el('div', { class: 'row' }, [
586
- el('span', { class: 'badge ' + (ends ? 'ok' : 'fail') }, [ends ? 'PASS' : 'FAIL']),
587
- el('span', { class: 'mono' }, ['C(n,0)=C(n,n)=1']),
588
- ]),
589
- );
590
- const sym = row.every((v, i) => v === row[row.length - 1 - i]);
591
- list.push(
592
- el('div', { class: 'row' }, [
593
- el('span', { class: 'badge ' + (sym ? 'ok' : 'fail') }, [sym ? 'PASS' : 'FAIL']),
594
- el('span', { class: 'mono' }, ['Symmetry C(n,k)=C(n,n−k)']),
595
- ]),
596
- );
597
- list.push(
598
- el('div', { class: 'row' }, [
599
- el('span', { class: 'badge ok' }, ['FACT']),
600
- el('span', { class: 'small muted' }, [`B(${nBig}) counts all 0/1 choices across ${nBig} elements.`]),
601
- ]),
602
- );
603
- checks.replaceChildren(...list);
604
- };
605
-
606
- if (h.negative) {
607
- const warn = el('div', { class: 'small muted' }, [
608
- 'This case is intentionally invalid and should report a failure.',
609
- ]);
610
- card.append(head, kpis, reason, warn, checks, run);
611
- } else {
612
- card.append(head, kpis, reason, checks, run);
613
- }
614
- return card;
615
- }
616
-
617
- harnessList.forEach((h) => harnessDiv.appendChild(makeHarnessCard(h)));
618
- document.getElementById('runAll').onclick = () => {
619
- const buttons = [...harnessDiv.querySelectorAll('button.secondary')];
620
- buttons.forEach((b) => b.click());
621
- };
622
- document.getElementById('clearHarness').onclick = () => {
623
- harnessDiv.querySelectorAll('.list').forEach((div) => div.replaceChildren());
624
- harnessDiv.querySelectorAll('.v').forEach((div) => (div.textContent = '—'));
625
- };
626
-
627
- // auto-evaluate initial n
628
- evaluate();
629
- </script>
630
- </body>
631
- </html>