eyeling 1.16.2 → 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 (51) hide show
  1. package/HANDBOOK.md +4 -0
  2. package/README.md +0 -1
  3. package/examples/ershov-mixed-computation.n3 +106 -0
  4. package/examples/output/ershov-mixed-computation.n3 +15 -0
  5. package/eyeling.js +510 -263
  6. package/lib/cli.js +22 -12
  7. package/lib/engine.js +488 -251
  8. package/package.json +2 -3
  9. package/arctifacts/README.md +0 -59
  10. package/arctifacts/ackermann.html +0 -678
  11. package/arctifacts/auroracare.html +0 -1297
  12. package/arctifacts/bike-trip.html +0 -752
  13. package/arctifacts/binomial-theorem.html +0 -631
  14. package/arctifacts/bmi.html +0 -511
  15. package/arctifacts/building-performance.html +0 -750
  16. package/arctifacts/clinical-care.html +0 -726
  17. package/arctifacts/collatz.html +0 -403
  18. package/arctifacts/complex.html +0 -321
  19. package/arctifacts/control-system.html +0 -482
  20. package/arctifacts/delfour.html +0 -849
  21. package/arctifacts/earthquake-epicenter.html +0 -982
  22. package/arctifacts/eco-route.html +0 -662
  23. package/arctifacts/euclid-infinitude.html +0 -564
  24. package/arctifacts/euler-identity.html +0 -667
  25. package/arctifacts/exoplanet-transit.html +0 -1000
  26. package/arctifacts/faltings-theorem.html +0 -1046
  27. package/arctifacts/fibonacci.html +0 -299
  28. package/arctifacts/fundamental-theorem-arithmetic.html +0 -398
  29. package/arctifacts/godel-numbering.html +0 -743
  30. package/arctifacts/gps-bike.html +0 -759
  31. package/arctifacts/gps-clinical-bench.html +0 -792
  32. package/arctifacts/graph-french.html +0 -449
  33. package/arctifacts/grass-molecular.html +0 -592
  34. package/arctifacts/group-theory.html +0 -740
  35. package/arctifacts/health-info.html +0 -833
  36. package/arctifacts/kaprekar-constant.html +0 -576
  37. package/arctifacts/lee.html +0 -805
  38. package/arctifacts/linked-lists.html +0 -502
  39. package/arctifacts/lldm.html +0 -612
  40. package/arctifacts/matrix-multiplication.html +0 -502
  41. package/arctifacts/matrix.html +0 -651
  42. package/arctifacts/newton-raphson.html +0 -944
  43. package/arctifacts/peano-factorial.html +0 -456
  44. package/arctifacts/pi.html +0 -363
  45. package/arctifacts/polynomial.html +0 -646
  46. package/arctifacts/prime.html +0 -366
  47. package/arctifacts/pythagorean-theorem.html +0 -468
  48. package/arctifacts/rest-path.html +0 -469
  49. package/arctifacts/roots-of-unity.html +0 -363
  50. package/arctifacts/turing.html +0 -409
  51. package/arctifacts/wind-turbines.html +0 -726
@@ -1,511 +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>BMI</title>
7
- <style>
8
- :root {
9
- --bg: #ffffff;
10
- --ink: #111827;
11
- --muted: #6b7280;
12
- --panel: #f8fafc;
13
- --border: #e5e7eb;
14
- --accent: #0ea5e9;
15
- --good: #16a34a;
16
- --warn: #d97706;
17
- --bad: #dc2626;
18
- --mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', monospace;
19
- --ui:
20
- system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', 'Apple Color Emoji',
21
- 'Segoe UI Emoji';
22
- }
23
- html,
24
- body {
25
- height: 100%;
26
- }
27
- body {
28
- margin: 0;
29
- background: var(--bg);
30
- color: var(--ink);
31
- font: 15px/1.55 var(--ui);
32
- }
33
- .wrap {
34
- max-width: 980px;
35
- margin: 36px auto;
36
- padding: 0 16px;
37
- }
38
- header {
39
- display: flex;
40
- align-items: center;
41
- justify-content: space-between;
42
- margin-bottom: 16px;
43
- }
44
- h1 {
45
- font-size: 22px;
46
- margin: 0;
47
- letter-spacing: 0.2px;
48
- }
49
- .pill {
50
- display: inline-flex;
51
- align-items: center;
52
- gap: 8px;
53
- padding: 6px 10px;
54
- border: 1px solid var(--border);
55
- border-radius: 999px;
56
- color: var(--muted);
57
- background: #fff;
58
- }
59
- .row {
60
- display: flex;
61
- flex-direction: column;
62
- gap: 16px;
63
- }
64
- .card {
65
- background: var(--panel);
66
- border: 1px solid var(--border);
67
- border-radius: 14px;
68
- overflow: hidden;
69
- }
70
- .head {
71
- display: flex;
72
- align-items: center;
73
- justify-content: space-between;
74
- padding: 10px 12px;
75
- border-bottom: 1px solid var(--border);
76
- }
77
- .head h2 {
78
- font-size: 13px;
79
- text-transform: uppercase;
80
- letter-spacing: 0.08em;
81
- color: var(--muted);
82
- margin: 0;
83
- }
84
- .body {
85
- padding: 12px;
86
- }
87
- pre {
88
- white-space: pre-wrap;
89
- background: #fff;
90
- border: 1px solid var(--border);
91
- border-radius: 10px;
92
- padding: 12px;
93
- overflow: auto;
94
- font-family: var(--mono);
95
- font-size: 13px;
96
- }
97
- .bar {
98
- display: flex;
99
- gap: 8px;
100
- margin-top: 10px;
101
- flex-wrap: wrap;
102
- }
103
- button {
104
- all: unset;
105
- background: #fff;
106
- border: 1px solid var(--border);
107
- padding: 8px 12px;
108
- border-radius: 10px;
109
- cursor: pointer;
110
- }
111
- button:hover {
112
- border-color: #cbd5e1;
113
- }
114
- .small {
115
- color: var(--muted);
116
- text-decoration: none;
117
- }
118
- .accent {
119
- color: var(--accent);
120
- }
121
- .grid {
122
- display: grid;
123
- grid-template-columns: repeat(3, minmax(0, 1fr));
124
- gap: 8px;
125
- }
126
- label {
127
- font-size: 12px;
128
- color: var(--muted);
129
- }
130
- input {
131
- width: 100%;
132
- box-sizing: border-box;
133
- padding: 8px;
134
- border: 1px solid var(--border);
135
- border-radius: 10px;
136
- background: #fff;
137
- font-family: var(--mono);
138
- font-size: 12px;
139
- }
140
- select {
141
- width: 100%;
142
- box-sizing: border-box;
143
- padding: 8px;
144
- border: 1px solid var(--border);
145
- border-radius: 10px;
146
- background: #fff;
147
- font-family: var(--mono);
148
- font-size: 12px;
149
- }
150
- /* ARC v2 (Cards) */
151
- .arc-grid {
152
- display: flex;
153
- flex-direction: column;
154
- gap: 12px;
155
- }
156
- .arc-card {
157
- background: #fff;
158
- border: 1px solid var(--border);
159
- border-radius: 14px;
160
- overflow: hidden;
161
- }
162
- .arc-card .ac-head {
163
- display: flex;
164
- align-items: center;
165
- gap: 8px;
166
- padding: 10px 12px;
167
- border-bottom: 1px solid var(--border);
168
- font-size: 12px;
169
- letter-spacing: 0.08em;
170
- text-transform: uppercase;
171
- color: var(--muted);
172
- }
173
- .arc-card .ac-body {
174
- padding: 12px;
175
- }
176
- .arc-card pre {
177
- margin: 0;
178
- white-space: pre-wrap;
179
- background: #fff;
180
- border: 1px solid #eef2f7;
181
- border-radius: 10px;
182
- padding: 10px;
183
- font-family: var(--mono);
184
- font-size: 13px;
185
- }
186
- .arc-card.answer {
187
- border-left: 4px solid #10b981;
188
- }
189
- .arc-card.reason {
190
- border-left: 4px solid #3b82f6;
191
- }
192
- .arc-card.check {
193
- border-left: 4px solid #f59e0b;
194
- }
195
- .toolbar {
196
- display: flex;
197
- gap: 8px;
198
- align-items: center;
199
- }
200
- .badge {
201
- display: inline-block;
202
- padding: 2px 8px;
203
- border-radius: 999px;
204
- font: 12px/1 var(--ui);
205
- border: 1px solid var(--border);
206
- margin-left: 8px;
207
- }
208
- .b-good {
209
- color: var(--good);
210
- border-color: #bbf7d0;
211
- background: #f0fdf4;
212
- }
213
- .b-warn {
214
- color: var(--warn);
215
- border-color: #fde68a;
216
- background: #fffbeb;
217
- }
218
- .b-bad {
219
- color: var(--bad);
220
- border-color: #fecaca;
221
- background: #fff1f2;
222
- }
223
- </style>
224
- </head>
225
- <body>
226
- <div class="wrap">
227
- <header>
228
- <h1>BMI</h1>
229
- <div class="pill">Self‑contained • No deps</div>
230
- </header>
231
-
232
- <div class="card" style="margin-bottom: 16px">
233
- <div class="body">
234
- <p>
235
- <strong>What this is?</strong> A self‑contained, browser‑only <em>ARC harness</em> for body mass index
236
- (BMI). Enter height and weight (metric or US units), then press <em>Run</em>. The page prints a step‑by‑step
237
- Trace and an ARC report (<em>Answer • Reason • Check</em>), including category and a healthy‑range weight
238
- band for the given height.
239
- </p>
240
- <p class="small">For reproducibility and documentation only; not medical advice.</p>
241
- </div>
242
- </div>
243
-
244
- <div class="row">
245
- <div class="card">
246
- <div class="head">
247
- <h2>Inputs</h2>
248
- <a
249
- href="#"
250
- class="small"
251
- onclick="
252
- demo();
253
- run();
254
- return false;
255
- "
256
- >Demo &amp; Run</a
257
- >
258
- </div>
259
- <div class="body">
260
- <div class="grid">
261
- <div>
262
- <label>Unit system</label>
263
- <select id="unit" onchange="syncUnits()">
264
- <option value="metric">Metric (kg, cm)</option>
265
- <option value="us">US (lb, ft+in)</option>
266
- </select>
267
- </div>
268
- <div>
269
- <label>Weight (<span id="wUnit">kg</span>)</label>
270
- <input id="weight" type="number" step="0.01" />
271
- </div>
272
- <div>
273
- <label>Height (<span id="hUnit">cm</span>)</label>
274
- <input id="height" type="number" step="0.01" />
275
- </div>
276
- </div>
277
- <div class="bar">
278
- <button onclick="run()">▶ Run</button>
279
- <a
280
- href="#"
281
- class="small"
282
- onclick="
283
- copyBoth();
284
- return false;
285
- "
286
- >Copy both outputs</a
287
- >
288
- </div>
289
- </div>
290
- </div>
291
-
292
- <div class="card">
293
- <div class="head">
294
- <h2>Trace</h2>
295
- <button onclick="downloadText('bmi_trace.txt', document.getElementById('trace').textContent)">
296
- ⬇ Export .txt
297
- </button>
298
- </div>
299
- <div class="body"><pre id="trace">(no run yet)</pre></div>
300
- </div>
301
-
302
- <div class="card">
303
- <div class="head">
304
- <h2>ARC Output</h2>
305
- <div class="toolbar">
306
- <button onclick="toggleArcStyle()" id="styleBtn">Style: Cards</button>
307
- <button onclick="downloadARC()">⬇ Export .txt</button>
308
- </div>
309
- </div>
310
- <div class="body">
311
- <div id="arc-cards" class="arc-grid">
312
- <div class="arc-card answer">
313
- <div class="ac-head">Answer <span id="catBadge" class="badge"></span></div>
314
- <div class="ac-body"><pre id="arc_ans">(no run yet)</pre></div>
315
- </div>
316
- <div class="arc-card reason">
317
- <div class="ac-head">Reason why</div>
318
- <div class="ac-body"><pre id="arc_reason">(no run yet)</pre></div>
319
- </div>
320
- <div class="arc-card check">
321
- <div class="ac-head">Check (harness)</div>
322
- <div class="ac-body"><pre id="arc_check">(no run yet)</pre></div>
323
- </div>
324
- </div>
325
- <pre id="arc" style="display: none">(no run yet)</pre>
326
- </div>
327
- </div>
328
- </div>
329
- </div>
330
-
331
- <script>
332
- // ---------- units & helpers ----------
333
- function syncUnits() {
334
- const u = document.getElementById('unit').value;
335
- document.getElementById('wUnit').textContent = u === 'metric' ? 'kg' : 'lb';
336
- document.getElementById('hUnit').textContent = u === 'metric' ? 'cm' : 'in';
337
- }
338
- function demo() {
339
- // A typical adult example ~ BMI ~ 22.7
340
- document.getElementById('unit').value = 'metric';
341
- syncUnits();
342
- document.getElementById('weight').value = 72.0; // kg
343
- document.getElementById('height').value = 178.0; // cm
344
- }
345
- function kg_from(weight, unit) {
346
- return unit === 'metric' ? weight : weight * 0.45359237;
347
- }
348
- function m_from(height, unit) {
349
- return unit === 'metric' ? height / 100.0 : height * 0.0254;
350
- }
351
- function round(n, d = 2) {
352
- return Number(n.toFixed(d));
353
- }
354
-
355
- const WHO = [
356
- { name: 'Underweight', min: null, max: 18.5 },
357
- { name: 'Normal', min: 18.5, max: 25.0 },
358
- { name: 'Overweight', min: 25.0, max: 30.0 },
359
- { name: 'Obesity I', min: 30.0, max: 35.0 },
360
- { name: 'Obesity II', min: 35.0, max: 40.0 },
361
- { name: 'Obesity III', min: 40.0, max: null },
362
- ];
363
- function classify(bmi) {
364
- for (const c of WHO) {
365
- const ge = c.min === null ? true : bmi >= c.min;
366
- const lt = c.max === null ? true : bmi < c.max;
367
- if (ge && lt) return c;
368
- }
369
- return WHO[WHO.length - 1];
370
- }
371
- function healthy_weight_range_for_height_m(m) {
372
- // BMI 18.5..24.9 (upper bound <25)
373
- const min = 18.5 * m * m;
374
- const max = 24.9 * m * m;
375
- return [min, max];
376
- }
377
-
378
- // ---------- ARC run ----------
379
- function run() {
380
- const unit = document.getElementById('unit').value;
381
- const w = parseFloat(document.getElementById('weight').value);
382
- const h = parseFloat(document.getElementById('height').value);
383
- if (!Number.isFinite(w) || !Number.isFinite(h) || w <= 0 || h <= 0) {
384
- document.getElementById('trace').textContent =
385
- 'Please fill weight and height with positive numbers (or use Demo).';
386
- ['arc', 'arc_ans', 'arc_reason', 'arc_check'].forEach(
387
- (id) => (document.getElementById(id).textContent = '(no run)'),
388
- );
389
- return;
390
- }
391
-
392
- const kg = kg_from(w, unit);
393
- const m = m_from(h, unit);
394
- const bmi = kg / (m * m);
395
- const cat = classify(bmi);
396
- const [hw_min, hw_max] = healthy_weight_range_for_height_m(m);
397
-
398
- // Trace
399
- const T = [];
400
- T.push(
401
- `Step 01: Normalize units → kg = ${unit === 'metric' ? w : round(kg, 2)} ${unit === 'metric' ? '(metric input)' : '(from lb)'}, m = ${unit === 'metric' ? round(m, 2) : round(m, 2)} ${unit === 'metric' ? '(from cm)' : '(from in)'}`,
402
- );
403
- T.push(`Step 02: BMI = weight_kg / (height_m)^2 = ${round(kg, 2)} / (${round(m, 2)}^2) = ${round(bmi, 2)}`);
404
- T.push(`Step 03: Category = ${cat.name} (WHO thresholds)`);
405
- T.push(
406
- `Step 04: Healthy weight range at this height (BMI 18.5–24.9): ${round(hw_min, 1)} kg .. ${round(hw_max, 1)} kg`,
407
- );
408
- document.getElementById('trace').textContent = T.join('\n');
409
-
410
- // ARC sections
411
- const A = [];
412
- const R = [];
413
- const C = [];
414
- A.push(`BMI = ${round(bmi, 2)}`);
415
- A.push(`Category = ${cat.name}`);
416
- A.push(
417
- `At height ${round(m * 100, 0)} cm, a “healthy range” is ≈ ${round(hw_min, 1)}–${round(hw_max, 1)} kg (BMI 18.5–24.9)`,
418
- );
419
-
420
- R.push('BMI is defined as weight (kg) divided by height (m) squared.');
421
- R.push('We normalize the inputs to SI units (kg, m), compute BMI, then map it to WHO adult categories.');
422
- R.push('Boundaries are interpreted as half-open intervals:');
423
- R.push(' Underweight: BMI < 18.5');
424
- R.push(' Normal: 18.5 ≤ BMI < 25');
425
- R.push(' Overweight: 25 ≤ BMI < 30');
426
- R.push(' Obesity I: 30 ≤ BMI < 35; Obesity II: 35 ≤ BMI < 40; Obesity III: BMI ≥ 40');
427
- R.push(
428
- 'We also translate the healthy BMI band (18.5..24.9) into a corresponding weight range for the given height.',
429
- );
430
-
431
- const ok_eq_185 = classify(18.5).name === 'Normal';
432
- const ok_lt_185 = classify(18.49).name === 'Underweight';
433
- const ok_eq_25 = classify(25.0).name === 'Overweight';
434
- const ok_eq_30 = classify(30.0).name === 'Obesity I';
435
- const ok_mon =
436
- classify(22.0).name === 'Normal' &&
437
- classify(27.0).name === 'Overweight' &&
438
- classify(41.0).name.startsWith('Obesity');
439
- C.push(
440
- `Boundary checks: BMI=18.49 → Underweight (${ok_lt_185}), 18.5 → Normal (${ok_eq_185}), 25.0 → Overweight (${ok_eq_25}), 30.0 → Obesity I (${ok_eq_30})`,
441
- );
442
- C.push(`Monotonicity example (22→Normal, 27→Overweight, 41→Obesity*): ${ok_mon}`);
443
-
444
- // Populate
445
- document.getElementById('arc_ans').textContent = A.join('\n');
446
- document.getElementById('arc_reason').textContent = R.join('\n');
447
- document.getElementById('arc_check').textContent = C.join('\n');
448
-
449
- // Badge
450
- const b = document.getElementById('catBadge');
451
- b.textContent = cat.name;
452
- b.className =
453
- 'badge ' + (cat.name === 'Normal' ? 'b-good' : cat.name.startsWith('Obesity') ? 'b-bad' : 'b-warn');
454
-
455
- // Combined plain text
456
- const combined = [
457
- 'Answer',
458
- '------',
459
- ...A,
460
- '',
461
- 'Reason why',
462
- '----------',
463
- ...R,
464
- '',
465
- 'Check (harness)',
466
- '---------------',
467
- ...C,
468
- ].join('\n');
469
- document.getElementById('arc').textContent = combined;
470
- }
471
-
472
- function toggleArcStyle() {
473
- const pre = document.getElementById('arc');
474
- const cards = document.getElementById('arc-cards');
475
- const btn = document.getElementById('styleBtn');
476
- const showingCards = cards.style.display !== 'none';
477
- if (showingCards) {
478
- cards.style.display = 'none';
479
- pre.style.display = 'block';
480
- btn.textContent = 'Style: Plain';
481
- } else {
482
- cards.style.display = 'block';
483
- pre.style.display = 'none';
484
- btn.textContent = 'Style: Cards';
485
- }
486
- }
487
- function downloadText(name, text) {
488
- const blob = new Blob([text], { type: 'text/plain' });
489
- const a = document.createElement('a');
490
- a.href = URL.createObjectURL(blob);
491
- a.download = name;
492
- document.body.appendChild(a);
493
- a.click();
494
- a.remove();
495
- }
496
- function downloadARC() {
497
- const text = document.getElementById('arc').textContent;
498
- downloadText('bmi_arc.txt', text);
499
- }
500
- function copyBoth() {
501
- const text = document.getElementById('trace').textContent + '\n\n' + document.getElementById('arc').textContent;
502
- navigator.clipboard.writeText(text);
503
- }
504
-
505
- // bootstrap
506
- syncUnits();
507
- demo();
508
- run();
509
- </script>
510
- </body>
511
- </html>