const PRODUCT_CATEGORIES = ['Белки','Жиры','Углеводы','Овощи и зелень','Витамины','Минералы','Напитки','Ограничить']; const PRODUCT_PAGES = [ ['Белки','Жиры'], ['Углеводы','Овощи и зелень'], ['Витамины','Минералы'], ['Напитки','Ограничить'] ]; function esc(s){return String(s||'').replace(/[&<>"']/g, m => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[m]));} function readState(){ try { return JSON.parse(localStorage.getItem('astrodis_full_state') || 'null'); } catch(e){ return null; } } function lines(items){ return (items||[]).map(x=>'• '+x).join('\n'); } function makeProductCard(title, items, note) { return `
${esc(title)}
${note ? `
${esc(note)}
` : ''}
${esc(lines(items))}
`; } function buildProducts(fields){ fields = fields || {}; const proteinText = (fields.proteinSourceText || '') + ' ' + (fields.fatSourceText || ''); const sugarText = fields.sugarRulesText || ''; const vitaminsText = fields.vitaminsText || ''; const mineralsText = fields.mineralsText || ''; const waterText = fields.waterText || ''; const proteinItems = []; if (/рыб|морепродукт/i.test(proteinText)) proteinItems.push('рыба','лосось','скумбрия','тунец','креветки'); if (/птиц|кур|индей/i.test(proteinText)) proteinItems.push('курица','индейка','яйца'); if (/мяс|говядин|телятина|баранина|свинина|конина|оленина/i.test(proteinText)) proteinItems.push('говядина','телятина','печень','баранина'); if (/творог|молоч|сыр/i.test(proteinText)) proteinItems.push('творог','греческий йогурт','сыр'); if (!proteinItems.length) proteinItems.push('яйца','курица','индейка','рыба','творог','бобовые'); const limitItems = ['фастфуд','трансжиры','сладкая газировка']; if (/сахароз/i.test(sugarText)) limitItems.push('сахар','конфеты','сладкие напитки'); if (/м[её]д/i.test(sugarText) && /запрет/i.test(sugarText)) limitItems.push('мёд'); if (/сахарозамен/i.test(sugarText)) limitItems.push('сахарозаменители'); const vitaminItems = []; if (/A/i.test(vitaminsText)) vitaminItems.push('морковь','тыква','яичный желток'); if (/B/i.test(vitaminsText)) vitaminItems.push('гречка','овсянка','бобовые'); if (/C/i.test(vitaminsText)) vitaminItems.push('цитрусовые','киви','болгарский перец'); if (/D/i.test(vitaminsText)) vitaminItems.push('жирная рыба','яйца'); if (/E/i.test(vitaminsText)) vitaminItems.push('орехи','семечки','растительные масла'); if (!vitaminItems.length) vitaminItems.push('зелень','овощи','ягоды','цельные крупы'); const mineralItems = []; if (/Магний/i.test(mineralsText)) mineralItems.push('тыквенные семечки','гречка','шпинат'); if (/Железо/i.test(mineralsText)) mineralItems.push('говядина','печень','гречка'); if (/Кальций/i.test(mineralsText)) mineralItems.push('творог','сыр','кунжут'); if (/Йод/i.test(mineralsText)) mineralItems.push('морская рыба','морская капуста'); if (/Цинк|Селен/i.test(mineralsText)) mineralItems.push('морепродукты','яйца','орехи'); if (!mineralItems.length) mineralItems.push('орехи','семечки','зелень','морская рыба'); const waterItems = ['чистая вода','несладкий травяной чай']; if (/минерал|соль/i.test(waterText)) waterItems.push('минеральная вода по рекомендации специалиста'); return { 'Белки': {items:[...new Set(proteinItems)], note:'Основа для завтрака, обеда и ужина.'}, 'Жиры': {items:['оливковое масло','сливочное масло','авокадо','орехи','семечки'], note:'Добавлять умеренно, без жарки во фритюре.'}, 'Углеводы': {items:['гречка','рис','овсянка','картофель','цельнозерновой хлеб'], note:'Лучше выбирать простые продукты без сладких добавок.'}, 'Овощи и зелень': {items:['огурцы','кабачок','брокколи','шпинат','листовой салат'], note:'Добавлять к основным приемам пищи.'}, 'Витамины': {items:[...new Set(vitaminItems)], note: vitaminsText && vitaminsText !== 'Не выявлено.' ? 'Подобрано по рассчитанным витаминам.' : 'Базовый поддерживающий набор.'}, 'Минералы': {items:[...new Set(mineralItems)], note: mineralsText && mineralsText !== 'Не выявлено.' ? 'Подобрано по рассчитанным минералам.' : 'Базовый поддерживающий набор.'}, 'Напитки': {items:waterItems, note:'Сладкие напитки лучше не использовать как замену воде.'}, 'Ограничить': {items:[...new Set(limitItems)], note:'Список ограничений формируется с учетом блока сахаров.'} }; } function planetName(sym){return ({n:'Солнце',o:'Луна',p:'Меркурий',q:'Венера',r:'Марс',s:'Юпитер',t:'Сатурн',u:'Уран',v:'Нептун',w:'Плутон','|':'Хирон'}[sym] || sym);} function signLabel(ch){return ({';':'Овен ♈','<':'Телец ♉','=':'Близнецы ♊','>':'Рак ♋','?':'Лев ♌','@':'Дева ♍','A':'Весы ♎','B':'Скорпион ♏','C':'Стрелец ♐','D':'Козерог ♑','E':'Водолей ♒','F':'Рыбы ♓'}[ch] || ch);} function aspectName(a){return ({0:'Соединение',60:'Секстиль',90:'Квадрат',120:'Тригон',180:'Оппозиция'}[a.type] || a.typeName || a.type);} function allProductsHtml(products){ return PRODUCT_CATEGORIES.map(cat => makeProductCard(cat, products[cat].items, products[cat].note)).join(''); } function exportFullWord(){ const state = readState(); if (!state) { alert('Нет сохранённых данных. Вернитесь на первую страницу и выполните расчёт.'); return false; } const products = buildProducts(state.fields || {}); const d = state.currentData || {}; const planets = (d.planets || []).map(p => `${esc(planetName(p.sym))}${esc(p.pos || '')}${esc(signLabel(p.signChar))}${p.isRetro ? 'R' : ''}`).join(''); const aspects = (d.aspects || []).map(a => `${esc(aspectName(a))}${esc(a.p1 || '')}${esc(a.p2 || '')}${esc(a.orb || '')}`).join(''); const name = (d.chartName || 'Расчёт питания').replace(/[\\/:*?"<>|]+/g,'').replace(/\s+/g,'_'); const htmlDoc = `Расчёт питания

Расчёт правильного питания

${esc(state.meta || '')}${state.genderBadge ? ' · '+esc(state.genderBadge) : ''}
Планеты в знаках
${planets}
ПланетаПоложениеЗнакR
Аспекты
${aspects}
АспектПланета 1Планета 2Орбис
Расчёт показателей
${state.indicatorsHTML || ''}
Питание
${state.foodHTML || ''}
Список продуктов
${allProductsHtml(products)}
`; const blob = new Blob(['\ufeff', htmlDoc], {type:'application/msword;charset=utf-8'}); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `${name || 'Расчет_питания'}_полный_отчет.doc`; document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(url); return false; } function renderPage(pageIndex){ const state = readState(); const content = document.getElementById('productsContent'); const meta = document.getElementById('productsMeta'); if (!state) { document.getElementById('productsPage').style.display='none'; document.getElementById('emptyState').style.display='block'; return; } const products = buildProducts(state.fields || {}); const cats = PRODUCT_PAGES[pageIndex-1] || PRODUCT_PAGES[0]; meta.textContent = (state.meta || '') + (state.genderBadge ? ' · ' + state.genderBadge : ''); document.getElementById('pageLabel').textContent = 'Страница ' + pageIndex + ' из ' + PRODUCT_PAGES.length + ' · ' + cats.join(' / '); content.innerHTML = cats.map(cat => makeProductCard(cat, products[cat].items, products[cat].note)).join(''); const prev = document.getElementById('prevBtn'); const next = document.getElementById('nextBtn'); const word = document.getElementById('wordBtn'); if (prev) prev.style.display = pageIndex === 1 ? 'none' : 'inline-flex'; if (next) next.style.display = pageIndex === PRODUCT_PAGES.length ? 'none' : 'inline-flex'; if (word) word.style.display = pageIndex === PRODUCT_PAGES.length ? 'inline-flex' : 'none'; }