Swedish adaptation: Instegscertifikat and HAREC content

- Sections and slides rewritten in Swedish; German law and institutions replaced by
  Swedish/CEPT/ITU equivalents (PTS, SSA, PTSFS 2025:1, SSMFS 2008:18), unverified
  statements marked "% TODO VERIFY"
- New toc: INSTEG, HAREC, UPPGRADERING; section idents are Swedish (see ident-map.tsv)
- Exam-question tags, BNetzA question pool, solutions and the German SWL course removed
- Static pages, snippets, applets, READMEs and image alt-texts translated
- TikZ labels translated; SVG drawings regenerated (drawing 689 still fails to build
  upstream: it references a missing photo)
- Changed from the original: not endorsed by DARC e.V., SSA or PTS

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
2026-10-10 15:03:03 +02:00
co-authored by Claude Sonnet 5.5
parent 0d034a0902
commit f7fa8cfbc1
3234 changed files with 84960 additions and 137393 deletions
+42 -39
View File
@@ -129,9 +129,9 @@
<!-- Controls -->
<div class="controls">
<div class="control-row">
<span class="control-label">Abtastrate $f_\text{s}$:</span>
<span class="control-label">Samplingsfrekvens $f_\text{s}$:</span>
<input type="range" id="sliderFs" min="1.0" max="8.0" step="0.025" value="3.0">
<span class="control-value" id="labelFs">3.0 kHz</span>
<span class="control-value" id="labelFs">3,0 kHz</span>
</div>
</div>
@@ -139,7 +139,7 @@
<div class="panel">
<div class="panel-label">
<span class="dot" style="background:var(--signal-color)"></span>
Originalsignal — Sinus mit 1kHz
Originalsignal — sinus på 1 kHz
</div>
<canvas id="canvasOriginal" height="300"></canvas>
</div>
@@ -148,7 +148,7 @@
<div class="panel">
<div class="panel-label">
<span class="dot" style="background:var(--sample-color)"></span>
Abgetastetes Signal
Samplad signal
</div>
<canvas id="canvasSampled" height="300"></canvas>
</div>
@@ -157,15 +157,15 @@
<div class="panel">
<div class="panel-label">
<span class="dot" style="background:var(--recon-color)"></span>
Rekonstruiertes Signal
Rekonstruerad signal
</div>
<canvas id="canvasRecon" height="300"></canvas>
</div>
<!-- Info box -->
<div class="info-box" id="infoBox">
<strong>✓ Nyquist-Bedingung erfüllt:</strong>
f<sub>s</sub> = 3.0 kHz ≥ 2 · 1 kHz. Das rekonstruierte Signal stimmt mit dem Original überein.
<strong>✓ Nyquistvillkoret är uppfyllt:</strong>
f<sub>s</sub> = 3,0 kHz ≥ 2 · 1 kHz. Den rekonstruerade signalen stämmer överens med originalet.
</div><br>
</div>
</div>
@@ -173,13 +173,13 @@
<script>
// ============================================================
// Signal- und Darstellungsparameter
// Signal- och visningsparametrar
// ============================================================
const F_SIG = 1.0; // Signalfrequenz (normiert auf 1)
const T_SHOW = 3.0; // Angezeigte Zeitdauer in Perioden
const N_DRAW = 1000; // Stützpunkte für analoge Kurve
const F_SIG = 1.0; // signalfrekvens (normerad till 1)
const T_SHOW = 3.0; // visad tidslängd i perioder
const N_DRAW = 1000; // punkter för den analoga kurvan
// Sinc-Funktion (normierte Version: sinc(u) = sin(πu)/(πu))
// sinc-funktion (normerad version: sinc(u) = sin(πu)/(πu))
function sinc(u) {
if (Math.abs(u) < 1e-10) return 1.0;
return Math.sin(Math.PI * u) / (Math.PI * u);
@@ -190,7 +190,7 @@ function signal(t) {
return Math.sin(2 * Math.PI * F_SIG * t);
}
// Whittaker-Shannon-Rekonstruktion
// Whittaker–Shannon-rekonstruktion
function reconstruct(t, samples, fs) {
let sum = 0;
for (let n = 0; n < samples.length; n++) {
@@ -200,7 +200,7 @@ function reconstruct(t, samples, fs) {
}
// ============================================================
// Canvas-Hilfsklasse
// Hjälpklass för canvas
// ============================================================
class Plot {
constructor(canvas, yMin=-1.3, yMax=1.3) {
@@ -325,7 +325,7 @@ class Plot {
}
// ============================================================
// Globale Plot-Objekte
// Globala plotobjekt
// ============================================================
let plotOrig, plotSamp, plotRecon;
@@ -336,11 +336,11 @@ function initPlots() {
}
// ============================================================
// Haupt-Render-Funktion
// Huvudfunktion för rendering
// ============================================================
function render(fs) {
// --- 1. Abtastwerte erzeugen ---
const Ts = 1 / fs; // Abtastintervall (in Perioden des Signals)
// --- 1. Skapa samplingsvärden ---
const Ts = 1 / fs; // samplingsintervall (i signalperioder)
const nSamples = Math.floor(T_SHOW * fs) + 2;
const samples = [];
for (let n = 0; n < nSamples; n++) {
@@ -348,81 +348,84 @@ function render(fs) {
samples.push({ t, y: signal(t) });
}
// --- 2. Analoge Kurve erzeugen ---
// --- 2. Skapa analog kurva ---
const analogPts = [];
for (let i = 0; i <= N_DRAW; i++) {
const t = (i / N_DRAW) * T_SHOW;
analogPts.push({ t, y: signal(t) });
}
// --- 3. Rekonstruktion (Sinc-Interpolation) ---
// --- 3. Rekonstruktion (sinc-interpolation) ---
const reconPts = [];
for (let i = 0; i <= N_DRAW; i++) {
const t = (i / N_DRAW) * T_SHOW;
reconPts.push({ t, y: reconstruct(t, samples, fs) });
}
// --- 4. Panel 1: Original ---
// --- 4. Panel 1: original ---
plotOrig.clear();
plotOrig.drawLine(analogPts, '#47ABE8', 2.2);
// --- 5. Panel 2: Samples (analog + stems) ---
// --- 5. Panel 2: samplingar (analog + stolpar) ---
plotSamp.clear();
plotSamp.drawLine(analogPts, '#47ABE8', 1.5); // leicht gedämpft im Hintergrund
plotSamp.drawLine(analogPts, '#47ABE8', 1.5); // svagt dämpad i bakgrunden
plotSamp.drawStems(samples, '#FE756C');
// --- 6. Panel 3: Rekonstruktion ---
// --- 6. Panel 3: rekonstruktion ---
const nyquistOk = fs >= 2 * F_SIG;
const reconColor = nyquistOk ? '#3BB583' : '#FE756C';
plotRecon.clear();
// Original als gestrichelte Referenz
// Original som streckad referens
const ctx = plotRecon.ctx;
ctx.save();
ctx.setLineDash([5, 5]);
plotRecon.drawLine(analogPts, '#47ABE8', 1.2);
ctx.setLineDash([]);
ctx.restore();
// Rekonstruiertes Signal
// Rekonstruerad signal
plotRecon.drawLine(reconPts, reconColor, 2.2);
// --- 7. UI-Updates ---
// --- 7. UI-uppdateringar ---
updateUI(fs, nyquistOk);
}
// decimalkomma i visade värden
function sv(s) { return String(s).replace(".", ","); }
function updateUI(fs, ok) {
const infoBox = document.getElementById('infoBox');
const ratio = (fs / F_SIG).toFixed(2);
const fAlias = Math.abs(fs - F_SIG).toFixed(2); // Aliasing-Frequenz (vereinfacht)
const fAlias = Math.abs(fs - F_SIG).toFixed(2); // aliasfrekvens (förenklad)
if (ok) {
infoBox.style.borderLeftColor = '#1565c0';
infoBox.style.background = '#DAEEFA';
infoBox.innerHTML =
`<strong>✓ Nyquist-Bedingung erfüllt:</strong> ` +
`f<sub>s</sub> = ${fs.toFixed(2)} kHz ≥ 2 · ${F_SIG} kHz = ${(2*F_SIG).toFixed(2)} kHz. ` +
`Das rekonstruierte Signal stimmt mit dem Original überein.`;
`<strong>✓ Nyquistvillkoret är uppfyllt:</strong> ` +
`f<sub>s</sub> = ${sv(fs.toFixed(2))} kHz ≥ 2 · ${sv(String(F_SIG))} kHz = ${sv((2*F_SIG).toFixed(2))} kHz. ` +
`Den rekonstruerade signalen stämmer överens med originalet.`;
} else {
infoBox.style.borderLeftColor = '#c62828';
infoBox.style.background = '#FFE3E2';
infoBox.innerHTML =
`<strong>⚠ Aliasing:</strong> f<sub>s</sub> = ${fs.toFixed(2)} kHz < 2 · ${F_SIG} kHz. ` +
`Das rekonstruierte Signal erscheint mit Aliasing-Frequenz ` +
`f<sub>Alias</sub> = |f<sub>s</sub> − f<sub>Signal</sub>| ≈ ${fAlias} kHz. ` +
`Erhöhe die Abtastrate über ${(2*F_SIG).toFixed(1)} kHz, um das Signal korrekt darzustellen.`;
`<strong>⚠ Aliasing:</strong> f<sub>s</sub> = ${sv(fs.toFixed(2))} kHz < 2 · ${sv(String(F_SIG))} kHz. ` +
`Den rekonstruerade signalen uppträder med aliasfrekvensen ` +
`f<sub>alias</sub> = |f<sub>s</sub> − f<sub>signal</sub>| ≈ ${sv(fAlias)} kHz. ` +
`Öka samplingsfrekvensen över ${sv((2*F_SIG).toFixed(1))} kHz för att återge signalen korrekt.`;
}
}
// ============================================================
// Event-Listener & Init
// Händelselyssnare och init
// ============================================================
const slider = document.getElementById('sliderFs');
const labelFs = document.getElementById('labelFs');
slider.addEventListener('input', () => {
const fs = parseFloat(slider.value);
labelFs.textContent = fs.toFixed(2) + ' kHz';
labelFs.textContent = sv(fs.toFixed(2)) + ' kHz';
render(fs);
});
@@ -436,11 +439,11 @@ function onResize() {
window.addEventListener('resize', onResize);
// Erst nach dem Laden initialisieren, wenn Canvas-Dimensionen bekannt sind
// Initiera först efter laddning, när canvasdimensionerna är kända
window.addEventListener('load', () => {
initPlots();
const fs = parseFloat(slider.value);
labelFs.textContent = fs.toFixed(2) + ' kHz';
labelFs.textContent = sv(fs.toFixed(2)) + ' kHz';
render(fs);
});
</script>