Исполнено
'+all.filter(function(e){return e.s==="done"}).length+'
На контроле
'+all.filter(function(e){return e.s==="warn"}).length+'
Просрочено
'+all.filter(function(e){return e.s==="late"}).length+'
';h+='Дивизионы ';branches.forEach(function(b,i){var it=all.filter(function(e){return e.b===i}),d=it.filter(function(e){return e.s==="done"}).length,p=it.length?Math.round(d/it.length*100):0;h+='
'+b+' =25?"var(--amber)":"var(--red)")+'">
'+p+'% ('+d+'/'+it.length+') '});h+='
';h+='Просрочено № Мероприятие Филиал Срок ';all.filter(function(e){return e.s==="late"}).forEach(function(e){h+=''+e.id+' '+esc(e.t.slice(0,80))+'... '+branches[e.b]+' '+e.due+' '});h+='
';document.getElementById("tab-analytics").innerHTML=h;cache.analytics=true}
+function renderAnalytics(){var all=events||[],h='Исполнено
'+all.filter(function(e){return e.s==="done"}).length+'
На контроле
'+all.filter(function(e){return e.s==="warn"}).length+'
Просрочено
'+all.filter(function(e){return e.s==="late"}).length+'
';
+ // Aggregate quantities
+ var totalQty=0,regQty={};regions.forEach(function(r,ri){regQty[ri]=0});
+ all.forEach(function(e){regions.forEach(function(ri){var d=getMD(e.id,ri,-1);for(var k in d){if(d.hasOwnProperty(k)&&d[k])totalQty+=d[k].qty||0;regQty[ri]+=d[k].qty||0}if(e.sub)e.sub.forEach(function(s,si){var sd=getMD(e.id,ri,si);for(var sk in sd){if(sd.hasOwnProperty(sk)&&sd[sk]){totalQty+=sd[sk].qty||0;regQty[ri]+=sd[sk].qty||0}}})})});
+ h+='📊 Количественные показатели ';
+ regions.forEach(function(r,ri){if(regQty[ri])h+='
'});
+ h+='
';
+ // Branch ranking
+ h+='Дивизионы ';branches.forEach(function(b,i){var it=all.filter(function(e){return e.b===i}),d=it.filter(function(e){return e.s==="done"}).length,p=it.length?Math.round(d/it.length*100):0;h+='
'+b+' =25?"var(--amber)":"var(--red)")+'">
'+p+'% ('+d+'/'+it.length+') '});h+='
';h+='Просрочено № Мероприятие Филиал Срок ';all.filter(function(e){return e.s==="late"}).forEach(function(e){h+=''+e.id+' '+esc(e.t.slice(0,80))+'... '+branches[e.b]+' '+e.due+' '});h+='
';document.getElementById("tab-analytics").innerHTML=h;cache.analytics=true}
// ===== JOURNAL =====
function renderJournal(){var log=JSON.parse(localStorage.getItem("samruk_log")||"[]").reverse(),h='Журнал действий ';if(!log.length)h+='
Записей пока нет
';else{h+='
Время Пользователь Действие ';log.forEach(function(l){h+=''+new Date(l.ts).toLocaleString()+' '+esc(l.user)+' '+esc(l.action)+(l.detail?' — '+esc(l.detail):'')+' '});h+='
'}h+='
';document.getElementById("tab-journal").innerHTML=h;cache.journal=true}
@@ -280,11 +288,12 @@ function openEdit(id,mi,ri,si){
h+='📎 '+regions[curRegion]+' '+mh+rh;
h+='
Текст за '+M(curMonth)+'
';
+ h+='
Количество (совещаний / работников / объектов)
';
cfs.forEach(function(f,i){h+='
📄 '+esc(f.name)+' '+(f.desc?''+esc(f.desc)+' ':'')+''+(f.size/1024).toFixed(0)+' КБ ×
'});
h+='
📤 Загрузить
';
h+='
Формы: '+esc(e.dname)+'
';
- if(e.sub&&e.sub.length){h+='📋 Подпункты Нажмите 📎 для управления файлами
';e.sub.forEach(function(s,i){var ch=sc.indexOf(i)>=0,sd=getMD(e.id,curRegion,i),scd=sd[cm]||{report:"",files:[]},scfs=scd.files||[],isA=editSubIdx===i;h+='
'+s.l+') '+esc(s.t)+' Файлов: '+scfs.length+' '+(isA?'📂':'📎')+'
';if(isA){h+='
'+s.l+') '+esc(s.t)+' '+regions[curRegion]+' · '+M(curMonth)+'
';h+='
Текст
';scfs.forEach(function(f,fi){h+='
📄 '+esc(f.name)+' '+(f.size/1024).toFixed(0)+' КБ ×
'});h+='
📤
'}});h+='
'}
+ if(e.sub&&e.sub.length){h+='📋 Подпункты Нажмите 📎 для управления файлами
';e.sub.forEach(function(s,i){var ch=sc.indexOf(i)>=0,sd=getMD(e.id,curRegion,i),scd=sd[cm]||{report:"",files:[]},scfs=scd.files||[],isA=editSubIdx===i;h+='
'+s.l+') '+esc(s.t)+' Файлов: '+scfs.length+' '+(isA?'📂':'📎')+'
'; if(isA){h+='
'+s.l+') '+esc(s.t)+' '+regions[curRegion]+' · '+M(curMonth)+'
';h+='
Текст
';h+='
Количество
';scfs.forEach(function(f,fi){h+='
📄 '+esc(f.name)+' '+(f.size/1024).toFixed(0)+' КБ ×
'});h+='
📤
'}});h+='
'}
h+='
🤖 ИИ '+esc(e.ai)+'';
h+='История: ';e.h.forEach(function(x){h+='
'});h+='
';
@@ -293,7 +302,7 @@ function openEdit(id,mi,ri,si){
document.getElementById("editModalOverlay").classList.add("open");
}
-function saveEdit(id,mk){mk=months[mk];var e=null;for(var i=0;i