@jjlmoya/utils-science 1.38.0 → 1.39.0

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 (37) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +2 -1
  3. package/src/entries.ts +3 -1
  4. package/src/index.ts +1 -0
  5. package/src/tests/locale_completeness.test.ts +2 -2
  6. package/src/tests/tool_validation.test.ts +2 -2
  7. package/src/tool/conway-life-rule-lab/bibliography.astro +14 -0
  8. package/src/tool/conway-life-rule-lab/bibliography.ts +16 -0
  9. package/src/tool/conway-life-rule-lab/component.astro +132 -0
  10. package/src/tool/conway-life-rule-lab/conway-life-rule-lab.css +603 -0
  11. package/src/tool/conway-life-rule-lab/entry.ts +26 -0
  12. package/src/tool/conway-life-rule-lab/i18n/de.ts +50 -0
  13. package/src/tool/conway-life-rule-lab/i18n/en.ts +174 -0
  14. package/src/tool/conway-life-rule-lab/i18n/es.ts +50 -0
  15. package/src/tool/conway-life-rule-lab/i18n/fr.ts +50 -0
  16. package/src/tool/conway-life-rule-lab/i18n/id.ts +50 -0
  17. package/src/tool/conway-life-rule-lab/i18n/it.ts +50 -0
  18. package/src/tool/conway-life-rule-lab/i18n/ja.ts +50 -0
  19. package/src/tool/conway-life-rule-lab/i18n/ko.ts +50 -0
  20. package/src/tool/conway-life-rule-lab/i18n/nl.ts +50 -0
  21. package/src/tool/conway-life-rule-lab/i18n/pl.ts +50 -0
  22. package/src/tool/conway-life-rule-lab/i18n/pt.ts +50 -0
  23. package/src/tool/conway-life-rule-lab/i18n/ru.ts +50 -0
  24. package/src/tool/conway-life-rule-lab/i18n/sv.ts +50 -0
  25. package/src/tool/conway-life-rule-lab/i18n/tr.ts +50 -0
  26. package/src/tool/conway-life-rule-lab/i18n/zh.ts +50 -0
  27. package/src/tool/conway-life-rule-lab/index.ts +11 -0
  28. package/src/tool/conway-life-rule-lab/logic/LifeAchievements.ts +85 -0
  29. package/src/tool/conway-life-rule-lab/logic/LifeCanvasRenderer.ts +104 -0
  30. package/src/tool/conway-life-rule-lab/logic/LifeLabDom.ts +55 -0
  31. package/src/tool/conway-life-rule-lab/logic/LifeLabRuntime.ts +253 -0
  32. package/src/tool/conway-life-rule-lab/logic/LifePatterns.ts +35 -0
  33. package/src/tool/conway-life-rule-lab/logic/LifeRules.ts +60 -0
  34. package/src/tool/conway-life-rule-lab/logic/LifeUniverse.ts +165 -0
  35. package/src/tool/conway-life-rule-lab/logic.ts +6 -0
  36. package/src/tool/conway-life-rule-lab/seo.astro +15 -0
  37. package/src/tools.ts +2 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jjlmoya/utils-science",
3
- "version": "1.38.0",
3
+ "version": "1.39.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -20,10 +20,11 @@ import { threeBodyProblem } from '../tool/three-body-problem/index';
20
20
  import { rocheLimitSatelliteDisruption } from '../tool/roche-limit-satellite-disruption/index';
21
21
  import { dysonSphereEnergyCapture } from '../tool/dyson-sphere-energy-capture/index';
22
22
  import { globalAlbedoSnowballSimulator } from '../tool/global-albedo-snowball-simulator/index';
23
+ import { conwayLifeRuleLab } from '../tool/conway-life-rule-lab/index';
23
24
 
24
25
  export const scienceCategory: ScienceCategoryEntry = {
25
26
  icon: 'mdi:flask',
26
- tools: [colonyCounter, asteroidImpact, microwaveDetector, simulationProbability, cellularRenewal, cosmicInflation, temperatureTimeline, lorenzAttractor, stellarHabitabilityZone, radioactiveDecay, naturalSelectionDrift, entropySecondLaw, doubleSlitDecoherence, phaseDiagramCriticalPoints, twinParadoxVisualizer, mandelbrotFractal, planetAtmosphereSurvival, threeBodyProblem, rocheLimitSatelliteDisruption, dysonSphereEnergyCapture, globalAlbedoSnowballSimulator],
27
+ tools: [colonyCounter, asteroidImpact, microwaveDetector, simulationProbability, cellularRenewal, cosmicInflation, temperatureTimeline, lorenzAttractor, stellarHabitabilityZone, radioactiveDecay, naturalSelectionDrift, entropySecondLaw, doubleSlitDecoherence, phaseDiagramCriticalPoints, twinParadoxVisualizer, mandelbrotFractal, planetAtmosphereSurvival, threeBodyProblem, rocheLimitSatelliteDisruption, dysonSphereEnergyCapture, globalAlbedoSnowballSimulator, conwayLifeRuleLab],
27
28
  i18n: {
28
29
  es: () => import('./i18n/es').then((m) => m.content),
29
30
  en: () => import('./i18n/en').then((m) => m.content),
package/src/entries.ts CHANGED
@@ -20,6 +20,7 @@ export { threeBodyProblem } from './tool/three-body-problem/entry';
20
20
  export { rocheLimitSatelliteDisruption } from './tool/roche-limit-satellite-disruption/entry';
21
21
  export { dysonSphereEnergyCapture } from './tool/dyson-sphere-energy-capture/entry';
22
22
  export { globalAlbedoSnowballSimulator } from './tool/global-albedo-snowball-simulator/entry';
23
+ export { conwayLifeRuleLab } from './tool/conway-life-rule-lab/entry';
23
24
  export { scienceCategory } from './category';
24
25
  import { asteroidImpact } from './tool/asteroid-impact/entry';
25
26
  import { cellularRenewal } from './tool/cellular-renewal/entry';
@@ -42,4 +43,5 @@ import { threeBodyProblem } from './tool/three-body-problem/entry';
42
43
  import { rocheLimitSatelliteDisruption } from './tool/roche-limit-satellite-disruption/entry';
43
44
  import { dysonSphereEnergyCapture } from './tool/dyson-sphere-energy-capture/entry';
44
45
  import { globalAlbedoSnowballSimulator } from './tool/global-albedo-snowball-simulator/entry';
45
- export const ALL_ENTRIES = [asteroidImpact, cellularRenewal, colonyCounter, microwaveDetector, simulationProbability, cosmicInflation, temperatureTimeline, lorenzAttractor, stellarHabitabilityZone, radioactiveDecay, naturalSelectionDrift, entropySecondLaw, doubleSlitDecoherence, phaseDiagramCriticalPoints, twinParadoxVisualizer, mandelbrotFractal, planetAtmosphereSurvival, threeBodyProblem, rocheLimitSatelliteDisruption, dysonSphereEnergyCapture, globalAlbedoSnowballSimulator];
46
+ import { conwayLifeRuleLab } from './tool/conway-life-rule-lab/entry';
47
+ export const ALL_ENTRIES = [asteroidImpact, cellularRenewal, colonyCounter, microwaveDetector, simulationProbability, cosmicInflation, temperatureTimeline, lorenzAttractor, stellarHabitabilityZone, radioactiveDecay, naturalSelectionDrift, entropySecondLaw, doubleSlitDecoherence, phaseDiagramCriticalPoints, twinParadoxVisualizer, mandelbrotFractal, planetAtmosphereSurvival, threeBodyProblem, rocheLimitSatelliteDisruption, dysonSphereEnergyCapture, globalAlbedoSnowballSimulator, conwayLifeRuleLab];
package/src/index.ts CHANGED
@@ -21,6 +21,7 @@ export { THREE_BODY_PROBLEM_TOOL } from './tool/three-body-problem/index';
21
21
  export { ROCHE_LIMIT_SATELLITE_DISRUPTION_TOOL } from './tool/roche-limit-satellite-disruption/index';
22
22
  export { DYSON_SPHERE_ENERGY_CAPTURE_TOOL } from './tool/dyson-sphere-energy-capture/index';
23
23
  export { GLOBAL_ALBEDO_SNOWBALL_SIMULATOR_TOOL } from './tool/global-albedo-snowball-simulator/index';
24
+ export { CONWAY_LIFE_RULE_LAB_TOOL } from './tool/conway-life-rule-lab/index';
24
25
 
25
26
  export type {
26
27
  KnownLocale,
@@ -18,7 +18,7 @@ describe('Locale Completeness Validation', () => {
18
18
  });
19
19
  });
20
20
 
21
- it('all 20 tools registered', () => {
22
- expect(ALL_TOOLS.length).toBe(21);
21
+ it('all 22 tools registered', () => {
22
+ expect(ALL_TOOLS.length).toBe(22);
23
23
  });
24
24
  });
@@ -4,8 +4,8 @@ import { scienceCategory } from '../data';
4
4
 
5
5
  describe('Tool Validation Suite', () => {
6
6
  describe('Library Registration', () => {
7
- it('should have 20 tools in ALL_TOOLS', () => {
8
- expect(ALL_TOOLS.length).toBe(21);
7
+ it('should have 22 tools in ALL_TOOLS', () => {
8
+ expect(ALL_TOOLS.length).toBe(22);
9
9
  });
10
10
 
11
11
  it('scienceCategory should be defined', () => {
@@ -0,0 +1,14 @@
1
+ ---
2
+ import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared';
3
+ import { conwayLifeRuleLab } from './index';
4
+ import type { KnownLocale } from '../../types';
5
+
6
+ interface Props {
7
+ locale?: KnownLocale;
8
+ }
9
+
10
+ const { locale = 'en' } = Astro.props;
11
+ const content = await conwayLifeRuleLab.i18n[locale]?.();
12
+ ---
13
+
14
+ {content && <SharedBibliography links={content.bibliography} />}
@@ -0,0 +1,16 @@
1
+ import type { BibliographyEntry } from '../../types';
2
+
3
+ export const bibliography: BibliographyEntry[] = [
4
+ {
5
+ name: 'Martin Gardner, Mathematical Games: The fantastic combinations of John Conway\'s new solitaire game "life"',
6
+ url: 'https://web.stanford.edu/class/sts145/Library/life.pdf',
7
+ },
8
+ {
9
+ name: 'LifeWiki: Conway\'s Game of Life',
10
+ url: 'https://conwaylife.com/wiki/Conway%27s_Game_of_Life',
11
+ },
12
+ {
13
+ name: 'Golly: A cross-platform cellular automata explorer',
14
+ url: 'https://golly.sourceforge.io/',
15
+ },
16
+ ];
@@ -0,0 +1,132 @@
1
+ ---
2
+ import './conway-life-rule-lab.css';
3
+
4
+ interface Props {
5
+ ui: Record<string, string>;
6
+ }
7
+
8
+ const { ui } = Astro.props;
9
+ ---
10
+
11
+ <div
12
+ class="life-lab-root"
13
+ id="life-lab-root"
14
+ data-pause={ui.pause}
15
+ data-status-frozen={ui.statusFrozen}
16
+ data-status-growing={ui.statusGrowing}
17
+ data-status-fading={ui.statusFading}
18
+ data-status-chaotic={ui.statusChaotic}
19
+ data-invalid-rule={ui.invalidRule}
20
+ data-pattern-glider={ui.patternGlider}
21
+ data-pattern-gosper={ui.patternGosper}
22
+ data-pattern-pulsar={ui.patternPulsar}
23
+ data-pattern-r-pentomino={ui.patternRPentomino}
24
+ data-achievement-pulsar={ui.achievementPulsar}
25
+ data-achievement-immortal={ui.achievementImmortal}
26
+ data-achievement-big-bang={ui.achievementBigBang}
27
+ >
28
+ <section class="life-lab-board-shell" aria-label={ui.boardLabel}>
29
+ <div class="life-lab-board-toolbar">
30
+ <button id="life-lab-play" class="life-lab-icon-button life-lab-play-button" type="button" aria-label={ui.play}>
31
+ <span class="life-lab-sr-only">{ui.play}</span>
32
+ <span class="life-lab-icon life-lab-icon-play" aria-hidden="true"></span>
33
+ </button>
34
+ <button id="life-lab-step" class="life-lab-icon-button" type="button" aria-label={ui.step}>
35
+ <span class="life-lab-sr-only">{ui.step}</span>
36
+ <span class="life-lab-icon life-lab-icon-step" aria-hidden="true"></span>
37
+ </button>
38
+ <button id="life-lab-clear" class="life-lab-icon-button" type="button" aria-label={ui.clear}>
39
+ <span class="life-lab-sr-only">{ui.clear}</span>
40
+ <span class="life-lab-icon life-lab-icon-clear" aria-hidden="true"></span>
41
+ </button>
42
+ </div>
43
+ <canvas id="life-lab-canvas" class="life-lab-canvas"></canvas>
44
+ <div class="life-lab-signal">
45
+ <span>{ui.colonyStatus}</span>
46
+ <strong id="life-lab-status">{ui.statusFrozen}</strong>
47
+ </div>
48
+ </section>
49
+
50
+ <section class="life-lab-console">
51
+ <div class="life-lab-readouts">
52
+ <div class="life-lab-readout life-lab-readout-main">
53
+ <span>{ui.generation}</span>
54
+ <strong id="life-lab-generation">0</strong>
55
+ </div>
56
+ <div class="life-lab-readout">
57
+ <span>{ui.population}</span>
58
+ <strong id="life-lab-population">0</strong>
59
+ </div>
60
+ <div class="life-lab-readout">
61
+ <span>{ui.density}</span>
62
+ <strong id="life-lab-density">0%</strong>
63
+ </div>
64
+ <div class="life-lab-readout">
65
+ <span>{ui.stability}</span>
66
+ <strong id="life-lab-stability">100%</strong>
67
+ </div>
68
+ <div class="life-lab-readout">
69
+ <span>{ui.births}</span>
70
+ <strong id="life-lab-births">0</strong>
71
+ </div>
72
+ <div class="life-lab-readout">
73
+ <span>{ui.deaths}</span>
74
+ <strong id="life-lab-deaths">0</strong>
75
+ </div>
76
+ </div>
77
+
78
+ <div class="life-lab-achievements" aria-label={ui.achievementsLabel}>
79
+ <span class="life-lab-achievements-label">{ui.achievementsLabel}</span>
80
+ <div class="life-lab-achievement" id="life-lab-achievement-pulsar">
81
+ <strong>{ui.achievementPulsar}</strong>
82
+ <span>{ui.achievementPulsarDescription}</span>
83
+ </div>
84
+ <div class="life-lab-achievement" id="life-lab-achievement-immortal">
85
+ <strong>{ui.achievementImmortal}</strong>
86
+ <span>{ui.achievementImmortalDescription}</span>
87
+ </div>
88
+ <div class="life-lab-achievement" id="life-lab-achievement-big-bang">
89
+ <strong>{ui.achievementBigBang}</strong>
90
+ <span>{ui.achievementBigBangDescription}</span>
91
+ </div>
92
+ </div>
93
+
94
+ <div class="life-lab-rule-deck" aria-label={ui.ruleHelp}>
95
+ <button class="life-lab-rule-preset active" type="button" data-rule="B3/S23">{ui.presetClassic}</button>
96
+ <button class="life-lab-rule-preset" type="button" data-rule="B36/S23">{ui.presetHighlife}</button>
97
+ <button class="life-lab-rule-preset" type="button" data-rule="B2/S">{ui.presetSeeds}</button>
98
+ <button class="life-lab-rule-preset" type="button" data-rule="B3678/S34678">{ui.presetDayNight}</button>
99
+ </div>
100
+
101
+ <div class="life-lab-controls">
102
+ <label class="life-lab-control life-lab-control-wide">
103
+ <span>{ui.ruleLabel}</span>
104
+ <input id="life-lab-rule" type="text" value="B3/S23" spellcheck="false" />
105
+ </label>
106
+ <label class="life-lab-control">
107
+ <span>{ui.speedLabel}</span>
108
+ <input id="life-lab-speed" type="range" min="2" max="30" value="10" step="1" />
109
+ </label>
110
+ <label class="life-lab-control">
111
+ <span>{ui.densityLabel}</span>
112
+ <input id="life-lab-seed-density" type="range" min="5" max="55" value="28" step="1" />
113
+ </label>
114
+ <label class="life-lab-control">
115
+ <span>{ui.patternLabel}</span>
116
+ <span class="life-lab-select-shell">
117
+ <select id="life-lab-pattern"></select>
118
+ </span>
119
+ </label>
120
+ <button id="life-lab-place-pattern" class="life-lab-command" type="button">{ui.placePattern}</button>
121
+ <button id="life-lab-randomize" class="life-lab-command life-lab-command-warm" type="button">{ui.randomize}</button>
122
+ </div>
123
+ </section>
124
+ </div>
125
+
126
+ <script>
127
+ import { startLifeLab } from './logic/LifeLabRuntime';
128
+
129
+ const root = document.getElementById('life-lab-root');
130
+ if (root) startLifeLab(root);
131
+ </script>
132
+