Upload index.html
Browse files- index.html +389 -15
index.html
CHANGED
|
@@ -225,14 +225,146 @@
|
|
| 225 |
.header-center-logo .reakt-name{display:block;font-family:Arial,'Segoe UI',sans-serif;font-weight:800;font-size:clamp(40px,3vw,56px);letter-spacing:-2.6px;line-height:.99;color:#ff5a0a;}
|
| 226 |
.header-center-logo .reakt-tagline{display:block;font-family:Arial,'Segoe UI',sans-serif;font-weight:500;font-size:clamp(12px,.9vw,15px);line-height:1.16;letter-spacing:-.2px;color:#ff5a0a;margin-top:4px;}
|
| 227 |
@media(max-width:1080px){.header-center-logo .reakt-name{font-size:44px}.header-center-logo .reakt-tagline{font-size:12px}}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 228 |
</style></head>
|
| 229 |
<body>
|
| 230 |
<div class="app">
|
| 231 |
<main class="main">
|
| 232 |
-
<header><div class="header-copy"><div class="eyebrow">REAKT / AI ANALYTICS PLATFORM</div><h1>Inloop <span>Intelligence</span> <em>ORCHESTRA</em></h1><p>
|
| 233 |
-
<div class="topbar"><div><span class="section-kicker">CONTROL CENTER</span><h2>
|
| 234 |
<section class="import-panel panel" aria-label="Lokale Excelanalyse met 2026 en historische referentie 2025">
|
| 235 |
-
<div class="import-intro"><span class="section-kicker">
|
| 236 |
<label class="import-file-label" for="scanFile"><span>▤</span> Rapportage 2026 (.xlsx)</label><input type="file" id="scanFile" accept=".xlsx" aria-label="Rapportagebestand januari tot en met september 2026" />
|
| 237 |
<label class="import-file-label history-label" for="historyFile"><span>◴</span> Historie 2025 (.xlsx)</label><input type="file" id="historyFile" accept=".xlsx" aria-label="Historisch referentiebestand 2025" disabled/>
|
| 238 |
<label class="site-label" for="siteSelect">Locatie</label><select id="siteSelect" disabled><option value="*">Alle locaties</option></select>
|
|
@@ -241,16 +373,20 @@
|
|
| 241 |
<div id="historyStatus" class="history-status">◴ Historie 2025 nog niet geladen. Zonder deze referentie zijn instroomcijfers voorlopig.</div>
|
| 242 |
</section>
|
| 243 |
<section class="orchestra panel">
|
| 244 |
-
<div class="mesh"></div><div class="conductor-wrap"><div class="conductor" id="conductor"><div class="conductor-glow"></div><div class="conductor-icon" aria-hidden="true"><svg class="brain-symbol" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.55" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5c-2.7-3.2-7.4-.9-7.1 2.4C2 9 2 13.6 5 15.2c-.7 4.4 4.9 6.8 7 2.6M12 5c2.7-3.2 7.4-.9 7.1 2.4 2.9 1.6 2.9 6.2-.1 7.8.7 4.4-4.9 6.8-7 2.6M12 5v13"/><path d="M6.6 10.1 9 12v3M17.4 10.1 15 12v3"/><circle cx="9" cy="15.5" r=".9" fill="currentColor" stroke="none"/><circle cx="15" cy="15.5" r=".9" fill="currentColor" stroke="none"/></svg></div><div><small>MASTER ORCHESTRATOR</small><strong>THE CONDUCTOR</strong><span id="conductorStatus">Gereed voor analyse</span></div><div class="conductor-indicator"></div></div></div>
|
| 245 |
-
<
|
| 246 |
<div class="agents">
|
| 247 |
<article class="agent" id="agent-data" style="--accent:#34e6b3"><div class="agent-top"><span>01 / DATA</span><span class="status">STANDBY</span></div><div class="agent-symbol">▤</div><h3>Data Agent</h3><p>Structuur & kwaliteit</p><div class="agent-steps" aria-live="polite" aria-label="Werkstappen"></div><div class="mini-visual bars"><b></b><b></b><b></b><b></b><b></b><b></b><b></b></div><div class="agent-bottom"><div class="track"><i></i></div><span class="percent">0%</span></div></article>
|
| 248 |
-
<article class="agent" id="agent-analysis" style="--accent:#ffcb62"><div class="agent-top"><span>
|
| 249 |
-
<article class="agent" id="agent-insight" style="--accent:#51b9ff"><div class="agent-top"><span>
|
| 250 |
-
<article class="agent" id="agent-verify" style="--accent:#b18aff"><div class="agent-top"><span>
|
| 251 |
-
<article class="agent" id="agent-report" style="--accent:#ff9a65"><div class="agent-top"><span>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 252 |
</div>
|
| 253 |
-
<div class="orchestra-footer"><span><i class="dot green"></i> Systeem gereed</span><span id="flowState">Wacht op startcommando</span><span>◌ <span id="completed">0</span> /
|
| 254 |
</section>
|
| 255 |
<div class="content-grid">
|
| 256 |
<div class="left-content">
|
|
@@ -304,14 +440,14 @@ window.addEventListener('error', function(event){
|
|
| 304 |
'use strict';
|
| 305 |
let demoData=null, running=false, completed=0;
|
| 306 |
const $=id=>document.getElementById(id);
|
| 307 |
-
const ids=['data','analysis','insight','verify','report'];
|
| 308 |
const sleep=ms=>new Promise(resolve=>setTimeout(resolve,ms));
|
| 309 |
const escapeHTML=s=>String(s).replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
|
| 310 |
function clock(){ $('clock').textContent=new Intl.DateTimeFormat('nl-NL',{hour:'2-digit',minute:'2-digit',day:'numeric',month:'short'}).format(new Date()); }
|
| 311 |
clock();setInterval(clock,60000);
|
| 312 |
function renderKPIs(data){$('kpis').innerHTML=data.kpis.map(k=>`<div class="kpi"><small>${escapeHTML(k.label)}</small><strong>${escapeHTML(k.value)}</strong><span>${escapeHTML(k.change)}</span></div>`).join('');}
|
| 313 |
function renderChecks(data){$('checks').innerHTML=data.checks.map(c=>{const delta=c.ours-c.shadow;return `<div class="check-row"><span>${escapeHTML(c.label)}</span><span>${c.ours.toLocaleString('nl-NL')} / ${c.shadow.toLocaleString('nl-NL')} <strong class="${delta?'bad':''}">${delta?'⚠ '+(delta>0?'+':'')+delta:'✓ 0'}</strong></span></div>`}).join('');}
|
| 314 |
-
function drawChart(data){const canvas=$('chart'),ctx=canvas.getContext('2d'),w=640,h=250;ctx.clearRect(0,0,w,h);ctx.font='13px Segoe UI';ctx.textAlign='left';const max=500;for(let i=0;i<=4;i++){let y=25+i*45;ctx.strokeStyle='#29405a';ctx.beginPath();ctx.moveTo(44,y);ctx.lineTo(w-15,y);ctx.stroke();ctx.fillStyle='#8298b4';ctx.fillText(String(Math.round(max*(4-i)/4)),5,y+4);}const cols=['#3ee1b6','#ffc66a','#5b9cff','#ad88ff'];data.locations.forEach((loc,index)=>{ctx.strokeStyle=cols[index];ctx.lineWidth=3;ctx.beginPath();loc.visits.forEach((v,j)=>{const x=72+(
|
| 315 |
function log(text){const now=new Date().toLocaleTimeString('nl-NL',{hour:'2-digit',minute:'2-digit',second:'2-digit'});if($('logs').querySelector('.muted'))$('logs').innerHTML='';$('logs').insertAdjacentHTML('afterbegin',`<div class="logitem"><time>${now}</time>${escapeHTML(text)}</div>`)}
|
| 316 |
// De lichtpunten volgen de vijf bestaande SVG-verbindingen. Ze lopen alleen tijdens een actieve processtap.
|
| 317 |
const signalPaths={data:'M500 0 V30 H100 V90',analysis:'M500 0 V30 H300 V90',insight:'M500 0 V90',verify:'M500 0 V30 H700 V90',report:'M500 0 V30 H900 V90'};
|
|
@@ -791,8 +927,8 @@ function drawImportedChart(result){
|
|
| 791 |
const colors=['#3ee1b6','#ffc66a','#5b9cff','#ad88ff'];
|
| 792 |
series.forEach((loc,li)=>{
|
| 793 |
ctx.strokeStyle=colors[li];ctx.lineWidth=3;ctx.beginPath();
|
| 794 |
-
loc.visits.forEach((v,j)=>{const x=72+(
|
| 795 |
-
loc.visits.forEach((v,j)=>{const x=72+(
|
| 796 |
});ctx.fillStyle='#a6b9d0';ctx.textAlign='center';
|
| 797 |
result.months.forEach((m,i)=>ctx.fillText(m,72+(result.months.length===1?0:i*(w-105)/(result.months.length-1)),239));
|
| 798 |
const legend=document.querySelector('.legend');
|
|
@@ -894,7 +1030,7 @@ $('scanFile').addEventListener('change',async e=>{
|
|
| 894 |
$('startBtn').textContent='▶ Analyseer Excelbestand';
|
| 895 |
$('flowState').textContent='Excelbestand lokaal ingelezen · start de analyse';
|
| 896 |
log('Excelbestand lokaal verwerkt; analyse moet nog starten. Voor echte data eerst interne toestemming controleren.');
|
| 897 |
-
}catch(err){$('startBtn').textContent='▶ Start
|
| 898 |
});
|
| 899 |
$('historyFile').addEventListener('change',async e=>{
|
| 900 |
const file=e.target.files?.[0];if(!file||!importedData)return;
|
|
@@ -1118,4 +1254,242 @@ function compareController(){
|
|
| 1118 |
$('controllerCompare').addEventListener('click',compareController);
|
| 1119 |
$('controllerClear').addEventListener('click',()=>resetControllerComparison(true));
|
| 1120 |
controllerDefs.forEach(([,id])=>$(id).addEventListener('input',()=>{if(controllerComparison)resetControllerComparison(false)}));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1121 |
</script></body></html>
|
|
|
|
| 225 |
.header-center-logo .reakt-name{display:block;font-family:Arial,'Segoe UI',sans-serif;font-weight:800;font-size:clamp(40px,3vw,56px);letter-spacing:-2.6px;line-height:.99;color:#ff5a0a;}
|
| 226 |
.header-center-logo .reakt-tagline{display:block;font-family:Arial,'Segoe UI',sans-serif;font-weight:500;font-size:clamp(12px,.9vw,15px);line-height:1.16;letter-spacing:-.2px;color:#ff5a0a;margin-top:4px;}
|
| 227 |
@media(max-width:1080px){.header-center-logo .reakt-name{font-size:44px}.header-center-logo .reakt-tagline{font-size:12px}}
|
| 228 |
+
|
| 229 |
+
/* ORCHESTRA NEXT: dynamischer command center met vloeiende netwerkanimaties */
|
| 230 |
+
.orchestra{padding:28px 28px 0;background:radial-gradient(ellipse at 50% 10%,#20376a 0%,#0b1730 58%,#08111f 100%);overflow:hidden}
|
| 231 |
+
.orchestra::before,.orchestra::after{content:'';position:absolute;pointer-events:none;z-index:0;border-radius:50%;filter:blur(54px);opacity:.2}
|
| 232 |
+
.orchestra::before{width:320px;height:320px;left:-70px;top:90px;background:#35c9ff}
|
| 233 |
+
.orchestra::after{width:360px;height:360px;right:-95px;top:170px;background:#8549ff}
|
| 234 |
+
.orchestra .conductor-wrap{position:relative;z-index:3;margin-bottom:34px}
|
| 235 |
+
.orchestra .conductor{width:362px;padding:20px 22px;border-color:#c194ff;box-shadow:0 0 45px #8c54df6f,inset 0 0 22px #9a69ff24;transition:transform .35s ease,box-shadow .35s ease,border-color .35s ease;overflow:hidden}
|
| 236 |
+
.orchestra .conductor::before{content:'';position:absolute;inset:-45% auto -45% -60%;width:52%;background:linear-gradient(90deg,transparent,rgba(255,255,255,.18),transparent);transform:rotate(18deg) translateX(-160%);opacity:0}
|
| 237 |
+
.orchestra .conductor::after{content:'';position:absolute;inset:auto;left:50%;top:50%;width:155px;height:155px;background:radial-gradient(circle,rgba(188,150,255,.16),transparent 68%);transform:translate(-50%,-50%);pointer-events:none;opacity:.65}
|
| 238 |
+
.orchestra .conductor strong{font-size:19px}
|
| 239 |
+
.orchestra .conductor.running{animation:conductorFloat 4.8s ease-in-out infinite}
|
| 240 |
+
.orchestra .conductor.transfering{transform:translateY(-4px) scale(1.02);border-color:#efd7ff;box-shadow:0 0 60px #b779ff88,inset 0 0 28px #d0a7ff30}
|
| 241 |
+
.orchestra .conductor.transfering::before{opacity:1;animation:conductorSweep 1s ease-out}
|
| 242 |
+
.orchestra .conductor.transfering .conductor-icon{box-shadow:0 0 28px #d0a7ff99,0 0 54px #7de1ff33}
|
| 243 |
+
.orchestra .conductor.transfering .brain-symbol{animation-duration:.9s}
|
| 244 |
+
.orchestra .conductor.attention{box-shadow:0 0 46px #ffae5990,inset 0 0 26px #ffbf6a24}
|
| 245 |
+
.orchestra .conductor.attention::after{background:radial-gradient(circle,rgba(255,189,106,.18),transparent 68%)}
|
| 246 |
+
.orchestra .agents{display:grid;grid-template-columns:repeat(3,minmax(300px,1fr));gap:34px 58px;max-width:1490px;margin:0 auto;z-index:2;position:relative;padding:20px 18px 28px}
|
| 247 |
+
.orchestra .agent{min-height:178px;padding:16px 18px;position:relative;z-index:2;overflow:hidden;transition:transform .42s ease,box-shadow .42s ease,border-color .42s ease;box-shadow:0 0 16px color-mix(in srgb,var(--accent) 10%,transparent),inset 0 0 25px color-mix(in srgb,var(--accent) 6%,transparent)}
|
| 248 |
+
.orchestra .agent::before{content:'';position:absolute;inset:auto -10% -48% auto;width:110px;height:110px;background:radial-gradient(circle,color-mix(in srgb,var(--accent) 34%,transparent),transparent 72%);opacity:.58;filter:blur(8px);pointer-events:none}
|
| 249 |
+
.orchestra .agent::after{content:'';position:absolute;inset:-30% auto -30% -55%;width:42%;background:linear-gradient(90deg,transparent,rgba(255,255,255,.12),transparent);transform:rotate(12deg) translateX(-210%);opacity:0;pointer-events:none}
|
| 250 |
+
.orchestra .agent:hover{transform:translateY(-2px)}
|
| 251 |
+
.orchestra .agent.active{transform:translateY(-8px) scale(1.012);box-shadow:0 0 34px color-mix(in srgb,var(--accent) 34%,transparent),inset 0 0 24px color-mix(in srgb,var(--accent) 13%,transparent)}
|
| 252 |
+
.orchestra .agent.active::after{opacity:1;animation:agentSweep 1.35s linear infinite}
|
| 253 |
+
.orchestra .agent.done .status{color:#62e5bd}
|
| 254 |
+
.orchestra .agent h3{font-size:17px;margin:4px 0}
|
| 255 |
+
.orchestra .agent .agent-symbol{font-size:23px;margin-top:7px;animation:iconFloat 5.5s ease-in-out infinite}
|
| 256 |
+
.orchestra .agent .mini-visual{margin:5px 0;height:27px;font-size:17px;opacity:.95}
|
| 257 |
+
.orchestra .agent .agent-steps{margin:5px 0;min-height:82px}
|
| 258 |
+
.orchestra .agent .agent-step{font-size:10px}
|
| 259 |
+
.orchestra .agent p{font-size:12px}
|
| 260 |
+
.orchestra .agent-bottom .track{height:6px;background:#223650}
|
| 261 |
+
.orchestra .agent-bottom .track i{transition:width .35s ease}
|
| 262 |
+
#agent-data{order:1}#agent-identity{order:2}#agent-history{order:3}#agent-analysis{order:4}#agent-insight{order:5}#agent-verify{order:6}#agent-privacy{order:7}#agent-report{order:8}#agent-quality{order:9}
|
| 263 |
+
#agent-data .bars b{animation:dataBar 1.75s ease-in-out infinite}
|
| 264 |
+
#agent-data .bars b:nth-child(2){animation-delay:.18s}#agent-data .bars b:nth-child(3){animation-delay:.36s}#agent-data .bars b:nth-child(4){animation-delay:.54s}#agent-data .bars b:nth-child(5){animation-delay:.72s}#agent-data .bars b:nth-child(6){animation-delay:.9s}#agent-data .bars b:nth-child(7){animation-delay:1.08s}
|
| 265 |
+
#agent-analysis .spark{animation:analysisSpark 2.4s ease-in-out infinite;letter-spacing:1px}
|
| 266 |
+
#agent-insight .rings{animation:ringsDrift 7.5s ease-in-out infinite}
|
| 267 |
+
#agent-insight .rings span{display:inline-block;animation:insightPulse 2.1s ease-in-out infinite}
|
| 268 |
+
#agent-verify .checkicons{animation:verifyPulse 2.35s ease-in-out infinite}
|
| 269 |
+
#agent-report .reportlines{animation:reportScan 2.6s ease-in-out infinite}
|
| 270 |
+
#agent-identity .mini-visual{animation:identityLink 2.8s ease-in-out infinite;letter-spacing:1px}
|
| 271 |
+
#agent-history .mini-visual{animation:historyLoop 3.7s ease-in-out infinite}
|
| 272 |
+
#agent-privacy .mini-visual{animation:privacyShield 2.9s ease-in-out infinite}
|
| 273 |
+
#agent-quality .mini-visual{animation:qualitySpark 2.4s ease-in-out infinite}
|
| 274 |
+
#agent-data.active .bars b,#agent-analysis.active .spark,#agent-insight.active .rings,#agent-insight.active .rings span,#agent-verify.active .checkicons,#agent-report.active .reportlines,#agent-identity.active .mini-visual,#agent-history.active .mini-visual,#agent-privacy.active .mini-visual,#agent-quality.active .mini-visual{animation-duration:.95s}
|
| 275 |
+
.network-links{position:absolute;inset:0;z-index:1;pointer-events:none;overflow:hidden}
|
| 276 |
+
#networkSvg{width:100%;height:100%;overflow:visible}
|
| 277 |
+
#networkEdges path{fill:none;stroke:#3e6888;stroke-width:1.55;opacity:.48;vector-effect:non-scaling-stroke;animation:routeGlow 5.5s ease-in-out infinite}
|
| 278 |
+
#networkEdges path.transfer{stroke:#86ecff;stroke-width:3.1;stroke-dasharray:8 12;opacity:1;animation:nextStream .72s linear infinite,routeTransferGlow 1.15s ease-in-out infinite;filter:drop-shadow(0 0 7px #75dafa)}
|
| 279 |
+
#networkEdges path.route-done{stroke:#4cc69f;opacity:.68;filter:drop-shadow(0 0 5px rgba(76,198,159,.35))}
|
| 280 |
+
#networkSignals circle{filter:drop-shadow(0 0 8px #8df3ff)}
|
| 281 |
+
@keyframes nextStream{to{stroke-dashoffset:-40}}
|
| 282 |
+
@keyframes routeGlow{50%{opacity:.72}}
|
| 283 |
+
@keyframes routeTransferGlow{50%{filter:drop-shadow(0 0 12px #9ef4ff)}}
|
| 284 |
+
@keyframes conductorFloat{50%{transform:translateY(-4px)}}
|
| 285 |
+
@keyframes conductorSweep{0%{transform:rotate(18deg) translateX(-160%)}100%{transform:rotate(18deg) translateX(360%)}}
|
| 286 |
+
@keyframes agentSweep{0%{transform:rotate(12deg) translateX(-220%)}100%{transform:rotate(12deg) translateX(360%)}}
|
| 287 |
+
@keyframes iconFloat{50%{transform:translateY(-3px)}}
|
| 288 |
+
@keyframes dataBar{0%,100%{transform:scaleY(.72);opacity:.7}50%{transform:scaleY(1.18);opacity:1}}
|
| 289 |
+
@keyframes analysisSpark{0%,100%{transform:translateX(0);opacity:.78}50%{transform:translateX(4px);opacity:1}}
|
| 290 |
+
@keyframes ringsDrift{50%{transform:translateY(-2px) rotate(4deg)}}
|
| 291 |
+
@keyframes insightPulse{50%{transform:scale(1.16);text-shadow:0 0 10px currentColor}}
|
| 292 |
+
@keyframes verifyPulse{0%,100%{opacity:.75}50%{opacity:1;text-shadow:0 0 14px currentColor}}
|
| 293 |
+
@keyframes reportScan{0%,100%{transform:translateY(0);opacity:.82}50%{transform:translateY(-2px);letter-spacing:4px;opacity:1}}
|
| 294 |
+
@keyframes identityLink{50%{letter-spacing:3px;transform:translateX(2px)}}
|
| 295 |
+
@keyframes historyLoop{50%{transform:translateY(-2px) scale(1.03);opacity:1}}
|
| 296 |
+
@keyframes privacyShield{50%{transform:scale(1.08);text-shadow:0 0 11px currentColor}}
|
| 297 |
+
@keyframes qualitySpark{50%{transform:translateY(-2px) scale(1.08);text-shadow:0 0 10px currentColor}}
|
| 298 |
+
.network-legend{display:flex;gap:20px;flex-wrap:wrap;justify-content:center;font-size:11px;color:#99b3d3;padding:2px 10px 14px;position:relative;z-index:2}
|
| 299 |
+
.network-legend strong{color:#d5eaff}
|
| 300 |
+
.next-narrative{text-align:center;color:#d9ebff;font-size:13px;line-height:1.55;margin:4px auto 15px;max-width:880px;text-shadow:0 0 12px rgba(98,167,255,.12)}
|
| 301 |
+
.next-mode{font-size:11px;color:#70dcc3;border:1px solid #255e5c;padding:6px 11px;border-radius:30px;white-space:nowrap}
|
| 302 |
+
@media(max-width:1080px){.orchestra .agents{max-width:1200px;gap:22px 24px;grid-template-columns:repeat(3,minmax(0,1fr))}.orchestra .agent{padding:13px 12px;min-height:170px}.orchestra .agent h3{font-size:15px}}
|
| 303 |
+
@media(max-width:700px){.orchestra .agents{grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}.orchestra .agent{min-height:154px}.orchestra .conductor{max-width:100%}.network-links{display:none}.network-legend{justify-content:flex-start}}
|
| 304 |
+
@media(prefers-reduced-motion:reduce){#networkEdges path,#networkEdges path.transfer,.orchestra .conductor,.orchestra .agent .agent-symbol,.orchestra .agent .mini-visual,#agent-data .bars b,#agent-analysis .spark,#agent-insight .rings,#agent-insight .rings span,#agent-verify .checkicons,#agent-report .reportlines,#agent-identity .mini-visual,#agent-history .mini-visual,#agent-privacy .mini-visual,#agent-quality .mini-visual{animation:none!important}.orchestra .agent::after,.orchestra .conductor::before{display:none}}
|
| 305 |
+
|
| 306 |
+
/* ORCHESTRA NEXT v4 — zichtbare lichtstromen, gebaseerd op de SVG-benadering van de originele Space.
|
| 307 |
+
Alleen interface: geen wijziging aan de Excel-import, berekeningen of rapportagefuncties. */
|
| 308 |
+
.orchestra{padding:26px 27px 0;isolation:isolate}
|
| 309 |
+
.orchestra .conductor-wrap{margin-bottom:68px;z-index:4}
|
| 310 |
+
.orchestra .conductor{overflow:visible;isolation:isolate;min-width:330px;max-width:100%;position:relative;animation:conductorBreathe 4s ease-in-out infinite}
|
| 311 |
+
.orchestra .conductor::after{content:"";position:absolute;inset:-8px;border:1px solid rgba(180,128,255,.43);border-radius:19px;box-shadow:0 0 18px rgba(168,112,255,.22);pointer-events:none;z-index:-1;animation:conductorRing 3.2s ease-in-out infinite}
|
| 312 |
+
.orchestra .conductor::before{content:"";position:absolute;inset:-17px;border:1px dashed rgba(154,125,255,.24);border-radius:26px;pointer-events:none;opacity:.45;z-index:-1;animation:conductorRing 5.3s ease-in-out infinite reverse}
|
| 313 |
+
.orchestra .conductor .conductor-icon{overflow:visible;box-shadow:0 0 27px rgba(193,151,255,.6);position:relative}
|
| 314 |
+
.orchestra .conductor .conductor-icon::before{inset:-8px;border-width:2.5px;opacity:1}
|
| 315 |
+
.orchestra .conductor .conductor-icon::after{inset:-16px;border-color:#ae86fc;opacity:.7}
|
| 316 |
+
.orchestra .conductor .brain-symbol{animation:brainBreath 2.8s ease-in-out infinite}
|
| 317 |
+
.orchestra .conductor.running{animation:conductorBreathe 2.5s ease-in-out infinite,conductorPulse 1.3s ease-in-out infinite}
|
| 318 |
+
.orchestra .conductor.transfering{border-color:#eee0ff;box-shadow:0 0 48px rgba(180,112,255,.85),0 0 86px rgba(91,204,255,.29),inset 0 0 35px rgba(151,107,255,.34);animation:conductorDispatch .85s ease-out 1,conductorPulse 1.5s infinite}
|
| 319 |
+
.orchestra .conductor.transfering .brain-symbol{filter:drop-shadow(0 0 10px #e5bcff);animation:brainBreath .9s ease-in-out infinite}
|
| 320 |
+
.orchestra .conductor.transfering .conductor-icon::before{animation-duration:.95s;border-top-color:#fff;border-right-color:#80e9ff}
|
| 321 |
+
.orchestra .agents{max-width:none;grid-template-columns:repeat(3,minmax(0,1fr));gap:88px clamp(65px,6vw,110px);padding:15px 13px 28px;margin:0 auto}
|
| 322 |
+
.orchestra .agent{min-height:228px;padding:18px 18px 15px;overflow:hidden;transition:transform .28s ease,box-shadow .3s ease,border-color .25s ease}
|
| 323 |
+
.orchestra .agent h3{font-size:18px;margin:7px 0 6px}
|
| 324 |
+
.orchestra .agent .agent-symbol{margin-top:8px}
|
| 325 |
+
.orchestra .agent .agent-steps{display:flex!important;flex-direction:column;gap:6px;min-height:110px;margin:12px 0 0;justify-content:flex-start}
|
| 326 |
+
.orchestra .agent .mini-visual{display:none!important}
|
| 327 |
+
.orchestra .agent .agent-bottom{display:none!important}
|
| 328 |
+
.orchestra .agent .agent-step{font-size:11px;line-height:1.4;min-height:19px;color:#9ab2d1;display:flex;gap:7px;animation:lineAppear .27s ease both}
|
| 329 |
+
.orchestra .agent .agent-step .step-mark{width:16px;height:16px;font-size:10px;flex:none;margin-top:1px}
|
| 330 |
+
.orchestra .agent .agent-step.current{color:#f4faff}
|
| 331 |
+
.orchestra .agent .agent-step.complete{color:#c5efe1}
|
| 332 |
+
.orchestra .agent .agent-step.skipped{color:#ffd39b}
|
| 333 |
+
.orchestra .agent.active{transform:translateY(-5px);border-color:var(--accent);box-shadow:0 0 31px color-mix(in srgb,var(--accent) 40%,transparent),inset 0 0 24px color-mix(in srgb,var(--accent) 13%,transparent)}
|
| 334 |
+
.orchestra .agent.active::after{animation:agentSweep 1.15s ease-in-out infinite;opacity:1}
|
| 335 |
+
.orchestra .agent.completed-pulse{animation:agentComplete .55s ease-out 1}
|
| 336 |
+
.orchestra .agent .agent-symbol{animation:iconFloat 3.4s ease-in-out infinite}
|
| 337 |
+
.network-links{position:absolute;inset:0;z-index:2;overflow:hidden;pointer-events:none}
|
| 338 |
+
#networkSvg{display:block;width:100%;height:100%;overflow:hidden}
|
| 339 |
+
#networkEdges .network-base{fill:none;stroke:#486f94;stroke-width:2;opacity:.7;vector-effect:non-scaling-stroke;animation:none}
|
| 340 |
+
#networkEdges .network-complete{fill:none;stroke:#50cead;stroke-width:2.1;opacity:.47;vector-effect:non-scaling-stroke;animation:none}
|
| 341 |
+
#networkEdges .network-active{fill:none;stroke:#83e9ff;stroke-width:3.4;stroke-dasharray:9 14;opacity:1;vector-effect:non-scaling-stroke;animation:networkChase .72s linear infinite;filter:drop-shadow(0 0 6px #5addff)}
|
| 342 |
+
#networkEdges .network-active-glow{fill:none;stroke:#80dfff;stroke-width:10;opacity:.21;vector-effect:non-scaling-stroke;filter:blur(3px)}
|
| 343 |
+
#networkSignals .network-orb{fill:#e5ffff;stroke:#70eaff;stroke-width:1.5;filter:drop-shadow(0 0 9px #6deeff)}
|
| 344 |
+
#networkSignals .network-orb-halo{fill:#6feaff;opacity:.27;filter:blur(4px)}
|
| 345 |
+
.network-legend{margin-top:7px}
|
| 346 |
+
@keyframes networkChase{to{stroke-dashoffset:-46}}
|
| 347 |
+
@keyframes conductorBreathe{50%{filter:brightness(1.16)}}
|
| 348 |
+
@keyframes conductorRing{50%{box-shadow:0 0 27px rgba(189,147,255,.56);opacity:.96;transform:scale(1.022)}}
|
| 349 |
+
@keyframes conductorDispatch{0%,100%{transform:scale(1)}45%{transform:scale(1.045) translateY(-3px)}}
|
| 350 |
+
@keyframes agentComplete{0%{filter:brightness(1)}45%{filter:brightness(1.6)}100%{filter:brightness(1)}}
|
| 351 |
+
@keyframes lineAppear{from{opacity:.3;transform:translateY(3px)}to{opacity:1;transform:translateY(0)}}
|
| 352 |
+
@media(max-width:1120px){.orchestra .agents{gap:65px 34px}.orchestra .agent{min-height:235px;padding:12px}.orchestra .agent h3{font-size:15px}}
|
| 353 |
+
@media(max-width:760px){.orchestra .agents{grid-template-columns:repeat(2,minmax(0,1fr));gap:38px 15px}.orchestra .conductor-wrap{margin-bottom:38px}.orchestra .agent{min-height:248px}.orchestra .agent .agent-step{font-size:10px}.network-links{display:none}}
|
| 354 |
+
@media(max-width:470px){.orchestra .agents{grid-template-columns:1fr}.orchestra .agent{min-height:185px}.orchestra .conductor{width:100%;min-width:0}}
|
| 355 |
+
/* Neutraliseer oudere pseudo-elementafmetingen; anders verschijnt links een vreemd schuin vlak. */
|
| 356 |
+
.orchestra .conductor::before{inset:-17px!important;left:-17px!important;right:-17px!important;top:-17px!important;bottom:-17px!important;width:auto!important;height:auto!important;background:none!important;transform:none!important;filter:none!important}
|
| 357 |
+
.orchestra .conductor::after{inset:-8px!important;left:-8px!important;right:-8px!important;top:-8px!important;bottom:-8px!important;width:auto!important;height:auto!important;background:none!important;transform:none!important;filter:none!important}
|
| 358 |
+
@media(prefers-reduced-motion:reduce){.orchestra .conductor,.orchestra .conductor::before,.orchestra .conductor::after,.orchestra .conductor.transfering,.orchestra .agent .agent-symbol,.orchestra .agent .agent-step,.orchestra .agent.active::after,#networkEdges .network-active,.orchestra .agent.completed-pulse{animation:none!important}#networkSignals{display:none}}
|
| 359 |
+
|
| 360 |
</style></head>
|
| 361 |
<body>
|
| 362 |
<div class="app">
|
| 363 |
<main class="main">
|
| 364 |
+
<header><div class="header-copy"><div class="eyebrow">REAKT / AI ANALYTICS PLATFORM</div><h1>Inloop <span>Intelligence</span> <em>ORCHESTRA</em></h1><p>Maak complexe informatie begrijpelijk en toegankelijk voor iedereen.</p></div><div class="orchestra-hero-title" aria-label="ORCHESTRA by Marcel Ooms"><span class="orchestra-hero-word">ORCHESTRA</span><span class="orchestra-hero-credit">by Marcel Ooms</span></div><div class="header-center-logo"><div class="reakt-wordmark" role="img" aria-label="Reakt — Werken aan je toekomst"><strong class="reakt-name">Reakt</strong><span class="reakt-tagline">Werken aan je toekomst</span></div></div><div class="header-actions"><span class="pill"><i></i> LOKALE ANALYSE</span><span class="clock" id="clock"></span></div></header>
|
| 365 |
+
<div class="topbar"><div><span class="section-kicker">CONTROL CENTER</span><h2>Agent Command Center <span class="live-dot"></span></h2></div><div class="actions"><label class="pace-label" for="paceSelect">Weergave <select id="paceSelect" aria-label="Animatiesnelheid"><option value="presentation">Presentatie ± 30 sec</option><option value="fast">Snel ± 6 sec</option></select></label><button id="resetBtn" class="ghost">↺ Reset</button><button id="startBtn" class="primary">▶ Start voorbeeldanalyse</button></div></div>
|
| 366 |
<section class="import-panel panel" aria-label="Lokale Excelanalyse met 2026 en historische referentie 2025">
|
| 367 |
+
<div class="import-intro"><span class="section-kicker">ORCHESTRA NEXT · BROWSER-LOKAAL</span><strong>Scanregistratie 2026 + referentie 2025</strong><small>Browser-lokale analyse · alle bronlocaties · geen bestanden in Space-repository</small></div>
|
| 368 |
<label class="import-file-label" for="scanFile"><span>▤</span> Rapportage 2026 (.xlsx)</label><input type="file" id="scanFile" accept=".xlsx" aria-label="Rapportagebestand januari tot en met september 2026" />
|
| 369 |
<label class="import-file-label history-label" for="historyFile"><span>◴</span> Historie 2025 (.xlsx)</label><input type="file" id="historyFile" accept=".xlsx" aria-label="Historisch referentiebestand 2025" disabled/>
|
| 370 |
<label class="site-label" for="siteSelect">Locatie</label><select id="siteSelect" disabled><option value="*">Alle locaties</option></select>
|
|
|
|
| 373 |
<div id="historyStatus" class="history-status">◴ Historie 2025 nog niet geladen. Zonder deze referentie zijn instroomcijfers voorlopig.</div>
|
| 374 |
</section>
|
| 375 |
<section class="orchestra panel">
|
| 376 |
+
<div class="mesh"></div><p class="next-narrative">Van ruwe scangegevens naar helder inzicht · volg taakverdeling, gegevensoverdracht en controles onder de motorkap.</p><div class="conductor-wrap"><div class="conductor" id="conductor"><div class="conductor-glow"></div><div class="conductor-icon" aria-hidden="true"><svg class="brain-symbol" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.55" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5c-2.7-3.2-7.4-.9-7.1 2.4C2 9 2 13.6 5 15.2c-.7 4.4 4.9 6.8 7 2.6M12 5c2.7-3.2 7.4-.9 7.1 2.4 2.9 1.6 2.9 6.2-.1 7.8.7 4.4-4.9 6.8-7 2.6M12 5v13"/><path d="M6.6 10.1 9 12v3M17.4 10.1 15 12v3"/><circle cx="9" cy="15.5" r=".9" fill="currentColor" stroke="none"/><circle cx="15" cy="15.5" r=".9" fill="currentColor" stroke="none"/></svg></div><div><small>MASTER ORCHESTRATOR</small><strong>THE CONDUCTOR</strong><span id="conductorStatus">Gereed voor analyse</span></div><div class="conductor-indicator"></div></div></div>
|
| 377 |
+
<div class="network-links" aria-hidden="true"><svg id="networkSvg" preserveAspectRatio="none"><g id="networkEdges"></g><g id="networkSignals"></g></svg></div>
|
| 378 |
<div class="agents">
|
| 379 |
<article class="agent" id="agent-data" style="--accent:#34e6b3"><div class="agent-top"><span>01 / DATA</span><span class="status">STANDBY</span></div><div class="agent-symbol">▤</div><h3>Data Agent</h3><p>Structuur & kwaliteit</p><div class="agent-steps" aria-live="polite" aria-label="Werkstappen"></div><div class="mini-visual bars"><b></b><b></b><b></b><b></b><b></b><b></b><b></b></div><div class="agent-bottom"><div class="track"><i></i></div><span class="percent">0%</span></div></article>
|
| 380 |
+
<article class="agent" id="agent-analysis" style="--accent:#ffcb62"><div class="agent-top"><span>04 / ANALYSE</span><span class="status">STANDBY</span></div><div class="agent-symbol">⌁</div><h3>Analysis Agent</h3><p>Trends & vergelijkingen</p><div class="agent-steps" aria-live="polite" aria-label="Werkstappen"></div><div class="mini-visual spark">▁ ▃ ▂ ▅ ▄ ▆ ▇</div><div class="agent-bottom"><div class="track"><i></i></div><span class="percent">0%</span></div></article>
|
| 381 |
+
<article class="agent" id="agent-insight" style="--accent:#51b9ff"><div class="agent-top"><span>06 / TREND</span><span class="status">STANDBY</span></div><div class="agent-symbol">✦</div><h3>Trend Agent</h3><p>Maandpatronen & duiding</p><div class="agent-steps" aria-live="polite" aria-label="Werkstappen"></div><div class="mini-visual rings">◎ <span>◉</span> ◎</div><div class="agent-bottom"><div class="track"><i></i></div><span class="percent">0%</span></div></article>
|
| 382 |
+
<article class="agent" id="agent-verify" style="--accent:#b18aff"><div class="agent-top"><span>07 / CONTROLE</span><span class="status">STANDBY</span></div><div class="agent-symbol">⬡</div><h3>Verification Agent</h3><p>Schaduwberekeningen</p><div class="agent-steps" aria-live="polite" aria-label="Werkstappen"></div><div class="mini-visual checkicons">✓ ✓ ! ✓</div><div class="agent-bottom"><div class="track"><i></i></div><span class="percent">0%</span></div></article>
|
| 383 |
+
<article class="agent" id="agent-report" style="--accent:#ff9a65"><div class="agent-top"><span>09 / RAPPORT</span><span class="status">STANDBY</span></div><div class="agent-symbol">▧</div><h3>Report Agent</h3><p>Infographic & export</p><div class="agent-steps" aria-live="polite" aria-label="Werkstappen"></div><div class="mini-visual reportlines">▰▰▰▰▰<br>▰▰▰▰<br>▰▰▰</div><div class="agent-bottom"><div class="track"><i></i></div><span class="percent">0%</span></div></article>
|
| 384 |
+
<article class="agent" id="agent-identity" style="--accent:#53d5ec"><div class="agent-top"><span>02 / IDENTITEIT</span><span class="status">STANDBY</span></div><div class="agent-symbol">⛓</div><h3>Identity Agent</h3><p>Pas- en cliëntkoppelingen</p><div class="agent-steps" aria-live="polite"></div><div class="mini-visual">◎ ↔ ◎</div><div class="agent-bottom"><div class="track"><i></i></div><span class="percent">0%</span></div></article>
|
| 385 |
+
<article class="agent" id="agent-history" style="--accent:#60bafa"><div class="agent-top"><span>03 / HISTORIE</span><span class="status">STANDBY</span></div><div class="agent-symbol">◷</div><h3>History Agent</h3><p>Referentie 2025</p><div class="agent-steps" aria-live="polite"></div><div class="mini-visual">2025 ↔ 2026</div><div class="agent-bottom"><div class="track"><i></i></div><span class="percent">0%</span></div></article>
|
| 386 |
+
<article class="agent" id="agent-privacy" style="--accent:#f28cbd"><div class="agent-top"><span>08 / PRIVACY</span><span class="status">STANDBY</span></div><div class="agent-symbol">◇</div><h3>Privacy Agent</h3><p>Lokale verwerkingsroute</p><div class="agent-steps" aria-live="polite"></div><div class="mini-visual">◈ ⛨ ◈</div><div class="agent-bottom"><div class="track"><i></i></div><span class="percent">0%</span></div></article>
|
| 387 |
+
<article class="agent" id="agent-quality" style="--accent:#ea88e9"><div class="agent-top"><span>10 / KWALITEIT</span><span class="status">STANDBY</span></div><div class="agent-symbol">✧</div><h3>Quality Agent</h3><p>Rapportagestatus</p><div class="agent-steps" aria-live="polite"></div><div class="mini-visual">✓ / !</div><div class="agent-bottom"><div class="track"><i></i></div><span class="percent">0%</span></div></article>
|
| 388 |
</div>
|
| 389 |
+
<div class="orchestra-footer"><span><i class="dot green"></i> Systeem gereed</span><span id="flowState">Wacht op startcommando</span><span>◌ <span id="completed">0</span> / 9 agenten voltooid</span></div>
|
| 390 |
</section>
|
| 391 |
<div class="content-grid">
|
| 392 |
<div class="left-content">
|
|
|
|
| 440 |
'use strict';
|
| 441 |
let demoData=null, running=false, completed=0;
|
| 442 |
const $=id=>document.getElementById(id);
|
| 443 |
+
const ids=['data','identity','history','analysis','insight','verify','privacy','report','quality'];
|
| 444 |
const sleep=ms=>new Promise(resolve=>setTimeout(resolve,ms));
|
| 445 |
const escapeHTML=s=>String(s).replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
|
| 446 |
function clock(){ $('clock').textContent=new Intl.DateTimeFormat('nl-NL',{hour:'2-digit',minute:'2-digit',day:'numeric',month:'short'}).format(new Date()); }
|
| 447 |
clock();setInterval(clock,60000);
|
| 448 |
function renderKPIs(data){$('kpis').innerHTML=data.kpis.map(k=>`<div class="kpi"><small>${escapeHTML(k.label)}</small><strong>${escapeHTML(k.value)}</strong><span>${escapeHTML(k.change)}</span></div>`).join('');}
|
| 449 |
function renderChecks(data){$('checks').innerHTML=data.checks.map(c=>{const delta=c.ours-c.shadow;return `<div class="check-row"><span>${escapeHTML(c.label)}</span><span>${c.ours.toLocaleString('nl-NL')} / ${c.shadow.toLocaleString('nl-NL')} <strong class="${delta?'bad':''}">${delta?'⚠ '+(delta>0?'+':'')+delta:'✓ 0'}</strong></span></div>`}).join('');}
|
| 450 |
+
function drawChart(data){const canvas=$('chart'),ctx=canvas.getContext('2d'),w=640,h=250;ctx.clearRect(0,0,w,h);ctx.font='13px Segoe UI';ctx.textAlign='left';const max=500;for(let i=0;i<=4;i++){let y=25+i*45;ctx.strokeStyle='#29405a';ctx.beginPath();ctx.moveTo(44,y);ctx.lineTo(w-15,y);ctx.stroke();ctx.fillStyle='#8298b4';ctx.fillText(String(Math.round(max*(4-i)/4)),5,y+4);}const cols=['#3ee1b6','#ffc66a','#5b9cff','#ad88ff'];data.locations.forEach((loc,index)=>{ctx.strokeStyle=cols[index];ctx.lineWidth=3;ctx.beginPath();loc.visits.forEach((v,j)=>{const x=72+(loc.visits.length===1?0:j*(w-105)/(loc.visits.length-1)),y=205-(v/max)*180;if(j===0)ctx.moveTo(x,y);else ctx.lineTo(x,y)});ctx.stroke();loc.visits.forEach((v,j)=>{const x=72+(loc.visits.length===1?0:j*(w-105)/(loc.visits.length-1)),y=205-(v/max)*180;ctx.fillStyle=cols[index];ctx.beginPath();ctx.arc(x,y,4,0,Math.PI*2);ctx.fill()})});ctx.textAlign='center';ctx.fillStyle='#a6b9d0';['JUL','AUG','SEP'].forEach((m,i)=>ctx.fillText(m,72+(3===1?0:i*(w-105)/2),239));}
|
| 451 |
function log(text){const now=new Date().toLocaleTimeString('nl-NL',{hour:'2-digit',minute:'2-digit',second:'2-digit'});if($('logs').querySelector('.muted'))$('logs').innerHTML='';$('logs').insertAdjacentHTML('afterbegin',`<div class="logitem"><time>${now}</time>${escapeHTML(text)}</div>`)}
|
| 452 |
// De lichtpunten volgen de vijf bestaande SVG-verbindingen. Ze lopen alleen tijdens een actieve processtap.
|
| 453 |
const signalPaths={data:'M500 0 V30 H100 V90',analysis:'M500 0 V30 H300 V90',insight:'M500 0 V90',verify:'M500 0 V30 H700 V90',report:'M500 0 V30 H900 V90'};
|
|
|
|
| 927 |
const colors=['#3ee1b6','#ffc66a','#5b9cff','#ad88ff'];
|
| 928 |
series.forEach((loc,li)=>{
|
| 929 |
ctx.strokeStyle=colors[li];ctx.lineWidth=3;ctx.beginPath();
|
| 930 |
+
loc.visits.forEach((v,j)=>{const x=72+(loc.visits.length===1?0:j*(w-105)/(loc.visits.length-1)),y=205-(v/max)*180;j===0?ctx.moveTo(x,y):ctx.lineTo(x,y)});ctx.stroke();
|
| 931 |
+
loc.visits.forEach((v,j)=>{const x=72+(loc.visits.length===1?0:j*(w-105)/(loc.visits.length-1)),y=205-(v/max)*180;ctx.fillStyle=colors[li];ctx.beginPath();ctx.arc(x,y,4,0,Math.PI*2);ctx.fill()});
|
| 932 |
});ctx.fillStyle='#a6b9d0';ctx.textAlign='center';
|
| 933 |
result.months.forEach((m,i)=>ctx.fillText(m,72+(result.months.length===1?0:i*(w-105)/(result.months.length-1)),239));
|
| 934 |
const legend=document.querySelector('.legend');
|
|
|
|
| 1030 |
$('startBtn').textContent='▶ Analyseer Excelbestand';
|
| 1031 |
$('flowState').textContent='Excelbestand lokaal ingelezen · start de analyse';
|
| 1032 |
log('Excelbestand lokaal verwerkt; analyse moet nog starten. Voor echte data eerst interne toestemming controleren.');
|
| 1033 |
+
}catch(err){$('startBtn').textContent='▶ Start voorbeeldanalyse';state.textContent='⚠ '+err.message;$('siteSelect').disabled=true;$('periodSelect').disabled=true;$('periodType').disabled=true;log('Excel-proef: '+err.message)}finally{$('startBtn').disabled=false}
|
| 1034 |
});
|
| 1035 |
$('historyFile').addEventListener('change',async e=>{
|
| 1036 |
const file=e.target.files?.[0];if(!file||!importedData)return;
|
|
|
|
| 1254 |
$('controllerCompare').addEventListener('click',compareController);
|
| 1255 |
$('controllerClear').addEventListener('click',()=>resetControllerComparison(true));
|
| 1256 |
controllerDefs.forEach(([,id])=>$(id).addEventListener('input',()=>{if(controllerComparison)resetControllerComparison(false)}));
|
| 1257 |
+
|
| 1258 |
+
|
| 1259 |
+
// ORCHESTRA NEXT v4. De concrete rekenfuncties hierboven blijven ongewijzigd.
|
| 1260 |
+
// De netwerkpaden worden aan de kaartRANDEN gekoppeld, niet achter het midden van de kaart.
|
| 1261 |
+
// Bewegende lichtpunten gebruiken requestAnimationFrame/getPointAtLength: zichtbaar in moderne browsers,
|
| 1262 |
+
// zonder afhankelijkheid van SVG animateMotion. De wachttijd is presentatie; echte rekentijd meten we apart.
|
| 1263 |
+
const nextRoutes=[
|
| 1264 |
+
['conductor','identity'],['data','identity'],['identity','history'],
|
| 1265 |
+
['data','analysis'],['identity','insight'],['history','verify'],
|
| 1266 |
+
['analysis','insight'],['insight','verify'],['analysis','privacy'],
|
| 1267 |
+
['insight','report'],['verify','quality'],['privacy','report'],['report','quality']
|
| 1268 |
+
];
|
| 1269 |
+
const nextIds=['data','identity','history','analysis','insight','verify','privacy','report','quality'];
|
| 1270 |
+
const nextRouteMap=new Map();
|
| 1271 |
+
let nextActiveKeys=[],nextFinishedKeys=[],nextAnimationFrame=0,nextAnimationStart=0,nextSignalCircles=[],nextIsRunning=false,nextTransferTimeout=0;
|
| 1272 |
+
const nextMotionDisabled=()=>window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
| 1273 |
+
const nextAgentElement=id=>id==='conductor'?$('conductor'):$('agent-'+id);
|
| 1274 |
+
const nextRouteKey=(a,b)=>a+'>'+b;
|
| 1275 |
+
const nextWait=ms=>new Promise(resolve=>setTimeout(resolve,ms));
|
| 1276 |
+
const nextShowCount=()=>{$('completed').textContent=String(nextIds.filter(id=>$('agent-'+id).classList.contains('done')).length)};
|
| 1277 |
+
function nextPathFor(a,b,frame){
|
| 1278 |
+
const acx=(a.left+a.right)/2,acy=(a.top+a.bottom)/2,bcx=(b.left+b.right)/2,bcy=(b.top+b.bottom)/2;
|
| 1279 |
+
const sameRow=Math.abs(acy-bcy)<Math.min(a.height,b.height)*.58;
|
| 1280 |
+
let x1,y1,x2,y2;
|
| 1281 |
+
if(sameRow){const towardsRight=bcx>=acx;x1=towardsRight?a.right:a.left;y1=acy;x2=towardsRight?b.left:b.right;y2=bcy;
|
| 1282 |
+
const bend=Math.min(20,Math.abs(x2-x1)*.15);return `M ${x1-frame.left} ${y1-frame.top} C ${x1-frame.left+(towardsRight?bend:-bend)} ${y1-frame.top-10},${x2-frame.left-(towardsRight?bend:-bend)} ${y2-frame.top+10},${x2-frame.left} ${y2-frame.top}`;}
|
| 1283 |
+
const downward=bcy>=acy;
|
| 1284 |
+
x1=acx;y1=downward?a.bottom:a.top;x2=bcx;y2=downward?b.top:b.bottom;
|
| 1285 |
+
const mid=(y1+y2)/2;
|
| 1286 |
+
return `M ${x1-frame.left} ${y1-frame.top} C ${x1-frame.left} ${mid-frame.top},${x2-frame.left} ${mid-frame.top},${x2-frame.left} ${y2-frame.top}`;
|
| 1287 |
+
}
|
| 1288 |
+
function nextMakeSvg(tag,attrs={},className=''){
|
| 1289 |
+
const n=document.createElementNS('http://www.w3.org/2000/svg',tag);
|
| 1290 |
+
Object.entries(attrs).forEach(([k,v])=>n.setAttribute(k,String(v)));
|
| 1291 |
+
if(className)n.setAttribute('class',className);
|
| 1292 |
+
return n;
|
| 1293 |
+
}
|
| 1294 |
+
function nextBuildGraph(){
|
| 1295 |
+
const root=document.querySelector('.orchestra'),svg=$('networkSvg'),edge=$('networkEdges');
|
| 1296 |
+
if(!root||!svg||!edge)return;
|
| 1297 |
+
const frame=root.getBoundingClientRect();if(!frame.width||!frame.height)return;
|
| 1298 |
+
svg.setAttribute('viewBox',`0 0 ${frame.width} ${frame.height}`);
|
| 1299 |
+
edge.replaceChildren();nextRouteMap.clear();
|
| 1300 |
+
for(const [from,to] of nextRoutes){
|
| 1301 |
+
const a=nextAgentElement(from)?.getBoundingClientRect(),b=nextAgentElement(to)?.getBoundingClientRect();
|
| 1302 |
+
if(!a||!b)continue;
|
| 1303 |
+
const d=nextPathFor(a,b,frame),key=nextRouteKey(from,to);
|
| 1304 |
+
const base=nextMakeSvg('path',{d},'network-base');base.dataset.route=key;edge.appendChild(base);
|
| 1305 |
+
const glow=nextMakeSvg('path',{d},'network-active-glow');glow.dataset.route=key;edge.appendChild(glow);
|
| 1306 |
+
const flow=nextMakeSvg('path',{d},'network-active');flow.dataset.route=key;edge.appendChild(flow);
|
| 1307 |
+
nextRouteMap.set(key,{base,glow,flow,length:0});
|
| 1308 |
+
}
|
| 1309 |
+
nextDrawRouteStates();
|
| 1310 |
+
}
|
| 1311 |
+
function nextDrawRouteStates(){
|
| 1312 |
+
for(const [key,r] of nextRouteMap){
|
| 1313 |
+
const active=nextActiveKeys.includes(key),done=nextFinishedKeys.includes(key);
|
| 1314 |
+
r.base.setAttribute('class',done?'network-complete':'network-base');
|
| 1315 |
+
r.glow.style.display=active?'':'none';r.flow.style.display=active?'':'none';
|
| 1316 |
+
}
|
| 1317 |
+
nextBuildOrbs();
|
| 1318 |
+
}
|
| 1319 |
+
function nextBuildOrbs(){
|
| 1320 |
+
const layer=$('networkSignals');if(!layer)return;
|
| 1321 |
+
if(nextAnimationFrame)cancelAnimationFrame(nextAnimationFrame);
|
| 1322 |
+
nextAnimationFrame=0;nextSignalCircles=[];layer.replaceChildren();
|
| 1323 |
+
if(!nextActiveKeys.length||nextMotionDisabled()||!document.querySelector('.orchestra.running'))return;
|
| 1324 |
+
for(const key of nextActiveKeys){
|
| 1325 |
+
const r=nextRouteMap.get(key);if(!r)continue;
|
| 1326 |
+
try{r.length=r.flow.getTotalLength()}catch(e){continue}
|
| 1327 |
+
if(!r.length)continue;
|
| 1328 |
+
for(let j=0;j<2;j++){
|
| 1329 |
+
const halo=nextMakeSvg('circle',{r:13,cx:0,cy:0},'network-orb-halo');
|
| 1330 |
+
const dot=nextMakeSvg('circle',{r:4.3,cx:0,cy:0},'network-orb');
|
| 1331 |
+
layer.append(halo,dot);nextSignalCircles.push({r,halo,dot,offset:j*.52});
|
| 1332 |
+
}
|
| 1333 |
+
}
|
| 1334 |
+
nextAnimationStart=performance.now();
|
| 1335 |
+
if(nextSignalCircles.length)nextAnimationFrame=requestAnimationFrame(nextTickOrbs);
|
| 1336 |
+
}
|
| 1337 |
+
function nextTickOrbs(now){
|
| 1338 |
+
const ms=$('paceSelect').value==='fast'?560:1450;
|
| 1339 |
+
for(const o of nextSignalCircles){
|
| 1340 |
+
const progress=((now-nextAnimationStart)/ms+o.offset)%1;
|
| 1341 |
+
const p=o.r.flow.getPointAtLength(o.r.length*progress);
|
| 1342 |
+
o.halo.setAttribute('cx',p.x);o.halo.setAttribute('cy',p.y);
|
| 1343 |
+
o.dot.setAttribute('cx',p.x);o.dot.setAttribute('cy',p.y);
|
| 1344 |
+
}
|
| 1345 |
+
nextAnimationFrame=requestAnimationFrame(nextTickOrbs);
|
| 1346 |
+
}
|
| 1347 |
+
function nextConductorSignal(){
|
| 1348 |
+
const c=$('conductor');if(!c)return;
|
| 1349 |
+
clearTimeout(nextTransferTimeout);c.classList.remove('transfering');
|
| 1350 |
+
// Herstart de CSS-puls betrouwbaar bij elke OVERDRACHT, ook bij opeenvolgende overdrachten.
|
| 1351 |
+
void c.offsetWidth;c.classList.add('transfering');
|
| 1352 |
+
nextTransferTimeout=setTimeout(()=>c.classList.remove('transfering'),$('paceSelect').value==='fast'?500:1000);
|
| 1353 |
+
}
|
| 1354 |
+
function nextRoutesActive(pairs=[]){
|
| 1355 |
+
nextActiveKeys=pairs.map(([a,b])=>nextRouteKey(a,b)).filter(k=>nextRouteMap.has(k));
|
| 1356 |
+
nextDrawRouteStates();
|
| 1357 |
+
if(nextActiveKeys.length)nextConductorSignal();
|
| 1358 |
+
}
|
| 1359 |
+
function nextLines(id,lines,doneIndex=-1,warning=false){
|
| 1360 |
+
const card=$('agent-'+id),wrap=card.querySelector('.agent-steps');card.classList.add('has-steps');wrap.replaceChildren();
|
| 1361 |
+
lines.forEach((line,i)=>{
|
| 1362 |
+
const item=document.createElement('div');item.className='agent-step '+(i<=doneIndex?(warning?'skipped':'complete'):i===doneIndex+1?'current':'');
|
| 1363 |
+
const mark=document.createElement('span');mark.className='step-mark';mark.textContent=i<=doneIndex?(warning?'!':'✓'):i===doneIndex+1?'◌':'·';
|
| 1364 |
+
const txt=document.createElement('span');txt.textContent=line;
|
| 1365 |
+
item.append(mark,txt);wrap.appendChild(item);
|
| 1366 |
+
});
|
| 1367 |
+
}
|
| 1368 |
+
function nextSetStatus(id,value){
|
| 1369 |
+
const card=$('agent-'+id);card.classList.toggle('active',value==='active');card.classList.toggle('done',value==='done'||value==='warning');
|
| 1370 |
+
card.querySelector('.status').textContent={active:'ACTIEF',done:'GEREED',warning:'LET OP',skipped:'NIET BESCHIKBAAR',idle:'STANDBY'}[value]||'STANDBY';
|
| 1371 |
+
}
|
| 1372 |
+
function nextInitCards(){
|
| 1373 |
+
for(const id of nextIds){
|
| 1374 |
+
const card=$('agent-'+id);card.classList.remove('has-steps','active','done','completed-pulse');
|
| 1375 |
+
nextSetStatus(id,'idle');
|
| 1376 |
+
nextLines(id,['Wacht op lokale analyse','Werkstappen verschijnen hier','Overdracht wordt zichtbaar'], -2);
|
| 1377 |
+
}
|
| 1378 |
+
nextShowCount();
|
| 1379 |
+
}
|
| 1380 |
+
async function nextPhase(id,lines,routes=[],warning=false){
|
| 1381 |
+
nextSetStatus(id,'active');nextLines(id,lines,-1,false);
|
| 1382 |
+
nextRoutesActive(routes);
|
| 1383 |
+
$('conductorStatus').textContent='Overdracht · '+$('agent-'+id).querySelector('h3').textContent;
|
| 1384 |
+
$('flowState').textContent=lines[0];
|
| 1385 |
+
log('Procesweergave: '+$('agent-'+id).querySelector('h3').textContent);
|
| 1386 |
+
const phaseDuration=$('paceSelect').value==='fast'?650:3300;
|
| 1387 |
+
const durationStep=phaseDuration/lines.length;
|
| 1388 |
+
for(let i=0;i<lines.length;i++){
|
| 1389 |
+
await nextWait(durationStep);
|
| 1390 |
+
nextLines(id,lines,i,false);
|
| 1391 |
+
$('flowState').textContent=lines[i];
|
| 1392 |
+
}
|
| 1393 |
+
for(const key of nextActiveKeys)if(!nextFinishedKeys.includes(key))nextFinishedKeys.push(key);
|
| 1394 |
+
nextSetStatus(id,warning?'warning':'done');nextLines(id,lines,lines.length-1,warning);
|
| 1395 |
+
const card=$('agent-'+id);card.classList.remove('completed-pulse');void card.offsetWidth;card.classList.add('completed-pulse');
|
| 1396 |
+
log((warning?'Aandacht: ':'Afgerond: ')+id+' · '+lines.at(-1));
|
| 1397 |
+
nextShowCount();
|
| 1398 |
+
}
|
| 1399 |
+
function nextClearNetwork(reset=false){
|
| 1400 |
+
nextActiveKeys=[];if(reset)nextFinishedKeys=[];
|
| 1401 |
+
clearTimeout(nextTransferTimeout);$('conductor').classList.remove('transfering');
|
| 1402 |
+
if(nextAnimationFrame)cancelAnimationFrame(nextAnimationFrame);nextAnimationFrame=0;
|
| 1403 |
+
nextSignalCircles=[];$('networkSignals')?.replaceChildren();nextDrawRouteStates();
|
| 1404 |
+
}
|
| 1405 |
+
function nextResetUI(){nextClearNetwork(true);nextInitCards();requestAnimationFrame(nextBuildGraph)}
|
| 1406 |
+
const nextOriginalReset=reset;
|
| 1407 |
+
reset=function(){nextOriginalReset();nextResetUI()};
|
| 1408 |
+
$('resetBtn').removeEventListener('click',nextOriginalReset);
|
| 1409 |
+
$('resetBtn').addEventListener('click',reset);
|
| 1410 |
+
const nextOriginalStart=start;
|
| 1411 |
+
async function nextStartImported(){
|
| 1412 |
+
if(running||!importedData)return;
|
| 1413 |
+
running=true;nextIsRunning=true;$('startBtn').disabled=true;$('resetBtn').disabled=true;
|
| 1414 |
+
const conductor=$('conductor');conductor.classList.remove('attention');conductor.classList.add('running');
|
| 1415 |
+
document.querySelector('.orchestra').classList.add('running');
|
| 1416 |
+
$('logs').replaceChildren();$('logStatus').textContent='Weergave actief';
|
| 1417 |
+
nextFinishedKeys=[];nextInitCards();nextBuildGraph();
|
| 1418 |
+
const timestamp=performance.now(),fmt=n=>Number(n||0).toLocaleString('nl-NL');let cpu=0;
|
| 1419 |
+
try{
|
| 1420 |
+
await nextPhase('data',[
|
| 1421 |
+
'Bestand 2026 eerder lokaal ingelezen',
|
| 1422 |
+
fmt(importedData.rawCount)+' bronregels beoordeeld bij het inlezen',
|
| 1423 |
+
importedData.sites.length+' inlooplocaties herkend'
|
| 1424 |
+
],[['conductor','identity'],['data','identity']]);
|
| 1425 |
+
const t1=performance.now();
|
| 1426 |
+
const result=calculateImported($('siteSelect').value);
|
| 1427 |
+
cpu+=performance.now()-t1;
|
| 1428 |
+
await nextPhase('identity',[
|
| 1429 |
+
'Pas- en cliëntkoppelingen toegepast',
|
| 1430 |
+
fmt(result.multiPassClients)+' cliënten met meerdere passen gesignaleerd',
|
| 1431 |
+
'Herhaalde scans apart geteld: '+fmt(result.duplicates)
|
| 1432 |
+
],[['data','identity'],['identity','history']]);
|
| 1433 |
+
await nextPhase('history',result.historyLoaded?[
|
| 1434 |
+
'Historische referentie 2025 gebruikt',
|
| 1435 |
+
fmt(result.correctedExisting)+' cliënten uit 2025 herkend',
|
| 1436 |
+
'Eerste registraties over jaren vergeleken'
|
| 1437 |
+
]:[
|
| 1438 |
+
'Geen referentiebestand 2025 geladen',
|
| 1439 |
+
'Eerdere bezoeken zijn niet volledig te toetsen',
|
| 1440 |
+
'Nieuwe instroom blijft voorlopig'
|
| 1441 |
+
],[['identity','history'],['history','verify']],!result.historyLoaded);
|
| 1442 |
+
await nextPhase('analysis',[
|
| 1443 |
+
fmt(result.rows)+' scans in de geselecteerde periode',
|
| 1444 |
+
fmt(result.visits)+' unieke bezoekdagen vastgesteld',
|
| 1445 |
+
fmt(result.active)+' actieve cliënten berekend'
|
| 1446 |
+
],[['data','analysis'],['identity','insight']]);
|
| 1447 |
+
await nextPhase('insight',[
|
| 1448 |
+
result.months.length+' maandperioden verwerkt',
|
| 1449 |
+
'Getelde trends beschikbaar voor de grafiek',
|
| 1450 |
+
'Geen AI-duiding: alleen feitelijke patronen'
|
| 1451 |
+
],[['analysis','insight'],['insight','verify']]);
|
| 1452 |
+
const v=performance.now();result.verification=independentlyVerify(result);importedData.last=result;cpu+=performance.now()-v;
|
| 1453 |
+
await nextPhase('verify',[
|
| 1454 |
+
result.verification.checks.length+' interne telvergelijkingen uitgevoerd',
|
| 1455 |
+
result.verification.mismatches+' interne telverschillen gevonden',
|
| 1456 |
+
result.verification.sourceIssues.length+' typen bronafwijkingen gerapporteerd'
|
| 1457 |
+
],[['history','verify'],['insight','verify'],['verify','quality']],result.verification.mismatches>0);
|
| 1458 |
+
await nextPhase('privacy',[
|
| 1459 |
+
'Excelgegevens lokaal in de browser verwerkt',
|
| 1460 |
+
'Geen AI-API voor deze agentweergave',
|
| 1461 |
+
'Geen zelfstandige AVG-certificering uitgevoerd'
|
| 1462 |
+
],[['analysis','privacy']]);
|
| 1463 |
+
resetControllerComparison(true);updateControllerContext();
|
| 1464 |
+
const t3=performance.now();renderImported(result);cpu+=performance.now()-t3;
|
| 1465 |
+
await nextPhase('report',[
|
| 1466 |
+
'Dashboard met berekende KPI’s bijgewerkt',
|
| 1467 |
+
'Witte managementrapportage beschikbaar',
|
| 1468 |
+
'Concept: niet extern gevalideerd'
|
| 1469 |
+
],[['insight','report'],['privacy','report'],['report','quality']]);
|
| 1470 |
+
const concern=result.verification.mismatches>0||!result.historyLoaded;
|
| 1471 |
+
await nextPhase('quality',[
|
| 1472 |
+
'Interne rekenvergelijking: '+(result.verification.mismatches?'afwijking':'geen telverschil'),
|
| 1473 |
+
'Historie 2025: '+(result.historyLoaded?'meegenomen':'niet aangeleverd'),
|
| 1474 |
+
'Geen formele vrijgave door businesscontroller'
|
| 1475 |
+
],[['verify','quality'],['report','quality']],concern);
|
| 1476 |
+
conductor.classList.add('attention');$('conductorStatus').textContent='Verwerkingsweergave afgerond';
|
| 1477 |
+
$('flowState').textContent='Concept beschikbaar · NIET EXTERN GEVALIDEERD';$('logStatus').textContent='Afgerond';
|
| 1478 |
+
log(`Echte berekening, interne verificatie en weergave: ${(cpu/1000).toFixed(2)} sec. Geanimeerde procesweergave: ${((performance.now()-timestamp)/1000).toFixed(1)} sec (exclusief Excel-invoer).`);
|
| 1479 |
+
}catch(err){log('FOUT: '+err.message);$('flowState').textContent='Berekening of weergave mislukt';conductor.classList.add('attention');$('conductorStatus').textContent='Fout gedetecteerd';}
|
| 1480 |
+
finally{nextClearNetwork(false);running=false;nextIsRunning=false;$('startBtn').disabled=false;$('resetBtn').disabled=false;conductor.classList.remove('running');document.querySelector('.orchestra').classList.remove('running');}
|
| 1481 |
+
}
|
| 1482 |
+
start=async function(){
|
| 1483 |
+
if(running)return;
|
| 1484 |
+
if(importedData)return nextStartImported();
|
| 1485 |
+
nextClearNetwork(true);
|
| 1486 |
+
for(const id of ['identity','history','privacy','quality']){nextSetStatus(id,'skipped');nextLines(id,['Geen echte Excelbron in demonstratie','Controle niet uitgevoerd'],1,true);}
|
| 1487 |
+
return nextOriginalStart();
|
| 1488 |
+
};
|
| 1489 |
+
$('startBtn').removeEventListener('click',nextOriginalStart);
|
| 1490 |
+
$('startBtn').addEventListener('click',start);
|
| 1491 |
+
window.addEventListener('resize',()=>requestAnimationFrame(nextBuildGraph));
|
| 1492 |
+
if(typeof ResizeObserver!=='undefined')new ResizeObserver(()=>requestAnimationFrame(nextBuildGraph)).observe(document.querySelector('.orchestra'));
|
| 1493 |
+
nextInitCards();requestAnimationFrame(nextBuildGraph);
|
| 1494 |
+
|
| 1495 |
</script></body></html>
|