let data = []; let currentFilter = 'all'; async function loadData() { try { const response = await fetch('data.json'); const json = await response.json(); data = json.zamечания || []; renderTable(); renderSummary(); } catch (error) { console.error('Ошибка загрузки данных:', error); document.getElementById('table-body').innerHTML = 'Ошибка загрузки данных'; } } function compareDecisions(zam, sf) { if (!zam || !sf) return 'partially'; const zamNorm = zam.toLowerCase().trim(); const sfNorm = sf.toLowerCase().trim(); if (zamNorm === sfNorm) return 'fully'; const zamWords = zamNorm.split(/[\s,;.]+/).filter(w => w.length > 3); const sfWords = sfNorm.split(/[\s,;.]+/).filter(w => w.length > 3); const matchCount = zamWords.filter(w => sfWords.includes(w)).length; const matchPercent = matchCount / Math.max(zamWords.length, sfWords.length); if (matchPercent >= 0.8) return 'fully'; if (matchPercent >= 0.4) return 'partially'; return 'partially'; } function findAddedContent(zam, sf) { if (!zam || !sf) return []; const zamNorm = zam.toLowerCase(); const sfNorm = sf.toLowerCase(); const zamSentences = zamNorm.split(/[.!?]/).filter(s => s.trim().length > 10); const sfSentences = sfNorm.split(/[.!?]/).filter(s => s.trim().length > 10); const added = sfSentences.filter(sfSent => !zamSentences.some(zamSent => { const words1 = sfSent.trim().split(/\s+/).filter(w => w.length > 3); const words2 = zamSent.trim().split(/\s+/).filter(w => w.length > 3); const match = words1.filter(w => words2.includes(w)).length; return match / Math.max(words1.length, words2.length) > 0.6; }) ); return added.slice(0, 3); } function getStatusHtml(status, added) { const statusLabels = { 'fully': 'Полностью учтено', 'partially': 'Частично учтено', 'added': 'Добавлено' }; let html = `${statusLabels[status]}`; if (added && added.length > 0) { html += `
Добавлено в Приложении 1_СФ:
`; } return html; } function renderTable(filter = 'all') { const tbody = document.getElementById('table-body'); const filtered = filter === 'all' ? data : data.filter(item => { const status = compareDecisions(item.decision_zam, item.decision_sf); const added = findAddedContent(item.decision_zam, item.decision_sf); if (filter === 'fully') return status === 'fully'; if (filter === 'partially') return status === 'partially'; if (filter === 'added') return added.length > 0; return true; }); if (filtered.length === 0) { tbody.innerHTML = 'Нет данных для отображения'; return; } tbody.innerHTML = filtered.map(item => { const status = compareDecisions(item.decision_zam, item.decision_sf); const added = findAddedContent(item.decision_zam, item.decision_sf); return ` ${item.id} ${item.problem} ${item.recommendation} ${item.decision_zam} ${item.decision_sf} ${getStatusHtml(status, added)} `; }).join(''); } function renderSummary() { const total = data.length; let fullyCount = 0; let partiallyCount = 0; let addedCount = 0; const addedItems = []; data.forEach(item => { const status = compareDecisions(item.decision_zam, item.decision_sf); const added = findAddedContent(item.decision_zam, item.decision_sf); if (status === 'fully') fullyCount++; else partiallyCount++; if (added.length > 0) { addedCount++; addedItems.push({ id: item.id, added }); } }); document.getElementById('summary').innerHTML = `
${total} Всего замечаний
${fullyCount} Полностью учтено
${partiallyCount} Частично учтено
${addedCount} С дополнениями
`; const summaryDetails = document.getElementById('summary-details'); summaryDetails.innerHTML = `

📊 Общая статистика

✨ Что добавлено в Приложении 1_СФ

${addedItems.length > 0 ? ` ` : '
  • Новых положений не выявлено
  • '}

    📋 Ключевые дополнения в Приложении 1_СФ по сравнению с ПКМ замечаниями

    ${addedItems.length > 0 ? addedItems.map(item => `
    Замечание ${item.id}
      ${item.added.map(a => `
    • ${a.trim()}.
    • `).join('')}
    `).join('') : '

    Все решения полностью соответствуют исходным замечаниям

    '}
    `; } document.querySelectorAll('.filter-btn').forEach(btn => { btn.addEventListener('click', () => { document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active')); btn.classList.add('active'); currentFilter = btn.dataset.filter; renderTable(currentFilter); }); }); document.addEventListener('DOMContentLoaded', loadData);