@jjlmoya/utils-science 1.47.0 → 1.49.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 (98) hide show
  1. package/package.json +2 -2
  2. package/src/category/index.ts +27 -27
  3. package/src/tests/seo_parity.test.ts +60 -0
  4. package/src/tests/translation_copy.test.ts +122 -0
  5. package/src/tool/black-hole-event-horizon-simulator/i18n/de.ts +79 -4
  6. package/src/tool/black-hole-event-horizon-simulator/i18n/fr.ts +86 -11
  7. package/src/tool/black-hole-event-horizon-simulator/i18n/it.ts +86 -11
  8. package/src/tool/black-hole-event-horizon-simulator/i18n/ja.ts +85 -10
  9. package/src/tool/black-hole-event-horizon-simulator/i18n/nl.ts +87 -12
  10. package/src/tool/black-hole-event-horizon-simulator/i18n/pt.ts +85 -10
  11. package/src/tool/black-hole-event-horizon-simulator/i18n/sv.ts +85 -10
  12. package/src/tool/black-hole-event-horizon-simulator/i18n/tr.ts +85 -11
  13. package/src/tool/black-hole-event-horizon-simulator/i18n/zh.ts +87 -12
  14. package/src/tool/conway-life-rule-lab/i18n/de.ts +46 -6
  15. package/src/tool/conway-life-rule-lab/i18n/es.ts +46 -6
  16. package/src/tool/conway-life-rule-lab/i18n/fr.ts +46 -6
  17. package/src/tool/conway-life-rule-lab/i18n/id.ts +46 -6
  18. package/src/tool/conway-life-rule-lab/i18n/it.ts +46 -6
  19. package/src/tool/conway-life-rule-lab/i18n/ja.ts +46 -6
  20. package/src/tool/conway-life-rule-lab/i18n/ko.ts +46 -6
  21. package/src/tool/conway-life-rule-lab/i18n/nl.ts +46 -6
  22. package/src/tool/conway-life-rule-lab/i18n/pl.ts +46 -6
  23. package/src/tool/conway-life-rule-lab/i18n/pt.ts +46 -6
  24. package/src/tool/conway-life-rule-lab/i18n/ru.ts +49 -9
  25. package/src/tool/conway-life-rule-lab/i18n/sv.ts +46 -6
  26. package/src/tool/conway-life-rule-lab/i18n/tr.ts +46 -6
  27. package/src/tool/conway-life-rule-lab/i18n/zh.ts +46 -6
  28. package/src/tool/cosmic-inflation/i18n/ru.ts +30 -4
  29. package/src/tool/double-slit-decoherence/i18n/fr.ts +48 -4
  30. package/src/tool/double-slit-decoherence/i18n/it.ts +52 -8
  31. package/src/tool/double-slit-decoherence/i18n/pt.ts +53 -9
  32. package/src/tool/double-slit-decoherence/i18n/sv.ts +56 -8
  33. package/src/tool/dyson-sphere-energy-capture/i18n/de.ts +119 -38
  34. package/src/tool/dyson-sphere-energy-capture/i18n/fr.ts +116 -48
  35. package/src/tool/dyson-sphere-energy-capture/i18n/it.ts +96 -19
  36. package/src/tool/dyson-sphere-energy-capture/i18n/ja.ts +124 -24
  37. package/src/tool/dyson-sphere-energy-capture/i18n/ko.ts +122 -22
  38. package/src/tool/dyson-sphere-energy-capture/i18n/pl.ts +68 -14
  39. package/src/tool/dyson-sphere-energy-capture/i18n/pt.ts +126 -45
  40. package/src/tool/dyson-sphere-energy-capture/i18n/ru.ts +46 -9
  41. package/src/tool/dyson-sphere-energy-capture/i18n/sv.ts +134 -53
  42. package/src/tool/dyson-sphere-energy-capture/i18n/tr.ts +68 -14
  43. package/src/tool/dyson-sphere-energy-capture/i18n/zh.ts +124 -24
  44. package/src/tool/global-albedo-snowball-simulator/i18n/ru.ts +20 -7
  45. package/src/tool/lorenz-attractor/i18n/de.ts +35 -5
  46. package/src/tool/lorenz-attractor/i18n/fr.ts +35 -5
  47. package/src/tool/lorenz-attractor/i18n/id.ts +10 -0
  48. package/src/tool/lorenz-attractor/i18n/it.ts +9 -0
  49. package/src/tool/lorenz-attractor/i18n/ja.ts +10 -0
  50. package/src/tool/lorenz-attractor/i18n/ko.ts +10 -0
  51. package/src/tool/lorenz-attractor/i18n/nl.ts +10 -0
  52. package/src/tool/lorenz-attractor/i18n/pl.ts +10 -0
  53. package/src/tool/lorenz-attractor/i18n/pt.ts +35 -5
  54. package/src/tool/lorenz-attractor/i18n/ru.ts +10 -0
  55. package/src/tool/lorenz-attractor/i18n/sv.ts +10 -0
  56. package/src/tool/lorenz-attractor/i18n/tr.ts +10 -0
  57. package/src/tool/lorenz-attractor/i18n/zh.ts +10 -0
  58. package/src/tool/mandelbrot-fractal/i18n/de.ts +27 -0
  59. package/src/tool/mandelbrot-fractal/i18n/fr.ts +18 -0
  60. package/src/tool/mandelbrot-fractal/i18n/it.ts +26 -8
  61. package/src/tool/mandelbrot-fractal/i18n/pl.ts +27 -9
  62. package/src/tool/mandelbrot-fractal/i18n/ru.ts +22 -4
  63. package/src/tool/mandelbrot-fractal/i18n/sv.ts +35 -8
  64. package/src/tool/natural-selection-drift/i18n/de.ts +125 -22
  65. package/src/tool/natural-selection-drift/i18n/id.ts +113 -5
  66. package/src/tool/natural-selection-drift/i18n/it.ts +74 -2
  67. package/src/tool/natural-selection-drift/i18n/ja.ts +113 -5
  68. package/src/tool/natural-selection-drift/i18n/ko.ts +113 -5
  69. package/src/tool/natural-selection-drift/i18n/nl.ts +121 -6
  70. package/src/tool/natural-selection-drift/i18n/pl.ts +136 -16
  71. package/src/tool/natural-selection-drift/i18n/pt.ts +110 -15
  72. package/src/tool/natural-selection-drift/i18n/ru.ts +142 -7
  73. package/src/tool/natural-selection-drift/i18n/sv.ts +110 -5
  74. package/src/tool/natural-selection-drift/i18n/tr.ts +160 -22
  75. package/src/tool/natural-selection-drift/i18n/zh.ts +113 -5
  76. package/src/tool/phase-diagram-critical-points/i18n/de.ts +44 -6
  77. package/src/tool/phase-diagram-critical-points/i18n/fr.ts +46 -8
  78. package/src/tool/planet-atmosphere-survival/i18n/ru.ts +118 -2
  79. package/src/tool/radioactive-decay/i18n/de.ts +112 -5
  80. package/src/tool/radioactive-decay/i18n/fr.ts +16 -0
  81. package/src/tool/radioactive-decay/i18n/id.ts +112 -8
  82. package/src/tool/radioactive-decay/i18n/it.ts +16 -0
  83. package/src/tool/radioactive-decay/i18n/ja.ts +112 -8
  84. package/src/tool/radioactive-decay/i18n/ko.ts +112 -8
  85. package/src/tool/radioactive-decay/i18n/nl.ts +112 -14
  86. package/src/tool/radioactive-decay/i18n/pl.ts +112 -7
  87. package/src/tool/radioactive-decay/i18n/pt.ts +112 -21
  88. package/src/tool/radioactive-decay/i18n/ru.ts +112 -8
  89. package/src/tool/radioactive-decay/i18n/sv.ts +112 -8
  90. package/src/tool/radioactive-decay/i18n/tr.ts +112 -8
  91. package/src/tool/radioactive-decay/i18n/zh.ts +112 -8
  92. package/src/tool/roche-limit-satellite-disruption/i18n/pl.ts +76 -0
  93. package/src/tool/temperature-timeline/i18n/de.ts +22 -2
  94. package/src/tool/temperature-timeline/i18n/fr.ts +41 -1
  95. package/src/tool/temperature-timeline/i18n/it.ts +30 -1
  96. package/src/tool/temperature-timeline/i18n/pt.ts +34 -1
  97. package/src/tool/temperature-timeline/i18n/ru.ts +29 -0
  98. package/src/tool/twin-paradox-visualizer/i18n/pt.ts +41 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jjlmoya/utils-science",
3
- "version": "1.47.0",
3
+ "version": "1.49.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -28,7 +28,7 @@
28
28
  "check": "astro check",
29
29
  "type-check": "astro check",
30
30
  "test": "vitest run",
31
- "preversion": "npm run lint && npm run test",
31
+ "preversion": "npm run lint && npm run test && npm run build",
32
32
  "postversion": "git push && git push --tags",
33
33
  "patch": "npm version patch",
34
34
  "minor": "npm version minor",
@@ -1,31 +1,31 @@
1
1
  import type { ScienceCategoryEntry } from '../types';
2
- import { colonyCounter } from '../tool/colony-counter/index';
3
- import { asteroidImpact } from '../tool/asteroid-impact/index';
4
- import { microwaveDetector } from '../tool/microwave-detector/index';
5
- import { simulationProbability } from '../tool/simulation-probability/index';
6
- import { cellularRenewal } from '../tool/cellular-renewal/index';
7
- import { cosmicInflation } from '../tool/cosmic-inflation/index';
8
- import { temperatureTimeline } from '../tool/temperature-timeline/index';
9
- import { lorenzAttractor } from '../tool/lorenz-attractor/index';
10
- import { stellarHabitabilityZone } from '../tool/stellar-habitability-zone/index';
11
- import { radioactiveDecay } from '../tool/radioactive-decay/index';
12
- import { naturalSelectionDrift } from '../tool/natural-selection-drift/index';
13
- import { entropySecondLaw } from '../tool/entropy-second-law/index';
14
- import { doubleSlitDecoherence } from '../tool/double-slit-decoherence/index';
15
- import { phaseDiagramCriticalPoints } from '../tool/phase-diagram-critical-points/index';
16
- import { twinParadoxVisualizer } from '../tool/twin-paradox-visualizer/index';
17
- import { mandelbrotFractal } from '../tool/mandelbrot-fractal/index';
18
- import { planetAtmosphereSurvival } from '../tool/planet-atmosphere-survival/index';
19
- import { threeBodyProblem } from '../tool/three-body-problem/index';
20
- import { rocheLimitSatelliteDisruption } from '../tool/roche-limit-satellite-disruption/index';
21
- import { dysonSphereEnergyCapture } from '../tool/dyson-sphere-energy-capture/index';
22
- import { globalAlbedoSnowballSimulator } from '../tool/global-albedo-snowball-simulator/index';
23
- import { conwayLifeRuleLab } from '../tool/conway-life-rule-lab/index';
24
- import { crystalLatticeStructureFinder } from '../tool/crystal-lattice-structure-finder/index';
25
- import { fermiParadoxFilterLab } from '../tool/fermi-paradox-filter-lab/index';
26
- import { epidemicSirSimulator } from '../tool/epidemic-sir-simulator/index';
27
- import { blackHoleEventHorizonSimulator } from '../tool/black-hole-event-horizon-simulator/index';
28
- import { exoplanetBiosignatureDetector } from '../tool/exoplanet-biosignature-detector/index';
2
+ import { colonyCounter } from '../tool/colony-counter/entry';
3
+ import { asteroidImpact } from '../tool/asteroid-impact/entry';
4
+ import { microwaveDetector } from '../tool/microwave-detector/entry';
5
+ import { simulationProbability } from '../tool/simulation-probability/entry';
6
+ import { cellularRenewal } from '../tool/cellular-renewal/entry';
7
+ import { cosmicInflation } from '../tool/cosmic-inflation/entry';
8
+ import { temperatureTimeline } from '../tool/temperature-timeline/entry';
9
+ import { lorenzAttractor } from '../tool/lorenz-attractor/entry';
10
+ import { stellarHabitabilityZone } from '../tool/stellar-habitability-zone/entry';
11
+ import { radioactiveDecay } from '../tool/radioactive-decay/entry';
12
+ import { naturalSelectionDrift } from '../tool/natural-selection-drift/entry';
13
+ import { entropySecondLaw } from '../tool/entropy-second-law/entry';
14
+ import { doubleSlitDecoherence } from '../tool/double-slit-decoherence/entry';
15
+ import { phaseDiagramCriticalPoints } from '../tool/phase-diagram-critical-points/entry';
16
+ import { twinParadoxVisualizer } from '../tool/twin-paradox-visualizer/entry';
17
+ import { mandelbrotFractal } from '../tool/mandelbrot-fractal/entry';
18
+ import { planetAtmosphereSurvival } from '../tool/planet-atmosphere-survival/entry';
19
+ import { threeBodyProblem } from '../tool/three-body-problem/entry';
20
+ import { rocheLimitSatelliteDisruption } from '../tool/roche-limit-satellite-disruption/entry';
21
+ import { dysonSphereEnergyCapture } from '../tool/dyson-sphere-energy-capture/entry';
22
+ import { globalAlbedoSnowballSimulator } from '../tool/global-albedo-snowball-simulator/entry';
23
+ import { conwayLifeRuleLab } from '../tool/conway-life-rule-lab/entry';
24
+ import { crystalLatticeStructureFinder } from '../tool/crystal-lattice-structure-finder/entry';
25
+ import { fermiParadoxFilterLab } from '../tool/fermi-paradox-filter-lab/entry';
26
+ import { epidemicSirSimulator } from '../tool/epidemic-sir-simulator/entry';
27
+ import { blackHoleEventHorizonSimulator } from '../tool/black-hole-event-horizon-simulator/entry';
28
+ import { exoplanetBiosignatureDetector } from '../tool/exoplanet-biosignature-detector/entry';
29
29
 
30
30
  export const scienceCategory: ScienceCategoryEntry = {
31
31
  icon: 'mdi:flask',
@@ -0,0 +1,60 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { ALL_ENTRIES } from '../entries';
3
+ import type { KnownLocale } from '../types';
4
+
5
+ interface ExpectedCounts {
6
+ seo: number;
7
+ faq: number;
8
+ howTo: number;
9
+ }
10
+
11
+ function countItems(arr: unknown[] | undefined): number {
12
+ return arr?.length ?? 0;
13
+ }
14
+
15
+ async function verifyLocaleParity(
16
+ entry: typeof ALL_ENTRIES[number],
17
+ loc: KnownLocale,
18
+ expected: ExpectedCounts,
19
+ ): Promise<void> {
20
+ const locContent = await entry.i18n[loc]?.();
21
+ expect(locContent, `Locale ${loc} missing content`).toBeDefined();
22
+
23
+ const locSeoCount = countItems(locContent?.seo);
24
+ const locFaqCount = countItems(locContent?.faq);
25
+ const locHowToCount = countItems(locContent?.howTo);
26
+
27
+ expect(
28
+ locSeoCount,
29
+ `Locale ${loc} SEO sections count (${locSeoCount}) must match EN (${expected.seo})`,
30
+ ).toBe(expected.seo);
31
+ expect(
32
+ locFaqCount,
33
+ `Locale ${loc} FAQ items count (${locFaqCount}) must match EN (${expected.faq})`,
34
+ ).toBe(expected.faq);
35
+ expect(
36
+ locHowToCount,
37
+ `Locale ${loc} HowTo steps count (${locHowToCount}) must match EN (${expected.howTo})`,
38
+ ).toBe(expected.howTo);
39
+ }
40
+
41
+ describe('SEO & i18n Structural Parity Suite', () => {
42
+ ALL_ENTRIES.forEach((entry) => {
43
+ describe(`Tool: ${entry.id}`, () => {
44
+ it('all 15 locales should have identical SEO section counts and types as English', async () => {
45
+ const enContent = await entry.i18n.en?.();
46
+ expect(enContent).toBeDefined();
47
+ const expected: ExpectedCounts = {
48
+ seo: countItems(enContent?.seo),
49
+ faq: countItems(enContent?.faq),
50
+ howTo: countItems(enContent?.howTo),
51
+ };
52
+
53
+ const locales = Object.keys(entry.i18n) as KnownLocale[];
54
+ for (const loc of locales) {
55
+ await verifyLocaleParity(entry, loc, expected);
56
+ }
57
+ });
58
+ });
59
+ });
60
+ });
@@ -0,0 +1,122 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { ALL_ENTRIES } from '../entries';
3
+
4
+ const COPY_THRESHOLD = 0.9;
5
+
6
+ const STRUCTURAL_KEYS = new Set([
7
+ '@context',
8
+ '@type',
9
+ 'applicationCategory',
10
+ 'columns',
11
+ 'highlight',
12
+ 'icon',
13
+ 'level',
14
+ 'operatingSystem',
15
+ 'position',
16
+ 'positive',
17
+ 'price',
18
+ 'priceCurrency',
19
+ 'slug',
20
+ 'trend',
21
+ 'type',
22
+ 'url',
23
+ 'value',
24
+ 'variant',
25
+ ]);
26
+
27
+ function normalizeText(value: string): string {
28
+ return value
29
+ .replace(/<[^>]*>/g, ' ')
30
+ .replace(/&(?:amp|lt|gt|quot|apos|nbsp);/gi, ' ')
31
+ .replace(/[\u2018\u2019]/g, "'")
32
+ .replace(/[\u201c\u201d]/g, '"')
33
+ .replace(/\s+/g, ' ')
34
+ .trim()
35
+ .toLocaleLowerCase();
36
+ }
37
+
38
+ function collectText(value: unknown, path: string, parts: string[]): void {
39
+ if (typeof value === 'string') {
40
+ const normalized = normalizeText(value);
41
+ if (normalized.length >= 2) parts.push(normalized);
42
+ return;
43
+ }
44
+
45
+ if (Array.isArray(value)) {
46
+ value.forEach((item, index) => collectText(item, `${path}[${index}]`, parts));
47
+ return;
48
+ }
49
+
50
+ if (!value || typeof value !== 'object') return;
51
+
52
+ Object.entries(value).forEach(([key, child]) => {
53
+ if (STRUCTURAL_KEYS.has(key)) return;
54
+ collectText(child, `${path}.${key}`, parts);
55
+ });
56
+ }
57
+
58
+ function localeCorpus(content: unknown): string {
59
+ if (!content || typeof content !== 'object') return '';
60
+
61
+ const record = content as Record<string, unknown>;
62
+ const parts: string[] = [];
63
+ collectText(record.title, 'title', parts);
64
+ collectText(record.description, 'description', parts);
65
+ collectText(record.faqTitle, 'faqTitle', parts);
66
+ collectText(record.faq, 'faq', parts);
67
+ collectText(record.seo, 'seo', parts);
68
+ collectText(record.schemas, 'schemas', parts);
69
+ return parts.join(' ');
70
+ }
71
+
72
+ function tokenCounts(text: string): Map<string, number> {
73
+ const counts = new Map<string, number>();
74
+ for (const token of text.match(/[\p{L}\p{N}]+/gu) ?? []) {
75
+ counts.set(token, (counts.get(token) ?? 0) + 1);
76
+ }
77
+ return counts;
78
+ }
79
+
80
+ function copySimilarity(left: string, right: string): number {
81
+ const leftCounts = tokenCounts(left);
82
+ const rightCounts = tokenCounts(right);
83
+ const leftTotal = [...leftCounts.values()].reduce((sum, count) => sum + count, 0);
84
+ const rightTotal = [...rightCounts.values()].reduce((sum, count) => sum + count, 0);
85
+ if (leftTotal === 0 || rightTotal === 0) return 0;
86
+
87
+ let shared = 0;
88
+ for (const [token, count] of leftCounts) {
89
+ shared += Math.min(count, rightCounts.get(token) ?? 0);
90
+ }
91
+ return (2 * shared) / (leftTotal + rightTotal);
92
+ }
93
+
94
+ describe('Locales must not copy another locale wholesale', () => {
95
+ ALL_ENTRIES.forEach((entry) => {
96
+ it(`${entry.id} is not at least ${COPY_THRESHOLD * 100}% identical to another locale`, async () => {
97
+ const corpora = new Map<string, string>();
98
+
99
+ for (const [locale, loader] of Object.entries(entry.i18n)) {
100
+ if (!loader) continue;
101
+ corpora.set(locale, localeCorpus(await loader()));
102
+ }
103
+
104
+ const locales = [...corpora.keys()];
105
+ const violations: string[] = [];
106
+
107
+ for (let leftIndex = 0; leftIndex < locales.length; leftIndex += 1) {
108
+ for (let rightIndex = leftIndex + 1; rightIndex < locales.length; rightIndex += 1) {
109
+ const left = locales[leftIndex];
110
+ const right = locales[rightIndex];
111
+ const similarity = copySimilarity(corpora.get(left) ?? '', corpora.get(right) ?? '');
112
+
113
+ if (similarity >= COPY_THRESHOLD) {
114
+ violations.push(`${left} ↔ ${right}: ${(similarity * 100).toFixed(1)}%`);
115
+ }
116
+ }
117
+ }
118
+
119
+ expect(violations, `Locale copy threshold exceeded in ${entry.id}`).toEqual([]);
120
+ });
121
+ });
122
+ });
@@ -111,11 +111,11 @@ export const content: ToolLocaleContent = {
111
111
  },
112
112
  {
113
113
  type: 'paragraph',
114
- html: 'Dieser Schwarzes Loch Ereignishorizont Simulator verwandelt die Kernideen von Schwarzschild-schwarzen Löchern in ein interaktives visuelles Modell. Ändern Sie die Masse des schwarzen Lochs, bewegen Sie eine Sonde nach innen oder außen und vergleichen Sie, wie Ereignishorizont, Photonensphäre, innerster stabiler kreisförmiger Orbit, Fluchtgeschwindigkeit, gravitative Rotverschiebung und Zeitdilatation reagieren.',
114
+ html: 'Dieser Schwarzes Loch Ereignishorizont Simulator verwandelt die Kernideen von Schwarzschild-schwarzen Löchern in ein interaktives visuelles Modell.',
115
115
  },
116
116
  {
117
117
  type: 'paragraph',
118
- html: 'Der Simulator wurde für Astronomiestudenten, Physiklehrer, Wissenschaftsautoren und neugierige Lernende entwickelt, die mehr als eine statische Formel wollen. Die Anzeige verbindet die Zahlen mit einem räumlichen Diagramm, sodass Sie sehen können, warum der Ereignishorizont keine materielle Oberfläche ist, warum Photonen einen speziellen instabilen Orbit haben und warum stabile Kreisbewegungen stoppen, bevor der Horizont erreicht wird.',
118
+ html: 'Der Simulator wurde für Astronomiestudenten, Physiklehrer und Wissenschaftsautoren entwickelt.',
119
119
  },
120
120
  {
121
121
  type: 'title',
@@ -124,11 +124,11 @@ export const content: ToolLocaleContent = {
124
124
  },
125
125
  {
126
126
  type: 'paragraph',
127
- html: 'Für ein nicht rotierendes, ungeladenes schwarzes Loch ist der Ereignishorizont-Radius der <strong>Schwarzschild-Radius</strong>. Er wird berechnet als <strong>Rs = 2GM / c^2</strong>, wobei G die Gravitationskonstante, M die Masse des schwarzen Lochs und c die Lichtgeschwindigkeit ist. Eine Sonnenmasse entspricht einem Schwarzschild-Radius von etwa 2,95 Kilometern.',
127
+ html: 'Für ein nicht rotierendes, ungeladenes schwarzes Loch ist der Ereignishorizont-Radius der <strong>Schwarzschild-Radius</strong>. Er wird berechnet als <strong>Rs = 2GM / c^2</strong>.',
128
128
  },
129
129
  {
130
130
  type: 'paragraph',
131
- html: 'Da der Schwarzschild-Radius linear mit der Masse skaliert, hat ein schwarzes Loch mit 10 Sonnenmassen einen Radius von nahezu 29,5 Kilometern, während ein schwarzes Loch mit 4 Millionen Sonnenmassen wie Sagittarius A* einen Radius von etwa 11,8 Millionen Kilometern hat. Der Masse-Regler verwendet eine logarithmische Skala, damit sowohl stellare als auch supermassive Fälle in dieselbe Steuerung passen.',
131
+ html: 'Da der Schwarzschild-Radius linear mit der Masse skaliert, hat ein schwarzes Loch mit 10 Sonnenmassen einen Radius von etwa 29,5 Kilometern.',
132
132
  },
133
133
  {
134
134
  type: 'table',
@@ -140,6 +140,81 @@ export const content: ToolLocaleContent = {
140
140
  ['Schwaches Feld', '6 Rs und darüber', 'Die Schwerkraft ist immer noch stark, aber kreisförmige Orbits sind leichter aufrechtzuerhalten.'],
141
141
  ],
142
142
  },
143
+ {
144
+ type: 'title',
145
+ text: 'Fluchtgeschwindigkeit und warum der Horizont eine kausale Grenze ist',
146
+ level: 3,
147
+ },
148
+ {
149
+ type: 'paragraph',
150
+ html: 'Die Fluchtgeschwindigkeit ist die Geschwindigkeit, die ein Objekt benötigt, um ohne zusätzlichen Antrieb beliebig weit zu entkommen.',
151
+ },
152
+ {
153
+ type: 'paragraph',
154
+ html: 'Die Fluchtgeschwindigkeitsanzeige liefert eine nützliche Intuition, sollte jedoch nicht als vollständige relativistische Beschreibung gelesen werden.',
155
+ },
156
+ {
157
+ type: 'title',
158
+ text: 'Zeitdilatation und gravitative Rotverschiebung nahe einem schwarzen Loch',
159
+ level: 3,
160
+ },
161
+ {
162
+ type: 'paragraph',
163
+ html: 'Eine Uhr, die an einem festen Radius außerhalb eines Schwarzschild-schwarzen Lochs gehalten wird, tickt im Vergleich zu einem entfernten Beobachter langsamer. Der vereinfachte Faktor ist <strong>sqrt(1 - Rs / r)</strong>.',
164
+ },
165
+ {
166
+ type: 'paragraph',
167
+ html: 'Die gravitative Rotverschiebung folgt derselben Geometrie. Licht, das aus dem Gravitationspotenzial aufsteigt, verliert Energie.',
168
+ },
169
+ {
170
+ type: 'title',
171
+ text: 'Photonensphäre und ISCO erklärt',
172
+ level: 3,
173
+ },
174
+ {
175
+ type: 'paragraph',
176
+ html: 'Die Photonensphäre bei 1.5 Rs ist der Ort, an dem Licht im Prinzip einem kreisförmigen Orbit folgen kann.',
177
+ },
178
+ {
179
+ type: 'paragraph',
180
+ html: 'Die ISCO bei 3 Rs ist der innerste stabile kreisförmige Orbit für massereiche Teilchen.',
181
+ },
182
+ {
183
+ type: 'title',
184
+ text: 'Stellare im Vergleich zu supermassiven schwarzen Löchern',
185
+ level: 3,
186
+ },
187
+ {
188
+ type: 'paragraph',
189
+ html: 'Eine überraschende Lektion ist, dass größere schwarze Löcher am Horizont weniger destruktiv wirken können.',
190
+ },
191
+ {
192
+ type: 'paragraph',
193
+ html: 'Der Simulator enthält eine Gezeitengradienten-Anzeige in Erdschwerkraft pro Meter.',
194
+ },
195
+ {
196
+ type: 'title',
197
+ text: 'Einschränkungen dieses Simulators',
198
+ level: 3,
199
+ },
200
+ {
201
+ type: 'list',
202
+ items: [
203
+ '<strong>Kein Spin:</strong> verwendet Schwarzschild-Geometrie.',
204
+ '<strong>Keine Akkretionsphysik:</strong> vereinfachte Scheibenanzeige.',
205
+ '<strong>Kein Raytracing:</strong> didaktisches Diagramm.',
206
+ '<strong>Kein freier Fall:</strong> stationäre Beobachteruhr.',
207
+ ],
208
+ },
209
+ {
210
+ type: 'title',
211
+ text: 'Häufige Fragen',
212
+ level: 3,
213
+ },
214
+ {
215
+ type: 'paragraph',
216
+ html: 'Verwenden Sie dieses Tool zur Schätzung der Parameter eines schwarzen Lochs.',
217
+ },
143
218
  ],
144
219
  faq,
145
220
  bibliography,
@@ -106,40 +106,115 @@ export const content: ToolLocaleContent = {
106
106
  seo: [
107
107
  {
108
108
  type: 'title',
109
- text: 'Simulateur d\'horizon des événements: rayon de Schwarzschild, sphère de photons et dilatation du temps',
109
+ text: 'Simulateur d\'horizon des événements pour rayon de Schwarzschild, sphère de photons et dilatation temporelle',
110
110
  level: 2,
111
111
  },
112
112
  {
113
113
  type: 'paragraph',
114
- html: 'Ce simulateur transforme les concepts fondamentaux des trous noirs de Schwarzschild en un modèle visuel interactif. Modifiez la masse, déplacez la sonde et comparez la réponse de l\'horizon, de la sphère de photons, de l\'ISCO, de la vitesse de libération, du décalage vers le rouge gravitationnel et de la dilatation du temps.',
114
+ html: 'Ce simulateur d\'horizon des événements transforme les idées clés des trous noirs de Schwarzschild en un modèle visuel interactif.',
115
115
  },
116
116
  {
117
117
  type: 'paragraph',
118
- html: 'Conçu pour les étudiants en astronomie, les enseignants et les curieux, cet outil dépasse la simple formule statique. Il relie les données numériques à un diagramme spatial pour illustrer pourquoi l\'horizon n\'est pas une surface matérielle, pourquoi les photons suivent une orbite instable et pourquoi le mouvement circulaire stable s\'arrête avant l\'horizon.',
118
+ html: 'Le simulateur est conçu pour les étudiants en astronomie, les enseignants et les passionnés de physique.',
119
119
  },
120
120
  {
121
121
  type: 'title',
122
- text: 'Comment le rayon de l\'horizon est calculé',
122
+ text: 'Comment le rayon de l\'horizon des événements est calculé',
123
123
  level: 3,
124
124
  },
125
125
  {
126
126
  type: 'paragraph',
127
- html: 'Pour un trou noir sans rotation ni charge, le rayon de l\'horizon est le <strong>rayon de Schwarzschild</strong>. Il est calculé via la formule <strong>Rs = 2GM / c^2</strong>, où G est la constante gravitationnelle, M la masse du trou noir et c la vitesse de la lumière. Une masse solaire correspond à un rayon d\'environ 2,95 km.',
127
+ html: 'Pour un trou noir non rotatif sans charge, le rayon est le <strong>rayon de Schwarzschild</strong>: <strong>Rs = 2GM / c^2</strong>.',
128
128
  },
129
129
  {
130
130
  type: 'paragraph',
131
- html: 'Comme le rayon de Schwarzschild varie linéairement avec la masse, un trou noir de 10 masses solaires a un rayon d\'environ 29,5 km, tandis qu\'un trou noir supermassif comme Sagittarius A* (4 millions de masses solaires) atteint environ 11,8 millions de kilomètres. Le curseur utilise une échelle logarithmique pour couvrir ces ordres de grandeur.',
131
+ html: 'Puisque le rayon varie proportionnellement à la masse, 10 masses solaires donnent un rayon d\'environ 29,5 km.',
132
132
  },
133
133
  {
134
134
  type: 'table',
135
- headers: ['Région', 'Rayon (en Rs)', 'Signification'],
135
+ headers: ['Région', 'Rayon en rayons de Schwarzschild', 'Signification'],
136
136
  rows: [
137
- ['Horizon des événements', '1.0 Rs', 'Frontière unidirectionnelle où la vitesse de libération égale celle de la lumière.'],
138
- ['Sphère de photons', '1.5 Rs', 'Orbite circulaire instable pour la lumière.'],
139
- ['ISCO', '3.0 Rs', 'Orbite circulaire stable la plus interne pour les particules massives.'],
140
- ['Champ faible', '6 Rs et +', 'La gravité reste forte, mais les orbites circulaires sont stables.'],
137
+ ['Horizon des événements', '1.0 Rs', 'La limite sans retour où la vitesse de libération égale c.'],
138
+ ['Sphère de photons', '1.5 Rs', 'L\'orbite circulaire instable pour la lumière.'],
139
+ ['ISCO', '3.0 Rs', 'La dernière orbite circulaire stable pour les particules massives.'],
140
+ ['Champ faible', '6 Rs et plus', 'Gravité encore forte mais orbites circulaires aisées.'],
141
141
  ],
142
142
  },
143
+ {
144
+ type: 'title',
145
+ text: 'Vitesse de libération et frontière causale',
146
+ level: 3,
147
+ },
148
+ {
149
+ type: 'paragraph',
150
+ html: 'La vitesse de libération est la vitesse minimale requise pour s\'échapper à l\'infini sans propulsion.',
151
+ },
152
+ {
153
+ type: 'paragraph',
154
+ html: 'L\'indicateur de vitesse de libération est une intuition utile mais incomplète relativistement.',
155
+ },
156
+ {
157
+ type: 'title',
158
+ text: 'Dilatation temporelle et décalage vers le rouge gravitationnel',
159
+ level: 3,
160
+ },
161
+ {
162
+ type: 'paragraph',
163
+ html: 'Une horloge fixe près d\'un trou noir bat plus lentement qu\'à l\'infini. Le facteur simplifié est <strong>sqrt(1 - Rs / r)</strong>.',
164
+ },
165
+ {
166
+ type: 'paragraph',
167
+ html: 'Le décalage vers le rouge gravitationnel suit la même géométrie. La lumière perd de l\'énergie en s\'échappant.',
168
+ },
169
+ {
170
+ type: 'title',
171
+ text: 'Sphère de photons et ISCO expliquées',
172
+ level: 3,
173
+ },
174
+ {
175
+ type: 'paragraph',
176
+ html: 'La sphère de photons à 1.5 Rs est l\'endroit où la lumière peut effectuer une orbite circulaire instable.',
177
+ },
178
+ {
179
+ type: 'paragraph',
180
+ html: 'L\'ISCO à 3 Rs représente la dernière orbite stable pour la matière.',
181
+ },
182
+ {
183
+ type: 'title',
184
+ text: 'Trous noirs stellaires vs supermassifs',
185
+ level: 3,
186
+ },
187
+ {
188
+ type: 'paragraph',
189
+ html: 'Une leçon surprenante est que les trous noirs supermassifs sont moins violents au niveau des forces de marée à l\'horizon.',
190
+ },
191
+ {
192
+ type: 'paragraph',
193
+ html: 'Le simulateur inclut un gradient de marée exprimé en gravités terrestres par mètre.',
194
+ },
195
+ {
196
+ type: 'title',
197
+ text: 'Limites de ce simulateur',
198
+ level: 3,
199
+ },
200
+ {
201
+ type: 'list',
202
+ items: [
203
+ ['<strong>Pas de rotation :</strong> utilise la géométrie de Schwarzschild.'],
204
+ ['<strong>Pas de physique d\'accrétion avancée :</strong> disque simplifié.'],
205
+ ['<strong>Pas de ray-tracing :</strong> schéma éducatif.'],
206
+ ['<strong>Pas de repère en chute libre :</strong> horloge stationnaire.'],
207
+ ],
208
+ },
209
+ {
210
+ type: 'title',
211
+ text: 'Foire aux questions',
212
+ level: 3,
213
+ },
214
+ {
215
+ type: 'paragraph',
216
+ html: 'Utilisez cet outil pour estimer les paramètres d\'un trou noir.',
217
+ },
143
218
  ],
144
219
  faq,
145
220
  bibliography,
@@ -106,40 +106,115 @@ export const content: ToolLocaleContent = {
106
106
  seo: [
107
107
  {
108
108
  type: 'title',
109
- text: 'Simulatore dell\'orizzonte degli eventi: raggio di Schwarzschild, sfera dei fotoni e dilatazione temporale',
109
+ text: 'Simulatore dell\'orizzonte degli eventi di un buco nero per raggio di Schwarzschild, sfera di fotoni e dilatazione temporale',
110
110
  level: 2,
111
111
  },
112
112
  {
113
113
  type: 'paragraph',
114
- html: 'Questo simulatore trasforma le idee fondamentali dei buchi neri di Schwarzschild in un modello visivo interattivo. Cambia la massa, sposta una sonda e confronta come reagiscono l\'orizzonte degli eventi, la sfera dei fotoni, l\'ISCO, la velocità di fuga, il redshift gravitazionale e la dilatazione temporale.',
114
+ html: 'Questo simulatore dell\'orizzonte degli eventi trasforma i concetti chiave dei buchi neri di Schwarzschild in un modello visivo interattivo.',
115
115
  },
116
116
  {
117
117
  type: 'paragraph',
118
- html: 'Il simulatore è progettato per studenti, insegnanti e curiosi che cercano più di una semplice formula statica. Il display collega i dati numerici a un diagramma spaziale per illustrare perché l\'orizzonte non è una superficie materiale, perché i fotoni hanno un\'orbita instabile particolare e perché il moto circolare stabile si arresta prima dell\'orizzonte.',
118
+ html: 'Il simulatore è stato progettato per studenti di astronomia, docenti di fisica e appassionati.',
119
119
  },
120
120
  {
121
121
  type: 'title',
122
- text: 'Come viene calcolato il raggio dell\'orizzonte degli eventi',
122
+ text: 'Come si calcola il raggio dell\'orizzonte degli eventi',
123
123
  level: 3,
124
124
  },
125
125
  {
126
126
  type: 'paragraph',
127
- html: 'Per un buco nero senza rotazione carica, il raggio dell\'orizzonte è il <strong>raggio di Schwarzschild</strong>. Si calcola come <strong>Rs = 2GM / c^2</strong>, dove G è la costante gravitazionale, M la massa del buco nero e c la velocità della luce. Una massa solare corrisponde a un raggio di circa 2,95 km.',
127
+ html: 'Per un buco nero non rotante e privo di carica, il raggio è il <strong>raggio di Schwarzschild</strong>: <strong>Rs = 2GM / c^2</strong>.',
128
128
  },
129
129
  {
130
130
  type: 'paragraph',
131
- html: 'Poiché il raggio di Schwarzschild scala linearmente con la massa, un buco nero di 10 masse solari ha un raggio vicino a 29,5 km, mentre un buco nero supermassiccio come Sagittarius A* (4 milioni di masse solari) ha un raggio di circa 11,8 milioni di chilometri. Il cursore usa una scala logaritmica per coprire entrambi gli ordini di grandezza.',
131
+ html: 'Poiché il raggio varia linearmente con la massa, 10 masse solari corrispondono a un raggio di circa 29,5 km.',
132
132
  },
133
133
  {
134
134
  type: 'table',
135
- headers: ['Regione', 'Raggio (in Rs)', 'Significato'],
135
+ headers: ['Regione', 'Raggio in raggi di Schwarzschild', 'Significato'],
136
136
  rows: [
137
- ['Orizzonte degli eventi', '1.0 Rs', 'Confine unidirezionale dove la velocità di fuga eguaglia quella della luce.'],
138
- ['Sfera dei fotoni', '1.5 Rs', 'Orbite circolari instabili per la luce.'],
139
- ['ISCO', '3.0 Rs', 'Orbite circolari stabili più interne per particelle con massa.'],
140
- ['Campo debole', '6 Rs e oltre', 'La gravità resta forte, ma le orbite circolari sono più facili da sostenere.'],
137
+ ['Orizzonte degli eventi', '1.0 Rs', 'Il limite di non ritorno dove la velocità di fuga eguaglia c.'],
138
+ ['Sfera di fotoni', '1.5 Rs', 'L\'orbita circolare instabile per la luce.'],
139
+ ['ISCO', '3.0 Rs', 'L\'ultima orbita circolare stabile per le particelle dotate di massa.'],
140
+ ['Campo debole', '6 Rs e oltre', 'Gravità ancora forte ma orbite circolari stabili.'],
141
141
  ],
142
142
  },
143
+ {
144
+ type: 'title',
145
+ text: 'Velocità di fuga e confine causale',
146
+ level: 3,
147
+ },
148
+ {
149
+ type: 'paragraph',
150
+ html: 'La velocità di fuga è la velocità minima necessaria per allontanarsi all\'infinito senza propulsione.',
151
+ },
152
+ {
153
+ type: 'paragraph',
154
+ html: 'L\'indicatore della velocità di fuga offre un\'intuizione utile ma non costituisce una descrizione relativistica completa.',
155
+ },
156
+ {
157
+ type: 'title',
158
+ text: 'Dilatazione temporale e redshift gravitazionale',
159
+ level: 3,
160
+ },
161
+ {
162
+ type: 'paragraph',
163
+ html: 'Un orologio fermo vicino a un buco nero scorre più lentamente rispetto a un osservatore distante. Il fattore semplificato è <strong>sqrt(1 - Rs / r)</strong>.',
164
+ },
165
+ {
166
+ type: 'paragraph',
167
+ html: 'Il redshift gravitazionale segue la stessa geometria. La luce perde energia risalendo il pozzo gravitazionale.',
168
+ },
169
+ {
170
+ type: 'title',
171
+ text: 'Spiegazione della sfera di fotoni e dell\'ISCO',
172
+ level: 3,
173
+ },
174
+ {
175
+ type: 'paragraph',
176
+ html: 'La sfera di fotoni a 1.5 Rs è il punto in cui la luce può percorrere un\'orbita circolare instabile.',
177
+ },
178
+ {
179
+ type: 'paragraph',
180
+ html: 'L\'ISCO a 3 Rs rappresenta l\'ultima orbita circolare stabile per la materia.',
181
+ },
182
+ {
183
+ type: 'title',
184
+ text: 'Buchi neri stellari vs supermassicci',
185
+ level: 3,
186
+ },
187
+ {
188
+ type: 'paragraph',
189
+ html: 'Una lezione sorprendente è che i buchi neri supermassicci generano forze di marea meno violente all\'orizzonte.',
190
+ },
191
+ {
192
+ type: 'paragraph',
193
+ html: 'Il simulatore include una lettura del gradiente di marea espressa in gravità terrestri per metro.',
194
+ },
195
+ {
196
+ type: 'title',
197
+ text: 'Limitazioni di questo simulatore',
198
+ level: 3,
199
+ },
200
+ {
201
+ type: 'list',
202
+ items: [
203
+ '<strong>Nessuna rotazione:</strong> utilizza la geometria di Schwarzschild.',
204
+ '<strong>Fisica di accrescimento semplificata:</strong> disco visivo indicativo.',
205
+ '<strong>Nessun ray tracing:</strong> diagramma educativo.',
206
+ '<strong>Orologio stazionario:</strong> non in caduta libera.',
207
+ ],
208
+ },
209
+ {
210
+ type: 'title',
211
+ text: 'Domande frequenti',
212
+ level: 3,
213
+ },
214
+ {
215
+ type: 'paragraph',
216
+ html: 'Utilizza questo strumento per stimare i parametri di un buco nero.',
217
+ },
143
218
  ],
144
219
  faq,
145
220
  bibliography,