/* ========================================================================= KUCHAŘKA KAMILY PEŠEK // PASCAL 7.0 WEB ENGINE (331 RECEPTŮ & 568 JÍDEL) Kulinářská paměť Kamily Pešek & Software-salon ALTÁN (Helena Heroutová) ========================================================================= */ // Audio engine (Retro PC Speaker via Web Audio API) let audioCtx = null; let soundEnabled = true; function playSpeaker(freq = 800, duration = 0.04, type = 'square') { if (!soundEnabled) return; try { if (!audioCtx) { audioCtx = new (window.AudioContext || window.webkitAudioContext)(); } if (audioCtx.state === 'suspended') { audioCtx.resume(); } const osc = audioCtx.createOscillator(); const gain = audioCtx.createGain(); osc.type = type; osc.frequency.setValueAtTime(freq, audioCtx.currentTime); gain.gain.setValueAtTime(0.08, audioCtx.currentTime); gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + duration); osc.connect(gain); gain.connect(audioCtx.destination); osc.start(); osc.stop(audioCtx.currentTime + duration); } catch (e) {} } // Data references const KNIHA_RECEPTU = window.KNIHA_RECEPTU || []; const HISTORICKA_JIDLA = window.HISTORICKA_JIDLA || []; // App State let currentView = 'menu'; // 'menu', 'recept', 'recepty_list', 'suroviny', 'davno', 'oblibena', 'kronika', 'altan' let currentRecipeId = 1; let currentCategory = 'Vše'; let listPage = 0; const PAGE_SIZE = 12; const screenEl = document.getElementById('screen-content'); const winTitleEl = document.getElementById('win-title'); const timeEl = document.getElementById('time-display'); // Clock setInterval(() => { const d = new Date(); timeEl.textContent = d.toTimeString().split(' ')[0]; }, 1000); // Normalization function (strip accents & non-alphanumeric) function norm(str) { return (str || "").toLowerCase() .normalize("NFD").replace(/[\u0300-\u036f]/g, "") .replace(/[^a-z0-9]/g, ""); } // Categories list const KATEGORIE = [ 'Vše', 'Polévky', 'Masitá jídla', 'Vánoční cukroví', 'Moučníky a sladké', 'Přílohy a bezmasá', 'Omáčky', 'Saláty a zelenina' ]; // Views renderers function renderMainMenu() { currentView = 'menu'; winTitleEl.textContent = "KUCHAŘKA KAMILY PEŠEK // HLAVNÍ NABÍDKA PASCAL 7.0"; let html = `
════════════════════════════════════════════════════════════════════════════════ KUCHAŘKA KAMILY PEŠEK // AUTENTICKÝ SEŠIT RECEPTŮ (1998–2026) Software-salon ALTÁN (Ing. Helena Heroutová, Dejvice) & Konzdat ════════════════════════════════════════════════════════════════════════════════
Vítejte v rodinném gastronomickém archivu babičky Kamily Pešek. Tento systém obsahuje ${KNIHA_RECEPTU.length} přepsaných receptů z jejího ručně psaného sešitu (strany 1–43) a ${HISTORICKA_JIDLA.length} záznamů rodinného jídelníčku z let 1998–2021.
── HLAVNÍ PROGRAMOVÉ MODULY ────────────────────────────────────────────────
[R] >> PROCHÁZET CELÝ RECEPTÁŘ KAMILY PEŠEK (${KNIHA_RECEPTU.length} receptů dle kategorií) <<
[S] >> VAŘIT PODLE SUROVIN VE ŠPAJZU << (Algoritmus prohledání lednice)
[N] Náhodný recept pro dnešní den (Inspirace z Kamilina sešitu)
[D] Doporučení: Dávno nevařeno (Prevence stereotypu - DoporucD)
[O] Železná statistika oblíbených jídel rodinného stolu (DoporucO)
[K] Kronika rodinného stolu (Prohlížeč ${HISTORICKA_JIDLA.length} záznamů z Bohnic a Dejvic)
[A] O programu & Software-salon ALTÁN (Historie Dejvic & Bohnic)
── RYCHLÝ VÝBĚR KATEGORIE ──────────────────────────────────────────────────
`; KATEGORIE.slice(1).forEach((cat, idx) => { const count = KNIHA_RECEPTU.filter(r => r.kategorie === cat).length; html += ``; }); html += `
Zvolte klávesu [R, S, N, D, O, K, A] nebo kategorii [1-7]. Na mobilu klepněte prstem.
`; screenEl.innerHTML = html; } // List of recipes with category filter & pagination function openReceptyList(category = 'Vše', page = 0) { currentView = 'recepty_list'; currentCategory = category; listPage = page; playSpeaker(700, 0.04); const filtered = category === 'Vše' ? KNIHA_RECEPTU : KNIHA_RECEPTU.filter(r => r.kategorie === category); const totalPages = Math.ceil(filtered.length / PAGE_SIZE); const pageItems = filtered.slice(page * PAGE_SIZE, (page + 1) * PAGE_SIZE); winTitleEl.textContent = `RECEPTÁŘ KAMILY PEŠEK // ${category.toUpperCase()} (${filtered.length} RECEPTŮ)`; let html = `
════════════════════════════════════════════════════════════════════════════════ RECEPTÁŘ KAMILY PEŠEK // KATEGORIE: ${category.toUpperCase()} (Strana ${page + 1}/${totalPages || 1}) ════════════════════════════════════════════════════════════════════════════════
`; KATEGORIE.forEach(cat => { const activeClass = cat === category ? 'style="background-color:var(--dos-yellow); color:var(--dos-black)"' : ''; html += ``; }); html += `
`; pageItems.forEach((r, idx) => { html += `
[${r.id}] ${r.nazev} Str. ${r.strana} | ${r.kategorie}
`; }); html += `
${page > 0 ? `` : ''} ${page < totalPages - 1 ? `` : ''}
Celkem ${filtered.length} receptů
`; screenEl.innerHTML = html; // Search input live filtering const searchInput = document.getElementById('recipe-search-input'); searchInput.addEventListener('input', (e) => { const q = norm(e.target.value); if (!q) { openReceptyList(category, page); return; } const matched = filtered.filter(r => norm(r.nazev).includes(q) || norm(r.postup).includes(q) || r.suroviny.some(s => norm(s).includes(q))); const container = document.getElementById('recipe-items-container'); let mHtml = ""; matched.slice(0, 15).forEach(r => { mHtml += `
[${r.id}] ${r.nazev} Str. ${r.strana} | ${r.kategorie}
`; }); if (matched.length === 0) { mHtml = `
Žádný recept neodpovídá hledanému výrazu "${e.target.value}".
`; } container.innerHTML = mHtml; }); } function openRecipe(id) { const r = KNIHA_RECEPTU.find(x => x.id === id); if (!r) return; currentView = 'recept'; currentRecipeId = id; playSpeaker(900, 0.05); winTitleEl.textContent = `RECEPT [${r.id}/${KNIHA_RECEPTU.length}]: ${r.nazev.toUpperCase()}`; let html = `
════════════════════════════════════════════════════════════════════════════════ RECEPT Č. ${r.id}: ${r.nazev} Původní sešit Kamily Pešek: Strana ${r.strana} | Kategorie: ${r.kategorie} ════════════════════════════════════════════════════════════════════════════════
── POTŘEBNÉ SUROVINY ZE SEŠITU ─────────────────────────────────────────────
── POSTUP PŘÍPRAVY ZE SEŠITU KAMILY PEŠEK ─────────────────────────────────
${r.postup}
★ TAJEMSTVÍ KAMILY PEŠEK:
"${r.tajemstvi}"
${id > 1 ? `` : ''} ${id < KNIHA_RECEPTU.length ? `` : ''}
`; screenEl.innerHTML = html; } function openRandomRecipe() { const randomId = Math.floor(Math.random() * KNIHA_RECEPTU.length) + 1; openRecipe(randomId); } function openSuroviny(defaultQuery = "") { currentView = 'suroviny'; playSpeaker(700, 0.06); winTitleEl.textContent = "ALGORITMUS: VAŘENÍ PODLE SUROVIN VE ŠPAJZU A LEDNICI"; let html = `
════════════════════════════════════════════════════════════════════════════════ VAŘENÍ PODLE SUROVIN // ROZHODOVACÍ SYSTÉM PRO HOSPODYNI (KUCHARKA.EXE) ════════════════════════════════════════════════════════════════════════════════
Zadejte suroviny, které máte právě doma ve špajzu a lednici (oddělené čárkou či mezerou). Algoritmus prohledá všech ${KNIHA_RECEPTU.length} receptů Kamily Pešek i ${HISTORICKA_JIDLA.length} jídel z kroniky.
MÁM DOMA:
`; screenEl.innerHTML = html; const input = document.getElementById('suroviny-input'); input.focus(); input.addEventListener('keydown', (e) => { if (e.key === 'Enter') { doSearchSuroviny(); } }); if (defaultQuery) { doSearchSuroviny(); } } function doSearchSuroviny() { const query = document.getElementById('suroviny-input').value.trim(); const resEl = document.getElementById('vysledky-hledani'); if (!query) { resEl.innerHTML = `
Zadejte alespoň jednu surovinu!
`; return; } playSpeaker(1000, 0.04); const tokens = query.toLowerCase().split(/[\s,]+/).filter(t => t.length > 1).map(norm); // Score Recipes (both suroviny and postup) const scoredRecipes = KNIHA_RECEPTU.map(r => { let matches = []; const fullText = (r.suroviny.join(' ') + ' ' + r.postup).toLowerCase(); const nFull = norm(fullText); tokens.forEach(tok => { if (nFull.includes(tok)) { matches.push(tok); } }); matches = [...new Set(matches)]; return { recipe: r, score: matches.length, matchedTokens: matches }; }).filter(x => x.score > 0).sort((a, b) => b.score - a.score); // Score Historical Database const scoredHist = HISTORICKA_JIDLA.map(j => { let matches = []; const nJidlo = norm(j.jidlo); tokens.forEach(tok => { if (nJidlo.includes(tok)) { matches.push(tok); } }); matches = [...new Set(matches)]; return { jidlo: j, score: matches.length, matchedTokens: matches }; }).filter(x => x.score > 0).sort((a, b) => b.score - a.score); let html = `
VÝSLEDEK SHODY PRO: "${query}" (Nalezeno ${scoredRecipes.length} receptů Kamily Pešek)
`; if (scoredRecipes.length > 0) { html += `
★ NALEZENÉ RECEPTY ZE SEŠITU KAMILY PEŠEK:
`; scoredRecipes.slice(0, 15).forEach(item => { html += `
[${item.recipe.id}] ${item.recipe.nazev} Shoda: ${item.score} surovin (${item.matchedTokens.join(', ')})
`; }); } if (scoredHist.length > 0) { html += `
📜 ZÁZNAMY Z HISTORICKÉHO JÍDELNÍČKU (1998–2021):
`; scoredHist.slice(0, 10).forEach(item => { html += `
${item.jidlo.jidlo} [${item.jidlo.datum}, ${item.jidlo.typ}] shoda: ${item.matchedTokens.join(', ')}
`; }); } if (scoredRecipes.length === 0 && scoredHist.length === 0) { html += `
Pro tyto suroviny nebyla v databázi nalezena přímá shoda. Zkuste zadat základní ingredience jako: brambory, maso, vejce, smetana, kuře.
`; } resEl.innerHTML = html; } function openDavno() { currentView = 'davno'; playSpeaker(600, 0.05); winTitleEl.textContent = "DOPORUČENÍ: DÁVNO NEVAŘENO // PREVENCE STEREOTYPU"; let html = `
════════════════════════════════════════════════════════════════════════════════ DOPORUČENÍ: DÁVNO NEVAŘENO // HISTORICKÝ CYKLUS RODINY (DoporucD) ════════════════════════════════════════════════════════════════════════════════
Tento modul dekompilovaný z původního Delphi programu prochází archiv datumu a vyhledává pokrmy, které se na stole neobjevily nejdéle, aby se jídelníček netočil.
DOPORUČENÁ JÍDLA S NEJDELŠÍM ČASOVÝM ODSTUPEM:
`; HISTORICKA_JIDLA.slice(0, 12).forEach((j, idx) => { html += `
${idx + 1}. ${j.jidlo} Naposledy: ${j.datum} | ${j.typ}
`; }); html += `
`; screenEl.innerHTML = html; } function openOblibena() { currentView = 'oblibena'; playSpeaker(850, 0.05); winTitleEl.textContent = "OBLÍBENÁ JÍDLA // ŽELEZNÁ STATISTIKA STOLU"; // Count occurrences of keywords in historical records const freq = {}; HISTORICKA_JIDLA.forEach(j => { const title = j.jidlo.split(',')[0].trim(); freq[title] = (freq[title] || 0) + 1; }); const top = Object.entries(freq).sort((a, b) => b[1] - a[1]).slice(0, 12); let html = `
════════════════════════════════════════════════════════════════════════════════ ŽELEZNÁ STATISTIKA OBLÍBENÝCH JÍDEL RODINNÉHO STOLU (DoporucO) ════════════════════════════════════════════════════════════════════════════════
Frekvenční žebříček z ${HISTORICKA_JIDLA.length} záznamů rodinného jídelníčku z let 1998–2021:
`; const maxVal = top[0] ? top[0][1] : 1; top.forEach(([name, count], idx) => { const barWidth = Math.max(2, Math.round((count / maxVal) * 24)); const bar = "█".repeat(barWidth); html += `
${idx + 1}. ${name} ${bar} ${count}×
`; }); html += `
`; screenEl.innerHTML = html; } function openKronika(page = 0) { currentView = 'kronika'; playSpeaker(650, 0.05); winTitleEl.textContent = `KRONIKA RODINNÉHO STOLU // ${HISTORICKA_JIDLA.length} ZÁZNAMŮ BOHNICE (1998–2021)`; const totalPages = Math.ceil(HISTORICKA_JIDLA.length / 20); const items = HISTORICKA_JIDLA.slice(page * 20, (page + 1) * 20); let html = `
════════════════════════════════════════════════════════════════════════════════ KRONIKA RODINNÉHO STOLU // BOHNICE & DEJVICE (Strana ${page + 1}/${totalPages}) ════════════════════════════════════════════════════════════════════════════════
Celkem ${HISTORICKA_JIDLA.length} autentických záznamů z databázových souborů JIDLA.TXT a JIDLA-bohnice.TXT. Od srpna 1998, přes dětská léta až po rok 2021.
`; items.forEach(j => { html += `
${j.datum} [${j.typ}] ${j.jidlo}
`; }); html += `
${page > 0 ? `` : ''} ${page < totalPages - 1 ? `` : ''}
`; screenEl.innerHTML = html; } function openAltan() { currentView = 'altan'; playSpeaker(750, 0.05); winTitleEl.textContent = "SOFTWARE-SALON ALTÁN // DEJVICE & BOHNICE"; let html = `
════════════════════════════════════════════════════════════════════════════════ SOFTWARE-SALON ALTÁN // VÁCLAVKOVA 2, PRAHA 6 (DEJVICE) ════════════════════════════════════════════════════════════════════════════════
PŮVODNÍ PROGRAMÁTORSKÁ STOPA Z JEDNOTKY TURBO PASCALU (POMUCKY.BAK):

const rec : array[1..3] of string = (
  'S PŘIPOMÍNKAMI A DOTAZY SE OBRACEJTE NA ADRESU:',
  ' Ing. B. Mikulecký, CSc., Ing. H. Heroutová',
  ' Software-salon ALTÁN ',
  ' Václavkova 2, 160 00 Praha 6, tel. 02/311 13 25');


Ing. Helena Heroutová patřila k průkopnické generaci českých softwarových inženýrek, které v 80. a 90. letech tvořily základní procedurální knihovny pro Turbo Pascal a DOS v dejvickém ateliéru na Václavkově ulici.

Když se na přelomu tisíciletí objevilo vývojové prostředí Borland Delphi, koncept rodinné kuchařky se přetavil do plnohodnotné 32bitové aplikace KUCHARKA.EXE.

Tato webová aplikace věrně propojuje kulinářské dědictví babičky Kamily Pešek (kompletní rukopisný sešit čítající ${KNIHA_RECEPTU.length} receptů) s procedurální logikou Turbo Pascalu pro budoucí generace.
`; screenEl.innerHTML = html; } // Global Keyboard Handler (Turbo Pascal Hotkeys) window.addEventListener('keydown', (e) => { // If in input, only hijack ESC if (document.activeElement && document.activeElement.tagName === 'INPUT') { if (e.key === 'Escape') { document.activeElement.blur(); renderMainMenu(); } return; } playSpeaker(800, 0.03); switch (e.key) { case 'r': case 'R': case 'F2': e.preventDefault(); openReceptyList('Vše'); break; case 's': case 'S': case 'F3': e.preventDefault(); openSuroviny(); break; case 'n': case 'N': openRandomRecipe(); break; case 'd': case 'D': case 'F4': e.preventDefault(); openDavno(); break; case 'o': case 'O': openOblibena(); break; case 'k': case 'K': case 'F5': e.preventDefault(); openKronika(); break; case 'a': case 'A': case 'F1': e.preventDefault(); openAltan(); break; case 'Escape': renderMainMenu(); break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': if (currentView === 'menu') { const idx = parseInt(e.key); if (KATEGORIE[idx]) openReceptyList(KATEGORIE[idx]); } break; } }); // Touch / Navigation controls handler document.querySelectorAll('[data-act]').forEach(el => { el.addEventListener('click', () => { const act = el.getAttribute('data-act'); if (act === 'menu') renderMainMenu(); else if (act === 'recepty') openReceptyList('Vše'); else if (act === 'suroviny') openSuroviny(); else if (act === 'davno') openDavno(); else if (act === 'oblibena') openOblibena(); else if (act === 'kronika') openKronika(); else if (act === 'altan') openAltan(); }); }); // Sound toggle document.getElementById('sound-btn').addEventListener('click', () => { soundEnabled = !soundEnabled; document.getElementById('sound-btn').textContent = soundEnabled ? '🔊 ZVUK: ON' : '🔈 ZVUK: OFF'; if (soundEnabled) playSpeaker(1200, 0.08); }); // Initial boot renderMainMenu();