@jjlmoya/utils-forensic-science 1.12.0 → 1.14.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 (169) hide show
  1. package/package.json +2 -1
  2. package/src/category/index.ts +63 -59
  3. package/src/category/seo.astro +1 -1
  4. package/src/components/PreviewNavSidebar.astro +1 -1
  5. package/src/components/PreviewToolbar.astro +1 -1
  6. package/src/data.ts +1 -1
  7. package/src/entries.ts +74 -68
  8. package/src/env.d.ts +1 -1
  9. package/src/index.ts +33 -31
  10. package/src/pages/[locale]/[slug].astro +161 -159
  11. package/src/pages/[locale].astro +8 -5
  12. package/src/pages/index.astro +1 -1
  13. package/src/tests/bibliography_wellformed_export.test.ts +46 -0
  14. package/src/tests/diacritics_density.test.ts +1 -1
  15. package/src/tests/faq_count.test.ts +19 -19
  16. package/src/tests/i18n_coverage.test.ts +36 -36
  17. package/src/tests/inverted_punctuation.test.ts +1 -1
  18. package/src/tests/locale_completeness.test.ts +2 -2
  19. package/src/tests/mocks/astro_mock.js +1 -1
  20. package/src/tests/no_h1_in_components.test.ts +1 -1
  21. package/src/tests/script_density.test.ts +94 -94
  22. package/src/tests/seo_length.test.ts +46 -46
  23. package/src/tests/seo_parity.test.ts +2 -7
  24. package/src/tests/seo_translation_completeness.test.ts +68 -0
  25. package/src/tests/seo_wellformed_export.test.ts +65 -0
  26. package/src/tests/tool_validation.test.ts +2 -2
  27. package/src/tests/translation_copy.test.ts +23 -24
  28. package/src/tool/bloodstain-pattern-origin-analyzer/component.astro +9 -9
  29. package/src/tool/bloodstain-pattern-origin-analyzer/i18n/zh.ts +1 -1
  30. package/src/tool/dna-profile-match-probability-lab/bibliography.astro +14 -0
  31. package/src/tool/dna-profile-match-probability-lab/bibliography.ts +16 -0
  32. package/src/tool/dna-profile-match-probability-lab/component.astro +121 -0
  33. package/src/tool/dna-profile-match-probability-lab/controller.ts +159 -0
  34. package/src/tool/dna-profile-match-probability-lab/dna-profile-match-probability-lab.css +485 -0
  35. package/src/tool/dna-profile-match-probability-lab/dom-views.ts +93 -0
  36. package/src/tool/dna-profile-match-probability-lab/entry.ts +29 -0
  37. package/src/tool/dna-profile-match-probability-lab/evaluator.ts +19 -0
  38. package/src/tool/dna-profile-match-probability-lab/i18n/de.ts +43 -0
  39. package/src/tool/dna-profile-match-probability-lab/i18n/en.ts +196 -0
  40. package/src/tool/dna-profile-match-probability-lab/i18n/es.ts +40 -0
  41. package/src/tool/dna-profile-match-probability-lab/i18n/fr.ts +10 -0
  42. package/src/tool/dna-profile-match-probability-lab/i18n/id.ts +41 -0
  43. package/src/tool/dna-profile-match-probability-lab/i18n/it.ts +10 -0
  44. package/src/tool/dna-profile-match-probability-lab/i18n/ja.ts +40 -0
  45. package/src/tool/dna-profile-match-probability-lab/i18n/ko.ts +40 -0
  46. package/src/tool/dna-profile-match-probability-lab/i18n/nl.ts +29 -0
  47. package/src/tool/dna-profile-match-probability-lab/i18n/pl.ts +10 -0
  48. package/src/tool/dna-profile-match-probability-lab/i18n/pt.ts +41 -0
  49. package/src/tool/dna-profile-match-probability-lab/i18n/ru.ts +29 -0
  50. package/src/tool/dna-profile-match-probability-lab/i18n/sv.ts +41 -0
  51. package/src/tool/dna-profile-match-probability-lab/i18n/tr.ts +10 -0
  52. package/src/tool/dna-profile-match-probability-lab/i18n/zh.ts +29 -0
  53. package/src/tool/dna-profile-match-probability-lab/index.ts +11 -0
  54. package/src/tool/dna-profile-match-probability-lab/localize.ts +107 -0
  55. package/src/tool/dna-profile-match-probability-lab/logic.test.ts +56 -0
  56. package/src/tool/dna-profile-match-probability-lab/logic.ts +139 -0
  57. package/src/tool/dna-profile-match-probability-lab/seo.astro +15 -0
  58. package/src/tool/dna-profile-match-probability-lab/storage.ts +26 -0
  59. package/src/tool/dna-profile-match-probability-lab/ui.ts +3 -0
  60. package/src/tool/fire-pattern-origin-analyzer/component.astro +1 -1
  61. package/src/tool/fire-pattern-origin-analyzer/i18n/zh.ts +5 -1
  62. package/src/tool/fire-pattern-origin-analyzer/logic.ts +9 -2
  63. package/src/tool/fire-pattern-origin-analyzer/view-bindings.ts +8 -4
  64. package/src/tool/fire-pattern-origin-analyzer/view-model.ts +6 -2
  65. package/src/tool/forensic-age-estimator/bibliography.astro +1 -1
  66. package/src/tool/forensic-age-estimator/component.astro +1 -1
  67. package/src/tool/forensic-age-estimator/entry.ts +17 -17
  68. package/src/tool/forensic-age-estimator/i18n/de.ts +244 -244
  69. package/src/tool/forensic-age-estimator/i18n/en.ts +244 -244
  70. package/src/tool/forensic-age-estimator/i18n/es.ts +244 -244
  71. package/src/tool/forensic-age-estimator/i18n/fr.ts +244 -244
  72. package/src/tool/forensic-age-estimator/i18n/id.ts +244 -244
  73. package/src/tool/forensic-age-estimator/i18n/it.ts +244 -244
  74. package/src/tool/forensic-age-estimator/i18n/nl.ts +244 -244
  75. package/src/tool/forensic-age-estimator/i18n/pl.ts +244 -244
  76. package/src/tool/forensic-age-estimator/i18n/pt.ts +244 -244
  77. package/src/tool/forensic-age-estimator/i18n/ru.ts +244 -244
  78. package/src/tool/forensic-age-estimator/i18n/sv.ts +244 -244
  79. package/src/tool/forensic-age-estimator/i18n/tr.ts +244 -244
  80. package/src/tool/forensic-age-estimator/i18n/zh.ts +245 -245
  81. package/src/tool/forensic-age-estimator/index.ts +1 -1
  82. package/src/tool/forensic-age-estimator/seo.astro +1 -1
  83. package/src/tool/forensic-blood-test-simulator/component.astro +1 -1
  84. package/src/tool/forensic-fiber-comparison-microscope/component.astro +1 -1
  85. package/src/tool/forensic-fiber-comparison-microscope/render.ts +1 -1
  86. package/src/tool/forensic-fiber-comparison-microscope/view.ts +1 -1
  87. package/src/tool/forensic-fingerprint-minutiae-identifier/component.astro +2 -2
  88. package/src/tool/forensic-fingerprint-minutiae-identifier/i18n/ja.ts +2 -1
  89. package/src/tool/forensic-fingerprint-minutiae-identifier/i18n/zh.ts +2 -0
  90. package/src/tool/forensic-fingerprint-minutiae-identifier/renderer.ts +9 -8
  91. package/src/tool/forensic-glass-becke-line-simulator/component.astro +1 -1
  92. package/src/tool/forensic-glass-becke-line-simulator/view.ts +8 -6
  93. package/src/tool/forensic-image-authenticity-analyzer/component.astro +1 -1
  94. package/src/tool/forensic-image-authenticity-analyzer/i18n/de.ts +105 -105
  95. package/src/tool/forensic-image-authenticity-analyzer/i18n/en.ts +105 -105
  96. package/src/tool/forensic-image-authenticity-analyzer/i18n/es.ts +105 -105
  97. package/src/tool/forensic-image-authenticity-analyzer/i18n/fr.ts +105 -105
  98. package/src/tool/forensic-image-authenticity-analyzer/i18n/id.ts +95 -90
  99. package/src/tool/forensic-image-authenticity-analyzer/i18n/it.ts +105 -105
  100. package/src/tool/forensic-image-authenticity-analyzer/i18n/ja.ts +7 -2
  101. package/src/tool/forensic-image-authenticity-analyzer/i18n/ko.ts +4 -1
  102. package/src/tool/forensic-image-authenticity-analyzer/i18n/nl.ts +95 -92
  103. package/src/tool/forensic-image-authenticity-analyzer/i18n/pl.ts +95 -92
  104. package/src/tool/forensic-image-authenticity-analyzer/i18n/pt.ts +105 -105
  105. package/src/tool/forensic-image-authenticity-analyzer/i18n/ru.ts +97 -92
  106. package/src/tool/forensic-image-authenticity-analyzer/i18n/sv.ts +97 -93
  107. package/src/tool/forensic-image-authenticity-analyzer/i18n/tr.ts +98 -93
  108. package/src/tool/forensic-image-authenticity-analyzer/i18n/zh.ts +11 -0
  109. package/src/tool/forensic-microcrystal-drug-simulator/component.astro +1 -1
  110. package/src/tool/forensic-sex-determinator/component.astro +3 -2
  111. package/src/tool/forensic-stature-estimator/component.astro +1 -1
  112. package/src/tool/forensic-stature-estimator/i18n/id.ts +4 -0
  113. package/src/tool/forensic-stature-estimator/i18n/nl.ts +4 -0
  114. package/src/tool/forensic-stature-estimator/i18n/ru.ts +4 -0
  115. package/src/tool/forensic-tlc-ink-simulator/component.astro +1 -1
  116. package/src/tool/forensic-tlc-ink-simulator/i18n/zh.ts +1 -0
  117. package/src/tool/forensic-toolmark-striation-matcher/component.astro +1 -1
  118. package/src/tool/forensic-toolmark-striation-matcher/logic.ts +1 -1
  119. package/src/tool/forensic-toolmark-striation-matcher/renderer.ts +7 -6
  120. package/src/tool/forensic-toolmark-striation-matcher/view.ts +19 -20
  121. package/src/tool/gsr-dispersion-calculator/component.astro +1 -1
  122. package/src/tool/gsr-dispersion-calculator/logic.ts +1 -1
  123. package/src/tool/time-of-death-algor-mortis-calculator/entry.ts +2 -0
  124. package/src/tool/voice-spectrogram-analyzer/audio-runtime.ts +75 -0
  125. package/src/tool/voice-spectrogram-analyzer/bibliography.astro +14 -0
  126. package/src/tool/voice-spectrogram-analyzer/bibliography.ts +16 -0
  127. package/src/tool/voice-spectrogram-analyzer/component.astro +116 -0
  128. package/src/tool/voice-spectrogram-analyzer/controller.ts +219 -0
  129. package/src/tool/voice-spectrogram-analyzer/dom-views.ts +204 -0
  130. package/src/tool/voice-spectrogram-analyzer/entry.ts +31 -0
  131. package/src/tool/voice-spectrogram-analyzer/evaluator.ts +13 -0
  132. package/src/tool/voice-spectrogram-analyzer/fft.ts +64 -0
  133. package/src/tool/voice-spectrogram-analyzer/i18n/de.ts +135 -0
  134. package/src/tool/voice-spectrogram-analyzer/i18n/en.ts +122 -0
  135. package/src/tool/voice-spectrogram-analyzer/i18n/es.ts +122 -0
  136. package/src/tool/voice-spectrogram-analyzer/i18n/fr.ts +135 -0
  137. package/src/tool/voice-spectrogram-analyzer/i18n/id.ts +136 -0
  138. package/src/tool/voice-spectrogram-analyzer/i18n/it.ts +135 -0
  139. package/src/tool/voice-spectrogram-analyzer/i18n/ja.ts +135 -0
  140. package/src/tool/voice-spectrogram-analyzer/i18n/ko.ts +135 -0
  141. package/src/tool/voice-spectrogram-analyzer/i18n/nl.ts +136 -0
  142. package/src/tool/voice-spectrogram-analyzer/i18n/pl.ts +136 -0
  143. package/src/tool/voice-spectrogram-analyzer/i18n/pt.ts +135 -0
  144. package/src/tool/voice-spectrogram-analyzer/i18n/ru.ts +136 -0
  145. package/src/tool/voice-spectrogram-analyzer/i18n/sv.ts +136 -0
  146. package/src/tool/voice-spectrogram-analyzer/i18n/tr.ts +136 -0
  147. package/src/tool/voice-spectrogram-analyzer/i18n/zh.ts +135 -0
  148. package/src/tool/voice-spectrogram-analyzer/index.ts +11 -0
  149. package/src/tool/voice-spectrogram-analyzer/logic.test.ts +46 -0
  150. package/src/tool/voice-spectrogram-analyzer/logic.ts +163 -0
  151. package/src/tool/voice-spectrogram-analyzer/seo.astro +15 -0
  152. package/src/tool/voice-spectrogram-analyzer/storage.ts +33 -0
  153. package/src/tool/voice-spectrogram-analyzer/ui.ts +49 -0
  154. package/src/tool/voice-spectrogram-analyzer/voice-spectrogram-analyzer.css +547 -0
  155. package/src/tool/widmark-alcohol-simulator/component.astro +1 -1
  156. package/src/tool/widmark-alcohol-simulator/i18n/de.ts +5 -0
  157. package/src/tool/widmark-alcohol-simulator/i18n/fr.ts +2 -1
  158. package/src/tool/widmark-alcohol-simulator/i18n/id.ts +1 -0
  159. package/src/tool/widmark-alcohol-simulator/i18n/it.ts +4 -1
  160. package/src/tool/widmark-alcohol-simulator/i18n/ja.ts +4 -1
  161. package/src/tool/widmark-alcohol-simulator/i18n/nl.ts +5 -1
  162. package/src/tool/widmark-alcohol-simulator/i18n/pl.ts +5 -1
  163. package/src/tool/widmark-alcohol-simulator/i18n/pt.ts +5 -1
  164. package/src/tool/widmark-alcohol-simulator/i18n/ru.ts +4 -1
  165. package/src/tool/widmark-alcohol-simulator/i18n/sv.ts +5 -1
  166. package/src/tool/widmark-alcohol-simulator/i18n/tr.ts +4 -1
  167. package/src/tool/widmark-alcohol-simulator/i18n/zh.ts +4 -1
  168. package/src/tools.ts +39 -35
  169. package/src/types.ts +4 -4
@@ -31,7 +31,6 @@ export function updateWorkflow(
31
31
  export function updateUIStates(
32
32
  activeMinutia: MinutiaType,
33
33
  activePattern: string,
34
- limits: Record<MinutiaType, number>,
35
34
  canAdd: (type: MinutiaType) => boolean
36
35
  ): void {
37
36
  document.querySelectorAll<HTMLButtonElement>('[data-fp-pattern]').forEach((button) => {
@@ -54,7 +53,7 @@ export function updateActionButtons(
54
53
  const undo = document.getElementById('fp-undo') as HTMLButtonElement | null;
55
54
  if (deleteSelected) {
56
55
  deleteSelected.disabled = !selectedMark;
57
- deleteSelected.title = selectedMark ? `${ui.deleteSelected}: ${ui[selectedMark.type] ?? selectedMark.type}` : ui.selectMarkToDelete;
56
+ deleteSelected.title = selectedMark ? `${ui.deleteSelected ?? 'Delete selected'}: ${ui[selectedMark.type] ?? selectedMark.type}` : (ui.selectMarkToDelete ?? 'Select a mark to delete');
58
57
  }
59
58
  if (undo) {
60
59
  undo.disabled = !hasLastMark;
@@ -86,7 +85,7 @@ export function updateMinutiaeLabels(
86
85
  (['ridgeEnding', 'bifurcation', 'island', 'dot'] as MinutiaType[]).forEach((type) => {
87
86
  setText(`fp-count-${type}`, `${summary.byType[type]}/${limits[type]}`);
88
87
  });
89
- setText('fp-active-minutia-label', ui.activeMinutia);
88
+ setText('fp-active-minutia-label', ui.activeMinutia ?? 'Active minutia');
90
89
  setText('fp-active-minutia-title', ui[activeMinutia] ?? activeMinutia);
91
90
  setText('fp-active-minutia-copy', ui[`${activeMinutia}Help`] ?? '');
92
91
  setText('fp-score', `${summary.validationScore}%`);
@@ -104,13 +103,15 @@ interface RenderTableParams {
104
103
  }
105
104
 
106
105
  export function renderTable(p: RenderTableParams): void {
107
- if (!p.tableBody) return;
108
- p.tableBody.innerHTML = '';
106
+ const tableBody = p.tableBody;
107
+ if (!tableBody) return;
108
+ tableBody.innerHTML = '';
109
109
  p.marks.forEach((mark) => {
110
110
  const row = document.createElement('tr');
111
111
  const label = p.ui[mark.type] ?? mark.type;
112
- const trashIcon = p.trashIconTemplate?.innerHTML || p.ui.remove;
113
- row.innerHTML = `<td><span style="--dot:${p.colors[mark.type]}"></span>${label}</td><td>${mark.x.toFixed(1)}, ${mark.y.toFixed(1)}</td><td><button type="button" class="fp-icon-button" data-remove="${mark.id}" aria-label="${p.ui.remove} ${label}">${trashIcon}</button></td>`;
114
- p.tableBody.append(row);
112
+ const removeLabel = p.ui.remove ?? 'Remove';
113
+ const trashIcon = p.trashIconTemplate?.innerHTML || removeLabel;
114
+ row.innerHTML = `<td><span style="--dot:${p.colors[mark.type]}"></span>${label}</td><td>${mark.x.toFixed(1)}, ${mark.y.toFixed(1)}</td><td><button type="button" class="fp-icon-button" data-remove="${mark.id}" aria-label="${removeLabel} ${label}">${trashIcon}</button></td>`;
115
+ tableBody.append(row);
115
116
  });
116
117
  }
@@ -73,7 +73,7 @@ const { ui } = Astro.props;
73
73
  </div>
74
74
  </section>
75
75
 
76
- <script id="becke-ui" type="application/json" set:html={JSON.stringify(ui)}></script>
76
+ <script is:inline id="becke-ui" type="application/json" set:html={JSON.stringify(ui)}></script>
77
77
  <script>
78
78
  import { initBeckeLineSimulator } from './view';
79
79
 
@@ -5,12 +5,14 @@ type Ui = Record<string, string>;
5
5
  type Theme = { center: string; background: string; glass: string; halo: string; grain: string; text: string };
6
6
  type Result = ReturnType<RefractiveIndexCalculator['simulate']>;
7
7
 
8
+ function uiText(ui: Ui, key: string, fallback = ''): string { return ui[key] ?? fallback; }
9
+
8
10
  const STORAGE_KEY = 'forensic-glass-becke-line-simulator-state';
9
11
  const GLASS_VALUES: GlassReference[] = ['sodaLime', 'borosilicate', 'leadCrystal', 'tempered'];
10
12
  const GLASS_TINTS: Record<GlassReference, string> = { sodaLime: '#b9d7d3', borosilicate: '#c8dff2', leadCrystal: '#d6ccf4', tempered: '#cfe4bd' };
11
13
  const HALO_SCALE: Record<GlassReference, number> = { sodaLime: 1, borosilicate: 0.42, leadCrystal: 1, tempered: 1 };
12
14
 
13
- function byId<T extends HTMLElement>(id: string): T | null { return document.getElementById(id) as T | null; }
15
+ function byId<T extends Element>(id: string): T | null { return document.getElementById(id) as T | null; }
14
16
 
15
17
  function isGlassReference(value: unknown): value is GlassReference { return typeof value === 'string' && GLASS_VALUES.includes(value as GlassReference); }
16
18
 
@@ -29,7 +31,7 @@ function drawBorosilicate(ctx: CanvasRenderingContext2D, radius: number): void {
29
31
 
30
32
  function drawLeadCrystal(ctx: CanvasRenderingContext2D, radius: number): void { drawPolygon(ctx, radius, [[0, -0.68], [0.28, -0.24], [0.74, -0.12], [0.34, 0.18], [0.42, 0.62], [0, 0.36], [-0.46, 0.58], [-0.34, 0.14], [-0.74, -0.16], [-0.26, -0.28]]); }
31
33
 
32
- function drawPolygon(ctx: CanvasRenderingContext2D, radius: number, points: number[][]): void { points.forEach(([x, y], index) => index === 0 ? ctx.moveTo(radius * x, radius * y) : ctx.lineTo(radius * x, radius * y)); }
34
+ function drawPolygon(ctx: CanvasRenderingContext2D, radius: number, points: number[][]): void { points.forEach((point, index) => { const x = point[0] ?? 0; const y = point[1] ?? 0; if (index === 0) ctx.moveTo(radius * x, radius * y); else ctx.lineTo(radius * x, radius * y); }); }
33
35
 
34
36
  function drawGlassPath(ctx: CanvasRenderingContext2D, glass: GlassReference, radius: number): void {
35
37
  if (glass === 'borosilicate') drawBorosilicate(ctx, radius);
@@ -64,11 +66,11 @@ class BeckeLineView {
64
66
  new MutationObserver(() => this.render()).observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
65
67
  }
66
68
 
67
- private labels(): Record<GlassReference, string> { return { sodaLime: this.ui.sodaLime, borosilicate: this.ui.borosilicate, leadCrystal: this.ui.leadCrystal, tempered: this.ui.tempered }; }
69
+ private labels(): Record<GlassReference, string> { return { sodaLime: this.ui.sodaLime ?? 'Soda-lime glass', borosilicate: this.ui.borosilicate ?? 'Borosilicate glass', leadCrystal: this.ui.leadCrystal ?? 'Lead crystal', tempered: this.ui.tempered ?? 'Tempered glass' }; }
68
70
 
69
71
  private setText(id: string, value: string): void { const element = byId(id); if (element) element.textContent = value; }
70
72
 
71
- private formatTemperature(celsius: number, fahrenheit: number): string { return this.unitSystem === 'metric' ? `${celsius.toFixed(1)}\u00b0${this.ui.unitCelsius}` : `${fahrenheit.toFixed(1)}\u00b0${this.ui.unitFahrenheit}`; }
73
+ private formatTemperature(celsius: number, fahrenheit: number): string { return this.unitSystem === 'metric' ? `${celsius.toFixed(1)}\u00b0${this.ui.unitCelsius ?? 'C'}` : `${fahrenheit.toFixed(1)}\u00b0${this.ui.unitFahrenheit ?? 'F'}`; }
72
74
 
73
75
  private updateButtons(): void {
74
76
  document.querySelectorAll<HTMLButtonElement>('[data-becke-unit]').forEach((button) => { button.dataset.active = button.dataset.beckeUnit === this.unitSystem ? 'true' : 'false'; });
@@ -257,8 +259,8 @@ class BeckeLineView {
257
259
 
258
260
  private drawCanvasLabel(result: Result, height: number, textColor: string): void {
259
261
  if (!this.context) return;
260
- const focusLabel = this.focusDirection === 'raised' ? this.ui.focusRaised : this.ui.focusLowered;
261
- const label = result.lineDirection === 'matched' ? this.ui.canvasMatched : `${this.ui.canvasHalo}${this.ui.canvasFocusSeparator}${focusLabel}`;
262
+ const focusLabel = this.focusDirection === 'raised' ? uiText(this.ui, 'focusRaised') : uiText(this.ui, 'focusLowered');
263
+ const label = result.lineDirection === 'matched' ? uiText(this.ui, 'canvasMatched') : `${uiText(this.ui, 'canvasHalo')}${uiText(this.ui, 'canvasFocusSeparator')}${focusLabel}`;
262
264
  this.context.fillStyle = textColor;
263
265
  this.context.font = '600 24px system-ui, sans-serif';
264
266
  this.context.fillText(label, 28, height - 34);
@@ -90,7 +90,7 @@ const { ui } = content;
90
90
  <p class="fia-disclaimer">{ui.disclaimer}</p>
91
91
  </section>
92
92
 
93
- <script id="fia-ui" type="application/json" set:html={JSON.stringify(ui)}></script>
93
+ <script is:inline id="fia-ui" type="application/json" set:html={JSON.stringify(ui)}></script>
94
94
  <script>
95
95
  import { ExifExtractor, IntegrityChecker, createHexSegments } from './logic';
96
96
  import type { ExifMetadata, IntegrityFinding, IntegrityResult } from './logic';
@@ -1,105 +1,105 @@
1
- import { bibliography } from '../bibliography';
2
- import type { ToolLocaleContent } from '../../../types';
3
-
4
- const slug = 'forensischer-bildmetadata-authentizitaets-analysator';
5
- const title = 'Forensischer Bildmetadata und Authentizitätsanalysator';
6
- const description = 'Untersuche Bildheader, EXIF-Aufnahmedaten, GPS-Koordinaten, Signaturen von Bearbeitungssoftware und Rohbytes lokal in deinem Browser.';
7
-
8
- const howTo = [
9
- { name: 'Originalbeweis sichern', text: 'Arbeite mit einer forensischen Kopie und bewahre die Quelldatei sowie ihren kryptografischen Hash außerhalb dieses Browser-Tools auf.' },
10
- { name: 'Bild lokal laden', text: 'Ziehe ein JPEG oder PNG hinein oder wähle eine Datei aus. Die Datei wird nur im Browserspeicher gelesen und nicht hochgeladen.' },
11
- { name: 'Metadaten und Ort prüfen', text: 'Vergleiche Aufnahmezeit, Kameradaten, Software und GPS-Felder mit der Falldarstellung und den Erfassungsunterlagen.' },
12
- { name: 'Integritaetssignale einordnen', text: 'Behandle Editiersignaturen und fehlende Felder als Ermittlungsansaetze, nicht als Beweis fuer Manipulation.' },
13
- { name: 'Hex-Vorschau auswerten', text: 'Nutze die markierten Header- und Metadatenbereiche, um die Containerstruktur zu erkennen und Offsets fuer eine tiefere Analyse zu dokumentieren.' },
14
- ];
15
-
16
- const faq = [
17
- { question: 'Koennen Metadaten beweisen, dass ein Foto echt ist?', answer: 'Nein. Metadaten können entfernt, kopiert oder verändert werden. Eine Authentifizierung erfordert die Kombination aus Dateistruktur, Herkunft, Hashes, visueller Prüfung, Kompressionsanalyse und validierten forensischen Methoden.' },
18
- { question: 'Beweist eine Adobe- oder GIMP-Signatur eine boeswillige Bearbeitung?', answer: 'Nein. Sie zeigt nur an, dass eine Software die Datei oder ihre Metadaten geschrieben oder exportiert haben koennte. Auch legitime Farbkorrektur, redaktionelle Verarbeitung oder Beweisaufbereitung können dieselbe Signatur erzeugen.' },
19
- { question: 'Wird das Bild hochgeladen?', answer: 'Nein. Die Analyse erfolgt im Arbeitsspeicher des Browsers. Beachte trotzdem die Beweisrichtlinien deiner Organisation, bevor du sensibles Material in irgendeiner Software öffnest.' },
20
- { question: 'Warum koennten GPS-Daten fehlen?', answer: 'Die Kamera unterstuetzt möglicherweise kein GPS, die Standortaufzeichnung war deaktiviert, eine Plattform hat Metadaten entfernt oder die Datei wurde neu kodiert.' },
21
- ];
22
-
23
- export const content: ToolLocaleContent = {
24
- slug,
25
- title,
26
- description,
27
- ui: {
28
- privacy: 'Nur lokale Binaeranalyse',
29
- dropTitle: 'Lege ein Bild auf den Beweistisch',
30
- dropHint: 'Ziehe hier ein JPEG oder PNG hinein oder wähle eine Datei. Es wird nichts hochgeladen.',
31
- chooseFile: 'Bild auswählen',
32
- replaceFile: 'Bild ersetzen',
33
- waiting: 'Warte auf Beweisstueck',
34
- metadata: 'Aufnahmemetadaten',
35
- integrity: 'Integritaetssignale',
36
- location: 'Erfasster Ort',
37
- hex: 'Hexadezimales Beweisfenster',
38
- hexHint: 'Erste 512 Bytes - cyanfarbener Header - bernsteinfarbene Metadaten - neutrale Bilddaten',
39
- noData: 'Kein lesbarer Wert',
40
- noGps: 'Es wurden keine lesbaren GPS-Koordinaten gefunden.',
41
- mapLink: 'Koordinaten in OpenStreetMap oeffnen',
42
- score: 'Heuristische Vertrauensstufe',
43
- disclaimer: 'Ein hoher Wert belegt keine Authentizitaet. Bewahre das Original auf, berechne kryptografische Hashes und nutze validierte Labor-Workflows fuer Fallbewertungen.',
44
- fileName: 'Datei',
45
- fileSize: 'Größe',
46
- fileType: 'Container',
47
- camera: 'Kamera',
48
- captured: 'Aufgenommen',
49
- software: 'Software',
50
- coordinates: 'Koordinaten',
51
- statusNoObvious: 'Keine offensichtlichen Bearbeitungshinweise',
52
- statusReview: 'Prüfung empfohlen',
53
- statusEditing: 'Bearbeitungssignatur erkannt',
54
- processing: 'Binaere Beweisdaten werden gelesen...',
55
- loadError: 'Die Datei konnte nicht analysiert werden. Waehle ein gueltiges JPEG- oder PNG-Bild aus.',
56
- },
57
- seo: [
58
- { type: 'title', text: 'Wie man Bildmetadaten und Authentizitaetssignale analysiert', level: 2 },
59
- { type: 'paragraph', html: 'Ein forensischer Bildmetadata-Analysator hilft Ermittlern, Journalisten, juristischen Teams, Compliance-Pruefern und Sachverstaendigen bei einer haeufig gesuchten Frage: <strong>Was können Bildmetadaten tatsaechlich über ein Foto verraten?</strong> Metadaten können nuetzliche Hinweise zu Aufnahme, Ort, Softwareverarbeitung und Dateistruktur liefern, sind aber keine eigenstaendige Wahrheitsmaschine. Ihr größter Nutzen liegt im Triage-Prozess. Sie helfen dabei zu erkennen, welche Dateien eine tiefere Analyse verdienen, welche Details die behauptete Geschichte des Bildes stuetzen und welche Widersprueche vor einer belastbaren Authentizitaetsaussage weiter geprueft werden muessen.' },
60
- { type: 'paragraph', html: 'Dieses Browser-Tool richtet sich an Nutzer, die mehr wollen als einen rohen EXIF-Dump. Es liest das ausgewaehlte JPEG oder PNG lokal ein und zeigt Kamerafelder, Aufnahmezeitpunkte, Software-Tags, Koordinaten, Containerhinweise und die ersten Bytes der Datei an einem Ort. Damit bedient es Suchintentionen hinter Begriffen wie <em>Foto Authentizitaetsprüfung</em>, <em>EXIF-Metadaten analysieren</em>, <em>woran erkennt man bearbeitete Bilder</em> oder <em>GPS-Metadaten eines Bildes prüfen</em>. Wer danach sucht, moechte in der Regel sowohl Belege als auch Einordnung und nicht nur eine Tag-Liste.' },
61
- { type: 'paragraph', html: 'Der wichtigste Grundsatz ist: Das Ergebnis muss als Kontext gelesen werden, nicht als Urteil. Eine Datei kann nuetzliche Metadaten enthalten und trotzdem irreführend sein. Sie kann nur wenige oder gar keine Metadaten enthalten und dennoch echt sein. Eine Softwaresignatur kann auf normales Exportverhalten hindeuten statt auf taeuschende Manipulation. Gute forensische Praxis behandelt Metadaten deshalb als eine Beweisebene, die mit Herkunft, Hashes, Zeugenaussagen, Gerätehistorie und validierten Untersuchungsmethoden abgeglichen werden muss.' },
62
- { type: 'title', text: 'Was EXIF sagen kann und was nicht', level: 3 },
63
- { type: 'paragraph', html: 'EXIF ist eine TIFF-basierte Metadatenstruktur, die haeufig in JPEG-Dateien eingebettet ist. Sie kann das Aufnahmegeraet, das urspruengliche Datum und die Uhrzeit, die Ausrichtung, Belichtungsparameter und die GPS-Position enthalten. Wenn diese Felder intern stimmig sind und zu den bekannten Umstaenden des Falls passen, können sie eine vorgeschlagene Zeitleiste oder Herkunft stuetzen. Wenn sie der behaupteten Entstehungsgeschichte widersprechen, liefern sie gezielte Fragen fuer die weitere Prüfung.' },
64
- { type: 'paragraph', html: 'Einer der größten Irrtuemer hinter Suchanfragen zu Bildmetadaten ist die Annahme, EXIF sei standardmaessig vertrauenswuerdig. Das ist nicht so. Metadaten können bearbeitet, zwischen Dateien kopiert, von sozialen Netzwerken entfernt, beim Export verändert, durch Cloud-Plattformen normalisiert oder bei der Neukodierung teilweise beschaedigt werden. Die bessere Frage lautet daher nicht nur, ob Metadaten vorhanden sind, sondern ob sie technisch kohaerent, kontextuell plausibel und durch unabhaengige Beweise gestuetzt sind.' },
65
- { type: 'table', headers: ['Beobachtung', 'Moegliche Bedeutung', 'Erforderliche Vorsicht'], rows: [
66
- ['Kameramarke und -modell vorhanden', 'Die Datei enthaelt Gerätekennungs-Tags.', 'Tags können kopiert oder umgeschrieben werden und identifizieren die physische Kamera nicht allein.'],
67
- ['GPS-Koordinaten vorhanden', 'In den Metadaten wurde ein Ort gespeichert.', 'Pruefe Vorzeichen, Datum, Zeitstempel und Uebereinstimmung mit unabhaengigen Beweisen.'],
68
- ['Software-Tag nennt einen Editor', 'Die genannte Anwendung hat die Datei wahrscheinlich geschrieben oder exportiert.', 'Das beweist keine taeuschende Montage oder inhaltliche Veraenderung.'],
69
- ['Aufnahmedatum fehlt', 'Das relevante Tag fehlt oder ist nicht lesbar.', 'Fehlende Daten können auf Privatsphaere-Einstellungen, Transkodierung oder Metadatenentfernung zurückgehen.'],
70
- ] },
71
- { type: 'title', text: 'Was Nutzer meist mit "Ist dieses Foto authentisch?" meinen', level: 3 },
72
- { type: 'paragraph', html: 'In der Praxis meinen Menschen, die nach Bildauthentizitaetsprüfungen suchen, oft unterschiedliche Dinge. Sie wollen wissen, ob die Datei direkt aus einer Kamera stammt, ob Bearbeitungssoftware sie beruehrt hat, ob das behauptete Datum oder der Ort plausibel wirken, ob die Dateistruktur normal aussieht oder ob unmittelbare Gruende zum Misstrauen bestehen. Ein nuetzlicher Analysator sollte diese Fragen auseinanderhalten, statt alles in ein vereinfachtes Ja-oder-Nein zu pressen.' },
73
- { type: 'paragraph', html: 'Dieses Tool trennt deshalb zwischen <strong>Beobachtungen</strong> und <strong>Heuristiken</strong>. Beobachtungen sind Dinge, die die Datei tatsaechlich zu enthalten scheint, zum Beispiel ein lesbares Softwarefeld oder ein Koordinatenpaar. Heuristiken sind risikoorientierte Einordnungen, etwa ob eine Editor-Signatur überprueft werden sollte. Diese Trennung ist sowohl fuer die Nutzbarkeit als auch fuer SEO wertvoll, weil sie eine reale Nutzerfrage beantwortet: Was sagt die Datei, was schließt das Tool daraus und wo bleibt menschliches Urteil unverzichtbar?' },
74
- { type: 'title', text: 'Bearbeitungssoftware-Signaturen richtig deuten', level: 3 },
75
- { type: 'paragraph', html: 'Namen wie Adobe Photoshop, Lightroom, GIMP, Snapseed oder ImageMagick können als Klartext in Metadaten oder Anwendungssegmenten erscheinen. Ihre Praesenz ist ein Herkunftshinweis zur Dateiverarbeitung, aber kein Beweis dafuer, dass Pixel boeswillig verändert wurden. Gerade hier liegt eine sehr haeufige Suchintention, weil viele Nutzer annehmen, der Name eines Editors bedeute automatisch Manipulation. Tatsaechlich können auch normales Skalieren, Formatumwandlung, Farbkorrektur, redaktionelle Verarbeitung, Schwaerzung oder Beweisaufbereitung dieselbe Signatur hinterlassen.' },
76
- { type: 'paragraph', html: 'Eine bessere Einordnung fragt danach, welche Rolle die genannte Software plausibel gespielt hat. Hat sie das Bild fuer das Web verkleinert? Beim Export Metadaten entfernt? Einen Screenshot gespeichert? Eine Social-Media-Kopie neu kodiert? Ein Farbprofil hinzugefuegt? Dieselbe Zeichenfolge kann je nach Workflow sehr unterschiedliche Geschichten stuetzen. Sachverstaendige sollten die Signatur mit dem erwarteten Verarbeitungsverlauf vergleichen und bei entsprechendem Risiko zu tieferen Methoden wie Quantisierungstabellen-Prüfung, Kompressionshistorien-Analyse, Thumbnail-Vergleich, Sensorpattern-Untersuchung und Pixeltests übergehen.' },
77
- { type: 'title', text: 'GPS-Metadaten verantwortungsvoll lesen', level: 3 },
78
- { type: 'paragraph', html: 'GPS-Metadaten können sehr wertvoll sein, weil sie ein Bild mit einem Ort verknuepfen können. Gleichzeitig werden sie oft überinterpretiert. Koordinaten sollten auf Hemisphaeren-Vorzeichen, Dezimalpraezision, zeitliche Zuordnung und Stimmigkeit mit dem Rest der Datei geprueft werden. Ein Koordinatenpaar, das praezise aussieht, ist nicht automatisch verlaesslich. Es kann auf alten Gerätestatus, manuelle Bearbeitung, Exportverhalten oder eine gemeinsam geteilte Medienhistorie zurückgehen. Fehlende GPS-Daten bedeuten ebenfalls nicht automatisch Verschleierung, weil viele Kameras nie Standortdaten speichern und viele Plattformen sie standardmaessig entfernen.' },
79
- { type: 'paragraph', html: 'Fuer Nutzer, die über Suchanfragen zu Foto-Geolokalisierung oder metadatenbasierter Ortsprüfung kommen, ist Vergleich der verlaesslichste Ansatz. Behandle Koordinaten als einen Hinweis unter mehreren. Vergleiche sie mit Zeugenaussagen, Reiseverlauf, markanten Szenenmerkmalen, Wetter, Netzwerkdaten, Cloud-Backups und Geräteeintraegen, sofern dies rechtlich zulaessig ist. Der eigentliche Wert der Metadaten liegt darin, wie gut sie in das groessere Beweisbild passen.' },
80
- { type: 'title', text: 'Warum die hexadezimale Ansicht wichtig ist', level: 3 },
81
- { type: 'paragraph', html: 'Ein Hex-Viewer zeigt die tatsaechlichen Bytewerte und Offsets, aus denen die Datei besteht. Das ist wichtig, weil viele Fragen zur Authentizitaet in Wahrheit Strukturfragen sind. JPEG-Dateien beginnen üblicherweise mit dem SOI-Marker FF D8, gefolgt von Segmenten wie APP0 oder APP1. EXIF liegt haeufig in APP1. PNG-Dateien starten mit einer Acht-Byte-Signatur und setzen sich als benannte Chunks fort. Ein Blick auf die ersten Bytes hilft zu prüfen, ob eine Datei zumindest wie der Container aussieht, der sie vorgibt zu sein, und bietet erfahrenen Pruefern eine schnelle Möglichkeit, Offsets fuer spaetere Berichte festzuhalten.' },
82
- { type: 'paragraph', html: 'Strukturelle Auffälligkeiten bedeuten nicht automatisch Manipulation, da sich legitime Encoder unterscheiden. Trotzdem ist Byte-Sichtbarkeit wertvoll, wenn eine Datei beschaedigt, falsch bezeichnet, teilweise überschrieben oder mit ihrer Endung unvereinbar erscheint. Viele Nutzer, die nach einem Bildforensik-Tool suchen, moechten Transparenz statt Blackbox. Wenn Header und Metadatenzonen direkt sichtbar sind, wird leichter nachvollziehbar, wo die Interpretation beginnt.' },
83
- { type: 'title', text: 'Ein praktischer Workflow fuer die Metadatenprüfung', level: 3 },
84
- { type: 'paragraph', html: 'Ein belastbarer Workflow beginnt vor der EXIF-Prüfung. Bewahre die Quelldatei auf, berechne einen kryptografischen Hash und behandle eine im Browser geladene Arbeitskopie niemals als beweisrelevantes Master. Pruefe danach gemeinsam den Container, die Dateieigenschaften, die Aufnahmefelder, die Softwarefelder und die GPS-Koordinaten. Suche zunaechst nach interner Stimmigkeit. Anschliessend vergleichst du, was die Datei erzählt, mit dem, was der Fall erzählt. In vielen Ermittlungen entsteht die nuetzlichste Erkenntnis aus der Abweichung zwischen diesen beiden Geschichten.' },
85
- { type: 'paragraph', html: 'Das ist auch fuer die Suchintention wichtig, weil viele Nutzer eben nicht nur eine Tag-Liste wollen. Sie moechten wissen, was sie nach dem Anblick eines Datums, einer Softwarebezeichnung oder eines Koordinatenpaars tun sollen. In den meisten Faellen bedeutet das: Beobachtung dokumentieren, Einschraenkung festhalten und entscheiden, ob die Datei eine tiefere Untersuchung mit laborzugelassenen Methoden benoetigt. Metadatenanalyse ist ein Einstiegsschritt, nicht die ganze Untersuchung.' },
86
- { type: 'title', text: 'Checkliste fuer den forensischen Workflow', level: 3 },
87
- { type: 'list', items: [
88
- '<strong>Sichern:</strong> Behandle eine im Browser geladene Arbeitskopie niemals als beweisrelevantes Master.',
89
- '<strong>Hashen:</strong> Erfasse einen kryptografischen Hash bei der Sicherung und nach jeder autorisierten Uebertragung.',
90
- '<strong>Abgleichen:</strong> Vergleiche Metadaten mit Gerätedaten, Cloud-Eintraegen, Zeugenaussagen und Tatsachen am Tatort.',
91
- '<strong>Dokumentieren:</strong> Halte Softwareversionen, Einstellungen, Offsets, Beobachtungen und Screenshots fuer die Reproduzierbarkeit fest.',
92
- '<strong>Validieren:</strong> Nutze laborzugelassene Werkzeuge und Peer Review, bevor du eine formale Authentizitaetsaussage triffst.',
93
- ] },
94
- { type: 'title', text: 'Wann Metadatenprüfung nicht ausreicht', level: 3 },
95
- { type: 'paragraph', html: 'Manchmal wirken die Metadaten sauber und das Bild ist trotzdem irreführend. Manchmal erscheinen die Metadaten verdaechtig und das Bild ist dennoch authentisch. Deshalb brauchen fortgeschrittene forensische Schlussfolgerungen mehr als Dateitags. Je nach Fallgewicht können Folgeschritte Kompressionsartefakt-Analyse, Quantisierungstabellen-Vergleich, Prüfung inkonsistenter Thumbnails, Pixeluntersuchung, Rekonstruktion der Herkunft und Review der Chain of Custody umfassen. Guter SEO-Inhalt sagt das klar, weil er damit die eigentliche Frage hinter vielen Suchanfragen beantwortet: Was kann dieses Tool leisten und wo beginnen seine Grenzen?' },
96
- ],
97
- faq,
98
- bibliography,
99
- howTo,
100
- schemas: [
101
- { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: title, description, applicationCategory: 'ForensicApplication', operatingSystem: 'Any' },
102
- { '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) },
103
- { '@context': 'https://schema.org', '@type': 'HowTo', name: title, step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) },
104
- ],
105
- };
1
+ import { bibliography } from '../bibliography';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+
4
+ const slug = 'forensischer-bildmetadata-authentizitaets-analysator';
5
+ const title = 'Forensischer Bildmetadata und Authentizitätsanalysator';
6
+ const description = 'Untersuche Bildheader, EXIF-Aufnahmedaten, GPS-Koordinaten, Signaturen von Bearbeitungssoftware und Rohbytes lokal in deinem Browser.';
7
+
8
+ const howTo = [
9
+ { name: 'Originalbeweis sichern', text: 'Arbeite mit einer forensischen Kopie und bewahre die Quelldatei sowie ihren kryptografischen Hash außerhalb dieses Browser-Tools auf.' },
10
+ { name: 'Bild lokal laden', text: 'Ziehe ein JPEG oder PNG hinein oder wähle eine Datei aus. Die Datei wird nur im Browserspeicher gelesen und nicht hochgeladen.' },
11
+ { name: 'Metadaten und Ort prüfen', text: 'Vergleiche Aufnahmezeit, Kameradaten, Software und GPS-Felder mit der Falldarstellung und den Erfassungsunterlagen.' },
12
+ { name: 'Integritaetssignale einordnen', text: 'Behandle Editiersignaturen und fehlende Felder als Ermittlungsansaetze, nicht als Beweis fuer Manipulation.' },
13
+ { name: 'Hex-Vorschau auswerten', text: 'Nutze die markierten Header- und Metadatenbereiche, um die Containerstruktur zu erkennen und Offsets fuer eine tiefere Analyse zu dokumentieren.' },
14
+ ];
15
+
16
+ const faq = [
17
+ { question: 'Koennen Metadaten beweisen, dass ein Foto echt ist?', answer: 'Nein. Metadaten können entfernt, kopiert oder verändert werden. Eine Authentifizierung erfordert die Kombination aus Dateistruktur, Herkunft, Hashes, visueller Prüfung, Kompressionsanalyse und validierten forensischen Methoden.' },
18
+ { question: 'Beweist eine Adobe- oder GIMP-Signatur eine boeswillige Bearbeitung?', answer: 'Nein. Sie zeigt nur an, dass eine Software die Datei oder ihre Metadaten geschrieben oder exportiert haben koennte. Auch legitime Farbkorrektur, redaktionelle Verarbeitung oder Beweisaufbereitung können dieselbe Signatur erzeugen.' },
19
+ { question: 'Wird das Bild hochgeladen?', answer: 'Nein. Die Analyse erfolgt im Arbeitsspeicher des Browsers. Beachte trotzdem die Beweisrichtlinien deiner Organisation, bevor du sensibles Material in irgendeiner Software öffnest.' },
20
+ { question: 'Warum koennten GPS-Daten fehlen?', answer: 'Die Kamera unterstuetzt möglicherweise kein GPS, die Standortaufzeichnung war deaktiviert, eine Plattform hat Metadaten entfernt oder die Datei wurde neu kodiert.' },
21
+ ];
22
+
23
+ export const content: ToolLocaleContent = {
24
+ slug,
25
+ title,
26
+ description,
27
+ ui: {
28
+ privacy: 'Nur lokale Binaeranalyse',
29
+ dropTitle: 'Lege ein Bild auf den Beweistisch',
30
+ dropHint: 'Ziehe hier ein JPEG oder PNG hinein oder wähle eine Datei. Es wird nichts hochgeladen.',
31
+ chooseFile: 'Bild auswählen',
32
+ replaceFile: 'Bild ersetzen',
33
+ waiting: 'Warte auf Beweisstueck',
34
+ metadata: 'Aufnahmemetadaten',
35
+ integrity: 'Integritaetssignale',
36
+ location: 'Erfasster Ort',
37
+ hex: 'Hexadezimales Beweisfenster',
38
+ hexHint: 'Erste 512 Bytes - cyanfarbener Header - bernsteinfarbene Metadaten - neutrale Bilddaten',
39
+ noData: 'Kein lesbarer Wert',
40
+ noGps: 'Es wurden keine lesbaren GPS-Koordinaten gefunden.',
41
+ mapLink: 'Koordinaten in OpenStreetMap oeffnen',
42
+ score: 'Heuristische Vertrauensstufe',
43
+ disclaimer: 'Ein hoher Wert belegt keine Authentizitaet. Bewahre das Original auf, berechne kryptografische Hashes und nutze validierte Labor-Workflows fuer Fallbewertungen.',
44
+ fileName: 'Datei',
45
+ fileSize: 'Größe',
46
+ fileType: 'Container',
47
+ camera: 'Kamera',
48
+ captured: 'Aufgenommen',
49
+ software: 'Software',
50
+ coordinates: 'Koordinaten',
51
+ statusNoObvious: 'Keine offensichtlichen Bearbeitungshinweise',
52
+ statusReview: 'Prüfung empfohlen',
53
+ statusEditing: 'Bearbeitungssignatur erkannt',
54
+ processing: 'Binaere Beweisdaten werden gelesen...',
55
+ loadError: 'Die Datei konnte nicht analysiert werden. Waehle ein gueltiges JPEG- oder PNG-Bild aus.',
56
+ },
57
+ seo: [
58
+ { type: 'title', text: 'Wie man Bildmetadaten und Authentizitaetssignale analysiert', level: 2 },
59
+ { type: 'paragraph', html: 'Ein forensischer Bildmetadata-Analysator hilft Ermittlern, Journalisten, juristischen Teams, Compliance-Pruefern und Sachverstaendigen bei einer haeufig gesuchten Frage: <strong>Was können Bildmetadaten tatsaechlich über ein Foto verraten?</strong> Metadaten können nuetzliche Hinweise zu Aufnahme, Ort, Softwareverarbeitung und Dateistruktur liefern, sind aber keine eigenstaendige Wahrheitsmaschine. Ihr größter Nutzen liegt im Triage-Prozess. Sie helfen dabei zu erkennen, welche Dateien eine tiefere Analyse verdienen, welche Details die behauptete Geschichte des Bildes stuetzen und welche Widersprueche vor einer belastbaren Authentizitaetsaussage weiter geprueft werden muessen.' },
60
+ { type: 'paragraph', html: 'Dieses Browser-Tool richtet sich an Nutzer, die mehr wollen als einen rohen EXIF-Dump. Es liest das ausgewaehlte JPEG oder PNG lokal ein und zeigt Kamerafelder, Aufnahmezeitpunkte, Software-Tags, Koordinaten, Containerhinweise und die ersten Bytes der Datei an einem Ort. Damit bedient es Suchintentionen hinter Begriffen wie <em>Foto Authentizitaetsprüfung</em>, <em>EXIF-Metadaten analysieren</em>, <em>woran erkennt man bearbeitete Bilder</em> oder <em>GPS-Metadaten eines Bildes prüfen</em>. Wer danach sucht, moechte in der Regel sowohl Belege als auch Einordnung und nicht nur eine Tag-Liste.' },
61
+ { type: 'paragraph', html: 'Der wichtigste Grundsatz ist: Das Ergebnis muss als Kontext gelesen werden, nicht als Urteil. Eine Datei kann nuetzliche Metadaten enthalten und trotzdem irreführend sein. Sie kann nur wenige oder gar keine Metadaten enthalten und dennoch echt sein. Eine Softwaresignatur kann auf normales Exportverhalten hindeuten statt auf taeuschende Manipulation. Gute forensische Praxis behandelt Metadaten deshalb als eine Beweisebene, die mit Herkunft, Hashes, Zeugenaussagen, Gerätehistorie und validierten Untersuchungsmethoden abgeglichen werden muss.' },
62
+ { type: 'title', text: 'Was EXIF sagen kann und was nicht', level: 3 },
63
+ { type: 'paragraph', html: 'EXIF ist eine TIFF-basierte Metadatenstruktur, die haeufig in JPEG-Dateien eingebettet ist. Sie kann das Aufnahmegeraet, das urspruengliche Datum und die Uhrzeit, die Ausrichtung, Belichtungsparameter und die GPS-Position enthalten. Wenn diese Felder intern stimmig sind und zu den bekannten Umstaenden des Falls passen, können sie eine vorgeschlagene Zeitleiste oder Herkunft stuetzen. Wenn sie der behaupteten Entstehungsgeschichte widersprechen, liefern sie gezielte Fragen fuer die weitere Prüfung.' },
64
+ { type: 'paragraph', html: 'Einer der größten Irrtuemer hinter Suchanfragen zu Bildmetadaten ist die Annahme, EXIF sei standardmaessig vertrauenswuerdig. Das ist nicht so. Metadaten können bearbeitet, zwischen Dateien kopiert, von sozialen Netzwerken entfernt, beim Export verändert, durch Cloud-Plattformen normalisiert oder bei der Neukodierung teilweise beschaedigt werden. Die bessere Frage lautet daher nicht nur, ob Metadaten vorhanden sind, sondern ob sie technisch kohaerent, kontextuell plausibel und durch unabhaengige Beweise gestuetzt sind.' },
65
+ { type: 'table', headers: ['Beobachtung', 'Moegliche Bedeutung', 'Erforderliche Vorsicht'], rows: [
66
+ ['Kameramarke und -modell vorhanden', 'Die Datei enthaelt Gerätekennungs-Tags.', 'Tags können kopiert oder umgeschrieben werden und identifizieren die physische Kamera nicht allein.'],
67
+ ['GPS-Koordinaten vorhanden', 'In den Metadaten wurde ein Ort gespeichert.', 'Pruefe Vorzeichen, Datum, Zeitstempel und Uebereinstimmung mit unabhaengigen Beweisen.'],
68
+ ['Software-Tag nennt einen Editor', 'Die genannte Anwendung hat die Datei wahrscheinlich geschrieben oder exportiert.', 'Das beweist keine taeuschende Montage oder inhaltliche Veraenderung.'],
69
+ ['Aufnahmedatum fehlt', 'Das relevante Tag fehlt oder ist nicht lesbar.', 'Fehlende Daten können auf Privatsphaere-Einstellungen, Transkodierung oder Metadatenentfernung zurückgehen.'],
70
+ ] },
71
+ { type: 'title', text: 'Was Nutzer meist mit "Ist dieses Foto authentisch?" meinen', level: 3 },
72
+ { type: 'paragraph', html: 'In der Praxis meinen Menschen, die nach Bildauthentizitaetsprüfungen suchen, oft unterschiedliche Dinge. Sie wollen wissen, ob die Datei direkt aus einer Kamera stammt, ob Bearbeitungssoftware sie beruehrt hat, ob das behauptete Datum oder der Ort plausibel wirken, ob die Dateistruktur normal aussieht oder ob unmittelbare Gruende zum Misstrauen bestehen. Ein nuetzlicher Analysator sollte diese Fragen auseinanderhalten, statt alles in ein vereinfachtes Ja-oder-Nein zu pressen.' },
73
+ { type: 'paragraph', html: 'Dieses Tool trennt deshalb zwischen <strong>Beobachtungen</strong> und <strong>Heuristiken</strong>. Beobachtungen sind Dinge, die die Datei tatsaechlich zu enthalten scheint, zum Beispiel ein lesbares Softwarefeld oder ein Koordinatenpaar. Heuristiken sind risikoorientierte Einordnungen, etwa ob eine Editor-Signatur überprueft werden sollte. Diese Trennung ist sowohl fuer die Nutzbarkeit als auch fuer SEO wertvoll, weil sie eine reale Nutzerfrage beantwortet: Was sagt die Datei, was schließt das Tool daraus und wo bleibt menschliches Urteil unverzichtbar?' },
74
+ { type: 'title', text: 'Bearbeitungssoftware-Signaturen richtig deuten', level: 3 },
75
+ { type: 'paragraph', html: 'Namen wie Adobe Photoshop, Lightroom, GIMP, Snapseed oder ImageMagick können als Klartext in Metadaten oder Anwendungssegmenten erscheinen. Ihre Praesenz ist ein Herkunftshinweis zur Dateiverarbeitung, aber kein Beweis dafuer, dass Pixel boeswillig verändert wurden. Gerade hier liegt eine sehr haeufige Suchintention, weil viele Nutzer annehmen, der Name eines Editors bedeute automatisch Manipulation. Tatsaechlich können auch normales Skalieren, Formatumwandlung, Farbkorrektur, redaktionelle Verarbeitung, Schwaerzung oder Beweisaufbereitung dieselbe Signatur hinterlassen.' },
76
+ { type: 'paragraph', html: 'Eine bessere Einordnung fragt danach, welche Rolle die genannte Software plausibel gespielt hat. Hat sie das Bild fuer das Web verkleinert? Beim Export Metadaten entfernt? Einen Screenshot gespeichert? Eine Social-Media-Kopie neu kodiert? Ein Farbprofil hinzugefuegt? Dieselbe Zeichenfolge kann je nach Workflow sehr unterschiedliche Geschichten stuetzen. Sachverstaendige sollten die Signatur mit dem erwarteten Verarbeitungsverlauf vergleichen und bei entsprechendem Risiko zu tieferen Methoden wie Quantisierungstabellen-Prüfung, Kompressionshistorien-Analyse, Thumbnail-Vergleich, Sensorpattern-Untersuchung und Pixeltests übergehen.' },
77
+ { type: 'title', text: 'GPS-Metadaten verantwortungsvoll lesen', level: 3 },
78
+ { type: 'paragraph', html: 'GPS-Metadaten können sehr wertvoll sein, weil sie ein Bild mit einem Ort verknuepfen können. Gleichzeitig werden sie oft überinterpretiert. Koordinaten sollten auf Hemisphaeren-Vorzeichen, Dezimalpraezision, zeitliche Zuordnung und Stimmigkeit mit dem Rest der Datei geprueft werden. Ein Koordinatenpaar, das praezise aussieht, ist nicht automatisch verlaesslich. Es kann auf alten Gerätestatus, manuelle Bearbeitung, Exportverhalten oder eine gemeinsam geteilte Medienhistorie zurückgehen. Fehlende GPS-Daten bedeuten ebenfalls nicht automatisch Verschleierung, weil viele Kameras nie Standortdaten speichern und viele Plattformen sie standardmaessig entfernen.' },
79
+ { type: 'paragraph', html: 'Fuer Nutzer, die über Suchanfragen zu Foto-Geolokalisierung oder metadatenbasierter Ortsprüfung kommen, ist Vergleich der verlaesslichste Ansatz. Behandle Koordinaten als einen Hinweis unter mehreren. Vergleiche sie mit Zeugenaussagen, Reiseverlauf, markanten Szenenmerkmalen, Wetter, Netzwerkdaten, Cloud-Backups und Geräteeintraegen, sofern dies rechtlich zulaessig ist. Der eigentliche Wert der Metadaten liegt darin, wie gut sie in das groessere Beweisbild passen.' },
80
+ { type: 'title', text: 'Warum die hexadezimale Ansicht wichtig ist', level: 3 },
81
+ { type: 'paragraph', html: 'Ein Hex-Viewer zeigt die tatsaechlichen Bytewerte und Offsets, aus denen die Datei besteht. Das ist wichtig, weil viele Fragen zur Authentizitaet in Wahrheit Strukturfragen sind. JPEG-Dateien beginnen üblicherweise mit dem SOI-Marker FF D8, gefolgt von Segmenten wie APP0 oder APP1. EXIF liegt haeufig in APP1. PNG-Dateien starten mit einer Acht-Byte-Signatur und setzen sich als benannte Chunks fort. Ein Blick auf die ersten Bytes hilft zu prüfen, ob eine Datei zumindest wie der Container aussieht, der sie vorgibt zu sein, und bietet erfahrenen Pruefern eine schnelle Möglichkeit, Offsets fuer spaetere Berichte festzuhalten.' },
82
+ { type: 'paragraph', html: 'Strukturelle Auffälligkeiten bedeuten nicht automatisch Manipulation, da sich legitime Encoder unterscheiden. Trotzdem ist Byte-Sichtbarkeit wertvoll, wenn eine Datei beschaedigt, falsch bezeichnet, teilweise überschrieben oder mit ihrer Endung unvereinbar erscheint. Viele Nutzer, die nach einem Bildforensik-Tool suchen, moechten Transparenz statt Blackbox. Wenn Header und Metadatenzonen direkt sichtbar sind, wird leichter nachvollziehbar, wo die Interpretation beginnt.' },
83
+ { type: 'title', text: 'Ein praktischer Workflow fuer die Metadatenprüfung', level: 3 },
84
+ { type: 'paragraph', html: 'Ein belastbarer Workflow beginnt vor der EXIF-Prüfung. Bewahre die Quelldatei auf, berechne einen kryptografischen Hash und behandle eine im Browser geladene Arbeitskopie niemals als beweisrelevantes Master. Pruefe danach gemeinsam den Container, die Dateieigenschaften, die Aufnahmefelder, die Softwarefelder und die GPS-Koordinaten. Suche zunaechst nach interner Stimmigkeit. Anschliessend vergleichst du, was die Datei erzählt, mit dem, was der Fall erzählt. In vielen Ermittlungen entsteht die nuetzlichste Erkenntnis aus der Abweichung zwischen diesen beiden Geschichten.' },
85
+ { type: 'paragraph', html: 'Das ist auch fuer die Suchintention wichtig, weil viele Nutzer eben nicht nur eine Tag-Liste wollen. Sie moechten wissen, was sie nach dem Anblick eines Datums, einer Softwarebezeichnung oder eines Koordinatenpaars tun sollen. In den meisten Faellen bedeutet das: Beobachtung dokumentieren, Einschraenkung festhalten und entscheiden, ob die Datei eine tiefere Untersuchung mit laborzugelassenen Methoden benoetigt. Metadatenanalyse ist ein Einstiegsschritt, nicht die ganze Untersuchung.' },
86
+ { type: 'title', text: 'Checkliste fuer den forensischen Workflow', level: 3 },
87
+ { type: 'list', items: [
88
+ '<strong>Sichern:</strong> Behandle eine im Browser geladene Arbeitskopie niemals als beweisrelevantes Master.',
89
+ '<strong>Hashen:</strong> Erfasse einen kryptografischen Hash bei der Sicherung und nach jeder autorisierten Uebertragung.',
90
+ '<strong>Abgleichen:</strong> Vergleiche Metadaten mit Gerätedaten, Cloud-Eintraegen, Zeugenaussagen und Tatsachen am Tatort.',
91
+ '<strong>Dokumentieren:</strong> Halte Softwareversionen, Einstellungen, Offsets, Beobachtungen und Screenshots fuer die Reproduzierbarkeit fest.',
92
+ '<strong>Validieren:</strong> Nutze laborzugelassene Werkzeuge und Peer Review, bevor du eine formale Authentizitaetsaussage triffst.',
93
+ ] },
94
+ { type: 'title', text: 'Wann Metadatenprüfung nicht ausreicht', level: 3 },
95
+ { type: 'paragraph', html: 'Manchmal wirken die Metadaten sauber und das Bild ist trotzdem irreführend. Manchmal erscheinen die Metadaten verdaechtig und das Bild ist dennoch authentisch. Deshalb brauchen fortgeschrittene forensische Schlussfolgerungen mehr als Dateitags. Je nach Fallgewicht können Folgeschritte Kompressionsartefakt-Analyse, Quantisierungstabellen-Vergleich, Prüfung inkonsistenter Thumbnails, Pixeluntersuchung, Rekonstruktion der Herkunft und Review der Chain of Custody umfassen. Guter SEO-Inhalt sagt das klar, weil er damit die eigentliche Frage hinter vielen Suchanfragen beantwortet: Was kann dieses Tool leisten und wo beginnen seine Grenzen?' },
96
+ ],
97
+ faq,
98
+ bibliography,
99
+ howTo,
100
+ schemas: [
101
+ { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: title, description, applicationCategory: 'ForensicApplication', operatingSystem: 'Any' },
102
+ { '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) },
103
+ { '@context': 'https://schema.org', '@type': 'HowTo', name: title, step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })) },
104
+ ],
105
+ };