// ================== Konfiguration / State ==================
const DEFAULT_CODE = [4, 2, 7, 9];
let code = JSON.parse(localStorage.getItem("escape_code") || "null") || DEFAULT_CODE;
let solvedText = localStorage.getItem("escape_message") || "GEHEIMNIS GEÖFFNET";
const pad = document.getElementById("pad");
// Merke dir das Original-HTML, damit wir es nach einem "Clear" wiederherstellen können
const padTemplate = pad.innerHTML;
// Startwerte der 4 Stellen (0–9)
let digits = [1, 2, 3, 4];
// Elemente-Cache für die Ziffern
let dEls = [];
function cacheDigitEls() {
dEls = [0, 1, 2, 3].map((i) => document.getElementById("d" + i));
}
cacheDigitEls();
// ================== Rendering & UI-Aufbau ==================
const render = () => digits.forEach((v, i) => dEls[i] && (dEls[i].textContent = v));
function wireOpenButton() {
const btn = document.getElementById("openBtn");
if (!btn) return;
btn.addEventListener("click", onOpenClick);
}
wireOpenButton();
// Delegierter Klick-Handler für die Münzen (↑/↓)
pad.addEventListener("click", (ev) => {
const btn = ev.target.closest(".coin");
if (!btn || !pad.contains(btn)) return;
const idx = +btn.dataset.idx;
const dir = btn.dataset.dir;
if (dir === "up") digits[idx] = (digits[idx] + 1) % 10;
if (dir === "down") digits[idx] = (digits[idx] + 9) % 10; // -1 modulo 10
render();
});
function onOpenClick() {
const ok = digits.every((v, i) => v === code[i]);
if (ok) showSolved();
else {
pad.classList.remove("pad--shake");
void pad.offsetWidth;
pad.classList.add("pad--shake");
}
}
function showSolved() {
pad.classList.remove("pad--shake");
pad.classList.add("pad--cleared");
pad.innerHTML = `
${escapeHtml(solvedText)}
`;
}
// UI wieder in den „Zahlenmodus“ versetzen (z. B. nach neuem Code)
function rebuildPadUI() {
pad.classList.remove("pad--cleared");
pad.innerHTML = padTemplate;
cacheDigitEls();
wireOpenButton();
render();
}
// ================== Shortcuts zum Setzen von Nachricht & Code ==================
document.addEventListener("keydown", (e) => {
// Strg (oder Cmd) + Ä -> Nachricht setzen
if ((e.ctrlKey || e.metaKey) && isKey(e, ["ä", "Ä", "m"])) {
e.preventDefault();
const msg = prompt('Nachricht (wird nach dem Öffnen angezeigt):', solvedText);
if (msg !== null) {
const clean = msg.trim();
if (clean) {
solvedText = clean;
localStorage.setItem("escape_message", solvedText);
// Wenn bereits gelöst, die sichtbare Nachricht aktualisieren
if (pad.classList.contains("pad--cleared")) showSolved();
}
}
return;
}
// Strg (oder Cmd) + Ö -> Code setzen
if ((e.ctrlKey || e.metaKey) && isKey(e, ["ö", "Ö", "k"])) {
e.preventDefault();
const input = prompt('Neuen 4-stelligen Code eingeben (z. B. 4279 oder 4,2,7,9):', code.join(""));
if (input !== null) {
const parsed = parseCode(input);
if (parsed) {
code = parsed;
localStorage.setItem("escape_code", JSON.stringify(code));
// Falls wir gerade die solved-Ansicht zeigen: UI wieder zum Schloss zurücksetzen
if (pad.classList.contains("pad--cleared")) rebuildPadUI();
alert("Neuer Code gesetzt: " + code.join(""));
} else {
alert("Ungültiges Format. Bitte genau 4 Ziffern (0–9) angeben.");
}
}
}
});
// ================== Utilities ==================
function parseCode(str) {
if (!str) return null;
// Erlaubt: "4279", "4 2 7 9", "4,2,7,9" etc.
const onlyDigits = str.match(/\d/g);
if (!onlyDigits || onlyDigits.length !== 4) return null;
return onlyDigits.map((d) => +d);
}
// Minimaler HTML-Escape für die Nachricht
function escapeHtml(s) {
return s.replace(/[&<>"']/g, (c) =>
({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[c])
);
}
// Hilfsfunktion: trifft auch Fallback-Tasten (M/K)
function isKey(e, keys) {
const k = (e.key || "").toLowerCase();
return keys.some((x) => k === x.toLowerCase());
}
// Initiales Rendern
render();