0% found this document useful (0 votes)
2 views488 pages

Source Code 32

Uploaded by

denbel
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views488 pages

Source Code 32

Uploaded by

denbel
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

<!

DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8"/>

<meta name="viewport" content="width=device-width, initial-scale=1.0"/>

<title>Ethio-Djibouti Railway Share Company (EDR)</title>

<style>

*{box-sizing:border-box;margin:0;padding:0}

body{font-family:"Segoe UI",Arial,sans-
serif;background:#e8f0f7;color:#1a2a1a;font-size:12px}

/* HEADER */

.hdr{background:linear-gradient(135deg,#0a3d1f 0%,#1a6b3a
50%,#0a3d1f 100%);padding:0;display:flex;align-items:stretch;border-
bottom:4px solid #27ae60;box-shadow:0 3px 12px rgba(0,0,0,.35)}

.hdr-logo{background:rgba(255,255,255,.97);padding:8px
18px;display:flex;align-items:center;border-right:3px solid #27ae60;min-
width:220px}

.hdr-logo img{height:54px;object-fit:contain}

.hdr-center{flex:1;padding:10px 20px;display:flex;flex-
direction:column;justify-content:center}

.hdr-title{font-size:19px;font-weight:800;color:#fff;letter-spacing:.5px;text-
shadow:1px 1px 4px rgba(0,0,0,.4);line-height:1.2}

.hdr-sub{font-size:10px;color:#a8d5b5;margin-top:3px;letter-spacing:.3px}

.hdr-right{display:flex;flex-direction:column;align-items:flex-end;justify-
content:center;padding:10px 16px;gap:5px}

.hdr-badges{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}

.hbadge{padding:3px 10px;border-radius:3px;font-size:10px;font-
weight:700;letter-spacing:.3px}

.[Link]{background:#27ae60;color:#fff}
.[Link]{background:rgba(255,255,255,.15);color:#fff;border:1px solid
rgba(255,255,255,.3)}

.[Link]{background:#e74c3c;color:#fff;cursor:pointer}

.[Link]:hover{background:#c0392b}

.hdr-leader{font-size:9px;color:#a8d5b5;text-align:right}

.hdr-leader span{color:#fff;font-weight:600}

/*
═══════════════════════════════════════════════════════
════════
LOGIN MODAL — Role-Based Card Selection (v2)

═══════════════════════════════════════════════════════
════════ */

/* Full-screen overlay with rail-themed blurred backdrop */

/*
═══════════════════════════════════════════════════════
════════
LOGIN OVERLAY — Integrated Corporate Branding (v3)

═══════════════════════════════════════════════════════
════════ */

/* Full-screen overlay with rail-themed blurred backdrop */

.login-overlay{

display:none;position:fixed;inset:0;z-index:10000;

align-items:center;justify-content:center;

background:
radial-gradient(ellipse at 20% 50%, rgba(10,61,31,.55) 0%, transparent
60%),

radial-gradient(ellipse at 80% 20%, rgba(39,174,96,.18) 0%, transparent


50%),

linear-gradient(160deg,#050e08 0%,#0a1f10 35%,#071a0d


70%,#020804 100%);

backdrop-filter:blur(2px);

pointer-events:all;

.[Link]{display:flex}

/* Animated rail track lines on backdrop */

.login-overlay::before{

content:"";position:absolute;inset:0;

background:

repeating-linear-gradient(90deg,transparent 0px,transparent
119px,rgba(39,174,96,.07) 119px,rgba(39,174,96,.07) 120px),

repeating-linear-gradient(0deg,transparent 0px,transparent
59px,rgba(39,174,96,.04) 59px,rgba(39,174,96,.04) 60px);

pointer-events:none;

/* ── Login card ── */

.login-box{

z-index:10001;

background:#fff;border-radius:16px;

width:500px;max-width:96vw;

box-shadow:
0 32px 80px rgba(0,0,0,.65),

0 0 0 1px rgba(39,174,96,.2),

0 0 60px rgba(10,61,31,.3);

position:relative;

overflow:hidden;

/* Bottom rail-stripe accent */

.login-box::after{

content:"";position:absolute;bottom:0;left:0;right:0;height:4px;

background:repeating-linear-gradient(90deg,#27ae60 0px,#27ae60
20px,#0a3d1f 20px,#0a3d1f 40px);

z-index:2;

/* ══════════════════════════════════════

BRANDED HEADER PANEL

══════════════════════════════════════ */

.login-brand-panel{

background:linear-gradient(145deg,#0a3d1f 0%,#0d4f28 40%,#0a3d1f


70%,#073016 100%);

padding:28px 32px 24px;

position:relative;

overflow:hidden;

border-radius:16px 16px 0 0;

/* Decorative geometry */
.login-brand-panel::before{

content:"";position:absolute;

top:-40px;right:-40px;

width:160px;height:160px;

border-radius:50%;

background:radial-gradient(circle,rgba(39,174,96,.22) 0%,transparent
70%);

pointer-events:none;

.login-brand-panel::after{

content:"";position:absolute;

bottom:-20px;left:-20px;

width:120px;height:120px;

border-radius:50%;

background:radial-gradient(circle,rgba(255,255,255,.04) 0%,transparent
70%);

pointer-events:none;

/* Rail track stripe inside header */

.login-brand-stripe{

position:absolute;bottom:0;left:0;right:0;height:3px;

background:repeating-linear-gradient(90deg,#27ae60 0px,#27ae60
14px,rgba(255,255,255,.12) 14px,rgba(255,255,255,.12) 18px);

/* Logo + text layout */

.login-brand-inner{

display:flex;align-items:center;gap:18px;position:relative;z-index:1;
}

/* Logo emblem container */

.login-emblem{

width:76px;height:76px;border-radius:12px;

background:linear-
gradient(145deg,rgba(255,255,255,.98),rgba(240,248,240,.95));

display:flex;align-items:center;justify-content:center;

flex-shrink:0;

box-shadow:

0 4px 20px rgba(0,0,0,.35),

0 0 0 3px rgba(39,174,96,.45),

inset 0 1px 0 rgba(255,255,255,.9);

position:relative;overflow:hidden;

.login-emblem::before{

content:"";position:absolute;bottom:0;left:0;right:0;height:3px;

background:linear-gradient(90deg,#27ae60,#1a6b3a);

.login-emblem img{

height:58px;width:58px;object-fit:contain;

filter:drop-shadow(0 2px 6px rgba(10,61,31,.25));

/* Text block */

.login-brand-text{flex:1;min-width:0}

.login-brand-org{
font-size:9px;font-weight:800;color:rgba(255,255,255,.55);

letter-spacing:1.4px;text-transform:uppercase;

margin-bottom:3px;

.login-brand-name{

font-size:17px;font-weight:900;color:#fff;

letter-spacing:.4px;line-height:1.15;

text-shadow:0 2px 8px rgba(0,0,0,.4);

margin-bottom:3px;

.login-brand-name span{color:#5dd68a}

.login-brand-div{

font-size:9.5px;font-weight:600;color:rgba(255,255,255,.55);

letter-spacing:.6px;margin-bottom:8px;

/* System badge row */

.login-badges-row{display:flex;gap:6px;align-items:center;flex-wrap:wrap}

.login-sys-badge{

display:inline-flex;align-items:center;gap:4px;

background:rgba(39,174,96,.18);border:1px solid rgba(39,174,96,.4);

border-radius:4px;padding:3px 8px;

font-size:8.5px;font-weight:800;color:#7ee8a2;

letter-spacing:.4px;text-transform:uppercase;

.[Link]{

background:rgba(255,255,255,.08);border-
color:rgba(255,255,255,.2);color:rgba(255,255,255,.7);
}

/* ── Login form body ── */

.login-form-body{padding:24px 32px 28px}

/* Divider label */

.login-step-label{

font-size:9px;font-weight:800;color:#0a3d1f;letter-spacing:.8px;

text-transform:uppercase;margin-bottom:10px;

display:flex;align-items:center;gap:8px;

.login-step-label::before,.login-step-label::after{

content:"";flex:1;height:1px;background:#d4e8d4;

/* Role cards row */

.role-cards{display:flex;gap:12px;margin-bottom:20px;position:relative;z-
index:1}

/* Individual role card */

.role-card{

flex:1;border:2px solid #d4e8d4;border-radius:8px;padding:14px 12px;

cursor:pointer;transition:all .2s ease;text-align:center;

background:#f8fdf8;position:relative;

user-select:none;

pointer-events:all;

-webkit-tap-highlight-color:rgba(39,174,96,.18);
}

.role-card:hover{

border-color:#27ae60;background:#edfaf0;

transform:translateY(-2px);box-shadow:0 6px 20px rgba(39,174,96,.18);

/* Selected state */

.[Link]{

border-color:#0a3d1f;background:linear-gradient(135deg,#edfaf0,#d4efdf);

box-shadow:0 6px 20px rgba(10,61,31,.22);transform:translateY(-2px);

.[Link]::before{

content:"✓";position:absolute;top:7px;right:10px;

font-size:11px;font-weight:900;color:#0a3d1f;

/* Admin card accent */

.[Link]-card .rc-icon{background:linear-
gradient(135deg,#0a3d1f,#1a6b3a)}

/* Guest card accent */

.[Link]-card .rc-icon{background:linear-
gradient(135deg,#1e8449,#27ae60)}

/* Chief Admin card accent */

.[Link]-admin-card .rc-icon{background:linear-
gradient(135deg,#7d6000,#b8860b)}

.[Link]-admin-card{border-color:#c9a227}

.[Link]-admin-card:hover{border-
color:#b8860b;background:#fffbea}

.[Link]{border-
color:#7d6000;background:linear-gradient(135deg,#fffbea,#fef3cd)}
.rc-icon{

width:44px;height:44px;border-radius:50%;display:flex;align-items:center;

justify-content:center;margin:0 auto 8px;font-size:20px;

box-shadow:0 3px 10px rgba(0,0,0,.18);

.rc-name{font-size:13px;font-weight:800;color:#0a3d1f;margin-bottom:2px}

.rc-desc{font-size:9px;color:#666;margin-bottom:8px;line-height:1.4}

.rc-perms{list-style:none;padding:0;margin:0;text-align:left}

.rc-perms li{font-size:8px;color:#444;padding:1px 0;display:flex;align-


items:center;gap:4px;pointer-events:none}

.rc-perms li::before{content:"•";color:#27ae60;font-weight:900;font-
size:10px}

.rc-perms [Link]::before{content:"✕";color:#e74c3c;font-size:8px}

.rc-icon,.rc-name,.rc-desc{pointer-events:none}

/* Password field (shown after role selection) */

.pw-section{

display:none;animation:fadeSlideIn .25s ease;

background:#f0f8f4;border:1px solid #c8e6d0;border-radius:8px;

padding:16px;margin-bottom:16px;

pointer-events:all;

.[Link]{display:block}

@keyframes fadeSlideIn{from{opacity:0;transform:translateY(-
6px)}to{opacity:1;transform:translateY(0)}}

.pw-role-badge{

display:inline-flex;align-items:center;gap:5px;
background:#0a3d1f;color:#fff;border-radius:20px;

padding:3px 10px;font-size:9px;font-weight:700;

margin-bottom:10px;letter-spacing:.3px;

.pw-label{font-size:10px;font-weight:700;color:#0a3d1f;margin-
bottom:4px;display:block;letter-spacing:.05em}

.pw-input-wrap{position:relative}

.pw-input-wrap input{

width:100%;border:1.5px solid #b8d8c0;border-radius:6px;

padding:9px 36px 9px 11px;font-size:12px;font-family:inherit;

outline:none;transition:border .15s;background:#fff;

.pw-input-wrap input:focus{border-color:#0a3d1f;box-shadow:0 0 0 3px


rgba(39,174,96,.12)}

.pw-toggle{

position:absolute;right:10px;top:50%;transform:translateY(-50%);

background:none;border:none;cursor:pointer;font-size:13px;

color:#888;line-height:1;padding:2px;

/* Sign-in button */

.login-btn{

width:100%;border:none;border-radius:8px;padding:12px;

font-size:13px;font-weight:800;cursor:pointer;

font-family:inherit;letter-spacing:.3px;transition:all .18s;

background:linear-gradient(135deg,#0a3d1f,#1a6b3a);color:#fff;

box-shadow:0 4px 14px rgba(10,61,31,.35);


}

.login-btn:hover:not(:disabled){

background:linear-gradient(135deg,#073016,#145730);

box-shadow:0 6px 20px rgba(10,61,31,.45);transform:translateY(-1px);

.login-btn:disabled{background:#c8d8c8;color:#888;cursor:not-allowed;box-
shadow:none;transform:none}

.login-btn:not(:disabled){pointer-events:all;cursor:pointer}

/* Error message */

.login-err{color:#c0392b;font-size:10px;text-align:center;margin-
top:9px;display:none;

background:#fdf0ef;border:1px solid #f5c6c3;border-


radius:4px;padding:6px 10px;}

/* Responsive */

@media(max-width:520px){

.login-box{border-radius:12px}

.login-brand-panel{padding:22px 20px 20px}

.login-emblem{width:62px;height:62px}

.login-emblem img{height:46px;width:46px}

.login-brand-name{font-size:14px}

.login-form-body{padding:18px 20px 22px}

/* NAV */

.nav-bar{background:#0a3d1f;display:flex;gap:0;padding:0 8px;overflow-
x:auto;border-bottom:2px solid #27ae60}
.nav-tab{padding:9px 15px;cursor:pointer;font-size:11px;font-
weight:600;color:#a8d5b5;border-bottom:3px solid transparent;white-
space:nowrap;transition:all .15s;display:flex;align-items:center;gap:5px}

.nav-tab:hover{color:#fff;background:rgba(255,255,255,.08)}

.[Link]{color:#fff;border-bottom-
color:#27ae60;background:rgba(255,255,255,.1)}

/* PAGES */

.page{display:none;padding:10px;min-height:calc(100vh - 130px)}

.[Link]{display:block}

/* WIDGET */

.row{display:flex;gap:8px;margin-bottom:8px;flex-wrap:wrap}

.widget{background:#fff;border-radius:5px;border:1px solid
#c8d8c8;overflow:hidden;box-shadow:0 1px 5px rgba(0,0,0,.07)}

.wh{padding:6px 10px;font-size:10px;font-weight:800;display:flex;align-
items:center;justify-content:space-between;letter-spacing:.6px;color:#fff}

.[Link]{background:linear-gradient(90deg,#0a3d1f,#1a6b3a)}

.[Link]{background:linear-gradient(90deg,#1e8449,#27ae60)}

.[Link]{background:linear-gradient(90deg,#0e6655,#17a589)}

.[Link]{background:linear-gradient(90deg,#7b241c,#e74c3c)}

.[Link]{background:linear-gradient(90deg,#1a252f,#2c3e50)}

.[Link]{background:linear-gradient(90deg,#784212,#d35400)}

.[Link]{background:linear-gradient(90deg,#4a235a,#8e44ad)}

.wb{padding:8px 10px}

/* FLEX UTILS */

.f1{flex:1;min-width:0}
.fw2{width:calc(50% - 4px)}

.fw3{width:calc(33.33% - 6px)}

.fw25{width:calc(25% - 6px)}

.fw75{width:calc(75% - 4px)}

.fw66{width:calc(66.66% - 4px)}

/* KPI TILE */

.kpi-grid{display:grid;gap:6px}

.kpi{background:#f0f8f0;border:1px solid #c8d8c8;border-


radius:4px;padding:8px 10px;text-align:center;border-left:3px solid
#27ae60}

.kpi-val{font-size:22px;font-weight:800;color:#0a3d1f;line-height:1}

.kpi-lbl{font-size:9px;color:#555;margin-top:2px;font-weight:600}

.[Link]-kpi{border-left-color:#e74c3c}.[Link]-kpi .kpi-val{color:#c0392b}

.[Link]-kpi{border-left-color:#d35400}.[Link]-kpi .kpi-
val{color:#d35400}

.[Link]-kpi{border-left-color:#2980b9}.[Link]-kpi .kpi-
val{color:#2980b9}

.[Link]-kpi{border-left-color:#27ae60}.[Link]-kpi .kpi-
val{color:#1e8449}

/* HBAR */

.hbr{display:flex;align-items:center;gap:5px;margin-bottom:5px}

.hbr-lbl{width:130px;font-size:9px;color:#333;text-align:right;flex-
shrink:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

.[Link]{width:90px}

.hbr-track{flex:1;height:16px;background:#e8f0e8;border-
radius:2px;overflow:hidden}
.hbr-fill{height:100%;border-radius:2px;display:flex;align-
items:center;padding-left:5px;font-size:9px;color:#fff;font-weight:700;min-
width:20px}

.hbr-num{font-size:9px;color:#333;width:32px;text-align:right;flex-shrink:0}

/* PBAR */

.pbar{height:8px;background:#e8f0e8;border-
radius:4px;overflow:hidden;margin-top:2px}

.pbar-f{height:100%;border-radius:4px}

/* BADGE */

.bdg{display:inline-block;padding:2px 7px;border-radius:10px;font-
size:9px;font-weight:700}

.bdg.g{background:#d4efdf;color:#1e8449}

.bdg.r{background:#fadbd8;color:#c0392b}

.bdg.o{background:#fdebd0;color:#d35400}

.bdg.b{background:#d6eaf8;color:#1a5276}

.[Link]{background:#eaecee;color:#555}

.bdg.p{background:#e8daef;color:#6c3483}

/* TABLE */

.tbl{width:100%;border-collapse:collapse;font-size:10px}

.tbl th{background:#0a3d1f;color:#fff;padding:5px 7px;font-size:9px;font-


weight:700;text-align:left;white-space:nowrap}

.tbl td{padding:4px 7px;border-bottom:1px solid #dde8d0;vertical-


align:middle}

.tbl tr:nth-child(even) td{background:#f4f9f2}

.tbl tr:hover td{background:#e4f0e0}

.tbl td:first-child{font-weight:600}
/* CRITICAL MILESTONES TABLE */

.cms-table{width:100%;border-collapse:collapse;font-size:9px;min-
width:720px}

.cms-table thead tr{background:linear-gradient(90deg,#0a3d1f,#1a6b3a)}

.cms-table th{padding:7px 9px;color:#fff;font-size:8.5px;font-


weight:800;text-align:left;white-space:nowrap;letter-spacing:.3px;border-
right:1px solid rgba(255,255,255,.1)}

.cms-table th:last-child{border-right:none}

.cms-table td{padding:6px 9px;border-bottom:1px solid #dde8d0;vertical-


align:middle;border-right:1px solid #eef3ee}

.cms-table td:last-child{border-right:none}

.cms-table tr:nth-child(even) td{background:#f4f9f2}

.cms-table tr:hover td{background:#e8f5e8}

.cms-row-critical td{background:#fff8f6!important}

.cms-row-critical:hover td{background:#fdeee8!important}

.cms-row-overdue td{background:#fdf0ef!important}

.cms-row-overdue:hover td{background:#fce4e1!important}

.cms-row-due30 td{background:#fffbf0!important}

.cms-row-due30:hover td{background:#fff5de!important}

.cms-proj-chip{display:inline-block;padding:2px 7px;border-radius:3px;font-
size:8px;font-weight:800;white-space:nowrap;letter-spacing:.2px}

.cms-ms-name{font-weight:800;color:#0a3d1f;font-size:9px;line-height:1.3}

.cms-activity{font-size:8px;color:#1a6b3a;font-weight:700;margin-top:1px}

.cms-days-badge{display:inline-block;padding:3px 8px;border-
radius:4px;font-size:8.5px;font-weight:800;white-space:nowrap;min-
width:58px;text-align:center}

.cms-days-overdue{background:#fadbd8;color:#c0392b;border:1px solid
#f5c6c3}
.cms-days-due30{background:#fdebd0;color:#a04000;border:1px solid
#f8cda0}

.cms-days-normal{background:#eafaf1;color:#1e8449;border:1px solid
#a9dfbf}

.cms-status-badge{display:inline-block;padding:2px 8px;border-
radius:8px;font-size:8px;font-weight:800;white-space:nowrap}

.cms-filter-bar{display:flex;gap:6px;padding:7px
10px;background:#f4f9f2;border-bottom:1px solid #dde8d0;flex-
wrap:wrap;align-items:center}

.cms-filter-btn{padding:3px 10px;border-radius:3px;font-size:8.5px;font-
weight:700;border:1px solid
#c8d8c8;background:#fff;color:#555;cursor:pointer;font-
family:inherit;transition:all .15s}

.[Link]{background:#0a3d1f;color:#fff;border-color:#0a3d1f}

.cms-legend{display:flex;gap:12px;align-items:center;margin-left:auto;flex-
wrap:wrap}

.cms-leg-item{display:flex;align-items:center;gap:4px;font-
size:8px;color:#666;font-weight:600}

.cms-leg-dot{width:10px;height:10px;border-radius:2px}

.cms-empty{text-align:center;padding:30px;color:#aaa;font-size:10px}

.cms-date-col{white-space:nowrap;font-size:9px}

.cms-date-delayed{color:#c0392b;font-weight:700}

.cms-date-normal{color:#555}

.cms-variance{font-size:8px;font-weight:700;margin-top:1px}

/* GANTT */

.gantt-lbl{width:180px;font-size:9px;color:#333;flex-shrink:0;white-
space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:600}

.gantt-track{flex:1;height:18px;background:#e8f0e8;border-
radius:3px;position:relative;overflow:hidden}
.gantt-bar{height:100%;border-
radius:3px;position:absolute;display:flex;align-items:center;padding:0
5px;font-size:9px;color:#fff;font-weight:700;white-
space:nowrap;overflow:hidden}

.gantt-pct{font-size:9px;width:32px;text-align:right;color:#333;flex-shrink:0}

.gantt-months{display:flex;margin-left:186px;margin-bottom:4px}

.gantt-m{flex:1;font-size:8px;color:#0a3d1f;font-weight:700;text-
align:center;border-left:1px solid #c8d8c8;padding:1px 0}

/* RISK MATRIX */

.rm{border-collapse:collapse;width:100%;font-size:10px}

.rm td,.rm th{border:1px solid #c8d8c8;padding:5px 6px;text-


align:center;font-weight:700}

.rm-r{background:#e74c3c;color:#fff}

.rm-o{background:#f39c12;color:#fff}

.rm-y{background:#f1c40f;color:#333}

.rm-g{background:#27ae60;color:#fff}

.rm-t{background:#1abc9c;color:#fff}

.rm-h{background:#0a3d1f;color:#fff;font-size:9px}

/* CALENDAR */

.cal{width:100%;border-collapse:collapse;font-size:10px}

.cal th{background:#0a3d1f;color:#fff;padding:4px;text-align:center;font-
size:9px}

.cal td{border:1px solid #dde8d0;padding:3px;text-


align:center;height:26px;vertical-align:middle;cursor:pointer}

.cal [Link]{background:#27ae60;color:#fff;border-radius:50%;font-
weight:700}

.cal [Link]-ev{background:#d4efdf;color:#1e8449;font-weight:700}
.cal [Link]{background:#fadbd8;color:#c0392b;font-weight:700}

/* EDIT CONTROLS */

.edit-btn{background:#0a3d1f;color:#fff;border:none;border-
radius:3px;padding:2px 8px;cursor:pointer;font-size:9px;font-
weight:700;font-family:inherit}

.edit-btn:hover{background:#1a6b3a}

.[Link]{background:#c0392b}.edit-
[Link]:hover{background:#922b21}

.[Link]{background:#1a5276}.edit-
[Link]:hover{background:#0d3349}

.[Link]{background:#d35400}.edit-
[Link]:hover{background:#a04000}

.add-btn{background:#27ae60;color:#fff;border:none;border-
radius:3px;padding:3px 10px;cursor:pointer;font-size:10px;font-
weight:700;font-family:inherit;display:inline-flex;align-items:center;gap:4px}

.add-btn:hover{background:#1e8449}

/* MODAL */

.modal-bg{display:none;position:fixed;inset:0;background:rgba(0,0,0,.55);z-
index:500;align-items:center;justify-content:center;backdrop-filter:blur(3px)}

.[Link]{display:flex}

.modal{background:#fff;border-radius:7px;padding:24px;width:500px;max-
width:96vw;max-height:90vh;overflow-y:auto;border-top:5px solid
#27ae60;box-shadow:0 20px 60px rgba(0,0,0,.4)}

.modal h3{font-size:15px;color:#0a3d1f;margin-bottom:16px;font-
weight:800;display:flex;align-items:center;gap:8px}

.mf{margin-bottom:11px}

.mf label{display:block;font-size:10px;font-weight:700;color:#555;margin-
bottom:3px;letter-spacing:.05em}
.mf input,.mf select,.mf textarea{width:100%;border:1px solid
#c8d8c8;border-radius:4px;padding:7px 9px;font-size:11px;font-
family:inherit;outline:none;transition:border .15s}

.mf input:focus,.mf select:focus,.mf textarea:focus{border-color:#27ae60}

.mf textarea{height:65px;resize:none}

.mf-row{display:grid;grid-template-columns:1fr 1fr;gap:10px}

.mbtns{display:flex;gap:8px;justify-content:flex-end;margin-top:16px;flex-
wrap:wrap}

.mbtn{padding:7px 18px;border-radius:4px;border:none;font-size:11px;font-
family:inherit;cursor:pointer;font-weight:700}

.mbtn.p{background:#0a3d1f;color:#fff}.mbtn.p:hover{background:#1a6b3
a}

.mbtn.c{background:#eaecee;color:#555}.mbtn.c:hover{background:#d5d8
dc}

.mbtn.r{background:#e74c3c;color:#fff}.mbtn.r:hover{background:#c0392b
}

/* TOAST */

.toast-wrap{position:fixed;bottom:18px;right:18px;z-
index:1000;display:flex;flex-direction:column;gap:6px}

.toast{background:#0a3d1f;color:#fff;padding:9px 15px;border-
radius:5px;font-size:11px;display:flex;align-items:center;gap:8px;border-
left:4px solid #27ae60;box-shadow:0 4px 15px
rgba(0,0,0,.25);animation:tIn .2s ease}

@keyframes
tIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:transla
teY(0)}}

/* INLINE EDIT */

.editable{border-bottom:1px dashed #27ae60;cursor:pointer;min-


width:20px;display:inline-block}
.editable:hover{background:#e4f0e0;border-radius:2px}

.editable[contenteditable="true"]{outline:none;background:#e4f0e0;border-
radius:2px;padding:1px 3px}

/* ADMIN PANEL */

/* Role status bar — shared by Admin and Guest; colour set by JS */

.admin-bar{

background:#1a2a1a;color:#fff;padding:5px 12px;

display:none;align-items:center;gap:10px;font-size:10px;

border-bottom:2px solid #e74c3c; /* overridden for guest in bar open


event */

.[Link]{display:flex}

/* The role badge pill inside the bar */

.admin-badge{

background:#e74c3c; /* default Admin; JS overrides for Guest */

padding:2px 10px;border-radius:20px;font-weight:800;font-size:9px;

letter-spacing:.3px;

/* PROGRESS RING */

.ring-wrap{display:flex;flex-direction:column;align-items:center}

/* REPORT PREVIEW */

.report-preview{background:#f8fdf8;border:1px solid #c8d8c8;border-


radius:4px;padding:10px;margin-top:8px;font-size:10px;color:#333;line-
height:1.6}
/* NOTIFICATIONS */

.notif-row{display:flex;align-items:center;justify-content:space-
between;padding:8px 0;border-bottom:1px solid #e8f0e8}

/* ── EVM / Cost Enhancement Styles ── */

.evm-kpi{background:#f4f9f2;border:1px solid #c8d8c8;border-


radius:4px;padding:7px 8px;text-align:center}

.[Link]{border-top:3px solid #0a3d1f}.[Link]{border-top:3px


solid #2980b9}.[Link]{border-top:3px solid #27ae60}

.[Link]{border-top:3px solid #d35400}.[Link]{border-top:3px


solid #8e44ad}.[Link]{border-top:3px solid #1abc9c}

.evm-kpi-val{font-size:15px;font-weight:800;line-height:1.1}

.evm-kpi-lbl{font-size:8px;color:#666;margin-top:2px;font-weight:700;letter-
spacing:.3px}

.evm-kpi-sub{font-size:8px;color:#888;margin-top:1px}

.cv-row{display:flex;align-items:center;gap:8px;padding:6px 0;border-
bottom:1px solid #e8f0e8}

.cv-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}

.cv-name{font-size:9px;font-weight:700;color:#0a3d1f;flex:1;min-
width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.cv-bar-track{flex:1;height:8px;background:#e8f0e8;border-
radius:3px;overflow:hidden;max-width:120px}

.cv-bar-fill{height:100%;border-radius:3px}

.cv-variance{font-size:9px;font-weight:700;width:70px;text-align:right;flex-
shrink:0}

.cv-status-badge{padding:2px 8px;border-radius:10px;font-size:8px;font-
weight:800;flex-shrink:0}

.[Link]{background:#d4efdf;color:#1e8449}

.[Link]{background:#fdebd0;color:#d35400}

.[Link]{background:#fadbd8;color:#c0392b}
.cf-chart-wrap{display:flex;align-items:flex-end;gap:6px;padding:10px 0
0;min-height:120px;overflow-x:auto}

.cf-month{display:flex;flex-direction:column;align-
items:center;gap:3px;flex:1;min-width:52px}

.cf-bar-track{width:100%;background:#e8f0e8;border-radius:3px 3px 0
0;position:relative}

.cf-bar-fill{width:100%;border-radius:3px 3px 0 0;transition:height .3s}

.cf-lbl{font-size:8px;font-weight:700;color:#555;text-align:center}

.cf-amt{font-size:7px;color:#0a3d1f;font-weight:700;white-
space:nowrap;text-align:center}

.bca-row{margin-bottom:8px;padding-bottom:8px;border-bottom:1px solid
#e8f0e8}

.bca-name{font-size:9px;font-weight:700;color:#0a3d1f;margin-
bottom:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.bca-bars{display:flex;flex-direction:column;gap:3px}

.bca-bar-row{display:flex;align-items:center;gap:5px}

.bca-bar-label{font-size:7px;width:32px;flex-shrink:0;font-weight:700}

.bca-bar-track{flex:1;height:9px;background:#e8f0e8;border-
radius:2px;overflow:hidden;position:relative}

.bca-bar-fill{height:100%;border-radius:2px;position:absolute;left:0;top:0}

.bca-pct{font-size:7px;width:30px;text-align:right;flex-shrink:0;font-
weight:700}

.toggle-sw{width:38px;height:20px;background:#bdc3c7;border-
radius:10px;position:relative;cursor:pointer;transition:.2s;flex-shrink:0}

.[Link]{background:#27ae60}

.toggle-thumb{width:16px;height:16px;background:#fff;border-
radius:50%;position:absolute;top:2px;left:2px;transition:.2s}

.[Link] .toggle-thumb{left:20px}

/* DONUT SVG */
.donut-pct{font-size:14px;font-weight:800;fill:#0a3d1f}

.donut-sub{font-size:8px;fill:#888}

::-webkit-scrollbar{width:5px;height:5px}

::-webkit-scrollbar-thumb{background:#27ae60;border-radius:3px}

::-webkit-scrollbar-track{background:#e8f0e8}

input[type=range]{accent-color:#27ae60;width:100%}

</style>

<script>

/* ── Login stubs — defined early so onclick works before main script parses
── */

window._loginQueue = [];

function selectRole(r){

if(window._selectRoleReady) window._selectRoleImpl(r);

else window._loginQueue.push(['selectRole',r]);

function doLogin(){

if(window._selectRoleReady) window._doLoginImpl();

else window._loginQueue.push(['doLogin']);

function togglePwVisibility(){

if(window._selectRoleReady) window._togglePwImpl();

else window._loginQueue.push(['togglePwVisibility']);

</script>
<style>

/* ── Enhanced Schedule Styles ── */

.sched-kpi-strip{display:flex;gap:8px;margin-bottom:8px;flex-wrap:wrap}

.sched-kpi{background:#fff;border:1px solid #c8d8c8;border-


radius:5px;padding:10px 14px;flex:1;min-width:120px;border-left:4px solid
#27ae60;display:flex;flex-direction:column;align-items:flex-start}

.[Link]{border-left-color:#e74c3c}.[Link]{border-left-
color:#f39c12}.[Link]{border-left-color:#2980b9}.sched-
[Link]{border-left-color:#8e44ad}

.sched-kpi-val{font-size:22px;font-weight:800;color:#0a3d1f;line-height:1}

.[Link] .sched-kpi-val{color:#c0392b}.[Link] .sched-kpi-


val{color:#d35400}.[Link] .sched-kpi-val{color:#1a5276}.sched-
[Link] .sched-kpi-val{color:#6c3483}

.sched-kpi-lbl{font-size:9px;color:#666;font-weight:600;margin-
top:2px;letter-spacing:.3px}

/* Gantt 2026 */

.g26-wrap{overflow-x:auto}

.g26-hdr{display:flex;margin-left:186px;border-bottom:2px solid
#0a3d1f;margin-bottom:0}

.g26-mon{flex:1;font-size:8px;font-
weight:800;color:#fff;background:#0a3d1f;text-align:center;padding:4px
0;border-right:1px solid #1a6b3a}

.g26-row{display:flex;align-items:center;margin-
bottom:3px;position:relative}

.g26-row:hover{background:#f0f8f0;border-radius:3px}

.g26-lbl{width:186px;font-size:9px;color:#1a2a1a;font-weight:700;flex-
shrink:0;padding:3px 5px;overflow:hidden;text-overflow:ellipsis;white-
space:nowrap;border-right:2px solid #c8d8c8}

.g26-track{flex:1;height:22px;background:#f0f4f0;border-
radius:2px;position:relative;overflow:visible}
.g26-grid-
line{position:absolute;top:0;bottom:0;width:1px;background:#e0e8e0;pointe
r-events:none}

.g26-bar{height:100%;border-radius:3px;position:absolute;display:flex;align-
items:center;padding:0 6px;font-size:9px;color:#fff;font-weight:700;white-
space:nowrap;overflow:hidden;cursor:pointer;transition:opacity .15s;box-
shadow:0 1px 3px rgba(0,0,0,.2)}

.g26-bar:hover{opacity:.85}

.g26-baseline{height:5px;border-radius:2px;position:absolute;bottom:-
8px;opacity:.45}

.g26-milestone-
dot{position:absolute;top:50%;width:14px;height:14px;background:#e74c3c
;border:2px solid #fff;border-radius:50%;transform:translate(-50%,-50%);z-
index:2;box-shadow:0 0 0 2px rgba(231,76,60,.35);cursor:pointer}

.g26-pct-badge{position:absolute;right:-34px;font-size:9px;font-
weight:800;color:#0a3d1f;white-space:nowrap}

.g26-today-
line{position:absolute;top:0;bottom:0;width:2px;background:#e74c3c;z-
index:3;pointer-events:none}

.g26-today-line::after{content:"TODAY";position:absolute;top:-
2px;left:3px;font-size:7px;font-weight:800;color:#e74c3c;white-
space:nowrap}

.g26-tooltip{position:fixed;background:#1a2a1a;color:#fff;padding:8px
12px;border-radius:5px;font-size:10px;z-index:9999;pointer-
events:none;display:none;max-width:220px;box-shadow:0 4px 16px
rgba(0,0,0,.4);border-left:3px solid #27ae60}

.g26-cp-
badge{position:absolute;top:0;bottom:0;left:0;right:0;background:repeating-
linear-gradient(45deg,transparent,transparent 3px,rgba(231,76,60,.12)
3px,rgba(231,76,60,.12) 6px);pointer-events:none;border-radius:3px}

.g26-legend{display:flex;gap:14px;flex-wrap:wrap;margin:8px 0 4px 186px}

.g26-leg-item{display:flex;align-items:center;gap:4px;font-
size:9px;color:#555}

.g26-leg-dot{width:12px;height:12px;border-radius:2px}
/* S-Curve */

.scurve-wrap{position:relative;overflow:hidden}

.scurve-svg{width:100%;height:200px;display:block}

.scurve-legend{display:flex;gap:16px;justify-content:center;margin-top:6px}

.scurve-leg{display:flex;align-items:center;gap:5px;font-
size:9px;color:#555;font-weight:600}

.scurve-leg-line{width:28px;height:3px;border-radius:2px}

.scurve-variance-badge{display:inline-block;padding:2px 8px;border-
radius:10px;font-size:9px;font-weight:700;margin-left:4px}

/* Phase dashboard */

.phase-grid{display:grid;grid-template-
columns:repeat(4,1fr);gap:6px;margin-bottom:4px}

.phase-card{background:#f8fdf8;border:1px solid #c8d8c8;border-


radius:5px;padding:8px 10px;position:relative;overflow:hidden}

.[Link]{border-color:#27ae60;border-left:4px solid #27ae60}

.[Link]{border-color:#e74c3c;border-left:4px solid #e74c3c}

.[Link]{border-color:#2980b9;border-left:4px solid
#2980b9}

.[Link]{border-color:#bdc3c7;border-left:4px solid #bdc3c7}

.phase-card-title{font-size:9px;font-weight:800;color:#0a3d1f;letter-
spacing:.3px;margin-bottom:3px}

.phase-card-pct{font-size:20px;font-weight:800;line-height:1;margin-
bottom:2px}

.phase-bar-bg{height:5px;background:#e8f0e8;border-
radius:3px;overflow:hidden;margin-top:4px}

.phase-bar-fill{height:100%;border-radius:3px}

.phase-card-status{font-size:8px;font-weight:700;margin-top:4px}
/* Delay analytics */

.delay-card{background:#fff8f6;border:1px solid #fadbd8;border-


radius:5px;padding:8px 10px;margin-bottom:6px;display:flex;align-
items:center;gap:8px;border-left:4px solid #e74c3c}

.[Link]{background:#fffbf0;border-color:#fdebd0;border-left-
color:#f39c12}

.[Link]{background:#fdf3f3;border-color:#fadbd8;border-left-
color:#e74c3c}

.delay-heat{width:10px;height:10px;border-radius:50%;flex-shrink:0}

.[Link]{background:#e74c3c}

.[Link]{background:#f39c12}

.[Link]{background:#27ae60}

.float-bar{height:8px;background:#e8f0e8;border-
radius:4px;overflow:hidden;flex:1}

.float-fill{height:100%;border-radius:4px}

/* Milestone tracker */

.ms-row{display:flex;align-items:center;gap:7px;padding:6px 0;border-
bottom:1px solid #e8f0e8}

.ms-icon{width:26px;height:26px;border-radius:50%;display:flex;align-
items:center;justify-content:center;font-size:11px;flex-shrink:0}

.[Link]{background:#d4efdf;color:#1e8449}

.[Link]-progress{background:#d6eaf8;color:#1a5276}

.[Link]{background:#eaecee;color:#555}

.[Link]{background:#fadbd8;color:#c0392b}

.ms-content{flex:1;min-width:0}

.ms-name{font-size:10px;font-weight:700;color:#0a3d1f;white-
space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ms-meta{font-size:9px;color:#888;margin-top:1px}

.ms-status-badge{font-size:8px;font-weight:800;padding:2px 7px;border-
radius:10px;white-space:nowrap}

.[Link]{background:#d4efdf;color:#1e8449}

.[Link]-progress{background:#d6eaf8;color:#1a5276}

.[Link]{background:#eaecee;color:#555}

.[Link]{background:#fadbd8;color:#c0392b}

</style>

<style>

/* ── Schedule v7 Additions ── */

.sched-proj-bar{background:linear-
gradient(90deg,#0a3d1f,#1a6b3a);padding:8px 10px;display:flex;align-
items:center;gap:10px;flex-wrap:wrap;border-bottom:2px solid #27ae60}

.sched-proj-label{color:#a8d5b5;font-size:10px;font-weight:700;letter-
spacing:.4px;white-space:nowrap}

.sched-proj-sel{background:#0a3d1f;color:#fff;border:1.5px solid
#27ae60;border-radius:4px;padding:4px 28px 4px 10px;font-size:11px;font-
weight:700;font-family:inherit;cursor:pointer;outline:none;appearance:none;-
webkit-appearance:none;background-image:url('data:image/svg+xml,<svg
xmlns=%22[Link] width=%2210%22 height=
%226%22 viewBox=%220 0 10 6%22><path d=%22M0 0l5 6 5-6z%22 fill=
%22%2327ae60%22/></svg>');background-repeat:no-repeat;background-
position:right 8px center;min-width:200px}

.sched-view-sel{background:#1a6b3a;color:#fff;border:1px solid
rgba(255,255,255,.3);border-radius:4px;padding:4px 28px 4px 10px;font-
size:10px;font-weight:700;font-
family:inherit;cursor:pointer;outline:none;appearance:none;-webkit-
appearance:none;background-image:url('data:image/svg+xml,<svg xmlns=
%22[Link] width=%2210%22 height=%226%22
viewBox=%220 0 10 6%22><path d=%22M0 0l5 6 5-6z%22 fill=%22%23fff
%22/></svg>');background-repeat:no-repeat;background-position:right 8px
center}
.sched-proj-info{margin-left:auto;display:flex;align-items:center;gap:8px;flex-
wrap:wrap}

.sched-proj-tag{background:rgba(39,174,96,.25);border:1px solid
#27ae60;color:#a8d5b5;border-radius:3px;padding:2px 8px;font-
size:9px;font-weight:700;letter-spacing:.3px}

/* Activity table */

.act-tbl{width:100%;border-collapse:collapse;font-size:9px}

.act-tbl th{background:#0a3d1f;color:#fff;padding:5px 6px;font-


size:8px;font-weight:700;text-align:left;white-
space:nowrap;position:sticky;top:0;z-index:1}

.act-tbl td{padding:4px 6px;border-bottom:1px solid #dde8d0;vertical-


align:middle}

.act-tbl tr:nth-child(even) td{background:#f4f9f2}

.act-tbl tr:hover td{background:#e4f0e0}

.act-tbl td:first-child{font-weight:600;color:#0a3d1f}

.act-status{display:inline-block;padding:2px 6px;border-radius:8px;font-
size:8px;font-weight:700;white-space:nowrap}

.[Link]{background:#d4efdf;color:#1e8449}

.[Link]-progress{background:#d6eaf8;color:#1a5276}

.[Link]{background:#eaecee;color:#555}

.[Link]{background:#fdebd0;color:#d35400}

.[Link]{background:#fadbd8;color:#c0392b}

/* Financial S-Curve */

.fin-scurve-svg{width:100%;height:160px;display:block}

/* Milestone Groups */

.ms-group-hdr{font-size:9px;font-weight:800;letter-spacing:.5px;padding:5px
8px;border-radius:3px;margin-bottom:5px;margin-top:8px;display:flex;align-
items:center;gap:6px}

.[Link]{background:#d4efdf;color:#1e8449}

.[Link]{background:#d6eaf8;color:#1a5276}
.[Link]{background:#eaecee;color:#555}

.ms-activity-chip{display:inline-block;background:#e8f4fd;border:1px solid
#b0d0ea;border-radius:10px;padding:1px 7px;font-
size:8px;color:#1a5276;margin:1px 2px;font-weight:600}

/* Delay v7 table */

.delay-tbl{width:100%;border-collapse:collapse;font-size:9px}

.delay-tbl th{background:#7b241c;color:#fff;padding:4px 6px;font-


size:8px;font-weight:700;text-align:left;white-space:nowrap}

.delay-tbl td{padding:4px 6px;border-bottom:1px solid #fadbd8;vertical-


align:middle}

.delay-tbl tr:nth-child(even) td{background:#fff8f6}

.delay-tbl tr:hover td{background:#fdebd0}

/* Upload zone */

.upload-zone{border:2px dashed #c8d8c8;border-


radius:6px;padding:14px;text-
align:center;cursor:pointer;transition:all .2s;background:#f8fdf8;margin-
bottom:8px}

.upload-zone:hover{border-color:#27ae60;background:#edfaf0}

.upload-zone-icon{font-size:22px;margin-bottom:4px}

.upload-zone-txt{font-size:9px;color:#555;font-weight:600}

.upload-zone-sub{font-size:8px;color:#888;margin-top:2px}

</style>

<style>

/* ── Cost Module v11 styles ── */

.cost-selector-bar{background:linear-gradient(135deg,#0a3d1f 0%,#1a6b3a
60%,#0a3d1f 100%);padding:10px 14px;display:flex;align-
items:center;gap:12px;flex-wrap:wrap;border-bottom:3px solid
#27ae60;box-shadow:0 2px 8px rgba(0,0,0,.18)}
.cost-sel-label{color:#a8d5b5;font-size:10px;font-weight:800;letter-
spacing:.5px;white-space:nowrap}

.cost-proj-sel{background:#0a3d1f;color:#fff;border:2px solid
#27ae60;border-radius:5px;padding:6px 32px 6px 12px;font-size:12px;font-
weight:800;font-family:inherit;cursor:pointer;outline:none;appearance:none;-
webkit-appearance:none;background-image:url('data:image/svg+xml,<svg
xmlns=%22[Link] width=%2210%22 height=
%226%22 viewBox=%220 0 10 6%22><path d=%22M0 0l5 6 5-6z%22 fill=
%22%2327ae60%22/></svg>');background-repeat:no-repeat;background-
position:right 10px center;min-width:260px;transition:border-color .15s}

.cost-proj-sel:hover{border-color:#fff}

.cost-upload-btn{background:rgba(255,255,255,.15);color:#fff;border:1px
solid rgba(255,255,255,.4);border-radius:4px;padding:5px 12px;font-
size:9px;font-weight:700;font-
family:inherit;cursor:pointer;transition:background .15s;white-space:nowrap}

.cost-upload-btn:hover{background:rgba(255,255,255,.25)}

.cost-sel-info{margin-left:auto;display:flex;align-items:center;gap:8px;flex-
wrap:wrap}

.cost-sel-tag{background:rgba(39,174,96,.25);border:1px solid
#27ae60;color:#a8d5b5;border-radius:3px;padding:2px 9px;font-
size:9px;font-weight:700;letter-spacing:.3px;white-space:nowrap}

/* Project Cost Summary Panel */

.pcs-panel{background:#fff;border:2px solid #27ae60;border-


radius:6px;margin-bottom:0;overflow:hidden;box-shadow:0 2px 8px
rgba(0,0,0,.1)}

.pcs-header{background:linear-
gradient(90deg,#0a3d1f,#1a6b3a);padding:8px 12px;display:flex;align-
items:center;justify-content:space-between;flex-wrap:wrap;gap:6px}

.pcs-title{font-size:11px;font-weight:800;color:#fff;letter-spacing:.5px}

.pcs-status-badge{padding:3px 12px;border-radius:12px;font-size:9px;font-
weight:800;letter-spacing:.3px}

.[Link]{background:#27ae60;color:#fff}

.[Link]{background:#f39c12;color:#fff}
.[Link]{background:#e74c3c;color:#fff}

.[Link]{background:#2980b9;color:#fff}

.pcs-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:0;border-
top:1px solid #c8d8c8}

@media(max-width:900px){.pcs-grid{grid-template-columns:repeat(3,1fr)}}

.pcs-cell{padding:10px 12px;border-right:1px solid #e8f0e8;border-


bottom:1px solid #e8f0e8;text-align:center;position:relative}

.pcs-cell:last-child{border-right:none}

.pcs-cell-val{font-size:17px;font-weight:800;color:#0a3d1f;line-
height:1.1;margin-bottom:2px}

.pcs-cell-lbl{font-size:8px;color:#777;font-weight:700;letter-
spacing:.4px;text-transform:uppercase}

.pcs-cell-sub{font-size:8px;font-weight:700;margin-top:2px}

.[Link] .pcs-cell-val{color:#0a3d1f}

.[Link] .pcs-cell-val{color:#2980b9}

.[Link] .pcs-cell-val{color:#27ae60}

.[Link] .pcs-cell-val{color:#1abc9c}

.[Link] .pcs-cell-val{font-size:22px}

.[Link] .pcs-cell-val{font-size:22px}

.[Link] .pcs-cell-val{color:#d35400}

.[Link] .pcs-cell-val{font-size:16px}

.[Link] .pcs-cell-val{font-size:20px}

.pcs-util-bar{height:5px;background:#e8f0e8;border-
radius:3px;overflow:hidden;margin-top:5px}

.pcs-util-bar-f{height:100%;border-radius:3px;transition:width .4s}

/* Cost section headers — compact row */

.cost-section-hdr{display:flex;align-items:center;justify-content:space-
between;background:linear-
gradient(90deg,#0a3d1f,#1a6b3a);color:#fff;padding:6px 10px;font-
size:10px;font-weight:800;letter-spacing:.5px;border-radius:5px 5px 0 0}

</style>

<style>

/*
══════════════════════════════════════════════════════
PMO REPORT MODULE v2 — Enterprise Grade

══════════════════════════════════════════════════════
*/

/* Page wrapper */

#page-reports { background:#eef3f8; }

/* ── Top banner ── */

.rpt-banner {

background: linear-gradient(135deg, #0a3d1f 0%, #1a6b3a 55%, #0e5230


100%);

padding: 16px 20px 14px;

display: flex; align-items: center; justify-content: space-between; flex-wrap:


wrap; gap: 10px;

border-bottom: 4px solid #27ae60;

box-shadow: 0 3px 12px rgba(0,0,0,.25);

.rpt-banner-left { display:flex; align-items:center; gap:14px; }

.rpt-banner-icon { width:44px; height:44px;


background:rgba(255,255,255,.15); border-radius:50%; display:flex; align-
items:center; justify-content:center; font-size:22px; border:2px solid
rgba(39,174,96,.5); }
.rpt-banner-title { font-size:17px; font-weight:800; color:#fff; letter-
spacing:.4px; line-height:1.2; }

.rpt-banner-sub { font-size:10px; color:#a8d5b5; margin-top:2px; letter-


spacing:.2px; }

.rpt-banner-right { display:flex; gap:8px; flex-wrap:wrap; }

.rpt-action-btn {

display:inline-flex; align-items:center; gap:5px;

padding:7px 14px; border:none; border-radius:5px; font-size:10px; font-


weight:700;

cursor:pointer; font-family:inherit; letter-spacing:.2px; transition:all .15s;

.[Link] { background:#27ae60; color:#fff; }

.[Link]:hover { background:#1e8449; }

.[Link] { background:rgba(255,255,255,.15); color:#fff;


border:1px solid rgba(255,255,255,.3); }

.[Link]:hover { background:rgba(255,255,255,.25); }

.[Link] { background:#c0392b; color:#fff; }

.[Link]:hover { background:#922b21; }

.[Link] { background:#1a5276; color:#fff; }

.[Link]:hover { background:#0d3349; }

.[Link] { background:#d35400; color:#fff; }

.[Link]:hover { background:#a04000; }

.[Link] { background:#6c3483; color:#fff; }

.[Link]:hover { background:#4a235a; }

/* ── Executive KPI strip ── */

.rpt-kpi-strip { display:flex; gap:10px; padding:14px 12px 4px; flex-


wrap:wrap; }
.rpt-kpi-card {

flex:1; min-width:130px;

background:#fff; border-radius:8px; padding:12px 14px;

border-top:4px solid #27ae60;

box-shadow:0 2px 8px rgba(0,0,0,.08);

display:flex; align-items:flex-start; gap:10px;

transition: box-shadow .2s;

.rpt-kpi-card:hover { box-shadow: 0 4px 16px rgba(0,0,0,.14); }

.[Link] { border-top-color:#e74c3c; }

.[Link]{ border-top-color:#f39c12; }

.[Link] { border-top-color:#2980b9; }

.[Link]{ border-top-color:#8e44ad; }

.[Link] { border-top-color:#16a085; }

.rpt-kpi-icon { font-size:22px; line-height:1; flex-shrink:0; margin-top:2px; }

.rpt-kpi-body { flex:1; min-width:0; }

.rpt-kpi-val { font-size:20px; font-weight:800; color:#0a3d1f; line-height:1; }

.[Link] .rpt-kpi-val { color:#c0392b; }

.[Link] .rpt-kpi-val{ color:#d35400; }

.[Link] .rpt-kpi-val { color:#1a5276; }

.[Link] .rpt-kpi-val{ color:#6c3483; }

.[Link] .rpt-kpi-val { color:#16a085; }

.rpt-kpi-lbl { font-size:9px; color:#777; font-weight:700; margin-top:3px;


letter-spacing:.3px; text-transform:uppercase; }

.rpt-kpi-sub { font-size:8px; color:#aaa; margin-top:2px; }

/* ── Executive summary panel ── */


.rpt-exec-summary {

margin:0 12px 8px;

background:linear-gradient(135deg,#edfaf3,#f8fff8);

border:1px solid #a8d5b5; border-left:5px solid #27ae60;

border-radius:8px; padding:12px 16px;

box-shadow:0 2px 6px rgba(39,174,96,.1);

.rpt-exec-summary-hdr { font-size:10px; font-weight:800; color:#0a3d1f;


letter-spacing:.5px; text-transform:uppercase; margin-bottom:6px;
display:flex; align-items:center; gap:6px; }

.rpt-exec-summary-text { font-size:11px; color:#1a3a1a; line-height:1.7; }

.rpt-exec-summary-text strong { color:#0a3d1f; }

/* ── Main body layout ── */

.rpt-body { display:flex; gap:10px; padding:0 12px 12px; flex-wrap:wrap; }

.rpt-sidebar { width:220px; flex-shrink:0; display:flex; flex-direction:column;


gap:8px; }

.rpt-main { flex:1; min-width:0; display:flex; flex-direction:column;


gap:10px; }

/* ── Sidebar cards ── */

.rpt-sidebar-card { background:#fff; border-radius:8px; box-shadow:0 2px


8px rgba(0,0,0,.07); overflow:hidden; }

.rpt-sidebar-hdr { padding:8px 12px; font-size:9px; font-weight:800; letter-


spacing:.6px; color:#fff; text-transform:uppercase; }

.[Link] { background:linear-
gradient(90deg,#0a3d1f,#1a6b3a); }

.[Link] { background:linear-
gradient(90deg,#1a252f,#2c3e50); }
.[Link] { background:linear-
gradient(90deg,#0e6655,#17a589); }

.rpt-sidebar-body { padding:10px; }

/* Report type buttons */

.rpt-type-btn {

display:flex; align-items:center; gap:8px; width:100%;

padding:9px 10px; margin-bottom:4px;

border:none; border-radius:6px; cursor:pointer; font-family:inherit;

font-size:10px; font-weight:700; text-align:left; transition:all .15s;

border-left:3px solid transparent;

.rpt-type-btn:last-child { margin-bottom:0; }

.rpt-type-btn .rbt-icon { font-size:14px; flex-shrink:0; }

.rpt-type-btn .rbt-text { flex:1; }

.rpt-type-btn .rbt-badge { font-size:8px; background:rgba(255,255,255,.25);


padding:1px 5px; border-radius:8px; }

.rbt-status { background:#edfaf3; color:#0a3d1f; border-left-color:#27ae60;


}

.rbt-status:hover,.[Link] { background:#0a3d1f; color:#fff; }

.rbt-cost { background:#eaf4ec; color:#1e8449; border-left-color:#1e8449;


}

.rbt-cost:hover,.[Link] { background:#1e8449; color:#fff; }

.rbt-risk { background:#fdf3f3; color:#c0392b; border-left-color:#e74c3c; }

.rbt-risk:hover,.[Link] { background:#c0392b; color:#fff; }

.rbt-resource{ background:#eaf2f8; color:#1a5276; border-left-


color:#2980b9; }

.rbt-resource:hover,.[Link]{ background:#1a5276; color:#fff; }


.rbt-schedule{ background:#e8f8f5; color:#0e6655; border-left-
color:#16a085; }

.rbt-schedule:hover,.[Link]{ background:#0e6655; color:#fff; }

.rbt-exec { background:#f4ecf7; color:#6c3483; border-left-color:#8e44ad;


}

.rbt-exec:hover,.[Link] { background:#6c3483; color:#fff; }

.rbt-kpi { background:#fef5e7; color:#784212; border-left-


color:#d35400; }

.rbt-kpi:hover,.[Link] { background:#784212; color:#fff; }

/* Distribute panel */

.rpt-dist-label { display:flex; align-items:center; gap:6px; font-size:10px;


color:#333; padding:4px 0; cursor:pointer; }

.rpt-dist-label input { accent-color:#27ae60; }

/* Advanced filters */

.rpt-filter-row { display:flex; flex-wrap:wrap; gap:6px; padding:8px 12px;


background:#fff; border-radius:8px; margin:0 12px 0; box-shadow:0 1px 5px
rgba(0,0,0,.06); align-items:center; }

.rpt-filter-lbl { font-size:9px; font-weight:800; color:#0a3d1f; letter-


spacing:.4px; text-transform:uppercase; white-space:nowrap; }

.rpt-filter-sel, .rpt-filter-inp {

background:#f8fdf8; border:1px solid #c8d8c8; border-radius:5px;

padding:5px 8px; font-size:10px; font-family:inherit; color:#1a2a1a;

outline:none; cursor:pointer; transition:border .15s;

.rpt-filter-sel:focus, .rpt-filter-inp:focus { border-color:#27ae60; box-shadow:0


0 0 2px rgba(39,174,96,.12); }

.rpt-filter-inp { width:90px; }
.rpt-filter-clear { font-size:9px; font-weight:700; color:#c0392b;
cursor:pointer; background:none; border:none; font-family:inherit;
padding:3px 6px; border-radius:4px; }

.rpt-filter-clear:hover { background:#fdf3f3; }

/* ── Charts area ── */

.rpt-charts-row { display:flex; gap:10px; flex-wrap:wrap; }

.rpt-chart-card { background:#fff; border-radius:8px; box-shadow:0 2px 8px


rgba(0,0,0,.07); overflow:hidden; flex:1; min-width:200px; }

.rpt-chart-hdr { padding:8px 12px; display:flex; align-items:center; justify-


content:space-between; border-bottom:1px solid #eef3f8; }

.rpt-chart-title{ font-size:10px; font-weight:800; color:#0a3d1f; letter-


spacing:.3px; }

.rpt-chart-sub { font-size:8px; color:#999; margin-top:1px; }

.rpt-chart-body { padding:10px 12px; }

/* Budget vs Actual bar chart */

.rpt-bar-row { display:flex; align-items:center; gap:6px; margin-bottom:7px; }

.rpt-bar-lbl { width:140px; font-size:9px; color:#333; font-weight:600; flex-


shrink:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; text-
align:right; }

.rpt-bar-track{ flex:1; height:12px; background:#f0f4f0; border-radius:3px;


overflow:hidden; position:relative; }

.rpt-bar-fill { height:100%; border-radius:3px; transition: width .6s ease; }

.rpt-bar-pct { width:36px; font-size:9px; font-weight:700; color:#333; text-


align:right; flex-shrink:0; }

/* Donut chart */

.rpt-donut-wrap { display:flex; align-items:center; gap:16px; }

.rpt-donut-legend { display:flex; flex-direction:column; gap:5px; }


.rpt-donut-leg-item { display:flex; align-items:center; gap:5px; font-size:9px;
color:#555; }

.rpt-donut-dot { width:10px; height:10px; border-radius:50%; flex-shrink:0; }

/* Monthly trend bars */

.rpt-trend-row { display:flex; align-items:flex-end; gap:4px; height:80px;


border-bottom:2px solid #e8f0e8; padding:0 4px; }

.rpt-trend-bar-wrap { flex:1; display:flex; flex-direction:column; align-


items:center; gap:2px; height:100%; justify-content:flex-end; }

.rpt-trend-bar { width:100%; border-radius:2px 2px 0 0; min-height:2px;


transition: height .4s ease; }

.rpt-trend-lbl { font-size:7px; color:#888; margin-top:3px; text-


align:center; }

/* Variance chart */

.rpt-variance-row { display:flex; align-items:center; gap:6px; margin-


bottom:6px; }

.rpt-var-lbl { width:120px; font-size:9px; color:#333; font-weight:600; flex-


shrink:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

.rpt-var-track { flex:1; height:18px; background:#f0f4f0; border-radius:3px;


position:relative; overflow:visible; }

.rpt-var-zero { position:absolute; left:50%; top:0; bottom:0; width:2px;


background:#bbb; z-index:1; }

.rpt-var-fill { height:100%; border-radius:3px; position:absolute; top:0;


transition: width .5s ease; }

.rpt-var-amt { font-size:8px; font-weight:700; flex-shrink:0; width:55px;


text-align:right; }

/* ── Enhanced cost summary table ── */

.rpt-tbl-card { background:#fff; border-radius:8px; box-shadow:0 2px 8px


rgba(0,0,0,.07); overflow:hidden; }
.rpt-tbl-hdr { padding:10px 14px; display:flex; align-items:center; justify-
content:space-between; flex-wrap:wrap; gap:8px; background:linear-
gradient(90deg,#0a3d1f,#1a6b3a); }

.rpt-tbl-title{ font-size:11px; font-weight:800; color:#fff; letter-spacing:.4px;


text-transform:uppercase; }

.rpt-tbl-controls { display:flex; gap:6px; align-items:center; flex-wrap:wrap; }

.rpt-tbl-search { background:rgba(255,255,255,.12); border:1px solid


rgba(255,255,255,.3); border-radius:5px; padding:5px 10px; font-size:10px;
color:#fff; font-family:inherit; outline:none; width:140px; }

.rpt-tbl-search::placeholder { color:rgba(255,255,255,.5); }

.rpt-tbl-search:focus { background:rgba(255,255,255,.2); border-


color:rgba(255,255,255,.6); }

.rpt-tbl-exp-btn { padding:5px 10px; background:rgba(255,255,255,.15);


border:1px solid rgba(255,255,255,.3); border-radius:4px; color:#fff; font-
size:9px; font-weight:700; cursor:pointer; font-family:inherit;
transition:all .15s; }

.rpt-tbl-exp-btn:hover { background:rgba(255,255,255,.3); }

.rpt-cost-tbl { width:100%; border-collapse:collapse; font-size:10px; }

.rpt-cost-tbl th { background:#0a3d1f; color:#fff; padding:7px 10px; font-


size:9px; font-weight:700; text-align:left; white-space:nowrap; cursor:pointer;
user-select:none; position:sticky; top:0; }

.rpt-cost-tbl th:hover { background:#1a6b3a; }

.rpt-cost-tbl th .sort-arrow { margin-left:4px; opacity:.5; font-size:8px; }

.rpt-cost-tbl [Link] .sort-arrow { opacity:1; }

.rpt-cost-tbl td { padding:7px 10px; border-bottom:1px solid #edf3ec;


vertical-align:middle; }

.rpt-cost-tbl tr:nth-child(even) td { background:#f8fdf8; }

.rpt-cost-tbl tr:hover td { background:#edfaf3; }

.rpt-cost-tbl td:first-child { font-weight:600; color:#0a3d1f; max-


width:220px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.rpt-tbl-pager { display:flex; align-items:center; gap:8px; padding:8px 14px;
background:#f8fdf8; border-top:1px solid #dde8d0; font-size:10px;
color:#555; }

.rpt-pg-btn { background:#0a3d1f; color:#fff; border:none; border-


radius:4px; padding:3px 9px; cursor:pointer; font-size:10px; font-
family:inherit; }

.rpt-pg-btn:disabled { background:#ccc; cursor:not-allowed; }

.rpt-pg-info { flex:1; text-align:center; }

.rpt-data-warn { background:#fff8e1; border:1px solid #ffe082; border-


radius:5px; padding:6px 10px; font-size:9px; color:#784212; display:flex;
align-items:center; gap:6px; margin:0 14px 8px; }

/* Status badges (smart) */

.rpt-status-badge { display:inline-flex; align-items:center; gap:4px;


padding:2px 9px; border-radius:12px; font-size:8px; font-weight:800; letter-
spacing:.2px; white-space:nowrap; }

.rsb-healthy { background:#d4efdf; color:#1e8449; }

.rsb-warning { background:#fdebd0; color:#d35400; }

.rsb-critical { background:#fadbd8; color:#c0392b; }

/* ── Preview area ── */

.rpt-preview-card { background:#fff; border-radius:8px; box-shadow:0 2px


8px rgba(0,0,0,.07); overflow:hidden; }

.rpt-preview-hdr { padding:10px 14px; display:flex; align-items:center;


justify-content:space-between; flex-wrap:wrap; gap:8px; background:linear-
gradient(90deg,#1e8449,#27ae60); }

.rpt-preview-title{ font-size:11px; font-weight:800; color:#fff; letter-


spacing:.4px; }

.rpt-preview-body { padding:14px; min-height:180px; }

.rpt-preview-empty{ text-align:center; color:#bbb; padding:50px 20px; font-


size:12px; }
.rpt-preview-empty .rpe-icon { font-size:36px; margin-bottom:10px;
opacity:.4; }

/* ── Report History ── */

.rpt-hist-tbl { width:100%; border-collapse:collapse; font-size:10px; }

.rpt-hist-tbl th { background:#1a252f; color:#fff; padding:7px 10px; font-


size:9px; font-weight:700; text-align:left; white-space:nowrap; }

.rpt-hist-tbl td { padding:6px 10px; border-bottom:1px solid #eee; vertical-


align:middle; }

.rpt-hist-tbl tr:nth-child(even) td { background:#f8f9fa; }

.rpt-hist-tbl tr:hover td { background:#eef3f8; }

.rpt-ver-badge { display:inline-block; background:#e8f0f7; color:#1a5276;


border-radius:3px; padding:1px 6px; font-size:8px; font-weight:700; }

.rpt-action-mini { display:inline-flex; align-items:center; gap:3px;


padding:3px 8px; border:none; border-radius:4px; font-size:8px; font-
weight:700; cursor:pointer; font-family:inherit; transition:all .12s; }

.[Link] { background:#d4efdf; color:#1e8449; }

.[Link]:hover { background:#1e8449; color:#fff; }

.[Link] { background:#d6eaf8; color:#1a5276; }

.[Link]:hover { background:#1a5276; color:#fff; }

.[Link] { background:#fdebd0; color:#d35400; }

.[Link]:hover { background:#d35400; color:#fff; }

.[Link] { background:#fadbd8; color:#c0392b; }

.[Link]:hover { background:#c0392b; color:#fff; }

.[Link] { background:#eaecee; color:#555; }

.[Link]:hover { background:#7f8c8d; color:#fff; }

/* ── Health Index panel ── */

.rpt-phi-grid { display:grid; grid-template-columns:1fr 1fr; gap:6px; }


.rpt-phi-card { background:#f8fdf8; border:1px solid #c8d8c8; border-
radius:6px; padding:8px 10px; text-align:center; }

.rpt-phi-val { font-size:18px; font-weight:800; color:#0a3d1f; }

.rpt-phi-lbl { font-size:8px; color:#777; font-weight:700; margin-top:2px;


letter-spacing:.3px; }

/* Completed + Upcoming sections */

.rpt-sect-card { background:#fff; border-radius:8px; box-shadow:0 2px 8px


rgba(0,0,0,.07); overflow:hidden; margin:0 12px 10px; }

.rpt-sect-hdr { padding:9px 14px; display:flex; align-items:center; justify-


content:space-between; flex-wrap:wrap; gap:6px; }

/* Photo gallery */

#photo-gallery { background:#fff; border-radius:8px; box-shadow:0 2px 8px


rgba(0,0,0,.07); margin:0 12px 10px; padding:12px; }

</style>

</head>

<body>

<!-- LOGIN -->

<!--
═══════════════════════════════════════════════════════
════════
LOGIN OVERLAY — Role-Based Card Authentication (v2)

Roles: Admin (PMO) full access | Guest (Project Managers) read-only

═══════════════════════════════════════════════════════
════════ -->

<div class="login-overlay open" id="login-overlay">

<div class="login-box">
<!-- ═══ BRANDED HEADER PANEL ═══ -->

<div class="login-brand-panel">

<div class="login-brand-inner">

<!-- Logo Emblem -->

<div class="login-emblem">

<img
src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAQDA
wQDAwQEAwQFBAQFBgoHBgYGBg0JCggKDw0QEA8NDw4RExgUERIXEg4PFR
wVFxkZGxsbEBQdHx0aHxgaGxr/
2wBDAQQFBQYFBgwHBwwaEQ8RGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaG
hoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhr/
wgARCAImBQADASIAAhEBAxEB/
8QAHAABAAICAwEAAAAAAAAAAAAAAAcIBQYBAwQC/
8QAGgEBAAIDAQAAAAAAAAAAAAAAAAECAwQFBv/
aAAwDAQACEAMQAAABn8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAB841XKNRwkYZJQ1hWCf/NW/
GRgsXhINMEr4XQkYdn8GHMP38CjjkevKYAtuecjAyzls9Zk7Nrea17lO5MTWdlnd
5C4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAB5MIx7Mj3Bxgl5A2EYLHYiuXXGCdcJEpg3/
AAmtow+ryjCAAPo+WTzC+qJFzDPESdsnOWuyyfevWVZvoK1rE4xSCUua/
GHQ2WxLXBDO4ImZpAqz756Fn0ZSPPV7hOYAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAfJ9MZg4xbejTBME0cV7wcYLI4SvhgmbB
Rsa+3YPGowc8CgA9J5mfy7LpKTstOaG0+5hmrblbI9rNAGZmZOaMcxuxmwO
W9CcwLgAAAAAcYfMlYz0Sw6NOqKyMaxzo4d3TGkzGHJnzcqoyFPVmx5vTbqgk
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcHLw4Jj2tG2CjXm
b5r7gmCx+BgFGvMWCjpGDaMH4zACh6cstgG6ZhljNMWXnNA3Nj8szVqy9heZ
zQhl5YM0f5jaDNjch9JygsAAAAAAAAAAAAAAABjYqmdGvVT4sbC0cbWxGpnJ2r
b6527RtP3C3dBkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPnEq5hp
GvxryugvX2CxmDrx8RrzZgIyNfb8F5cpGHBtwyy0cpcys5YOWFzDNWnJWS+2
WActNCc0WZffDLrOWyCc3z9DIAAAAAAAAAAAAAAODl4cKx7Qj/HRhlFE/
YrKiNMsvurE5Wc/
IWAAAAdfYRE0WWs0uvLgV6vLHI+5ohTlmtaimVbeg5E5gAAAAAAAAAAAAAA
AAAAAAAAAAAAAABwcsXgGLc0X4yMEx+WGOtjk7X8BlWPE4CSMpFIF6LKZFF
aclYpOWC8pMBljPKbwZdcynvTl+foZAAAAAAAAAAAAAAAAB8n0xWDYtxRhgo
15s+a84OMFkMHAJgmLBR0jBtWFx5gBQAABlcUTJG/
V5Tt2t5rrK89Pc3HM7oAAAGAgWzOMjRrI2HXq8NIsdFrVdkBznbv+kTsgAAAAA
AAAAAAAAAAAAAAAAAAAAAMfkCMD49qRi1jJ5Qt1dpNwSAAAAAAAAAAAAA
AAAAAAdeFUzzQcBGvLvEB4Fgsbga+o15jwMdGvs+D8iNcFQB6TzM9mGXSU
mZdlhxPeWnNXDI2U72avmQnNOaE+mcia+4SzvDHVJZfTY1YabLrUaQK7lNFZf
bO7aFp2427YMgAAHlgyfeuNaqqRo5rwGya2Vs9kK0z5bu5oTugAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHRr7Hs6NdcjXm3z13wka1hd
dhk1pE1/W0a/
f0duQYsU2fKsuhpPyc5YdTvlGWunosv7WWt+Un5OWF8vKJm0PLbMZfB7fpOUF
gAAAAAAGrbSUr3qtrI6ryYYd/
RHM+5mhYzWuRNK9vQfQnMAABxF0pIw1S4nOEq8Dp93hMFh9nqzOVu3ugno
gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADyo9XxgMZGHMaz7
vewx7rk5+9hrN6rLfSteMhO5khfIyuZI6yG6mXXMlkU5OvsGQAAAAAAAAAAAA
AAAAADXIHs3jI0ayNh16vDSHHha1XZAs5W7/oE7IAADV9oKVg8FlYErwcL9/
CNSapEqjLE9eVnHNuqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAOtHY1/
XYwyEhvANewOOrj4o17A+aBzDYrYKq5Jls4jiRbdP6DKAAB5oNnvrjWqqkmNq8
BtGrlbQ+2t0+272UE7gAADw+4iveq2ohavE0ARz5HmOqu8T0p2dHfbsgkAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY9GQ8e
o4WNXP6v7fY1o/
12bvbGGviyOSTWXI2S+mWv+VmtOWKu2UDJCmi2lxka9ZN+xWrRzLU9sBTrb
u+gTsgAAIzkxGKqfzPUHV4HmymLMFkM9V6ebdzaBO+AAA+foRPFVrY/
ryoRdvVHI2meKvZ2d6yLFZW3cBYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAADphab+I16pbRusSV4doPZXKfbdnIC
dsAABr2wlay4uzkEV4Wtd/
QjSnrdKqTVbsyCJ6YAAAGpwVaHCRoVsZnDV4eTnyuHrnZtG1Ta7d8FwAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADpxi
mZafioxSLpet45r6LtWCzFeXPwv6QAAAB5/
QRBei2siivHirlxHMmCTqoynPVltxzbrgAAAeGCLC9MatV2/wCgV4HbN8F/
TJaxG0k39ADKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAABjsZshj03wyAjHG3RKBSK5AyhkCc4AAAAAGgQtajWI5teGRx1
eNKktVTsnbsZkT0wAAAPmKpXRhqim+Fa8DqlWKitreYXmW3oPsTnAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAA1+uNmKz14qbYSnJi3wW74AAAADVtpKVf8NloErwcJJEbowWualtt/
SguAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAcdCPQxOOY9naT4YxyIivwqTEhDxsc9q7eFSy3xWDoilnfLWgpYvxwAUnT
wQ0U2LXXManfZjSZEt2QnogAAAAAMZkytXPJIceU8zvc51tslbrhPRAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdfYRgsftq
MWj9G/
lY588nFYu6ZXIiLiXiIb65oKwl1ziRBvVO4gX5nwiAOuwZEISJtZnCdoAAAAAAAcE
RRfs+sU81m7JwRO9umE9IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfB9ujoV9zE+ZXPtY8sV3Fp
HhUkWNtQ0mNAbfHNkbefn6v6YGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAeZHpYXxxj2ZpWOY5GRb4lJf+IW8bH
NvlhfqUmPyxMUk/yxv8xTf/
AC6T8qbj5NZK57y4cpkPN0Ir8+X2FMZ582VwHGw/
ZrbZOTWm0cmrNsJ1Nvu8TmjidfR9z1wnaAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AA6cfjK9Rz7MKzo1bMKzizHtq3N07G0qzo17McVoFmFZxZj31Yn+dnN/
NfMVGC0HuheaJ6DzemN1ty4rQjl2s831Hk9PduK0I5lrPrzem3ZMRC0a0346unE
c+0frqrIM55pef0T0gSA6+zDqfSs6vIsvzWcWm9FVdynNPDEZeekCzFZSrcadj/
VV2VWvK2M9FX2azHsq3NDHIeL76wslmFZ0admFZxZ/
31SlediVhPSMVDEas2Y2unEc+0Ptqpvs55ueX1T0vN4tPheOdZjKVTtIyeoTvY3r
gnXa8iz31C2UnNJqs6Nay6tAsvzWcWYyNVrJzt9qs6NS0nqjuRLdQGbpx+Hr/
HOswrOjWsx6qu/SbWIYmOel2Cc7q7Y3Ydy+qy/
deZatjclbrurt11HsVnV5Fp+dY9Fun71Z1eZafv07cbdZjsjEEY5J5rN9RzbV4rsgK
d2effViY2GRcfqELJsvla22EZev5rT8xp2bycMTPPRYzurGxWT99WJeYZQ8Xt1Od/
LKzq8m1XZHkh26rH+ms8YLE81m3SNWUa9WFr0wvr5sLGvXxadO7Vma97+p
z1WWoRgqq2XWo5j63OdZ3Krz7tf1O/
WjFZXFV4kjTRDEz27iN5IjdkhkV87aWPJDjy3oIdFfP2m8/
fE9vR6LjH3XzvxzO+3T0KspRi6NPdJ5qlP09DcBbrgMNmcNGOtQr5flNm8z0asp
khuNTJ2MrBKc7Uti3c4q5aOrleV5ZViqVY0pLq/Z+sE7KaIXmiMG7Vhs/
WCc7t6psjThzptVoM7cIffwjm2h580d29HoOIc187xzOW5z0KspYieNPbZ+qpOs
7/
hhiZ4YjXWkq3aOdj1i3Yrnruxa7Ty+75TFzpPSqutPwiqzs645XPMsSfPQqxZDL+
Kd2sYrwpqkSO5Et6MJ2dRr/
YCv9eE+vmxMYK8fNp6+zk1qXIj2KMVjBf0qu02VuryT2+KOVL8n1wsdbuc67s
WutquYr5iwPo8/
ot6Cuwr5+fdx03crelYLOpy1RbTq1PLzP4tUmW3VrXuWm91eXuOkejzplXK7NEl
uppRsVeTNOx8c39PG0NbLrVPPM9jfGw2t51zY7+nr/
qNha9V4OyWJqlYhtYOE9j1yNLmxsVzpO/
q1erC16YGya2jR23nUS8477FspW7oTtV31nZtZp5fdp4geeLdgJ6FZsVlsTTyvry
GEGb8fgAK2ljyQ48t6CHRXz9pa52MrRPW8O56ZIsaE0i/
peqsFpK1V5WGkqNd6jQnRo0bW69glfDHYPDattLYrUK+cnDftB363o1d7EQS19
H2bWc5Xj2SF/U8VctHVyvK8sqxVKsaUl1fs/
WCdlNELzRGDd6wWfrBOdsmto52969hS7cNPlJeW66WJrVbo4na9U3+vMm8X9
N8Vks9XCOXgJBj7dK87c4YmeGGVaOrloJ2PcLdiueu7FrtPL7vO8EztbsuOeJ36rdf
Z108nLkpRbKVvQsdkcdOxWIU8tNUiR3IlvRhOzqNf7AV/
rwlgq+owWegPXU3bHrkuxjlE+L+kiWLsnjKeak3Rpp0OduPrF10kpjmTXdi123ar
mKeYsD6PP6LegrsK+fnzctN3K3pQnPHsJ2mrHXidNnquzgRlrm4afGmz+A21E8
Vhm6Cp3kyxDZtX2YLOxFPTi73+Dfa8DKRdYGv07MlzHWCzU73bAU+60zV22L
XuK8B9fO/rSlnS/
ptWr1YWvVeKmSG5bYtl48ienseX0XcGf1Cc9eNY2bWaeX3aeIHni3YCehWfE5b
E08ruEjafNFuvo+nTTG68MivDtLHkhx5b0EOivn7SwDP2hW7sL7DryvEtbzCe32
7+11m2PWY5SVIusetqEOWO1hnhhM5reDffJ656lahXz84b9Dmx27u9VrzOpRo
Nv1Ca2KQ2heqe3t1WZVieOWlqJZvY9wrBZ+sDOmeGJnjBvFYLPVhnOk6MZOa
u5eH2Y6epCfHPFeFOMebNnJ6sH5zBo5dq/
uD9zt39wrJsmqxy0lxrYpOKgmz9ZWTqsLXrYIwWO6tG0q3W1DxlfPyNNGib3b0
Ljniduq3X2ddPJy5KUWylb0LHZHHTsViFPLTVIkdyJb0YTs6jX+wFf68IWCjBX1v2g
sWxWJqtYielsmnbjBk7miCvnt/w2smZ7/
AYbU4LE5W3o66CvnLA+jz+i3oK7Cvn583KJdgt3t6aNwzb1DEqY9Sum26krwO
zj43lOlcb1oSdw08RIE3artVu/
wBdaJqgKNBs2so52/6ALJ3gjd5zTuLeigXS5PjCnm/
qyddLRzu8i3X1avVi4VrxdebEjR11sQ12yUHzrPQy4t2K76zIOv083lZ4h6YbdYJ3
qz4ncsdTzOzTPFcqW7KN5I0RkgxsPNeBYOPJE0m3dg/nYOa8Kwfd199/
TQNpVqo3ryIdbJ4Y5+JbjJc58JJpPdCcoDDZnFsdZWw8083rrYuTXG8bzObSJx5+J
7NbcRuus14PgZHPq61ZXEbLbt+Gr9oq/
Rra9M8cymw7VWG0MAM2utiRztdbENdbxIM5/
rcfpbuwbodq47ry4YbNj452JbfJU59flUnuIqlXgqkm+Oq8LVWW9bDr21bZKM7/
AN9hbsvn6+U1X69l+KeX3uUY9kK3eY7I+Gc9X2xKeakiRNI3e3fCdnUa/
wBiIYrxdesZCs4p9dbrQx9OzCWyfKvJn6ssjarO1rso6hNKM29C3brXhZc0SnnsrK
sNTJO7XVsSObL/
AKHdbu1wbDzXha62Ia62ISru+pbbb0Nc9dm2NI4muz5GM+tvVq+2sgU03Od0
jtSROXTb0MJaJtHTTznishGMr26fnjCV8E2K3dmeV4E/
e7R94t6OIIwmHQI4mHtHXuwk7vInpgAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAf/
EADIQAAAGAQIEBgICAgMAAwAAAAACAwQFBgEQFREUNDUSExYgMDMxYFBw
QEEhIjIkgLD/2gAIAQEAAQUC/
VzrpJhWbj0QrbGJArcgpbXxgewyJwaWfHBzmUNqi6WbAk1IECdokSBK5KYCFsYq
BvJNHX9E5zjAUkWiIUsscmFbi3wFLivkK2aRUCsm8WGTZN/
gtpZ61DW4KlDSeYvP6AOoRMKzLBEK2tgmFLkUK256YKz8isFHKyv+WzmHjEM
LaiqElk1yfuyjlFEKz8ckFLczIFbkcK2mQUCsu+WBjmPn5MFyYJxztYJ1uRUCdPdG
CdNTCdUjyAkBHEG0MRtzQbe0G0Mcg8DHHClVjzhSmkC9TephxGO2vvavV2R4
62JqBNQipP25R82RCtjjkgrcGxQrcV8hWyyKgVkHa4znOfkKQx8pxL5UErMicJU5z
kJ01LATq0eQJwzBIERTTx87mLZuw6p6Jg7gHzT3MZNzHHi7C3kP2fOcYCsg1QCt
ljkgrcUMBW4OTBWxSKoUeOFvkI3WUCcJIKhOqyBwnTVQnTm+AnWY5MJxTJIFT
KTH+S8iGb4PqkskFUjon9kRZlGoQXTcp/
r3HgFX7VEK2WOSCtxQwFbe6MFbDIqhR0ut8WMZyE2DpXKddkVAnUXpgnTAn
UWRQnXo5MJMGqIxjh/
Bu2Ld8SSqiqIMXJDax0qvGKRsohJpfrCrxuiFrHHIha4NyhW4ODBWxSKoVeOF/
hI3WUBISQUCdWkDhOmrZCdNQwE6tHkCcMwSBEU0/
wCNkYZtJFk4VxGZ1buVWisPOpSRf1E6yaQWno9EK25mQLXFXIVs0iqFZB0t7yo
qHCcS+VCdYkThOnushOmlCdTYFCcBHJgjJskOHD+VOXByzFX4DOMlzoQ5kzQd
hw8/
S85xgKyjNAK2mPTC1yC1rfqBaXfLgxjG9hEFVcpwz9UErEicJ091kJ00gTqbEoJXo
4gTYtUhjGMfxCjtBEKWGOSB7cyKM3JMZuYxcyglxb5Cdpj1AjJNHHzzEAlI4cN1G
qun4EFY+P6Ko4SSC1gj0QrcGxQtcHJgrYZFYKuVl84IYwTj3auCQEicEqb8wJTVQ
nTkMBOqx5ASCj0wRk2THDGP4nOcYCsi0QCtmjkgpcUMBW4OTBSxyKoVfOV/
ibyTtqGtvXIGc+ye/LJxSMmk/j1o5bWDsWWoIcpy/wA6tINUAtZ49IKW/
wAQNOTLkZbT7sFq8kqCU5xnBKamCVJiUErsaQEi2SWSpkJ/
GZzwCsi0QCtmjkwrcUsBW3uzBWwSKwUcrLf4bGceMBHWNq9+R6xRfoysQtFq
6ws8pHGRWTcJ/wAyphznJmbpUGgkVQSvxxASOaJjBCl/
kFXjdAK2OOSC1xblCtwdGCthkVQo6XW+XBcmCcc7WCdbkVBipv8AI9IPBmpPs
BStyKYWYOkPfF2JwwDJ+hIJfEugm5SmYJSNNrEzC0WozeJPkf2cxykwtMsUArbW
RAtcjhWzyKgVkXa/
yEbLKBOFfqhOqyBwSmrBOnIYCdXjiBOHYJAiSafwOIxm6DqoIHD2Besva1dqs1Y
eeSki/
EYuDlnK5lt7I6SWjVo6TRkkf2FRZNILT8eiFrg2KFre6MFp6QWB1lFfhTbqq5Thn6oJ
WJEwTp7rITpqYJU2BQnARyYTZN0hjHD/
AAn8C0fiSgXUd7CHMmaDsWHXyTlb8YzjJc6NHirFaImEpRP9bUVTSwtPx6AWuD
coWtzs4Vmn6wMcx8+zCZzAkY8UBK9JHBKk+ME6aoCU1DATqseQEgo9MEZt0
xw4f5f5EtWE3AWROgprBWT5Juvkf4VSOgpoisdupCzxJEv6rnOCheYYtwvbmhAt
cHJgvOSDgeBwuCRjxQEr0icEqkgcEp7rITpgJT2uASrRxASBjkwmwapDBcF/
hpWIRk03zBaPW1g7FlqCmwcvxS8KlKJu2arFbQhzJmg7Dh3+pq+bnCjJ4qD1tJb
JatHFBYCOKCxbIgKgkQcP5F6xRkEZWIWi1dYWePHGRWIun8UhGoySMlGLRq2s
FY+P74rINUAeyRxBi1R+QlOx62SmwfHxLoJuUpqBUjjaxE0rFqNXSTxH4nTRJ4j
MQisYfWCsWWwKbBy/uZjlJhabYIBa3MyBa4r5C1kkVgo8cLe1q/cMjRdpTcD8/
EYuDlnK5lv7IyVWjFmL9GQQ+JRMqpJuumZ+yEnzx+UlSLp/
tyzpFvhxaGCIXuJ8hexSC4UXVWzoVuqcEiHymU61IqBOoOzAtMwM01IOqi6SC7
dVscQlhMyyQ5VC/
FN1vCwMXJDaMH60cvGSiMmj8X5E5Wh+NYiaViztXSTxH9rcczkOIuUcj0fk+cU1
IFqDTAJVI8oLXI0oLDsCArZEnwPWCD9OXhFYw4hZ1SNOisRwn8UzApyJV26jZX
Rq6VZrREylKJ/
HN14r0KJmSPpGSq0YsxfoyCH72omVUk3XTs9IeaVi1GzlN2j8UpEIyiT9gtHLaIrH
bqQk6SRL8cxCJSZHTVVmtoxfrR60XKoyaP75NVrBwYuS5iZdWLWaO0nqPxPWK
L9GWhlotTQhzJmg7Dh78klGIyaUjGLxq2jZyq0Wh5tKTJ+
+TEAlI4ctlWitYeGbyPxqokXTmq8dhnTGeGYKxeb8jpqk8Rl4RWMPokqdFSEnyS
GP3YyhCBSVZJA9mjiA9wa4B7mD3B1kSEmvJGrTUy8n8mcccTdaH41gbF4fkUT
KqSbrp2WpTZLmCsWHH7ssxbOcngY5QGrEcYZqLLIzTm2RmmpgtNL4mLBCPS
+aarpHoVSOippWpvPi+P8AInK2PxrBWP8AoyWhkZQj1kswWBTZIaLd88w+Sbr
xHoVSOifSCsRm2SmwbH9FTDAkgy0qJ+Md8svCoyhHbNVitpW5vKB/
6KkXJWjLSppeCM+aQjkZJGSjFoxbSvSPPsf6CycuAZ2gUGlGRBmdjijNljsA1rYFB7
i3wJSYXlDhBEzhZm3K0bfO+ZJv2zludquKo58qR/
djLJlBpNmQGsEcUGtUdgGuDTANcig9xWBrc9yDWiRMMz8iYHlHpwZ0ucZObPw
Yxk2a7Ccnj/
Bt6GCPhDm8Mp+6GLg+FIhoqD1uPOM1SPyM1FkM09oM01EZpqYzTB6MOPRq
gzTXAzTnQzUHg9JPh6SfD0pID0tIjNXkcD0zIjFbkshCpPFMxsA2jv8ADuRseaIfHil
P6dnnuH0iKq386T/
pywzpUCaVhhyjH+kvFgZVTwOcb4BpNmUb3H4BrBHFGbNHYBrVH4ClvalD+zO
neNIGIzIucY4Y/
oDJsYBnKJBmSZ4GZuPKDWGOIM2iOwDW1hgZuLYGuSYNcsg1xcA1veZBrXIZB
rPImGbDJZBpqQMMyTzIM7cGGVD5HHj8URBLSRm7dNoj+8n80GzIA27BQk7nB
kbCYZYWAwUiZ4wNAzJh6alMg1Zkh6akh6akh6bkhmuyWB6ekh6ekhsEkNgkRs
EiNjkBscgNjkBscgNjkBscgNjkBscgNikcjYJIbBJD0/
JD09JDFcksj03JD01JBCpPVAxq7RrnGMYx/
wDmqqKERJubMbmzG5sxubMbmzG5swqumiTc2Y3NmNzZjc2Q3NmNzZjcmYS
VIsQ0i0Kbc2YReN3BtFnCTfG5sxubIYzxws5Sb43NmNzZDGeONVn7ZuMTkfnKT
lFx8JjYIXc2Y3NmNzZjc2YTWTW9+ZJnjO5swi6RcjOcFxubMbmzCLhJxjOcFxubIb
mzG5sxubMbmzCT1utn2rPWzcb5H8UXSDj2LLpN8bmzG5MxjPHGh37VI25swk
9brnWdoN87mzG5sxubIbmyG5sxubMbmzHjLgm5sxubMIuEnGNVFCIk3NmNz
Zjc2Y3NmEnSC/
uOoVIm5swWRaGNqc5UibmzG5MwkqRYiihUibmzG5swksRcmij5skfc2YxItDZG
5sxubMJKkXIooREm5sxubIYzxwaRaFNubMEkGqh9DyDVM25swkqRYgWdItxub
MbmzBDlULoo9bIm3NmNyZixdn9uPzaOze+s9nk+4Cn9bpcei0b/
AEXLpdEPoEhIoxyMhYXb3PHjoQ5kzRdpVQyisRwn7pXtvsKcxMsLM7aZYSKEil7
HPUCmfl50mlP6J90ftxnOM12eOc+j5+hHoyNjdPM5znOQU5iZjLQu3ygum5SFw
6HRv0+k93cVTu1y6r3r9p0p/
b9bL2f2FNkmYizqImKbBy62535bUFNkhmLnDxppO9p0rfZ5/
s+lY7Ppb2fhVGM+HLBxh2zmmnJyQp7nxNrc58tkIlpzsg8Xw0aGNk5hUWXmO
Q7cYatlFMqqCoO/
EkJ+P59jpU3vnMwqoVFN65M8dCtx3OvbF2fTw5HhyPDkeHPGz9n8OR4c+zw5
HhyKz2eS7gKd1ulx6PRv9Fy6XRD6XjsjJu/
fKyDjThrX5jLBf3SvbdMYzkcOGrB8rHuGboj1vq56gUz8vOk0p/
Qvuj0Kkc45dYGLkmQQ+UztFuYbOXBGiEjIKSTnThrBS5o1xjODYuPRaNun0nu7i
qd2uOOLrwmHhNrjGcjw5HhyF+0aU/
t+tl7Pp4cjhnGtTkcnLrPPOcktKg88SWk52nSt9nn+z6Vjs+kuz56P/
GlQdeY0uDTiUVhx5EpanPnSYpzT/
m3OvLZaQjPko4W535bbSGd8lI6WKP5F+IN7yMiLW98hmMY8WYZhiOY2Ls+kA
UuYjwFHgKPAUZxjI8BR4Cif7uKtjjLeAo8BRjHASfcBTut0uPR6N/
ouXS6IfRbnviWBS5OaIr6DJMyCZy2CvkRJpW3vOR3tle26VIuMxpkUz4ma0mon
pT3n/fVz1Ipn5edJpT+ie9HpT+3C2IJmjtI5PKTC3vf+RjGTZh68i0TyinnE/
XiFS0q77mmFx6LRt0+k93cVTu2S4yPAUZIXgp9gp2MZT8so8BQ/
6HSn9v1svZ9IMpdpMimfE8yKxkRBK5SltJd5yMeGrVR4qIZ3yUjpOdp0rfZ5/
s+lY7PrYGfJyQrTrlpSVa87HhFUyCq6xnCwh2nJx1odcxJiDZ87I6TzznJIOWyjUwg3
nOxono/
cGGkE952NnHvPSIrEfzTwWLs+jedfNUfU0kPUskK1IuJAmtg7wKr3bWT7iEHKzU
28PxvD8OHzh1jRv9Fy6XRv9Est58kKu3wvKaHJhQjlLyHApy3B17ZbtulR7ZpPts
NZUV9TKcvq66kUz8vOk0p/
Qvej0j5tzGo+rH4fSrqR0gYk79yJ1XK0sK43w4ldM4wbD5HlngqK3gkLj0Wjbp9J7
u4qndtP9Kf+xTfr0f8ARaU/
t+tl7PpCuUSRRnrYhZt8WQkBApebLaXB3xOKe28Ssk35V8IN5zsaJztOlb7PP9n0
rHZ9bYz85kEz5TO1Xw5bTjXlJPSFa85JLq4QRWVysqKiz8tsJh3yUeGSHNO7g18O
RUHfgX0scfyT4R0qePRBS5OaJY4j2IsXZ/
bTfq1sHeBVO7ayfcfe3+i5dLo3+h7jg8FPz/8AO1ljYPJip4zullfrsG/
qSSHqSSHqSSFZkXMgJbtulR7Zpa88ZUQ2OMrq56kUz8vOk0p/
RPej90PZsEGM8cSZfDIiomxiR1mzeKVFW7vcei0aZ8TXSd7uKp3XT/Sn2Cm/
Xo/6LSn9v1svZ/dU43KZQY2C4kHWXjwVpty8XbW/lvxUHngcCd7TpW+zz/
Z9Kx2fVZIq6TlAzZwKm686PsrnmJTStuuWlLU68iNCCRl1myBWrcXB5xUFTbebI
WNvzEUGTnLR2Q+FCCcj9wYfjWrR3Mu9LF2fSIgmLqO9NRw9NRwZRrePxrYe8C
qd21k+4ivRyMi59KR49KR4sUM1jW+jf6Ll0uiH0WBvlvKiDeYYyOj90Vk0MbJzC
mt/
+1y6XWmfiW7ZpUe2BRQqSci7516Kyh50toc3hIbPEwphP+rzpNKd0T3o9K5EN
H7P01HB3V2Z0M44ZFVeZcMbI38iVEQ85GQxnBsB24K0bqqZWVFPb+JxakvMit
K+6w5iwofCRHa/MuhT0uLzT/Sn2Cm/Vo/6LSn9v1svZ/
bCIN3MgUuC4FlecrG6J2xyknJzasqmGTnLN0Q+FCTvadK32ef7PpWOz+y3M/
LcivyOI5yofKqhCZUOomZI5DZIafkyyKgqbPznoMbBCyDrL14IuaViiKWx0qnpV3
nMx2llY4aSAKXJjRjLEez0sXZ9IqxM2bD1YwHqxgPVjAN1yuUdLB3gVTu2sn3EU/
rdLj0ejf6Ll0uiH0WuP89vpE2c7MhraxxiWmlZQwIXKholjiPYykUnKp+j2o9HtR6P
aiLh0ooS3bdICcaxzM9uZFxKz68ljSqx+W7WTsW2v0rPHKYmLMio30qSOU4550
mlP6J90eldmGkez9TRoeWpoRHOeORTPzaY/
LpppEWU7EmbaxxiXnFZTIxjJswrDb2Dxvh21VTMioIqVVi1i21jkszYzyBNKqz5eP
0/0p9gpv1aP+i0p/b9bL2fSFbImirNFcouCmyQ0LJYkmYtTzz3/
uq7zmY6d7TpW+zz/Z9IWfaMI/
1ZHj1ZHj1ZHhi9SkEJxnzsdrVmXMyFqZ+Q+1r7Lko0WV5ysb7qu75eR0uX3Bt1
Gti7P7oftelg7wKr3bWT7iKd1ulx6PRv9Fy6XRD6M4wbE7Bmj1PZ+RXILKHvle2
+6Cgjvj4xguJRxzUhq1bHdrtG5WjZ50mlP6J90fvrkcZgy/In4IzI/
trsDkmdLNC5Nn2wkQeSXKXBC6Z/Cn/sU36tH/RaU/
t+tl7PpBdpeNSPWzpsdm4EJJZjXi7kiDZZUy6oqDTB8+SmPJTEs15ORFXectIzva
dK32ef7P7qr2kTjPkpHStsuUjbCy5yN0iGfPSGlqd+e/
Ea25x95CWB5KYt7PGCBM+Ujs3GHbYXL7g26jWcRUcRmxSI2KRGxSI2KRGxSI
2KREYmZGP0mol64k9ikRXYt20kdX8M+Ve7FIisRzpm70tDRd422ORGxSIRx4Ur
QzXeIbFIjYpEI44JAxcHLI1NNXK0BIIZxFvchtWX6+YyvN4/4JFMyrDYpEbFIjYpEbD
IhCqv1QwqzZrnGOGFC+Mj2sPWxjsnKeSMHSga1p+5zFQyEWUOi5O22ORGxyI
rDRZm0dlydrsUiNikRsUiNikRsUiEKq/
VEZW27DOhi4NiRqiS+V4CQQztb3IbVp+4zGVtuwz7JOsIO8r12QQztb3ASgpBb
LCo/wDKSJEE9c/
g8HIZPsUiKuycMk9HhcnabFIjYpEVloszZ6zyCjmM2KRGxSIiEjoRossOZ6TYpEbFI
gxJU8RsUiNikRCM8so7SzxK7pxsUiE4aSSPIlVdw+xSI2KREEgo3jJlE68ZsUiNikRs
UiNikRsUiNikRXW6rWNFnjFHqexSIaV96o5xjBccOIfV94R3sUiKxFKMsBQ2SJrQ8
mursUiK1EuGzvSYac7HbFIjYpEVpN03ai0MHLxXYpEIQkgVb/7x/wD/
xAA7EQACAgEBBgQFAQQJBQAAAAABAgADBBEQEhMxQVEUITIzICJCUGFSIzBA
YgU0Q1NgcYGh8BVwkJGx/9oACAEDAQE/AftBYDnDkVD6oc2oQ5/
ZYc608ocm4/VDY55naGYcjBkWr9UXOsHPziZ1Z5+UV1fzU/
fTYi8zDlUjrDn19BDnt0EOZcesN1jc2+EVu3IQYtx6QYNs8A/
eeAfvDg2xsa5ekII57AxU6iV5rL6/
OV2pb6T91NqLzMOXSOsOevQQ579BDl3HrDY7cz8AqsbksGJcekGDZ1MGAOrQ
YVQgxqR9MCKvIfuCobnHw6m5eUsw7E5eewEqdRKc3pZOf202IvMw5dI6xs9eg
hzn6CHKuPWF2bmdgVjyEGPafpgwrjBgN1MGAnUwYdI6QUVD6YABy/
grcdLecuxnq8+myjJany6RHWwar9mLBecbJpXrDnVjkI2e3QQ5dx6zets7mCi0/
TBh3HpBgP1MGAOrQYNQgxaR9MFaDkP4E2IvMw5VI+qeLp7wZNJ+qBg3L48jD
1+aucpVc1J1EqtW1dV+wNbWvMw5dXTzhyXPpQzfy25DScHKfm0GAx5tBgJ1M
GFSIMakfTBWg5D+DNta8zDmUjrDnr0EOdZ0EOVcesLs3M/CCRyiZdqc/
OVZddnly+LIxhb5jnGUqdDK7GrbVZRetw/P8aRrDUh5wVoOQ/
hi6rzMbKpXrGz06CNnv0EOVc3WF2bmfgFVjclgxLj0gwbOpgwO7QYNU8FVDgJ0
MfCsXl5xlZTodlOU1fkfMRHWwar8N1C3D8yytq20aKxQ6iY+SLfI8/
t7Oq8zGzKV6xs8fSsbNtPKNda3NpoTBTYfpgxLj0gwbesGB3aDAr6mDDpHSCiof
TAAOX7lkVxowl2ER517KrmpOolVq3Lqvw21LaujS6lqToYDp5iY2Vv/
ACvz+1GF36LD4luwhxr39TwYA6tBg194MOkdIMekfTBWg5D+EyMYW+Y5xlKn
Qyuxq21WU3rcPLn8LoHGjS/
HNJ1HLZjZf02ffGvqXm0bNqHKNn9lnjrYuefqErtW0ar8N1C3D8yytqjo0Vih1Ex8
gXDTr8JAI0MyMUp8yctmNlbvyvynP7sTpGst+lI3jG/EOJe/
qMGA3UwYA6tBg1CeEp7SzBU+iAvQ/
Yyi9bh+fhsqW0aNLqGpPnASDqJj5Qs+VufxZGJ9VezHyTV8rcoCGGo+/
XULcPOMlmO8x8gXD8/CyhxoZkYxq8xy2Y2VvfK/
P4sjFFnzLzhBU6GUZDUn8RHVxqv3wso5mHIqH1SzJx3Gjecr94bnxc5kYm781e
zGy/of4r8dbh+Y6NWdGlNzUnUSuxbV1X72a0bmIceo/TPC09olFdZ1UfuMjED/
ADJzhGnkZhXFhuH4raltGjS6lqToZXa1TarKbluGo/
wNn6b4mF73xugcaNL8Y0+fSV2Gpt4RHDqGH3w2oOZhyaR9UOZSOs8dVPHp
2h/
pDss8e36Z46ztDm3RmLHUzDpNa7x5n9wQGGhlqcNyswW1rI+9mms8xPD0/
pnhaf0zwlPaeDp7TwVM8FTPA1TwNU8DX3leLVX5gfur237SRMAaVk/
4K3hOInecar9UOTSPql+ZvDdriKXbdErQVqFH302adDDd/
KYchv7sw5Nn92Ycm7+7nicn9H/2eIyu3+0N+V/
wTi5X5/8AU38k95rf+f8AeaXHv/vNyzsZw37Thv2nCs/TODZ+mJi2v00lOOtI/
P8A428jJNLaATx79p49+0rymdGbTlPHv2nj37Tx79pj5LXPukQ5zA6aSiw2pvGW
vw0LTx79pbYa69+ePftBLslKf84c9+glecreTjSc9rHdUmePftPHv2iZyn1CAhhqN
mTeaNNBKctrLAukycg0EaCUZbWvukTJyDSQAJ49+08e/
aU5odt1hpsuyEp584c9+glecD5ONIDrL8tqn3QJjZBuJ1Gxs5lYjSDKbg8TSePftPH
v2nj37SjJNu9qOU8e/
aVPxEDbMjKal90CePftBnt1WVXLcNV2Wvw0LTx7doDvDURzuqTPHv2nE/Zb/
wCJ49+0rbfQNL7GqTeE8e3aX3mtQyiUZZtfdIl+Wan3QJRebVLMOU8e3aUWNa
m8RMnI4OgEpyzY+6RLCyqSs8e/aVPxEDTJyOBppEzLHYKFmd7glFPGbTWeA/
mleJuKy685/wBP/
mjDdYiUYvGXe1lGLwW3tY3qMwvZmV7LbMn2Dsus4VW9CSx1MTBYjUnSWVtU
260wrv7M7bPQdleHxEDay2pqTo0w7Sr7h5HZ/
SHJZie8Jn+pZh+8Jn+pZTXxX3ZZhbiFtdllvDq3jCSx1MTBZhqTpLamqbdaYVvn
wzMz3jMDm2yz1mUV8XH3fzPAfzbKsPioG1lWPwA3nsxvZXZne7KKeM2msvxTS
N7WUOa7AdmfZySaTCfer07S3222D+rf6bKPaWMoYaGMpRiplf7fFK9ojbjBpY2+
5aP+xxd3vFUsdBFUIoUTIfiWEwEo2sVg6hhMqrh2fgzBs5pMiziWEzBq/
tDM73BFYryM41n6pjEmoE7LfcaYPtbG9RgZhyM3mPXZk+wdmd6FmONbV2Z4
GimY50uWWZaVNukTx9fYziC2ksPzsxvZWZw/Z6yv1jZ/
SHJZie8Jn+pZh+8Jn+pYrFDqI1tjDQmUCsv85mefkEoGtqjZnj5QZQdLVmZ7xm
BzbZZ6zMH2tuL7Ij+k7Mb2V2Z3uyi7gtrpLslrhppMdDZYBsufiWFpbVu4yn/
nnMN9y3TvLfbOwf1b/TZR7S7M6vR9/
vMF9HK95boLDpKtDYNZnPq4XtMKvefe7TIfh1kypd9wszF3bf8AOYL6pu9plVcW
v8xWKnUStDYwURVCjQTO9wTF4e/
+0muJ+JW9Z8k2W+40wfa2N6jMSqt6tWEyKa1qJA2ZPsHZlV79Oo6RWKnURcq
phqTpMq4XN5chMNN6ze7TIxrLLCyzwd3aVoa8fdb87KL6lqAJmVkC3yXlMZN+0
TxFWumszLVsYBekwxrcJn+pZh+8Jn+pZjbnE+flG8Lp02FTbiA9opKnURMuphq
TpMq8XN8vITDr37Ne0zl0cNMa3gvqY+VUq6g6znMVd2kbcX2RH9J2Y3srszvdlF
PGbTWWIa23TMF1816zKfcqOw3WMN0mA6ecL8Sje/Gwf1b/
AE2U31CtQWniKf1S9RdV5RGKNvCIpscLLE4blY7F23jMavh1CZz6kJFYodRHsaz1
GYr7lo2ZAC2sBMBRqTszVZrPIThv2nDftMJWVzqNllb758phAirz2NW+8fKYYIq85
kgmk6Thv2mQCaCJw37QcpfhnXerhRx0leLZZ00lVa1LujbZ6DOG/
acN+0TFtfpKaRSugjo4b5hFrduQmLj8EatzmcrMw0ExEYW+YmcrMw0E4b9pw3
7SvFtfppEQVruiX4Z13q4a3HMSvGss6aSqpal3RLahau6ZZjWV9JuOekow2J1s2
8N+0xQRSNY3pM4b9pjjSpddmarGzyEwlZXOomZTxF3hzEVbEOoEyWe7TQTEq
bi6sJoJbSyuQBMfe4LIROG/aAHw+n4nDftOG/
acN+0o8qll9LLYdBMKohi7CZtRJDKJTQz2AEbLBZY5bSYdW6mpEvr36yJw37Spi6
AmZKObjoJgqV3tR/2i/
8QAIBEAAwEBAAIDAQEBAAAAAAAAAAERECAwUCFAYEFwkP/
aAAgBAgEBPwH1VKXul/
AUpfBCEJzfb0pS9QhCeOE2+wpeoQhPwFKXYQhPq3wz03zkIT61KUvdL+ApS9Q
hCEITb7mlLxCEITyTx310IT0N97SlL9G+5+SEIQhPoT/Gpl/
DTwzF+PYvxFKUpSlxeJe+hCEIQnkX46/
hvk+f+c1LlKXLty7S80peLlylLtLl25Sly8UvF25duUuXbl2jyZOUPHxMXMxYxDEPJ
xMQxcTJy8mvF9FixD6XTx69vD14xD4evGLVq1Y+v4Lti1i1i5fS6ePhZOVjEMQxb
/NYh9rl6vovVqx6tWrqZPIxD2ZMnM8LEPGLxofC5X+Rf//
EAEgQAAEDAQIICwYCCgICAgMAAAEAAgMEEBESISIjMTRxchMgMjNBUXOBgpK
xMEJSYZHBYKEFFCRAQ1BicKLRU2ODsnThgKOw/9oACAEBAAY/
AvwvnJGt2lZVVH3Y1kcJJsCzNL5nLNtij7r1rJbsACyqqXzLCkcXO6zxP2eV8e665Z
NVIsb2v2tWfpmu3XXLO4cO0XrMVDHfK/
8AsTjWdqI2+Jc9hbrVmoJH7cSzUDG7TeudDN1qztTIfEsZv/cczUPu6jjCuq4Q/
wCbcSuZKGO+F+L+wGW8N2lZdVH3G9ZBfJsaszSnxOWbZFH3XrHUubu4lnZX
v2u/
e8zKcH4XYwsGtZwLviGMLDheHt6wfxvnZWM2uWOpad3Gs2ySTuuWZpgN5yy
XMj3WrOVUn1uV73F232tzQSs3TSu8C5jB3nBZ2WNn5rO1LjsbcsoSP2uWqtO3
GtUi8q1aLyLVovIsdJF5VjpW9yyRIzY5ZmpI3mrNGOUfI3LPU72/
O7j4VNK5hQZ+kG8G74xoQfE4Paekfi/
Ozxt2uXP4W6L1mYJH7cSzUDG7TeudDN1qztRK7xrGb/
aXMaTsWRSy+W5c0GbXLOzxtHyxrO1LzsFyymvftcsilj7xes3G1uwfuGfp2E9d1x
V9JM6M9TsYV7ouEb1sx8a+nfi6WnQUGPzM3wnp/
E+NZ2ojb4lzpfutvWap5HbTcs1DGzbjXP4G6LlnZ5H7Xe0ujie7Y1ZNLJ4sSygyPa
5Z2paN0LOzyO2XBc0X7zlkUsQ8KuY0NHyH71n4hhfEMRRdRP4ZvwnSiyVhY4d
DuK2Ktvli+LpCEkDg9h0Efh/
Gs7URt2uXOl+61Zmne7ablmoo2fmtYLN0XLOzPftd7LEL1dHTyu8C1cjaQFlviZ3
3rO1XlYst0r++5asDvG9Zqnjb4Vi/
keDUxh4RfQHhWfB0oteC0jSDxL4Tez3mHQVhQnKHKadI/
DOdmjZtcufw90XrMwSP24lmYY2bca5/A3Rcs7PI/
a72Obie7Y1ZNLJ34ljYxm1yztSxuxt6ztRI7YLljY9+85ZNLH3i9ZuNrdg/
ludbgydDxpV7xhxdDxxBJA8seEGSXR1A0t6/
wlnHtZtKyqlp3cazTJJO65ZinY3eN6xSiMf0tWdqJXeLj5EbnbAsill8q5prN5wWcmj
b9Ss7VE7GrL4R+1yxUzTvY1m4I2+FYv5qWvAc06QUZv0aNsX+kQ4XEWhzCW
uGghCCsIbP0O+L8F4ys7UxjxLJc+TdasxTeZyyMCLY1Zyqk7jcspxO3iXRxvfutW
TSyd4uXNNbtcFnJomj5XlZ2qcd1qyjK/
xLVwdpWbp4m7GLEP5RnZo2bXLHUB26L1kNlf3LFSu8yxUn+ayqQ+dZynkb33
rG98e81Zmojd4vbmSK6Oo6+vanRTtLHjo4gp/0g7H7sh+/
4FzsjGbXLHUB27jWZhkk24lmYY2bca1gs3Rcr5pXybzlkglXx00rtjCsVM4bbgsrg
2+JZ2paN1qztRI7YLllNfJtcsVKw7VkQRN2MH8qx4lnaiNviXOl+61Zqne7ablmoY
2fmufwd0ALOzyP2u9lmJ3tHVfiV1XG2UdbcRVzZODf8L8XtcGUYLxyXjoXBzt2Hr
4gp604UPuu+FBzCHNOgj+fZ6ojb4likdJutV1LSOdtK/
Z6bA2R3rL4e75uwVfJgN3nrLnjbsvWcqXHY1ZRlf4lq4O1xV7KWIeFZDQ3YP5Zj
WdqI2+Jc6X7rVmKd7t43LNRxx/msdS5u7iWdle/a79zAZJhx/A/
Gg2Q8BL1O9oYqht46Pkrn5UR5L+II5b30x6PhTZIXB7HaCP51mjEwfMErLrnNH/
WwBftE9TNvSrVgdpvWRTRDwLJaB3fzDPTRs2uXP4e6L1mYJH7cSzUMbPzWsFu
6Llnpnv3ne1yQSs3TSu8C5jB3nBY+DHiXOw/
UrEYj4lzOFuuCz1PIza3jhkufg6icYXCUz8LrHSPZujnaHsdpBRkivfTHp+HiZOXCe
UxCWndhNP5fii95Ddqy6mPuN6zYkl2C5HgKYDecsUjY91qztRK7xe0yInu2NWTS
yd4uWU1ke1yzlSwbAs7USO2C5Y43P2vKyaWPvCzbGt2D2Gfp2OPXdjV9JK6I9T
sYRLo+EZ8TMfFElO8scFgPzdQPd6/
Zlrxe06QjUUILoveZ8PE4SA4veb1rDgOP3m9I/
EWdkazaVjqGu3cazMMj9uJZmKOPbjWOpc3dxK+R7n7T7G6KN79jVkUsveLlzT
W7XBZyaJo+V5WdqnHY25ZXCP8SxUzTtxrNQRM2MWL9yJLOCk+NiLruFh+NvE
DmEtcNBCbT1pDZvdd8XtDUfo8ZXvR9exXEXG0S07sFw/
NYsiYcpn4cvke1g+ZWOoDj/TjWYge/biWZZHF+ay6l/
diV7yXH58XJa49yyKWY+BasRtIWUYmeJZ2paN1qzlRI7YLllNfJtcsVKw7cayII27G
fvploLo5fg6CjHM0seNIPEbTfpB3ybIfv7QzU1zKj8nIxytLHt0g2tkhcWvboIXBzXM
qB0fF+FryblnKlncb1mWSS/
ksxCyPbjWVUOA6m4leWyyfPSsillPgWrEbSFlCNm1yy5om/VZ2q8rFlyyu/
JY2PftesVKzvxrN08TfCskAfybLyZRyXrg6ht3Ueg8QU9acKH3XfCg5hvadB9nfyJx
yXoxVDcFw/
O0OYS1w0EJtPWHBn6HfF+E8yWt+bhesqvcwf0RgL9oqamba9Y2PdtetWadqya
WLyLJjYPD/ADIxVDbx0HqVzxhRHkv4gimvfTH/
ABTZIXBzHaCPZ8HOMfuu6QsCYZPuv6DxG01e7HobIfv+PM7URt2uXP4W61cp
48CubUsB/
qxK9pBHy9m6OZoex2kFGSG99Men4eJdy4DympstO7CYfZmKobhNKwhnIDod
1beIKeuN8Xuv+FAtN4PT+NL3uDR81l1LL/ljWZZJKdlyzMDG7TeuewB/
SLlnZpH7XcXCppXM+XQhFXXRSfF0H2Za4Xg6QjUUAwo/
eZ1cTCixsPKZ1oS07r+sdXsyyRoc06QUZ6QF8HSPh4giqL303/
qmyRODmO0Efi++aVkY+ZWS90p/pC/ZqcD5vK5/
AH9AuV8sjnn+o23MiedjVk0kvlXMhm84LOSxM/NZdWe5ixVT/
Kr6eRs3y0FFk7HRu6jY2CrJfT9B6WIOYQ5p0EezdUUAuk95nWi1wucNItEsB2jrW
HFieOUzq9o6o/Rzfm6P/XEu5cB0t/
0hLTuwmH8WfspjHzesv9JBg6mMuV81YXHdWVUv7mrKllcsYkftctXv2uKxUsXlW
REweH2GBUswh0HpCv5cB0P/
AN2COW99Mej4U2SFwex2gj2ZkiujqOvr2p0U7Sx7dItbLTuwXhfBOOUz2jp6QBt
R0jociyRpa4aQbcKLGw8pnWhLAdo6vx4WSNDmnSCnT0d74OkdLbLuXAeUz/
SbLA7CY72d0gwZByX9S4Oobd1HoNrZIXFj26CFwc1zKgdHxe0whkTjQ7/
aMVQ3BcLRLTuu6x1rCjyZBymdX49dP+jxc/
3o+vYiHC4jSFe3KiPLYmy07sJp9mYqhuEOj5LHlwnkvtDmEtcNBCbBVkNqOg/
F7TAmGV7rukLAnGT7rug2tlgdgPCwTkVA0s/
HpkizdR19e1GKoYWPCZFfm5sRHz9o6OZoex2kFGamvfT/AJttvGlCmr3Zz3X/
ABe0MVQ3CYVeM5AdDv8AdofE4te04iEIai5lT/7fjfLcG7SsupiHiXOl261ZEUr/
AMlm6X6vWTDE36prqkjJ0XBRvAyYson2txTqj9HN+bov9cRtNXuxaGSH7+0LJG
hzTpBTp6S98HSPhtBabiNBTaeuN0vuv+L8bXzwskPzCx0rO7EsUTm7HlYnSjxLJ
nkHcsVS/
wAqy6olvyauDpm3DpPX7czUtzJ+kdDk5krSx7dINraOqdffzbj6e1dUfo8fN0f+uI
2m/SDvkyQ/
f+xmPImHJejFUNwT0fOwFpuIxhQzdJGPb7UzUtzKjpHQ5FkrSx7dINraetOFDoa/
4UC03g/2LkY4ZbRew9Rte34ZD7a/
kTjkvRiqG4Lh+dopKo5t2Jh+H5f2Lmlf0Ntwj77yfb8HONjukLAmF7TyX9dowzfLH
ku/
sHjIWVNGPEsqqiHjWtMXPX+ErJ4R3hWbgkdtxIcJkRjksFjIoxe55uCigZoY279wd
DMMR0HqUkMvKYbrOC92Vv5/jfKkaO9ZVVEPGtZadgKxOefAsmKU/
RZFKe9yyKdg2lZLIm9y5bG7GLWnLKqpfOsuaQ+JY3E+wuAvK/WatuedyR8I/
copR/EZj7rKS7/kH41uKy2O85WOE+YrRIPGuVKPEsU035LJqZPKFiqneVYqv/
8AX/8Aa1seRa03yrFUR/
QrFPF+axSRHvK0xeZaYvMtEfnXIZ51zbT41zQ8wXMXeILPOZEPqsIDhZfjd+50r
em42Ug/7R/Z6RzDexmS2wP6Imk/2ddS0jr5XYnuHu28K8Zc2Pu/
snpCxvaO9c/H5llVUQ8YWtx/Vay07AVzp8hWJzz4Fm4pH/
kiyL9njPw6bQ+Qfs7DlfP5K4f2BxlZUrBtcsdTF51jq4/
qtZB2ArnHHwLEJT4ViglKyaV3e5ZNL9XrJp4x3lZMcQ+qxGNvhXOtHgC1k/
QLHVy/
VY6mbzrKnkPjWNzvqtPsg54MdP8AF17E2KBuCxuj8dZsN7ysltN5isn9U/
yWTJSjYFz8I2LW2+b/AOljqSdkyypCf/MsbQf/ACLmgfGFzH+QXMf5Bcx/
kFq5PiC1Y+YLVT9QtVd9VqrvqFqrvqFqj1qj1qj1qj1qj1qj1qj1qj1qr1qrvqFqrvqtV
d9QtWPmC1e7xBcx/kFzH+QWdLIhtvQdNfUP/q0fRXDR/
wDzVi+VwY0dJWtReda1F51rUXnWtReda1F51rUXnWHK9rG9ZK1qLzrWovOtai
861qLzrWovOtai861qLzoPicHtPSEWuqIwRpylrUXnRbBMyQjoabQZ5Gxg/
EVrUXnWtRedXhAzyNjB0YRWtReda1F51eOJn542bXK79ajWYlZJun2Jc43NGkrW
ovOtai861qLzrWovOs1I1+6ePcamLzLWovOjwErZLtOCVecQC1qLzrWovOiYJGy
AfCUS7EAtai861qLzrWovOtai861qLzq6KeN56g7jZ+eNm1yu/
Wo1mJWSbruJfPI2Mf1Fa1F51rUXnV40WlslRG1w0guWtRedYEM8b3dQcgJ5WRk
6MIrWovOtai861qLzrWovOtai861qLzrWovOsO8YN1961qLzrWovOiYJGyAfCeIXy
uDGjpK1qLzrWovOtai861qLzrMysfsdxi6Rwa0aSVrUXnQa2oiJOIDC4hdI4NaNJK
1qLzrWovOg+Jwe09IRfI4NaNJK1qLzrWovOsOF4e3rFpZLPGxw0guWtRedACpiJ
OjKs1qLzrWovOsOF4e3rBRfK4MaOkrWovOtai86vGhFrqmIEaRhLWovOgyOojc4
6AHWlr6iNrhpBctai86D4nB7T0iwcPKyO/
RhFa1F51rUXnQcw4TToItwJZ42O6i5azF51rMXnVTsHrx27zfYQ7T6qq7V3rZN2f3
tg7S2PdCpt82x7os4Sodsb0lEMdwEXwtWPHZhRuLT1hBlfnY/j6R/
tNkhcHsdoI49V2R4t7HFp+SAmP6xH/
VpXCU7to6RxZd8+tlX4fup+zPpbN2n2VR2bvTjXg3FCkrHYRPNvPpbwlQ67qHS
UWxHgIupulXk32XsJaesIMrc9F8XvBNlgcHsd02Q9rbFuC2q37BuFU/Zn19hJ/
wDHP/
rbL2v2HEn7vXi3tJB+SbFXnhI9GH0hBzTe06DxI6dpypTedlgc3SDeFFMPfbbVbls
Hf6qq3fvbDtd62xVTfeyXWAjEQoZh77VNGBc0nCbZNAdLHYX1UcI0yO/
KyCLoLr3bFLL0Mbei52k47JKl2iMXDbZLM7Qxt6c9+NzjebJaV3u5TdljsEZ2PKba
6ndyoTi2WOkfia0XlSzu0vdfZwkgvihxn5lVOwetuhaD9FoK0Jm81aD9FoPE0FaC
odp9VVdqfWyfs/vbB2lse6FTb9se6E+abktRlnOwdXGEUp/Z3/
l8+PV9kbcQv4jZoTo0jrUc8XJeOJNvn1sq/
D91P2bvS2btFUdm70tvYxztgXNP8queCD87A5huIN4UMvxsBT5peSwXoyy6Pd
b1DjBrz+zvOV8vmrxjBUHa/a2LcFtVv2DcKp+z+65JWg24gtB+i0FSf/HP/
rbL2v2HEn7vW3QtFrqOU8nGzZxJXA5LMhtstK7Sw4TdltVuWwd/
qqrd+9sO13rbNF7117dtskB0xuvGxQ1LejIdYxvRKMFFg0RNwbJ6p241MgGmV
35WxMPLIwnbbI6ZumQ3nZbDITc2/
Bdstc5gzUuU2yJ7jcx2S6wQNOVMceywAYyUyP3zjftVTsHrbTZI5PUuSPouSPouS
PosYvXJH0XJH0VTd1/axt/wFckfRckfRYlVdq6yfs/
vbB2n2ti3Qqbfti3Qo6VuhmU7bYGsF5OIBNfUMElQdJOO7YsF0bSNidVUQuaOW
y1oeb3xZJ41X2RtdeBzpVz42kbE6agbgSD3BoNstK7Ry28SbfNlX4fup+zd6Wzd
p9lUdm70tk7X7CzhSBwjXDBNtMx2kRhRUjTi5b7ABjJTZKpglnPXoarjG0jYnVVC
3Bwcb2C3g3nLhOD3KDtPtbDuC2q37BuFYxeuSPouSPonbbKm8DSFyR9FyR9FU
9k70tl7X7DiT93rbS5I5HUrnMaRsT44sTHDCA6rKYjpdd9bZpfeuubts4OHlXE2Q
yX5N+C7ZbVblsHf6qq3fvbFtd68SS7kSZbbGA8mUYCni6S3FtsZIzlMN4Ukr+U9
15sgj966921FgOTCMGyJh5DThOtlcDkMyW2NbKMbmhw77IXnlAYLttjg0Z1mUy
2N7jltyXKV4OQ3JbZw8gzcPrZU7B62tihluY3Rkhc8PKFz3+IU5qn4WCRdiu4lVt+
1jdx3Equ1dYXU8joyRde1a3L9VrUvmQFRM+QDRhG2LdCpt+2LcCqX/
wBZFjS7RE3Ctc12NpFxUsXwPIsni6HMv41X2Rtd2ptma3kuyvrZTXdJweJNvn1s
q/D91P2bvS2btFUdm70tMVPgYJN+UF/C8qH6y+8DQ0DFY2R7f2dhvJ6/
lZVE9DsH6WRYWhmXaQcYKniGhjyBY+PoexQdp9rYdwW1W/
YNw8R22yq3hbU9k70tl7X7DiT93rbSh0rAcD4kS6eMAf1J8sfIGS2ymHU6891sN
K3oy3WTzn3RghVEXwvN1kLzygMF22yq3LYO/
wBVVbv3ti2u9eI2dvKhP5WNe3E5pvCimboe29TtHJccJvfbAz3b8J3cpJHcljb0+R/
KebzY+pdplxDZZNKOVdc3bZDCPfeAqaZoxXYBslpnHE8YTdtpewZqXKG2ypjZj
4ZuL5GwNaLycQUcPvaXbbKnYPXjVW8OJU7R6WN3HcSq7V3sIt0Km37YtwKcH/
kNk3Z/fiVRb/yGy/8A6zeoXUr8Bzn3HFetY/wC1j/
ELWP8Qqj9bkw8G67Eqvsja7tTbi6IxZSdoOJNvmyr8P3U/
Zu9LZu0+yqOzd6cdkFaxrGaGvaLleMYVUD/
AMpseOuLiVZHx2M3HKDtPtbAf+seltVv2f8AjPEdtsqt4W1HZu9LZe1+w4k/
d68d1ZKLi4XM2WEnQFNMfedi2WRk6ZctMlGiRv5iyWmdoeMJu2yq3LYO/
wBVVbtsW13rxHxv5LxcVJC/
Sx11hiPKhdd3J4GiIYFsd+iTIXBjTMcGxkTOU91wUcLNDG3WQ0rToy3fawynRE3
81N1x5Yshmb7jr017cYcLxY9jecblM28Q1EgzcOjetqdg9bYJZosJ7hjOEuZ/
yXMnzFOFKzBwtOPiVO0eljdw8Sq7V1kjKm/Bay/
EblyZPOtEnnUT6YOvc643m+2LdCpt+2PdCn6nnDHfZFI7Ew5LrZZ3+6PzRc7S
TfZUTnRiYFTdofTiVfh+6q+yNru1NjnyG5rReSpp+hzsWyyM9EYLrXE9ARPzsq3f
NoU/
Zu9LZu0+yqOzd6WySVMeE4Pu0rmf8k79XaY5LsRvVxsMTze6E3dylPRJlCyGY8
m+52xXjRZJNJyWC9PkdynG82TznQ1uCEXfA4G2H4mDANjnvNzWi8qab43k2T
SdDWXcR22yq3hbUdm70tl7X7DiT93rxo46w5J0DrKAaLgLHgcuXJFrGMhhwWi4
aUxs0bG4BvBbZFM33HXpr2Y2uF4VVuWwd/
qqrd+9sW13rxWVLdEouO2yUyG5joz9U578bnG8oNYL3ONwCcyQXOabiE1zcR
GMKn4M3tbHj3jpsdO7kwjFtsLnYgFNMfedi2WPbDGx2GbyXJzHQxXOFx02hh5UJ
we60vZyJsqwNGk4lHCNI5R6zbU7B62wwy8JhsGO5q/
ieRfxPIv4nkTJY+S8Xi2p2j0sbuO4lV2rrJuz+9sHafa2LdCpt/
7Wx7oTamMXui5W7aIatpljGhw0hYhKT1YKuORCNDLA1gvcTcAo4fe0u2pjJXuZg
G/
EuflXPyrn5VJwL3Pw7r8JVfZG0xVGHhYZOIXrIbK7uXBgcFB8I6dtrqiQZc2jYuAdF
wjMG8kHGsqR0e80p8FDe4vFxfdda55/
iSEqfs3els3afZVHZu9LXx1Ly1xkv0Lnj5CnfqpMsvRiV5squrJQnjF8kPpaIalplhHJI
0hYhKT1YKwbuDgGhvXtsAaLyUyM84cp+1Swu99tydG8XOabjYXR5UbuUxXuEr
T1YKMNO0xw9PWbeFdypjf3cR22yq3hbU9k70tl7X7DiT93rbSl0TCcDpahUQtuh
k0gdBsDmm5wxhNeedbiePnZwLeTCPz44jPKhOD3Kq3LYO/1VVu/
e1kM+HhtJ0NX8XyL+L5F/E8iE0F+BfdjClYOWMpu3icK7kQ4+9cM0ZMw/
PiRg8uTLdY8Dly5I44jJyZhd320u6bId8cSp2D149J2Ytqdo9LG7h4lV2psn7P72w
dp9rY90Km3zbHuhEOxgoywDCpnf48XEhV1guk9xp6OPV9keOJqkFtOP81cMQC
qJb8Rfi4jIYRe5xuUcLNDBcp+zd6Wzdp9lUdm709hfKLpZThEdVhnphfTu0j4OM2
rrG3H+Gw+tprKVt5/iN+/
GBcLqdvKPX8kGtxAaOI7bZVbwtqeyd6Wy9r9hxJ+71tpdxPgl5LgpIZeUw2NcT
mn4nhPnJyGtwk+R+NzzebJ6iRoIGQ29c236Lm2/
RTxdGFeNlgjdyZsnvVVuWwd/qqrd+/
HbvmyVg5LsptrS7ly5RUmCL3x5bbYYvdvvdst4FvJhF3fZBD8Tsexc236Lm2+VQ
VEbQLjgm6xr2YnNN4UUzdD232Uu6bId8evEnjhaXvddcBtWqSLVXrVXrVXrVXr
VXqnZKMF7WAEWzyQ07nsJxEbFqj0JKiB0bMA4zxKh8dM8tdISCtUepXVMLo2ll1
5thbTRmRwffiWqPWqvTAdIaFA2mjMhDrzctUetVemA6cGwteL2nSCi+gdwR+A
6FjpnO+bMa1SbyLLYIW9byg92em+I9HsKhkYvc6MgBapItVetVetVes4GQj5lB9
Qf1h/z0K4aE5t914uvRMLf1hn9On6K59PKPAsinlPgWWzgG9b/
wDSyMuU8p5sma0XksIC1R61R6lbUxmNxffjUzWi8lhAWqvWqvWqvWqvWqvQ
4QMhHzKEkmemHSdAtucLwUX0TuBd8PurV3PHWzGtUm8iyo+BHW9CSXPzDp
OgcUyUx4CQ/
QrmeFH9GNapN5CsmleN7Eg79ISeBiEcLQxg0AcU3Ur9K1V6qBVRGPCIuvtna0X
ksIH0WqvWqvUjKmMxuMl9x4kscDS95uuA2rVHrVXqnjlbgva3GLGz0rcKduIjrC1
V61V6/UXUkl4PK/
pWqvWqvUUb24L9LttsU1JEZDg3OuWqvTXspXhzTeFKGxnhnx8j5rVXrVXqGOd
pY8X3g7VURwtw3uGILVJFqr1qr1qr1qr1qr0I6hhY/
COI2RSUzMOVhuuHUtVeomzwOjjwsonqVw0BY1MKaBz4sLJIWqvUs1UzAkdiAPV
Y5zW4RAxDrT5H0r8J5vK1V6fNVxGO5tzb7Zomi9117dq1V61V6fBWROjwTk32
U5pYnSYLTfctVeoy6lfcHD/85P/
EAC4QAAECAwYGAwEAAwEBAAAAAAEAERAhMUFRYXGh8CCBkbHB8TDR4WB
AUHCAsP/aAAgBAQABPyH+XEuDwQnR4Rf8VT/
Je6q9b6VpoeZH5pY4O3uMLEAS5jnNSoPcRAjc2X7ptb99FrQHc6oI29JVC8k9P+
EgHIAYp4dhVxVt84U54QSCyvP5A7DLvlUE7nog5ixP+BSkimVmFtpFMAXfu6JoL
OIQL0/vwjisAIBu7BGiGPdND1PJ7JxaEUiLh8VqLR/
yzoB6wxrSgBHo6H9uMfJIKQn8B7UMn2RCZY84ttjm6cXINg8SdgsT/
KacGAXeoK63ALSmdANGk2B+TKh5qUAadGgGnRL1JGqPKqIcxC2m+box+vHZ
OxzEtVQuzR1Cz4r2ZAGRzCyQD13Kmhorg/
1zgVQklvqynKzvU1w4+6BEXeTJRxcLyqJuJIi5ixPyAhGbAdGWIzPuQ+eW0R5Wk
vC0q9G45r+Fv3s0CAGLkfOQ9UELms6gICUAwMkh3BVEESMuF8UW0/
IXNCssh/
pwEwAxQAljq4KSDOydTkSPQE3uJHbK4aa9WVnP4zoIzfFUDZPNDQdt2I0yvFKF
T/D9qbCShela/
AHuhYGWMf5Q0zf3qamyH6qri4DHgdjKRwWDM77qoZUfz5AHJk6yO5VMNxipa
bvEr+33l0r+Q01ys/
ERYhYBO5mZULdyaKBqzJOWAA+DD4Ik4LxPJAWyMUAGBh/
o7kfEiYyKc0vlP2pcEgGI4J14ZhEkf+ZE6LgE4SELDI7DECC9eQilzWGmoTlZ/
BqpxQkEIYPJbufJa1V9FoSqa3Kth1mgzA8Ef63SUMi1zmTlzu4LY8AtTZRVOofyQ5
x2GFV3ud2quOh2ww+MjBwIJanhp3rM8WvslBASheW91U9hUWm+i10tldyzsF
3P3ctOYUABgYf7UOMGAcFWDqqHCVQIiQ+LkTBVnYLL9/
xYVxAXlS4vcwnRV2cXygW+fiCkjbMOqcXouZaIq5nE8ck8GYhQCfG1NBgTzORX
roeEGeko7ug/
WWJvY8Xx8oo5jAVFBkP9QPJbKtBa0wj90+PKt9zFfrfleEfwinMgCVqMXwq+N1S
d6fM2y6WVVeYlEEk4kVkvdogL0/hAbhMIKp/
cKyslexXQY6RPwq4BcNHALEK0hw6ZCkGtsN/
uJpePFyOo2IVoiX3QxjW+ibpBmRAE4KEBCgDf6kK5jMnzJyKcADReFaYUjmMbLk
raqmpcokmszj8J8M7G6CjYRJNQ5cQgXp8nP4UQlbXdBvHA/XQLX8ICUXIcH/
eu1U7uYsIJ2BkXx7oBOfdIIoxM33LSQw8IpMM3s6mTsBIYB+wgtUxnhFHBuM8p
4JvahDBsAf6wAOQAxT45CwgpKC8QqvJgI9jFppSIuEdqIdaj/
hnCYMB+Kes20jkfkeZdVpXhMAcyqHPHgcTTNiCG3J6A/
wC6a96TPhcs9qpddAwjK0XjIWcvgC04v9g0BcJ9qXHRwzwwspxkulZDwk1g0/
LpSBW9lrmXgkKuIaB66yCsbnCopXlZZy4ixpBLSBQ4AHsB8Y0pMgOgpK3gPBNJ
zMOoxQP9ReVx/qGgS8mTnPCx7onsFtqaJZdRe7J1attV3naJJrM4/
FktQsKJBu9rXVbkvJ0aORlKLvgIE2fzBMlPa6grZPj4HRyYPUE8oCpS5hOnDqdiwK
EmwJuljHxjwCMQSKtOWCuTDgBXFtMhVLXUq/
0QdwWGFV8u+tVTciyXFHLR5u+tGndjn4Mk5CYxQKi2poOCQUivXQ8ILQ9Bs5ry
zsmYlhfPctDSCAEgA/whwAtgx53p0GlhTMWcBD4uQxBVjgbH9/
IGWawakICgVBETXaq4LirFjM7jD+cxQgIKXXW+tSzE009OtU9i4/
FYgMJ+HTERiLhiTIwJuyNSjFyJoWIVpWf2Q6dY/
hNUiuoWc9eAIBQAP8sgAQQ4KCCVRo+tUNOmNKSOCY2TSQEEOJj4wiWvyIgoG
ApE/ZHQFrZrGIfywxkAtKtW3PdFJzmTFSSsLiTs/
NtkZyOApRizIFLJxbhPJaLjleOzFaXpCCOuXhCJ/
n7kBYRgKHdEH+mZ4tJImPxFz5YUbxwPc0SV/
CHgEcBkfjchhaOhwVnfRsC8RINFyGIKHgqNl+/
5MGBa8eS5IjXC6JCcXrCCo+eEqjPkKCCW3AgAoAP9i+QMwrwnIDZYkc8eB6EK
W4ggcEcivxmkioVcETOjoCTEEiYkU02RAjvT+6JADmi0i1S/
qhRJjniWHmPtQaerScfGAODIO5JmwHgeJz6uoQEtKR2+MW2/
WYhTWl054OA6bTJXNggBhnAGv9pjAAmRIg8LDfonwckOqcRj5kcGww0MOcxz
wht5HTckbFKkB3BAgHBcH4gwhmIJFOk1Q1y4cDyrdGX6TSAalTuPxg1OwDgo3
Wjb/ngKWR1y4IAJHIkf6/
IjGETI5S9VLg+I7Jy5JDPDyYMTSZRJx4hTWzpb3R6ewqLywJug1TKUOIoAQq8oBc
2LQp0QTYyC/
NyHBHxtp17HLcUSEaxBMR7IPG4p9Nsqn8ZABiHC6AHuhBJjIiL9udl4oBbbbsP6
wANgYToEBIMfep1Nls/lW7ZAQbUAFsaclYXZ2o477Fy09wCAApLjJx/
UBTOuZSphA4gE7eIIFUHIr8beJErOFDYQmRKl1uBTbkDU1GHyDqgtjNE3OwExF
zVujL9J5GKHqdx/
vB7nYCRTKKvayg4Tl1KY4kPMJIj45USkCaFmEdG8RJVB0A5op2MQ+SS0enXBD
79diIuMFvQbinUsJxn/AHkhxNX6oCiCNimIKLMiSuWKH06oG4/
GDHarSvCdAupI0OMSHxciYKFUYWf7+STWFGqpypUaMSp7T4KkMFnGuIw/
vW128uFLEwBtyQa/gg/
ILADASKtpWR3cIkERgoXQ2wKD6Dj8g1OlxRu8VTphE4OQRMI5oA5ZP7cQ/
JhVvLmFP7N70rteBN3eECnXMierSJZej175QGA4NQm6BQd0IJMZERzSQ0R3p8Y
NTsBIogDU2v5iRsU4DRMr0yUzY/
22MHH1SNz9iHNABTO2OK8tAhslAgoLttaFefnafU7CaImBgJiMm5J8kEAGIcJ2r0f
dCCTGRhSkk3sCkgLiX/C3zLZHY4Jkm1WBeIOBm4L0+Nnyq/
KFHqNhNEPAwExG0DgrmwQGgTgi3/
hYyDm6kTGqMuYHzOkwkkaFGv01wXiJRpM7teH/
AAs+YAIALyaBVrAt3ZkJfOeTdlVwV3ooSGGUiia+bcf+BO1VQVmUTbPBXaaKuH
yco+z8iu3NqFTLIktFWZc8YMSlAqLC/wAA/szArwhMT5QKcjNDkn/
bh3zsQhbisirecHhaC5LsRh5QxmclF6+ld/
KfKCSyh5VnOQAVVvMtfU1q9H4AAolAAjyQKbsf/
CCjZZoDHSOPrL+1OX2NxZVBb71QhkqlZZCRJQVQbYKyjMiZSOYr9dBsOq+0bO
HDgankgYmyPbF7ZBxsuiVCyQIjFfJRBucUdcdejYO6JkLP8O6YftAoK91/49plFD9g
UqKxxMv+Otlk4UXZxNJR+Wz/
AMTI6i5rVcFGoDywMg1CdWzg8K1vJGjuSHT7EBG/
bwn5qtZwrQcRtoAQGAoP+A0ZGZWgeBOrNsC7QXqvZpeF2ZEtF8ftA+AXhVVi
0FasZdkcloJKClkUWB5fUuwhvZEHKOZarRKoLNCVTjn8VreZhA4wzAP7o5n+Jx4
U11X0w8QPGL5Xhi+kenyGpRFxAgfXVNQGRAdmjAKwCsIrskRuzyiDbar1aKjnrV
61etXrV61etXrV61D8HAT1JAiDdHlWhzKwisAogM/OaJiIXECQWCgH/
wA1auBo7AL0petL1petL1petLIzeC9KXrS9aXqS9aXpS9aVDHR3BREfMBGS9KQ
ABOQTKJChMCw5XpSa+kgCI4NETDjEw69aXqSAIjg0PAbYqLAOmY6yGOAwT8I
8QjkoAvWl60vWk79JBnF4J4yoEQWIIr1pHhuuSyODgBySvSl6UiNCYlxijtAJyTYnv
pL1petL1petLA+KJ4pIRwggdh7NBeiB4AkwlgWA69KXrSCIjlQxplPAEL0pSYG7IlA
Kg4BDr0petL1JepL1petL1pF4CtiTXr1pelIhQmJcD8FcDRWAXpS9aXrS9aWiPHin
RmIYBetIqN2AzPAOI7kMAvSl60qGOjuCganchgF60vWkCEehXEaOEmBC9KR6w
MAGaJaq9KXpSDCPR0FXA0VgF6UiKvRIAiOVCiomYgyK9aVJQ4EmJb8sBBC9KV
DHR3BgfEzdLr1pelIBcFyHBidhGxAr0ZerLfbvFQ+Eey3uJC2xwgFs1y2K6Aqt2ug
XVFKrgjpaILM5lEicnYmAYB6FYpyakkBUB7Rx7rdw4+EJlhBktJU5hq9XHgNOAp
my3o7/
AALbr3EBFAtBVF0ajNE6b7CpcEXXZmmzKcSLEwExTQjFHfO4YoeEnAQ3WBhat
9ujssPiORbwIavwGp7XCCDq0mRMxZD1b0PEI4LRwS5ORMDHsMTFWZ4TgbY6
tHf4lpXZHcr0W7yHnikDlbhwrFxJztWgUIZwuNJkj4mdnJBwQTygmUT8iw6Igjnc8
GI67/kKnaU3zmbEwfZM+crAc8fqhZweo/
UMCmu5sAqoKAXCwQbLSrkBb7diCUIjKDPTIMpuinahs9cqVkYAE0mcF65euQE
O7S4skb/
CAWzXLUe0BVbdcifMHqbk6sJyhuEXWhovczsXtoC8xTi3m6NUMgRIpgjMRmEs
mNxRaXeZG6JpwZM3y9Hd4BbVeiLYmIV7usGFA0GJjEFhXsUQj2s8I0jUOSuouFk
X0zIVDBWDgraYoWrZbo7LCJyMw8yeoXqo1AOQgy96HApqfAaztRBaEcgjWEBiI
viCPnDgmcG5A/
Yv81AjrUd3iWldkdyvRaEOXKKIgkxkRBx780E0aryCDqGdPuE5KW5jMwcAU+wp
zDTWScW7NzSg+xuT8Z5DzCSrCTBTLDaITgDyz+wlvNsmsCALhgEUYtq8lvt2JR
LrtR4Na0FYAYx1IQBgwbAJgBvxGUgAwMMFtF/
GDgWxXLUe0BVblcjncrnqQf8AjYWlAYY4LMKEhXsIqq3gKAXiJXAXLs4t5ui9aNxg
EfkaoIoOMdzpNxRDFjIwKC0w8JiaLc7403y9Hf4FuV6OroZSIzWk7IykBp6I8rM+i
Ai3DABDZU5a+AEfnWwinsO6RF4iabPpC2uKFq2m4R2WET0PzCEna5TU4P8Aj
CirW+3o6nwGs7UTjn9BEJ7qCKB6AmKWQlKB3lJEQAt1ZIKtZlMCBqpsAeD4MLn
Cd6Q1qO7xLS+zjsZ4tqFdYOlYgs7E2Icw5UwiGLGSkHA5wVZtNYrJPaG6smVNa
B56mDLH5CEZnhOUP2AWwa64Hg4B+WkJpnVLuapWUJtAeeFOSPyx+wr5nh7
bMN9uxGvFYCSUCsKp65Gxw4NJ7OLW8XwfLkEaUY0JuVwcaAWxXLUe0LVtFyMf
LgiZCQgFZyOeQERRuQLwUUh9CYGNGQEYg/
vFtN0dguERCAEaICpe3MRNOAam+Xo7vALcr0cWQ5OSw0Vnt2AIVzWQkdyE0
KSykgFhcZLlSIy2DEIOhiHgZzm+oW1xQtW03COyw4ZmpavDeLo7RejqfAaztRF
FwAggqoWi1TBRAjVAgQUHHJpou4kPMsgy+Qc4zKIyy5BUQcE/
LSGtR3eJaX2cdjMnmM9YE/
Y8wKggutNybkKJ8Q4cpMpfZB8gpnxPOgzydycHfN1ZIKtZlFmSgXWoA3m8qkLF
RGCsZfHJbQgO4yJg8/WDgBsC9XaLt51hvt3i3C7is267g3C/
jC2K5aj2gFtFyJKhFXOAgG0+LgojeeBxhQJP7gIxwbFb30rf+tb31p84Hwzvctpujtt
wiMoqBMCACUQ0U7G8xpvl6O/
wLcr3HTUDCDMIAiuUIRpgI7sDGqZuo4AX4iG4XLa4o46dlHdYQpxTUtThvF0duv
R1PgNZ2uOVYL7oEbYDlUnzeCDamMS5o4FBjktEKw1aO7xLS+447BvuTzlWUx
wdm/
UEwhUbOiupiCXgbudNU5kYXkqYBVcDnKmJhhQgHmQM8d+M0lLQdrkfkLLKIY
Wo2LITAwYg/
TFiIJEGREfMKfxHfbsTBHdwsf1Q6JoE3qPwbNchtd3BuF8AfGwCscL2iDAHt1s0Ati
uWo9oCq3a5DMioNr4FNcOYFAghxMQooSxfYCMI5xQJRmdweJA2w3R224QElOF
WBGp9V5BAjXOPbuYiMmBCVjcUMy9wt8vR2+BbleiREdEuEmCx/
UhaNufmeKIaQRCX6OcdEdslg2ddRARiw80khgrkHBgWliUnzl5xnAwRJExJdMkH
PjfMWsNE4iAaBAhsCIQ+5MDfuEYmpa3DcLo7dejqfAaztcR/
Ayq6KA0CYAWQc2360W8p5RVp+A8LC+zC1H4YCYFatHd4lpfZ8FjPdJvyGjGYm
EWZzzCmJ0AWlOFeuBRW3YJimgAZZZAMz7hgQBm5OCpFGbdYgzLxwdOj9kWo
uPd97IjRYDRcbYTESsTd7D3hUx327GneMzwMzOftXAxaO7XIbddwbhfx0YFsVy
1GAVW7XI9N2y2KQaOkvKJSpIuB7KOpgW41AVKkKaHbzqhCgoFdyFuQtyF420L
abokffuuLKcFulRFiK1ItJuhsoIGCMkCU6il3hOpjHIwBhGyMDISW+Xo7/
AtqvRMPYLGZMIWO9QMLwOaIaYTB2WSqKBF9uNaEg3hPVAREXV3eqB8IGAZN
1bqhUxj8ycFODEQGlbI1/
UJFjERAzrO9olMFumqRNS1OG4XR2i9HU+A1naiZnpiG9DfYsBL94OAi4LCiMD9
Mg1kpzmrFk0XQu8di1SO7xLSuyJ7hIGZUkrERiIxFTS4qIyTP3DySzjIST16JvrIcte
BgLdYMHNsX7osmif1lKO43w3u9Ckd9u/
FLdrkN7u4N5v4wcC2a5bFdAVW7XIbQAYg2ok0iTaeEAk02SKuIPOnHj3m7jKdd
wCNmQyEAMAE0ziuUSHBIks+1RH+Zb5ejv8AAtqvcYBJYTyVYqFYsCIAEGYKce5
wCr64cplNNmdgxeImyWFxDty/
rEEEBMAsEai1eG4XR2i9HU+A1najtsSh6uye42FDjZpnjDQLWv5IRwkuvDIg7jzo
M6EYcyvW162miDCWamIOIYf0cFbvEtK7Ph2zxjco/
sWjN040TE7DK6RegP0tVAMGEG8jvWasCMjgPcKAgAbGFetJzwDbpAtzETEKjWo
NxvjkKRGXK8pFsAtmFuwt2Fswt2EeaRKwxGuleE3ITV4OIeAVXlWh1uQmFYloXi
6T2F1oTswih7ACOSIz2CwGW5CHo0QdYABHKA4IjAOCnCrWby3I1APZkiTAvOh7
ahIItJ9AyyD4MRZ0EhbALZhbsIF/
JEBzB9kaEGwGHkgCAwUCm4fMWIQC9QdAcSWhOSGGb1QrLwbxyuEGiTS8tG
ZZjRC4yYlfLyy2YWzC3YWzCBi3bRzmh9kSo0gegIkYgzEG1PRu3MvpFoKAgpg7
nUqN6NoriAD6A4bU+gBpJuDGEhIYuqYgO8PNMvQDcShaRYCQ4KiLJYJNRbsIwD
KvJRZzPLyU3YW7CNaAFww4Dv3vKSA7sIooSDWGFHSSvdhbsIKKAiYUWLdhbsJ
78uPFEjPcmotmEGpJi8JmrWKiS3YWzCwmrlMjZQoHbMLYBbMLdhbsLdhbsIahH
gF/
vG0NbMIoGhckGRsBgEQAiYFPEcNwK3YRZeGyEwo4Q2rkQ5JlC1bMLPduyaxK9i
1wTC3YW7CCxHztgwGhcALdhBeCRJaU0Kf+4//
aAAwDAQACAAMAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAFCMThSThQBzHkJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAANHBjRyBAAEPCBPDJCAARXDAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAELAOIRTgAFGEMygCxA
AAAAAAQAkABvBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AEADU5CAAMPNaYgCxAAAAAAAAAAAAAAAAACEARBAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAEPAiUjqNI7gTggAAAAAAAAAAAAAAEMDJLJAAA
AABHBzLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMGcJvWwwSBgAAAAAA
AAAAAAAAAAAMNDASigAAAQRBIAAAAlACOAAAAAAAAAAAAAAAAAAAAAAA
AAAAAADihAAAAAAAAAAAAAAAAAAAAFLY6xRAANGPNzAhlhIAgJAAAA2CALA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAeBiBKEG+
xgDRAAAAAAAAAHB3OAAAAzjRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAEbrppRBSBgAAAAAAAAAAAAAAAAAARISuAAAAAJAuAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCM
6AyJAAAACDRCAAAAAvAyJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAEPpCaagBCKmAAAACqAgAAAAAGBAJAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyaOAA
AAQARNAAAAAgJFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAANCYaAAAAARDADAAAAAWBzAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxzDiAAAAAAAF
AJAAAAACuyCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAeFAAAAAAQhXAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJFDCBBaCxREBAAAA
AAABLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAARzCyAihBgwBiAAAAAAAAEiJAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANIGLPDAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAFHHMJgUT0AMufPuHHKMLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYDDQjT
TxiCHzSXICTFJAABDhBJAEFwwYDDMAP7kJQoAaRjzjYThAZDHGAFCJAz5DADzVl
YlKqE1UTAImpG/
czgw1BhRAfUaALCDAAWAyGCAuXLDjSvQqlDDTLvAoSDI0pAqABDFXAWABCAr
ALQhJfsYApDZhsTripAjLALpABQzA/
UTXAjGJMDADFHA2XLDDQCWoXAhGr2AooAopBAqABSxHBijEAArArAniCTCfDn
gMCAWgpRQjALpABRhA5UtQKIEONIAAxVPgFrXLRNorBjZctCOhCAopAAqABCLr
GA+BOArAlGLZziiqjEqRAKiAPCCWAmoAGBDCrOhnPdCAARKCBTqHwDVrCCYhj
HQjHPGahUqDFCjAKDgCzVxOzCvKCCqJenQBqZTSKpEAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/
8QALREBAAECAwcEAwEBAQEBAAAAAQARMSFB0VFhcYGRobEQweHwIFDxQD
BgcJD/2gAIAQMBAT8Q/UB1QS/jz4luq8tYes6S0A5V8y+rlhLg9XWKt/
S6hzdZalzx8y0TsmBl7jtpCKBN3720ZzJt3wqwl56EdbOKstIOB/
ZfjrpSKuL+F4XkzZPjQ94i6HP4hnHvHKPRgLI8/
iXRvDGK0FH0rRo7phwo256MErU3Z9P2tqzmTbrgPxD33oaxto6uk2T4AS87zfU
FaEvh0ZsvxSOsHVmmjWX6rz0lpHPHzLQHI/
4FUIm+Y7ibrdJieBuv0iI0YYWjK1OvrrBBUt+tt+cybdcB+IG+8aGsfaOrNk+FCXq
eK+l1HgOkta8eZeAOekfbOS6Q116GsuieKy2jprBaCn+IPDjtL/
eM2q2j32ePRirHY0+0hlqn6YqrDiy6F4Yy+T2ibZxq6TZLgEbh6jLeulPMuAOKfM
bZOrM2ciXKrz0lpHOr7y0pyNP8NszmTInfSfeOktI8eYVVV4fklYFQY7NNIiqMyq5
mTKuuJmfoLLnOCaVcAy77j/I2b0e6xy1z0IhUuj7sFdekuAvOWEefeWFORp/
jtmcyWmrgPxDX3ihrHWDqzZvhQl+nm/ijVUZhio36xGrFv1/
Ie358dYnOiQE1GYLwFz7l/toKVllV4q+8s6cjSBT/
AC4yRxSbU8KsDfehrE2zq6TZnhQl6nivqC2l8OjNl+KR9g6vtD0jVgrq8/iO/
wCvxGXzo6TFmdj31lFKO/0p/
uhw0glqn444wFn7lERUftoFeiQOx58NP19njiywVcD+TVDpMnHLWXU66UgvAX
qyzrpNheKRFwc6+0fQNWAuPQm2nFfiWkdIJQU/
44yBKzjGzPltiI0ZWrhmZMqy4mZ+NDXPMmTXJ2xEJRINOFtbfn9UqFZrdDWG13
GfMPxM0dPmDunppMyPNlkEsKcjSW/xjW/PjrEx0SAmo/
bys8AufcvxTlUZfht7OMtKlG4OuvX92tLywnWviszU8tYus6RVwDp8wrfN3zKkK+
fxxxgLP3KUDY+eEOvRJVjA5bd5+KIKjK7jbGz49Fpfcdnx4ggqftqCtK8JZPzQ8My
NOCnzMSF4qxdnozNnQlyq89CA/N1hSujsbazYY+8yVWYC59y/
Gl7UlL4jJ+5wElEhJg+fzu/KvUuJpp0iJeOXPH43dIYSo/
vqFwuTshJslnJ+7JQjgLnufcPxWnUYvf8AHjrBRqQaX3Hbx3+fyyl7X53xwFElMOK
uaQG1R/eWUOKS7jzGLUcGYKtpUpt+0r+SAox6iwzNnDT0tLwfZ16/
lUFsjrujsqMukMzb8yuL44/u8YF5GkuQ6Rf+9ZhYPX/
hWMLYydGI0KJET4luHx+VH3BzJk1ycmVlfMza5mz/
AMMCpemPtA0U2P5pyqMaox29nGBP67paQf3aheWN6msuA+8ptJyYjary+Y5T
7QPk+I5Y6sXsO+sRZDlEz1WKDp2D5/4OAqM3CMZDJ8lf3SVlhekWyfecVyd9Yr
83WfUsdg9Wcbr8Ti9fib56/
Edu7aRDEO1x+P8AkdjV8YRUM3wf+KRunUidz1NYlcdSXAfeUNcy7pBw4syCv3i
0nwL5iln5fMDbsQNvpymTXfSKW7If6URkn1ui309o3j0ukXuybggtfoMr5+jpN/
6Ok3zozeujFsja4fMwtirv3L/
82z5GpXObj3m4946gU1zm495uPebj3igBhXOPaODvhsqYvaOaVpNx7xCCqB7a
zce8VQZgDjsHvslRg05xjmGWsEFT13Yi9Bm495uvVjlKW8x+YYWo+gyBrW8VJ
B47IMA121gMhWu3KDwa7azce83HvAWKWcvTBMWwfcIhwe8b5gYmsAVLRGR
pTbAwClLV9CicFM4h0qjSmM3HvNx7zce8LQFFc9+k3HvGVKVPQABwrnNx7yq
wKcWZ9C5mehu5eYVcT1YYWGKbkL0m494Jw8cXas3HvEQLgxCdaX4Tc+rD+I
8dlSCTFeMYmacYUwP6Y7H3mENW3CKwVXxDZivG8EiqZTce8EnPznKChVfENB
V4ztvdlSwqFZX/
AB8xMc00tbvKv4+ZuxU6RLbjS0S+4UtO8fLLHFnZe56dme3pvZgHGIEqsH1Ry
pXrPuhjKrvPc9/
Xt3w+ig01NnzOjZyZXRqfPp5HtPL8M7R8ztnxO0fMp1dL9pSiumNvRM+odUjhK
rAtUcqV6z6IY9SYXPcnbHidseX0798sr9dNFJX/
AB8+jYDru+ZVWKpspk+nae76WOB7ytYVCu2A8QtshmzaPB9LDxfaVBXKYvvg
5ZTtHw+n18PTtiI7ThLwA0m+PsxNI4mSM3sLDSze7F7QHeWktABSU0sYHAgA
YIy0AlZUqGYe5KSvE95TyxgcCUBzMD3fadt7sXqw7pvXVjuVcfL6dw+WXOL7en
ePlgtEObrElFPN19OzPb0TR+2IBnb6bZKp2jINsYuU2U1n1DWUBYJ4Pp2GsJOYdY
kc2nk9PI9p5fhnaPmds+J2j5lWNGVU04wjhHZ47CJRyr7QGLVPQtqq+IyjaTtjxO2
PPp375Zd4vt6+f5Z2T4fTtPd9LHA94jGqpSG3QXgmyavAi0mxhcOGUwVxGr9c
pRFbBpO1fD6fTw9O2PShC3kfErZk7nxCDbVgJtqeZSHJ3fiVl28n4lNb2OLN7z/
e0q6WA+3tKu7+D8yoUsxNOcqJo/
SZpEB2idt7sQWClM9tZ9p8QuuYZHp3D5Zc4vt6d4+WCArVhWxD3PTsj29GC5
Q9sYDvGMx6GxgnhN+
+Ps3llCoKNM903bqRJcD3egKxDWIlp3Y5MjF5fMxLImGOEaCpV3io2C9vmdo+Z
2z4naPmYHBgb2ir16KV5el7D4GHjxBN4xgOobGADUb4g5cWkfJE7nxByRwY4q
mQRVK5xyN3Hr6+f5Z2T4fTtPd9LHA94jGihWL7pDVTFjXbu5TDl3A5/
HpXJTZ9IiBcgIM14fT6eHoDAQJukc35nL6wVdIYLrEQyf5FV1lIN3F5/
Eppli8X4lWdGJDUpMWWcHnbv6WyK/
MYu5Q6+glZwyHazf8Ao6Tf+jpHFjDMTP0Y47uTt4RUCmLfl6NSu7k7XdBYKNW
8ARVp7k3vo6QAFWh7Tf8Ao6QYKwKCps2cIpRfR0jWRtftYK/r6hRNj4Zv/R0m/
wDR0jeQ2uHzLuVu7Y2WFdkRo7yYiXnYlUZwbG+F1Ao5OyVRnBsLnN/6Ok3/
AKOkRxobXS8I2CVwMNmmkRovR0j2RtftZ1Eu2N/
4sSxqNpjBlB9HSAiobM3QgU9N/wCjpAEUcfLDUDY+Gb/
0dIxhRp7voLUcCw745MYZjti0P3CHX1NzpHK2gbG7fLKKCAMcSbqNbSuFBt0jKo
oNMHMd23zN/wCjpLCx0zf+jpN/6Ok3/
o6QIEo0IKMlyg58pTgUwK77yuUrg07RIYZ1Gxyi0KxQPF2OkZ8cuZkcYQxjSpxM
Zv8A0dIBVGmPGKqpwdhuhVUWuU2//Iv/
xAAiEQADAQEAAgMBAQEBAQAAAAAAAREQMSAhQVBRMEBgcJD/
2gAIAQIBAT8Q+pqIxRWV+FZRH39RGKK/GMjK0oj8EE79rURiiivwjKKxBF/
JoNtX6+vqIKK/CMrEEEX+NpMamJz6iojFFbIyisQREX+Kogq/g/
xicE79BUVFKI8QQRf5KiMUUV+SZCR+TVxOCd/3Qi/
z1EYrxjKKxBBBWqDvi1RqYnfsIxRXkZRWIIIv5v8AGJwTvi1RqYq+s9keIIIiL/
I1cTgnfJqYv195URisd8WqNTE75NYv19xXinpBAx7QnfFqjUxO+T/
GJz79qntCd8mpif75NXE599UNpi75v8Yv15NUkE4W/d+iIgSS/
g6xvjyao1BOCd/4d1/BqCc+9qKiCCNKKxJ/F+jj7uIiIiCCCCCCBJL+T9s4/
wCMqKhhezn31KV/hWVlZRRWez2RkZGRkZGJT/
5ttzRPwCdwnRuYbi03ML+QNwVDcFQ3NFWNpeA4YndX1fAJ3C943NE7lniX1jo/
WG4KmOBO4Xsbgq10bgmZ0JXCU0lRKDODjOMbmmoN8a+YqGoN8a6x1hK6b
i01Bvg60xKrSpCUxczoSo4F3G+Mb0PmfGLmP0dQvQzi1uvUjG+BusT5OsrFzH
04x5c40u6XRtIg6sXDgXdLuOtVihwLul060zjeN4zoTg3RdxusaDex8z4xc8B9F3
CDcQunRwNVYvedCnyehTH04xiXoaUzjEqxNMbonsabZRIsTUG6dFQ1OsdY6P
WdwmhqdHQnGVLFzeNXM6EqP1huLK86sXMTUKh+0L0L2P0P2JRDfGWnWPuk
9kZHpp04xpnA+EY+EeP8EZQlNfCMjIxKDTIxKCCexCMjKF6GIyhKDVGmiMWox
cyMXM6OhKez2E9417FwjFwjIyMXBr2J8iCXvHWcD9ojENO/+Rv/
xAAuEAEAAgAEBAYCAgMBAQEAAAABABEQITFRQWGh8CBxgZGxwTDRYPFAU
OFwgLD/2gAIAQEAAT8Q/
i6vf35xih1EP3kyF7v5iGAd2+UCddV+WNUB4ETnFP0EyFlVmrzcUEoUhTtHj2IO
9C5UDjSv5pKg598SjKPJo94BLPwD3VPSCOn/
AIRzU0qlT0NXDrOKPb6eEho0Ife4fkfj8BUQC3ib7Rpt2tA9ic6PM/
4ArFIRXvLRZv8Ap6oZRPTS+7ygkUI6J/
P+bZzOsZKnYH84oK1Lh1EyjnJfAyl8FIke7EFecBBO0O5tir/
lFDP9a6RRhdbF+yGrmxm9T+bpARr9ix/
kkz0seV7QoPuwd2Ev4VLQC2BhVNQ3n2pOem3XX8pNL0GWKV5FF4aNxrIxl20
9a7ySKJreV8YECq0+yYPQSBIGDT+mKa9ryhFQAeuzvJl9mu+yvyboGT3EpzWk
Cs1fd64REa8Qr+4izJmyrWleTWBUDZpOSfy51oIUh0gp6XczQGNHviHUxuBAon
iD0npPh/
aZZsipFbrxsfyaIF2p9p6AdPvSGkLiFYBYpwbNeyu4qjnAg+lITm+zxzTSEVHsfnA
oLGU6PmPoTH1fQoXrkf10OpqNR8JG97c83F3hytRdb+T2rfSqcL0V49LjSl7jSCU
zsH7i3AspvSJLSwXtqBeyxVbX42mzcsPYjb5l+mm98zPPay1bFU61PN7/AJwh/
iZWXWG9wu6HGygwPQ/
ylDbDV6IOQsyr3tU1cVaXo+ARKQ0YszoizL6wYtXbD/
H2AAaq1AFULQKdZkuwv1MAdgkfccHDdqTQK2kvrbbB1fxC3TQsZ5aCiWJr3im
9u7YexEE2G37GbmuUH0I5uW+XikO5X6gYhaAUf6N3XlUnlmZPSZSXLhD5GW
SDgj4CjRm2/SwHWxezNk/jChqwO/
Pc9rgVuNifEtSTQQ+9zJgN09I65tiEst1qBeyxVbXjBY7XejkR8U2/
nJV1O5P2gtod1bABZHd5zOXDcfFSvbpx/cQeWaHxpKD/AFjRrSi16/
EmXWS68p4vA848l0bJxGMhmRyfNP4kxOdX5FiVc+L0sBQ5yn3bi5BNQ+iBCjQ
fq2xVzHhUi3afEd/
ebESN9ECKRNeP7SBryOQpZDgQdWMps1BD7E1xub5TDDJ9K/1AAA4B/
tV+CAAeCMfPGa939I/DErkTgjiLZ1WBojBzmGg/
Xyfwt2RapRG+Qr2qzMk2cD6QSjDgb9kAY2qVhav9qpOaglXXEFajlw1HoS7d0+
mEQHgIQacSP0EXYjb5FFPY3H4kbeir8/AoK4hfiDUXyD/
TqGrDhPEQ9FiFLbfFkqShsV94FfK6P1G7zpPCLyfuSAJ2slcbY/
YSpFnCD2OcAbQn5iGAsSuXu840cq+SPEcTKotiZIwtuOPc7fnAIqx/
gnMdfzLBmiaqXSX3ACgfe5UucBT0hpGEXzYz8izra/
wnNyaiCrtgVLb5yx7EZvYyHWoN23cYD7rOfSDXLQlfVmoDIA9ammfkP9TQibqo
EnjW19rm2FX6mE0/F5cipvTSX2VeEzLDNmHtHbbufgCkVNMbeoE4ydN0NI7/
AMkOXJ94BFWP5E5gqLP+zlHvFt9dDwZjVM65bvIOiAAOiJ/
vUFUAREajW3tcT4GxHvQjjgu/
WLKVtNevTc5Wx+1cUCfzvRF+258rKizr+9jY1GoAfaDRR/
RscsLrviclGfCH+s5vKVEouull7XGUY4frYIgDiZ0uCl3BDkYVEf8AEJfVOxt/
w9Sk9lPLjFLlI1n7bBHT8Y/8wOW+ODHan6WTts8Bks0arfdOUvKAaw/
3SSnePPkImRVTP5+ZaUbr0MVGLN2+aYfMdGydJ0FY+P8AXqGrAL7S82Ohpa/
SIIETQJ1uWgo4qzIdsw377Y82Kv5HqR2dleh8Efckqq8+I0VXHO/
E7w+o9TDTUQZQ5E7eGM4iNC3iqCwrR86cUkXJduB+OiIArEm+CQfQ+ABZw7
H4YyYDAeYDg/yhcG6hHWF7vdKXjYQ0aT6qUJ/HumKwrND+bRj0hA9iO23c/
EBWoo+8DQh0Bp60pFiq3N+MAlntrCgnj+3wEtOc+RLBd0BfW4IGnD4E8aDqQ
3jZI6Qw9Z6f2MXT3b62omng4+UDQ7HEmsvy/
YT8a3dWIHUSPZ0c6527l8CMXQ8ozA1QQX5BP5FzHGT1ZchrUFRam5mHW5b
ULiJH0ebM3Ky2vyv4AVoTkI1noQA9g+CMgG2SGd9VBAOcdxawSbePxRXQkX+
qN2hv8ESnbCCv8HWafZgM8mkbY8ch97wAZMqxaIkLyNsy/
XyfjQRHSUP5+XnwHlHPKlcicEx0p6HzAcRizKVc0+X+OFQRqF6sdRxpNRFqq3Q
dblkLNFGDqLti+MfJer118Nfmul7ABHSlcZ3kV3WBOcU+JFr5+TrUuO2PWAZvQ3
0gVs0KLqsBG+iI9idGw/yzZCpHMSc/M0+W/
wAols6pExFYpBsY8gXEPgecNqIWJ+MYxL4PpPOPLJXFGN/
FhUkZkLZD+LK3VElBC0Kf+QvAHgyp95uXRxIfZaRE7Ppl62HVeYeKDkfMszXY2
wq0/N+LNeXliPHeR9x27hsMqKW/6CUAHl+UzkGo/wBQMAnAz/
TKgvHpW78ka/
rZ7cPgXyg515+8hZ1YgdEfxtgqhZvthvnMHALxMQJMqRaIkODgXl+vk/
iZhwG6I8gHzMpRa+yUUWPOL/
qO2nzsctTts45aW78ohQRoqV0h9eWH+xL9niy3xwYoUzQnbZ4Do5o1q+4coC
Vt8A/
jP2EozmFLWtcaDoqDYkGo8mTX8TzgAKsf504UBqsDvltj5ibajs6ldFvQhhC0sfST
ShMVPU/HXGIViQGska/nTn4CiZy9HxsGp+4Hijgn4wR/
pqXBOCRdk0HwA0GhnnI3c8GKa1AdEf5ojJdQg9WaywX9AypLaUE9YpzeCjpRG
gLf9c2x/LCVfAkHNC/mrJlRFsmfn+8MiFYmYn4mV+sQOok1aDnnP38ngKJSaN/
UBsyTudDf8ahDHgvBGZn46z9/
gttXJ1526Dgovgfy9eaFr86wY23n3UlzukX7Q4FNlUUZumr8q4DKDA+h6HxBBn
miPvSZG3cnyYYLk6Q3OJ++XeYK/
uUHvodbSaudVrzNzBoQrPv2SXdFkLiP4tZqQY+XPgcTipKaiONJtMn9KQOEII9Zy
/GpEpSOYkoM+z4v26RyKqkckTEy93d/4GDYDIOa4o4J/
LCDNM6e+YTWwIkexucZFrl1ksYqxz79SZ04cv4EUsbzEU59w/
KABT99UFog8dLSbC76gxvlMD/
gODB7okelDBFvgPxitsQ+s5yh2T5JuOLco1NDxDiMKlzVZvt/
ICsh0fmbc0fyKvIYkLZNOz4gn7+4UN/54nI1kDZiuYjU/
swgV7tFUWfSa4eInBPxpCJa9bO5yi3lrntwY34CNSMVzZyB+TbDlzycpxIrl9HQ8
E4ji1gqPQQg44WrX2c/
54CAsdSVPJeVczY8onXFSUaiMBMvLcg32QLUcy64oOCfjcmLRy3xwYmVXZV9OI
WzqsDRGFUQAy/Xy/
kWmC1fMERWa48MjuwaJxDiMLredIdf+eiILkJXznnE0PSGjdcSLBbuByX+QYqS2
BABU8R9jEmJ4nRE4kZyhZefB/IH9mjquAeCQmsrf/
EcQWgriEoAKDSvjz8v5uqDGqPymS7aM9i44EexVB225g6rGqq3f9Ue7sRXrgRI
MQgs8ENUfynCMiFiRM6Zu1fSORVUjkiYs7vJoTbnQBFCOj+N6hrIGyTOBvWfvxh
0xUlGiJNFG5dydn828oENe87Q7zEbJd/sLHrN2o/
UuHzaKi57t6y69wQYBN21nvji/nM5c15u3NEygrymNq286+D/
ACKRKUjmJOYFxH4HlHJotI5I4CsVYmoUy4h93OACrHR/
8LyOrA8z5YXXmtXfPEwaYRkSBsSWVE9PDK6j8om0cB5u3NEegrimLiVrM+Tu54
GZC1gdEf8AwuyEkags9GqiIph8bhEfmRhRsw+0iSQ0eoOJiFknFXTzP/
C3dnrhkDzYq14sEw0lvIHw/nH6kU/mFENgLlU+HcwFEVRLHUjutflP/
AkagQCx9xJbg7F+4d15+GHKcb/
gJnw+c+oY5ruZsT7LsXzMwL2oh33YEyFPus0WIu7xfVv/
AAC1DujJ6c4lCTYprROThW/Fj5P+bKGrFwY1fnGc8IK/
DB1E7Go1Becl0V+lyKIZuL6htc9+NhVQgrjvf1SyvsdkRe/
RSO35nflhtee7+BzyhfKvAJXbWHtbfm/whSHqDZdKwedXoqt/
NSZWvYvclpmfCcP2vfctPWT9ReNbg/
U+UVy+slkKV5zf3A2YrLdOcFZznNwA23mE1i/
Ily2tRh4zRiR4GRmkfKRAclDCvH6P2SBsJo59F/hnAc3+Sj6w/wCJJt/
46oFsIhWc0dR9cFpxzyVf/HSEsZAfUO/G+AxjrRl9n/
xNL3Aw32Ifcsso1v8AfA7G5/
ujVWeVp27BtFMevH1NSORfyOD1WBQQiIhz4Yq1VnVwTMC0YNDAhGoMgP8Aw
FOm+SQqyeytnOmL/
bMoS9jKd8M7Q5RzyZrF8h8wknrR+4LXeT+pT1XIPqZLIDqnSd/
j5rKItMgr5JxlmG57H1db9xe3d1Y9bcz8QTmbqE7T94lBLxf50YC/
DoAUsh5wYSrk9cbAGEwJR5JNgk5D8ItbNwj0bzGYze9GA9qOa8AAAD3cPnh6Ku
3yi7h+5359zvT7n9Kn9Kn9Kn9Kn9Kn9Kn9Kn9Kj1HQTuz7nZP3HapOf78PTfev
niAA3P8AV6HG6ixBeWiClLQKA/8AzVjLGJOYrNZ3D9ztn7nbP3O2fuds/
cR17nnB7igAudM2dw/c7Z+52z9zun7nbP3O4fudw/
ctbtU1GmkjPbBijUc53D9yxpTKbssaAGCnYFncP3EltXbxgwjWjRGVehRK2LnbP3
Ete55w4RrDRHwJNRgw9LuU4Hmw+I9KNX4V/C5uTNA1VnbP3O2fud4/
cGUI9vGPAjV+FfGgrwGjtrO2fuNDq8YtLqM7AhQBqs7h+53D9yutnp2Go0FClA
M1YaTuec7Z+52z9ztn7nbP3Brvokeg+J1AtRA9Lnu8mviXw+rpH2HwU/
NVbYLOwfudw/cLEUQbExY8lebgLO4fuFHNCsjVoYuvyVBqlzuH7nbP3O6fud0/
c7x+52z9xEtI7eMaiNryK3m2qCljHbxncP3Ku2aFss8GnCTfMLO4fuds/
c7Z+52z9zKXDgz7D4i2bRgc1nbP3C+lRFNAz8GWOAQbrOwfudw/
ctKNU0MskmTAwYbrO2fudo/ca4aCojTmY0qLzFCyxZ3D9wT1ktToGcAqqCdw/
c7h+48CUGauZKQA1tjdZ3D9wSxHbxh6iiGiMbYclQ1HOds/
cSRdPjyDGyBQgbJc7h+5aXapqbJhb1OoZetXO0fudw/
cFRSiB4iYmSQUyHks7Z+53z9+ND1J+JHbtG7w877nxdv2SmZgdPzhoe2mFGZ
yZ3YCJsirQPfY1eurY4Pre2S9SKXfKJhBlesHjVP238JM7bHofMizS1ygiB4ayewHD
wavlO1bsOk/
HZONDovsrJGdZwLb8uIotHPbI4sXruAlNUq6ti4MzW2Q8kmjAeSO9kBbPJ2cOmY
RogoTh8XHvOT8T+DRO9bsagn4WxLYexiPUjlWMw+sgH5M2Joj4BFqB93r8YPw
KHUDYyregfoj3HHsW5+IqQIoRMpec3B6Qi7JmRAxB+1aHuMzqEwNdzIjyv8AkC
p299fnBjEnImVhhzmZD3qMVZXiVtwoXfnb7YNbGxuhke8bfukpbgd1lPfI6qwN6
guatHVIiNYKF7TmzDr84FrSLgFssd9gF6BgQrQ4DwMhLvfhH94n94nOGcUDMP7
xP7zEWgQwdouxH95n95gIUeLLvO7DoOKg3N88Xb9kpnYfT853jZM7rtGraDms
a6uj8riIlqMUfhnofQcoBEtFj4u578R19aJVPSDFUYgesZUMwIufGXMcsdadq3YdJ
+C8REH4m0pg+k7V+o93jq9nBBmXCSbGCZxvzBfmXpdXi1oHNjjLXNOCGNC7
1ihMbgVoCA+EFmI5iYoGidu249lyYvsqhf3Gf2HG1yvmT+8ShOqR2nZbGgZ42b
E2dukOvGhn9d3s1r4EAste/PFwExegnvWPetzHq/
GpAgLbzl58ORsUmGjSR6p1iWqsnJ+28Mufzsjm6nsKDMGj9vFINRJ1rvlgCz7d6l
PTLB/
uNl645Hi+6oIBMGsEPDYf3oMflA3NP5A1M5YPXAPmq6EIBT79e2ngQqKK7JL+rf
qf1b9T+vfqcnogSf1Sf1iEpLLPJgHm6Nk/rE/
rEDB2hRMncZ8Oi4h735Yu17ZTMw+n5zve2AnqicdC4PxPzBZoCGb4IXsOhAgx
S8J5VKjPxYeZ4adUGf2+PF3Pfir6mUsxmLSYT2jVnZaIcEHc0GkcLJ/
l5KHHWnYN+HS/
guHHCmiG3Km0BjvkBWptiVVGdmsti0D7HBwYmfKuQEGjYg5RYHSKWhPKoXIj5
pS35Y5E2LdZb9sTDR4NXZcmL3RSNE2f1iZhotwTsO+F46a4eDP6JFtX9H6hsND
GqBnjZsiKovJugDJR4J7Q9DO9TAhyHzwcWccHNmKtVY2s2zqotOJUf4+bWAAqx
w71uY9X4EQ7Nu8Gcb8nTY9MAetxFnI+QjP7AjudhpIgfq9LJXztIFXRAVCNKY8z9
5AowDCp8+k/VgBphQFlH354PJFJSMPqGZX6wDMu16oM/
SyiLQWNSDUMI8mcu/
UqWwaQd94LSwjhH8NDZAo0MQwwo6gCgjw8vFMNp4Dsm/
DPZMSdjjlyc+NQ3F2vbKZmHNEVdjllzizz/
iMBKmbjAt2h0BSdZqO+9BhQ87aPTxe87/
F3EQPnhbhxlPyXMdadt3YdL+C8RIDVaWqrAn9z/
ccA0mmb0YNzB5eDZAAKIyOb8kDgegiO/
wC5xNEorREpJ0ydirB2WW9UcTDR4NXZcnhP0DOw74d93eL9Qq8bNhBHKo28
4QYLTJ6y/
wCXSjrnD0L5QOLJ3UOyywlfLX2mkdlBhzvwOH1RMr9Yd63Mer8CId+3eDVzb2v
098LWIbZLJpY2NqWnvH01287o45O7lw1kTsavKz6jdWc5q8OndfR64ZOCu3OP
SKtVY2sOlTOxOb0IIoUPccMvq5Oxli2aJ2cC0HcU4HTgaQTqSmgJQo0vzC/
Ah7ju8HdtniA75v8AwO17ZTMw+si7Hhg6o1PNwvOcD5eA1lJe1MPmQwoQdrY
VBukOPgllPCZpRWug2ned/il/Noi4MrbH1fKMRofk4dL+S8cIBhICnk/
T0h5AiixNyN/9t4aTM+nwelT70AfFSoAujcTuuTAq22J0DOw74d93eKxQM/
GzZUllOe31uWAHm3eAFsXpVuQ5H2wqo8lOjoQnFcy8j4rAqC+FL2vDsW5j1fgV
Ls27wGVNjsKhj1zlpofXBLaA9pvH/EE7ubEACTP7uhMgpTy/
oMKXbTmqhA1zloq8FpZw8+Qwzpgb0XSWwvcLn1OGoluxoHqQSQqcQswobzX
x/YMoZ6tEdRMc0RB2Np4iG2WjDbbznb/3O8PuEKVarjTX8RBLvm/
DP1dyyUV7TpFP3v1EQtRQ2OLte2UzsPp+c7/
tjIAxuJmcFldttl36MNKIWJgsJZW42XqNS9qR3Vtwpshd+Gg62HYd/
hlrucigC1gItZGoGT7GGvKz5FMSzsw2Auc7Z7uDDdPZDwfHRvAcDLHKsXJ2/
wDcV/
wRaaAVuEjbRNkwV4SriF9NzK+8tisB8hpFMA8UDMRwHa0XxQyPVjsepwthSN8
4mdBntOHF2xVDu6Rk/GCzkOoAtZrI+gWGHAex53/
WPQM7Lvh3Hd4rFQz8TNrwjcAOjbMDEgagGgYUvo9N1+3ziTWCbBW8QRKGcx
SZrhqhLHtPUhCQU4hYzsW5j1fgRDs27w0enxX98HFhzLy53gAW6WxtuuERoCJ6
dbUmki8Ax1A2MQzB9GYHtgN009jgnbRfoAtYvyrJwcj7YK8zC8hQZJHMdtgVvzx
o38wNT9rxNIsH0eBK0o7q0Q+VV3Ne54kKkhBUNfPnMu7979zn+9+5l3fvfuOW
9c4bn4bAHfN+HTcRMzf8sXa9srmYbT852TZGsWx1Jq+j84k30cvYI6IHZmii+tz
OodfW7vFwGj6xLNASkKofnFByUaWqVxn9x+s/
uP1n9x+szgWsGWaqrzned+J2AjJUDflEjw3R1rDgI3mHGXEKJdR+2vpE6U3WiZ
aTfvd10w/qZUuUttcQJoA8gHx+DxwQD2LCrPUmT2HtLjNrLXimNrbVd1wN/
kPZis74NV04geGsgds9YSlhlkL1mRhq2VuYOwMPZVyAnGnL7x6QPiprwRk+jUW
04/BKcBwECiCcTYQZCZ5o9bilVzuSfGJI9THhldN49AzsO+Hcd3izUy/
GzY8nlSublCRZcj9PA8wnIkGxIcQIDgDodcK23qL6KxtLYlbrF7n7XO6bnj6kHOra1
apcyL6n9z+y/uf2f9xUUI1LVlKeetz1LIiNYgzPR88j26x6cv3AyOinwVn/
ADFD0KwMd9A3V7fONpbGss9+TN49+2Ydo2zR8vxYe07fhsZd134dFxUGd/
yxds2Ym6fnOybI0FglgckYvQrRanj5eEyCloMyxNNgLMvjnc9/
jNyKpKOBALiAUAaBMmz63b4jwJ0K2A4rkTT+q7gzfVv8hDggbFS0EK3BaoBXpn
zDZBUjmJGvo2JXwwVAWR4VfXNo/
DGhstym3nv4hsLdMp1GF5flQBQGPRM7Dvh3nd4v1Azxs26PC0SQGvCOY5y5v
C2PAckwdplc1088G3elyCxXnLC7zmrwOSFRS3/jO/vqd9fWLIZ7PNNeXOeq/
Jj134FI7LuYfY8r9MVRqOeaH2+Ywhkjiuh629sVpc8pnwJBQFGAiAXueAw+xN9JC
KQAOEek78+oRBZ0ZOfWOHJoCqWRvRyvwUzPRvDv2zDtWyaPliD5DWIT68YPc
5zmtdUIDMxS/wD1qoDBQUamuqPBRYcCmSOCgjZpazOKvJasWk/
oSE9yrUAgJryfxyOCr4yPkarggswRZoAB4I6wVttFY82sAmWwWBbqaPxYX7mZe
B4udP8AA+0xtUQPADnFAA9kfXuqbPS8ziSlpcpPEWgKAihs4oWKsmsMR89Tkxs
s6pvjFxxUfZnAnHA83IdDBYBo6owJ/Qk/
oScb492mKkEHVGB7vh57nBwA9EQEuqbPS8zPCVq9PFNQB7A6iQT+aRscjWBT
rYL7YZlid9n6NsSTXUK9PwIJTBZZy9bnwekdpHQ69o1ioghOmPwjE9JE1+WZUA
xA8FsjZiTAsDggG2uQxKgPnVAD3cecradBbTvp4Fkg6iiPxOxMOagw6szLCxrSsH
9xjzhfa2tzh5485US3ERM/
rFBhzrla04OSxFUySyAE8j1Z+WPPVfx6iyHzNZwELurp4we5znFntWzBcsHE81T
UdcOZfMTUDbDVEA0AhNAkR4jFamjqc4MOJBsrLDNffDX6PSBkPOM3/
OIrw4LWbIWvMemPmbuD/IY846BPniPRwLiy6U1MOaDX3AjS/wDuP//Z"
alt="EDR Logo"/>

</div>

<!-- Identity Text -->

<div class="login-brand-text">

<div class="login-brand-name">Ethio-Djibouti
Railway<br><span>Share Company</span></div>

<div class="login-brand-div">Engineering Construction


Department</div>
<div class="login-badges-row">

<span class="login-sys-badge">📊 Project Management


Dashboard</span>

<span class="login-sys-badge pmo">PMO · EDR</span>

</div>

</div>

</div>

<div class="login-brand-stripe"></div>

</div><!-- /brand-panel -->

<!-- ═══ LOGIN FORM ═══ -->

<div class="login-form-body">

<!-- ── STEP 1: Role Selection ── -->

<div class="login-step-label">Select Your Role</div>

<div class="role-cards">

<!-- Chief Admin card — highest authority -->

<div class="role-card chief-admin-card" id="card-chief_admin"


onclick="selectRole('chief_admin')">

<div class="rc-icon">👑</div>

<div class="rc-name">Chief Admin</div>

<div class="rc-desc">System Administrator</div>

</div>

<!-- Admin card — PMO full access -->


<div class="role-card admin-card" id="card-admin"
onclick="selectRole('admin')">

<div class="rc-icon"></div>

<div class="rc-name">Admin</div>

<div class="rc-desc">Project Management Office (PMO)</div>

</div>

<!-- Guest card — read-only for Project Managers -->

<div class="role-card guest-card" id="card-guest"


onclick="selectRole('guest')">

<div class="rc-icon"></div>

<div class="rc-name">Guest</div>

<div class="rc-desc">Project Manager / Guest User</div>

</div>

</div><!-- /role-cards -->

<!-- ── STEP 2: Password entry (shown after role selection) ── -->

<div class="pw-section" id="pw-section">

<span class="pw-role-badge" id="pw-role-badge"> Admin


(PMO)</span>

<label class="pw-label" for="login-pass">PASSWORD</label>

<div class="pw-input-wrap">

<input type="password" id="login-pass" placeholder="Enter


password…" autocomplete="current-password"/>

<button class="pw-toggle" type="button"


onclick="togglePwVisibility()" id="pw-toggle-btn"
title="Show/Hide">👁</button>

</div>
</div>

<!-- Sign-in button (disabled until a role is chosen) -->

<button class="login-btn" id="login-btn" onclick="doLogin()" disabled>🔐


Sign In</button>

<!-- Error message -->

<div class="login-err" id="login-err">❌ Incorrect password. Please try


again.</div>

</div><!-- /login-form-body -->

</div><!-- /login-box -->

</div><!-- /login-overlay -->

<!--
═══════════════════════════════════════════════════════
════════
ROLE STATUS BAR — shown after login, colour-coded by role

Admin: dark green bar | Guest: teal bar

═══════════════════════════════════════════════════════
════════ -->

<div class="admin-bar" id="admin-bar">

<!-- Role badge (updated dynamically by JS) -->

<span class="admin-badge" id="role-badge-label">ADMIN MODE</span>

<!-- Logged-in user info -->

<span id="admin-user-label" style="color:#ccc;font-size:10px"></span>

<span style="color:#555">·</span>
<!-- Access level description (updated dynamically) -->

<span id="access-level-label" style="font-weight:700;font-


size:10px;color:#f39c12">Full edit access enabled</span>

<span style="flex:1"></span>

<!-- Edit Mode toggle: Admin-only; hidden for Guest -->

<button onclick="toggleEditMode()" id="edit-toggle-btn"

style="background:#e74c3c;color:#fff;border:none;border-radius:3px;

padding:3px 10px;cursor:pointer;font-size:10px;font-
weight:700;display:none">

✏ Edit Mode: OFF

</button>

<!-- Logout button — always visible -->

<button onclick="doLogout()"

style="background:#555;color:#fff;border:none;border-radius:3px;

padding:3px 10px;cursor:pointer;font-size:10px;font-weight:700">

⏻ Logout

</button>

</div>

<!-- HEADER -->

<div class="hdr" id="main-hdr" style="display:none">

<div class="hdr-logo">

<img
src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAQDA
wQDAwQEAwQFBAQFBgoHBgYGBg0JCggKDw0QEA8NDw4RExgUERIXEg4PFR
wVFxkZGxsbEBQdHx0aHxgaGxr/
2wBDAQQFBQYFBgwHBwwaEQ8RGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaG
hoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhr/
wgARCAImBQADASIAAhEBAxEB/
8QAHAABAAICAwEAAAAAAAAAAAAAAAcIBQYBAwQC/
8QAGgEBAAIDAQAAAAAAAAAAAAAAAAECAwQFBv/
aAAwDAQACEAMQAAABn8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAB841XKNRwkYZJQ1hWCf/NW/
GRgsXhINMEr4XQkYdn8GHMP38CjjkevKYAtuecjAyzls9Zk7Nrea17lO5MTWdlnd
5C4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAB5MIx7Mj3Bxgl5A2EYLHYiuXXGCdcJEpg3/
AAmtow+ryjCAAPo+WTzC+qJFzDPESdsnOWuyyfevWVZvoK1rE4xSCUua/
GHQ2WxLXBDO4ImZpAqz756Fn0ZSPPV7hOYAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAfJ9MZg4xbejTBME0cV7wcYLI4SvhgmbB
Rsa+3YPGowc8CgA9J5mfy7LpKTstOaG0+5hmrblbI9rNAGZmZOaMcxuxmwO
W9CcwLgAAAAAcYfMlYz0Sw6NOqKyMaxzo4d3TGkzGHJnzcqoyFPVmx5vTbqgk
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcHLw4Jj2tG2CjXm
b5r7gmCx+BgFGvMWCjpGDaMH4zACh6cstgG6ZhljNMWXnNA3Nj8szVqy9heZ
zQhl5YM0f5jaDNjch9JygsAAAAAAAAAAAAAAABjYqmdGvVT4sbC0cbWxGpnJ2r
b6527RtP3C3dBkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPnEq5hp
GvxryugvX2CxmDrx8RrzZgIyNfb8F5cpGHBtwyy0cpcys5YOWFzDNWnJWS+2
WActNCc0WZffDLrOWyCc3z9DIAAAAAAAAAAAAAAODl4cKx7Qj/HRhlFE/
YrKiNMsvurE5Wc/
IWAAAAdfYRE0WWs0uvLgV6vLHI+5ohTlmtaimVbeg5E5gAAAAAAAAAAAAAA
AAAAAAAAAAAAAABwcsXgGLc0X4yMEx+WGOtjk7X8BlWPE4CSMpFIF6LKZFF
aclYpOWC8pMBljPKbwZdcynvTl+foZAAAAAAAAAAAAAAAAB8n0xWDYtxRhgo
15s+a84OMFkMHAJgmLBR0jBtWFx5gBQAABlcUTJG/
V5Tt2t5rrK89Pc3HM7oAAAGAgWzOMjRrI2HXq8NIsdFrVdkBznbv+kTsgAAAAA
AAAAAAAAAAAAAAAAAAAAAMfkCMD49qRi1jJ5Qt1dpNwSAAAAAAAAAAAAA
AAAAAAdeFUzzQcBGvLvEB4Fgsbga+o15jwMdGvs+D8iNcFQB6TzM9mGXSU
mZdlhxPeWnNXDI2U72avmQnNOaE+mcia+4SzvDHVJZfTY1YabLrUaQK7lNFZf
bO7aFp2427YMgAAHlgyfeuNaqqRo5rwGya2Vs9kK0z5bu5oTugAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHRr7Hs6NdcjXm3z13wka1hd
dhk1pE1/W0a/
f0duQYsU2fKsuhpPyc5YdTvlGWunosv7WWt+Un5OWF8vKJm0PLbMZfB7fpOUF
gAAAAAAGrbSUr3qtrI6ryYYd/
RHM+5mhYzWuRNK9vQfQnMAABxF0pIw1S4nOEq8Dp93hMFh9nqzOVu3ugno
gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADyo9XxgMZGHMaz7
vewx7rk5+9hrN6rLfSteMhO5khfIyuZI6yG6mXXMlkU5OvsGQAAAAAAAAAAAA
AAAAADXIHs3jI0ayNh16vDSHHha1XZAs5W7/oE7IAADV9oKVg8FlYErwcL9/
CNSapEqjLE9eVnHNuqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAOtHY1/
XYwyEhvANewOOrj4o17A+aBzDYrYKq5Jls4jiRbdP6DKAAB5oNnvrjWqqkmNq8
BtGrlbQ+2t0+272UE7gAADw+4iveq2ohavE0ARz5HmOqu8T0p2dHfbsgkAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY9GQ8e
o4WNXP6v7fY1o/
12bvbGGviyOSTWXI2S+mWv+VmtOWKu2UDJCmi2lxka9ZN+xWrRzLU9sBTrb
u+gTsgAAIzkxGKqfzPUHV4HmymLMFkM9V6ebdzaBO+AAA+foRPFVrY/
ryoRdvVHI2meKvZ2d6yLFZW3cBYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAADphab+I16pbRusSV4doPZXKfbdnIC
dsAABr2wlay4uzkEV4Wtd/
QjSnrdKqTVbsyCJ6YAAAGpwVaHCRoVsZnDV4eTnyuHrnZtG1Ta7d8FwAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADpxi
mZafioxSLpet45r6LtWCzFeXPwv6QAAAB5/
QRBei2siivHirlxHMmCTqoynPVltxzbrgAAAeGCLC9MatV2/wCgV4HbN8F/
TJaxG0k39ADKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAABjsZshj03wyAjHG3RKBSK5AyhkCc4AAAAAGgQtajWI5teGRx1
eNKktVTsnbsZkT0wAAAPmKpXRhqim+Fa8DqlWKitreYXmW3oPsTnAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAA1+uNmKz14qbYSnJi3wW74AAAADVtpKVf8NloErwcJJEbowWualtt/
SguAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAcdCPQxOOY9naT4YxyIivwqTEhDxsc9q7eFSy3xWDoilnfLWgpYvxwAUnT
wQ0U2LXXManfZjSZEt2QnogAAAAAMZkytXPJIceU8zvc51tslbrhPRAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdfYRgsftq
MWj9G/
lY588nFYu6ZXIiLiXiIb65oKwl1ziRBvVO4gX5nwiAOuwZEISJtZnCdoAAAAAAAcE
RRfs+sU81m7JwRO9umE9IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfB9ujoV9zE+ZXPtY8sV3Fp
HhUkWNtQ0mNAbfHNkbefn6v6YGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAeZHpYXxxj2ZpWOY5GRb4lJf+IW8bH
NvlhfqUmPyxMUk/yxv8xTf/
AC6T8qbj5NZK57y4cpkPN0Ir8+X2FMZ582VwHGw/
ZrbZOTWm0cmrNsJ1Nvu8TmjidfR9z1wnaAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AA6cfjK9Rz7MKzo1bMKzizHtq3N07G0qzo17McVoFmFZxZj31Yn+dnN/
NfMVGC0HuheaJ6DzemN1ty4rQjl2s831Hk9PduK0I5lrPrzem3ZMRC0a0346unE
c+0frqrIM55pef0T0gSA6+zDqfSs6vIsvzWcWm9FVdynNPDEZeekCzFZSrcadj/
VV2VWvK2M9FX2azHsq3NDHIeL76wslmFZ0admFZxZ/
31SlediVhPSMVDEas2Y2unEc+0Ptqpvs55ueX1T0vN4tPheOdZjKVTtIyeoTvY3r
gnXa8iz31C2UnNJqs6Nay6tAsvzWcWYyNVrJzt9qs6NS0nqjuRLdQGbpx+Hr/
HOswrOjWsx6qu/SbWIYmOel2Cc7q7Y3Ydy+qy/
deZatjclbrurt11HsVnV5Fp+dY9Fun71Z1eZafv07cbdZjsjEEY5J5rN9RzbV4rsgK
d2effViY2GRcfqELJsvla22EZev5rT8xp2bycMTPPRYzurGxWT99WJeYZQ8Xt1Od/
LKzq8m1XZHkh26rH+ms8YLE81m3SNWUa9WFr0wvr5sLGvXxadO7Vma97+p
z1WWoRgqq2XWo5j63OdZ3Krz7tf1O/
WjFZXFV4kjTRDEz27iN5IjdkhkV87aWPJDjy3oIdFfP2m8/
fE9vR6LjH3XzvxzO+3T0KspRi6NPdJ5qlP09DcBbrgMNmcNGOtQr5flNm8z0asp
khuNTJ2MrBKc7Uti3c4q5aOrleV5ZViqVY0pLq/Z+sE7KaIXmiMG7Vhs/
WCc7t6psjThzptVoM7cIffwjm2h580d29HoOIc187xzOW5z0KspYieNPbZ+qpOs
7/
hhiZ4YjXWkq3aOdj1i3Yrnruxa7Ty+75TFzpPSqutPwiqzs645XPMsSfPQqxZDL+
Kd2sYrwpqkSO5Et6MJ2dRr/
YCv9eE+vmxMYK8fNp6+zk1qXIj2KMVjBf0qu02VuryT2+KOVL8n1wsdbuc67s
WutquYr5iwPo8/
ot6Cuwr5+fdx03crelYLOpy1RbTq1PLzP4tUmW3VrXuWm91eXuOkejzplXK7NEl
uppRsVeTNOx8c39PG0NbLrVPPM9jfGw2t51zY7+nr/
qNha9V4OyWJqlYhtYOE9j1yNLmxsVzpO/
q1erC16YGya2jR23nUS8477FspW7oTtV31nZtZp5fdp4geeLdgJ6FZsVlsTTyvry
GEGb8fgAK2ljyQ48t6CHRXz9pa52MrRPW8O56ZIsaE0i/
peqsFpK1V5WGkqNd6jQnRo0bW69glfDHYPDattLYrUK+cnDftB363o1d7EQS19
H2bWc5Xj2SF/U8VctHVyvK8sqxVKsaUl1fs/
WCdlNELzRGDd6wWfrBOdsmto52969hS7cNPlJeW66WJrVbo4na9U3+vMm8X9
N8Vks9XCOXgJBj7dK87c4YmeGGVaOrloJ2PcLdiueu7FrtPL7vO8EztbsuOeJ36rdf
Z108nLkpRbKVvQsdkcdOxWIU8tNUiR3IlvRhOzqNf7AV/
rwlgq+owWegPXU3bHrkuxjlE+L+kiWLsnjKeak3Rpp0OduPrF10kpjmTXdi123ar
mKeYsD6PP6LegrsK+fnzctN3K3pQnPHsJ2mrHXidNnquzgRlrm4afGmz+A21E8
Vhm6Cp3kyxDZtX2YLOxFPTi73+Dfa8DKRdYGv07MlzHWCzU73bAU+60zV22L
XuK8B9fO/rSlnS/
ptWr1YWvVeKmSG5bYtl48ienseX0XcGf1Cc9eNY2bWaeX3aeIHni3YCehWfE5b
E08ruEjafNFuvo+nTTG68MivDtLHkhx5b0EOivn7SwDP2hW7sL7DryvEtbzCe32
7+11m2PWY5SVIusetqEOWO1hnhhM5reDffJ656lahXz84b9Dmx27u9VrzOpRo
Nv1Ca2KQ2heqe3t1WZVieOWlqJZvY9wrBZ+sDOmeGJnjBvFYLPVhnOk6MZOa
u5eH2Y6epCfHPFeFOMebNnJ6sH5zBo5dq/
uD9zt39wrJsmqxy0lxrYpOKgmz9ZWTqsLXrYIwWO6tG0q3W1DxlfPyNNGib3b0
Ljniduq3X2ddPJy5KUWylb0LHZHHTsViFPLTVIkdyJb0YTs6jX+wFf68IWCjBX1v2g
sWxWJqtYielsmnbjBk7miCvnt/w2smZ7/
AYbU4LE5W3o66CvnLA+jz+i3oK7Cvn583KJdgt3t6aNwzb1DEqY9Sum26krwO
zj43lOlcb1oSdw08RIE3artVu/
wBdaJqgKNBs2so52/6ALJ3gjd5zTuLeigXS5PjCnm/
qyddLRzu8i3X1avVi4VrxdebEjR11sQ12yUHzrPQy4t2K76zIOv083lZ4h6YbdYJ3
qz4ncsdTzOzTPFcqW7KN5I0RkgxsPNeBYOPJE0m3dg/nYOa8Kwfd199/
TQNpVqo3ryIdbJ4Y5+JbjJc58JJpPdCcoDDZnFsdZWw8083rrYuTXG8bzObSJx5+J
7NbcRuus14PgZHPq61ZXEbLbt+Gr9oq/
Rra9M8cymw7VWG0MAM2utiRztdbENdbxIM5/
rcfpbuwbodq47ry4YbNj452JbfJU59flUnuIqlXgqkm+Oq8LVWW9bDr21bZKM7/
AN9hbsvn6+U1X69l+KeX3uUY9kK3eY7I+Gc9X2xKeakiRNI3e3fCdnUa/
wBiIYrxdesZCs4p9dbrQx9OzCWyfKvJn6ssjarO1rso6hNKM29C3brXhZc0SnnsrK
sNTJO7XVsSObL/
AKHdbu1wbDzXha62Ia62ISru+pbbb0Nc9dm2NI4muz5GM+tvVq+2sgU03Od0
jtSROXTb0MJaJtHTTznishGMr26fnjCV8E2K3dmeV4E/
e7R94t6OIIwmHQI4mHtHXuwk7vInpgAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAf/
EADIQAAAGAQIEBgICAgMAAwAAAAACAwQFBgEQFREUNDUSExYgMDMxYFBw
QEEhIjIkgLD/2gAIAQEAAQUC/
VzrpJhWbj0QrbGJArcgpbXxgewyJwaWfHBzmUNqi6WbAk1IECdokSBK5KYCFsYq
BvJNHX9E5zjAUkWiIUsscmFbi3wFLivkK2aRUCsm8WGTZN/
gtpZ61DW4KlDSeYvP6AOoRMKzLBEK2tgmFLkUK256YKz8isFHKyv+WzmHjEM
LaiqElk1yfuyjlFEKz8ckFLczIFbkcK2mQUCsu+WBjmPn5MFyYJxztYJ1uRUCdPdG
CdNTCdUjyAkBHEG0MRtzQbe0G0Mcg8DHHClVjzhSmkC9TephxGO2vvavV2R4
62JqBNQipP25R82RCtjjkgrcGxQrcV8hWyyKgVkHa4znOfkKQx8pxL5UErMicJU5z
kJ01LATq0eQJwzBIERTTx87mLZuw6p6Jg7gHzT3MZNzHHi7C3kP2fOcYCsg1QCt
ljkgrcUMBW4OTBWxSKoUeOFvkI3WUCcJIKhOqyBwnTVQnTm+AnWY5MJxTJIFT
KTH+S8iGb4PqkskFUjon9kRZlGoQXTcp/
r3HgFX7VEK2WOSCtxQwFbe6MFbDIqhR0ut8WMZyE2DpXKddkVAnUXpgnTAn
UWRQnXo5MJMGqIxjh/
Bu2Ld8SSqiqIMXJDax0qvGKRsohJpfrCrxuiFrHHIha4NyhW4ODBWxSKoVeOF/
hI3WUBISQUCdWkDhOmrZCdNQwE6tHkCcMwSBEU0/
wCNkYZtJFk4VxGZ1buVWisPOpSRf1E6yaQWno9EK25mQLXFXIVs0iqFZB0t7yo
qHCcS+VCdYkThOnushOmlCdTYFCcBHJgjJskOHD+VOXByzFX4DOMlzoQ5kzQd
hw8/
S85xgKyjNAK2mPTC1yC1rfqBaXfLgxjG9hEFVcpwz9UErEicJ091kJ00gTqbEoJXo
4gTYtUhjGMfxCjtBEKWGOSB7cyKM3JMZuYxcyglxb5Cdpj1AjJNHHzzEAlI4cN1G
qun4EFY+P6Ko4SSC1gj0QrcGxQtcHJgrYZFYKuVl84IYwTj3auCQEicEqb8wJTVQ
nTkMBOqx5ASCj0wRk2THDGP4nOcYCsi0QCtmjkgpcUMBW4OTBSxyKoVfOV/
ibyTtqGtvXIGc+ye/LJxSMmk/j1o5bWDsWWoIcpy/wA6tINUAtZ49IKW/
wAQNOTLkZbT7sFq8kqCU5xnBKamCVJiUErsaQEi2SWSpkJ/
GZzwCsi0QCtmjkwrcUsBW3uzBWwSKwUcrLf4bGceMBHWNq9+R6xRfoysQtFq
6ws8pHGRWTcJ/wAyphznJmbpUGgkVQSvxxASOaJjBCl/
kFXjdAK2OOSC1xblCtwdGCthkVQo6XW+XBcmCcc7WCdbkVBipv8AI9IPBmpPs
BStyKYWYOkPfF2JwwDJ+hIJfEugm5SmYJSNNrEzC0WozeJPkf2cxykwtMsUArbW
RAtcjhWzyKgVkXa/
yEbLKBOFfqhOqyBwSmrBOnIYCdXjiBOHYJAiSafwOIxm6DqoIHD2Besva1dqs1Y
eeSki/
EYuDlnK5lt7I6SWjVo6TRkkf2FRZNILT8eiFrg2KFre6MFp6QWB1lFfhTbqq5Thn6oJ
WJEwTp7rITpqYJU2BQnARyYTZN0hjHD/
AAn8C0fiSgXUd7CHMmaDsWHXyTlb8YzjJc6NHirFaImEpRP9bUVTSwtPx6AWuD
coWtzs4Vmn6wMcx8+zCZzAkY8UBK9JHBKk+ME6aoCU1DATqseQEgo9MEZt0
xw4f5f5EtWE3AWROgprBWT5Juvkf4VSOgpoisdupCzxJEv6rnOCheYYtwvbmhAt
cHJgvOSDgeBwuCRjxQEr0icEqkgcEp7rITpgJT2uASrRxASBjkwmwapDBcF/
hpWIRk03zBaPW1g7FlqCmwcvxS8KlKJu2arFbQhzJmg7Dh3+pq+bnCjJ4qD1tJb
JatHFBYCOKCxbIgKgkQcP5F6xRkEZWIWi1dYWePHGRWIun8UhGoySMlGLRq2s
FY+P74rINUAeyRxBi1R+QlOx62SmwfHxLoJuUpqBUjjaxE0rFqNXSTxH4nTRJ4j
MQisYfWCsWWwKbBy/uZjlJhabYIBa3MyBa4r5C1kkVgo8cLe1q/cMjRdpTcD8/
EYuDlnK5lv7IyVWjFmL9GQQ+JRMqpJuumZ+yEnzx+UlSLp/
tyzpFvhxaGCIXuJ8hexSC4UXVWzoVuqcEiHymU61IqBOoOzAtMwM01IOqi6SC7
dVscQlhMyyQ5VC/
FN1vCwMXJDaMH60cvGSiMmj8X5E5Wh+NYiaViztXSTxH9rcczkOIuUcj0fk+cU1
IFqDTAJVI8oLXI0oLDsCArZEnwPWCD9OXhFYw4hZ1SNOisRwn8UzApyJV26jZX
Rq6VZrREylKJ/
HN14r0KJmSPpGSq0YsxfoyCH72omVUk3XTs9IeaVi1GzlN2j8UpEIyiT9gtHLaIrH
bqQk6SRL8cxCJSZHTVVmtoxfrR60XKoyaP75NVrBwYuS5iZdWLWaO0nqPxPWK
L9GWhlotTQhzJmg7Dh78klGIyaUjGLxq2jZyq0Wh5tKTJ+
+TEAlI4ctlWitYeGbyPxqokXTmq8dhnTGeGYKxeb8jpqk8Rl4RWMPokqdFSEnyS
GP3YyhCBSVZJA9mjiA9wa4B7mD3B1kSEmvJGrTUy8n8mcccTdaH41gbF4fkUT
KqSbrp2WpTZLmCsWHH7ssxbOcngY5QGrEcYZqLLIzTm2RmmpgtNL4mLBCPS
+aarpHoVSOippWpvPi+P8AInK2PxrBWP8AoyWhkZQj1kswWBTZIaLd88w+Sbr
xHoVSOifSCsRm2SmwbH9FTDAkgy0qJ+Md8svCoyhHbNVitpW5vKB/
6KkXJWjLSppeCM+aQjkZJGSjFoxbSvSPPsf6CycuAZ2gUGlGRBmdjijNljsA1rYFB7
i3wJSYXlDhBEzhZm3K0bfO+ZJv2zludquKo58qR/
djLJlBpNmQGsEcUGtUdgGuDTANcig9xWBrc9yDWiRMMz8iYHlHpwZ0ucZObPw
Yxk2a7Ccnj/
Bt6GCPhDm8Mp+6GLg+FIhoqD1uPOM1SPyM1FkM09oM01EZpqYzTB6MOPRq
gzTXAzTnQzUHg9JPh6SfD0pID0tIjNXkcD0zIjFbkshCpPFMxsA2jv8ADuRseaIfHil
P6dnnuH0iKq386T/
pywzpUCaVhhyjH+kvFgZVTwOcb4BpNmUb3H4BrBHFGbNHYBrVH4ClvalD+zO
neNIGIzIucY4Y/
oDJsYBnKJBmSZ4GZuPKDWGOIM2iOwDW1hgZuLYGuSYNcsg1xcA1veZBrXIZB
rPImGbDJZBpqQMMyTzIM7cGGVD5HHj8URBLSRm7dNoj+8n80GzIA27BQk7nB
kbCYZYWAwUiZ4wNAzJh6alMg1Zkh6akh6akh6bkhmuyWB6ekh6ekhsEkNgkRs
EiNjkBscgNjkBscgNjkBscgNjkBscgNikcjYJIbBJD0/
JD09JDFcksj03JD01JBCpPVAxq7RrnGMYx/
wDmqqKERJubMbmzG5sxubMbmzG5swqumiTc2Y3NmNzZjc2Q3NmNzZjcmYS
VIsQ0i0Kbc2YReN3BtFnCTfG5sxubIYzxws5Sb43NmNzZDGeONVn7ZuMTkfnKT
lFx8JjYIXc2Y3NmNzZjc2YTWTW9+ZJnjO5swi6RcjOcFxubMbmzCLhJxjOcFxubIb
mzG5sxubMbmzCT1utn2rPWzcb5H8UXSDj2LLpN8bmzG5MxjPHGh37VI25swk
9brnWdoN87mzG5sxubIbmyG5sxubMbmzHjLgm5sxubMIuEnGNVFCIk3NmNz
Zjc2Y3NmEnSC/
uOoVIm5swWRaGNqc5UibmzG5MwkqRYiihUibmzG5swksRcmij5skfc2YxItDZG
5sxubMJKkXIooREm5sxubIYzxwaRaFNubMEkGqh9DyDVM25swkqRYgWdItxub
MbmzBDlULoo9bIm3NmNyZixdn9uPzaOze+s9nk+4Cn9bpcei0b/
AEXLpdEPoEhIoxyMhYXb3PHjoQ5kzRdpVQyisRwn7pXtvsKcxMsLM7aZYSKEil7
HPUCmfl50mlP6J90ftxnOM12eOc+j5+hHoyNjdPM5znOQU5iZjLQu3ygum5SFw
6HRv0+k93cVTu1y6r3r9p0p/
b9bL2f2FNkmYizqImKbBy62535bUFNkhmLnDxppO9p0rfZ5/
s+lY7Ppb2fhVGM+HLBxh2zmmnJyQp7nxNrc58tkIlpzsg8Xw0aGNk5hUWXmO
Q7cYatlFMqqCoO/
EkJ+P59jpU3vnMwqoVFN65M8dCtx3OvbF2fTw5HhyPDkeHPGz9n8OR4c+zw5
HhyKz2eS7gKd1ulx6PRv9Fy6XRD6XjsjJu/
fKyDjThrX5jLBf3SvbdMYzkcOGrB8rHuGboj1vq56gUz8vOk0p/
Qvuj0Kkc45dYGLkmQQ+UztFuYbOXBGiEjIKSTnThrBS5o1xjODYuPRaNun0nu7i
qd2uOOLrwmHhNrjGcjw5HhyF+0aU/
t+tl7Pp4cjhnGtTkcnLrPPOcktKg88SWk52nSt9nn+z6Vjs+kuz56P/
GlQdeY0uDTiUVhx5EpanPnSYpzT/
m3OvLZaQjPko4W535bbSGd8lI6WKP5F+IN7yMiLW98hmMY8WYZhiOY2Ls+kA
UuYjwFHgKPAUZxjI8BR4Cif7uKtjjLeAo8BRjHASfcBTut0uPR6N/
ouXS6IfRbnviWBS5OaIr6DJMyCZy2CvkRJpW3vOR3tle26VIuMxpkUz4ma0mon
pT3n/fVz1Ipn5edJpT+ie9HpT+3C2IJmjtI5PKTC3vf+RjGTZh68i0TyinnE/
XiFS0q77mmFx6LRt0+k93cVTu2S4yPAUZIXgp9gp2MZT8so8BQ/
6HSn9v1svZ9IMpdpMimfE8yKxkRBK5SltJd5yMeGrVR4qIZ3yUjpOdp0rfZ5/
s+lY7PrYGfJyQrTrlpSVa87HhFUyCq6xnCwh2nJx1odcxJiDZ87I6TzznJIOWyjUwg3
nOxono/
cGGkE952NnHvPSIrEfzTwWLs+jedfNUfU0kPUskK1IuJAmtg7wKr3bWT7iEHKzU
28PxvD8OHzh1jRv9Fy6XRv9Est58kKu3wvKaHJhQjlLyHApy3B17ZbtulR7ZpPts
NZUV9TKcvq66kUz8vOk0p/
Qvej0j5tzGo+rH4fSrqR0gYk79yJ1XK0sK43w4ldM4wbD5HlngqK3gkLj0Wjbp9J7
u4qndtP9Kf+xTfr0f8ARaU/
t+tl7PpCuUSRRnrYhZt8WQkBApebLaXB3xOKe28Ssk35V8IN5zsaJztOlb7PP9n0
rHZ9bYz85kEz5TO1Xw5bTjXlJPSFa85JLq4QRWVysqKiz8tsJh3yUeGSHNO7g18O
RUHfgX0scfyT4R0qePRBS5OaJY4j2IsXZ/
bTfq1sHeBVO7ayfcfe3+i5dLo3+h7jg8FPz/8AO1ljYPJip4zullfrsG/
qSSHqSSHqSSFZkXMgJbtulR7Zpa88ZUQ2OMrq56kUz8vOk0p/
RPej90PZsEGM8cSZfDIiomxiR1mzeKVFW7vcei0aZ8TXSd7uKp3XT/Sn2Cm/
Xo/6LSn9v1svZ/dU43KZQY2C4kHWXjwVpty8XbW/lvxUHngcCd7TpW+zz/
Z9Kx2fVZIq6TlAzZwKm686PsrnmJTStuuWlLU68iNCCRl1myBWrcXB5xUFTbebI
WNvzEUGTnLR2Q+FCCcj9wYfjWrR3Mu9LF2fSIgmLqO9NRw9NRwZRrePxrYe8C
qd21k+4ivRyMi59KR49KR4sUM1jW+jf6Ll0uiH0WBvlvKiDeYYyOj90Vk0MbJzC
mt/
+1y6XWmfiW7ZpUe2BRQqSci7516Kyh50toc3hIbPEwphP+rzpNKd0T3o9K5EN
H7P01HB3V2Z0M44ZFVeZcMbI38iVEQ85GQxnBsB24K0bqqZWVFPb+JxakvMit
K+6w5iwofCRHa/MuhT0uLzT/Sn2Cm/Vo/6LSn9v1svZ/
bCIN3MgUuC4FlecrG6J2xyknJzasqmGTnLN0Q+FCTvadK32ef7PpWOz+y3M/
LcivyOI5yofKqhCZUOomZI5DZIafkyyKgqbPznoMbBCyDrL14IuaViiKWx0qnpV3
nMx2llY4aSAKXJjRjLEez0sXZ9IqxM2bD1YwHqxgPVjAN1yuUdLB3gVTu2sn3EU/
rdLj0ejf6Ll0uiH0WuP89vpE2c7MhraxxiWmlZQwIXKholjiPYykUnKp+j2o9HtR6P
aiLh0ooS3bdICcaxzM9uZFxKz68ljSqx+W7WTsW2v0rPHKYmLMio30qSOU4550
mlP6J90eldmGkez9TRoeWpoRHOeORTPzaY/
LpppEWU7EmbaxxiXnFZTIxjJswrDb2Dxvh21VTMioIqVVi1i21jkszYzyBNKqz5eP
0/0p9gpv1aP+i0p/b9bL2fSFbImirNFcouCmyQ0LJYkmYtTzz3/
uq7zmY6d7TpW+zz/Z9IWfaMI/
1ZHj1ZHj1ZHhi9SkEJxnzsdrVmXMyFqZ+Q+1r7Lko0WV5ysb7qu75eR0uX3Bt1
Gti7P7oftelg7wKr3bWT7iKd1ulx6PRv9Fy6XRD6M4wbE7Bmj1PZ+RXILKHvle2
+6Cgjvj4xguJRxzUhq1bHdrtG5WjZ50mlP6J90fvrkcZgy/In4IzI/
trsDkmdLNC5Nn2wkQeSXKXBC6Z/Cn/sU36tH/RaU/
t+tl7PpBdpeNSPWzpsdm4EJJZjXi7kiDZZUy6oqDTB8+SmPJTEs15ORFXectIzva
dK32ef7P7qr2kTjPkpHStsuUjbCy5yN0iGfPSGlqd+e/
Ea25x95CWB5KYt7PGCBM+Ujs3GHbYXL7g26jWcRUcRmxSI2KRGxSI2KRGxSI
2KREYmZGP0mol64k9ikRXYt20kdX8M+Ve7FIisRzpm70tDRd422ORGxSIRx4Ur
QzXeIbFIjYpEI44JAxcHLI1NNXK0BIIZxFvchtWX6+YyvN4/4JFMyrDYpEbFIjYpEbD
IhCqv1QwqzZrnGOGFC+Mj2sPWxjsnKeSMHSga1p+5zFQyEWUOi5O22ORGxyI
rDRZm0dlydrsUiNikRsUiNikRsUiEKq/
VEZW27DOhi4NiRqiS+V4CQQztb3IbVp+4zGVtuwz7JOsIO8r12QQztb3ASgpBb
LCo/wDKSJEE9c/
g8HIZPsUiKuycMk9HhcnabFIjYpEVloszZ6zyCjmM2KRGxSIiEjoRossOZ6TYpEbFI
gxJU8RsUiNikRCM8so7SzxK7pxsUiE4aSSPIlVdw+xSI2KREEgo3jJlE68ZsUiNikRs
UiNikRsUiNikRXW6rWNFnjFHqexSIaV96o5xjBccOIfV94R3sUiKxFKMsBQ2SJrQ8
mursUiK1EuGzvSYac7HbFIjYpEVpN03ai0MHLxXYpEIQkgVb/7x/wD/
xAA7EQACAgEBBgQFAQQJBQAAAAABAgADBBEQEhMxQVEUITIzICJCUGFSIzBA
YgU0Q1NgcYGh8BVwkJGx/9oACAEDAQE/AftBYDnDkVD6oc2oQ5/
ZYc608ocm4/VDY55naGYcjBkWr9UXOsHPziZ1Z5+UV1fzU/
fTYi8zDlUjrDn19BDnt0EOZcesN1jc2+EVu3IQYtx6QYNs8A/
eeAfvDg2xsa5ekII57AxU6iV5rL6/
OV2pb6T91NqLzMOXSOsOevQQ579BDl3HrDY7cz8AqsbksGJcekGDZ1MGAOrQ
YVQgxqR9MCKvIfuCobnHw6m5eUsw7E5eewEqdRKc3pZOf202IvMw5dI6xs9eg
hzn6CHKuPWF2bmdgVjyEGPafpgwrjBgN1MGAnUwYdI6QUVD6YABy/
grcdLecuxnq8+myjJany6RHWwar9mLBecbJpXrDnVjkI2e3QQ5dx6zets7mCi0/
TBh3HpBgP1MGAOrQYNQgxaR9MFaDkP4E2IvMw5VI+qeLp7wZNJ+qBg3L48jD
1+aucpVc1J1EqtW1dV+wNbWvMw5dXTzhyXPpQzfy25DScHKfm0GAx5tBgJ1M
GFSIMakfTBWg5D+DNta8zDmUjrDnr0EOdZ0EOVcesLs3M/CCRyiZdqc/
OVZddnly+LIxhb5jnGUqdDK7GrbVZRetw/P8aRrDUh5wVoOQ/
hi6rzMbKpXrGz06CNnv0EOVc3WF2bmfgFVjclgxLj0gwbOpgwO7QYNU8FVDgJ0
MfCsXl5xlZTodlOU1fkfMRHWwar8N1C3D8yytq20aKxQ6iY+SLfI8/
t7Oq8zGzKV6xs8fSsbNtPKNda3NpoTBTYfpgxLj0gwbesGB3aDAr6mDDpHSCiof
TAAOX7lkVxowl2ER517KrmpOolVq3Lqvw21LaujS6lqToYDp5iY2Vv/
ACvz+1GF36LD4luwhxr39TwYA6tBg194MOkdIMekfTBWg5D+EyMYW+Y5xlKn
Qyuxq21WU3rcPLn8LoHGjS/
HNJ1HLZjZf02ffGvqXm0bNqHKNn9lnjrYuefqErtW0ar8N1C3D8yytqjo0Vih1Ex8
gXDTr8JAI0MyMUp8yctmNlbvyvynP7sTpGst+lI3jG/EOJe/
qMGA3UwYA6tBg1CeEp7SzBU+iAvQ/
Yyi9bh+fhsqW0aNLqGpPnASDqJj5Qs+VufxZGJ9VezHyTV8rcoCGGo+/
XULcPOMlmO8x8gXD8/CyhxoZkYxq8xy2Y2VvfK/
P4sjFFnzLzhBU6GUZDUn8RHVxqv3wso5mHIqH1SzJx3Gjecr94bnxc5kYm781e
zGy/of4r8dbh+Y6NWdGlNzUnUSuxbV1X72a0bmIceo/TPC09olFdZ1UfuMjED/
ADJzhGnkZhXFhuH4raltGjS6lqToZXa1TarKbluGo/
wNn6b4mF73xugcaNL8Y0+fSV2Gpt4RHDqGH3w2oOZhyaR9UOZSOs8dVPHp
2h/
pDss8e36Z46ztDm3RmLHUzDpNa7x5n9wQGGhlqcNyswW1rI+9mms8xPD0/
pnhaf0zwlPaeDp7TwVM8FTPA1TwNU8DX3leLVX5gfur237SRMAaVk/
4K3hOInecar9UOTSPql+ZvDdriKXbdErQVqFH302adDDd/
KYchv7sw5Nn92Ycm7+7nicn9H/2eIyu3+0N+V/
wTi5X5/8AU38k95rf+f8AeaXHv/vNyzsZw37Thv2nCs/TODZ+mJi2v00lOOtI/
P8A428jJNLaATx79p49+0rymdGbTlPHv2nj37Tx79pj5LXPukQ5zA6aSiw2pvGW
vw0LTx79pbYa69+ePftBLslKf84c9+glecreTjSc9rHdUmePftPHv2iZyn1CAhhqN
mTeaNNBKctrLAukycg0EaCUZbWvukTJyDSQAJ49+08e/
aU5odt1hpsuyEp584c9+glecD5ONIDrL8tqn3QJjZBuJ1Gxs5lYjSDKbg8TSePftPH
v2nj37SjJNu9qOU8e/
aVPxEDbMjKal90CePftBnt1WVXLcNV2Wvw0LTx7doDvDURzuqTPHv2nE/Zb/
wCJ49+0rbfQNL7GqTeE8e3aX3mtQyiUZZtfdIl+Wan3QJRebVLMOU8e3aUWNa
m8RMnI4OgEpyzY+6RLCyqSs8e/aVPxEDTJyOBppEzLHYKFmd7glFPGbTWeA/
mleJuKy685/wBP/
mjDdYiUYvGXe1lGLwW3tY3qMwvZmV7LbMn2Dsus4VW9CSx1MTBYjUnSWVtU
260wrv7M7bPQdleHxEDay2pqTo0w7Sr7h5HZ/
SHJZie8Jn+pZh+8Jn+pZTXxX3ZZhbiFtdllvDq3jCSx1MTBZhqTpLamqbdaYVvn
wzMz3jMDm2yz1mUV8XH3fzPAfzbKsPioG1lWPwA3nsxvZXZne7KKeM2msvxTS
N7WUOa7AdmfZySaTCfer07S3222D+rf6bKPaWMoYaGMpRiplf7fFK9ojbjBpY2+
5aP+xxd3vFUsdBFUIoUTIfiWEwEo2sVg6hhMqrh2fgzBs5pMiziWEzBq/
tDM73BFYryM41n6pjEmoE7LfcaYPtbG9RgZhyM3mPXZk+wdmd6FmONbV2Z4
GimY50uWWZaVNukTx9fYziC2ksPzsxvZWZw/Z6yv1jZ/
SHJZie8Jn+pZh+8Jn+pYrFDqI1tjDQmUCsv85mefkEoGtqjZnj5QZQdLVmZ7xm
BzbZZ6zMH2tuL7Ij+k7Mb2V2Z3uyi7gtrpLslrhppMdDZYBsufiWFpbVu4yn/
nnMN9y3TvLfbOwf1b/TZR7S7M6vR9/
vMF9HK95boLDpKtDYNZnPq4XtMKvefe7TIfh1kypd9wszF3bf8AOYL6pu9plVcW
v8xWKnUStDYwURVCjQTO9wTF4e/
+0muJ+JW9Z8k2W+40wfa2N6jMSqt6tWEyKa1qJA2ZPsHZlV79Oo6RWKnURcq
phqTpMq4XN5chMNN6ze7TIxrLLCyzwd3aVoa8fdb87KL6lqAJmVkC3yXlMZN+0
TxFWumszLVsYBekwxrcJn+pZh+8Jn+pZjbnE+flG8Lp02FTbiA9opKnURMuphq
TpMq8XN8vITDr37Ne0zl0cNMa3gvqY+VUq6g6znMVd2kbcX2RH9J2Y3srszvdlF
PGbTWWIa23TMF1816zKfcqOw3WMN0mA6ecL8Sje/Gwf1b/
AE2U31CtQWniKf1S9RdV5RGKNvCIpscLLE4blY7F23jMavh1CZz6kJFYodRHsaz1
GYr7lo2ZAC2sBMBRqTszVZrPIThv2nDftMJWVzqNllb758phAirz2NW+8fKYYIq85
kgmk6Thv2mQCaCJw37QcpfhnXerhRx0leLZZ00lVa1LujbZ6DOG/
acN+0TFtfpKaRSugjo4b5hFrduQmLj8EatzmcrMw0ExEYW+YmcrMw0E4b9pw3
7SvFtfppEQVruiX4Z13q4a3HMSvGss6aSqpal3RLahau6ZZjWV9JuOekow2J1s2
8N+0xQRSNY3pM4b9pjjSpddmarGzyEwlZXOomZTxF3hzEVbEOoEyWe7TQTEq
bi6sJoJbSyuQBMfe4LIROG/aAHw+n4nDftOG/
acN+0o8qll9LLYdBMKohi7CZtRJDKJTQz2AEbLBZY5bSYdW6mpEvr36yJw37Spi6
AmZKObjoJgqV3tR/2i/
8QAIBEAAwEBAAIDAQEBAAAAAAAAAAERECAwUCFAYEFwkP/
aAAgBAgEBPwH1VKXul/
AUpfBCEJzfb0pS9QhCeOE2+wpeoQhPwFKXYQhPq3wz03zkIT61KUvdL+ApS9Q
hCEITb7mlLxCEITyTx310IT0N97SlL9G+5+SEIQhPoT/Gpl/
DTwzF+PYvxFKUpSlxeJe+hCEIQnkX46/
hvk+f+c1LlKXLty7S80peLlylLtLl25Sly8UvF25duUuXbl2jyZOUPHxMXMxYxDEPJ
xMQxcTJy8mvF9FixD6XTx69vD14xD4evGLVq1Y+v4Lti1i1i5fS6ePhZOVjEMQxb
/NYh9rl6vovVqx6tWrqZPIxD2ZMnM8LEPGLxofC5X+Rf//
EAEgQAAEDAQIICwYCCgICAgMAAAEAAgMEEBESISIjMTRxchMgMjNBUXOBgpK
xMEJSYZHBYKEFFCRAQ1BicKLRU2ODsnThgKOw/9oACAEBAAY/
AvwvnJGt2lZVVH3Y1kcJJsCzNL5nLNtij7r1rJbsACyqqXzLCkcXO6zxP2eV8e665Z
NVIsb2v2tWfpmu3XXLO4cO0XrMVDHfK/
8AsTjWdqI2+Jc9hbrVmoJH7cSzUDG7TeudDN1qztTIfEsZv/cczUPu6jjCuq4Q/
wCbcSuZKGO+F+L+wGW8N2lZdVH3G9ZBfJsaszSnxOWbZFH3XrHUubu4lnZX
v2u/
e8zKcH4XYwsGtZwLviGMLDheHt6wfxvnZWM2uWOpad3Gs2ySTuuWZpgN5yy
XMj3WrOVUn1uV73F232tzQSs3TSu8C5jB3nBZ2WNn5rO1LjsbcsoSP2uWqtO3
GtUi8q1aLyLVovIsdJF5VjpW9yyRIzY5ZmpI3mrNGOUfI3LPU72/
O7j4VNK5hQZ+kG8G74xoQfE4Paekfi/
Ozxt2uXP4W6L1mYJH7cSzUDG7TeudDN1qztRK7xrGb/
aXMaTsWRSy+W5c0GbXLOzxtHyxrO1LzsFyymvftcsilj7xes3G1uwfuGfp2E9d1x
V9JM6M9TsYV7ouEb1sx8a+nfi6WnQUGPzM3wnp/
E+NZ2ojb4lzpfutvWap5HbTcs1DGzbjXP4G6LlnZ5H7Xe0ujie7Y1ZNLJ4sSygyPa
5Z2paN0LOzyO2XBc0X7zlkUsQ8KuY0NHyH71n4hhfEMRRdRP4ZvwnSiyVhY4d
DuK2Ktvli+LpCEkDg9h0Efh/
Gs7URt2uXOl+61Zmne7ablmoo2fmtYLN0XLOzPftd7LEL1dHTyu8C1cjaQFlviZ3
3rO1XlYst0r++5asDvG9Zqnjb4Vi/
keDUxh4RfQHhWfB0oteC0jSDxL4Tez3mHQVhQnKHKadI/
DOdmjZtcufw90XrMwSP24lmYY2bca5/A3Rcs7PI/
a72Obie7Y1ZNLJ34ljYxm1yztSxuxt6ztRI7YLljY9+85ZNLH3i9ZuNrdg/
ludbgydDxpV7xhxdDxxBJA8seEGSXR1A0t6/
wlnHtZtKyqlp3cazTJJO65ZinY3eN6xSiMf0tWdqJXeLj5EbnbAsill8q5prN5wWcmj
b9Ss7VE7GrL4R+1yxUzTvY1m4I2+FYv5qWvAc06QUZv0aNsX+kQ4XEWhzCW
uGghCCsIbP0O+L8F4ys7UxjxLJc+TdasxTeZyyMCLY1Zyqk7jcspxO3iXRxvfutW
TSyd4uXNNbtcFnJomj5XlZ2qcd1qyjK/
xLVwdpWbp4m7GLEP5RnZo2bXLHUB26L1kNlf3LFSu8yxUn+ayqQ+dZynkb33
rG98e81Zmojd4vbmSK6Oo6+vanRTtLHjo4gp/0g7H7sh+/
4FzsjGbXLHUB27jWZhkk24lmYY2bca1gs3Rcr5pXybzlkglXx00rtjCsVM4bbgsrg
2+JZ2paN1qztRI7YLllNfJtcsVKw7VkQRN2MH8qx4lnaiNviXOl+61Zqne7ablmoY
2fmufwd0ALOzyP2u9lmJ3tHVfiV1XG2UdbcRVzZODf8L8XtcGUYLxyXjoXBzt2Hr
4gp604UPuu+FBzCHNOgj+fZ6ojb4likdJutV1LSOdtK/
Z6bA2R3rL4e75uwVfJgN3nrLnjbsvWcqXHY1ZRlf4lq4O1xV7KWIeFZDQ3YP5Zj
WdqI2+Jc6X7rVmKd7t43LNRxx/msdS5u7iWdle/a79zAZJhx/A/
Gg2Q8BL1O9oYqht46Pkrn5UR5L+II5b30x6PhTZIXB7HaCP51mjEwfMErLrnNH/
WwBftE9TNvSrVgdpvWRTRDwLJaB3fzDPTRs2uXP4e6L1mYJH7cSzUMbPzWsFu
6Llnpnv3ne1yQSs3TSu8C5jB3nBY+DHiXOw/
UrEYj4lzOFuuCz1PIza3jhkufg6icYXCUz8LrHSPZujnaHsdpBRkivfTHp+HiZOXCe
UxCWndhNP5fii95Ddqy6mPuN6zYkl2C5HgKYDecsUjY91qztRK7xe0yInu2NWTS
yd4uWU1ke1yzlSwbAs7USO2C5Y43P2vKyaWPvCzbGt2D2Gfp2OPXdjV9JK6I9T
sYRLo+EZ8TMfFElO8scFgPzdQPd6/
Zlrxe06QjUUILoveZ8PE4SA4veb1rDgOP3m9I/
EWdkazaVjqGu3cazMMj9uJZmKOPbjWOpc3dxK+R7n7T7G6KN79jVkUsveLlzT
W7XBZyaJo+V5WdqnHY25ZXCP8SxUzTtxrNQRM2MWL9yJLOCk+NiLruFh+NvE
DmEtcNBCbT1pDZvdd8XtDUfo8ZXvR9exXEXG0S07sFw/
NYsiYcpn4cvke1g+ZWOoDj/TjWYge/biWZZHF+ay6l/
diV7yXH58XJa49yyKWY+BasRtIWUYmeJZ2paN1qzlRI7YLllNfJtcsVKw7cayII27G
fvploLo5fg6CjHM0seNIPEbTfpB3ybIfv7QzU1zKj8nIxytLHt0g2tkhcWvboIXBzXM
qB0fF+FryblnKlncb1mWSS/
ksxCyPbjWVUOA6m4leWyyfPSsillPgWrEbSFlCNm1yy5om/VZ2q8rFlyyu/
JY2PftesVKzvxrN08TfCskAfybLyZRyXrg6ht3Ueg8QU9acKH3XfCg5hvadB9nfyJx
yXoxVDcFw/
O0OYS1w0EJtPWHBn6HfF+E8yWt+bhesqvcwf0RgL9oqamba9Y2PdtetWadqya
WLyLJjYPD/ADIxVDbx0HqVzxhRHkv4gimvfTH/
ABTZIXBzHaCPZ8HOMfuu6QsCYZPuv6DxG01e7HobIfv+PM7URt2uXP4W61cp
48CubUsB/
qxK9pBHy9m6OZoex2kFGSG99Men4eJdy4DympstO7CYfZmKobhNKwhnIDod
1beIKeuN8Xuv+FAtN4PT+NL3uDR81l1LL/ljWZZJKdlyzMDG7TeuewB/
SLlnZpH7XcXCppXM+XQhFXXRSfF0H2Za4Xg6QjUUAwo/
eZ1cTCixsPKZ1oS07r+sdXsyyRoc06QUZ6QF8HSPh4giqL303/
qmyRODmO0Efi++aVkY+ZWS90p/pC/ZqcD5vK5/
AH9AuV8sjnn+o23MiedjVk0kvlXMhm84LOSxM/NZdWe5ixVT/
Kr6eRs3y0FFk7HRu6jY2CrJfT9B6WIOYQ5p0EezdUUAuk95nWi1wucNItEsB2jrW
HFieOUzq9o6o/Rzfm6P/XEu5cB0t/
0hLTuwmH8WfspjHzesv9JBg6mMuV81YXHdWVUv7mrKllcsYkftctXv2uKxUsXlW
REweH2GBUswh0HpCv5cB0P/
AN2COW99Mej4U2SFwex2gj2ZkiujqOvr2p0U7Sx7dItbLTuwXhfBOOUz2jp6QBt
R0jociyRpa4aQbcKLGw8pnWhLAdo6vx4WSNDmnSCnT0d74OkdLbLuXAeUz/
SbLA7CY72d0gwZByX9S4Oobd1HoNrZIXFj26CFwc1zKgdHxe0whkTjQ7/
aMVQ3BcLRLTuu6x1rCjyZBymdX49dP+jxc/
3o+vYiHC4jSFe3KiPLYmy07sJp9mYqhuEOj5LHlwnkvtDmEtcNBCbBVkNqOg/
F7TAmGV7rukLAnGT7rug2tlgdgPCwTkVA0s/
HpkizdR19e1GKoYWPCZFfm5sRHz9o6OZoex2kFGamvfT/AJttvGlCmr3Zz3X/
ABe0MVQ3CYVeM5AdDv8AdofE4te04iEIai5lT/7fjfLcG7SsupiHiXOl261ZEUr/
AMlm6X6vWTDE36prqkjJ0XBRvAyYson2txTqj9HN+bov9cRtNXuxaGSH7+0LJG
hzTpBTp6S98HSPhtBabiNBTaeuN0vuv+L8bXzwskPzCx0rO7EsUTm7HlYnSjxLJ
nkHcsVS/
wAqy6olvyauDpm3DpPX7czUtzJ+kdDk5krSx7dINraOqdffzbj6e1dUfo8fN0f+uI
2m/SDvkyQ/
f+xmPImHJejFUNwT0fOwFpuIxhQzdJGPb7UzUtzKjpHQ5FkrSx7dINraetOFDoa/
4UC03g/2LkY4ZbRew9Rte34ZD7a/
kTjkvRiqG4Lh+dopKo5t2Jh+H5f2Lmlf0Ntwj77yfb8HONjukLAmF7TyX9dowzfLH
ku/
sHjIWVNGPEsqqiHjWtMXPX+ErJ4R3hWbgkdtxIcJkRjksFjIoxe55uCigZoY279wd
DMMR0HqUkMvKYbrOC92Vv5/jfKkaO9ZVVEPGtZadgKxOefAsmKU/
RZFKe9yyKdg2lZLIm9y5bG7GLWnLKqpfOsuaQ+JY3E+wuAvK/WatuedyR8I/
copR/EZj7rKS7/kH41uKy2O85WOE+YrRIPGuVKPEsU035LJqZPKFiqneVYqv/
8AX/8Aa1seRa03yrFUR/
QrFPF+axSRHvK0xeZaYvMtEfnXIZ51zbT41zQ8wXMXeILPOZEPqsIDhZfjd+50r
em42Ug/7R/Z6RzDexmS2wP6Imk/2ddS0jr5XYnuHu28K8Zc2Pu/
snpCxvaO9c/H5llVUQ8YWtx/Vay07AVzp8hWJzz4Fm4pH/
kiyL9njPw6bQ+Qfs7DlfP5K4f2BxlZUrBtcsdTF51jq4/
qtZB2ArnHHwLEJT4ViglKyaV3e5ZNL9XrJp4x3lZMcQ+qxGNvhXOtHgC1k/
QLHVy/
VY6mbzrKnkPjWNzvqtPsg54MdP8AF17E2KBuCxuj8dZsN7ysltN5isn9U/
yWTJSjYFz8I2LW2+b/AOljqSdkyypCf/MsbQf/ACLmgfGFzH+QXMf5Bcx/
kFq5PiC1Y+YLVT9QtVd9VqrvqFqrvqFqj1qj1qj1qj1qj1qj1qj1qj1qr1qrvqFqrvqtV
d9QtWPmC1e7xBcx/kFzH+QWdLIhtvQdNfUP/q0fRXDR/
wDzVi+VwY0dJWtReda1F51rUXnWtReda1F51rUXnWHK9rG9ZK1qLzrWovOtai
861qLzrWovOtai861qLzoPicHtPSEWuqIwRpylrUXnRbBMyQjoabQZ5Gxg/
EVrUXnWtRedXhAzyNjB0YRWtReda1F51eOJn542bXK79ajWYlZJun2Jc43NGkrW
ovOtai861qLzrWovOs1I1+6ePcamLzLWovOjwErZLtOCVecQC1qLzrWovOiYJGy
AfCUS7EAtai861qLzrWovOtai861qLzq6KeN56g7jZ+eNm1yu/
Wo1mJWSbruJfPI2Mf1Fa1F51rUXnV40WlslRG1w0guWtRedYEM8b3dQcgJ5WRk
6MIrWovOtai861qLzrWovOtai861qLzrWovOsO8YN1961qLzrWovOiYJGyAfCeIXy
uDGjpK1qLzrWovOtai861qLzrMysfsdxi6Rwa0aSVrUXnQa2oiJOIDC4hdI4NaNJK
1qLzrWovOg+Jwe09IRfI4NaNJK1qLzrWovOsOF4e3rFpZLPGxw0guWtRedACpiJ
OjKs1qLzrWovOsOF4e3rBRfK4MaOkrWovOtai86vGhFrqmIEaRhLWovOgyOojc4
6AHWlr6iNrhpBctai86D4nB7T0iwcPKyO/
RhFa1F51rUXnQcw4TToItwJZ42O6i5azF51rMXnVTsHrx27zfYQ7T6qq7V3rZN2f3
tg7S2PdCpt82x7os4Sodsb0lEMdwEXwtWPHZhRuLT1hBlfnY/j6R/
tNkhcHsdoI49V2R4t7HFp+SAmP6xH/
VpXCU7to6RxZd8+tlX4fup+zPpbN2n2VR2bvTjXg3FCkrHYRPNvPpbwlQ67qHS
UWxHgIupulXk32XsJaesIMrc9F8XvBNlgcHsd02Q9rbFuC2q37BuFU/Zn19hJ/
wDHP/
rbL2v2HEn7vXi3tJB+SbFXnhI9GH0hBzTe06DxI6dpypTedlgc3SDeFFMPfbbVbls
Hf6qq3fvbDtd62xVTfeyXWAjEQoZh77VNGBc0nCbZNAdLHYX1UcI0yO/
KyCLoLr3bFLL0Mbei52k47JKl2iMXDbZLM7Qxt6c9+NzjebJaV3u5TdljsEZ2PKba
6ndyoTi2WOkfia0XlSzu0vdfZwkgvihxn5lVOwetuhaD9FoK0Jm81aD9FoPE0FaC
odp9VVdqfWyfs/vbB2lse6FTb9se6E+abktRlnOwdXGEUp/Z3/
l8+PV9kbcQv4jZoTo0jrUc8XJeOJNvn1sq/
D91P2bvS2btFUdm70tvYxztgXNP8queCD87A5huIN4UMvxsBT5peSwXoyy6Pd
b1DjBrz+zvOV8vmrxjBUHa/a2LcFtVv2DcKp+z+65JWg24gtB+i0FSf/HP/
rbL2v2HEn7vW3QtFrqOU8nGzZxJXA5LMhtstK7Sw4TdltVuWwd/
qqrd+9sO13rbNF7117dtskB0xuvGxQ1LejIdYxvRKMFFg0RNwbJ6p241MgGmV
35WxMPLIwnbbI6ZumQ3nZbDITc2/
Bdstc5gzUuU2yJ7jcx2S6wQNOVMceywAYyUyP3zjftVTsHrbTZI5PUuSPouSPouS
PosYvXJH0XJH0VTd1/axt/wFckfRckfRYlVdq6yfs/
vbB2n2ti3Qqbfti3Qo6VuhmU7bYGsF5OIBNfUMElQdJOO7YsF0bSNidVUQuaOW
y1oeb3xZJ41X2RtdeBzpVz42kbE6agbgSD3BoNstK7Ry28SbfNlX4fup+zd6Wzd
p9lUdm70tk7X7CzhSBwjXDBNtMx2kRhRUjTi5b7ABjJTZKpglnPXoarjG0jYnVVC
3Bwcb2C3g3nLhOD3KDtPtbDuC2q37BuFYxeuSPouSPonbbKm8DSFyR9FyR9FU
9k70tl7X7DiT93rbS5I5HUrnMaRsT44sTHDCA6rKYjpdd9bZpfeuubts4OHlXE2Q
yX5N+C7ZbVblsHf6qq3fvbFtd68SS7kSZbbGA8mUYCni6S3FtsZIzlMN4Ukr+U9
15sgj966921FgOTCMGyJh5DThOtlcDkMyW2NbKMbmhw77IXnlAYLttjg0Z1mUy
2N7jltyXKV4OQ3JbZw8gzcPrZU7B62tihluY3Rkhc8PKFz3+IU5qn4WCRdiu4lVt+
1jdx3Equ1dYXU8joyRde1a3L9VrUvmQFRM+QDRhG2LdCpt+2LcCqX/
wBZFjS7RE3Ctc12NpFxUsXwPIsni6HMv41X2Rtd2ptma3kuyvrZTXdJweJNvn1s
q/D91P2bvS2btFUdm70tMVPgYJN+UF/C8qH6y+8DQ0DFY2R7f2dhvJ6/
lZVE9DsH6WRYWhmXaQcYKniGhjyBY+PoexQdp9rYdwW1W/
YNw8R22yq3hbU9k70tl7X7DiT93rbSh0rAcD4kS6eMAf1J8sfIGS2ymHU6891sN
K3oy3WTzn3RghVEXwvN1kLzygMF22yq3LYO/
wBVVbv3ti2u9eI2dvKhP5WNe3E5pvCimboe29TtHJccJvfbAz3b8J3cpJHcljb0+R/
KebzY+pdplxDZZNKOVdc3bZDCPfeAqaZoxXYBslpnHE8YTdtpewZqXKG2ypjZj
4ZuL5GwNaLycQUcPvaXbbKnYPXjVW8OJU7R6WN3HcSq7V3sIt0Km37YtwKcH/
kNk3Z/fiVRb/yGy/8A6zeoXUr8Bzn3HFetY/wC1j/
ELWP8Qqj9bkw8G67Eqvsja7tTbi6IxZSdoOJNvmyr8P3U/
Zu9LZu0+yqOzd6cdkFaxrGaGvaLleMYVUD/
AMpseOuLiVZHx2M3HKDtPtbAf+seltVv2f8AjPEdtsqt4W1HZu9LZe1+w4k/
d68d1ZKLi4XM2WEnQFNMfedi2WRk6ZctMlGiRv5iyWmdoeMJu2yq3LYO/
wBVVbtsW13rxHxv5LxcVJC/
Sx11hiPKhdd3J4GiIYFsd+iTIXBjTMcGxkTOU91wUcLNDG3WQ0rToy3fawynRE3
81N1x5Yshmb7jr017cYcLxY9jecblM28Q1EgzcOjetqdg9bYJZosJ7hjOEuZ/
yXMnzFOFKzBwtOPiVO0eljdw8Sq7V1kjKm/Bay/
EblyZPOtEnnUT6YOvc643m+2LdCpt+2PdCn6nnDHfZFI7Ew5LrZZ3+6PzRc7S
TfZUTnRiYFTdofTiVfh+6q+yNru1NjnyG5rReSpp+hzsWyyM9EYLrXE9ARPzsq3f
NoU/
Zu9LZu0+yqOzd6WySVMeE4Pu0rmf8k79XaY5LsRvVxsMTze6E3dylPRJlCyGY8
m+52xXjRZJNJyWC9PkdynG82TznQ1uCEXfA4G2H4mDANjnvNzWi8qab43k2T
SdDWXcR22yq3hbUdm70tl7X7DiT93rxo46w5J0DrKAaLgLHgcuXJFrGMhhwWi4
aUxs0bG4BvBbZFM33HXpr2Y2uF4VVuWwd/
qqrd+9sW13rxWVLdEouO2yUyG5joz9U578bnG8oNYL3ONwCcyQXOabiE1zcR
GMKn4M3tbHj3jpsdO7kwjFtsLnYgFNMfedi2WPbDGx2GbyXJzHQxXOFx02hh5UJ
we60vZyJsqwNGk4lHCNI5R6zbU7B62wwy8JhsGO5q/
ieRfxPIv4nkTJY+S8Xi2p2j0sbuO4lV2rrJuz+9sHafa2LdCpt/
7Wx7oTamMXui5W7aIatpljGhw0hYhKT1YKuORCNDLA1gvcTcAo4fe0u2pjJXuZg
G/
EuflXPyrn5VJwL3Pw7r8JVfZG0xVGHhYZOIXrIbK7uXBgcFB8I6dtrqiQZc2jYuAdF
wjMG8kHGsqR0e80p8FDe4vFxfdda55/
iSEqfs3els3afZVHZu9LXx1Ly1xkv0Lnj5CnfqpMsvRiV5squrJQnjF8kPpaIalplhHJI
0hYhKT1YKwbuDgGhvXtsAaLyUyM84cp+1Swu99tydG8XOabjYXR5UbuUxXuEr
T1YKMNO0xw9PWbeFdypjf3cR22yq3hbU9k70tl7X7DiT93rbSl0TCcDpahUQtuh
k0gdBsDmm5wxhNeedbiePnZwLeTCPz44jPKhOD3Kq3LYO/1VVu/
e1kM+HhtJ0NX8XyL+L5F/E8iE0F+BfdjClYOWMpu3icK7kQ4+9cM0ZMw/
PiRg8uTLdY8Dly5I44jJyZhd320u6bId8cSp2D149J2Ytqdo9LG7h4lV2psn7P72w
dp9rY90Km3zbHuhEOxgoywDCpnf48XEhV1guk9xp6OPV9keOJqkFtOP81cMQC
qJb8Rfi4jIYRe5xuUcLNDBcp+zd6Wzdp9lUdm709hfKLpZThEdVhnphfTu0j4OM2
rrG3H+Gw+tprKVt5/iN+/
GBcLqdvKPX8kGtxAaOI7bZVbwtqeyd6Wy9r9hxJ+71tpdxPgl5LgpIZeUw2NcT
mn4nhPnJyGtwk+R+NzzebJ6iRoIGQ29c236Lm2/
RTxdGFeNlgjdyZsnvVVuWwd/qqrd+/
HbvmyVg5LsptrS7ly5RUmCL3x5bbYYvdvvdst4FvJhF3fZBD8Tsexc236Lm2+VQ
VEbQLjgm6xr2YnNN4UUzdD232Uu6bId8evEnjhaXvddcBtWqSLVXrVXrVXrVXr
VXqnZKMF7WAEWzyQ07nsJxEbFqj0JKiB0bMA4zxKh8dM8tdISCtUepXVMLo2ll1
5thbTRmRwffiWqPWqvTAdIaFA2mjMhDrzctUetVemA6cGwteL2nSCi+gdwR+A
6FjpnO+bMa1SbyLLYIW9byg92em+I9HsKhkYvc6MgBapItVetVetVes4GQj5lB9
Qf1h/z0K4aE5t914uvRMLf1hn9On6K59PKPAsinlPgWWzgG9b/
wDSyMuU8p5sma0XksIC1R61R6lbUxmNxffjUzWi8lhAWqvWqvWqvWqvWqvQ
4QMhHzKEkmemHSdAtucLwUX0TuBd8PurV3PHWzGtUm8iyo+BHW9CSXPzDp
OgcUyUx4CQ/
QrmeFH9GNapN5CsmleN7Eg79ISeBiEcLQxg0AcU3Ur9K1V6qBVRGPCIuvtna0X
ksIH0WqvWqvUjKmMxuMl9x4kscDS95uuA2rVHrVXqnjlbgva3GLGz0rcKduIjrC1
V61V6/UXUkl4PK/
pWqvWqvUUb24L9LttsU1JEZDg3OuWqvTXspXhzTeFKGxnhnx8j5rVXrVXqGOd
pY8X3g7VURwtw3uGILVJFqr1qr1qr1qr1qr0I6hhY/
COI2RSUzMOVhuuHUtVeomzwOjjwsonqVw0BY1MKaBz4sLJIWqvUs1UzAkdiAPV
Y5zW4RAxDrT5H0r8J5vK1V6fNVxGO5tzb7Zomi9117dq1V61V6fBWROjwTk32
U5pYnSYLTfctVeoy6lfcHD/85P/
EAC4QAAECAwYGAwEAAwEBAAAAAAEAERAhMUFRYXGh8CCBkbHB8TDR4WB
AUHCAsP/aAAgBAQABPyH+XEuDwQnR4Rf8VT/
Je6q9b6VpoeZH5pY4O3uMLEAS5jnNSoPcRAjc2X7ptb99FrQHc6oI29JVC8k9P+
EgHIAYp4dhVxVt84U54QSCyvP5A7DLvlUE7nog5ixP+BSkimVmFtpFMAXfu6JoL
OIQL0/vwjisAIBu7BGiGPdND1PJ7JxaEUiLh8VqLR/
yzoB6wxrSgBHo6H9uMfJIKQn8B7UMn2RCZY84ttjm6cXINg8SdgsT/
KacGAXeoK63ALSmdANGk2B+TKh5qUAadGgGnRL1JGqPKqIcxC2m+box+vHZ
OxzEtVQuzR1Cz4r2ZAGRzCyQD13Kmhorg/
1zgVQklvqynKzvU1w4+6BEXeTJRxcLyqJuJIi5ixPyAhGbAdGWIzPuQ+eW0R5Wk
vC0q9G45r+Fv3s0CAGLkfOQ9UELms6gICUAwMkh3BVEESMuF8UW0/
IXNCssh/
pwEwAxQAljq4KSDOydTkSPQE3uJHbK4aa9WVnP4zoIzfFUDZPNDQdt2I0yvFKF
T/D9qbCShela/
AHuhYGWMf5Q0zf3qamyH6qri4DHgdjKRwWDM77qoZUfz5AHJk6yO5VMNxipa
bvEr+33l0r+Q01ys/
ERYhYBO5mZULdyaKBqzJOWAA+DD4Ik4LxPJAWyMUAGBh/
o7kfEiYyKc0vlP2pcEgGI4J14ZhEkf+ZE6LgE4SELDI7DECC9eQilzWGmoTlZ/
BqpxQkEIYPJbufJa1V9FoSqa3Kth1mgzA8Ef63SUMi1zmTlzu4LY8AtTZRVOofyQ5
x2GFV3ud2quOh2ww+MjBwIJanhp3rM8WvslBASheW91U9hUWm+i10tldyzsF
3P3ctOYUABgYf7UOMGAcFWDqqHCVQIiQ+LkTBVnYLL9/
xYVxAXlS4vcwnRV2cXygW+fiCkjbMOqcXouZaIq5nE8ck8GYhQCfG1NBgTzORX
roeEGeko7ug/
WWJvY8Xx8oo5jAVFBkP9QPJbKtBa0wj90+PKt9zFfrfleEfwinMgCVqMXwq+N1S
d6fM2y6WVVeYlEEk4kVkvdogL0/hAbhMIKp/
cKyslexXQY6RPwq4BcNHALEK0hw6ZCkGtsN/
uJpePFyOo2IVoiX3QxjW+ibpBmRAE4KEBCgDf6kK5jMnzJyKcADReFaYUjmMbLk
raqmpcokmszj8J8M7G6CjYRJNQ5cQgXp8nP4UQlbXdBvHA/XQLX8ICUXIcH/
eu1U7uYsIJ2BkXx7oBOfdIIoxM33LSQw8IpMM3s6mTsBIYB+wgtUxnhFHBuM8p
4JvahDBsAf6wAOQAxT45CwgpKC8QqvJgI9jFppSIuEdqIdaj/
hnCYMB+Kes20jkfkeZdVpXhMAcyqHPHgcTTNiCG3J6A/
wC6a96TPhcs9qpddAwjK0XjIWcvgC04v9g0BcJ9qXHRwzwwspxkulZDwk1g0/
LpSBW9lrmXgkKuIaB66yCsbnCopXlZZy4ixpBLSBQ4AHsB8Y0pMgOgpK3gPBNJ
zMOoxQP9ReVx/qGgS8mTnPCx7onsFtqaJZdRe7J1attV3naJJrM4/
FktQsKJBu9rXVbkvJ0aORlKLvgIE2fzBMlPa6grZPj4HRyYPUE8oCpS5hOnDqdiwK
EmwJuljHxjwCMQSKtOWCuTDgBXFtMhVLXUq/
0QdwWGFV8u+tVTciyXFHLR5u+tGndjn4Mk5CYxQKi2poOCQUivXQ8ILQ9Bs5ry
zsmYlhfPctDSCAEgA/whwAtgx53p0GlhTMWcBD4uQxBVjgbH9/
IGWawakICgVBETXaq4LirFjM7jD+cxQgIKXXW+tSzE009OtU9i4/
FYgMJ+HTERiLhiTIwJuyNSjFyJoWIVpWf2Q6dY/
hNUiuoWc9eAIBQAP8sgAQQ4KCCVRo+tUNOmNKSOCY2TSQEEOJj4wiWvyIgoG
ApE/ZHQFrZrGIfywxkAtKtW3PdFJzmTFSSsLiTs/
NtkZyOApRizIFLJxbhPJaLjleOzFaXpCCOuXhCJ/
n7kBYRgKHdEH+mZ4tJImPxFz5YUbxwPc0SV/
CHgEcBkfjchhaOhwVnfRsC8RINFyGIKHgqNl+/
5MGBa8eS5IjXC6JCcXrCCo+eEqjPkKCCW3AgAoAP9i+QMwrwnIDZYkc8eB6EK
W4ggcEcivxmkioVcETOjoCTEEiYkU02RAjvT+6JADmi0i1S/
qhRJjniWHmPtQaerScfGAODIO5JmwHgeJz6uoQEtKR2+MW2/
WYhTWl054OA6bTJXNggBhnAGv9pjAAmRIg8LDfonwckOqcRj5kcGww0MOcxz
wht5HTckbFKkB3BAgHBcH4gwhmIJFOk1Q1y4cDyrdGX6TSAalTuPxg1OwDgo3
Wjb/ngKWR1y4IAJHIkf6/
IjGETI5S9VLg+I7Jy5JDPDyYMTSZRJx4hTWzpb3R6ewqLywJug1TKUOIoAQq8oBc
2LQp0QTYyC/
NyHBHxtp17HLcUSEaxBMR7IPG4p9Nsqn8ZABiHC6AHuhBJjIiL9udl4oBbbbsP6
wANgYToEBIMfep1Nls/lW7ZAQbUAFsaclYXZ2o477Fy09wCAApLjJx/
UBTOuZSphA4gE7eIIFUHIr8beJErOFDYQmRKl1uBTbkDU1GHyDqgtjNE3OwExF
zVujL9J5GKHqdx/
vB7nYCRTKKvayg4Tl1KY4kPMJIj45USkCaFmEdG8RJVB0A5op2MQ+SS0enXBD
79diIuMFvQbinUsJxn/AHkhxNX6oCiCNimIKLMiSuWKH06oG4/
GDHarSvCdAupI0OMSHxciYKFUYWf7+STWFGqpypUaMSp7T4KkMFnGuIw/
vW128uFLEwBtyQa/gg/
ILADASKtpWR3cIkERgoXQ2wKD6Dj8g1OlxRu8VTphE4OQRMI5oA5ZP7cQ/
JhVvLmFP7N70rteBN3eECnXMierSJZej175QGA4NQm6BQd0IJMZERzSQ0R3p8Y
NTsBIogDU2v5iRsU4DRMr0yUzY/
22MHH1SNz9iHNABTO2OK8tAhslAgoLttaFefnafU7CaImBgJiMm5J8kEAGIcJ2r0f
dCCTGRhSkk3sCkgLiX/C3zLZHY4Jkm1WBeIOBm4L0+Nnyq/
KFHqNhNEPAwExG0DgrmwQGgTgi3/
hYyDm6kTGqMuYHzOkwkkaFGv01wXiJRpM7teH/
AAs+YAIALyaBVrAt3ZkJfOeTdlVwV3ooSGGUiia+bcf+BO1VQVmUTbPBXaaKuH
yco+z8iu3NqFTLIktFWZc8YMSlAqLC/wAA/szArwhMT5QKcjNDkn/
bh3zsQhbisirecHhaC5LsRh5QxmclF6+ld/
KfKCSyh5VnOQAVVvMtfU1q9H4AAolAAjyQKbsf/
CCjZZoDHSOPrL+1OX2NxZVBb71QhkqlZZCRJQVQbYKyjMiZSOYr9dBsOq+0bO
HDgankgYmyPbF7ZBxsuiVCyQIjFfJRBucUdcdejYO6JkLP8O6YftAoK91/49plFD9g
UqKxxMv+Otlk4UXZxNJR+Wz/
AMTI6i5rVcFGoDywMg1CdWzg8K1vJGjuSHT7EBG/
bwn5qtZwrQcRtoAQGAoP+A0ZGZWgeBOrNsC7QXqvZpeF2ZEtF8ftA+AXhVVi
0FasZdkcloJKClkUWB5fUuwhvZEHKOZarRKoLNCVTjn8VreZhA4wzAP7o5n+Jx4
U11X0w8QPGL5Xhi+kenyGpRFxAgfXVNQGRAdmjAKwCsIrskRuzyiDbar1aKjnrV
61etXrV61etXrV61D8HAT1JAiDdHlWhzKwisAogM/OaJiIXECQWCgH/
wA1auBo7AL0petL1petL1petLIzeC9KXrS9aXqS9aXpS9aVDHR3BREfMBGS9KQ
ABOQTKJChMCw5XpSa+kgCI4NETDjEw69aXqSAIjg0PAbYqLAOmY6yGOAwT8I
8QjkoAvWl60vWk79JBnF4J4yoEQWIIr1pHhuuSyODgBySvSl6UiNCYlxijtAJyTYnv
pL1petL1petLA+KJ4pIRwggdh7NBeiB4AkwlgWA69KXrSCIjlQxplPAEL0pSYG7IlA
Kg4BDr0petL1JepL1petL1pF4CtiTXr1pelIhQmJcD8FcDRWAXpS9aXrS9aWiPHin
RmIYBetIqN2AzPAOI7kMAvSl60qGOjuCganchgF60vWkCEehXEaOEmBC9KR6w
MAGaJaq9KXpSDCPR0FXA0VgF6UiKvRIAiOVCiomYgyK9aVJQ4EmJb8sBBC9KV
DHR3BgfEzdLr1pelIBcFyHBidhGxAr0ZerLfbvFQ+Eey3uJC2xwgFs1y2K6Aqt2ug
XVFKrgjpaILM5lEicnYmAYB6FYpyakkBUB7Rx7rdw4+EJlhBktJU5hq9XHgNOAp
my3o7/
AALbr3EBFAtBVF0ajNE6b7CpcEXXZmmzKcSLEwExTQjFHfO4YoeEnAQ3WBhat
9ujssPiORbwIavwGp7XCCDq0mRMxZD1b0PEI4LRwS5ORMDHsMTFWZ4TgbY6
tHf4lpXZHcr0W7yHnikDlbhwrFxJztWgUIZwuNJkj4mdnJBwQTygmUT8iw6Igjnc8
GI67/kKnaU3zmbEwfZM+crAc8fqhZweo/
UMCmu5sAqoKAXCwQbLSrkBb7diCUIjKDPTIMpuinahs9cqVkYAE0mcF65euQE
O7S4skb/
CAWzXLUe0BVbdcifMHqbk6sJyhuEXWhovczsXtoC8xTi3m6NUMgRIpgjMRmEs
mNxRaXeZG6JpwZM3y9Hd4BbVeiLYmIV7usGFA0GJjEFhXsUQj2s8I0jUOSuouFk
X0zIVDBWDgraYoWrZbo7LCJyMw8yeoXqo1AOQgy96HApqfAaztRBaEcgjWEBiI
viCPnDgmcG5A/
Yv81AjrUd3iWldkdyvRaEOXKKIgkxkRBx780E0aryCDqGdPuE5KW5jMwcAU+wp
zDTWScW7NzSg+xuT8Z5DzCSrCTBTLDaITgDyz+wlvNsmsCALhgEUYtq8lvt2JR
LrtR4Na0FYAYx1IQBgwbAJgBvxGUgAwMMFtF/
GDgWxXLUe0BVblcjncrnqQf8AjYWlAYY4LMKEhXsIqq3gKAXiJXAXLs4t5ui9aNxg
EfkaoIoOMdzpNxRDFjIwKC0w8JiaLc7403y9Hf4FuV6OroZSIzWk7IykBp6I8rM+i
Ai3DABDZU5a+AEfnWwinsO6RF4iabPpC2uKFq2m4R2WET0PzCEna5TU4P8Aj
CirW+3o6nwGs7UTjn9BEJ7qCKB6AmKWQlKB3lJEQAt1ZIKtZlMCBqpsAeD4MLn
Cd6Q1qO7xLS+zjsZ4tqFdYOlYgs7E2Icw5UwiGLGSkHA5wVZtNYrJPaG6smVNa
B56mDLH5CEZnhOUP2AWwa64Hg4B+WkJpnVLuapWUJtAeeFOSPyx+wr5nh7
bMN9uxGvFYCSUCsKp65Gxw4NJ7OLW8XwfLkEaUY0JuVwcaAWxXLUe0LVtFyMf
LgiZCQgFZyOeQERRuQLwUUh9CYGNGQEYg/
vFtN0dguERCAEaICpe3MRNOAam+Xo7vALcr0cWQ5OSw0Vnt2AIVzWQkdyE0
KSykgFhcZLlSIy2DEIOhiHgZzm+oW1xQtW03COyw4ZmpavDeLo7RejqfAaztRF
FwAggqoWi1TBRAjVAgQUHHJpou4kPMsgy+Qc4zKIyy5BUQcE/
LSGtR3eJaX2cdjMnmM9YE/
Y8wKggutNybkKJ8Q4cpMpfZB8gpnxPOgzydycHfN1ZIKtZlFmSgXWoA3m8qkLF
RGCsZfHJbQgO4yJg8/WDgBsC9XaLt51hvt3i3C7is267g3C/
jC2K5aj2gFtFyJKhFXOAgG0+LgojeeBxhQJP7gIxwbFb30rf+tb31p84Hwzvctpujtt
wiMoqBMCACUQ0U7G8xpvl6O/
wLcr3HTUDCDMIAiuUIRpgI7sDGqZuo4AX4iG4XLa4o46dlHdYQpxTUtThvF0duv
R1PgNZ2uOVYL7oEbYDlUnzeCDamMS5o4FBjktEKw1aO7xLS+447BvuTzlWUx
wdm/
UEwhUbOiupiCXgbudNU5kYXkqYBVcDnKmJhhQgHmQM8d+M0lLQdrkfkLLKIY
Wo2LITAwYg/
TFiIJEGREfMKfxHfbsTBHdwsf1Q6JoE3qPwbNchtd3BuF8AfGwCscL2iDAHt1s0Ati
uWo9oCq3a5DMioNr4FNcOYFAghxMQooSxfYCMI5xQJRmdweJA2w3R224QElOF
WBGp9V5BAjXOPbuYiMmBCVjcUMy9wt8vR2+BbleiREdEuEmCx/
UhaNufmeKIaQRCX6OcdEdslg2ddRARiw80khgrkHBgWliUnzl5xnAwRJExJdMkH
PjfMWsNE4iAaBAhsCIQ+5MDfuEYmpa3DcLo7dejqfAaztcR/
Ayq6KA0CYAWQc2360W8p5RVp+A8LC+zC1H4YCYFatHd4lpfZ8FjPdJvyGjGYm
EWZzzCmJ0AWlOFeuBRW3YJimgAZZZAMz7hgQBm5OCpFGbdYgzLxwdOj9kWo
uPd97IjRYDRcbYTESsTd7D3hUx327GneMzwMzOftXAxaO7XIbddwbhfx0YFsVy
1GAVW7XI9N2y2KQaOkvKJSpIuB7KOpgW41AVKkKaHbzqhCgoFdyFuQtyF420L
abokffuuLKcFulRFiK1ItJuhsoIGCMkCU6il3hOpjHIwBhGyMDISW+Xo7/
AtqvRMPYLGZMIWO9QMLwOaIaYTB2WSqKBF9uNaEg3hPVAREXV3eqB8IGAZN
1bqhUxj8ycFODEQGlbI1/
UJFjERAzrO9olMFumqRNS1OG4XR2i9HU+A1naiZnpiG9DfYsBL94OAi4LCiMD9
Mg1kpzmrFk0XQu8di1SO7xLSuyJ7hIGZUkrERiIxFTS4qIyTP3DySzjIST16JvrIcte
BgLdYMHNsX7osmif1lKO43w3u9Ckd9u/
FLdrkN7u4N5v4wcC2a5bFdAVW7XIbQAYg2ok0iTaeEAk02SKuIPOnHj3m7jKdd
wCNmQyEAMAE0ziuUSHBIks+1RH+Zb5ejv8AAtqvcYBJYTyVYqFYsCIAEGYKce5
wCr64cplNNmdgxeImyWFxDty/
rEEEBMAsEai1eG4XR2i9HU+A1najtsSh6uye42FDjZpnjDQLWv5IRwkuvDIg7jzo
M6EYcyvW162miDCWamIOIYf0cFbvEtK7Ph2zxjco/
sWjN040TE7DK6RegP0tVAMGEG8jvWasCMjgPcKAgAbGFetJzwDbpAtzETEKjWo
NxvjkKRGXK8pFsAtmFuwt2Fswt2EeaRKwxGuleE3ITV4OIeAVXlWh1uQmFYloXi
6T2F1oTswih7ACOSIz2CwGW5CHo0QdYABHKA4IjAOCnCrWby3I1APZkiTAvOh7
ahIItJ9AyyD4MRZ0EhbALZhbsIF/
JEBzB9kaEGwGHkgCAwUCm4fMWIQC9QdAcSWhOSGGb1QrLwbxyuEGiTS8tG
ZZjRC4yYlfLyy2YWzC3YWzCBi3bRzmh9kSo0gegIkYgzEG1PRu3MvpFoKAgpg7
nUqN6NoriAD6A4bU+gBpJuDGEhIYuqYgO8PNMvQDcShaRYCQ4KiLJYJNRbsIwD
KvJRZzPLyU3YW7CNaAFww4Dv3vKSA7sIooSDWGFHSSvdhbsIKKAiYUWLdhbsJ
78uPFEjPcmotmEGpJi8JmrWKiS3YWzCwmrlMjZQoHbMLYBbMLdhbsLdhbsIahH
gF/
vG0NbMIoGhckGRsBgEQAiYFPEcNwK3YRZeGyEwo4Q2rkQ5JlC1bMLPduyaxK9i
1wTC3YW7CCxHztgwGhcALdhBeCRJaU0Kf+4//
aAAwDAQACAAMAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAFCMThSThQBzHkJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAANHBjRyBAAEPCBPDJCAARXDAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAELAOIRTgAFGEMygCxA
AAAAAAQAkABvBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AEADU5CAAMPNaYgCxAAAAAAAAAAAAAAAAACEARBAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAEPAiUjqNI7gTggAAAAAAAAAAAAAAEMDJLJAAA
AABHBzLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMGcJvWwwSBgAAAAAA
AAAAAAAAAAAMNDASigAAAQRBIAAAAlACOAAAAAAAAAAAAAAAAAAAAAAA
AAAAAADihAAAAAAAAAAAAAAAAAAAAFLY6xRAANGPNzAhlhIAgJAAAA2CALA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAeBiBKEG+
xgDRAAAAAAAAAHB3OAAAAzjRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAEbrppRBSBgAAAAAAAAAAAAAAAAAARISuAAAAAJAuAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCM
6AyJAAAACDRCAAAAAvAyJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAEPpCaagBCKmAAAACqAgAAAAAGBAJAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyaOAA
AAQARNAAAAAgJFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAANCYaAAAAARDADAAAAAWBzAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxzDiAAAAAAAF
AJAAAAACuyCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAeFAAAAAAQhXAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJFDCBBaCxREBAAAA
AAABLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAARzCyAihBgwBiAAAAAAAAEiJAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANIGLPDAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAFHHMJgUT0AMufPuHHKMLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYDDQjT
TxiCHzSXICTFJAABDhBJAEFwwYDDMAP7kJQoAaRjzjYThAZDHGAFCJAz5DADzVl
YlKqE1UTAImpG/
czgw1BhRAfUaALCDAAWAyGCAuXLDjSvQqlDDTLvAoSDI0pAqABDFXAWABCAr
ALQhJfsYApDZhsTripAjLALpABQzA/
UTXAjGJMDADFHA2XLDDQCWoXAhGr2AooAopBAqABSxHBijEAArArAniCTCfDn
gMCAWgpRQjALpABRhA5UtQKIEONIAAxVPgFrXLRNorBjZctCOhCAopAAqABCLr
GA+BOArAlGLZziiqjEqRAKiAPCCWAmoAGBDCrOhnPdCAARKCBTqHwDVrCCYhj
HQjHPGahUqDFCjAKDgCzVxOzCvKCCqJenQBqZTSKpEAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/
8QALREBAAECAwcEAwEBAQEBAAAAAQARMSFB0VFhcYGRobEQweHwIFDxQD
BgcJD/2gAIAQMBAT8Q/UB1QS/jz4luq8tYes6S0A5V8y+rlhLg9XWKt/
S6hzdZalzx8y0TsmBl7jtpCKBN3720ZzJt3wqwl56EdbOKstIOB/
ZfjrpSKuL+F4XkzZPjQ94i6HP4hnHvHKPRgLI8/
iXRvDGK0FH0rRo7phwo256MErU3Z9P2tqzmTbrgPxD33oaxto6uk2T4AS87zfU
FaEvh0ZsvxSOsHVmmjWX6rz0lpHPHzLQHI/
4FUIm+Y7ibrdJieBuv0iI0YYWjK1OvrrBBUt+tt+cybdcB+IG+8aGsfaOrNk+FCXq
eK+l1HgOkta8eZeAOekfbOS6Q116GsuieKy2jprBaCn+IPDjtL/
eM2q2j32ePRirHY0+0hlqn6YqrDiy6F4Yy+T2ibZxq6TZLgEbh6jLeulPMuAOKfM
bZOrM2ciXKrz0lpHOr7y0pyNP8NszmTInfSfeOktI8eYVVV4fklYFQY7NNIiqMyq5
mTKuuJmfoLLnOCaVcAy77j/I2b0e6xy1z0IhUuj7sFdekuAvOWEefeWFORp/
jtmcyWmrgPxDX3ihrHWDqzZvhQl+nm/ijVUZhio36xGrFv1/
Ie358dYnOiQE1GYLwFz7l/toKVllV4q+8s6cjSBT/
AC4yRxSbU8KsDfehrE2zq6TZnhQl6nivqC2l8OjNl+KR9g6vtD0jVgrq8/iO/
wCvxGXzo6TFmdj31lFKO/0p/
uhw0glqn444wFn7lERUftoFeiQOx58NP19njiywVcD+TVDpMnHLWXU66UgvAX
qyzrpNheKRFwc6+0fQNWAuPQm2nFfiWkdIJQU/
44yBKzjGzPltiI0ZWrhmZMqy4mZ+NDXPMmTXJ2xEJRINOFtbfn9UqFZrdDWG13
GfMPxM0dPmDunppMyPNlkEsKcjSW/xjW/PjrEx0SAmo/
bys8AufcvxTlUZfht7OMtKlG4OuvX92tLywnWviszU8tYus6RVwDp8wrfN3zKkK+
fxxxgLP3KUDY+eEOvRJVjA5bd5+KIKjK7jbGz49Fpfcdnx4ggqftqCtK8JZPzQ8My
NOCnzMSF4qxdnozNnQlyq89CA/N1hSujsbazYY+8yVWYC59y/
Gl7UlL4jJ+5wElEhJg+fzu/KvUuJpp0iJeOXPH43dIYSo/
vqFwuTshJslnJ+7JQjgLnufcPxWnUYvf8AHjrBRqQaX3Hbx3+fyyl7X53xwFElMOK
uaQG1R/eWUOKS7jzGLUcGYKtpUpt+0r+SAox6iwzNnDT0tLwfZ16/
lUFsjrujsqMukMzb8yuL44/u8YF5GkuQ6Rf+9ZhYPX/
hWMLYydGI0KJET4luHx+VH3BzJk1ycmVlfMza5mz/
AMMCpemPtA0U2P5pyqMaox29nGBP67paQf3aheWN6msuA+8ptJyYjary+Y5T
7QPk+I5Y6sXsO+sRZDlEz1WKDp2D5/4OAqM3CMZDJ8lf3SVlhekWyfecVyd9Yr
83WfUsdg9Wcbr8Ti9fib56/
Edu7aRDEO1x+P8AkdjV8YRUM3wf+KRunUidz1NYlcdSXAfeUNcy7pBw4syCv3i
0nwL5iln5fMDbsQNvpymTXfSKW7If6URkn1ui309o3j0ukXuybggtfoMr5+jpN/
6Ok3zozeujFsja4fMwtirv3L/
82z5GpXObj3m4946gU1zm495uPebj3igBhXOPaODvhsqYvaOaVpNx7xCCqB7a
zce8VQZgDjsHvslRg05xjmGWsEFT13Yi9Bm495uvVjlKW8x+YYWo+gyBrW8VJ
B47IMA121gMhWu3KDwa7azce83HvAWKWcvTBMWwfcIhwe8b5gYmsAVLRGR
pTbAwClLV9CicFM4h0qjSmM3HvNx7zce8LQFFc9+k3HvGVKVPQABwrnNx7yq
wKcWZ9C5mehu5eYVcT1YYWGKbkL0m494Jw8cXas3HvEQLgxCdaX4Tc+rD+I
8dlSCTFeMYmacYUwP6Y7H3mENW3CKwVXxDZivG8EiqZTce8EnPznKChVfENB
V4ztvdlSwqFZX/
AB8xMc00tbvKv4+ZuxU6RLbjS0S+4UtO8fLLHFnZe56dme3pvZgHGIEqsH1Ry
pXrPuhjKrvPc9/
Xt3w+ig01NnzOjZyZXRqfPp5HtPL8M7R8ztnxO0fMp1dL9pSiumNvRM+odUjhK
rAtUcqV6z6IY9SYXPcnbHidseX0798sr9dNFJX/
AB8+jYDru+ZVWKpspk+nae76WOB7ytYVCu2A8QtshmzaPB9LDxfaVBXKYvvg
5ZTtHw+n18PTtiI7ThLwA0m+PsxNI4mSM3sLDSze7F7QHeWktABSU0sYHAgA
YIy0AlZUqGYe5KSvE95TyxgcCUBzMD3fadt7sXqw7pvXVjuVcfL6dw+WXOL7en
ePlgtEObrElFPN19OzPb0TR+2IBnb6bZKp2jINsYuU2U1n1DWUBYJ4Pp2GsJOYdY
kc2nk9PI9p5fhnaPmds+J2j5lWNGVU04wjhHZ47CJRyr7QGLVPQtqq+IyjaTtjxO2
PPp375Zd4vt6+f5Z2T4fTtPd9LHA94jGqpSG3QXgmyavAi0mxhcOGUwVxGr9c
pRFbBpO1fD6fTw9O2PShC3kfErZk7nxCDbVgJtqeZSHJ3fiVl28n4lNb2OLN7z/
e0q6WA+3tKu7+D8yoUsxNOcqJo/
SZpEB2idt7sQWClM9tZ9p8QuuYZHp3D5Zc4vt6d4+WCArVhWxD3PTsj29GC5
Q9sYDvGMx6GxgnhN+
+Ps3llCoKNM903bqRJcD3egKxDWIlp3Y5MjF5fMxLImGOEaCpV3io2C9vmdo+Z
2z4naPmYHBgb2ir16KV5el7D4GHjxBN4xgOobGADUb4g5cWkfJE7nxByRwY4q
mQRVK5xyN3Hr6+f5Z2T4fTtPd9LHA94jGihWL7pDVTFjXbu5TDl3A5/
HpXJTZ9IiBcgIM14fT6eHoDAQJukc35nL6wVdIYLrEQyf5FV1lIN3F5/
Eppli8X4lWdGJDUpMWWcHnbv6WyK/
MYu5Q6+glZwyHazf8Ao6Tf+jpHFjDMTP0Y47uTt4RUCmLfl6NSu7k7XdBYKNW
8ARVp7k3vo6QAFWh7Tf8Ao6QYKwKCps2cIpRfR0jWRtftYK/r6hRNj4Zv/R0m/
wDR0jeQ2uHzLuVu7Y2WFdkRo7yYiXnYlUZwbG+F1Ao5OyVRnBsLnN/6Ok3/
AKOkRxobXS8I2CVwMNmmkRovR0j2RtftZ1Eu2N/
4sSxqNpjBlB9HSAiobM3QgU9N/wCjpAEUcfLDUDY+Gb/
0dIxhRp7voLUcCw745MYZjti0P3CHX1NzpHK2gbG7fLKKCAMcSbqNbSuFBt0jKo
oNMHMd23zN/wCjpLCx0zf+jpN/6Ok3/
o6QIEo0IKMlyg58pTgUwK77yuUrg07RIYZ1Gxyi0KxQPF2OkZ8cuZkcYQxjSpxM
Zv8A0dIBVGmPGKqpwdhuhVUWuU2//Iv/
xAAiEQADAQEAAgMBAQEBAQAAAAAAAREQMSAhQVBRMEBgcJD/
2gAIAQIBAT8Q+pqIxRWV+FZRH39RGKK/GMjK0oj8EE79rURiiivwjKKxBF/
JoNtX6+vqIKK/CMrEEEX+NpMamJz6iojFFbIyisQREX+Kogq/g/
xicE79BUVFKI8QQRf5KiMUUV+SZCR+TVxOCd/3Qi/
z1EYrxjKKxBBBWqDvi1RqYnfsIxRXkZRWIIIv5v8AGJwTvi1RqYq+s9keIIIiL/
I1cTgnfJqYv195URisd8WqNTE75NYv19xXinpBAx7QnfFqjUxO+T/
GJz79qntCd8mpif75NXE599UNpi75v8Yv15NUkE4W/d+iIgSS/
g6xvjyao1BOCd/4d1/BqCc+9qKiCCNKKxJ/F+jj7uIiIiCCCCCCBJL+T9s4/
wCMqKhhezn31KV/hWVlZRRWez2RkZGRkZGJT/
5ttzRPwCdwnRuYbi03ML+QNwVDcFQ3NFWNpeA4YndX1fAJ3C943NE7lniX1jo/
WG4KmOBO4Xsbgq10bgmZ0JXCU0lRKDODjOMbmmoN8a+YqGoN8a6x1hK6b
i01Bvg60xKrSpCUxczoSo4F3G+Mb0PmfGLmP0dQvQzi1uvUjG+BusT5OsrFzH
04x5c40u6XRtIg6sXDgXdLuOtVihwLul060zjeN4zoTg3RdxusaDex8z4xc8B9F3
CDcQunRwNVYvedCnyehTH04xiXoaUzjEqxNMbonsabZRIsTUG6dFQ1OsdY6P
WdwmhqdHQnGVLFzeNXM6EqP1huLK86sXMTUKh+0L0L2P0P2JRDfGWnWPuk
9kZHpp04xpnA+EY+EeP8EZQlNfCMjIxKDTIxKCCexCMjKF6GIyhKDVGmiMWox
cyMXM6OhKez2E9417FwjFwjIyMXBr2J8iCXvHWcD9ojENO/+Rv/
xAAuEAEAAgAEBAYCAgMBAQEAAAABABEQITFRQWGh8CBxgZGxwTDRYPFAU
OFwgLD/2gAIAQEAAT8Q/
i6vf35xih1EP3kyF7v5iGAd2+UCddV+WNUB4ETnFP0EyFlVmrzcUEoUhTtHj2IO
9C5UDjSv5pKg598SjKPJo94BLPwD3VPSCOn/
AIRzU0qlT0NXDrOKPb6eEho0Ife4fkfj8BUQC3ib7Rpt2tA9ic6PM/
4ArFIRXvLRZv8Ap6oZRPTS+7ygkUI6J/
P+bZzOsZKnYH84oK1Lh1EyjnJfAyl8FIke7EFecBBO0O5tir/
lFDP9a6RRhdbF+yGrmxm9T+bpARr9ix/
kkz0seV7QoPuwd2Ev4VLQC2BhVNQ3n2pOem3XX8pNL0GWKV5FF4aNxrIxl20
9a7ySKJreV8YECq0+yYPQSBIGDT+mKa9ryhFQAeuzvJl9mu+yvyboGT3EpzWk
Cs1fd64REa8Qr+4izJmyrWleTWBUDZpOSfy51oIUh0gp6XczQGNHviHUxuBAon
iD0npPh/
aZZsipFbrxsfyaIF2p9p6AdPvSGkLiFYBYpwbNeyu4qjnAg+lITm+zxzTSEVHsfnA
oLGU6PmPoTH1fQoXrkf10OpqNR8JG97c83F3hytRdb+T2rfSqcL0V49LjSl7jSCU
zsH7i3AspvSJLSwXtqBeyxVbX42mzcsPYjb5l+mm98zPPay1bFU61PN7/AJwh/
iZWXWG9wu6HGygwPQ/
ylDbDV6IOQsyr3tU1cVaXo+ARKQ0YszoizL6wYtXbD/
H2AAaq1AFULQKdZkuwv1MAdgkfccHDdqTQK2kvrbbB1fxC3TQsZ5aCiWJr3im
9u7YexEE2G37GbmuUH0I5uW+XikO5X6gYhaAUf6N3XlUnlmZPSZSXLhD5GW
SDgj4CjRm2/SwHWxezNk/jChqwO/
Pc9rgVuNifEtSTQQ+9zJgN09I65tiEst1qBeyxVbXjBY7XejkR8U2/
nJV1O5P2gtod1bABZHd5zOXDcfFSvbpx/cQeWaHxpKD/AFjRrSi16/
EmXWS68p4vA848l0bJxGMhmRyfNP4kxOdX5FiVc+L0sBQ5yn3bi5BNQ+iBCjQ
fq2xVzHhUi3afEd/
ebESN9ECKRNeP7SBryOQpZDgQdWMps1BD7E1xub5TDDJ9K/1AAA4B/
tV+CAAeCMfPGa939I/DErkTgjiLZ1WBojBzmGg/
Xyfwt2RapRG+Qr2qzMk2cD6QSjDgb9kAY2qVhav9qpOaglXXEFajlw1HoS7d0+
mEQHgIQacSP0EXYjb5FFPY3H4kbeir8/AoK4hfiDUXyD/
TqGrDhPEQ9FiFLbfFkqShsV94FfK6P1G7zpPCLyfuSAJ2slcbY/
YSpFnCD2OcAbQn5iGAsSuXu840cq+SPEcTKotiZIwtuOPc7fnAIqx/
gnMdfzLBmiaqXSX3ACgfe5UucBT0hpGEXzYz8izra/
wnNyaiCrtgVLb5yx7EZvYyHWoN23cYD7rOfSDXLQlfVmoDIA9ammfkP9TQibqo
EnjW19rm2FX6mE0/F5cipvTSX2VeEzLDNmHtHbbufgCkVNMbeoE4ydN0NI7/
AMkOXJ94BFWP5E5gqLP+zlHvFt9dDwZjVM65bvIOiAAOiJ/
vUFUAREajW3tcT4GxHvQjjgu/
WLKVtNevTc5Wx+1cUCfzvRF+258rKizr+9jY1GoAfaDRR/
RscsLrviclGfCH+s5vKVEouull7XGUY4frYIgDiZ0uCl3BDkYVEf8AEJfVOxt/
w9Sk9lPLjFLlI1n7bBHT8Y/8wOW+ODHan6WTts8Bks0arfdOUvKAaw/
3SSnePPkImRVTP5+ZaUbr0MVGLN2+aYfMdGydJ0FY+P8AXqGrAL7S82Ohpa/
SIIETQJ1uWgo4qzIdsw377Y82Kv5HqR2dleh8Efckqq8+I0VXHO/
E7w+o9TDTUQZQ5E7eGM4iNC3iqCwrR86cUkXJduB+OiIArEm+CQfQ+ABZw7
H4YyYDAeYDg/yhcG6hHWF7vdKXjYQ0aT6qUJ/HumKwrND+bRj0hA9iO23c/
EBWoo+8DQh0Bp60pFiq3N+MAlntrCgnj+3wEtOc+RLBd0BfW4IGnD4E8aDqQ
3jZI6Qw9Z6f2MXT3b62omng4+UDQ7HEmsvy/
YT8a3dWIHUSPZ0c6527l8CMXQ8ozA1QQX5BP5FzHGT1ZchrUFRam5mHW5b
ULiJH0ebM3Ky2vyv4AVoTkI1noQA9g+CMgG2SGd9VBAOcdxawSbePxRXQkX+
qN2hv8ESnbCCv8HWafZgM8mkbY8ch97wAZMqxaIkLyNsy/
XyfjQRHSUP5+XnwHlHPKlcicEx0p6HzAcRizKVc0+X+OFQRqF6sdRxpNRFqq3Q
dblkLNFGDqLti+MfJer118Nfmul7ABHSlcZ3kV3WBOcU+JFr5+TrUuO2PWAZvQ3
0gVs0KLqsBG+iI9idGw/yzZCpHMSc/M0+W/
wAols6pExFYpBsY8gXEPgecNqIWJ+MYxL4PpPOPLJXFGN/
FhUkZkLZD+LK3VElBC0Kf+QvAHgyp95uXRxIfZaRE7Ppl62HVeYeKDkfMszXY2
wq0/N+LNeXliPHeR9x27hsMqKW/6CUAHl+UzkGo/wBQMAnAz/
TKgvHpW78ka/
rZ7cPgXyg515+8hZ1YgdEfxtgqhZvthvnMHALxMQJMqRaIkODgXl+vk/
iZhwG6I8gHzMpRa+yUUWPOL/
qO2nzsctTts45aW78ohQRoqV0h9eWH+xL9niy3xwYoUzQnbZ4Do5o1q+4coC
Vt8A/
jP2EozmFLWtcaDoqDYkGo8mTX8TzgAKsf504UBqsDvltj5ibajs6ldFvQhhC0sfST
ShMVPU/HXGIViQGska/nTn4CiZy9HxsGp+4Hijgn4wR/
pqXBOCRdk0HwA0GhnnI3c8GKa1AdEf5ojJdQg9WaywX9AypLaUE9YpzeCjpRG
gLf9c2x/LCVfAkHNC/mrJlRFsmfn+8MiFYmYn4mV+sQOok1aDnnP38ngKJSaN/
UBsyTudDf8ahDHgvBGZn46z9/
gttXJ1526Dgovgfy9eaFr86wY23n3UlzukX7Q4FNlUUZumr8q4DKDA+h6HxBBn
miPvSZG3cnyYYLk6Q3OJ++XeYK/
uUHvodbSaudVrzNzBoQrPv2SXdFkLiP4tZqQY+XPgcTipKaiONJtMn9KQOEII9Zy
/GpEpSOYkoM+z4v26RyKqkckTEy93d/4GDYDIOa4o4J/
LCDNM6e+YTWwIkexucZFrl1ksYqxz79SZ04cv4EUsbzEU59w/
KABT99UFog8dLSbC76gxvlMD/
gODB7okelDBFvgPxitsQ+s5yh2T5JuOLco1NDxDiMKlzVZvt/
ICsh0fmbc0fyKvIYkLZNOz4gn7+4UN/54nI1kDZiuYjU/
swgV7tFUWfSa4eInBPxpCJa9bO5yi3lrntwY34CNSMVzZyB+TbDlzycpxIrl9HQ8
E4ji1gqPQQg44WrX2c/
54CAsdSVPJeVczY8onXFSUaiMBMvLcg32QLUcy64oOCfjcmLRy3xwYmVXZV9OI
WzqsDRGFUQAy/Xy/
kWmC1fMERWa48MjuwaJxDiMLredIdf+eiILkJXznnE0PSGjdcSLBbuByX+QYqS2
BABU8R9jEmJ4nRE4kZyhZefB/IH9mjquAeCQmsrf/
EcQWgriEoAKDSvjz8v5uqDGqPymS7aM9i44EexVB225g6rGqq3f9Ue7sRXrgRI
MQgs8ENUfynCMiFiRM6Zu1fSORVUjkiYs7vJoTbnQBFCOj+N6hrIGyTOBvWfvxh
0xUlGiJNFG5dydn828oENe87Q7zEbJd/sLHrN2o/
UuHzaKi57t6y69wQYBN21nvji/nM5c15u3NEygrymNq286+D/
ACKRKUjmJOYFxH4HlHJotI5I4CsVYmoUy4h93OACrHR/
8LyOrA8z5YXXmtXfPEwaYRkSBsSWVE9PDK6j8om0cB5u3NEegrimLiVrM+Tu54
GZC1gdEf8AwuyEkags9GqiIph8bhEfmRhRsw+0iSQ0eoOJiFknFXTzP/
C3dnrhkDzYq14sEw0lvIHw/nH6kU/mFENgLlU+HcwFEVRLHUjutflP/
AkagQCx9xJbg7F+4d15+GHKcb/
gJnw+c+oY5ruZsT7LsXzMwL2oh33YEyFPus0WIu7xfVv/
AAC1DujJ6c4lCTYprROThW/Fj5P+bKGrFwY1fnGc8IK/
DB1E7Go1Becl0V+lyKIZuL6htc9+NhVQgrjvf1SyvsdkRe/
RSO35nflhtee7+BzyhfKvAJXbWHtbfm/whSHqDZdKwedXoqt/
NSZWvYvclpmfCcP2vfctPWT9ReNbg/
U+UVy+slkKV5zf3A2YrLdOcFZznNwA23mE1i/
Ily2tRh4zRiR4GRmkfKRAclDCvH6P2SBsJo59F/hnAc3+Sj6w/wCJJt/
46oFsIhWc0dR9cFpxzyVf/HSEsZAfUO/G+AxjrRl9n/
xNL3Aw32Ifcsso1v8AfA7G5/
ujVWeVp27BtFMevH1NSORfyOD1WBQQiIhz4Yq1VnVwTMC0YNDAhGoMgP8Aw
FOm+SQqyeytnOmL/
bMoS9jKd8M7Q5RzyZrF8h8wknrR+4LXeT+pT1XIPqZLIDqnSd/
j5rKItMgr5JxlmG57H1db9xe3d1Y9bcz8QTmbqE7T94lBLxf50YC/
DoAUsh5wYSrk9cbAGEwJR5JNgk5D8ItbNwj0bzGYze9GA9qOa8AAAD3cPnh6Ku
3yi7h+5359zvT7n9Kn9Kn9Kn9Kn9Kn9Kn9Kn9Kj1HQTuz7nZP3HapOf78PTfev
niAA3P8AV6HG6ixBeWiClLQKA/8AzVjLGJOYrNZ3D9ztn7nbP3O2fuds/
cR17nnB7igAudM2dw/c7Z+52z9zun7nbP3O4fudw/
ctbtU1GmkjPbBijUc53D9yxpTKbssaAGCnYFncP3EltXbxgwjWjRGVehRK2LnbP3
Ete55w4RrDRHwJNRgw9LuU4Hmw+I9KNX4V/C5uTNA1VnbP3O2fud4/
cGUI9vGPAjV+FfGgrwGjtrO2fuNDq8YtLqM7AhQBqs7h+53D9yutnp2Go0FClA
M1YaTuec7Z+52z9ztn7nbP3Brvokeg+J1AtRA9Lnu8mviXw+rpH2HwU/
NVbYLOwfudw/cLEUQbExY8lebgLO4fuFHNCsjVoYuvyVBqlzuH7nbP3O6fud0/
c7x+52z9xEtI7eMaiNryK3m2qCljHbxncP3Ku2aFss8GnCTfMLO4fuds/
c7Z+52z9zKXDgz7D4i2bRgc1nbP3C+lRFNAz8GWOAQbrOwfudw/
ctKNU0MskmTAwYbrO2fudo/ca4aCojTmY0qLzFCyxZ3D9wT1ktToGcAqqCdw/
c7h+48CUGauZKQA1tjdZ3D9wSxHbxh6iiGiMbYclQ1HOds/
cSRdPjyDGyBQgbJc7h+5aXapqbJhb1OoZetXO0fudw/
cFRSiB4iYmSQUyHks7Z+53z9+ND1J+JHbtG7w877nxdv2SmZgdPzhoe2mFGZ
yZ3YCJsirQPfY1eurY4Pre2S9SKXfKJhBlesHjVP238JM7bHofMizS1ygiB4ayewHD
wavlO1bsOk/
HZONDovsrJGdZwLb8uIotHPbI4sXruAlNUq6ti4MzW2Q8kmjAeSO9kBbPJ2cOmY
RogoTh8XHvOT8T+DRO9bsagn4WxLYexiPUjlWMw+sgH5M2Joj4BFqB93r8YPw
KHUDYyregfoj3HHsW5+IqQIoRMpec3B6Qi7JmRAxB+1aHuMzqEwNdzIjyv8AkC
p299fnBjEnImVhhzmZD3qMVZXiVtwoXfnb7YNbGxuhke8bfukpbgd1lPfI6qwN6
guatHVIiNYKF7TmzDr84FrSLgFssd9gF6BgQrQ4DwMhLvfhH94n94nOGcUDMP7
xP7zEWgQwdouxH95n95gIUeLLvO7DoOKg3N88Xb9kpnYfT853jZM7rtGraDms
a6uj8riIlqMUfhnofQcoBEtFj4u578R19aJVPSDFUYgesZUMwIufGXMcsdadq3YdJ
+C8REH4m0pg+k7V+o93jq9nBBmXCSbGCZxvzBfmXpdXi1oHNjjLXNOCGNC7
1ihMbgVoCA+EFmI5iYoGidu249lyYvsqhf3Gf2HG1yvmT+8ShOqR2nZbGgZ42b
E2dukOvGhn9d3s1r4EAste/PFwExegnvWPetzHq/
GpAgLbzl58ORsUmGjSR6p1iWqsnJ+28Mufzsjm6nsKDMGj9vFINRJ1rvlgCz7d6l
PTLB/
uNl645Hi+6oIBMGsEPDYf3oMflA3NP5A1M5YPXAPmq6EIBT79e2ngQqKK7JL+rf
qf1b9T+vfqcnogSf1Sf1iEpLLPJgHm6Nk/rE/
rEDB2hRMncZ8Oi4h735Yu17ZTMw+n5zve2AnqicdC4PxPzBZoCGb4IXsOhAgx
S8J5VKjPxYeZ4adUGf2+PF3Pfir6mUsxmLSYT2jVnZaIcEHc0GkcLJ/
l5KHHWnYN+HS/
guHHCmiG3Km0BjvkBWptiVVGdmsti0D7HBwYmfKuQEGjYg5RYHSKWhPKoXIj5
pS35Y5E2LdZb9sTDR4NXZcmL3RSNE2f1iZhotwTsO+F46a4eDP6JFtX9H6hsND
GqBnjZsiKovJugDJR4J7Q9DO9TAhyHzwcWccHNmKtVY2s2zqotOJUf4+bWAAqx
w71uY9X4EQ7Nu8Gcb8nTY9MAetxFnI+QjP7AjudhpIgfq9LJXztIFXRAVCNKY8z9
5AowDCp8+k/VgBphQFlH354PJFJSMPqGZX6wDMu16oM/
SyiLQWNSDUMI8mcu/
UqWwaQd94LSwjhH8NDZAo0MQwwo6gCgjw8vFMNp4Dsm/
DPZMSdjjlyc+NQ3F2vbKZmHNEVdjllzizz/
iMBKmbjAt2h0BSdZqO+9BhQ87aPTxe87/
F3EQPnhbhxlPyXMdadt3YdL+C8RIDVaWqrAn9z/
ccA0mmb0YNzB5eDZAAKIyOb8kDgegiO/
wC5xNEorREpJ0ydirB2WW9UcTDR4NXZcnhP0DOw74d93eL9Qq8bNhBHKo28
4QYLTJ6y/
wCXSjrnD0L5QOLJ3UOyywlfLX2mkdlBhzvwOH1RMr9Yd63Mer8CId+3eDVzb2v
098LWIbZLJpY2NqWnvH01287o45O7lw1kTsavKz6jdWc5q8OndfR64ZOCu3OP
SKtVY2sOlTOxOb0IIoUPccMvq5Oxli2aJ2cC0HcU4HTgaQTqSmgJQo0vzC/
Ah7ju8HdtniA75v8AwO17ZTMw+si7Hhg6o1PNwvOcD5eA1lJe1MPmQwoQdrY
VBukOPgllPCZpRWug2ned/il/Noi4MrbH1fKMRofk4dL+S8cIBhICnk/
T0h5AiixNyN/9t4aTM+nwelT70AfFSoAujcTuuTAq22J0DOw74d93eKxQM/
GzZUllOe31uWAHm3eAFsXpVuQ5H2wqo8lOjoQnFcy8j4rAqC+FL2vDsW5j1fgV
Ls27wGVNjsKhj1zlpofXBLaA9pvH/EE7ubEACTP7uhMgpTy/
oMKXbTmqhA1zloq8FpZw8+Qwzpgb0XSWwvcLn1OGoluxoHqQSQqcQswobzX
x/YMoZ6tEdRMc0RB2Np4iG2WjDbbznb/3O8PuEKVarjTX8RBLvm/
DP1dyyUV7TpFP3v1EQtRQ2OLte2UzsPp+c7/
tjIAxuJmcFldttl36MNKIWJgsJZW42XqNS9qR3Vtwpshd+Gg62HYd/
hlrucigC1gItZGoGT7GGvKz5FMSzsw2Auc7Z7uDDdPZDwfHRvAcDLHKsXJ2/
wDcV/
wRaaAVuEjbRNkwV4SriF9NzK+8tisB8hpFMA8UDMRwHa0XxQyPVjsepwthSN8
4mdBntOHF2xVDu6Rk/GCzkOoAtZrI+gWGHAex53/
WPQM7Lvh3Hd4rFQz8TNrwjcAOjbMDEgagGgYUvo9N1+3ziTWCbBW8QRKGcx
SZrhqhLHtPUhCQU4hYzsW5j1fgRDs27w0enxX98HFhzLy53gAW6WxtuuERoCJ6
dbUmki8Ax1A2MQzB9GYHtgN009jgnbRfoAtYvyrJwcj7YK8zC8hQZJHMdtgVvzx
o38wNT9rxNIsH0eBK0o7q0Q+VV3Ne54kKkhBUNfPnMu7979zn+9+5l3fvfuOW
9c4bn4bAHfN+HTcRMzf8sXa9srmYbT852TZGsWx1Jq+j84k30cvYI6IHZmii+tz
OodfW7vFwGj6xLNASkKofnFByUaWqVxn9x+s/
uP1n9x+szgWsGWaqrzned+J2AjJUDflEjw3R1rDgI3mHGXEKJdR+2vpE6U3WiZ
aTfvd10w/qZUuUttcQJoA8gHx+DxwQD2LCrPUmT2HtLjNrLXimNrbVd1wN/
kPZis74NV04geGsgds9YSlhlkL1mRhq2VuYOwMPZVyAnGnL7x6QPiprwRk+jUW
04/BKcBwECiCcTYQZCZ5o9bilVzuSfGJI9THhldN49AzsO+Hcd3izUy/
GzY8nlSublCRZcj9PA8wnIkGxIcQIDgDodcK23qL6KxtLYlbrF7n7XO6bnj6kHOra1
apcyL6n9z+y/uf2f9xUUI1LVlKeetz1LIiNYgzPR88j26x6cv3AyOinwVn/
ADFD0KwMd9A3V7fONpbGss9+TN49+2Ydo2zR8vxYe07fhsZd134dFxUGd/
yxds2Ym6fnOybI0FglgckYvQrRanj5eEyCloMyxNNgLMvjnc9/
jNyKpKOBALiAUAaBMmz63b4jwJ0K2A4rkTT+q7gzfVv8hDggbFS0EK3BaoBXpn
zDZBUjmJGvo2JXwwVAWR4VfXNo/
DGhstym3nv4hsLdMp1GF5flQBQGPRM7Dvh3nd4v1Azxs26PC0SQGvCOY5y5v
C2PAckwdplc1088G3elyCxXnLC7zmrwOSFRS3/jO/vqd9fWLIZ7PNNeXOeq/
Jj134FI7LuYfY8r9MVRqOeaH2+Ywhkjiuh629sVpc8pnwJBQFGAiAXueAw+xN9JC
KQAOEek78+oRBZ0ZOfWOHJoCqWRvRyvwUzPRvDv2zDtWyaPliD5DWIT68YPc
5zmtdUIDMxS/wD1qoDBQUamuqPBRYcCmSOCgjZpazOKvJasWk/
oSE9yrUAgJryfxyOCr4yPkarggswRZoAB4I6wVttFY82sAmWwWBbqaPxYX7mZe
B4udP8AA+0xtUQPADnFAA9kfXuqbPS8ziSlpcpPEWgKAihs4oWKsmsMR89Tkxs
s6pvjFxxUfZnAnHA83IdDBYBo6owJ/Qk/
oScb492mKkEHVGB7vh57nBwA9EQEuqbPS8zPCVq9PFNQB7A6iQT+aRscjWBT
rYL7YZlid9n6NsSTXUK9PwIJTBZZy9bnwekdpHQ69o1ioghOmPwjE9JE1+WZUA
xA8FsjZiTAsDggG2uQxKgPnVAD3cecradBbTvp4Fkg6iiPxOxMOagw6szLCxrSsH
9xjzhfa2tzh5485US3ERM/
rFBhzrla04OSxFUySyAE8j1Z+WPPVfx6iyHzNZwELurp4we5znFntWzBcsHE81T
UdcOZfMTUDbDVEA0AhNAkR4jFamjqc4MOJBsrLDNffDX6PSBkPOM3/
OIrw4LWbIWvMemPmbuD/IY846BPniPRwLiy6U1MOaDX3AjS/wDuP//Z"
alt="Ethio-Djibouti Railway" style="height:54px;object-fit:contain"/>

</div>

<div class="hdr-center">

<div class="hdr-title">⚙ Ethio-Djibouti Railway — Engineering Project


Management Dashboard</div>

<div class="hdr-sub">Project Management Office (PMO) · Real-time


Monitoring & Control System</div>

</div>

<div class="hdr-right">

<div class="hdr-badges">

<span class="hbadge live">● LIVE</span>

<span class="hbadge date" id="hdr-date"></span>

<span class="hbadge admin" onclick="openLoginOverlay()" id="admin-


badge">🔐 Admin</span>

</div>

</div>

</div>

<!-- NAV -->

<div class="nav-bar" id="main-nav" style="display:none">

<div class="nav-tab active" onclick="showPage(this,'overview')">📊


Portfolio Overview</div>

<div class="nav-tab" onclick="showPage(this,'schedule')">📅 Project


Control</div>
<div class="nav-tab" onclick="showPage(this,'cost')">💰 Cost</div>

<div class="nav-tab" onclick="showPage(this,'resource')">👥


Resources</div>

<div class="nav-tab" onclick="showPage(this,'reports')">📋 Reports</div>

<div class="nav-tab" onclick="showPage(this,'settings')">⚙


Settings</div>

<div class="nav-tab"
onclick="showPage(this,'auditlog');renderAuditLog()">🔍 Audit Log</div>

</div>

<!-- PAGES WRAPPER -->

<div id="pages-wrap" style="display:none">

<!-- ═══════ PAGE: OVERVIEW ═══════ -->

<div class="page active" id="page-overview">

<div class="row">

<!-- KPI tiles -->

<div class="widget fw25">

<div class="wh blue">PORTFOLIO KPIs — PORTFOLIO OVERVIEW <span


id="ov-add-btn"></span></div>

<div class="wb">

<div class="kpi-grid" style="grid-template-columns:1fr 1fr;gap:6px">

<div class="kpi green-kpi"><div class="kpi-val" id="kpi-


projects">6</div><div class="kpi-lbl">Active Projects</div></div>

<div class="kpi blue-kpi"><div class="kpi-val" id="kpi-total-


budget">2.85B</div><div class="kpi-lbl">Total Budget (ETB)</div></div>

<div class="kpi orange-kpi"><div class="kpi-val" id="kpi-budget-


util">71%</div><div class="kpi-lbl">Budget Utilization</div></div>
<div class="kpi green-kpi"><div class="kpi-val" id="kpi-portfolio-
progress">68%</div><div class="kpi-lbl">Portfolio Progress</div></div>

<div class="kpi red-kpi"><div class="kpi-val"


id="kpi-safety">2</div><div class="kpi-lbl">Safety Incidents</div></div>

<div class="kpi orange-kpi"><div class="kpi-val" id="kpi-


pending">5</div><div class="kpi-lbl">Pending Approvals</div></div>

</div>

<div style="margin-top:10px">

<div style="text-align:center;margin-bottom:6px">

<svg width="110" height="110" viewBox="0 0 110 110">

<circle cx="55" cy="55" r="42" fill="none" stroke="#e8f0e8"


stroke-width="14"/>

<circle cx="55" cy="55" r="42" fill="none" stroke="#27ae60"


stroke-width="14" stroke-dasharray="158 106" stroke-dashoffset="30"
stroke-linecap="round"/>

<circle cx="55" cy="55" r="42" fill="none" stroke="#f39c12"


stroke-width="14" stroke-dasharray="60 204" stroke-dashoffset="-128"
stroke-linecap="round"/>

<circle cx="55" cy="55" r="42" fill="none" stroke="#e74c3c"


stroke-width="14" stroke-dasharray="46 218" stroke-dashoffset="-188"/>

<text x="55" y="50" text-anchor="middle" class="donut-


pct">68%</text>

<text x="55" y="62" text-anchor="middle" class="donut-sub">Avg


Progress</text>

</svg>

</div>

<div style="font-size:9px;line-height:1.9">

<div><span style="display:inline-
block;width:9px;height:9px;background:#27ae60;border-radius:2px;margin-
right:4px;vertical-align:middle"></span>On Track: 3 projects</div>
<div><span style="display:inline-
block;width:9px;height:9px;background:#f39c12;border-radius:2px;margin-
right:4px;vertical-align:middle"></span>At Risk: 2 projects</div>

<div><span style="display:inline-
block;width:9px;height:9px;background:#e74c3c;border-radius:2px;margin-
right:4px;vertical-align:middle"></span>Delayed: 1 project</div>

</div>

</div>

</div>

</div>

<!-- Project Health -->

<div class="widget fw75">

<div class="wh green">PROJECT PORTFOLIO — ETHIO-DJIBOUTI RAILWAY


— ALL PROJECTS

<div style="display:flex;gap:6px">

<button class="add-btn" onclick="openModal('add-project')">+ Add


Project</button>

<button class="edit-btn blue" onclick="exportTable()">⬇ Export


CSV</button>

</div>

</div>

<div class="wb" style="padding:6px">

<table class="tbl" id="ov-project-table">

<thead><tr><th>#</th><th>Project Name</th><th>Project
Manager</th><th>Phase</th><th>Baseline Start</th><th>Baseline
Finish</th><th>Budget
(ETB)</th><th>Spent</th><th>Progress</th><th>Status</th><th
id="ov-action-th" style="display:none">Actions</th></tr></thead>

<tbody id="ov-tbody"></tbody>
</table>

</div>

</div>

</div>

<div class="row">

<!-- Portfolio Progress Bars -->

<div class="widget fw2">

<div class="wh green">PROGRESS BY PROJECT</div>

<div class="wb" id="port-progress-bars"></div>

</div>

<div class="widget fw2">

<div class="wh teal">BUDGET UTILIZATION</div>

<div class="wb" id="port-budget-bars"></div>

</div>

</div>

<div class="row">

<div class="widget fw2">

<div class="wh teal">PROJECT STATUS SUMMARY</div>

<div class="wb" id="ov-task-breakdown"></div>

</div>

</div>

</div>

<!-- ═══════ PAGE: SCHEDULE ═══════ -->


<div class="page" id="page-schedule">

<!-- ── PROJECT SELECTOR BAR ── -->

<div class="sched-proj-bar">

<span class="sched-proj-label">📂 PROJECT:</span>

<select class="sched-proj-sel" id="sched-global-project"


onchange="onScheduleProjectChange()">

</select>

<span class="sched-proj-label" style="margin-left:12px">VIEW:</span>

<select class="sched-view-sel" id="sched-global-view"


onchange="onScheduleProjectChange()">

<option value="monthly">Monthly</option>

<option value="weekly">Weekly</option>

<option value="daily">Daily</option>

</select>

<div class="sched-proj-info">

<span class="sched-proj-tag" id="sched-proj-status-tag">On


Track</span>

<span class="sched-proj-tag" id="sched-proj-progress-tag">67%


Complete</span>

<span class="sched-proj-tag" id="sched-proj-spi-tag">SPI: 0.94</span>

<button class="edit-btn blue" onclick="[Link]('sched-


master-upload').click()" style="font-size:9px;padding:3px 8px">⬆ Upload
Schedule</button>

<input type="file" id="sched-master-upload" accept=".xml,.xlsx,.xls,.csv"


style="display:none" onchange="importMasterSchedule(this)">

</div>

</div>
<!-- ── Schedule KPI Strip ── -->

<div class="sched-kpi-strip">

<div class="sched-kpi orange"><div class="sched-kpi-val" id="sk-


delayed">2</div><div class="sched-kpi-lbl">DELAYED
ACTIVITIES</div></div>

<div class="sched-kpi red"><div class="sched-kpi-val" id="sk-


critical">3</div><div class="sched-kpi-lbl">CRITICAL
ACTIVITIES</div></div>

<div class="sched-kpi blue"><div class="sched-kpi-val" id="sk-


progress">67%</div><div class="sched-kpi-lbl">PHYSICAL
PROGRESS</div></div>

<div class="sched-kpi purple"><div class="sched-kpi-val" id="sk-


spi">0.94</div><div class="sched-kpi-lbl">SCHEDULE PERF.
INDEX</div></div>

<div class="sched-kpi orange"><div class="sched-kpi-val" id="sk-


variance">-18d</div><div class="sched-kpi-lbl">SCHEDULE
VARIANCE</div></div>

<div class="sched-kpi"><div class="sched-kpi-val" id="sk-


milestones">4/12</div><div class="sched-kpi-lbl">MILESTONES
COMPLETED</div></div>

</div>

<!-- ── Row 1: Master Gantt Chart ── -->

<div class="row">

<div class="widget f1">

<div class="wh blue" style="background:linear-


gradient(90deg,#0a3d1f,#1a6b3a)">

<span id="gantt-title">INTEGRATED MASTER GANTT CHART — PROJECT


SCHEDULE JAN–DEC 2026</span>

<div style="display:flex;gap:5px;flex-wrap:wrap">

<button class="add-btn" onclick="openModal('add-task')">+ Add


Task</button>
<button class="edit-btn blue" onclick="exportScheduleCSV()">⬇
Export</button>

<button class="edit-btn blue"


onclick="[Link]('schedule-csv-input').click()"
style="background:#27ae60">⬆ CSV</button>

<button class="edit-btn blue" onclick="showMSPHelp()"


style="background:#2980b9">⬆ MS Project</button>

<button class="edit-btn blue"


onclick="[Link]('schedule-excel-input').click()"
style="background:#d35400">⬆ Excel</button>

<input type="file" id="schedule-csv-input" accept=".csv"


style="display:none" onchange="importScheduleCSV(this)">

<input type="file" id="schedule-msp-input" accept=".xml"


style="display:none" onchange="importMSProject(this)">

<input type="file" id="schedule-excel-input" accept=".xlsx,.xls"


style="display:none" onchange="importExcelSchedule(this)">

<div id="msp-help-overlay"
style="display:none;position:fixed;inset:0;background:rgba(0,0,0,0.55);z-
index:9999;align-items:center;justify-content:center">

<div style="background:#fff;border-radius:10px;padding:24px
28px;max-width:420px;width:90%;box-shadow:0 8px 32px
rgba(0,0,0,0.25);font-family:inherit">

<div style="display:flex;justify-content:space-between;align-
items:center;margin-bottom:14px">

<span style="font-size:13px;font-weight:800;color:#0a3d1f;letter-
spacing:.5px">UPLOAD MS PROJECT FILE</span>

<button onclick="[Link]('msp-help-
overlay').[Link]='none'" style="background:none;border:none;font-
size:18px;cursor:pointer;color:#555">✕</button>

</div>

<div style="background:#fff8e1;border:1px solid #f39c12;border-


radius:6px;padding:10px 12px;margin-bottom:14px;font-
size:11px;color:#7d5a00;line-height:1.6">
<strong>⚠ Important:</strong> Export your MS Project file as XML
first.

</div>

<div style="font-size:11px;color:#333;line-height:1.8;margin-
bottom:16px">

1. Open in <strong>Microsoft Project</strong> → File → Save


As<br>

2. Set type to <strong>XML Format (*.xml)</strong> → Save<br>

3. Upload the .xml file below ↓

</div>

<div style="display:flex;gap:10px">

<button onclick="[Link]('schedule-msp-
input').click();[Link]('msp-help-
overlay').[Link]='none'"
style="flex:1;padding:9px;background:#2980b9;color:#fff;border:none;bord
er-radius:6px;font-size:11px;font-weight:700;cursor:pointer">📂 Choose XML
File</button>

<button onclick="[Link]('msp-help-
overlay').[Link]='none'" style="padding:9px
14px;background:#eee;color:#555;border:none;border-radius:6px;font-
size:11px;cursor:pointer">Cancel</button>

</div>

</div>

</div>

</div>

</div>

<div class="wb" style="padding:8px 10px;overflow-x:auto">

<div id="g26-legend" class="g26-legend"></div>

<div class="g26-wrap">

<div class="g26-hdr" id="gantt-months-hdr"></div>


<div id="gantt-chart"></div>

</div>

<div id="g26-tooltip" class="g26-tooltip"></div>

<div id="scurve-tooltip"
style="position:fixed;background:#1a2a1a;color:#fff;padding:8px
12px;border-radius:5px;font-size:10px;z-index:9999;pointer-
events:none;display:none;max-width:200px;box-shadow:0 4px 16px
rgba(0,0,0,.4);border-left:3px solid #27ae60;line-height:1.6"></div>

</div>

</div>

</div>

<!-- ── Row 2: Physical S-Curve + Financial S-Curve ── -->

<div class="row">

<div class="widget f1">

<div class="wh teal" style="flex-wrap:wrap;gap:6px;padding:7px 10px">

<span style="font-weight:800;letter-spacing:.5px;flex-shrink:0">📈
PHYSICAL PROGRESS S-CURVE</span>

<div style="display:flex;gap:6px;align-items:center;margin-left:auto;flex-
wrap:wrap">

<select id="scurve-project-select"

onchange="onSCurveControlChange()"

style="background:#0e6655;color:#fff;border:1px solid
rgba(255,255,255,.35);border-radius:4px;

padding:3px 24px 3px 8px;font-size:10px;font-weight:700;font-


family:inherit;

cursor:pointer;outline:none;appearance:none;-webkit-
appearance:none;

background-image:url('data:image/svg+xml,<svg xmlns=
%22[Link] width=%2210%22 height=%226%22
viewBox=%220 0 10 6%22><path d=%22M0 0l5 6 5-6z%22 fill=%22%23fff
%22/></svg>');

background-repeat:no-repeat;background-position:right 7px
center;min-width:160px">

</select>

<select id="scurve-view-select"

onchange="onSCurveControlChange()"

style="background:#0e6655;color:#fff;border:1px solid
rgba(255,255,255,.35);border-radius:4px;

padding:3px 24px 3px 8px;font-size:10px;font-weight:700;font-


family:inherit;

cursor:pointer;outline:none;appearance:none;-webkit-
appearance:none;

background-image:url('data:image/svg+xml,<svg xmlns=
%22[Link] width=%2210%22 height=%226%22
viewBox=%220 0 10 6%22><path d=%22M0 0l5 6 5-6z%22 fill=%22%23fff
%22/></svg>');

background-repeat:no-repeat;background-position:right 7px
center;min-width:100px">

<option value="monthly">Monthly</option>

<option value="weekly">Weekly</option>

<option value="daily">Daily</option>

</select>

</div>

</div>

<div class="wb" style="padding:8px 10px">

<div id="scurve-container" class="scurve-wrap">

<svg id="scurve-svg" class="scurve-svg" viewBox="0 0 720 200"


preserveAspectRatio="none"></svg>

</div>
<div class="scurve-legend">

<div class="scurve-leg"><div class="scurve-leg-line"


style="background:#2980b9"></div> Planned Physical</div>

<div class="scurve-leg"><div class="scurve-leg-line"


style="background:#27ae60"></div> Actual Physical</div>

<div class="scurve-leg"><div class="scurve-leg-line"


style="background:#e74c3c;border-top:2px dashed
#e74c3c;height:0"></div> Variance Gap</div>

<div class="scurve-leg"><div class="scurve-leg-line"


style="background:#8e44ad;border-top:2px dashed
#8e44ad;height:0"></div> Forecast</div>

</div>

<div id="scurve-stats" style="display:flex;gap:10px;flex-


wrap:wrap;margin-top:8px;padding:8px;background:#f4f9f2;border-
radius:4px;border:1px solid #c8d8c8"></div>

</div>

</div>

</div>

<!-- ── Row 2b: Financial S-Curve ── -->

<div class="row">

<div class="widget f1">

<div class="wh" style="background:linear-


gradient(90deg,#1a3a5c,#2980b9);flex-wrap:wrap;gap:6px;padding:7px
10px">

<span style="font-weight:800;letter-spacing:.5px;flex-shrink:0">💰
FINANCIAL PROGRESS S-CURVE</span>

<span style="font-size:9px;color:#a8d0f0;font-weight:600;margin-
left:auto" id="fin-scurve-proj-label"></span>

</div>

<div class="wb" style="padding:8px 10px">


<div class="scurve-wrap">

<svg id="fin-scurve-svg" class="fin-scurve-svg" viewBox="0 0 720


170" preserveAspectRatio="none"></svg>

</div>

<div class="scurve-legend">

<div class="scurve-leg"><div class="scurve-leg-line"


style="background:#1a5276"></div> Planned Financial</div>

<div class="scurve-leg"><div class="scurve-leg-line"


style="background:#2ecc71"></div> Actual Financial</div>

<div class="scurve-leg"><div class="scurve-leg-line"


style="background:#e74c3c;border-top:2px dashed
#e74c3c;height:0"></div> Variance</div>

<div class="scurve-leg"><div class="scurve-leg-line"


style="background:#f39c12;border-top:2px dashed
#f39c12;height:0"></div> Forecast</div>

</div>

<div id="fin-scurve-stats" style="display:flex;gap:10px;flex-


wrap:wrap;margin-top:8px;padding:8px;background:#f0f4f9;border-
radius:4px;border:1px solid #b0cce8"></div>

</div>

</div>

</div>

<!-- ── Row 3: Activity Performance Dashboard ── -->

<div class="row">

<div class="widget f1">

<div class="wh" style="background:linear-


gradient(90deg,#1a252f,#2c3e50);flex-wrap:wrap;gap:6px">

<span>📋 ACTIVITY PERFORMANCE DASHBOARD</span>

<div style="display:flex;gap:5px;flex-wrap:wrap;margin-left:auto">
<input id="act-search" type="text" placeholder="Search activities…"
oninput="renderActivityDashboard()"
style="background:#2c3e50;color:#fff;border:1px solid
rgba(255,255,255,.3);border-radius:3px;padding:3px 8px;font-size:9px;font-
family:inherit;outline:none;width:140px">

<select id="act-status-filter" onchange="renderActivityDashboard()"


style="background:#2c3e50;color:#fff;border:1px solid
rgba(255,255,255,.3);border-radius:3px;padding:3px 8px;font-size:9px;font-
family:inherit;outline:none">

<option value="all">All Status</option>

<option value="completed">Completed</option>

<option value="in-progress">In Progress</option>

<option value="upcoming">Upcoming</option>

<option value="delayed">Delayed</option>

<option value="critical">Critical</option>

</select>

<button class="edit-btn blue" onclick="[Link]('act-


schedule-upload').click()" style="font-size:9px">⬆ Import</button>

<input type="file" id="act-schedule-upload"


accept=".xml,.xlsx,.xls,.csv" style="display:none"
onchange="importActivitySchedule(this)">

</div>

</div>

<div class="wb" style="padding:6px;overflow-x:auto">

<div id="activity-dashboard-wrap" style="max-height:340px;overflow-


y:auto">

<table class="act-tbl" id="activity-dashboard-tbl">

<thead><tr>

<th>Activity Name</th>

<th>ID</th>
<th>Start</th>

<th>Finish</th>

<th>Physical %</th>

<th>Financial %</th>

<th>Status</th>

<th>Variance (d)</th>

<th>Owner</th>

</tr></thead>

<tbody id="activity-dashboard-tbody"></tbody>

</table>

</div>

<div id="activity-summary-strip" style="display:flex;gap:8px;margin-


top:8px;flex-wrap:wrap"></div>

</div>

</div>

</div>

<!-- ── Row 4: Milestone & Activity Dashboard + Delay & Critical ── -->

<div class="row">

<div class="widget fw66">

<div class="wh green" style="flex-wrap:wrap;gap:6px">

<span>🏁 MILESTONE &amp; ACTIVITY DASHBOARD</span>

<div style="margin-left:auto;display:flex;gap:5px">

<button class="edit-btn blue" onclick="[Link]('ms-


schedule-upload').click()" style="font-size:9px">⬆ Import</button>

<input type="file" id="ms-schedule-upload"


accept=".xml,.xlsx,.xls,.csv" style="display:none"
onchange="importMilestoneSchedule(this)">
<button class="add-btn" id="add-milestone-btn"
style="display:none;font-size:9px;padding:2px 8px"
onclick="addMilestone()">+ Add</button>

</div>

</div>

<div class="wb" style="padding:6px 10px;max-height:480px;overflow-


y:auto" id="sched-milestones"></div>

</div>

<div class="widget f1">

<div class="wh red" style="background:linear-


gradient(90deg,#7b241c,#c0392b);flex-wrap:wrap;gap:6px">

<span>⚠ DELAY &amp; CRITICAL ACTIVITIES</span>

<button class="edit-btn" onclick="[Link]('delay-


sched-upload').click()" style="font-size:9px;margin-left:auto">⬆
Import</button>

<input type="file" id="delay-sched-upload" accept=".xml,.xlsx,.xls,.csv"


style="display:none" onchange="importDelaySchedule(this)">

</div>

<div class="wb" style="padding:8px 10px;max-height:480px;overflow-


y:auto" id="delay-analysis"></div>

</div>

</div>

<!-- ── Upcoming Critical Milestones by Project ── -->

<div class="row" style="margin-top:4px">

<div class="widget f1">

<div class="wh orange" style="display:flex;align-items:center;justify-


content:space-between;flex-wrap:wrap;gap:6px">

<span id="pc-ms-section-title">🚩 UPCOMING CRITICAL MILESTONES —


BY PROJECT</span>
<div style="display:flex;gap:6px;align-items:center;flex-wrap:wrap">

<span id="pc-ms-summary-badge"
style="background:rgba(255,255,255,.18);border:1px solid
rgba(255,255,255,.35);border-radius:3px;padding:2px 10px;font-
size:9px;font-weight:700;color:#fff;white-space:nowrap"></span>

<!-- Filter buttons -->

<button id="ms-filter-all" onclick="setMilestoneFilter('all')"


style="background:rgba(255,255,255,.25);color:#fff;border:1px solid
rgba(255,255,255,.5);border-radius:3px;padding:2px 8px;font-size:8px;font-
weight:700;cursor:pointer;font-family:inherit">All</button>

<button id="ms-filter-overdue" onclick="setMilestoneFilter('overdue')"


style="background:transparent;color:rgba(255,255,255,.75);border:1px solid
rgba(255,255,255,.3);border-radius:3px;padding:2px 8px;font-size:8px;font-
weight:700;cursor:pointer;font-family:inherit">🔴 Overdue</button>

<button id="ms-filter-duesoon" onclick="setMilestoneFilter('duesoon')"


style="background:transparent;color:rgba(255,255,255,.75);border:1px solid
rgba(255,255,255,.3);border-radius:3px;padding:2px 8px;font-size:8px;font-
weight:700;cursor:pointer;font-family:inherit">🟡 Due Soon</button>

<button id="ms-filter-delayed" onclick="setMilestoneFilter('delayed')"


style="background:transparent;color:rgba(255,255,255,.75);border:1px solid
rgba(255,255,255,.3);border-radius:3px;padding:2px 8px;font-size:8px;font-
weight:700;cursor:pointer;font-family:inherit">⚠ Delayed</button>

<label style="font-size:9px;color:rgba(255,255,255,.85);font-
weight:600;display:flex;align-items:center;gap:4px;cursor:pointer;white-
space:nowrap;margin-left:4px">

<input type="checkbox" id="pc-ms-show-all"


onchange="renderPCMilestones()" style="accent-color:#fff;cursor:pointer">
Show all upcoming

</label>

</div>

</div>

<div id="pc-milestones-wrap" style="overflow-x:auto"></div>

</div>
</div>

<!-- ── Recent Achievements & Activity Logs by Project ── -->

<div class="row" style="margin-top:4px">

<div class="widget f1">

<div class="wh dark" style="background:linear-


gradient(90deg,#1a252f,#2c3e50);display:flex;align-items:center;justify-
content:space-between;flex-wrap:wrap;gap:6px">

<span>📋 RECENT ACHIEVEMENTS &amp; ACTIVITY LOGS — BY


PROJECT</span>

<div style="display:flex;gap:6px;align-items:center">

<span id="pc-activity-proj-label" style="font-


size:9px;color:rgba(255,255,255,.8);font-weight:700;padding:2px
8px;background:rgba(255,255,255,.12);border-radius:3px;border:1px solid
rgba(255,255,255,.25)"></span>

<select id="pc-activity-type-filter"
onchange="renderPCActivityByProject()"
style="background:#2c3e50;color:#fff;border:1px solid
rgba(255,255,255,.3);border-radius:3px;padding:3px 8px;font-size:9px;font-
family:inherit;outline:none">

<option value="all">All Types</option>

<option value="milestone">Milestones</option>

<option value="activity">Activities</option>

</select>

</div>

<!-- hidden for legacy compat -->

<select id="pc-activity-proj-filter" style="display:none">

<option value="ALL">All Projects</option>

</select>

</div>
<div id="pc-activity-by-project" style="padding:8px 10px"></div>

</div>

</div>

<!-- hidden elements kept for backward compat -->

<div style="display:none">

<div id="phase-grid"></div>

<div id="sched-phases"></div>

<div id="sched-calendar"></div>

<div id="ov-milestones"></div>

<span id="ms-summary-badge"></span>

<input type="checkbox" id="ms-show-all">

<div id="ov-activity"></div>

<div id="ov-glance"></div>

</div>

</div>

<!-- ═══════ PAGE: COST ═══════ --><div class="page" id="page-cost">

<!--
══════════════════════════════════════════════════════
PRIMARY PROJECT SELECTOR BAR

══════════════════════════════════════════════════════
-->

<div class="cost-selector-bar">

<span class="cost-sel-label">📂 PROJECT:</span>


<select class="cost-proj-sel" id="cost-project-select"
onchange="onCostProjectChange()">

<option value="ALL">📊 All Projects — Portfolio View</option>

</select>

<div style="display:flex;gap:6px;flex-wrap:wrap">

<button class="cost-upload-btn"
onclick="[Link]('cost-excel-upload').click()">⬆ Upload
Excel</button>

<button class="cost-upload-btn"
onclick="[Link]('cost-msp-upload').click()">⬆ Upload MS
Project</button>

<button class="cost-upload-btn" onclick="exportCostCSV()">⬇ Export


CSV</button>

<input type="file" id="cost-excel-upload" accept=".xlsx,.xls"


style="display:none" onchange="importCostExcel(this)">

<input type="file" id="cost-msp-upload" accept=".xml"


style="display:none" onchange="importCostMSP(this)">

</div>

<div class="cost-sel-info">

<span class="cost-sel-tag" id="cost-sel-tag-phase"


style="display:none"></span>

<span class="cost-sel-tag" id="cost-sel-tag-manager"


style="display:none"></span>

<span class="cost-sel-tag" id="cost-sel-tag-status"


style="display:none"></span>

</div>

</div>

<!--
══════════════════════════════════════════════════════
PROJECT COST SUMMARY — appears immediately below selector
══════════════════════════════════════════════════════
-->

<div class="row" style="margin-top:8px">

<div class="pcs-panel f1" style="flex:1;min-width:0">

<div class="pcs-header">

<span class="pcs-title" id="pcs-title">📊 PROJECT COST SUMMARY —


ALL PROJECTS (PORTFOLIO)</span>

<span class="pcs-status-badge portfolio" id="pcs-status-


badge">PORTFOLIO VIEW</span>

</div>

<div class="pcs-grid" id="pcs-grid">

<!-- 10 cells populated by JS: BAC, AC, EV, PV, CPI, SPI, EAC, VAC, Util%,
Status -->

<div class="pcs-cell bac"><div class="pcs-cell-val" id="pcs-bac">—


</div><div class="pcs-cell-lbl">BAC</div><div class="pcs-cell-sub"
style="color:#888">Budget at Completion</div></div>

<div class="pcs-cell ac"><div class="pcs-cell-val"


id="pcs-ac">—</div><div class="pcs-cell-lbl">AC</div><div class="pcs-
cell-sub" style="color:#888">Actual Cost to Date</div></div>

<div class="pcs-cell ev"><div class="pcs-cell-val"


id="pcs-ev">—</div><div class="pcs-cell-lbl">EV</div><div class="pcs-
cell-sub" style="color:#888">Earned Value</div></div>

<div class="pcs-cell pv"><div class="pcs-cell-val"


id="pcs-pv">—</div><div class="pcs-cell-lbl">PV</div><div class="pcs-
cell-sub" style="color:#888">Planned Value</div></div>

<div class="pcs-cell cpi"><div class="pcs-cell-val"


id="pcs-cpi">—</div><div class="pcs-cell-lbl">CPI</div><div class="pcs-
cell-sub" id="pcs-cpi-sub" style="color:#888">Cost
Performance</div></div>

<div class="pcs-cell spi"><div class="pcs-cell-val"


id="pcs-spi">—</div><div class="pcs-cell-lbl">SPI</div><div class="pcs-
cell-sub" id="pcs-spi-sub" style="color:#888">Schedule
Performance</div></div>

<div class="pcs-cell eac"><div class="pcs-cell-val" id="pcs-eac">—


</div><div class="pcs-cell-lbl">EAC</div><div class="pcs-cell-sub"
style="color:#888">Estimate at Completion</div></div>

<div class="pcs-cell vac"><div class="pcs-cell-val" id="pcs-vac">—


</div><div class="pcs-cell-lbl">VAC</div><div class="pcs-cell-sub"
id="pcs-vac-sub" style="color:#888">Variance at Completion</div></div>

<div class="pcs-cell util" style="grid-column:span 2">

<div class="pcs-cell-val" id="pcs-util">—</div>

<div class="pcs-cell-lbl">Budget Utilization %</div>

<div class="pcs-util-bar"><div class="pcs-util-bar-f" id="pcs-util-bar"


style="width:0%;background:#27ae60"></div></div>

<div class="pcs-cell-sub" id="pcs-util-sub" style="color:#888;margin-


top:3px">of approved budget spent</div>

</div>

</div>

</div>

</div>

<!--
══════════════════════════════════════════════════════
SECTION 1: EVM + COST VARIANCE ANALYSIS

══════════════════════════════════════════════════════
-->

<div class="row" style="margin-top:8px" id="cost-row-evm">

<div class="widget f1">

<div class="wh purple">📐 EARNED VALUE MANAGEMENT (EVM) —


DETAILED TABLE</div>
<div class="wb" style="padding:8px 10px">

<div style="overflow-x:auto" id="evm-table-wrap">

<table class="tbl" id="evm-table">

<thead><tr><th>Project</th><th>BAC (ETB)</th><th>PV
(ETB)</th><th>EV (ETB)</th><th>AC (ETB)</th><th>CV
(EV-AC)</th><th>SV
(EV-PV)</th><th>CPI</th><th>SPI</th><th>EAC</th><th>VAC</th></tr
></thead>

<tbody id="evm-tbody"></tbody>

</table>

</div>

</div>

</div>

</div>

<!--
══════════════════════════════════════════════════════
SECTION 2: COST VARIANCE + BUDGET vs ACTUAL

══════════════════════════════════════════════════════
-->

<div class="row" id="cost-row-variance">

<div class="widget fw2">

<div class="wh teal">📊 COST VARIANCE ANALYSIS</div>

<div class="wb" style="padding:8px 10px" id="cost-variance-


analysis"></div>

</div>

<div class="widget fw2">

<div class="wh dark">💼 BUDGET vs ACTUAL</div>


<div class="wb" style="padding:8px 10px" id="budget-commitment-
actual"></div>

</div>

</div>

<!--
══════════════════════════════════════════════════════
SECTION 3: CASH FLOW FORECAST

══════════════════════════════════════════════════════
-->

<div class="row" id="cost-row-cashflow">

<div class="widget f1">

<div class="wh orange">📅 CASH FLOW FORECAST — PLANNED


EXPENDITURES BY PERIOD</div>

<div class="wb" style="padding:8px 10px"


id="cash-flow-forecast"></div>

</div>

</div>

<!--
══════════════════════════════════════════════════════
SECTION 4: DETAILED COST BREAKDOWN

══════════════════════════════════════════════════════
-->

<div class="row" id="cost-row-breakdown">

<div class="widget f1">

<div class="wh teal">📋 DETAILED COST BREAKDOWN</div>

<div class="wb" style="padding:6px">


<div style="margin-
bottom:10px;padding:8px;background:#f4f9f2;border-radius:4px;border:1px
solid #c8d8c8">

<div style="font-size:10px;font-weight:800;color:#0a3d1f;margin-
bottom:8px;letter-spacing:.4px">BUDGET vs SPENT — GRAPHICAL
VIEW</div>

<div id="cost-breakdown-chart" style="overflow-x:auto"></div>

</div>

<table class="tbl" id="cost-table">

<thead><tr><th>Project</th><th>Category</th><th>Budgeted
(ETB)</th><th>Actual (ETB)</th><th>Forecast
(ETB)</th><th>Variance</th><th>%
Used</th><th>CPI</th><th>Status</th></tr></thead>

<tbody id="cost-tbody"></tbody>

</table>

</div>

</div>

</div>

<!--
══════════════════════════════════════════════════════
PROJECT VIEW — shown only when a specific project is selected

══════════════════════════════════════════════════════
-->

<div id="cost-project-view" style="display:none">

<!-- Project cost KPI cards row -->

<div class="row" style="margin-top:0">

<div class="widget f1">


<div class="wh blue" id="pv-kpi-header">📊 PROJECT COST
PERFORMANCE INDICATORS</div>

<div class="wb">

<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:8px"
id="pv-kpi-grid">

<!-- populated by JS -->

</div>

</div>

</div>

</div>

<!-- Budget / Actual / Committed / Forecast row -->

<div class="row">

<div class="widget fw2">

<div class="wh teal">💰 BUDGET vs ACTUAL COST</div>

<div class="wb" style="padding:8px 10px"


id="pv-budget-actual"></div>

</div>

<div class="widget fw2">

<div class="wh purple">📋 COST FORECAST vs ACTUAL</div>

<div class="wb" style="padding:8px 10px" id="pv-committed-


forecast"></div>

</div>

</div>

<!-- Variance + CPI + EAC row -->

<div class="row">

<div class="widget fw3">


<div class="wh orange">📐 VARIANCE ANALYSIS</div>

<div class="wb" style="padding:8px 10px" id="pv-variance"></div>

</div>

<div class="widget fw3">

<div class="wh green">📈 CPI PERFORMANCE</div>

<div class="wb" style="padding:8px 10px" id="pv-cpi"></div>

</div>

<div class="widget fw3">

<div class="wh red">🔮 ESTIMATE AT COMPLETION</div>

<div class="wb" style="padding:8px 10px" id="pv-eac"></div>

</div>

</div>

<!-- Project cash flow chart -->

<div class="row">

<div class="widget f1">

<div class="wh orange" id="pv-cashflow-header">📅 PROJECT CASH


FLOW — PLANNED vs ACTUAL EXPENDITURE</div>

<div class="wb" style="padding:8px 10px" id="pv-cashflow"></div>

</div>

</div>

<!-- Project cost breakdown -->

<div class="row">

<div class="widget f1">

<div class="wh teal" id="pv-breakdown-header">📋 PROJECT COST


BREAKDOWN</div>
<div class="wb" style="padding:6px">

<div style="margin-
bottom:10px;padding:8px;background:#f4f9f2;border-radius:4px;border:1px
solid #c8d8c8">

<div style="font-size:10px;font-weight:800;color:#0a3d1f;margin-
bottom:8px;letter-spacing:.4px">BUDGET vs SPENT — GRAPHICAL
VIEW</div>

<div id="pv-breakdown-chart" style="overflow-x:auto"></div>

</div>

<table class="tbl" id="pv-cost-table">

<thead><tr><th>Project</th><th>Category</th><th>Budgeted
(ETB)</th><th>Actual (ETB)</th><th>Forecast
(ETB)</th><th>Variance</th><th>%
Used</th><th>CPI</th><th>EAC</th><th>Status</th></tr></thead>

<tbody id="pv-cost-tbody"></tbody>

</table>

</div>

</div>

</div>

</div><!-- /#cost-project-view -->

<!-- hidden legacy elements kept for backward compat -->

<div style="display:none">

<div id="cost-by-proj"></div>

<div id="cost-by-cat"></div>

<div id="cost-per-project-row"></div>

<div id="evm-kpi-grid"></div>

<div id="cost-kpi-budget"></div><div id="cost-kpi-budget-lbl"></div>


<div id="cost-kpi-budget-bar"></div><div
id="cost-kpi-budget-util"></div>

<div id="cost-kpi-spent"></div><div id="cost-kpi-spent-lbl"></div>

<div id="cost-kpi-spent-bar"></div><div id="cost-kpi-eac"></div>

<div id="cost-kpi-eac-lbl"></div><div id="cost-kpi-variance"></div>

<div id="cost-kpi-cpi-lbl"></div>

<span id="cost-project-badge"></span>

</div>

</div>

<!-- ═══════ PAGE: RESOURCE ═══════ -->

<div class="page" id="page-resource">

<!-- ── RESOURCE MODULE HEADER & CONTROLS ── -->

<div style="background:linear-gradient(135deg,#0a3d1f 0%,#1a6b3a


60%,#0e6655 100%);border-radius:6px;padding:10px 14px;margin-
bottom:8px;display:flex;align-items:center;justify-content:space-
between;gap:10px;flex-wrap:wrap;box-shadow:0 2px 10px rgba(0,0,0,.18)">

<div>

<div style="font-size:13px;font-weight:800;color:#fff;letter-
spacing:.4px">👥 RESOURCE MANAGEMENT MODULE</div>

<div style="font-size:9px;color:#a8d5b5;margin-top:2px">Manpower ·
Machinery &amp; Equipment · Materials · Fuel &amp; Consumables —
Comprehensive Tracking &amp; Monitoring</div>

</div>

<div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap">

<!-- DATA SOURCE UPLOAD -->

<div style="display:flex;align-
items:center;gap:6px;background:rgba(255,255,255,.1);border:1px solid
rgba(255,255,255,.25);border-radius:5px;padding:5px 10px">
<span style="font-size:9px;color:#a8d5b5;font-weight:700">📂 DATA
SOURCE:</span>

<label style="cursor:pointer">

<input type="file" id="res-file-input"


accept=".xlsx,.xls,.csv,.xml,.mpp" style="display:none"
onchange="handleResourceFileUpload(this)">

<span style="background:#27ae60;color:#fff;border-
radius:3px;padding:3px 8px;font-size:9px;font-weight:700;cursor:pointer">⬆
Upload MS Project / Excel</span>

</label>

<span id="res-file-status" style="font-size:9px;color:#fff;font-


weight:600">● Built-in Data</span>

</div>

<!-- PROJECT SELECTOR -->

<div style="display:flex;align-items:center;gap:6px">

<span style="font-size:9px;color:#a8d5b5;font-weight:700">📁
PROJECT:</span>

<select id="res-project-select"
onchange="filterResourcesByProject([Link])"
style="background:#fff;color:#0a3d1f;border:none;border-
radius:4px;padding:5px 10px;font-size:10px;font-
weight:700;cursor:pointer;min-width:220px;outline:none">

<option value="ALL">— All Projects —</option>

</select>

</div>

<!-- VIEW TOGGLE -->

<div style="display:flex;gap:4px">

<button onclick="setResView('summary')" id="res-view-summary"


style="background:#fff;color:#0a3d1f;border:none;border-
radius:3px;padding:4px 10px;font-size:9px;font-
weight:800;cursor:pointer">📊 Summary</button>
<button onclick="setResView('detail')" id="res-view-detail"
style="background:rgba(255,255,255,.2);color:#fff;border:none;border-
radius:3px;padding:4px 10px;font-size:9px;font-
weight:700;cursor:pointer">📋 Detail</button>

<button onclick="setResView('forecast')" id="res-view-forecast"


style="background:rgba(255,255,255,.2);color:#fff;border:none;border-
radius:3px;padding:4px 10px;font-size:9px;font-
weight:700;cursor:pointer">📈 Forecast</button>

</div>

</div>

</div>

<!-- ── CRITICAL ALERTS BANNER ── -->

<div id="res-alerts-banner" style="margin-bottom:8px"></div>

<!-- ══════════ SUMMARY VIEW ══════════ -->

<div id="res-view-summary-panel">

<!-- ROW 1: KPI CARDS — 8 across -->

<div class="row" id="res-kpi-row" style="flex-wrap:nowrap;overflow-


x:auto;gap:6px;padding-bottom:2px"></div>

<!-- ROW 2: Manpower + Equipment -->

<div class="row">

<!-- MANPOWER RESOURCES -->

<div class="widget fw2">

<div class="wh blue">👷 MANPOWER RESOURCES

<div style="display:flex;align-items:center;gap:6px">
<span id="res-proj-label-mp"
style="font-size:9px;opacity:.8"></span>

<button class="add-btn" onclick="openModal('add-member')"


style="font-size:9px;padding:2px 8px">+ Add</button>

</div>

</div>

<div class="wb">

<!-- Manpower KPIs -->

<div style="display:grid;grid-template-
columns:repeat(4,1fr);gap:5px;margin-bottom:8px" id="mp-kpi-grid"></div>

<!-- Planned vs Actual bars -->

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:5px;letter-spacing:.3px">PLANNED vs ACTUAL DEPLOYMENT</div>

<div id="mp-planned-actual"></div>

<!-- Productivity & Upcoming -->

<div style="display:flex;gap:6px;margin-top:8px;flex-wrap:wrap">

<div style="flex:1;min-width:120px">

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:4px">PRODUCTIVITY INDEX</div>

<div id="mp-productivity"></div>

</div>

<div style="flex:1;min-width:120px">

<div style="font-size:9px;font-weight:800;color:#d35400;margin-
bottom:4px">⚡ UPCOMING DEMAND (4 WKS)</div>

<div id="mp-upcoming-demand"></div>

</div>

</div>

<!-- Member table -->


<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin:8px 0
4px;letter-spacing:.3px">TEAM ALLOCATION DETAIL</div>

<div style="overflow-x:auto">

<table class="tbl" id="res-table" style="font-size:9px">

<thead><tr><th>Name</th><th>Role</th><th>Project</th><th>Util
%</th><th>Tasks</th><th>Productivity</th><th>Status</th><th
id="res-action-th" style="display:none">Actions</th></tr></thead>

<tbody id="res-tbody"></tbody>

</table>

</div>

</div>

</div>

<!-- MACHINERY & EQUIPMENT -->

<div class="widget fw2">

<div class="wh teal">🚧 MACHINERY &amp; EQUIPMENT

<span id="res-proj-label-eq"
style="font-size:9px;opacity:.8"></span>

</div>

<div class="wb">

<!-- Equipment KPIs -->

<div style="display:grid;grid-template-
columns:repeat(4,1fr);gap:5px;margin-bottom:8px" id="eq-kpi-grid"></div>

<!-- Status donut + list -->

<div style="display:flex;gap:8px">

<div style="flex:0 0 auto;text-align:center">

<svg id="eq-donut" width="100" height="100" viewBox="0 0 100


100"></svg>
<div style="font-size:8px;color:#555;margin-
top:2px">Utilization</div>

</div>

<div style="flex:1">

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:5px">EQUIPMENT STATUS</div>

<div id="eq-status-list"></div>

</div>

</div>

<!-- Equipment table -->

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin:8px 0
4px">EQUIPMENT REGISTER</div>

<div style="overflow-x:auto">

<table class="tbl" style="font-size:9px" id="eq-table">

<thead><tr><th>Equipment</th><th>Type</th><th>Project</th><th>S
tatus</th><th>Util %</th><th>Next Maint.</th></tr></thead>

<tbody id="eq-tbody"></tbody>

</table>

</div>

</div>

</div>

</div>

<!-- ROW 3: Materials + Fuel -->

<div class="row">

<!-- MATERIAL RESOURCES -->

<div class="widget fw2">


<div class="wh green">🧱 MATERIAL RESOURCES

<span id="res-proj-label-mat"
style="font-size:9px;opacity:.8"></span>

</div>

<div class="wb">

<!-- Material KPIs -->

<div style="display:grid;grid-template-
columns:repeat(4,1fr);gap:5px;margin-bottom:8px"
id="mat-kpi-grid"></div>

<!-- Planned vs Consumed stacked bars -->

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:5px">PLANNED vs CONSUMED vs REMAINING STOCK</div>

<div id="mat-stacked-bars"></div>

<!-- Usage trend -->

<div style="margin-top:8px">

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:4px">MONTHLY USAGE TREND (TONNES)</div>

<div id="mat-trend-chart"
style="height:55px;position:relative"></div>

</div>

<!-- Material table -->

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin:8px 0
4px">MATERIAL STOCK REGISTER</div>

<div style="overflow-x:auto">

<table class="tbl" style="font-size:9px" id="mat-table">

<thead><tr><th>Material</th><th>Unit</th><th>Planned</th><th>Co
nsumed</th><th>Stock</th><th>Reorder
Lvl</th><th>Status</th></tr></thead>

<tbody id="mat-tbody"></tbody>
</table>

</div>

</div>

</div>

<!-- FUEL & CONSUMABLES -->

<div class="widget fw2">

<div class="wh orange">⛽ FUEL &amp; CONSUMABLES

<span id="res-proj-label-fuel"
style="font-size:9px;opacity:.8"></span>

</div>

<div class="wb">

<!-- Fuel KPIs -->

<div style="display:grid;grid-template-
columns:repeat(4,1fr);gap:5px;margin-bottom:8px"
id="fuel-kpi-grid"></div>

<!-- Fuel by activity chart -->

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:5px">FUEL CONSUMPTION BY ACTIVITY</div>

<div id="fuel-activity-chart"></div>

<!-- Efficiency trend + cost -->

<div style="display:flex;gap:8px;margin-top:8px;flex-wrap:wrap">

<div style="flex:1;min-width:120px">

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:4px">FUEL EFFICIENCY TREND (L/HR)</div>

<div id="fuel-efficiency-chart"
style="height:50px;position:relative"></div>

</div>

<div style="flex:1;min-width:120px">
<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:4px">MONTHLY FUEL COST (ETB '000)</div>

<div id="fuel-cost-chart"
style="height:50px;position:relative"></div>

</div>

</div>

<!-- Fuel table -->

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin:8px 0
4px">FUEL &amp; CONSUMABLES REGISTER</div>

<div style="overflow-x:auto">

<table class="tbl" style="font-size:9px" id="fuel-table">

<thead><tr><th>Item</th><th>Unit</th><th>MTD
Consumption</th><th>MTD Cost (ETB)</th><th>Stock
Level</th><th>Efficiency</th><th>Status</th></tr></thead>

<tbody id="fuel-tbody"></tbody>

</table>

</div>

</div>

</div>

</div>

<!-- ROW 4: Utilization Heatmap + Allocation Chart + Cost Analysis -->

<div class="row">

<!-- UTILIZATION HEATMAP -->

<div class="widget fw2">

<div class="wh dark">🔥 RESOURCE UTILIZATION HEATMAP —


WEEKLY</div>

<div class="wb">

<div id="util-heatmap"></div>
</div>

</div>

<!-- RESOURCE ALLOCATION PIE + COST -->

<div class="widget f1">

<div class="wh purple">💰 RESOURCE COST ANALYSIS

<span id="res-proj-label-cost"
style="font-size:9px;opacity:.8"></span>

</div>

<div class="wb">

<div style="display:flex;gap:8px;flex-wrap:wrap">

<div style="flex:1;min-width:140px">

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:5px">COST BREAKDOWN BY TYPE</div>

<svg id="res-cost-pie" width="110" height="110" viewBox="0 0


110 110"></svg>

<div id="res-cost-legend" style="margin-top:4px;font-


size:8px"></div>

</div>

<div style="flex:2;min-width:200px">

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:5px">MONTHLY RESOURCE COST vs BUDGET</div>

<div id="res-cost-monthly"
style="height:100px;position:relative"></div>

<div style="font-size:9px;font-
weight:800;color:#0a3d1f;margin:8px 0 4px">COST SUMMARY</div>

<div id="res-cost-summary"></div>

</div>

</div>

</div>
</div>

</div>

</div><!-- /summary view -->

<!-- ══════════ DETAIL VIEW ══════════ -->

<div id="res-view-detail-panel" style="display:none">

<div class="row">

<div class="widget f1">

<div class="wh blue">📋 DETAILED RESOURCE REGISTER — PLANNED vs


ACTUAL

<span id="res-proj-label-detail"
style="font-size:9px;opacity:.8"></span>

</div>

<div class="wb" id="res-detail-content"></div>

</div>

</div>

<div id="res-per-project-sections"></div>

</div>

<!-- ══════════ FORECAST VIEW ══════════ -->

<div id="res-view-forecast-panel" style="display:none">

<div class="row">

<div class="widget fw2">

<div class="wh green">📈 RESOURCE DEMAND FORECAST — 4-WEEK


LOOKAHEAD

<span id="res-proj-label-fc" style="font-size:9px;opacity:.8"></span>

</div>
<div class="wb" id="res-forecast-content"></div>

</div>

<div class="widget fw2">

<div class="wh teal">📊 UTILIZATION TREND ANALYSIS — MONTHLY /


WEEKLY / DAILY</div>

<div class="wb" id="res-trend-content"></div>

</div>

</div>

</div>

</div><!-- /page-resource -->

<!-- ═══════ PAGE: REPORTS ═══════ -->

<div class="page" id="page-reports">

<!-- ── TOP BANNER ── -->

<div class="rpt-banner">

<div class="rpt-banner-left">

<div class="rpt-banner-icon">📊</div>

<div>

<div class="rpt-banner-title">PMO Report & Analytics Center</div>

<div class="rpt-banner-sub">Ethio-Djibouti Railway · Engineering


Department · Portfolio Intelligence Platform</div>

</div>

</div>

<div class="rpt-banner-right">

<button class="rpt-action-btn green"


onclick="generateReport('executive')">🎯 Executive Summary</button>
<button class="rpt-action-btn white" onclick="printReport()">🖨
Print</button>

<button class="rpt-action-btn white" onclick="downloadReport()">⬇


Download</button>

<button class="rpt-action-btn white" onclick="toast('📧 Report emailed to


distribution list!')">📧 Email</button>

<button class="rpt-action-btn white" onclick="toast('🔗 Report link copied


to clipboard!')">🔗 Share</button>

<button class="rpt-action-btn white" onclick="toast('🗄 Report archived


successfully!')">🗄 Archive</button>

</div>

</div>

<!-- ── EXECUTIVE KPI CARDS ── -->

<div class="rpt-kpi-strip" id="rpt-kpi-strip">

<!-- populated by JS -->

</div>

<!-- ── EXECUTIVE SUMMARY PANEL ── -->

<div class="rpt-exec-summary" id="rpt-exec-summary-panel">

<!-- populated by JS -->

</div>

<!-- ── ADVANCED FILTERS ── -->

<div class="rpt-filter-row">

<span class="rpt-filter-lbl">🔍 Filters:</span>

<select class="rpt-filter-sel" id="rptf-project"


onchange="applyRptFilters()">

<option value="">All Projects</option>


</select>

<select class="rpt-filter-sel" id="rptf-status"


onchange="applyRptFilters()">

<option value="">All Statuses</option>

<option>On Track</option><option>At
Risk</option><option>Delayed</option>

</select>

<select class="rpt-filter-sel" id="rptf-manager"


onchange="applyRptFilters()">

<option value="">All Project Managers</option>

</select>

<select class="rpt-filter-sel" id="rptf-phase"


onchange="applyRptFilters()">

<option value="">All Phases</option>

<option>Discovery</option><option>Design</option><option>Build</opti
on><option>Closeout</option>

</select>

<select class="rpt-filter-sel" id="rptf-budget"


onchange="applyRptFilters()">

<option value="">All Budget Ranges</option>

<option value="0-500">Under ETB 500M</option>

<option value="500-800">ETB 500M–800M</option>

<option value="800+">Over ETB 800M</option>

</select>

<button class="rpt-filter-clear" onclick="clearRptFilters()">✕


Clear</button>

</div>
<!-- ── CHARTS ROW ── -->

<div class="rpt-charts-row" style="padding:10px 12px 0;">

<!-- Budget vs Actual -->

<div class="rpt-chart-card" style="flex:2;min-width:280px;">

<div class="rpt-chart-hdr">

<div><div class="rpt-chart-title">📊 Budget vs Actual


Spending</div><div class="rpt-chart-sub">ETB Millions · All
Projects</div></div>

</div>

<div class="rpt-chart-body" id="rpt-chart-bva"></div>

</div>

<!-- Cost Utilization Donut -->

<div class="rpt-chart-card" style="min-width:180px;flex:1;">

<div class="rpt-chart-hdr">

<div><div class="rpt-chart-title">🍩 Cost Utilization</div><div


class="rpt-chart-sub">Portfolio-wide</div></div>

</div>

<div class="rpt-chart-body" id="rpt-chart-donut"


style="display:flex;justify-content:center;align-items:center;"></div>

</div>

<!-- Monthly Trend -->

<div class="rpt-chart-card" style="min-width:180px;flex:1;">

<div class="rpt-chart-hdr">

<div><div class="rpt-chart-title">📈 Monthly Cost Trend</div><div


class="rpt-chart-sub">ETB Millions · 2025</div></div>

</div>

<div class="rpt-chart-body" id="rpt-chart-trend"></div>

</div>
<!-- Variance Chart -->

<div class="rpt-chart-card" style="flex:1.5;min-width:200px;">

<div class="rpt-chart-hdr">

<div><div class="rpt-chart-title">⚡ Project Variance</div><div


class="rpt-chart-sub">Budget Remaining (ETB M)</div></div>

</div>

<div class="rpt-chart-body" id="rpt-chart-variance"></div>

</div>

</div>

<!-- ── MAIN BODY ── -->

<div class="rpt-body" style="padding-top:10px;">

<!-- SIDEBAR -->

<div class="rpt-sidebar">

<!-- Report types -->

<div class="rpt-sidebar-card">

<div class="rpt-sidebar-hdr green">📋 Report Types</div>

<div class="rpt-sidebar-body" style="padding:8px;">

<button class="rpt-type-btn rbt-status"


onclick="generateReport('status');setActiveRptBtn(this)">

<span class="rbt-icon">📊</span><span class="rbt-text">Status


Report</span>

</button>

<button class="rpt-type-btn rbt-cost"


onclick="generateReport('cost');setActiveRptBtn(this)">
<span class="rbt-icon">💰</span><span class="rbt-text">Cost
Analysis</span>

</button>

<button class="rpt-type-btn rbt-risk"


onclick="generateReport('risk');setActiveRptBtn(this)">

<span class="rbt-icon">⚠</span><span class="rbt-text">Risk


Report</span>

</button>

<button class="rpt-type-btn rbt-resource"


onclick="generateReport('resource');setActiveRptBtn(this)">

<span class="rbt-icon">👥</span><span class="rbt-text">Resource


Report</span>

</button>

<button class="rpt-type-btn rbt-schedule"


onclick="generateReport('schedule');setActiveRptBtn(this)">

<span class="rbt-icon">📅</span><span class="rbt-text">Schedule


Report</span>

</button>

<button class="rpt-type-btn rbt-exec"


onclick="generateReport('executive');setActiveRptBtn(this)">

<span class="rbt-icon">🎯</span><span class="rbt-text">Executive


Summary</span>

</button>

<button class="rpt-type-btn rbt-kpi"


onclick="generateReport('kpi');setActiveRptBtn(this)">

<span class="rbt-icon">📈</span><span class="rbt-text">KPI


Dashboard</span>

</button>

</div>

</div>
<!-- Portfolio Health Index -->

<div class="rpt-sidebar-card">

<div class="rpt-sidebar-hdr teal">📐 Portfolio Health</div>

<div class="rpt-sidebar-body">

<div class="rpt-phi-grid" id="rpt-phi-grid"><!-- JS --></div>

</div>

</div>

<!-- Distribute -->

<div class="rpt-sidebar-card">

<div class="rpt-sidebar-hdr dark">📧 Distribution</div>

<div class="rpt-sidebar-body">

<label class="rpt-dist-label"><input type="checkbox" id="dist-pm"


checked/> All Project Managers</label>

<label class="rpt-dist-label"><input type="checkbox" id="dist-


exec"/> Executive Leadership</label>

<label class="rpt-dist-label"><input type="checkbox" id="dist-


pmo"/> PMO Director</label>

<label class="rpt-dist-label"><input type="checkbox" id="dist-fin"/>


Finance Department</label>

<label class="rpt-dist-label"><input type="checkbox" id="dist-


board"/> Board of Directors</label>

<button onclick="toast('📧 Report distributed to selected recipients!')"


style="margin-top:8px;background:#27ae60;color:#fff;border:none;border-
radius:5px;padding:7px 10px;cursor:pointer;font-size:10px;font-
weight:700;width:100%;font-family:inherit;">📧 Send Report</button>

<button onclick="toast('📤 Report shared via link!')" style="margin-


top:5px;background:#1a5276;color:#fff;border:none;border-
radius:5px;padding:7px 10px;cursor:pointer;font-size:10px;font-
weight:700;width:100%;font-family:inherit;">🔗 Share Link</button>

</div>

</div>

</div><!-- /sidebar -->

<!-- MAIN RIGHT COLUMN -->

<div class="rpt-main">

<!-- Data quality warning if any -->

<div id="rpt-data-warn" class="rpt-data-warn" style="display:none;


margin:0 0 0 0;">

⚠ <span id="rpt-data-warn-text"></span>

</div>

<!-- Enhanced Cost Summary Table -->

<div class="rpt-tbl-card">

<div class="rpt-tbl-hdr">

<div class="rpt-tbl-title">📋 Cost Performance Summary — All


Projects</div>

<div class="rpt-tbl-controls">

<input class="rpt-tbl-search" type="text" id="rpt-tbl-search"


placeholder="🔍 Search projects…" oninput="rptTableSearch()"/>

<button class="rpt-tbl-exp-btn" onclick="exportRptTableCSV()">⬇


CSV</button>

<button class="rpt-tbl-exp-btn" onclick="downloadReport()">⬇


HTML</button>
<button class="rpt-tbl-exp-btn" onclick="printReport()">🖨
Print</button>

</div>

</div>

<div style="overflow-x:auto;max-height:310px;overflow-y:auto;">

<table class="rpt-cost-tbl" id="rpt-cost-table">

<thead>

<tr>

<th onclick="sortRptTable(0)">Project <span class="sort-


arrow">↕</span></th>

<th onclick="sortRptTable(1)">Budget <span class="sort-


arrow">↕</span></th>

<th onclick="sortRptTable(2)">Actual Cost <span class="sort-


arrow">↕</span></th>

<th onclick="sortRptTable(3)">% Utilized <span class="sort-


arrow">↕</span></th>

<th onclick="sortRptTable(4)">Variance <span class="sort-


arrow">↕</span></th>

<th onclick="sortRptTable(5)">CPI <span class="sort-


arrow">↕</span></th>

<th onclick="sortRptTable(6)">SPI <span class="sort-


arrow">↕</span></th>

<th>Status</th>

<th>EAC</th>

<th>Project Manager</th>

</tr>

</thead>

<tbody id="rpt-cost-tbody"></tbody>

</table>
</div>

<div class="rpt-tbl-pager">

<button class="rpt-pg-btn" id="rpt-pg-prev"


onclick="rptPageChange(-1)">‹ Prev</button>

<span class="rpt-pg-info" id="rpt-pg-info">Page 1 of 1</span>

<button class="rpt-pg-btn" id="rpt-pg-next"


onclick="rptPageChange(1)">Next ›</button>

<span style="font-size:9px;color:#aaa;">Rows per page:</span>

<select style="font-size:9px;border:1px solid #dde;border-


radius:3px;padding:2px 4px;"
onchange="rptRowsPerPage=+[Link];rptPage=1;renderRptTable()">

<option value="5">5</option><option value="10"


selected>10</option><option value="20">20</option><option
value="50">50</option>

</select>

</div>

</div>

<!-- Report Preview -->

<div class="rpt-preview-card">

<div class="rpt-preview-hdr">

<div class="rpt-preview-title">📄 REPORT PREVIEW</div>

<div style="display:flex;gap:6px;">

<button class="rpt-action-btn white" style="padding:5px 10px;font-


size:9px;" onclick="printReport()">🖨 Print</button>

<button class="rpt-action-btn white" style="padding:5px 10px;font-


size:9px;" onclick="downloadReport()">⬇ Download</button>

</div>

</div>
<div class="rpt-preview-body" id="report-preview-area">

<div class="rpt-preview-empty">

<div class="rpe-icon">📊</div>

<div style="font-weight:700;color:#999;margin-bottom:4px;">No
Report Generated Yet</div>

<div style="font-size:10px;color:#bbb;">Select a report type from


the left panel to generate and preview it here.</div>

</div>

</div>

</div>

</div><!-- /main -->

</div><!-- /rpt-body -->

<!-- ── REPORT HISTORY ── -->

<div class="rpt-sect-card">

<div class="rpt-sect-hdr" style="background:linear-


gradient(90deg,#1a252f,#2c3e50);">

<div style="font-size:11px;font-weight:800;color:#fff;letter-
spacing:.4px;text-transform:uppercase;">🗂 Report History &amp;
Archive</div>

<div style="display:flex;gap:6px;flex-wrap:wrap;">

<button class="rpt-tbl-exp-btn"
onclick="[Link]('excel-upload-input').click()">📤 Upload
Excel</button>

<button class="rpt-tbl-exp-btn" onclick="downloadPageHTML()">📄


HTML</button>

<button class="rpt-tbl-exp-btn" onclick="downloadPageExcel()">📊


Excel</button>
</div>

</div>

<div style="padding:8px;overflow-x:auto;">

<input type="file" id="excel-upload-input" accept=".xlsx,.xls"


style="display:none" onchange="importProjectReport(this)"/>

<table class="rpt-hist-tbl" id="report-history-table">

<thead><tr>

<th>Report Name</th><th>Type</th><th>Generated
Date</th><th>Generated By</th>

<th>Distributed
To</th><th>Format</th><th>Version</th><th>Actions</th>

</tr></thead>

<tbody id="report-history-tbody"></tbody>

</table>

</div>

</div>

<!-- PROJECT PROGRESS PHOTO SECTION -->

<div class="rpt-sect-card">

<div class="rpt-sect-hdr" style="background:linear-


gradient(90deg,#0e6655,#17a589);">

<div style="font-size:11px;font-weight:800;color:#fff;letter-
spacing:.4px;text-transform:uppercase;">📸 Project Progress Photos</div>

<button class="rpt-action-btn white" style="padding:5px 10px;font-


size:9px;" onclick="[Link]('photo-upload-
input').click()">📸 Upload Photo</button>

</div>

<div id="photo-gallery" style="display:grid;grid-template-


columns:repeat(auto-
fill,minmax(150px,1fr));gap:10px;padding:12px;background:#fff;margin:0;">
<input type="file" id="photo-upload-input" accept="image/*"
style="display:none" onchange="addProjectPhoto(this)"/>

<div style="text-align:center;color:#bbb;padding:20px;font-
size:11px;grid-column:1/-1;">No photos uploaded yet. Click "Upload Photo"
to add project progress images.</div>

</div>

</div>

<!-- COMPLETED PROJECTS SECTION -->

<div class="rpt-sect-card">

<div class="rpt-sect-hdr" style="background:linear-


gradient(90deg,#1e8449,#27ae60);">

<div style="font-size:11px;font-weight:800;color:#fff;letter-
spacing:.4px;text-transform:uppercase;">✅ Completed Projects</div>

<select id="completed-filter" style="padding:5px 8px;border:1px solid


rgba(255,255,255,.3);border-radius:4px;font-
size:9px;background:rgba(255,255,255,.15);color:#fff;font-family:inherit;"
onchange="renderCompletedProjects()">

<option>All</option><option>2024</option><option>2025</option><opt
ion>2026</option>

</select>

</div>

<div class="wb" style="padding:10px;">

<div id="completed-projects-list" style="max-height:300px;overflow-


y:auto;">

<div style="text-align:center;color:#bbb;padding:20px;font-
size:11px;">No completed projects to display.</div>

</div>

</div>

</div>
<!-- UPCOMING ENGINEERING AND CONSTRUCTION WORKS SECTION -->

<div class="rpt-sect-card" style="margin-bottom:14px;">

<div class="rpt-sect-hdr" style="background:linear-


gradient(90deg,#784212,#d35400);">

<div style="font-size:11px;font-weight:800;color:#fff;letter-
spacing:.4px;text-transform:uppercase;">🏗 Upcoming Engineering &amp;
Construction Works</div>

<button class="rpt-action-btn white" style="padding:5px 10px;font-


size:9px;" onclick="showUpcomingWorksModal()">➕ Add Work
Item</button>

</div>

<div style="padding:6px;overflow-x:auto;">

<table class="tbl" id="upcoming-works-table">

<thead><tr><th>Work Item</th><th>Planned
Start</th><th>Planned End</th><th>Scope</th><th>Budget
(ETB)</th><th>Status</th></tr></thead>

<tbody id="upcoming-works-tbody"></tbody>

</table>

</div>

</div>

</div><!-- /page-reports -->

<!-- ═══════ PAGE: SETTINGS ═══════ -->

<div class="page" id="page-settings">

<div class="row">

<div class="widget fw2">

<div class="wh blue">ORGANIZATION & GENERAL SETTINGS</div>


<div class="wb">

<div class="mf"><label>ORGANIZATION NAME</label><input id="set-


org" value="Ethio-Djibouti Railway S.C."/></div>

<div class="mf"><label>DEPARTMENT</label><input id="set-dept"


value="Engineering Construction Department"/></div>

<div class="mf"><label>CHIEF OF ENGINEERING</label><input


id="set-chief" value="Eng. Daniel H/Michael"/></div>

<div class="mf"><label>PMO DIRECTOR (SCHEDULING &


TRACKING)</label><input id="set-pmo" value="Eng. Denbel
Meshesha"/></div>

<div class="mf-row">

<div class="mf"><label>FISCAL YEAR START</label><select id="set-


fy"><option>January</option><option>July</option><option>October</
option></select></div>

<div class="mf"><label>CURRENCY</label><select id="set-


cur"><option>ETB (Br)</option><option>USD ($)</option><option>EUR
(€)</option></select></div>

</div>

<div class="mf"><label>DATE
FORMAT</label><select><option>DD/MM/YYYY</option><option>MM/DD/
YYYY</option></select></div>

<button class="add-btn" onclick="logAudit('Settings


Modified','Settings','Organizational settings saved');toast('Settings saved
successfully!')">💾 Save Settings</button>

</div>

</div>

<div class="widget fw2">

<div class="wh green">👥 USER MANAGEMENT &amp; ACCESS CONTROL

<div style="display:flex;gap:6px;align-items:center;flex-wrap:wrap">

<input type="text" id="um-search" placeholder="🔍 Search users…"


oninput="renderUsersTable()"
style="background:rgba(255,255,255,.14);border:1px solid
rgba(255,255,255,.3);border-radius:4px;padding:3px 8px;font-
size:9px;color:#fff;font-family:inherit;outline:none;width:130px"/>

<select id="um-filter-role" onchange="renderUsersTable()"


style="background:rgba(255,255,255,.12);border:1px solid
rgba(255,255,255,.3);border-radius:4px;padding:3px 8px;font-
size:9px;color:#fff;font-family:inherit;outline:none">

<option value="">All Roles</option>

<option>Administrator</option>

<option>Project Manager</option>

<option>Viewer</option>

</select>

<select id="um-filter-status" onchange="renderUsersTable()"


style="background:rgba(255,255,255,.12);border:1px solid
rgba(255,255,255,.3);border-radius:4px;padding:3px 8px;font-
size:9px;color:#fff;font-family:inherit;outline:none">

<option value="">All Status</option>

<option>Active</option>

<option>Inactive</option>

</select>

<button class="add-btn" onclick="openUserModal('add')" id="um-


add-btn">+ Add User</button>

</div>

</div>

<div class="wb" style="padding:0">

<!-- Sub-tab navigation -->

<div style="display:flex;border-bottom:2px solid


#c8d8c8;background:#f4f9f2">

<button id="umtab-users" onclick="showUMTab('users')"


style="flex:1;padding:6px
4px;background:#0a3d1f;color:#fff;border:none;cursor:pointer;font-
size:9px;font-weight:700;font-family:inherit;border-bottom:2px solid
#27ae60;transition:all .15s">👤 Users</button>

<button id="umtab-roles" onclick="showUMTab('roles')"


style="flex:1;padding:6px
4px;background:transparent;color:#0a3d1f;border:none;cursor:pointer;font-
size:9px;font-weight:700;font-family:inherit;border-bottom:2px solid
transparent;transition:all .15s">🔑 Roles &amp; Perms</button>

<button id="umtab-assign" onclick="showUMTab('assign')"


style="flex:1;padding:6px
4px;background:transparent;color:#0a3d1f;border:none;cursor:pointer;font-
size:9px;font-weight:700;font-family:inherit;border-bottom:2px solid
transparent;transition:all .15s">📁 Assignments</button>

<button id="umtab-audit" onclick="showUMTab('audit')"


style="flex:1;padding:6px
4px;background:transparent;color:#0a3d1f;border:none;cursor:pointer;font-
size:9px;font-weight:700;font-family:inherit;border-bottom:2px solid
transparent;transition:all .15s">🔒 Security</button>

</div>

<!-- PANEL: Users -->

<div id="umpanel-users" style="padding:6px">

<!-- Chief Admin exclusive notice -->

<div id="chief-admin-panel" style="display:none;background:linear-


gradient(135deg,#fffbea,#fef3cd);border:1.5px solid #c9a227;border-
radius:6px;padding:10px 12px;margin-bottom:8px">

<div style="font-size:10px;font-weight:800;color:#7d6000;margin-
bottom:4px">👑 CHIEF ADMIN PRIVILEGES</div>

<div style="font-size:9px;color:#555;line-height:1.6">

• Create, edit, activate, deactivate &amp; delete all accounts<br>

• Manage all users, roles, and project assignments<br>

• Reset passwords for any user • Access all projects and


settings<br>
• View complete audit logs • Override permissions when necessary

</div>

<div style="margin-top:6px;font-size:9px;font-
weight:700;color:#7d6000">ROLE HIERARCHY: 👑 Chief Admin &gt;
Administrator &gt; 👤 Project Manager &gt; Viewer</div>

</div>

<!-- Summary KPI strip -->

<div id="um-kpi-strip" style="display:flex;gap:6px;margin-


bottom:8px;flex-wrap:wrap"></div>

<!-- Access restriction notice for non-admins -->

<div id="um-restricted-notice"
style="display:none;background:#fff3cd;border:1px solid #ffc107;border-
radius:4px;padding:8px 10px;margin-bottom:8px;font-
size:9px;color:#7d4a00">

⚠️<strong>Restricted View:</strong> As a Project Manager, you can


view your own profile only. Contact an Administrator to modify user accounts.

</div>

<table class="tbl" id="users-table">

<thead>

<tr>

<th>#</th>

<th>Full Name</th>

<th>Username</th>

<th>Email</th>

<th>Role</th>

<th>Assigned Project(s)</th>
<th>Password</th>

<th>Status</th>

<th>Date Created</th>

<th>Last Login</th>

<th>Actions</th>

</tr>

</thead>

<tbody id="users-tbody"></tbody>

</table>

<div id="um-table-footer" style="padding:4px 0;font-


size:9px;color:#888;text-align:right"></div>

</div>

<!-- PANEL: Roles & Permissions -->

<div id="umpanel-roles" style="display:none;padding:6px">

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:6px;letter-spacing:.3px">🔑 ROLES &amp; PERMISSIONS
MATRIX</div>

<table class="tbl" style="font-size:9px">

<thead><tr><th>Role</th><th>View Dashboard</th><th>Edit
Projects</th><th>Cost Module</th><th>User Mgmt</th><th>Audit
Log</th><th>Export Data</th><th>Settings</th></tr></thead>

<tbody>

<tr><td style="font-weight:700;color:#7d6000">👑 Chief


Admin</td><td>✅ All</td><td>✅ All</td><td>✅ Full</td><td>✅
Full</td><td>✅ Full</td><td>✅</td><td>✅ Full</td></tr>

<tr><td style="font-weight:700;color:#c0392b">
Administrator</td><td>✅ All</td><td>✅ All</td><td>✅ Full</td><td>✅
Full</td><td>✅ Full</td><td>✅</td><td>✅ Full</td></tr>
<tr><td style="font-weight:700;color:#1e8449">👤 Project
Manager</td><td>✅ Own</td><td>✅ Own Project</td><td>🔒 Read-
only</td><td>❌ None</td><td>✅ Own Activity</td><td>✅</td><td>❌
None</td></tr>

<tr><td style="font-weight:700;color:#555"> Viewer</td><td>✅


Permitted</td><td>❌ None</td><td>🔒 Read-only</td><td>❌
None</td><td>❌ None</td><td>❌ None</td><td>❌ None</td></tr>

</tbody>

</table>

<div style="margin-top:8px;padding:8px;background:#f0f8f4;border-
radius:4px;border:1px solid #c8d8c8;font-size:9px;color:#555;line-
height:1.7">

<strong style="color:#0a3d1f">Permission
Guidelines:</strong><br>

• <strong>Administrators</strong> have full write access to all


modules, users, and settings across all projects<br>

• <strong>Project Managers</strong> can only view and edit


activities, costs, and data within their assigned projects<br>

• <strong>Viewers</strong> have read-only access to permitted


dashboards — no editing or exporting<br>

• <strong>Chief Admin</strong> can override any permission, reset


any password, and manage all accounts<br>

• Passwords are stored as one-way hashes (FNV-1a); plain-text is


never displayed after creation

</div>

</div>

<!-- PANEL: Project Assignments -->

<div id="umpanel-assign" style="display:none;padding:6px">

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:6px;letter-spacing:.3px">📁 PROJECT MANAGER ASSIGNMENTS</div>
<table class="tbl" id="assign-table" style="font-size:9px">

<thead><tr><th>Project</th><th>Project
Manager</th><th>Phase</th><th>Progress</th><th>Status</th></tr><
/thead>

<tbody id="assign-tbody"></tbody>

</table>

</div>

<!-- PANEL: Security & Audit Logs -->

<div id="umpanel-audit" style="display:none;padding:6px">

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:6px;letter-spacing:.3px">🔒 SECURITY &amp; AUDIT LOGS</div>

<div id="um-audit-summary" style="display:flex;gap:6px;margin-


bottom:8px;flex-wrap:wrap"></div>

<table class="tbl" style="font-size:9px">

<thead><tr><th>Timestamp</th><th>User</th><th>Action</th><th>M
odule</th><th>Detail</th></tr></thead>

<tbody id="um-audit-tbody"></tbody>

</table>

<div style="margin-top:6px;text-align:right">

<button
onclick="showPage([Link]('[onclick*=auditlog]'),'auditlog')
" style="background:#0a3d1f;color:#fff;border:none;border-
radius:4px;padding:5px 12px;font-size:9px;font-
weight:700;cursor:pointer;font-family:inherit">📋 View Full Audit Log
→</button>

</div>

</div>

</div>
</div>

</div>

<div class="row">

<div class="widget fw2">

<div class="wh teal">EMAIL DIGEST & NOTIFICATION SETTINGS</div>

<div class="wb">

<div style="font-size:10px;font-weight:700;color:#0a3d1f;margin-
bottom:8px">Team Email Addresses</div>

<div id="email-digest-list"></div>

<div style="margin-top:12px;font-size:10px;font-
weight:700;color:#0a3d1f;margin-bottom:6px">Notification
Preferences</div>

<div id="notif-prefs"></div>

<button class="add-btn" style="margin-top:10px"


onclick="toast('Notification settings saved!')">💾 Save Notifications</button>

</div>

</div>

<div class="widget fw2">

<div class="wh dark">INTEGRATIONS & SYSTEM</div>

<div class="wb">

<div id="integrations-list"></div>

<div style="margin-top:12px;padding:10px;background:#f4f9f2;border-
radius:4px;border:1px solid #c8d8c8">

<div style="font-size:10px;font-weight:700;color:#0a3d1f;margin-
bottom:6px">ADMIN CREDENTIALS</div>

<div class="mf"><label>ADMIN PASSWORD (CHANGE)</label><input


type="password" placeholder="New password" id="new-pass"/></div>

<div class="mf"><label>CONFIRM PASSWORD</label><input


type="password" placeholder="Confirm password" id="conf-pass"/></div>
<button onclick="changePass()" class="add-btn">🔐 Update
Password</button>

</div>

</div>

</div>

</div>

</div>

<!-- ═══════ PAGE: AUDIT LOG ═══════ -->

<div class="page" id="page-auditlog">

<div class="row">

<div class="widget f1">

<div class="wh dark">🔍 SYSTEM ACTIVITY LOG &amp; AUDIT TRAIL

<div style="display:flex;gap:6px;align-items:center">

<input type="text" id="audit-search" placeholder="🔍 Search log…"


oninput="renderAuditLog()"
style="background:rgba(255,255,255,.12);border:1px solid
rgba(255,255,255,.3);border-radius:4px;padding:4px 10px;font-
size:10px;color:#fff;font-family:inherit;outline:none;width:160px"/>

<select id="audit-filter-module" onchange="renderAuditLog()"


style="background:rgba(255,255,255,.12);border:1px solid
rgba(255,255,255,.3);border-radius:4px;padding:4px 10px;font-
size:10px;color:#fff;font-family:inherit;outline:none">

<option value="">All Modules</option>

<option>Authentication</option>

<option>Projects</option>

<option>Risks</option>

<option>Resources</option>

<option>Reports</option>
<option>Settings</option>

</select>

<select id="audit-filter-action" onchange="renderAuditLog()"


style="background:rgba(255,255,255,.12);border:1px solid
rgba(255,255,255,.3);border-radius:4px;padding:4px 10px;font-
size:10px;color:#fff;font-family:inherit;outline:none">

<option value="">All Actions</option>

<option>Login</option>

<option>Logout</option>

<option>Add</option>

<option>Edit</option>

<option>Delete</option>

<option>Report Generated</option>

<option>Settings Modified</option>

</select>

<button class="edit-btn blue" onclick="exportAuditLog()">⬇ Export


CSV</button>

<button class="edit-btn" onclick="if(confirm('Clear audit log?'))


{AUDIT_LOG=[];renderAuditLog();}" style="display:none" id="audit-clear-
btn">🗑 Clear</button>

</div>

</div>

<div class="wb" style="padding:6px">

<div id="audit-summary-strip" style="display:flex;gap:8px;margin-


bottom:8px;flex-wrap:wrap"></div>

<table class="tbl" id="audit-table">

<thead><tr><th>#</th><th>Date &amp;
Time</th><th>User</th><th>Action</th><th>Module</th><th>Detail</t
h></tr></thead>

<tbody id="audit-log-tbody"></tbody>
</table>

<div style="padding:6px 0;font-size:9px;color:#888;text-align:right"


id="audit-count"></div>

</div>

</div>

</div>

</div>

</div><!-- /pages-wrap -->

<!-- MODAL -->

<div class="modal-bg" id="modal-bg" onclick="closeMbg(event)">

<div class="modal" id="modal-body"></div>

</div>

<!-- TOAST -->

<div class="toast-wrap" id="toast-wrap"></div>

<script>

//
═══════════════════════════════════════════════════════
════════
// DATA

//
═══════════════════════════════════════════════════════
════════
const LOGO_SRC =
"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAQDAwQD
AwQEAwQFBAQFBgoHBgYGBg0JCggKDw0QEA8NDw4RExgUERIXEg4PFRwVFx
kZGxsbEBQdHx0aHxgaGxr/
2wBDAQQFBQYFBgwHBwwaEQ8RGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaG
hoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhr/
wgARCAImBQADASIAAhEBAxEB/
8QAHAABAAICAwEAAAAAAAAAAAAAAAcIBQYBAwQC/
8QAGgEBAAIDAQAAAAAAAAAAAAAAAAECAwQFBv/
aAAwDAQACEAMQAAABn8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAB841XKNRwkYZJQ1hWCf/NW/
GRgsXhINMEr4XQkYdn8GHMP38CjjkevKYAtuecjAyzls9Zk7Nrea17lO5MTWdlnd
5C4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAB5MIx7Mj3Bxgl5A2EYLHYiuXXGCdcJEpg3/
AAmtow+ryjCAAPo+WTzC+qJFzDPESdsnOWuyyfevWVZvoK1rE4xSCUua/
GHQ2WxLXBDO4ImZpAqz756Fn0ZSPPV7hOYAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAfJ9MZg4xbejTBME0cV7wcYLI4SvhgmbB
Rsa+3YPGowc8CgA9J5mfy7LpKTstOaG0+5hmrblbI9rNAGZmZOaMcxuxmwO
W9CcwLgAAAAAcYfMlYz0Sw6NOqKyMaxzo4d3TGkzGHJnzcqoyFPVmx5vTbqgk
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcHLw4Jj2tG2CjXm
b5r7gmCx+BgFGvMWCjpGDaMH4zACh6cstgG6ZhljNMWXnNA3Nj8szVqy9heZ
zQhl5YM0f5jaDNjch9JygsAAAAAAAAAAAAAAABjYqmdGvVT4sbC0cbWxGpnJ2r
b6527RtP3C3dBkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPnEq5hp
GvxryugvX2CxmDrx8RrzZgIyNfb8F5cpGHBtwyy0cpcys5YOWFzDNWnJWS+2
WActNCc0WZffDLrOWyCc3z9DIAAAAAAAAAAAAAAODl4cKx7Qj/HRhlFE/
YrKiNMsvurE5Wc/
IWAAAAdfYRE0WWs0uvLgV6vLHI+5ohTlmtaimVbeg5E5gAAAAAAAAAAAAAA
AAAAAAAAAAAAAABwcsXgGLc0X4yMEx+WGOtjk7X8BlWPE4CSMpFIF6LKZFF
aclYpOWC8pMBljPKbwZdcynvTl+foZAAAAAAAAAAAAAAAAB8n0xWDYtxRhgo
15s+a84OMFkMHAJgmLBR0jBtWFx5gBQAABlcUTJG/
V5Tt2t5rrK89Pc3HM7oAAAGAgWzOMjRrI2HXq8NIsdFrVdkBznbv+kTsgAAAAA
AAAAAAAAAAAAAAAAAAAAAMfkCMD49qRi1jJ5Qt1dpNwSAAAAAAAAAAAAA
AAAAAAdeFUzzQcBGvLvEB4Fgsbga+o15jwMdGvs+D8iNcFQB6TzM9mGXSU
mZdlhxPeWnNXDI2U72avmQnNOaE+mcia+4SzvDHVJZfTY1YabLrUaQK7lNFZf
bO7aFp2427YMgAAHlgyfeuNaqqRo5rwGya2Vs9kK0z5bu5oTugAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHRr7Hs6NdcjXm3z13wka1hd
dhk1pE1/W0a/
f0duQYsU2fKsuhpPyc5YdTvlGWunosv7WWt+Un5OWF8vKJm0PLbMZfB7fpOUF
gAAAAAAGrbSUr3qtrI6ryYYd/
RHM+5mhYzWuRNK9vQfQnMAABxF0pIw1S4nOEq8Dp93hMFh9nqzOVu3ugno
gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADyo9XxgMZGHMaz7
vewx7rk5+9hrN6rLfSteMhO5khfIyuZI6yG6mXXMlkU5OvsGQAAAAAAAAAAAA
AAAAADXIHs3jI0ayNh16vDSHHha1XZAs5W7/oE7IAADV9oKVg8FlYErwcL9/
CNSapEqjLE9eVnHNuqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAOtHY1/
XYwyEhvANewOOrj4o17A+aBzDYrYKq5Jls4jiRbdP6DKAAB5oNnvrjWqqkmNq8
BtGrlbQ+2t0+272UE7gAADw+4iveq2ohavE0ARz5HmOqu8T0p2dHfbsgkAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY9GQ8e
o4WNXP6v7fY1o/
12bvbGGviyOSTWXI2S+mWv+VmtOWKu2UDJCmi2lxka9ZN+xWrRzLU9sBTrb
u+gTsgAAIzkxGKqfzPUHV4HmymLMFkM9V6ebdzaBO+AAA+foRPFVrY/
ryoRdvVHI2meKvZ2d6yLFZW3cBYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAADphab+I16pbRusSV4doPZXKfbdnIC
dsAABr2wlay4uzkEV4Wtd/
QjSnrdKqTVbsyCJ6YAAAGpwVaHCRoVsZnDV4eTnyuHrnZtG1Ta7d8FwAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADpxi
mZafioxSLpet45r6LtWCzFeXPwv6QAAAB5/
QRBei2siivHirlxHMmCTqoynPVltxzbrgAAAeGCLC9MatV2/wCgV4HbN8F/
TJaxG0k39ADKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAABjsZshj03wyAjHG3RKBSK5AyhkCc4AAAAAGgQtajWI5teGRx1
eNKktVTsnbsZkT0wAAAPmKpXRhqim+Fa8DqlWKitreYXmW3oPsTnAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAA1+uNmKz14qbYSnJi3wW74AAAADVtpKVf8NloErwcJJEbowWualtt/
SguAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAcdCPQxOOY9naT4YxyIivwqTEhDxsc9q7eFSy3xWDoilnfLWgpYvxwAUnT
wQ0U2LXXManfZjSZEt2QnogAAAAAMZkytXPJIceU8zvc51tslbrhPRAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdfYRgsftq
MWj9G/
lY588nFYu6ZXIiLiXiIb65oKwl1ziRBvVO4gX5nwiAOuwZEISJtZnCdoAAAAAAAcE
RRfs+sU81m7JwRO9umE9IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfB9ujoV9zE+ZXPtY8sV3Fp
HhUkWNtQ0mNAbfHNkbefn6v6YGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAeZHpYXxxj2ZpWOY5GRb4lJf+IW8bH
NvlhfqUmPyxMUk/yxv8xTf/
AC6T8qbj5NZK57y4cpkPN0Ir8+X2FMZ582VwHGw/
ZrbZOTWm0cmrNsJ1Nvu8TmjidfR9z1wnaAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AA6cfjK9Rz7MKzo1bMKzizHtq3N07G0qzo17McVoFmFZxZj31Yn+dnN/
NfMVGC0HuheaJ6DzemN1ty4rQjl2s831Hk9PduK0I5lrPrzem3ZMRC0a0346unE
c+0frqrIM55pef0T0gSA6+zDqfSs6vIsvzWcWm9FVdynNPDEZeekCzFZSrcadj/
VV2VWvK2M9FX2azHsq3NDHIeL76wslmFZ0admFZxZ/
31SlediVhPSMVDEas2Y2unEc+0Ptqpvs55ueX1T0vN4tPheOdZjKVTtIyeoTvY3r
gnXa8iz31C2UnNJqs6Nay6tAsvzWcWYyNVrJzt9qs6NS0nqjuRLdQGbpx+Hr/
HOswrOjWsx6qu/SbWIYmOel2Cc7q7Y3Ydy+qy/
deZatjclbrurt11HsVnV5Fp+dY9Fun71Z1eZafv07cbdZjsjEEY5J5rN9RzbV4rsgK
d2effViY2GRcfqELJsvla22EZev5rT8xp2bycMTPPRYzurGxWT99WJeYZQ8Xt1Od/
LKzq8m1XZHkh26rH+ms8YLE81m3SNWUa9WFr0wvr5sLGvXxadO7Vma97+p
z1WWoRgqq2XWo5j63OdZ3Krz7tf1O/
WjFZXFV4kjTRDEz27iN5IjdkhkV87aWPJDjy3oIdFfP2m8/
fE9vR6LjH3XzvxzO+3T0KspRi6NPdJ5qlP09DcBbrgMNmcNGOtQr5flNm8z0asp
khuNTJ2MrBKc7Uti3c4q5aOrleV5ZViqVY0pLq/Z+sE7KaIXmiMG7Vhs/
WCc7t6psjThzptVoM7cIffwjm2h580d29HoOIc187xzOW5z0KspYieNPbZ+qpOs
7/
hhiZ4YjXWkq3aOdj1i3Yrnruxa7Ty+75TFzpPSqutPwiqzs645XPMsSfPQqxZDL+
Kd2sYrwpqkSO5Et6MJ2dRr/
YCv9eE+vmxMYK8fNp6+zk1qXIj2KMVjBf0qu02VuryT2+KOVL8n1wsdbuc67s
WutquYr5iwPo8/
ot6Cuwr5+fdx03crelYLOpy1RbTq1PLzP4tUmW3VrXuWm91eXuOkejzplXK7NEl
uppRsVeTNOx8c39PG0NbLrVPPM9jfGw2t51zY7+nr/
qNha9V4OyWJqlYhtYOE9j1yNLmxsVzpO/
q1erC16YGya2jR23nUS8477FspW7oTtV31nZtZp5fdp4geeLdgJ6FZsVlsTTyvry
GEGb8fgAK2ljyQ48t6CHRXz9pa52MrRPW8O56ZIsaE0i/
peqsFpK1V5WGkqNd6jQnRo0bW69glfDHYPDattLYrUK+cnDftB363o1d7EQS19
H2bWc5Xj2SF/U8VctHVyvK8sqxVKsaUl1fs/
WCdlNELzRGDd6wWfrBOdsmto52969hS7cNPlJeW66WJrVbo4na9U3+vMm8X9
N8Vks9XCOXgJBj7dK87c4YmeGGVaOrloJ2PcLdiueu7FrtPL7vO8EztbsuOeJ36rdf
Z108nLkpRbKVvQsdkcdOxWIU8tNUiR3IlvRhOzqNf7AV/
rwlgq+owWegPXU3bHrkuxjlE+L+kiWLsnjKeak3Rpp0OduPrF10kpjmTXdi123ar
mKeYsD6PP6LegrsK+fnzctN3K3pQnPHsJ2mrHXidNnquzgRlrm4afGmz+A21E8
Vhm6Cp3kyxDZtX2YLOxFPTi73+Dfa8DKRdYGv07MlzHWCzU73bAU+60zV22L
XuK8B9fO/rSlnS/
ptWr1YWvVeKmSG5bYtl48ienseX0XcGf1Cc9eNY2bWaeX3aeIHni3YCehWfE5b
E08ruEjafNFuvo+nTTG68MivDtLHkhx5b0EOivn7SwDP2hW7sL7DryvEtbzCe32
7+11m2PWY5SVIusetqEOWO1hnhhM5reDffJ656lahXz84b9Dmx27u9VrzOpRo
Nv1Ca2KQ2heqe3t1WZVieOWlqJZvY9wrBZ+sDOmeGJnjBvFYLPVhnOk6MZOa
u5eH2Y6epCfHPFeFOMebNnJ6sH5zBo5dq/
uD9zt39wrJsmqxy0lxrYpOKgmz9ZWTqsLXrYIwWO6tG0q3W1DxlfPyNNGib3b0
Ljniduq3X2ddPJy5KUWylb0LHZHHTsViFPLTVIkdyJb0YTs6jX+wFf68IWCjBX1v2g
sWxWJqtYielsmnbjBk7miCvnt/w2smZ7/
AYbU4LE5W3o66CvnLA+jz+i3oK7Cvn583KJdgt3t6aNwzb1DEqY9Sum26krwO
zj43lOlcb1oSdw08RIE3artVu/
wBdaJqgKNBs2so52/6ALJ3gjd5zTuLeigXS5PjCnm/
qyddLRzu8i3X1avVi4VrxdebEjR11sQ12yUHzrPQy4t2K76zIOv083lZ4h6YbdYJ3
qz4ncsdTzOzTPFcqW7KN5I0RkgxsPNeBYOPJE0m3dg/nYOa8Kwfd199/
TQNpVqo3ryIdbJ4Y5+JbjJc58JJpPdCcoDDZnFsdZWw8083rrYuTXG8bzObSJx5+J
7NbcRuus14PgZHPq61ZXEbLbt+Gr9oq/
Rra9M8cymw7VWG0MAM2utiRztdbENdbxIM5/
rcfpbuwbodq47ry4YbNj452JbfJU59flUnuIqlXgqkm+Oq8LVWW9bDr21bZKM7/
AN9hbsvn6+U1X69l+KeX3uUY9kK3eY7I+Gc9X2xKeakiRNI3e3fCdnUa/
wBiIYrxdesZCs4p9dbrQx9OzCWyfKvJn6ssjarO1rso6hNKM29C3brXhZc0SnnsrK
sNTJO7XVsSObL/
AKHdbu1wbDzXha62Ia62ISru+pbbb0Nc9dm2NI4muz5GM+tvVq+2sgU03Od0
jtSROXTb0MJaJtHTTznishGMr26fnjCV8E2K3dmeV4E/
e7R94t6OIIwmHQI4mHtHXuwk7vInpgAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAf/
EADIQAAAGAQIEBgICAgMAAwAAAAACAwQFBgEQFREUNDUSExYgMDMxYFBw
QEEhIjIkgLD/2gAIAQEAAQUC/
VzrpJhWbj0QrbGJArcgpbXxgewyJwaWfHBzmUNqi6WbAk1IECdokSBK5KYCFsYq
BvJNHX9E5zjAUkWiIUsscmFbi3wFLivkK2aRUCsm8WGTZN/
gtpZ61DW4KlDSeYvP6AOoRMKzLBEK2tgmFLkUK256YKz8isFHKyv+WzmHjEM
LaiqElk1yfuyjlFEKz8ckFLczIFbkcK2mQUCsu+WBjmPn5MFyYJxztYJ1uRUCdPdG
CdNTCdUjyAkBHEG0MRtzQbe0G0Mcg8DHHClVjzhSmkC9TephxGO2vvavV2R4
62JqBNQipP25R82RCtjjkgrcGxQrcV8hWyyKgVkHa4znOfkKQx8pxL5UErMicJU5z
kJ01LATq0eQJwzBIERTTx87mLZuw6p6Jg7gHzT3MZNzHHi7C3kP2fOcYCsg1QCt
ljkgrcUMBW4OTBWxSKoUeOFvkI3WUCcJIKhOqyBwnTVQnTm+AnWY5MJxTJIFT
KTH+S8iGb4PqkskFUjon9kRZlGoQXTcp/
r3HgFX7VEK2WOSCtxQwFbe6MFbDIqhR0ut8WMZyE2DpXKddkVAnUXpgnTAn
UWRQnXo5MJMGqIxjh/
Bu2Ld8SSqiqIMXJDax0qvGKRsohJpfrCrxuiFrHHIha4NyhW4ODBWxSKoVeOF/
hI3WUBISQUCdWkDhOmrZCdNQwE6tHkCcMwSBEU0/
wCNkYZtJFk4VxGZ1buVWisPOpSRf1E6yaQWno9EK25mQLXFXIVs0iqFZB0t7yo
qHCcS+VCdYkThOnushOmlCdTYFCcBHJgjJskOHD+VOXByzFX4DOMlzoQ5kzQd
hw8/
S85xgKyjNAK2mPTC1yC1rfqBaXfLgxjG9hEFVcpwz9UErEicJ091kJ00gTqbEoJXo
4gTYtUhjGMfxCjtBEKWGOSB7cyKM3JMZuYxcyglxb5Cdpj1AjJNHHzzEAlI4cN1G
qun4EFY+P6Ko4SSC1gj0QrcGxQtcHJgrYZFYKuVl84IYwTj3auCQEicEqb8wJTVQ
nTkMBOqx5ASCj0wRk2THDGP4nOcYCsi0QCtmjkgpcUMBW4OTBSxyKoVfOV/
ibyTtqGtvXIGc+ye/LJxSMmk/j1o5bWDsWWoIcpy/wA6tINUAtZ49IKW/
wAQNOTLkZbT7sFq8kqCU5xnBKamCVJiUErsaQEi2SWSpkJ/
GZzwCsi0QCtmjkwrcUsBW3uzBWwSKwUcrLf4bGceMBHWNq9+R6xRfoysQtFq
6ws8pHGRWTcJ/wAyphznJmbpUGgkVQSvxxASOaJjBCl/
kFXjdAK2OOSC1xblCtwdGCthkVQo6XW+XBcmCcc7WCdbkVBipv8AI9IPBmpPs
BStyKYWYOkPfF2JwwDJ+hIJfEugm5SmYJSNNrEzC0WozeJPkf2cxykwtMsUArbW
RAtcjhWzyKgVkXa/
yEbLKBOFfqhOqyBwSmrBOnIYCdXjiBOHYJAiSafwOIxm6DqoIHD2Besva1dqs1Y
eeSki/
EYuDlnK5lt7I6SWjVo6TRkkf2FRZNILT8eiFrg2KFre6MFp6QWB1lFfhTbqq5Thn6oJ
WJEwTp7rITpqYJU2BQnARyYTZN0hjHD/
AAn8C0fiSgXUd7CHMmaDsWHXyTlb8YzjJc6NHirFaImEpRP9bUVTSwtPx6AWuD
coWtzs4Vmn6wMcx8+zCZzAkY8UBK9JHBKk+ME6aoCU1DATqseQEgo9MEZt0
xw4f5f5EtWE3AWROgprBWT5Juvkf4VSOgpoisdupCzxJEv6rnOCheYYtwvbmhAt
cHJgvOSDgeBwuCRjxQEr0icEqkgcEp7rITpgJT2uASrRxASBjkwmwapDBcF/
hpWIRk03zBaPW1g7FlqCmwcvxS8KlKJu2arFbQhzJmg7Dh3+pq+bnCjJ4qD1tJb
JatHFBYCOKCxbIgKgkQcP5F6xRkEZWIWi1dYWePHGRWIun8UhGoySMlGLRq2s
FY+P74rINUAeyRxBi1R+QlOx62SmwfHxLoJuUpqBUjjaxE0rFqNXSTxH4nTRJ4j
MQisYfWCsWWwKbBy/uZjlJhabYIBa3MyBa4r5C1kkVgo8cLe1q/cMjRdpTcD8/
EYuDlnK5lv7IyVWjFmL9GQQ+JRMqpJuumZ+yEnzx+UlSLp/
tyzpFvhxaGCIXuJ8hexSC4UXVWzoVuqcEiHymU61IqBOoOzAtMwM01IOqi6SC7
dVscQlhMyyQ5VC/
FN1vCwMXJDaMH60cvGSiMmj8X5E5Wh+NYiaViztXSTxH9rcczkOIuUcj0fk+cU1
IFqDTAJVI8oLXI0oLDsCArZEnwPWCD9OXhFYw4hZ1SNOisRwn8UzApyJV26jZX
Rq6VZrREylKJ/
HN14r0KJmSPpGSq0YsxfoyCH72omVUk3XTs9IeaVi1GzlN2j8UpEIyiT9gtHLaIrH
bqQk6SRL8cxCJSZHTVVmtoxfrR60XKoyaP75NVrBwYuS5iZdWLWaO0nqPxPWK
L9GWhlotTQhzJmg7Dh78klGIyaUjGLxq2jZyq0Wh5tKTJ+
+TEAlI4ctlWitYeGbyPxqokXTmq8dhnTGeGYKxeb8jpqk8Rl4RWMPokqdFSEnyS
GP3YyhCBSVZJA9mjiA9wa4B7mD3B1kSEmvJGrTUy8n8mcccTdaH41gbF4fkUT
KqSbrp2WpTZLmCsWHH7ssxbOcngY5QGrEcYZqLLIzTm2RmmpgtNL4mLBCPS
+aarpHoVSOippWpvPi+P8AInK2PxrBWP8AoyWhkZQj1kswWBTZIaLd88w+Sbr
xHoVSOifSCsRm2SmwbH9FTDAkgy0qJ+Md8svCoyhHbNVitpW5vKB/
6KkXJWjLSppeCM+aQjkZJGSjFoxbSvSPPsf6CycuAZ2gUGlGRBmdjijNljsA1rYFB7
i3wJSYXlDhBEzhZm3K0bfO+ZJv2zludquKo58qR/
djLJlBpNmQGsEcUGtUdgGuDTANcig9xWBrc9yDWiRMMz8iYHlHpwZ0ucZObPw
Yxk2a7Ccnj/
Bt6GCPhDm8Mp+6GLg+FIhoqD1uPOM1SPyM1FkM09oM01EZpqYzTB6MOPRq
gzTXAzTnQzUHg9JPh6SfD0pID0tIjNXkcD0zIjFbkshCpPFMxsA2jv8ADuRseaIfHil
P6dnnuH0iKq386T/
pywzpUCaVhhyjH+kvFgZVTwOcb4BpNmUb3H4BrBHFGbNHYBrVH4ClvalD+zO
neNIGIzIucY4Y/
oDJsYBnKJBmSZ4GZuPKDWGOIM2iOwDW1hgZuLYGuSYNcsg1xcA1veZBrXIZB
rPImGbDJZBpqQMMyTzIM7cGGVD5HHj8URBLSRm7dNoj+8n80GzIA27BQk7nB
kbCYZYWAwUiZ4wNAzJh6alMg1Zkh6akh6akh6bkhmuyWB6ekh6ekhsEkNgkRs
EiNjkBscgNjkBscgNjkBscgNjkBscgNikcjYJIbBJD0/
JD09JDFcksj03JD01JBCpPVAxq7RrnGMYx/
wDmqqKERJubMbmzG5sxubMbmzG5swqumiTc2Y3NmNzZjc2Q3NmNzZjcmYS
VIsQ0i0Kbc2YReN3BtFnCTfG5sxubIYzxws5Sb43NmNzZDGeONVn7ZuMTkfnKT
lFx8JjYIXc2Y3NmNzZjc2YTWTW9+ZJnjO5swi6RcjOcFxubMbmzCLhJxjOcFxubIb
mzG5sxubMbmzCT1utn2rPWzcb5H8UXSDj2LLpN8bmzG5MxjPHGh37VI25swk
9brnWdoN87mzG5sxubIbmyG5sxubMbmzHjLgm5sxubMIuEnGNVFCIk3NmNz
Zjc2Y3NmEnSC/
uOoVIm5swWRaGNqc5UibmzG5MwkqRYiihUibmzG5swksRcmij5skfc2YxItDZG
5sxubMJKkXIooREm5sxubIYzxwaRaFNubMEkGqh9DyDVM25swkqRYgWdItxub
MbmzBDlULoo9bIm3NmNyZixdn9uPzaOze+s9nk+4Cn9bpcei0b/
AEXLpdEPoEhIoxyMhYXb3PHjoQ5kzRdpVQyisRwn7pXtvsKcxMsLM7aZYSKEil7
HPUCmfl50mlP6J90ftxnOM12eOc+j5+hHoyNjdPM5znOQU5iZjLQu3ygum5SFw
6HRv0+k93cVTu1y6r3r9p0p/
b9bL2f2FNkmYizqImKbBy62535bUFNkhmLnDxppO9p0rfZ5/
s+lY7Ppb2fhVGM+HLBxh2zmmnJyQp7nxNrc58tkIlpzsg8Xw0aGNk5hUWXmO
Q7cYatlFMqqCoO/
EkJ+P59jpU3vnMwqoVFN65M8dCtx3OvbF2fTw5HhyPDkeHPGz9n8OR4c+zw5
HhyKz2eS7gKd1ulx6PRv9Fy6XRD6XjsjJu/
fKyDjThrX5jLBf3SvbdMYzkcOGrB8rHuGboj1vq56gUz8vOk0p/
Qvuj0Kkc45dYGLkmQQ+UztFuYbOXBGiEjIKSTnThrBS5o1xjODYuPRaNun0nu7i
qd2uOOLrwmHhNrjGcjw5HhyF+0aU/
t+tl7Pp4cjhnGtTkcnLrPPOcktKg88SWk52nSt9nn+z6Vjs+kuz56P/
GlQdeY0uDTiUVhx5EpanPnSYpzT/
m3OvLZaQjPko4W535bbSGd8lI6WKP5F+IN7yMiLW98hmMY8WYZhiOY2Ls+kA
UuYjwFHgKPAUZxjI8BR4Cif7uKtjjLeAo8BRjHASfcBTut0uPR6N/
ouXS6IfRbnviWBS5OaIr6DJMyCZy2CvkRJpW3vOR3tle26VIuMxpkUz4ma0mon
pT3n/fVz1Ipn5edJpT+ie9HpT+3C2IJmjtI5PKTC3vf+RjGTZh68i0TyinnE/
XiFS0q77mmFx6LRt0+k93cVTu2S4yPAUZIXgp9gp2MZT8so8BQ/
6HSn9v1svZ9IMpdpMimfE8yKxkRBK5SltJd5yMeGrVR4qIZ3yUjpOdp0rfZ5/
s+lY7PrYGfJyQrTrlpSVa87HhFUyCq6xnCwh2nJx1odcxJiDZ87I6TzznJIOWyjUwg3
nOxono/
cGGkE952NnHvPSIrEfzTwWLs+jedfNUfU0kPUskK1IuJAmtg7wKr3bWT7iEHKzU
28PxvD8OHzh1jRv9Fy6XRv9Est58kKu3wvKaHJhQjlLyHApy3B17ZbtulR7ZpPts
NZUV9TKcvq66kUz8vOk0p/
Qvej0j5tzGo+rH4fSrqR0gYk79yJ1XK0sK43w4ldM4wbD5HlngqK3gkLj0Wjbp9J7
u4qndtP9Kf+xTfr0f8ARaU/
t+tl7PpCuUSRRnrYhZt8WQkBApebLaXB3xOKe28Ssk35V8IN5zsaJztOlb7PP9n0
rHZ9bYz85kEz5TO1Xw5bTjXlJPSFa85JLq4QRWVysqKiz8tsJh3yUeGSHNO7g18O
RUHfgX0scfyT4R0qePRBS5OaJY4j2IsXZ/
bTfq1sHeBVO7ayfcfe3+i5dLo3+h7jg8FPz/8AO1ljYPJip4zullfrsG/
qSSHqSSHqSSFZkXMgJbtulR7Zpa88ZUQ2OMrq56kUz8vOk0p/
RPej90PZsEGM8cSZfDIiomxiR1mzeKVFW7vcei0aZ8TXSd7uKp3XT/Sn2Cm/
Xo/6LSn9v1svZ/dU43KZQY2C4kHWXjwVpty8XbW/lvxUHngcCd7TpW+zz/
Z9Kx2fVZIq6TlAzZwKm686PsrnmJTStuuWlLU68iNCCRl1myBWrcXB5xUFTbebI
WNvzEUGTnLR2Q+FCCcj9wYfjWrR3Mu9LF2fSIgmLqO9NRw9NRwZRrePxrYe8C
qd21k+4ivRyMi59KR49KR4sUM1jW+jf6Ll0uiH0WBvlvKiDeYYyOj90Vk0MbJzC
mt/
+1y6XWmfiW7ZpUe2BRQqSci7516Kyh50toc3hIbPEwphP+rzpNKd0T3o9K5EN
H7P01HB3V2Z0M44ZFVeZcMbI38iVEQ85GQxnBsB24K0bqqZWVFPb+JxakvMit
K+6w5iwofCRHa/MuhT0uLzT/Sn2Cm/Vo/6LSn9v1svZ/
bCIN3MgUuC4FlecrG6J2xyknJzasqmGTnLN0Q+FCTvadK32ef7PpWOz+y3M/
LcivyOI5yofKqhCZUOomZI5DZIafkyyKgqbPznoMbBCyDrL14IuaViiKWx0qnpV3
nMx2llY4aSAKXJjRjLEez0sXZ9IqxM2bD1YwHqxgPVjAN1yuUdLB3gVTu2sn3EU/
rdLj0ejf6Ll0uiH0WuP89vpE2c7MhraxxiWmlZQwIXKholjiPYykUnKp+j2o9HtR6P
aiLh0ooS3bdICcaxzM9uZFxKz68ljSqx+W7WTsW2v0rPHKYmLMio30qSOU4550
mlP6J90eldmGkez9TRoeWpoRHOeORTPzaY/
LpppEWU7EmbaxxiXnFZTIxjJswrDb2Dxvh21VTMioIqVVi1i21jkszYzyBNKqz5eP
0/0p9gpv1aP+i0p/b9bL2fSFbImirNFcouCmyQ0LJYkmYtTzz3/
uq7zmY6d7TpW+zz/Z9IWfaMI/
1ZHj1ZHj1ZHhi9SkEJxnzsdrVmXMyFqZ+Q+1r7Lko0WV5ysb7qu75eR0uX3Bt1
Gti7P7oftelg7wKr3bWT7iKd1ulx6PRv9Fy6XRD6M4wbE7Bmj1PZ+RXILKHvle2
+6Cgjvj4xguJRxzUhq1bHdrtG5WjZ50mlP6J90fvrkcZgy/In4IzI/
trsDkmdLNC5Nn2wkQeSXKXBC6Z/Cn/sU36tH/RaU/
t+tl7PpBdpeNSPWzpsdm4EJJZjXi7kiDZZUy6oqDTB8+SmPJTEs15ORFXectIzva
dK32ef7P7qr2kTjPkpHStsuUjbCy5yN0iGfPSGlqd+e/
Ea25x95CWB5KYt7PGCBM+Ujs3GHbYXL7g26jWcRUcRmxSI2KRGxSI2KRGxSI
2KREYmZGP0mol64k9ikRXYt20kdX8M+Ve7FIisRzpm70tDRd422ORGxSIRx4Ur
QzXeIbFIjYpEI44JAxcHLI1NNXK0BIIZxFvchtWX6+YyvN4/4JFMyrDYpEbFIjYpEbD
IhCqv1QwqzZrnGOGFC+Mj2sPWxjsnKeSMHSga1p+5zFQyEWUOi5O22ORGxyI
rDRZm0dlydrsUiNikRsUiNikRsUiEKq/
VEZW27DOhi4NiRqiS+V4CQQztb3IbVp+4zGVtuwz7JOsIO8r12QQztb3ASgpBb
LCo/wDKSJEE9c/
g8HIZPsUiKuycMk9HhcnabFIjYpEVloszZ6zyCjmM2KRGxSIiEjoRossOZ6TYpEbFI
gxJU8RsUiNikRCM8so7SzxK7pxsUiE4aSSPIlVdw+xSI2KREEgo3jJlE68ZsUiNikRs
UiNikRsUiNikRXW6rWNFnjFHqexSIaV96o5xjBccOIfV94R3sUiKxFKMsBQ2SJrQ8
mursUiK1EuGzvSYac7HbFIjYpEVpN03ai0MHLxXYpEIQkgVb/7x/wD/
xAA7EQACAgEBBgQFAQQJBQAAAAABAgADBBEQEhMxQVEUITIzICJCUGFSIzBA
YgU0Q1NgcYGh8BVwkJGx/9oACAEDAQE/AftBYDnDkVD6oc2oQ5/
ZYc608ocm4/VDY55naGYcjBkWr9UXOsHPziZ1Z5+UV1fzU/
fTYi8zDlUjrDn19BDnt0EOZcesN1jc2+EVu3IQYtx6QYNs8A/
eeAfvDg2xsa5ekII57AxU6iV5rL6/
OV2pb6T91NqLzMOXSOsOevQQ579BDl3HrDY7cz8AqsbksGJcekGDZ1MGAOrQ
YVQgxqR9MCKvIfuCobnHw6m5eUsw7E5eewEqdRKc3pZOf202IvMw5dI6xs9eg
hzn6CHKuPWF2bmdgVjyEGPafpgwrjBgN1MGAnUwYdI6QUVD6YABy/
grcdLecuxnq8+myjJany6RHWwar9mLBecbJpXrDnVjkI2e3QQ5dx6zets7mCi0/
TBh3HpBgP1MGAOrQYNQgxaR9MFaDkP4E2IvMw5VI+qeLp7wZNJ+qBg3L48jD
1+aucpVc1J1EqtW1dV+wNbWvMw5dXTzhyXPpQzfy25DScHKfm0GAx5tBgJ1M
GFSIMakfTBWg5D+DNta8zDmUjrDnr0EOdZ0EOVcesLs3M/CCRyiZdqc/
OVZddnly+LIxhb5jnGUqdDK7GrbVZRetw/P8aRrDUh5wVoOQ/
hi6rzMbKpXrGz06CNnv0EOVc3WF2bmfgFVjclgxLj0gwbOpgwO7QYNU8FVDgJ0
MfCsXl5xlZTodlOU1fkfMRHWwar8N1C3D8yytq20aKxQ6iY+SLfI8/
t7Oq8zGzKV6xs8fSsbNtPKNda3NpoTBTYfpgxLj0gwbesGB3aDAr6mDDpHSCiof
TAAOX7lkVxowl2ER517KrmpOolVq3Lqvw21LaujS6lqToYDp5iY2Vv/
ACvz+1GF36LD4luwhxr39TwYA6tBg194MOkdIMekfTBWg5D+EyMYW+Y5xlKn
Qyuxq21WU3rcPLn8LoHGjS/
HNJ1HLZjZf02ffGvqXm0bNqHKNn9lnjrYuefqErtW0ar8N1C3D8yytqjo0Vih1Ex8
gXDTr8JAI0MyMUp8yctmNlbvyvynP7sTpGst+lI3jG/EOJe/
qMGA3UwYA6tBg1CeEp7SzBU+iAvQ/
Yyi9bh+fhsqW0aNLqGpPnASDqJj5Qs+VufxZGJ9VezHyTV8rcoCGGo+/
XULcPOMlmO8x8gXD8/CyhxoZkYxq8xy2Y2VvfK/
P4sjFFnzLzhBU6GUZDUn8RHVxqv3wso5mHIqH1SzJx3Gjecr94bnxc5kYm781e
zGy/of4r8dbh+Y6NWdGlNzUnUSuxbV1X72a0bmIceo/TPC09olFdZ1UfuMjED/
ADJzhGnkZhXFhuH4raltGjS6lqToZXa1TarKbluGo/
wNn6b4mF73xugcaNL8Y0+fSV2Gpt4RHDqGH3w2oOZhyaR9UOZSOs8dVPHp
2h/
pDss8e36Z46ztDm3RmLHUzDpNa7x5n9wQGGhlqcNyswW1rI+9mms8xPD0/
pnhaf0zwlPaeDp7TwVM8FTPA1TwNU8DX3leLVX5gfur237SRMAaVk/
4K3hOInecar9UOTSPql+ZvDdriKXbdErQVqFH302adDDd/
KYchv7sw5Nn92Ycm7+7nicn9H/2eIyu3+0N+V/
wTi5X5/8AU38k95rf+f8AeaXHv/vNyzsZw37Thv2nCs/TODZ+mJi2v00lOOtI/
P8A428jJNLaATx79p49+0rymdGbTlPHv2nj37Tx79pj5LXPukQ5zA6aSiw2pvGW
vw0LTx79pbYa69+ePftBLslKf84c9+glecreTjSc9rHdUmePftPHv2iZyn1CAhhqN
mTeaNNBKctrLAukycg0EaCUZbWvukTJyDSQAJ49+08e/
aU5odt1hpsuyEp584c9+glecD5ONIDrL8tqn3QJjZBuJ1Gxs5lYjSDKbg8TSePftPH
v2nj37SjJNu9qOU8e/
aVPxEDbMjKal90CePftBnt1WVXLcNV2Wvw0LTx7doDvDURzuqTPHv2nE/Zb/
wCJ49+0rbfQNL7GqTeE8e3aX3mtQyiUZZtfdIl+Wan3QJRebVLMOU8e3aUWNa
m8RMnI4OgEpyzY+6RLCyqSs8e/aVPxEDTJyOBppEzLHYKFmd7glFPGbTWeA/
mleJuKy685/wBP/
mjDdYiUYvGXe1lGLwW3tY3qMwvZmV7LbMn2Dsus4VW9CSx1MTBYjUnSWVtU
260wrv7M7bPQdleHxEDay2pqTo0w7Sr7h5HZ/
SHJZie8Jn+pZh+8Jn+pZTXxX3ZZhbiFtdllvDq3jCSx1MTBZhqTpLamqbdaYVvn
wzMz3jMDm2yz1mUV8XH3fzPAfzbKsPioG1lWPwA3nsxvZXZne7KKeM2msvxTS
N7WUOa7AdmfZySaTCfer07S3222D+rf6bKPaWMoYaGMpRiplf7fFK9ojbjBpY2+
5aP+xxd3vFUsdBFUIoUTIfiWEwEo2sVg6hhMqrh2fgzBs5pMiziWEzBq/
tDM73BFYryM41n6pjEmoE7LfcaYPtbG9RgZhyM3mPXZk+wdmd6FmONbV2Z4
GimY50uWWZaVNukTx9fYziC2ksPzsxvZWZw/Z6yv1jZ/
SHJZie8Jn+pZh+8Jn+pYrFDqI1tjDQmUCsv85mefkEoGtqjZnj5QZQdLVmZ7xm
BzbZZ6zMH2tuL7Ij+k7Mb2V2Z3uyi7gtrpLslrhppMdDZYBsufiWFpbVu4yn/
nnMN9y3TvLfbOwf1b/TZR7S7M6vR9/
vMF9HK95boLDpKtDYNZnPq4XtMKvefe7TIfh1kypd9wszF3bf8AOYL6pu9plVcW
v8xWKnUStDYwURVCjQTO9wTF4e/
+0muJ+JW9Z8k2W+40wfa2N6jMSqt6tWEyKa1qJA2ZPsHZlV79Oo6RWKnURcq
phqTpMq4XN5chMNN6ze7TIxrLLCyzwd3aVoa8fdb87KL6lqAJmVkC3yXlMZN+0
TxFWumszLVsYBekwxrcJn+pZh+8Jn+pZjbnE+flG8Lp02FTbiA9opKnURMuphq
TpMq8XN8vITDr37Ne0zl0cNMa3gvqY+VUq6g6znMVd2kbcX2RH9J2Y3srszvdlF
PGbTWWIa23TMF1816zKfcqOw3WMN0mA6ecL8Sje/Gwf1b/
AE2U31CtQWniKf1S9RdV5RGKNvCIpscLLE4blY7F23jMavh1CZz6kJFYodRHsaz1
GYr7lo2ZAC2sBMBRqTszVZrPIThv2nDftMJWVzqNllb758phAirz2NW+8fKYYIq85
kgmk6Thv2mQCaCJw37QcpfhnXerhRx0leLZZ00lVa1LujbZ6DOG/
acN+0TFtfpKaRSugjo4b5hFrduQmLj8EatzmcrMw0ExEYW+YmcrMw0E4b9pw3
7SvFtfppEQVruiX4Z13q4a3HMSvGss6aSqpal3RLahau6ZZjWV9JuOekow2J1s2
8N+0xQRSNY3pM4b9pjjSpddmarGzyEwlZXOomZTxF3hzEVbEOoEyWe7TQTEq
bi6sJoJbSyuQBMfe4LIROG/aAHw+n4nDftOG/
acN+0o8qll9LLYdBMKohi7CZtRJDKJTQz2AEbLBZY5bSYdW6mpEvr36yJw37Spi6
AmZKObjoJgqV3tR/2i/
8QAIBEAAwEBAAIDAQEBAAAAAAAAAAERECAwUCFAYEFwkP/
aAAgBAgEBPwH1VKXul/
AUpfBCEJzfb0pS9QhCeOE2+wpeoQhPwFKXYQhPq3wz03zkIT61KUvdL+ApS9Q
hCEITb7mlLxCEITyTx310IT0N97SlL9G+5+SEIQhPoT/Gpl/
DTwzF+PYvxFKUpSlxeJe+hCEIQnkX46/
hvk+f+c1LlKXLty7S80peLlylLtLl25Sly8UvF25duUuXbl2jyZOUPHxMXMxYxDEPJ
xMQxcTJy8mvF9FixD6XTx69vD14xD4evGLVq1Y+v4Lti1i1i5fS6ePhZOVjEMQxb
/NYh9rl6vovVqx6tWrqZPIxD2ZMnM8LEPGLxofC5X+Rf//
EAEgQAAEDAQIICwYCCgICAgMAAAEAAgMEEBESISIjMTRxchMgMjNBUXOBgpK
xMEJSYZHBYKEFFCRAQ1BicKLRU2ODsnThgKOw/9oACAEBAAY/
AvwvnJGt2lZVVH3Y1kcJJsCzNL5nLNtij7r1rJbsACyqqXzLCkcXO6zxP2eV8e665Z
NVIsb2v2tWfpmu3XXLO4cO0XrMVDHfK/
8AsTjWdqI2+Jc9hbrVmoJH7cSzUDG7TeudDN1qztTIfEsZv/cczUPu6jjCuq4Q/
wCbcSuZKGO+F+L+wGW8N2lZdVH3G9ZBfJsaszSnxOWbZFH3XrHUubu4lnZX
v2u/
e8zKcH4XYwsGtZwLviGMLDheHt6wfxvnZWM2uWOpad3Gs2ySTuuWZpgN5yy
XMj3WrOVUn1uV73F232tzQSs3TSu8C5jB3nBZ2WNn5rO1LjsbcsoSP2uWqtO3
GtUi8q1aLyLVovIsdJF5VjpW9yyRIzY5ZmpI3mrNGOUfI3LPU72/
O7j4VNK5hQZ+kG8G74xoQfE4Paekfi/
Ozxt2uXP4W6L1mYJH7cSzUDG7TeudDN1qztRK7xrGb/
aXMaTsWRSy+W5c0GbXLOzxtHyxrO1LzsFyymvftcsilj7xes3G1uwfuGfp2E9d1x
V9JM6M9TsYV7ouEb1sx8a+nfi6WnQUGPzM3wnp/
E+NZ2ojb4lzpfutvWap5HbTcs1DGzbjXP4G6LlnZ5H7Xe0ujie7Y1ZNLJ4sSygyPa
5Z2paN0LOzyO2XBc0X7zlkUsQ8KuY0NHyH71n4hhfEMRRdRP4ZvwnSiyVhY4d
DuK2Ktvli+LpCEkDg9h0Efh/
Gs7URt2uXOl+61Zmne7ablmoo2fmtYLN0XLOzPftd7LEL1dHTyu8C1cjaQFlviZ3
3rO1XlYst0r++5asDvG9Zqnjb4Vi/
keDUxh4RfQHhWfB0oteC0jSDxL4Tez3mHQVhQnKHKadI/
DOdmjZtcufw90XrMwSP24lmYY2bca5/A3Rcs7PI/
a72Obie7Y1ZNLJ34ljYxm1yztSxuxt6ztRI7YLljY9+85ZNLH3i9ZuNrdg/
ludbgydDxpV7xhxdDxxBJA8seEGSXR1A0t6/
wlnHtZtKyqlp3cazTJJO65ZinY3eN6xSiMf0tWdqJXeLj5EbnbAsill8q5prN5wWcmj
b9Ss7VE7GrL4R+1yxUzTvY1m4I2+FYv5qWvAc06QUZv0aNsX+kQ4XEWhzCW
uGghCCsIbP0O+L8F4ys7UxjxLJc+TdasxTeZyyMCLY1Zyqk7jcspxO3iXRxvfutW
TSyd4uXNNbtcFnJomj5XlZ2qcd1qyjK/
xLVwdpWbp4m7GLEP5RnZo2bXLHUB26L1kNlf3LFSu8yxUn+ayqQ+dZynkb33
rG98e81Zmojd4vbmSK6Oo6+vanRTtLHjo4gp/0g7H7sh+/
4FzsjGbXLHUB27jWZhkk24lmYY2bca1gs3Rcr5pXybzlkglXx00rtjCsVM4bbgsrg
2+JZ2paN1qztRI7YLllNfJtcsVKw7VkQRN2MH8qx4lnaiNviXOl+61Zqne7ablmoY
2fmufwd0ALOzyP2u9lmJ3tHVfiV1XG2UdbcRVzZODf8L8XtcGUYLxyXjoXBzt2Hr
4gp604UPuu+FBzCHNOgj+fZ6ojb4likdJutV1LSOdtK/
Z6bA2R3rL4e75uwVfJgN3nrLnjbsvWcqXHY1ZRlf4lq4O1xV7KWIeFZDQ3YP5Zj
WdqI2+Jc6X7rVmKd7t43LNRxx/msdS5u7iWdle/a79zAZJhx/A/
Gg2Q8BL1O9oYqht46Pkrn5UR5L+II5b30x6PhTZIXB7HaCP51mjEwfMErLrnNH/
WwBftE9TNvSrVgdpvWRTRDwLJaB3fzDPTRs2uXP4e6L1mYJH7cSzUMbPzWsFu
6Llnpnv3ne1yQSs3TSu8C5jB3nBY+DHiXOw/
UrEYj4lzOFuuCz1PIza3jhkufg6icYXCUz8LrHSPZujnaHsdpBRkivfTHp+HiZOXCe
UxCWndhNP5fii95Ddqy6mPuN6zYkl2C5HgKYDecsUjY91qztRK7xe0yInu2NWTS
yd4uWU1ke1yzlSwbAs7USO2C5Y43P2vKyaWPvCzbGt2D2Gfp2OPXdjV9JK6I9T
sYRLo+EZ8TMfFElO8scFgPzdQPd6/
Zlrxe06QjUUILoveZ8PE4SA4veb1rDgOP3m9I/
EWdkazaVjqGu3cazMMj9uJZmKOPbjWOpc3dxK+R7n7T7G6KN79jVkUsveLlzT
W7XBZyaJo+V5WdqnHY25ZXCP8SxUzTtxrNQRM2MWL9yJLOCk+NiLruFh+NvE
DmEtcNBCbT1pDZvdd8XtDUfo8ZXvR9exXEXG0S07sFw/
NYsiYcpn4cvke1g+ZWOoDj/TjWYge/biWZZHF+ay6l/
diV7yXH58XJa49yyKWY+BasRtIWUYmeJZ2paN1qzlRI7YLllNfJtcsVKw7cayII27G
fvploLo5fg6CjHM0seNIPEbTfpB3ybIfv7QzU1zKj8nIxytLHt0g2tkhcWvboIXBzXM
qB0fF+FryblnKlncb1mWSS/
ksxCyPbjWVUOA6m4leWyyfPSsillPgWrEbSFlCNm1yy5om/VZ2q8rFlyyu/
JY2PftesVKzvxrN08TfCskAfybLyZRyXrg6ht3Ueg8QU9acKH3XfCg5hvadB9nfyJx
yXoxVDcFw/
O0OYS1w0EJtPWHBn6HfF+E8yWt+bhesqvcwf0RgL9oqamba9Y2PdtetWadqya
WLyLJjYPD/ADIxVDbx0HqVzxhRHkv4gimvfTH/
ABTZIXBzHaCPZ8HOMfuu6QsCYZPuv6DxG01e7HobIfv+PM7URt2uXP4W61cp
48CubUsB/
qxK9pBHy9m6OZoex2kFGSG99Men4eJdy4DympstO7CYfZmKobhNKwhnIDod
1beIKeuN8Xuv+FAtN4PT+NL3uDR81l1LL/ljWZZJKdlyzMDG7TeuewB/
SLlnZpH7XcXCppXM+XQhFXXRSfF0H2Za4Xg6QjUUAwo/
eZ1cTCixsPKZ1oS07r+sdXsyyRoc06QUZ6QF8HSPh4giqL303/
qmyRODmO0Efi++aVkY+ZWS90p/pC/ZqcD5vK5/
AH9AuV8sjnn+o23MiedjVk0kvlXMhm84LOSxM/NZdWe5ixVT/
Kr6eRs3y0FFk7HRu6jY2CrJfT9B6WIOYQ5p0EezdUUAuk95nWi1wucNItEsB2jrW
HFieOUzq9o6o/Rzfm6P/XEu5cB0t/
0hLTuwmH8WfspjHzesv9JBg6mMuV81YXHdWVUv7mrKllcsYkftctXv2uKxUsXlW
REweH2GBUswh0HpCv5cB0P/
AN2COW99Mej4U2SFwex2gj2ZkiujqOvr2p0U7Sx7dItbLTuwXhfBOOUz2jp6QBt
R0jociyRpa4aQbcKLGw8pnWhLAdo6vx4WSNDmnSCnT0d74OkdLbLuXAeUz/
SbLA7CY72d0gwZByX9S4Oobd1HoNrZIXFj26CFwc1zKgdHxe0whkTjQ7/
aMVQ3BcLRLTuu6x1rCjyZBymdX49dP+jxc/
3o+vYiHC4jSFe3KiPLYmy07sJp9mYqhuEOj5LHlwnkvtDmEtcNBCbBVkNqOg/
F7TAmGV7rukLAnGT7rug2tlgdgPCwTkVA0s/
HpkizdR19e1GKoYWPCZFfm5sRHz9o6OZoex2kFGamvfT/AJttvGlCmr3Zz3X/
ABe0MVQ3CYVeM5AdDv8AdofE4te04iEIai5lT/7fjfLcG7SsupiHiXOl261ZEUr/
AMlm6X6vWTDE36prqkjJ0XBRvAyYson2txTqj9HN+bov9cRtNXuxaGSH7+0LJG
hzTpBTp6S98HSPhtBabiNBTaeuN0vuv+L8bXzwskPzCx0rO7EsUTm7HlYnSjxLJ
nkHcsVS/
wAqy6olvyauDpm3DpPX7czUtzJ+kdDk5krSx7dINraOqdffzbj6e1dUfo8fN0f+uI
2m/SDvkyQ/
f+xmPImHJejFUNwT0fOwFpuIxhQzdJGPb7UzUtzKjpHQ5FkrSx7dINraetOFDoa/
4UC03g/2LkY4ZbRew9Rte34ZD7a/
kTjkvRiqG4Lh+dopKo5t2Jh+H5f2Lmlf0Ntwj77yfb8HONjukLAmF7TyX9dowzfLH
ku/
sHjIWVNGPEsqqiHjWtMXPX+ErJ4R3hWbgkdtxIcJkRjksFjIoxe55uCigZoY279wd
DMMR0HqUkMvKYbrOC92Vv5/jfKkaO9ZVVEPGtZadgKxOefAsmKU/
RZFKe9yyKdg2lZLIm9y5bG7GLWnLKqpfOsuaQ+JY3E+wuAvK/WatuedyR8I/
copR/EZj7rKS7/kH41uKy2O85WOE+YrRIPGuVKPEsU035LJqZPKFiqneVYqv/
8AX/8Aa1seRa03yrFUR/
QrFPF+axSRHvK0xeZaYvMtEfnXIZ51zbT41zQ8wXMXeILPOZEPqsIDhZfjd+50r
em42Ug/7R/Z6RzDexmS2wP6Imk/2ddS0jr5XYnuHu28K8Zc2Pu/
snpCxvaO9c/H5llVUQ8YWtx/Vay07AVzp8hWJzz4Fm4pH/
kiyL9njPw6bQ+Qfs7DlfP5K4f2BxlZUrBtcsdTF51jq4/
qtZB2ArnHHwLEJT4ViglKyaV3e5ZNL9XrJp4x3lZMcQ+qxGNvhXOtHgC1k/
QLHVy/
VY6mbzrKnkPjWNzvqtPsg54MdP8AF17E2KBuCxuj8dZsN7ysltN5isn9U/
yWTJSjYFz8I2LW2+b/AOljqSdkyypCf/MsbQf/ACLmgfGFzH+QXMf5Bcx/
kFq5PiC1Y+YLVT9QtVd9VqrvqFqrvqFqj1qj1qj1qj1qj1qj1qj1qj1qr1qrvqFqrvqtV
d9QtWPmC1e7xBcx/kFzH+QWdLIhtvQdNfUP/q0fRXDR/
wDzVi+VwY0dJWtReda1F51rUXnWtReda1F51rUXnWHK9rG9ZK1qLzrWovOtai
861qLzrWovOtai861qLzoPicHtPSEWuqIwRpylrUXnRbBMyQjoabQZ5Gxg/
EVrUXnWtRedXhAzyNjB0YRWtReda1F51eOJn542bXK79ajWYlZJun2Jc43NGkrW
ovOtai861qLzrWovOs1I1+6ePcamLzLWovOjwErZLtOCVecQC1qLzrWovOiYJGy
AfCUS7EAtai861qLzrWovOtai861qLzq6KeN56g7jZ+eNm1yu/
Wo1mJWSbruJfPI2Mf1Fa1F51rUXnV40WlslRG1w0guWtRedYEM8b3dQcgJ5WRk
6MIrWovOtai861qLzrWovOtai861qLzrWovOsO8YN1961qLzrWovOiYJGyAfCeIXy
uDGjpK1qLzrWovOtai861qLzrMysfsdxi6Rwa0aSVrUXnQa2oiJOIDC4hdI4NaNJK
1qLzrWovOg+Jwe09IRfI4NaNJK1qLzrWovOsOF4e3rFpZLPGxw0guWtRedACpiJ
OjKs1qLzrWovOsOF4e3rBRfK4MaOkrWovOtai86vGhFrqmIEaRhLWovOgyOojc4
6AHWlr6iNrhpBctai86D4nB7T0iwcPKyO/
RhFa1F51rUXnQcw4TToItwJZ42O6i5azF51rMXnVTsHrx27zfYQ7T6qq7V3rZN2f3
tg7S2PdCpt82x7os4Sodsb0lEMdwEXwtWPHZhRuLT1hBlfnY/j6R/
tNkhcHsdoI49V2R4t7HFp+SAmP6xH/
VpXCU7to6RxZd8+tlX4fup+zPpbN2n2VR2bvTjXg3FCkrHYRPNvPpbwlQ67qHS
UWxHgIupulXk32XsJaesIMrc9F8XvBNlgcHsd02Q9rbFuC2q37BuFU/Zn19hJ/
wDHP/
rbL2v2HEn7vXi3tJB+SbFXnhI9GH0hBzTe06DxI6dpypTedlgc3SDeFFMPfbbVbls
Hf6qq3fvbDtd62xVTfeyXWAjEQoZh77VNGBc0nCbZNAdLHYX1UcI0yO/
KyCLoLr3bFLL0Mbei52k47JKl2iMXDbZLM7Qxt6c9+NzjebJaV3u5TdljsEZ2PKba
6ndyoTi2WOkfia0XlSzu0vdfZwkgvihxn5lVOwetuhaD9FoK0Jm81aD9FoPE0FaC
odp9VVdqfWyfs/vbB2lse6FTb9se6E+abktRlnOwdXGEUp/Z3/
l8+PV9kbcQv4jZoTo0jrUc8XJeOJNvn1sq/
D91P2bvS2btFUdm70tvYxztgXNP8queCD87A5huIN4UMvxsBT5peSwXoyy6Pd
b1DjBrz+zvOV8vmrxjBUHa/a2LcFtVv2DcKp+z+65JWg24gtB+i0FSf/HP/
rbL2v2HEn7vW3QtFrqOU8nGzZxJXA5LMhtstK7Sw4TdltVuWwd/
qqrd+9sO13rbNF7117dtskB0xuvGxQ1LejIdYxvRKMFFg0RNwbJ6p241MgGmV
35WxMPLIwnbbI6ZumQ3nZbDITc2/
Bdstc5gzUuU2yJ7jcx2S6wQNOVMceywAYyUyP3zjftVTsHrbTZI5PUuSPouSPouS
PosYvXJH0XJH0VTd1/axt/wFckfRckfRYlVdq6yfs/
vbB2n2ti3Qqbfti3Qo6VuhmU7bYGsF5OIBNfUMElQdJOO7YsF0bSNidVUQuaOW
y1oeb3xZJ41X2RtdeBzpVz42kbE6agbgSD3BoNstK7Ry28SbfNlX4fup+zd6Wzd
p9lUdm70tk7X7CzhSBwjXDBNtMx2kRhRUjTi5b7ABjJTZKpglnPXoarjG0jYnVVC
3Bwcb2C3g3nLhOD3KDtPtbDuC2q37BuFYxeuSPouSPonbbKm8DSFyR9FyR9FU
9k70tl7X7DiT93rbS5I5HUrnMaRsT44sTHDCA6rKYjpdd9bZpfeuubts4OHlXE2Q
yX5N+C7ZbVblsHf6qq3fvbFtd68SS7kSZbbGA8mUYCni6S3FtsZIzlMN4Ukr+U9
15sgj966921FgOTCMGyJh5DThOtlcDkMyW2NbKMbmhw77IXnlAYLttjg0Z1mUy
2N7jltyXKV4OQ3JbZw8gzcPrZU7B62tihluY3Rkhc8PKFz3+IU5qn4WCRdiu4lVt+
1jdx3Equ1dYXU8joyRde1a3L9VrUvmQFRM+QDRhG2LdCpt+2LcCqX/
wBZFjS7RE3Ctc12NpFxUsXwPIsni6HMv41X2Rtd2ptma3kuyvrZTXdJweJNvn1s
q/D91P2bvS2btFUdm70tMVPgYJN+UF/C8qH6y+8DQ0DFY2R7f2dhvJ6/
lZVE9DsH6WRYWhmXaQcYKniGhjyBY+PoexQdp9rYdwW1W/
YNw8R22yq3hbU9k70tl7X7DiT93rbSh0rAcD4kS6eMAf1J8sfIGS2ymHU6891sN
K3oy3WTzn3RghVEXwvN1kLzygMF22yq3LYO/
wBVVbv3ti2u9eI2dvKhP5WNe3E5pvCimboe29TtHJccJvfbAz3b8J3cpJHcljb0+R/
KebzY+pdplxDZZNKOVdc3bZDCPfeAqaZoxXYBslpnHE8YTdtpewZqXKG2ypjZj
4ZuL5GwNaLycQUcPvaXbbKnYPXjVW8OJU7R6WN3HcSq7V3sIt0Km37YtwKcH/
kNk3Z/fiVRb/yGy/8A6zeoXUr8Bzn3HFetY/wC1j/
ELWP8Qqj9bkw8G67Eqvsja7tTbi6IxZSdoOJNvmyr8P3U/
Zu9LZu0+yqOzd6cdkFaxrGaGvaLleMYVUD/
AMpseOuLiVZHx2M3HKDtPtbAf+seltVv2f8AjPEdtsqt4W1HZu9LZe1+w4k/
d68d1ZKLi4XM2WEnQFNMfedi2WRk6ZctMlGiRv5iyWmdoeMJu2yq3LYO/
wBVVbtsW13rxHxv5LxcVJC/
Sx11hiPKhdd3J4GiIYFsd+iTIXBjTMcGxkTOU91wUcLNDG3WQ0rToy3fawynRE3
81N1x5Yshmb7jr017cYcLxY9jecblM28Q1EgzcOjetqdg9bYJZosJ7hjOEuZ/
yXMnzFOFKzBwtOPiVO0eljdw8Sq7V1kjKm/Bay/
EblyZPOtEnnUT6YOvc643m+2LdCpt+2PdCn6nnDHfZFI7Ew5LrZZ3+6PzRc7S
TfZUTnRiYFTdofTiVfh+6q+yNru1NjnyG5rReSpp+hzsWyyM9EYLrXE9ARPzsq3f
NoU/
Zu9LZu0+yqOzd6WySVMeE4Pu0rmf8k79XaY5LsRvVxsMTze6E3dylPRJlCyGY8
m+52xXjRZJNJyWC9PkdynG82TznQ1uCEXfA4G2H4mDANjnvNzWi8qab43k2T
SdDWXcR22yq3hbUdm70tl7X7DiT93rxo46w5J0DrKAaLgLHgcuXJFrGMhhwWi4
aUxs0bG4BvBbZFM33HXpr2Y2uF4VVuWwd/
qqrd+9sW13rxWVLdEouO2yUyG5joz9U578bnG8oNYL3ONwCcyQXOabiE1zcR
GMKn4M3tbHj3jpsdO7kwjFtsLnYgFNMfedi2WPbDGx2GbyXJzHQxXOFx02hh5UJ
we60vZyJsqwNGk4lHCNI5R6zbU7B62wwy8JhsGO5q/
ieRfxPIv4nkTJY+S8Xi2p2j0sbuO4lV2rrJuz+9sHafa2LdCpt/
7Wx7oTamMXui5W7aIatpljGhw0hYhKT1YKuORCNDLA1gvcTcAo4fe0u2pjJXuZg
G/
EuflXPyrn5VJwL3Pw7r8JVfZG0xVGHhYZOIXrIbK7uXBgcFB8I6dtrqiQZc2jYuAdF
wjMG8kHGsqR0e80p8FDe4vFxfdda55/
iSEqfs3els3afZVHZu9LXx1Ly1xkv0Lnj5CnfqpMsvRiV5squrJQnjF8kPpaIalplhHJI
0hYhKT1YKwbuDgGhvXtsAaLyUyM84cp+1Swu99tydG8XOabjYXR5UbuUxXuEr
T1YKMNO0xw9PWbeFdypjf3cR22yq3hbU9k70tl7X7DiT93rbSl0TCcDpahUQtuh
k0gdBsDmm5wxhNeedbiePnZwLeTCPz44jPKhOD3Kq3LYO/1VVu/
e1kM+HhtJ0NX8XyL+L5F/E8iE0F+BfdjClYOWMpu3icK7kQ4+9cM0ZMw/
PiRg8uTLdY8Dly5I44jJyZhd320u6bId8cSp2D149J2Ytqdo9LG7h4lV2psn7P72w
dp9rY90Km3zbHuhEOxgoywDCpnf48XEhV1guk9xp6OPV9keOJqkFtOP81cMQC
qJb8Rfi4jIYRe5xuUcLNDBcp+zd6Wzdp9lUdm709hfKLpZThEdVhnphfTu0j4OM2
rrG3H+Gw+tprKVt5/iN+/
GBcLqdvKPX8kGtxAaOI7bZVbwtqeyd6Wy9r9hxJ+71tpdxPgl5LgpIZeUw2NcT
mn4nhPnJyGtwk+R+NzzebJ6iRoIGQ29c236Lm2/
RTxdGFeNlgjdyZsnvVVuWwd/qqrd+/
HbvmyVg5LsptrS7ly5RUmCL3x5bbYYvdvvdst4FvJhF3fZBD8Tsexc236Lm2+VQ
VEbQLjgm6xr2YnNN4UUzdD232Uu6bId8evEnjhaXvddcBtWqSLVXrVXrVXrVXr
VXqnZKMF7WAEWzyQ07nsJxEbFqj0JKiB0bMA4zxKh8dM8tdISCtUepXVMLo2ll1
5thbTRmRwffiWqPWqvTAdIaFA2mjMhDrzctUetVemA6cGwteL2nSCi+gdwR+A
6FjpnO+bMa1SbyLLYIW9byg92em+I9HsKhkYvc6MgBapItVetVetVes4GQj5lB9
Qf1h/z0K4aE5t914uvRMLf1hn9On6K59PKPAsinlPgWWzgG9b/
wDSyMuU8p5sma0XksIC1R61R6lbUxmNxffjUzWi8lhAWqvWqvWqvWqvWqvQ
4QMhHzKEkmemHSdAtucLwUX0TuBd8PurV3PHWzGtUm8iyo+BHW9CSXPzDp
OgcUyUx4CQ/
QrmeFH9GNapN5CsmleN7Eg79ISeBiEcLQxg0AcU3Ur9K1V6qBVRGPCIuvtna0X
ksIH0WqvWqvUjKmMxuMl9x4kscDS95uuA2rVHrVXqnjlbgva3GLGz0rcKduIjrC1
V61V6/UXUkl4PK/
pWqvWqvUUb24L9LttsU1JEZDg3OuWqvTXspXhzTeFKGxnhnx8j5rVXrVXqGOd
pY8X3g7VURwtw3uGILVJFqr1qr1qr1qr1qr0I6hhY/
COI2RSUzMOVhuuHUtVeomzwOjjwsonqVw0BY1MKaBz4sLJIWqvUs1UzAkdiAPV
Y5zW4RAxDrT5H0r8J5vK1V6fNVxGO5tzb7Zomi9117dq1V61V6fBWROjwTk32
U5pYnSYLTfctVeoy6lfcHD/85P/
EAC4QAAECAwYGAwEAAwEBAAAAAAEAERAhMUFRYXGh8CCBkbHB8TDR4WB
AUHCAsP/aAAgBAQABPyH+XEuDwQnR4Rf8VT/
Je6q9b6VpoeZH5pY4O3uMLEAS5jnNSoPcRAjc2X7ptb99FrQHc6oI29JVC8k9P+
EgHIAYp4dhVxVt84U54QSCyvP5A7DLvlUE7nog5ixP+BSkimVmFtpFMAXfu6JoL
OIQL0/vwjisAIBu7BGiGPdND1PJ7JxaEUiLh8VqLR/
yzoB6wxrSgBHo6H9uMfJIKQn8B7UMn2RCZY84ttjm6cXINg8SdgsT/
KacGAXeoK63ALSmdANGk2B+TKh5qUAadGgGnRL1JGqPKqIcxC2m+box+vHZ
OxzEtVQuzR1Cz4r2ZAGRzCyQD13Kmhorg/
1zgVQklvqynKzvU1w4+6BEXeTJRxcLyqJuJIi5ixPyAhGbAdGWIzPuQ+eW0R5Wk
vC0q9G45r+Fv3s0CAGLkfOQ9UELms6gICUAwMkh3BVEESMuF8UW0/
IXNCssh/
pwEwAxQAljq4KSDOydTkSPQE3uJHbK4aa9WVnP4zoIzfFUDZPNDQdt2I0yvFKF
T/D9qbCShela/
AHuhYGWMf5Q0zf3qamyH6qri4DHgdjKRwWDM77qoZUfz5AHJk6yO5VMNxipa
bvEr+33l0r+Q01ys/
ERYhYBO5mZULdyaKBqzJOWAA+DD4Ik4LxPJAWyMUAGBh/
o7kfEiYyKc0vlP2pcEgGI4J14ZhEkf+ZE6LgE4SELDI7DECC9eQilzWGmoTlZ/
BqpxQkEIYPJbufJa1V9FoSqa3Kth1mgzA8Ef63SUMi1zmTlzu4LY8AtTZRVOofyQ5
x2GFV3ud2quOh2ww+MjBwIJanhp3rM8WvslBASheW91U9hUWm+i10tldyzsF
3P3ctOYUABgYf7UOMGAcFWDqqHCVQIiQ+LkTBVnYLL9/
xYVxAXlS4vcwnRV2cXygW+fiCkjbMOqcXouZaIq5nE8ck8GYhQCfG1NBgTzORX
roeEGeko7ug/
WWJvY8Xx8oo5jAVFBkP9QPJbKtBa0wj90+PKt9zFfrfleEfwinMgCVqMXwq+N1S
d6fM2y6WVVeYlEEk4kVkvdogL0/hAbhMIKp/
cKyslexXQY6RPwq4BcNHALEK0hw6ZCkGtsN/
uJpePFyOo2IVoiX3QxjW+ibpBmRAE4KEBCgDf6kK5jMnzJyKcADReFaYUjmMbLk
raqmpcokmszj8J8M7G6CjYRJNQ5cQgXp8nP4UQlbXdBvHA/XQLX8ICUXIcH/
eu1U7uYsIJ2BkXx7oBOfdIIoxM33LSQw8IpMM3s6mTsBIYB+wgtUxnhFHBuM8p
4JvahDBsAf6wAOQAxT45CwgpKC8QqvJgI9jFppSIuEdqIdaj/
hnCYMB+Kes20jkfkeZdVpXhMAcyqHPHgcTTNiCG3J6A/
wC6a96TPhcs9qpddAwjK0XjIWcvgC04v9g0BcJ9qXHRwzwwspxkulZDwk1g0/
LpSBW9lrmXgkKuIaB66yCsbnCopXlZZy4ixpBLSBQ4AHsB8Y0pMgOgpK3gPBNJ
zMOoxQP9ReVx/qGgS8mTnPCx7onsFtqaJZdRe7J1attV3naJJrM4/
FktQsKJBu9rXVbkvJ0aORlKLvgIE2fzBMlPa6grZPj4HRyYPUE8oCpS5hOnDqdiwK
EmwJuljHxjwCMQSKtOWCuTDgBXFtMhVLXUq/
0QdwWGFV8u+tVTciyXFHLR5u+tGndjn4Mk5CYxQKi2poOCQUivXQ8ILQ9Bs5ry
zsmYlhfPctDSCAEgA/whwAtgx53p0GlhTMWcBD4uQxBVjgbH9/
IGWawakICgVBETXaq4LirFjM7jD+cxQgIKXXW+tSzE009OtU9i4/
FYgMJ+HTERiLhiTIwJuyNSjFyJoWIVpWf2Q6dY/
hNUiuoWc9eAIBQAP8sgAQQ4KCCVRo+tUNOmNKSOCY2TSQEEOJj4wiWvyIgoG
ApE/ZHQFrZrGIfywxkAtKtW3PdFJzmTFSSsLiTs/
NtkZyOApRizIFLJxbhPJaLjleOzFaXpCCOuXhCJ/
n7kBYRgKHdEH+mZ4tJImPxFz5YUbxwPc0SV/
CHgEcBkfjchhaOhwVnfRsC8RINFyGIKHgqNl+/
5MGBa8eS5IjXC6JCcXrCCo+eEqjPkKCCW3AgAoAP9i+QMwrwnIDZYkc8eB6EK
W4ggcEcivxmkioVcETOjoCTEEiYkU02RAjvT+6JADmi0i1S/
qhRJjniWHmPtQaerScfGAODIO5JmwHgeJz6uoQEtKR2+MW2/
WYhTWl054OA6bTJXNggBhnAGv9pjAAmRIg8LDfonwckOqcRj5kcGww0MOcxz
wht5HTckbFKkB3BAgHBcH4gwhmIJFOk1Q1y4cDyrdGX6TSAalTuPxg1OwDgo3
Wjb/ngKWR1y4IAJHIkf6/
IjGETI5S9VLg+I7Jy5JDPDyYMTSZRJx4hTWzpb3R6ewqLywJug1TKUOIoAQq8oBc
2LQp0QTYyC/
NyHBHxtp17HLcUSEaxBMR7IPG4p9Nsqn8ZABiHC6AHuhBJjIiL9udl4oBbbbsP6
wANgYToEBIMfep1Nls/lW7ZAQbUAFsaclYXZ2o477Fy09wCAApLjJx/
UBTOuZSphA4gE7eIIFUHIr8beJErOFDYQmRKl1uBTbkDU1GHyDqgtjNE3OwExF
zVujL9J5GKHqdx/
vB7nYCRTKKvayg4Tl1KY4kPMJIj45USkCaFmEdG8RJVB0A5op2MQ+SS0enXBD
79diIuMFvQbinUsJxn/AHkhxNX6oCiCNimIKLMiSuWKH06oG4/
GDHarSvCdAupI0OMSHxciYKFUYWf7+STWFGqpypUaMSp7T4KkMFnGuIw/
vW128uFLEwBtyQa/gg/
ILADASKtpWR3cIkERgoXQ2wKD6Dj8g1OlxRu8VTphE4OQRMI5oA5ZP7cQ/
JhVvLmFP7N70rteBN3eECnXMierSJZej175QGA4NQm6BQd0IJMZERzSQ0R3p8Y
NTsBIogDU2v5iRsU4DRMr0yUzY/
22MHH1SNz9iHNABTO2OK8tAhslAgoLttaFefnafU7CaImBgJiMm5J8kEAGIcJ2r0f
dCCTGRhSkk3sCkgLiX/C3zLZHY4Jkm1WBeIOBm4L0+Nnyq/
KFHqNhNEPAwExG0DgrmwQGgTgi3/
hYyDm6kTGqMuYHzOkwkkaFGv01wXiJRpM7teH/
AAs+YAIALyaBVrAt3ZkJfOeTdlVwV3ooSGGUiia+bcf+BO1VQVmUTbPBXaaKuH
yco+z8iu3NqFTLIktFWZc8YMSlAqLC/wAA/szArwhMT5QKcjNDkn/
bh3zsQhbisirecHhaC5LsRh5QxmclF6+ld/
KfKCSyh5VnOQAVVvMtfU1q9H4AAolAAjyQKbsf/
CCjZZoDHSOPrL+1OX2NxZVBb71QhkqlZZCRJQVQbYKyjMiZSOYr9dBsOq+0bO
HDgankgYmyPbF7ZBxsuiVCyQIjFfJRBucUdcdejYO6JkLP8O6YftAoK91/49plFD9g
UqKxxMv+Otlk4UXZxNJR+Wz/
AMTI6i5rVcFGoDywMg1CdWzg8K1vJGjuSHT7EBG/
bwn5qtZwrQcRtoAQGAoP+A0ZGZWgeBOrNsC7QXqvZpeF2ZEtF8ftA+AXhVVi
0FasZdkcloJKClkUWB5fUuwhvZEHKOZarRKoLNCVTjn8VreZhA4wzAP7o5n+Jx4
U11X0w8QPGL5Xhi+kenyGpRFxAgfXVNQGRAdmjAKwCsIrskRuzyiDbar1aKjnrV
61etXrV61etXrV61D8HAT1JAiDdHlWhzKwisAogM/OaJiIXECQWCgH/
wA1auBo7AL0petL1petL1petLIzeC9KXrS9aXqS9aXpS9aVDHR3BREfMBGS9KQ
ABOQTKJChMCw5XpSa+kgCI4NETDjEw69aXqSAIjg0PAbYqLAOmY6yGOAwT8I
8QjkoAvWl60vWk79JBnF4J4yoEQWIIr1pHhuuSyODgBySvSl6UiNCYlxijtAJyTYnv
pL1petL1petLA+KJ4pIRwggdh7NBeiB4AkwlgWA69KXrSCIjlQxplPAEL0pSYG7IlA
Kg4BDr0petL1JepL1petL1pF4CtiTXr1pelIhQmJcD8FcDRWAXpS9aXrS9aWiPHin
RmIYBetIqN2AzPAOI7kMAvSl60qGOjuCganchgF60vWkCEehXEaOEmBC9KR6w
MAGaJaq9KXpSDCPR0FXA0VgF6UiKvRIAiOVCiomYgyK9aVJQ4EmJb8sBBC9KV
DHR3BgfEzdLr1pelIBcFyHBidhGxAr0ZerLfbvFQ+Eey3uJC2xwgFs1y2K6Aqt2ug
XVFKrgjpaILM5lEicnYmAYB6FYpyakkBUB7Rx7rdw4+EJlhBktJU5hq9XHgNOAp
my3o7/
AALbr3EBFAtBVF0ajNE6b7CpcEXXZmmzKcSLEwExTQjFHfO4YoeEnAQ3WBhat
9ujssPiORbwIavwGp7XCCDq0mRMxZD1b0PEI4LRwS5ORMDHsMTFWZ4TgbY6
tHf4lpXZHcr0W7yHnikDlbhwrFxJztWgUIZwuNJkj4mdnJBwQTygmUT8iw6Igjnc8
GI67/kKnaU3zmbEwfZM+crAc8fqhZweo/
UMCmu5sAqoKAXCwQbLSrkBb7diCUIjKDPTIMpuinahs9cqVkYAE0mcF65euQE
O7S4skb/
CAWzXLUe0BVbdcifMHqbk6sJyhuEXWhovczsXtoC8xTi3m6NUMgRIpgjMRmEs
mNxRaXeZG6JpwZM3y9Hd4BbVeiLYmIV7usGFA0GJjEFhXsUQj2s8I0jUOSuouFk
X0zIVDBWDgraYoWrZbo7LCJyMw8yeoXqo1AOQgy96HApqfAaztRBaEcgjWEBiI
viCPnDgmcG5A/
Yv81AjrUd3iWldkdyvRaEOXKKIgkxkRBx780E0aryCDqGdPuE5KW5jMwcAU+wp
zDTWScW7NzSg+xuT8Z5DzCSrCTBTLDaITgDyz+wlvNsmsCALhgEUYtq8lvt2JR
LrtR4Na0FYAYx1IQBgwbAJgBvxGUgAwMMFtF/
GDgWxXLUe0BVblcjncrnqQf8AjYWlAYY4LMKEhXsIqq3gKAXiJXAXLs4t5ui9aNxg
EfkaoIoOMdzpNxRDFjIwKC0w8JiaLc7403y9Hf4FuV6OroZSIzWk7IykBp6I8rM+i
Ai3DABDZU5a+AEfnWwinsO6RF4iabPpC2uKFq2m4R2WET0PzCEna5TU4P8Aj
CirW+3o6nwGs7UTjn9BEJ7qCKB6AmKWQlKB3lJEQAt1ZIKtZlMCBqpsAeD4MLn
Cd6Q1qO7xLS+zjsZ4tqFdYOlYgs7E2Icw5UwiGLGSkHA5wVZtNYrJPaG6smVNa
B56mDLH5CEZnhOUP2AWwa64Hg4B+WkJpnVLuapWUJtAeeFOSPyx+wr5nh7
bMN9uxGvFYCSUCsKp65Gxw4NJ7OLW8XwfLkEaUY0JuVwcaAWxXLUe0LVtFyMf
LgiZCQgFZyOeQERRuQLwUUh9CYGNGQEYg/
vFtN0dguERCAEaICpe3MRNOAam+Xo7vALcr0cWQ5OSw0Vnt2AIVzWQkdyE0
KSykgFhcZLlSIy2DEIOhiHgZzm+oW1xQtW03COyw4ZmpavDeLo7RejqfAaztRF
FwAggqoWi1TBRAjVAgQUHHJpou4kPMsgy+Qc4zKIyy5BUQcE/
LSGtR3eJaX2cdjMnmM9YE/
Y8wKggutNybkKJ8Q4cpMpfZB8gpnxPOgzydycHfN1ZIKtZlFmSgXWoA3m8qkLF
RGCsZfHJbQgO4yJg8/WDgBsC9XaLt51hvt3i3C7is267g3C/
jC2K5aj2gFtFyJKhFXOAgG0+LgojeeBxhQJP7gIxwbFb30rf+tb31p84Hwzvctpujtt
wiMoqBMCACUQ0U7G8xpvl6O/
wLcr3HTUDCDMIAiuUIRpgI7sDGqZuo4AX4iG4XLa4o46dlHdYQpxTUtThvF0duv
R1PgNZ2uOVYL7oEbYDlUnzeCDamMS5o4FBjktEKw1aO7xLS+447BvuTzlWUx
wdm/
UEwhUbOiupiCXgbudNU5kYXkqYBVcDnKmJhhQgHmQM8d+M0lLQdrkfkLLKIY
Wo2LITAwYg/
TFiIJEGREfMKfxHfbsTBHdwsf1Q6JoE3qPwbNchtd3BuF8AfGwCscL2iDAHt1s0Ati
uWo9oCq3a5DMioNr4FNcOYFAghxMQooSxfYCMI5xQJRmdweJA2w3R224QElOF
WBGp9V5BAjXOPbuYiMmBCVjcUMy9wt8vR2+BbleiREdEuEmCx/
UhaNufmeKIaQRCX6OcdEdslg2ddRARiw80khgrkHBgWliUnzl5xnAwRJExJdMkH
PjfMWsNE4iAaBAhsCIQ+5MDfuEYmpa3DcLo7dejqfAaztcR/
Ayq6KA0CYAWQc2360W8p5RVp+A8LC+zC1H4YCYFatHd4lpfZ8FjPdJvyGjGYm
EWZzzCmJ0AWlOFeuBRW3YJimgAZZZAMz7hgQBm5OCpFGbdYgzLxwdOj9kWo
uPd97IjRYDRcbYTESsTd7D3hUx327GneMzwMzOftXAxaO7XIbddwbhfx0YFsVy
1GAVW7XI9N2y2KQaOkvKJSpIuB7KOpgW41AVKkKaHbzqhCgoFdyFuQtyF420L
abokffuuLKcFulRFiK1ItJuhsoIGCMkCU6il3hOpjHIwBhGyMDISW+Xo7/
AtqvRMPYLGZMIWO9QMLwOaIaYTB2WSqKBF9uNaEg3hPVAREXV3eqB8IGAZN
1bqhUxj8ycFODEQGlbI1/
UJFjERAzrO9olMFumqRNS1OG4XR2i9HU+A1naiZnpiG9DfYsBL94OAi4LCiMD9
Mg1kpzmrFk0XQu8di1SO7xLSuyJ7hIGZUkrERiIxFTS4qIyTP3DySzjIST16JvrIcte
BgLdYMHNsX7osmif1lKO43w3u9Ckd9u/
FLdrkN7u4N5v4wcC2a5bFdAVW7XIbQAYg2ok0iTaeEAk02SKuIPOnHj3m7jKdd
wCNmQyEAMAE0ziuUSHBIks+1RH+Zb5ejv8AAtqvcYBJYTyVYqFYsCIAEGYKce5
wCr64cplNNmdgxeImyWFxDty/
rEEEBMAsEai1eG4XR2i9HU+A1najtsSh6uye42FDjZpnjDQLWv5IRwkuvDIg7jzo
M6EYcyvW162miDCWamIOIYf0cFbvEtK7Ph2zxjco/
sWjN040TE7DK6RegP0tVAMGEG8jvWasCMjgPcKAgAbGFetJzwDbpAtzETEKjWo
NxvjkKRGXK8pFsAtmFuwt2Fswt2EeaRKwxGuleE3ITV4OIeAVXlWh1uQmFYloXi
6T2F1oTswih7ACOSIz2CwGW5CHo0QdYABHKA4IjAOCnCrWby3I1APZkiTAvOh7
ahIItJ9AyyD4MRZ0EhbALZhbsIF/
JEBzB9kaEGwGHkgCAwUCm4fMWIQC9QdAcSWhOSGGb1QrLwbxyuEGiTS8tG
ZZjRC4yYlfLyy2YWzC3YWzCBi3bRzmh9kSo0gegIkYgzEG1PRu3MvpFoKAgpg7
nUqN6NoriAD6A4bU+gBpJuDGEhIYuqYgO8PNMvQDcShaRYCQ4KiLJYJNRbsIwD
KvJRZzPLyU3YW7CNaAFww4Dv3vKSA7sIooSDWGFHSSvdhbsIKKAiYUWLdhbsJ
78uPFEjPcmotmEGpJi8JmrWKiS3YWzCwmrlMjZQoHbMLYBbMLdhbsLdhbsIahH
gF/
vG0NbMIoGhckGRsBgEQAiYFPEcNwK3YRZeGyEwo4Q2rkQ5JlC1bMLPduyaxK9i
1wTC3YW7CCxHztgwGhcALdhBeCRJaU0Kf+4//
aAAwDAQACAAMAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAFCMThSThQBzHkJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAANHBjRyBAAEPCBPDJCAARXDAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAELAOIRTgAFGEMygCxA
AAAAAAQAkABvBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AEADU5CAAMPNaYgCxAAAAAAAAAAAAAAAAACEARBAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAEPAiUjqNI7gTggAAAAAAAAAAAAAAEMDJLJAAA
AABHBzLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMGcJvWwwSBgAAAAAA
AAAAAAAAAAAMNDASigAAAQRBIAAAAlACOAAAAAAAAAAAAAAAAAAAAAAA
AAAAAADihAAAAAAAAAAAAAAAAAAAAFLY6xRAANGPNzAhlhIAgJAAAA2CALA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAeBiBKEG+
xgDRAAAAAAAAAHB3OAAAAzjRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAEbrppRBSBgAAAAAAAAAAAAAAAAAARISuAAAAAJAuAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCM
6AyJAAAACDRCAAAAAvAyJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAEPpCaagBCKmAAAACqAgAAAAAGBAJAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyaOAA
AAQARNAAAAAgJFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAANCYaAAAAARDADAAAAAWBzAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxzDiAAAAAAAF
AJAAAAACuyCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAeFAAAAAAQhXAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJFDCBBaCxREBAAAA
AAABLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAARzCyAihBgwBiAAAAAAAAEiJAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANIGLPDAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAFHHMJgUT0AMufPuHHKMLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYDDQjT
TxiCHzSXICTFJAABDhBJAEFwwYDDMAP7kJQoAaRjzjYThAZDHGAFCJAz5DADzVl
YlKqE1UTAImpG/
czgw1BhRAfUaALCDAAWAyGCAuXLDjSvQqlDDTLvAoSDI0pAqABDFXAWABCAr
ALQhJfsYApDZhsTripAjLALpABQzA/
UTXAjGJMDADFHA2XLDDQCWoXAhGr2AooAopBAqABSxHBijEAArArAniCTCfDn
gMCAWgpRQjALpABRhA5UtQKIEONIAAxVPgFrXLRNorBjZctCOhCAopAAqABCLr
GA+BOArAlGLZziiqjEqRAKiAPCCWAmoAGBDCrOhnPdCAARKCBTqHwDVrCCYhj
HQjHPGahUqDFCjAKDgCzVxOzCvKCCqJenQBqZTSKpEAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/
8QALREBAAECAwcEAwEBAQEBAAAAAQARMSFB0VFhcYGRobEQweHwIFDxQD
BgcJD/2gAIAQMBAT8Q/UB1QS/jz4luq8tYes6S0A5V8y+rlhLg9XWKt/
S6hzdZalzx8y0TsmBl7jtpCKBN3720ZzJt3wqwl56EdbOKstIOB/
ZfjrpSKuL+F4XkzZPjQ94i6HP4hnHvHKPRgLI8/
iXRvDGK0FH0rRo7phwo256MErU3Z9P2tqzmTbrgPxD33oaxto6uk2T4AS87zfU
FaEvh0ZsvxSOsHVmmjWX6rz0lpHPHzLQHI/
4FUIm+Y7ibrdJieBuv0iI0YYWjK1OvrrBBUt+tt+cybdcB+IG+8aGsfaOrNk+FCXq
eK+l1HgOkta8eZeAOekfbOS6Q116GsuieKy2jprBaCn+IPDjtL/
eM2q2j32ePRirHY0+0hlqn6YqrDiy6F4Yy+T2ibZxq6TZLgEbh6jLeulPMuAOKfM
bZOrM2ciXKrz0lpHOr7y0pyNP8NszmTInfSfeOktI8eYVVV4fklYFQY7NNIiqMyq5
mTKuuJmfoLLnOCaVcAy77j/I2b0e6xy1z0IhUuj7sFdekuAvOWEefeWFORp/
jtmcyWmrgPxDX3ihrHWDqzZvhQl+nm/ijVUZhio36xGrFv1/
Ie358dYnOiQE1GYLwFz7l/toKVllV4q+8s6cjSBT/
AC4yRxSbU8KsDfehrE2zq6TZnhQl6nivqC2l8OjNl+KR9g6vtD0jVgrq8/iO/
wCvxGXzo6TFmdj31lFKO/0p/
uhw0glqn444wFn7lERUftoFeiQOx58NP19njiywVcD+TVDpMnHLWXU66UgvAX
qyzrpNheKRFwc6+0fQNWAuPQm2nFfiWkdIJQU/
44yBKzjGzPltiI0ZWrhmZMqy4mZ+NDXPMmTXJ2xEJRINOFtbfn9UqFZrdDWG13
GfMPxM0dPmDunppMyPNlkEsKcjSW/xjW/PjrEx0SAmo/
bys8AufcvxTlUZfht7OMtKlG4OuvX92tLywnWviszU8tYus6RVwDp8wrfN3zKkK+
fxxxgLP3KUDY+eEOvRJVjA5bd5+KIKjK7jbGz49Fpfcdnx4ggqftqCtK8JZPzQ8My
NOCnzMSF4qxdnozNnQlyq89CA/N1hSujsbazYY+8yVWYC59y/
Gl7UlL4jJ+5wElEhJg+fzu/KvUuJpp0iJeOXPH43dIYSo/
vqFwuTshJslnJ+7JQjgLnufcPxWnUYvf8AHjrBRqQaX3Hbx3+fyyl7X53xwFElMOK
uaQG1R/eWUOKS7jzGLUcGYKtpUpt+0r+SAox6iwzNnDT0tLwfZ16/
lUFsjrujsqMukMzb8yuL44/u8YF5GkuQ6Rf+9ZhYPX/
hWMLYydGI0KJET4luHx+VH3BzJk1ycmVlfMza5mz/
AMMCpemPtA0U2P5pyqMaox29nGBP67paQf3aheWN6msuA+8ptJyYjary+Y5T
7QPk+I5Y6sXsO+sRZDlEz1WKDp2D5/4OAqM3CMZDJ8lf3SVlhekWyfecVyd9Yr
83WfUsdg9Wcbr8Ti9fib56/
Edu7aRDEO1x+P8AkdjV8YRUM3wf+KRunUidz1NYlcdSXAfeUNcy7pBw4syCv3i
0nwL5iln5fMDbsQNvpymTXfSKW7If6URkn1ui309o3j0ukXuybggtfoMr5+jpN/
6Ok3zozeujFsja4fMwtirv3L/
82z5GpXObj3m4946gU1zm495uPebj3igBhXOPaODvhsqYvaOaVpNx7xCCqB7a
zce8VQZgDjsHvslRg05xjmGWsEFT13Yi9Bm495uvVjlKW8x+YYWo+gyBrW8VJ
B47IMA121gMhWu3KDwa7azce83HvAWKWcvTBMWwfcIhwe8b5gYmsAVLRGR
pTbAwClLV9CicFM4h0qjSmM3HvNx7zce8LQFFc9+k3HvGVKVPQABwrnNx7yq
wKcWZ9C5mehu5eYVcT1YYWGKbkL0m494Jw8cXas3HvEQLgxCdaX4Tc+rD+I
8dlSCTFeMYmacYUwP6Y7H3mENW3CKwVXxDZivG8EiqZTce8EnPznKChVfENB
V4ztvdlSwqFZX/
AB8xMc00tbvKv4+ZuxU6RLbjS0S+4UtO8fLLHFnZe56dme3pvZgHGIEqsH1Ry
pXrPuhjKrvPc9/
Xt3w+ig01NnzOjZyZXRqfPp5HtPL8M7R8ztnxO0fMp1dL9pSiumNvRM+odUjhK
rAtUcqV6z6IY9SYXPcnbHidseX0798sr9dNFJX/
AB8+jYDru+ZVWKpspk+nae76WOB7ytYVCu2A8QtshmzaPB9LDxfaVBXKYvvg
5ZTtHw+n18PTtiI7ThLwA0m+PsxNI4mSM3sLDSze7F7QHeWktABSU0sYHAgA
YIy0AlZUqGYe5KSvE95TyxgcCUBzMD3fadt7sXqw7pvXVjuVcfL6dw+WXOL7en
ePlgtEObrElFPN19OzPb0TR+2IBnb6bZKp2jINsYuU2U1n1DWUBYJ4Pp2GsJOYdY
kc2nk9PI9p5fhnaPmds+J2j5lWNGVU04wjhHZ47CJRyr7QGLVPQtqq+IyjaTtjxO2
PPp375Zd4vt6+f5Z2T4fTtPd9LHA94jGqpSG3QXgmyavAi0mxhcOGUwVxGr9c
pRFbBpO1fD6fTw9O2PShC3kfErZk7nxCDbVgJtqeZSHJ3fiVl28n4lNb2OLN7z/
e0q6WA+3tKu7+D8yoUsxNOcqJo/
SZpEB2idt7sQWClM9tZ9p8QuuYZHp3D5Zc4vt6d4+WCArVhWxD3PTsj29GC5
Q9sYDvGMx6GxgnhN+
+Ps3llCoKNM903bqRJcD3egKxDWIlp3Y5MjF5fMxLImGOEaCpV3io2C9vmdo+Z
2z4naPmYHBgb2ir16KV5el7D4GHjxBN4xgOobGADUb4g5cWkfJE7nxByRwY4q
mQRVK5xyN3Hr6+f5Z2T4fTtPd9LHA94jGihWL7pDVTFjXbu5TDl3A5/
HpXJTZ9IiBcgIM14fT6eHoDAQJukc35nL6wVdIYLrEQyf5FV1lIN3F5/
Eppli8X4lWdGJDUpMWWcHnbv6WyK/
MYu5Q6+glZwyHazf8Ao6Tf+jpHFjDMTP0Y47uTt4RUCmLfl6NSu7k7XdBYKNW
8ARVp7k3vo6QAFWh7Tf8Ao6QYKwKCps2cIpRfR0jWRtftYK/r6hRNj4Zv/R0m/
wDR0jeQ2uHzLuVu7Y2WFdkRo7yYiXnYlUZwbG+F1Ao5OyVRnBsLnN/6Ok3/
AKOkRxobXS8I2CVwMNmmkRovR0j2RtftZ1Eu2N/
4sSxqNpjBlB9HSAiobM3QgU9N/wCjpAEUcfLDUDY+Gb/
0dIxhRp7voLUcCw745MYZjti0P3CHX1NzpHK2gbG7fLKKCAMcSbqNbSuFBt0jKo
oNMHMd23zN/wCjpLCx0zf+jpN/6Ok3/
o6QIEo0IKMlyg58pTgUwK77yuUrg07RIYZ1Gxyi0KxQPF2OkZ8cuZkcYQxjSpxM
Zv8A0dIBVGmPGKqpwdhuhVUWuU2//Iv/
xAAiEQADAQEAAgMBAQEBAQAAAAAAAREQMSAhQVBRMEBgcJD/
2gAIAQIBAT8Q+pqIxRWV+FZRH39RGKK/GMjK0oj8EE79rURiiivwjKKxBF/
JoNtX6+vqIKK/CMrEEEX+NpMamJz6iojFFbIyisQREX+Kogq/g/
xicE79BUVFKI8QQRf5KiMUUV+SZCR+TVxOCd/3Qi/
z1EYrxjKKxBBBWqDvi1RqYnfsIxRXkZRWIIIv5v8AGJwTvi1RqYq+s9keIIIiL/
I1cTgnfJqYv195URisd8WqNTE75NYv19xXinpBAx7QnfFqjUxO+T/
GJz79qntCd8mpif75NXE599UNpi75v8Yv15NUkE4W/d+iIgSS/
g6xvjyao1BOCd/4d1/BqCc+9qKiCCNKKxJ/F+jj7uIiIiCCCCCCBJL+T9s4/
wCMqKhhezn31KV/hWVlZRRWez2RkZGRkZGJT/
5ttzRPwCdwnRuYbi03ML+QNwVDcFQ3NFWNpeA4YndX1fAJ3C943NE7lniX1jo/
WG4KmOBO4Xsbgq10bgmZ0JXCU0lRKDODjOMbmmoN8a+YqGoN8a6x1hK6b
i01Bvg60xKrSpCUxczoSo4F3G+Mb0PmfGLmP0dQvQzi1uvUjG+BusT5OsrFzH
04x5c40u6XRtIg6sXDgXdLuOtVihwLul060zjeN4zoTg3RdxusaDex8z4xc8B9F3
CDcQunRwNVYvedCnyehTH04xiXoaUzjEqxNMbonsabZRIsTUG6dFQ1OsdY6P
WdwmhqdHQnGVLFzeNXM6EqP1huLK86sXMTUKh+0L0L2P0P2JRDfGWnWPuk
9kZHpp04xpnA+EY+EeP8EZQlNfCMjIxKDTIxKCCexCMjKF6GIyhKDVGmiMWox
cyMXM6OhKez2E9417FwjFwjIyMXBr2J8iCXvHWcD9ojENO/+Rv/
xAAuEAEAAgAEBAYCAgMBAQEAAAABABEQITFRQWGh8CBxgZGxwTDRYPFAU
OFwgLD/2gAIAQEAAT8Q/
i6vf35xih1EP3kyF7v5iGAd2+UCddV+WNUB4ETnFP0EyFlVmrzcUEoUhTtHj2IO
9C5UDjSv5pKg598SjKPJo94BLPwD3VPSCOn/
AIRzU0qlT0NXDrOKPb6eEho0Ife4fkfj8BUQC3ib7Rpt2tA9ic6PM/
4ArFIRXvLRZv8Ap6oZRPTS+7ygkUI6J/
P+bZzOsZKnYH84oK1Lh1EyjnJfAyl8FIke7EFecBBO0O5tir/
lFDP9a6RRhdbF+yGrmxm9T+bpARr9ix/
kkz0seV7QoPuwd2Ev4VLQC2BhVNQ3n2pOem3XX8pNL0GWKV5FF4aNxrIxl20
9a7ySKJreV8YECq0+yYPQSBIGDT+mKa9ryhFQAeuzvJl9mu+yvyboGT3EpzWk
Cs1fd64REa8Qr+4izJmyrWleTWBUDZpOSfy51oIUh0gp6XczQGNHviHUxuBAon
iD0npPh/
aZZsipFbrxsfyaIF2p9p6AdPvSGkLiFYBYpwbNeyu4qjnAg+lITm+zxzTSEVHsfnA
oLGU6PmPoTH1fQoXrkf10OpqNR8JG97c83F3hytRdb+T2rfSqcL0V49LjSl7jSCU
zsH7i3AspvSJLSwXtqBeyxVbX42mzcsPYjb5l+mm98zPPay1bFU61PN7/AJwh/
iZWXWG9wu6HGygwPQ/
ylDbDV6IOQsyr3tU1cVaXo+ARKQ0YszoizL6wYtXbD/
H2AAaq1AFULQKdZkuwv1MAdgkfccHDdqTQK2kvrbbB1fxC3TQsZ5aCiWJr3im
9u7YexEE2G37GbmuUH0I5uW+XikO5X6gYhaAUf6N3XlUnlmZPSZSXLhD5GW
SDgj4CjRm2/SwHWxezNk/jChqwO/
Pc9rgVuNifEtSTQQ+9zJgN09I65tiEst1qBeyxVbXjBY7XejkR8U2/
nJV1O5P2gtod1bABZHd5zOXDcfFSvbpx/cQeWaHxpKD/AFjRrSi16/
EmXWS68p4vA848l0bJxGMhmRyfNP4kxOdX5FiVc+L0sBQ5yn3bi5BNQ+iBCjQ
fq2xVzHhUi3afEd/
ebESN9ECKRNeP7SBryOQpZDgQdWMps1BD7E1xub5TDDJ9K/1AAA4B/
tV+CAAeCMfPGa939I/DErkTgjiLZ1WBojBzmGg/
Xyfwt2RapRG+Qr2qzMk2cD6QSjDgb9kAY2qVhav9qpOaglXXEFajlw1HoS7d0+
mEQHgIQacSP0EXYjb5FFPY3H4kbeir8/AoK4hfiDUXyD/
TqGrDhPEQ9FiFLbfFkqShsV94FfK6P1G7zpPCLyfuSAJ2slcbY/
YSpFnCD2OcAbQn5iGAsSuXu840cq+SPEcTKotiZIwtuOPc7fnAIqx/
gnMdfzLBmiaqXSX3ACgfe5UucBT0hpGEXzYz8izra/
wnNyaiCrtgVLb5yx7EZvYyHWoN23cYD7rOfSDXLQlfVmoDIA9ammfkP9TQibqo
EnjW19rm2FX6mE0/F5cipvTSX2VeEzLDNmHtHbbufgCkVNMbeoE4ydN0NI7/
AMkOXJ94BFWP5E5gqLP+zlHvFt9dDwZjVM65bvIOiAAOiJ/
vUFUAREajW3tcT4GxHvQjjgu/
WLKVtNevTc5Wx+1cUCfzvRF+258rKizr+9jY1GoAfaDRR/
RscsLrviclGfCH+s5vKVEouull7XGUY4frYIgDiZ0uCl3BDkYVEf8AEJfVOxt/
w9Sk9lPLjFLlI1n7bBHT8Y/8wOW+ODHan6WTts8Bks0arfdOUvKAaw/
3SSnePPkImRVTP5+ZaUbr0MVGLN2+aYfMdGydJ0FY+P8AXqGrAL7S82Ohpa/
SIIETQJ1uWgo4qzIdsw377Y82Kv5HqR2dleh8Efckqq8+I0VXHO/
E7w+o9TDTUQZQ5E7eGM4iNC3iqCwrR86cUkXJduB+OiIArEm+CQfQ+ABZw7
H4YyYDAeYDg/yhcG6hHWF7vdKXjYQ0aT6qUJ/HumKwrND+bRj0hA9iO23c/
EBWoo+8DQh0Bp60pFiq3N+MAlntrCgnj+3wEtOc+RLBd0BfW4IGnD4E8aDqQ
3jZI6Qw9Z6f2MXT3b62omng4+UDQ7HEmsvy/
YT8a3dWIHUSPZ0c6527l8CMXQ8ozA1QQX5BP5FzHGT1ZchrUFRam5mHW5b
ULiJH0ebM3Ky2vyv4AVoTkI1noQA9g+CMgG2SGd9VBAOcdxawSbePxRXQkX+
qN2hv8ESnbCCv8HWafZgM8mkbY8ch97wAZMqxaIkLyNsy/
XyfjQRHSUP5+XnwHlHPKlcicEx0p6HzAcRizKVc0+X+OFQRqF6sdRxpNRFqq3Q
dblkLNFGDqLti+MfJer118Nfmul7ABHSlcZ3kV3WBOcU+JFr5+TrUuO2PWAZvQ3
0gVs0KLqsBG+iI9idGw/yzZCpHMSc/M0+W/
wAols6pExFYpBsY8gXEPgecNqIWJ+MYxL4PpPOPLJXFGN/
FhUkZkLZD+LK3VElBC0Kf+QvAHgyp95uXRxIfZaRE7Ppl62HVeYeKDkfMszXY2
wq0/N+LNeXliPHeR9x27hsMqKW/6CUAHl+UzkGo/wBQMAnAz/
TKgvHpW78ka/
rZ7cPgXyg515+8hZ1YgdEfxtgqhZvthvnMHALxMQJMqRaIkODgXl+vk/
iZhwG6I8gHzMpRa+yUUWPOL/
qO2nzsctTts45aW78ohQRoqV0h9eWH+xL9niy3xwYoUzQnbZ4Do5o1q+4coC
Vt8A/
jP2EozmFLWtcaDoqDYkGo8mTX8TzgAKsf504UBqsDvltj5ibajs6ldFvQhhC0sfST
ShMVPU/HXGIViQGska/nTn4CiZy9HxsGp+4Hijgn4wR/
pqXBOCRdk0HwA0GhnnI3c8GKa1AdEf5ojJdQg9WaywX9AypLaUE9YpzeCjpRG
gLf9c2x/LCVfAkHNC/mrJlRFsmfn+8MiFYmYn4mV+sQOok1aDnnP38ngKJSaN/
UBsyTudDf8ahDHgvBGZn46z9/
gttXJ1526Dgovgfy9eaFr86wY23n3UlzukX7Q4FNlUUZumr8q4DKDA+h6HxBBn
miPvSZG3cnyYYLk6Q3OJ++XeYK/
uUHvodbSaudVrzNzBoQrPv2SXdFkLiP4tZqQY+XPgcTipKaiONJtMn9KQOEII9Zy
/GpEpSOYkoM+z4v26RyKqkckTEy93d/4GDYDIOa4o4J/
LCDNM6e+YTWwIkexucZFrl1ksYqxz79SZ04cv4EUsbzEU59w/
KABT99UFog8dLSbC76gxvlMD/
gODB7okelDBFvgPxitsQ+s5yh2T5JuOLco1NDxDiMKlzVZvt/
ICsh0fmbc0fyKvIYkLZNOz4gn7+4UN/54nI1kDZiuYjU/
swgV7tFUWfSa4eInBPxpCJa9bO5yi3lrntwY34CNSMVzZyB+TbDlzycpxIrl9HQ8
E4ji1gqPQQg44WrX2c/
54CAsdSVPJeVczY8onXFSUaiMBMvLcg32QLUcy64oOCfjcmLRy3xwYmVXZV9OI
WzqsDRGFUQAy/Xy/
kWmC1fMERWa48MjuwaJxDiMLredIdf+eiILkJXznnE0PSGjdcSLBbuByX+QYqS2
BABU8R9jEmJ4nRE4kZyhZefB/IH9mjquAeCQmsrf/
EcQWgriEoAKDSvjz8v5uqDGqPymS7aM9i44EexVB225g6rGqq3f9Ue7sRXrgRI
MQgs8ENUfynCMiFiRM6Zu1fSORVUjkiYs7vJoTbnQBFCOj+N6hrIGyTOBvWfvxh
0xUlGiJNFG5dydn828oENe87Q7zEbJd/sLHrN2o/
UuHzaKi57t6y69wQYBN21nvji/nM5c15u3NEygrymNq286+D/
ACKRKUjmJOYFxH4HlHJotI5I4CsVYmoUy4h93OACrHR/
8LyOrA8z5YXXmtXfPEwaYRkSBsSWVE9PDK6j8om0cB5u3NEegrimLiVrM+Tu54
GZC1gdEf8AwuyEkags9GqiIph8bhEfmRhRsw+0iSQ0eoOJiFknFXTzP/
C3dnrhkDzYq14sEw0lvIHw/nH6kU/mFENgLlU+HcwFEVRLHUjutflP/
AkagQCx9xJbg7F+4d15+GHKcb/
gJnw+c+oY5ruZsT7LsXzMwL2oh33YEyFPus0WIu7xfVv/
AAC1DujJ6c4lCTYprROThW/Fj5P+bKGrFwY1fnGc8IK/
DB1E7Go1Becl0V+lyKIZuL6htc9+NhVQgrjvf1SyvsdkRe/
RSO35nflhtee7+BzyhfKvAJXbWHtbfm/whSHqDZdKwedXoqt/
NSZWvYvclpmfCcP2vfctPWT9ReNbg/
U+UVy+slkKV5zf3A2YrLdOcFZznNwA23mE1i/
Ily2tRh4zRiR4GRmkfKRAclDCvH6P2SBsJo59F/hnAc3+Sj6w/wCJJt/
46oFsIhWc0dR9cFpxzyVf/HSEsZAfUO/G+AxjrRl9n/
xNL3Aw32Ifcsso1v8AfA7G5/
ujVWeVp27BtFMevH1NSORfyOD1WBQQiIhz4Yq1VnVwTMC0YNDAhGoMgP8Aw
FOm+SQqyeytnOmL/
bMoS9jKd8M7Q5RzyZrF8h8wknrR+4LXeT+pT1XIPqZLIDqnSd/
j5rKItMgr5JxlmG57H1db9xe3d1Y9bcz8QTmbqE7T94lBLxf50YC/
DoAUsh5wYSrk9cbAGEwJR5JNgk5D8ItbNwj0bzGYze9GA9qOa8AAAD3cPnh6Ku
3yi7h+5359zvT7n9Kn9Kn9Kn9Kn9Kn9Kn9Kn9Kj1HQTuz7nZP3HapOf78PTfev
niAA3P8AV6HG6ixBeWiClLQKA/8AzVjLGJOYrNZ3D9ztn7nbP3O2fuds/
cR17nnB7igAudM2dw/c7Z+52z9zun7nbP3O4fudw/
ctbtU1GmkjPbBijUc53D9yxpTKbssaAGCnYFncP3EltXbxgwjWjRGVehRK2LnbP3
Ete55w4RrDRHwJNRgw9LuU4Hmw+I9KNX4V/C5uTNA1VnbP3O2fud4/
cGUI9vGPAjV+FfGgrwGjtrO2fuNDq8YtLqM7AhQBqs7h+53D9yutnp2Go0FClA
M1YaTuec7Z+52z9ztn7nbP3Brvokeg+J1AtRA9Lnu8mviXw+rpH2HwU/
NVbYLOwfudw/cLEUQbExY8lebgLO4fuFHNCsjVoYuvyVBqlzuH7nbP3O6fud0/
c7x+52z9xEtI7eMaiNryK3m2qCljHbxncP3Ku2aFss8GnCTfMLO4fuds/
c7Z+52z9zKXDgz7D4i2bRgc1nbP3C+lRFNAz8GWOAQbrOwfudw/
ctKNU0MskmTAwYbrO2fudo/ca4aCojTmY0qLzFCyxZ3D9wT1ktToGcAqqCdw/
c7h+48CUGauZKQA1tjdZ3D9wSxHbxh6iiGiMbYclQ1HOds/
cSRdPjyDGyBQgbJc7h+5aXapqbJhb1OoZetXO0fudw/
cFRSiB4iYmSQUyHks7Z+53z9+ND1J+JHbtG7w877nxdv2SmZgdPzhoe2mFGZ
yZ3YCJsirQPfY1eurY4Pre2S9SKXfKJhBlesHjVP238JM7bHofMizS1ygiB4ayewHD
wavlO1bsOk/
HZONDovsrJGdZwLb8uIotHPbI4sXruAlNUq6ti4MzW2Q8kmjAeSO9kBbPJ2cOmY
RogoTh8XHvOT8T+DRO9bsagn4WxLYexiPUjlWMw+sgH5M2Joj4BFqB93r8YPw
KHUDYyregfoj3HHsW5+IqQIoRMpec3B6Qi7JmRAxB+1aHuMzqEwNdzIjyv8AkC
p299fnBjEnImVhhzmZD3qMVZXiVtwoXfnb7YNbGxuhke8bfukpbgd1lPfI6qwN6
guatHVIiNYKF7TmzDr84FrSLgFssd9gF6BgQrQ4DwMhLvfhH94n94nOGcUDMP7
xP7zEWgQwdouxH95n95gIUeLLvO7DoOKg3N88Xb9kpnYfT853jZM7rtGraDms
a6uj8riIlqMUfhnofQcoBEtFj4u578R19aJVPSDFUYgesZUMwIufGXMcsdadq3YdJ
+C8REH4m0pg+k7V+o93jq9nBBmXCSbGCZxvzBfmXpdXi1oHNjjLXNOCGNC7
1ihMbgVoCA+EFmI5iYoGidu249lyYvsqhf3Gf2HG1yvmT+8ShOqR2nZbGgZ42b
E2dukOvGhn9d3s1r4EAste/PFwExegnvWPetzHq/
GpAgLbzl58ORsUmGjSR6p1iWqsnJ+28Mufzsjm6nsKDMGj9vFINRJ1rvlgCz7d6l
PTLB/
uNl645Hi+6oIBMGsEPDYf3oMflA3NP5A1M5YPXAPmq6EIBT79e2ngQqKK7JL+rf
qf1b9T+vfqcnogSf1Sf1iEpLLPJgHm6Nk/rE/
rEDB2hRMncZ8Oi4h735Yu17ZTMw+n5zve2AnqicdC4PxPzBZoCGb4IXsOhAgx
S8J5VKjPxYeZ4adUGf2+PF3Pfir6mUsxmLSYT2jVnZaIcEHc0GkcLJ/
l5KHHWnYN+HS/
guHHCmiG3Km0BjvkBWptiVVGdmsti0D7HBwYmfKuQEGjYg5RYHSKWhPKoXIj5
pS35Y5E2LdZb9sTDR4NXZcmL3RSNE2f1iZhotwTsO+F46a4eDP6JFtX9H6hsND
GqBnjZsiKovJugDJR4J7Q9DO9TAhyHzwcWccHNmKtVY2s2zqotOJUf4+bWAAqx
w71uY9X4EQ7Nu8Gcb8nTY9MAetxFnI+QjP7AjudhpIgfq9LJXztIFXRAVCNKY8z9
5AowDCp8+k/VgBphQFlH354PJFJSMPqGZX6wDMu16oM/
SyiLQWNSDUMI8mcu/
UqWwaQd94LSwjhH8NDZAo0MQwwo6gCgjw8vFMNp4Dsm/
DPZMSdjjlyc+NQ3F2vbKZmHNEVdjllzizz/
iMBKmbjAt2h0BSdZqO+9BhQ87aPTxe87/
F3EQPnhbhxlPyXMdadt3YdL+C8RIDVaWqrAn9z/
ccA0mmb0YNzB5eDZAAKIyOb8kDgegiO/
wC5xNEorREpJ0ydirB2WW9UcTDR4NXZcnhP0DOw74d93eL9Qq8bNhBHKo28
4QYLTJ6y/
wCXSjrnD0L5QOLJ3UOyywlfLX2mkdlBhzvwOH1RMr9Yd63Mer8CId+3eDVzb2v
098LWIbZLJpY2NqWnvH01287o45O7lw1kTsavKz6jdWc5q8OndfR64ZOCu3OP
SKtVY2sOlTOxOb0IIoUPccMvq5Oxli2aJ2cC0HcU4HTgaQTqSmgJQo0vzC/
Ah7ju8HdtniA75v8AwO17ZTMw+si7Hhg6o1PNwvOcD5eA1lJe1MPmQwoQdrY
VBukOPgllPCZpRWug2ned/il/Noi4MrbH1fKMRofk4dL+S8cIBhICnk/
T0h5AiixNyN/9t4aTM+nwelT70AfFSoAujcTuuTAq22J0DOw74d93eKxQM/
GzZUllOe31uWAHm3eAFsXpVuQ5H2wqo8lOjoQnFcy8j4rAqC+FL2vDsW5j1fgV
Ls27wGVNjsKhj1zlpofXBLaA9pvH/EE7ubEACTP7uhMgpTy/
oMKXbTmqhA1zloq8FpZw8+Qwzpgb0XSWwvcLn1OGoluxoHqQSQqcQswobzX
x/YMoZ6tEdRMc0RB2Np4iG2WjDbbznb/3O8PuEKVarjTX8RBLvm/
DP1dyyUV7TpFP3v1EQtRQ2OLte2UzsPp+c7/
tjIAxuJmcFldttl36MNKIWJgsJZW42XqNS9qR3Vtwpshd+Gg62HYd/
hlrucigC1gItZGoGT7GGvKz5FMSzsw2Auc7Z7uDDdPZDwfHRvAcDLHKsXJ2/
wDcV/
wRaaAVuEjbRNkwV4SriF9NzK+8tisB8hpFMA8UDMRwHa0XxQyPVjsepwthSN8
4mdBntOHF2xVDu6Rk/GCzkOoAtZrI+gWGHAex53/
WPQM7Lvh3Hd4rFQz8TNrwjcAOjbMDEgagGgYUvo9N1+3ziTWCbBW8QRKGcx
SZrhqhLHtPUhCQU4hYzsW5j1fgRDs27w0enxX98HFhzLy53gAW6WxtuuERoCJ6
dbUmki8Ax1A2MQzB9GYHtgN009jgnbRfoAtYvyrJwcj7YK8zC8hQZJHMdtgVvzx
o38wNT9rxNIsH0eBK0o7q0Q+VV3Ne54kKkhBUNfPnMu7979zn+9+5l3fvfuOW
9c4bn4bAHfN+HTcRMzf8sXa9srmYbT852TZGsWx1Jq+j84k30cvYI6IHZmii+tz
OodfW7vFwGj6xLNASkKofnFByUaWqVxn9x+s/
uP1n9x+szgWsGWaqrzned+J2AjJUDflEjw3R1rDgI3mHGXEKJdR+2vpE6U3WiZ
aTfvd10w/qZUuUttcQJoA8gHx+DxwQD2LCrPUmT2HtLjNrLXimNrbVd1wN/
kPZis74NV04geGsgds9YSlhlkL1mRhq2VuYOwMPZVyAnGnL7x6QPiprwRk+jUW
04/BKcBwECiCcTYQZCZ5o9bilVzuSfGJI9THhldN49AzsO+Hcd3izUy/
GzY8nlSublCRZcj9PA8wnIkGxIcQIDgDodcK23qL6KxtLYlbrF7n7XO6bnj6kHOra1
apcyL6n9z+y/uf2f9xUUI1LVlKeetz1LIiNYgzPR88j26x6cv3AyOinwVn/
ADFD0KwMd9A3V7fONpbGss9+TN49+2Ydo2zR8vxYe07fhsZd134dFxUGd/
yxds2Ym6fnOybI0FglgckYvQrRanj5eEyCloMyxNNgLMvjnc9/
jNyKpKOBALiAUAaBMmz63b4jwJ0K2A4rkTT+q7gzfVv8hDggbFS0EK3BaoBXpn
zDZBUjmJGvo2JXwwVAWR4VfXNo/
DGhstym3nv4hsLdMp1GF5flQBQGPRM7Dvh3nd4v1Azxs26PC0SQGvCOY5y5v
C2PAckwdplc1088G3elyCxXnLC7zmrwOSFRS3/jO/vqd9fWLIZ7PNNeXOeq/
Jj134FI7LuYfY8r9MVRqOeaH2+Ywhkjiuh629sVpc8pnwJBQFGAiAXueAw+xN9JC
KQAOEek78+oRBZ0ZOfWOHJoCqWRvRyvwUzPRvDv2zDtWyaPliD5DWIT68YPc
5zmtdUIDMxS/wD1qoDBQUamuqPBRYcCmSOCgjZpazOKvJasWk/
oSE9yrUAgJryfxyOCr4yPkarggswRZoAB4I6wVttFY82sAmWwWBbqaPxYX7mZe
B4udP8AA+0xtUQPADnFAA9kfXuqbPS8ziSlpcpPEWgKAihs4oWKsmsMR89Tkxs
s6pvjFxxUfZnAnHA83IdDBYBo6owJ/Qk/
oScb492mKkEHVGB7vh57nBwA9EQEuqbPS8zPCVq9PFNQB7A6iQT+aRscjWBT
rYL7YZlid9n6NsSTXUK9PwIJTBZZy9bnwekdpHQ69o1ioghOmPwjE9JE1+WZUA
xA8FsjZiTAsDggG2uQxKgPnVAD3cecradBbTvp4Fkg6iiPxOxMOagw6szLCxrSsH
9xjzhfa2tzh5485US3ERM/
rFBhzrla04OSxFUySyAE8j1Z+WPPVfx6iyHzNZwELurp4we5znFntWzBcsHE81T
UdcOZfMTUDbDVEA0AhNAkR4jFamjqc4MOJBsrLDNffDX6PSBkPOM3/
OIrw4LWbIWvMemPmbuD/IY846BPniPRwLiy6U1MOaDX3AjS/wDuP//Z";

let PROJECTS = [

{id:1,name:"Ayisha Substation Building Maintenance


Project",manager:"Taye Abu",phase:"Execution",start:"Jan 2025",end:"Dec
2025",budget:450000000,spent:280000000,progress:72,status:"On
Track",color:"#27ae60"},

{id:2,name:"Dawanle Freight Terminal Expansion


Project",manager:"Tewodros Alemayehu",phase:"Execution",start:"Mar
2025",end:"Jun
2026",budget:820000000,spent:310000000,progress:55,status:"At
Risk",color:"#f39c12"},

{id:3,name:"Indode Rail Link-1 / Indode Pavement Construction-


1",manager:"Wakuma Ensermu",phase:"Execution",start:"Feb
2025",end:"Nov
2025",budget:650000000,spent:480000000,progress:85,status:"On
Track",color:"#2980b9"},

{id:4,name:"Indode Bulk Cargo Construction Project",manager:"Dawit


Diriba",phase:"Planning",start:"May 2025",end:"Mar
2026",budget:380000000,spent:95000000,progress:38,status:"At
Risk",color:"#e74c3c"},

{id:5,name:"AMG Link Rail Project",manager:"Nigisti


Hailu",phase:"Execution",start:"Apr 2025",end:"Feb
2026",budget:550000000,spent:220000000,progress:58,status:"On
Track",color:"#8e44ad"},
{id:6,name:"AMG OC Project",manager:"Taye
Abu",phase:"Planning",start:"Jun 2025",end:"Dec
2025",budget:280000000,spent:85000000,progress:42,status:"On
Track",color:"#1e8449"},

{id:7,name:"AMG FY, Sebeta dedicated power line


construction",manager:"Tewodros Alemayehu",phase:"Execution",start:"Jul
2025",end:"May
2026",budget:320000000,spent:95000000,progress:35,status:"On
Track",color:"#0e6655"},

];

let RISKS = [

{id:"R-001",text:"Substation equipment delivery delay from


supplier",project:"Ayisha Substation Building Maintenance
Project",sev:"High",prob:"Likely",impact:"Major",status:"Open",owner:"Taye
Abu",due:"Jun 2025",mitigation:"Alternative supplier pre-qualified, weekly
tracking"},

{id:"R-002",text:"Weather disruption to terminal foundation


works",project:"Dawanle Freight Terminal Expansion
Project",sev:"Medium",prob:"Possible",impact:"Moderate",status:"Open",own
er:"Tewodros Alemayehu",due:"Jul 2025",mitigation:"Seasonal schedule
buffer incorporated"},

{id:"R-003",text:"Land acquisition dispute at Indode


corridor",project:"Indode Rail Link-1 / Indode Pavement Construction-
1",sev:"High",prob:"Likely",impact:"Major",status:"Open",owner:"Wakuma
Ensermu",due:"May 2025",mitigation:"Legal team engaged, MOT
coordination underway"},

{id:"R-004",text:"Bulk cargo crane specification mismatch",project:"Indode


Bulk Cargo Construction
Project",sev:"High",prob:"Possible",impact:"Major",status:"Mitigated",owner:"
Dawit Diriba",due:"Jun 2025",mitigation:"Revised specification approved and
ordered"},

{id:"R-005",text:"AMG link ballast material quality below


spec",project:"AMG Link Rail
Project",sev:"Medium",prob:"Unlikely",impact:"Moderate",status:"Open",own
er:"Nigisti Hailu",due:"Aug 2025",mitigation:"Independent QA inspection
regime implemented"},

{id:"R-006",text:"Currency fluctuation increasing import


costs",project:"Dawanle Freight Terminal Expansion
Project",sev:"High",prob:"Almost
Certain",impact:"Major",status:"Open",owner:"Tewodros
Alemayehu",due:"Ongoing",mitigation:"Forex hedging strategy approved by
finance"},

{id:"R-007",text:"Skilled labour shortage in remote Ayisha


site",project:"Ayisha Substation Building Maintenance
Project",sev:"Medium",prob:"Possible",impact:"Moderate",status:"Open",own
er:"Taye Abu",due:"Ongoing",mitigation:"Labour mobilisation plan with Addis
recruitment"},

{id:"R-008",text:"Environmental permit delay for Indode


works",project:"Indode Bulk Cargo Construction
Project",sev:"High",prob:"Possible",impact:"Major",status:"Open",owner:"Daw
it Diriba",due:"Jun 2025",mitigation:"Environmental study submitted,
expediting review"},

{id:"R-009",text:"AMG corridor track alignment survey errors",project:"AMG


Link Rail
Project",sev:"Low",prob:"Unlikely",impact:"Minor",status:"Open",owner:"Nigis
ti Hailu",due:"Jul 2025",mitigation:"Independent survey verification
commissioned"},

{id:"R-010",text:"Power supply instability at construction


sites",project:"Indode Rail Link-1 / Indode Pavement Construction-
1",sev:"Medium",prob:"Possible",impact:"Moderate",status:"Open",owner:"W
akuma Ensermu",due:"Ongoing",mitigation:"Generator backup plan in
place"},

];

let TASKS = [

];

let MEMBERS = [
{name:"Taye Abu",role:"Project Manager",projects:"Ayisha Substation /
Maintenance",util:85,tasks:18,status:"Active",email:"[Link]@[Link]"},

{name:"Tewodros Alemayehu",role:"Project Manager",projects:"Dawanle


Freight
Terminal",util:88,tasks:22,status:"Active",email:"[Link]@[Link]
"},

{name:"Wakuma Ensermu",role:"Project Manager",projects:"Indode Rail


Link-1 /
Pavement",util:92,tasks:25,status:"Overloaded",email:"[Link]@ed
[Link]"},

{name:"Dawit Diriba",role:"Project Manager",projects:"Indode Bulk


Cargo",util:78,tasks:15,status:"Active",email:"[Link]@[Link]"},

{name:"Nigisti Hailu",role:"Project Manager",projects:"AMG Link Rail


Project",util:80,tasks:19,status:"Active",email:"[Link]@[Link]"},

{name:"Site Engineer 1",role:"Civil Engineer",projects:"Indode Rail Link-


1",util:95,tasks:12,status:"Overloaded",email:"site.eng1@[Link]"},

{name:"Site Engineer 2",role:"Electrical Engineer",projects:"Ayisha


Substation",util:82,tasks:11,status:"Active",email:"site.eng2@[Link]"},

{name:"QA Inspector",role:"Quality Assurance",projects:"AMG Link


Rail",util:65,tasks:8,status:"Active",email:"qa@[Link]"},

];

// ── Simple deterministic hash (FNV-1a 32-bit) for password "encryption"


display ──

function hashPw(str) {

let h = 2166136261;

for (let i = 0; i < [Link]; i++) { h ^= [Link](i); h = (h *


16777619) >>> 0; }

return [Link](16).padStart(8,'0').toUpperCase();

}
let USERS = [

{id:"U001",name:"System
Administrator",username:"sysadmin",role:"Administrator",email:"admin@edr.
et",access:"Admin",assignedProjects:["All
Projects"],status:"Active",dateCreated:"2025-01-01",lastLogin:"2026-06-03
08:15",pw:"edrengpmo@admin"},

{id:"U002",name:"Taye Abu",username:"[Link]",role:"Project
Manager",email:"[Link]@[Link]",access:"Editor",assignedProjects:["Ayisha
Substation Maintenance"],status:"Active",dateCreated:"2025-03-
10",lastLogin:"2026-06-03 07:45",pw:"pm2026"},

{id:"U003",name:"Tewodros
Alemayehu",username:"[Link]",role:"Project
Manager",email:"[Link]@[Link]",access:"Editor",assignedProje
cts:["Indode Link-1 Pavement Constr."],status:"Active",dateCreated:"2025-
03-10",lastLogin:"2026-06-02 08:12",pw:"pm2026"},

{id:"U004",name:"Wakuma Ensermu",username:"[Link]",role:"Project
Manager",email:"[Link]@[Link]",access:"Editor",assignedProjects:
["Dawanle Freight Terminal"],status:"Active",dateCreated:"2025-03-
12",lastLogin:"2026-06-03 09:00",pw:"pm2026"},

{id:"U005",name:"Dawit Diriba",username:"[Link]",role:"Project
Manager",email:"[Link]@[Link]",access:"Editor",assignedProjects:
["AMG OC Construction","AMG FY
Construction"],status:"Active",dateCreated:"2025-03-12",lastLogin:"2026-06-
01 14:30",pw:"pm2026"},

{id:"U006",name:"Nigisti Hailu",username:"[Link]",role:"Project
Manager",email:"[Link]@[Link]",access:"Editor",assignedProjects:["AMG
Link Rail Project"],status:"Active",dateCreated:"2025-04-01",lastLogin:"2026-
06-02 10:15",pw:"pm2026"},

{id:"U007",name:"Viewer
Account",username:"viewer",role:"Viewer",email:"stakeholder@[Link]",acces
s:"Viewer",assignedProjects:[],status:"Active",dateCreated:"2025-06-
15",lastLogin:"2026-05-28 11:00",pw:"view2026"},

];

let REPORT_HISTORY = [
{name:"Weekly Status Report — W19 2026",type:"Status",date:"May 12,
2026",by:"System Administrator",to:"All Project Managers",fmt:"PDF"},

{name:"Q1 Cost Analysis 2026",type:"Cost",date:"Apr 1, 2026",by:"System


Administrator",to:"Executive Leadership",fmt:"PDF"},

{name:"Risk Register Summary — Apr 2026",type:"Risk",date:"Apr 28,


2026",by:"System Administrator",to:"All Project Managers",fmt:"PDF"},

{name:"Resource Utilization — Q1 2026",type:"Resource",date:"Apr 30,


2026",by:"System Administrator",to:"Executive Leadership",fmt:"Excel"},

{name:"Executive Summary — Q1 2026",type:"Executive",date:"Apr 1,


2026",by:"System Administrator",to:"Executive Leadership",fmt:"PDF"},

];

let currentUser = null; // currently logged-in user object

let isAdmin = false; // true → Admin (PMO) full-access

let editMode = false; // true → inline editing active (Admin only)

let nextId = 200;

//
═══════════════════════════════════════════════════════
════════
// SYSTEM-WIDE AUDIT / ACTIVITY LOG

// Records: login/logout, data add/edit/delete, reports, settings

//
═══════════════════════════════════════════════════════
════════
let AUDIT_LOG = [

{ts:"2026-06-03 08:15",user:"System
Administrator",action:"Login",module:"Authentication",detail:"Admin login
successful"},
{ts:"2026-06-03 08:20",user:"System
Administrator",action:"Edit",module:"Projects",detail:"Updated progress for
Ayisha Substation Maintenance Project"},

{ts:"2026-06-03 09:00",user:"System Administrator",action:"Report


Generated",module:"Reports",detail:"Weekly Status Report — W22 2026
generated"},

{ts:"2026-06-02 14:30",user:"Project Manager


(Guest)",action:"Login",module:"Authentication",detail:"Guest login
successful"},

{ts:"2026-06-02 14:55",user:"Project Manager


(Guest)",action:"Logout",module:"Authentication",detail:"Session ended"},

{ts:"2026-06-01 10:10",user:"System
Administrator",action:"Add",module:"Risks",detail:"Added Risk R-010: Power
supply instability"},

{ts:"2026-06-01 11:45",user:"System Administrator",action:"Settings


Modified",module:"Settings",detail:"PMO Director and Chief of Engineering
updated"},

];

function logAudit(action, module, detail) {

if(!currentUser) return;

const now = new Date();

const pad = n => String(n).padStart(2,'0');

const ts = `${[Link]()}-${pad([Link]()+1)}-$
{pad([Link]())} ${pad([Link]())}:${pad([Link]())}`;

AUDIT_LOG.unshift({ts, user: [Link] || [Link],


action, module, detail});

// Keep last 500 entries

if(AUDIT_LOG.length > 500) AUDIT_LOG.length = 500;

// If audit page is open, refresh it

if([Link]("audit-log-tbody")) renderAuditLog();
}

//
═══════════════════════════════════════════════════════
════════
// ROLE-BASED AUTHENTICATION

// Two roles only — selected via card UI, authenticated by password.

// Admin (PMO) → password: edrengpmo@admin

// Guest (Project Mgrs) → password: edrengpm@guest

//
═══════════════════════════════════════════════════════
════════

const CREDENTIALS = {

"chief_admin": {

pw: "edrengchief@admin",

role: "chief_admin",

name: "Chief Admin",

icon: "👑"

},

"admin": {

pw: "edrengpmo@admin",

role: "admin",

name: "Project Management Office (PMO)",

icon: ""

},

"guest": {

pw: "edrengpm@guest",
role: "guest",

name: "Project Manager (Guest)",

icon: ""

};

// Role hierarchy: chief_admin > admin > guest

const ROLE_HIERARCHY = { "chief_admin": 3, "admin": 2, "guest": 1 };

function isChiefAdmin() { return currentUser && [Link] ===


"chief_admin"; }

// Track which role card the user has selected in the UI

let selectedRole = null;

/* ── selectRole ──────────────────────────────────────────────

Called when a role card is clicked.

Highlights the chosen card, shows the password field,

and enables the Sign-In button.

─────────────────────────────────────────────────────────── */

window._selectRoleImpl = function selectRole(role) {

selectedRole = role;

// Highlight the selected card; de-highlight the others

["chief_admin","admin","guest"].forEach(r => {

const card = [Link]("card-" + r);

if(card) [Link]("selected", r === role);

});
// Show the password section with the correct role label

const pwSection = [Link]("pw-section");

const pwBadge = [Link]("pw-role-badge");

const cred = CREDENTIALS[role];

if(pwSection) [Link]("visible");

if(pwBadge && cred) {

const labels = { "chief_admin": "Chief Admin", "admin": "Admin (PMO)",


"guest": "Guest (Project Manager)" };

[Link] = [Link] + " " + (labels[role] || role);

// Clear any previous password & error; focus the field

const pwInput = [Link]("login-pass");

if(pwInput) { [Link] = ""; [Link](); }

const errEl = [Link]("login-err");

if(errEl) [Link] = "none";

// Enable the sign-in button

const btn = [Link]("login-btn");

if(btn) [Link] = false;

/* ── togglePwVisibility ──────────────────────────────────────

Toggles the password field between plain text and masked.

─────────────────────────────────────────────────────────── */

window._togglePwImpl = function togglePwVisibility() {


const input = [Link]("login-pass");

const toggle = [Link]("pw-toggle-btn");

if(!input) return;

const show = [Link] === "password";

[Link] = show ? "text" : "password";

if(toggle) [Link] = show ? "🙈" : "👁";

/* ── doLogin ─────────────────────────────────────────────────

Validates the password for the selected role and either

grants access or shows an error.

─────────────────────────────────────────────────────────── */

window._doLoginImpl = function doLogin() {

if(!selectedRole) return; // shouldn't happen (button disabled)

const pw = ([Link]("login-pass").value || "").trim();

const cred = CREDENTIALS[selectedRole];

if(!cred || [Link] !== pw) {

// Wrong password — show error, clear field

const errEl = [Link]("login-err");

if(errEl) [Link] = "block";

const pwInput = [Link]("login-pass");

if(pwInput) { [Link] = ""; [Link](); }

return;

}
// ── Credentials OK ──────────────────────────────────────

currentUser = { username: selectedRole, ...cred };

isAdmin = selectedRole === "admin" || selectedRole ===


"chief_admin";

editMode = isAdmin; // only Admins and Chief Admin start in edit mode

// Hide login overlay; reveal main UI

[Link]("login-overlay").[Link]("open");

[Link]("main-hdr").[Link] = "";

[Link]("main-nav").[Link] = "";

[Link]("pages-wrap").[Link] = "";

// Show role status bar with appropriate styling

const adminBar = [Link]("admin-bar");

if(adminBar) [Link]("open");

// Update status bar content

const roleBadge = [Link]("role-badge-label");

const userLabel = [Link]("admin-user-label");

const accessLbl = [Link]("access-level-label");

const editBtn = [Link]("edit-toggle-btn");

if(selectedRole === "chief_admin") {

// Chief Admin: supreme authority (gold indicator)

if(roleBadge) { [Link] = "👑 CHIEF ADMIN";


[Link] = "#b8860b"; }

if(userLabel) [Link] = [Link] + " — Highest


Authority";
if(accessLbl) { [Link] = "Full system control · All
permissions · Override capability"; [Link] = "#ffd700"; }

if(editBtn) { [Link] = ""; [Link] = "✏ Edit


Mode: ON"; [Link] = "#27ae60"; }

// Show action columns in tables

["ov-action-th","port-action-th","res-action-th","risk-action-th"].forEach(id
=> {

const el = [Link](id);

if(el) [Link] = "";

});

// Update header badge

const hdrBadge = [Link]("admin-badge");

if(hdrBadge) { [Link] = "👑 Chief Admin";


[Link] = "#b8860b"; }

} else if(isAdmin) {

// Admin: full access bar (dark red indicator)

if(roleBadge) { [Link] = " ADMIN MODE";


[Link] = "#e74c3c"; }

if(userLabel) [Link] = [Link];

if(accessLbl) { [Link] = "Full edit access enabled";


[Link] = "#f39c12"; }

if(editBtn) { [Link] = ""; [Link] = "✏ Edit


Mode: ON"; [Link] = "#27ae60"; }

// Show action columns in tables

["ov-action-th","port-action-th","res-action-th","risk-action-th"].forEach(id
=> {

const el = [Link](id);

if(el) [Link] = "";

});
// Update header badge

const hdrBadge = [Link]("admin-badge");

if(hdrBadge) [Link] = " PMO Admin";

} else {

// Guest: read-only bar (green indicator)

if(roleBadge) { [Link] = " GUEST MODE";


[Link] = "#1e8449"; }

if(userLabel) [Link] = [Link];

if(accessLbl) { [Link] = "View-only access — editing


disabled"; [Link] = "#a8d5b5"; }

if(editBtn) [Link] = "none"; // hide edit toggle for guests

// Keep action columns hidden

["ov-action-th","port-action-th","res-action-th","risk-action-th"].forEach(id
=> {

const el = [Link](id);

if(el) [Link] = "none";

});

// Update header badge

const hdrBadge = [Link]("admin-badge");

if(hdrBadge) { [Link] = " Guest";


[Link] = "#1e8449"; }

// Hide user-management tab in nav

applyGuestNavRestrictions();

renderAll();

logAudit("Login", "Authentication", (selectedRole === "chief_admin" ?


"Chief Admin" : isAdmin ? "Admin" : "Guest") + " login successful");
toast("✅ Welcome, " + [Link] + "!" +

(selectedRole === "chief_admin" ? " Supreme administrative access


granted." : isAdmin ? " Full administrative access granted." : " Read-only
access granted."));

/* ── applyGuestNavRestrictions ────────────────────────────────

Hides the Settings tab (user management) from Guest users.

─────────────────────────────────────────────────────────── */

function applyGuestNavRestrictions() {

// Hide the Settings and Audit Log nav tabs from Guest users

const navTabs = [Link](".nav-tab");

[Link](tab => {

const txt = [Link]();

if([Link]("Settings") || [Link]("Audit Log")) [Link] =


"none";

});

// Hide add-project buttons everywhere

[Link]('.add-btn,
button[onclick*="openModal"]').forEach(btn => {

[Link] = "none";

});

/* Enter key triggers login */

[Link]("keydown", function(e) {

if([Link] === "Enter") {

const overlay = [Link]("login-overlay");


if(overlay && [Link]("open")) doLogin();

});

/* ── doLogout ─────────────────────────────────────────────────

Resets all auth state and returns to the login screen.

─────────────────────────────────────────────────────────── */

function doLogout() {

if(currentUser) logAudit("Logout", "Authentication", "User session ended");

currentUser = null;

isAdmin = false;

editMode = false;

selectedRole = null;

// Hide main UI; show login overlay

[Link]("main-hdr").[Link] = "none";

[Link]("main-nav").[Link] = "none";

[Link]("pages-wrap").[Link] = "none";

[Link]("admin-bar").[Link]("open");

[Link]("login-overlay").[Link]("open");

[Link]("login-err").[Link] = "none";

// Reset role card selection and hide password section

["chief_admin","admin","guest"].forEach(r => {

const card = [Link]("card-" + r);

if(card) [Link]("selected");

});
const pwSection = [Link]("pw-section");

if(pwSection) [Link]("visible");

const loginBtn = [Link]("login-btn");

if(loginBtn) [Link] = true;

const pwInput = [Link]("login-pass");

if(pwInput) { [Link] = ""; [Link] = "password"; }

const pwToggle = [Link]("pw-toggle-btn");

if(pwToggle) [Link] = "👁";

// Restore nav tabs in case they were hidden for guest

[Link](".nav-tab").forEach(t => { [Link] =


""; });

// Restore header badge

const hdrBadge = [Link]("admin-badge");

if(hdrBadge) { [Link] = "🔐 Login";


[Link] = ""; }

setEditMode(false);

/* ── openLoginOverlay ─────────────────────────────────────────

Opens the login overlay (e.g. when clicking the header badge

while already logged in as Admin to re-authenticate).

─────────────────────────────────────────────────────────── */

function openLoginOverlay() {

[Link]("login-overlay").[Link]("open");
}

/* ── toggleEditMode ──────────────────────────────────────────

Admin-only: toggle inline editing on/off.

─────────────────────────────────────────────────────────── */

function toggleEditMode() {

if(!isAdmin) return; // guests cannot toggle edit mode

editMode = !editMode;

setEditMode(editMode);

/* ── setEditMode ─────────────────────────────────────────────

Applies or removes inline-editing capabilities across the UI.

For Admin role only.

─────────────────────────────────────────────────────────── */

function setEditMode(on) {

editMode = isAdmin ? on : false; // guests always stay in view-only mode

const btn = [Link]("edit-toggle-btn");

if(btn) {

[Link] = "✏ Edit Mode: " + (editMode ? "ON" : "OFF");

[Link] = editMode ? "#27ae60" : "#e74c3c";

// Show/hide action columns in tables

["ov-action-th","port-action-th","res-action-th","risk-action-th"].forEach(id
=> {

const el = [Link](id);

if(el) [Link] = editMode ? "" : "none";


});

renderAll();

//
═══════════════════════════════════════════════════════
════════
// NAV

//
═══════════════════════════════════════════════════════
════════
function showPage(tab, id) {

[Link](".nav-
tab").forEach(t=>[Link]("active"));

[Link](".page").forEach(p=>[Link]("active")
);

[Link]("active");

[Link]("page-"+id).[Link]("active");

if (id === "cost") renderCost();

if (id === "reports") { renderReportHistory(); initRptModule(); }

if (id === "auditlog") renderAuditLog();

if (id === "schedule") { populatePCActivityFilter(); renderPCMilestones();


renderPCActivityByProject(); }

//
═══════════════════════════════════════════════════════
════════
// RENDER ALL
//
═══════════════════════════════════════════════════════
════════
function renderAll() {

renderOverview();

renderPortfolio();

renderSchedule();

populatePCActivityFilter();

renderPCMilestones();

renderPCActivityByProject();

renderCost();

renderResources();

renderRisks();

renderSettings();

renderReportHistory();

initRptModule();

//
═══════════════════════════════════════════════════════
════════
// OVERVIEW

//
═══════════════════════════════════════════════════════
════════
function renderOverview() {

// KPIs

[Link]("kpi-projects").textContent = [Link];

const totalBudget = [Link]((s,p)=>s+[Link],0);


const totalSpent = [Link]((s,p)=>s+[Link],0);

const utilPct = [Link](totalSpent/totalBudget*100);

const avgProgress =
[Link]([Link]((s,p)=>s+[Link],0)/[Link](PROJECTS.l
ength,1));

if([Link]("kpi-total-budget"))
[Link]("kpi-total-budget").textContent =
(totalBudget/1e9).toFixed(2)+"B";

if([Link]("kpi-budget-util"))
[Link]("kpi-budget-util").textContent = utilPct+"%";

if([Link]("kpi-portfolio-progress"))
[Link]("kpi-portfolio-progress").textContent =
avgProgress+"%";

if([Link]("kpi-safety")) [Link]("kpi-
safety").textContent = [Link]("kpi-safety").textContent ||
"2";

if([Link]("kpi-pending"))
[Link]("kpi-pending").textContent =
[Link]("kpi-pending").textContent || "5";

// Project table

const tbody = [Link]("ov-tbody");

if(!tbody) return;

[Link] = [Link]((p,i)=>`<tr>

<td>${i+1}</td>

<td><span style="color:${[Link]};font-weight:800">●</span> <span


class="${editMode?"editable":""}" ${editMode?'contenteditable="true"
onblur="PROJECTS['+i+'].name=[Link]"':''}>${[Link]}</span><
/td>

<td><span class="${editMode?"editable":""}" $
{editMode?'contenteditable="true"
onblur="PROJECTS['+i+'].manager=[Link]"':''}>${[Link]}</
span></td>

<td><span class="bdg ${[Link]==="Closing / Testing &


Commissioning"?"g":[Link]==="Execution"?"b":[Link]==="Monitoring &
Controlling"?"p":"gr"}">${[Link]}</span></td>

<td style="color:#555;font-size:9px">${[Link]}</td>

<td style="color:#555;font-size:9px">${[Link]}</td>

<td style="font-size:9px">ETB ${([Link]/1e6).toFixed(0)}M</td>

<td style="font-size:9px">ETB ${([Link]/1e6).toFixed(0)}M</td>

<td><div style="display:flex;align-items:center;gap:5px"><div
class="pbar" style="flex:1;min-width:50px"><div class="pbar-f"
style="width:${[Link]}%;background:${[Link]}"></div></div><span
style="font-size:9px;font-weight:700">${[Link]}%</span></div></td>

<td><span class="bdg ${[Link]==="On


Track"?"g":[Link]==="Completed"?"b":"o"}">${[Link]}</span></td>

${editMode?`<td><button class="edit-btn" onclick="openModal('edit-


project',${[Link]})">✏</button> <button class="edit-btn red"
onclick="deleteProject(${[Link]})">✕</button></td>`:""}

</tr>`).join("");

// ── C. Project Status Summary — Activity & Milestone Driven ──

const tb = [Link]("ov-task-breakdown");

if(tb) {

// Aggregate activity counts across all projects from SCHEDULE_ACTIVITIES

const allActs = [Link](window.SCHEDULE_ACTIVITIES || {}).flat();

const allMilestones = [Link](window.MILESTONE_DATA_BY_PROJECT


|| {}).flat();

// Activity counts
const actCompleted = [Link](a => [Link] ===
"completed").length;

const actInProgress = [Link](a => [Link] === "in-


progress").length;

const actDelayed = [Link](a => [Link] === "delayed" ||


[Link] === "critical").length;

const actUpcoming = [Link](a => [Link] ===


"upcoming").length;

const actTotal = [Link];

// Milestone counts

const msCompleted = [Link](m => m.s ===


"completed").length;

const msInProgress = [Link](m => m.s === "in-


progress").length;

const msDelayed = [Link](m => m.s === "in-progress" &&


[Link] < 20 && [Link] < [Link] * 0.85).length;

const msUpcoming = [Link](m => m.s ===


"planned").length;

// Auto-generate project status from activity performance

const projStatusRows = [Link](p => {

// Map project name to schedule key (approximate match)

const schedKey = [Link](window.SCHEDULE_ACTIVITIES || {}).find(k


=>

[Link]().includes([Link]().split(" ")[0]) ||

[Link]().includes([Link]().split(" ")[0])

) || "";

const pActs = (window.SCHEDULE_ACTIVITIES || {})[schedKey] || [];


const pMS = (window.MILESTONE_DATA_BY_PROJECT || {})[schedKey] ||
[];

const comp = [Link](a=>[Link]==="completed").length;

const inprog = [Link](a=>[Link]==="in-progress").length;

const delayed = [Link](a=>[Link]==="delayed"||


[Link]==="critical").length;

const upcoming = [Link](a=>[Link]==="upcoming").length;

// Auto-status: if any critical/delayed activities → Delayed, if ms behind →


At Risk, else On Track

const autoStatus = delayed > 0 &&


[Link](a=>[Link]==="critical").length > 0 ? "Delayed"

: delayed > 0 ? "At Risk"

: [Link];

const statusColor = autoStatus === "On Track" ? "#27ae60" :


autoStatus === "At Risk" ? "#f39c12" : "#e74c3c";

const short = [Link] > 30 ? [Link](0,28)+"…" :


[Link];

return `<div style="padding:5px 0;border-bottom:1px solid #e8f0e8">

<div style="display:flex;justify-content:space-between;align-
items:center;margin-bottom:3px">

<span style="font-size:9px;font-weight:800;color:#0a3d1f" title="$


{[Link]}">${short}</span>

<span style="padding:1px 7px;border-radius:8px;font-size:8px;font-


weight:800;background:${statusColor}20;color:${statusColor};border:1px
solid ${statusColor}40">${autoStatus}</span>

</div>

<div style="display:flex;gap:8px;font-size:8px;flex-wrap:wrap">

<span style="color:#27ae60;font-weight:700">✓ ${comp}


Completed</span>

<span style="color:#2980b9;font-weight:700">▶ ${inprog}


Ongoing</span>
<span style="color:#e74c3c;font-weight:700">⚠ ${delayed}
Delayed</span>

<span style="color:#bdc3c7;font-weight:700">◷ ${upcoming}


Upcoming</span>

</div>

</div>`;

}).join("");

[Link] = `

<div style="background:#f0f8f4;border:1px solid #c8d8c8;border-


radius:4px;padding:7px 10px;margin-bottom:8px">

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:5px;letter-spacing:.4px">PORTFOLIO — ACTIVITY SUMMARY</div>

<div style="display:grid;grid-template-columns:1fr 1fr;gap:5px">

<div style="background:#d4efdf;border-radius:3px;padding:5px
8px;text-align:center"><div style="font-size:16px;font-
weight:800;color:#1e8449">${actCompleted}</div><div style="font-
size:8px;color:#555;font-weight:700">Completed</div></div>

<div style="background:#d6eaf8;border-radius:3px;padding:5px
8px;text-align:center"><div style="font-size:16px;font-
weight:800;color:#1a5276">${actInProgress}</div><div style="font-
size:8px;color:#555;font-weight:700">Ongoing</div></div>

<div style="background:#fadbd8;border-radius:3px;padding:5px
8px;text-align:center"><div style="font-size:16px;font-
weight:800;color:#c0392b">${actDelayed}</div><div style="font-
size:8px;color:#555;font-weight:700">Delayed</div></div>

<div style="background:#eaecee;border-radius:3px;padding:5px
8px;text-align:center"><div style="font-size:16px;font-
weight:800;color:#555">${actUpcoming}</div><div style="font-
size:8px;color:#555;font-weight:700">Upcoming</div></div>

</div>
<div style="margin-top:5px;font-size:8px;color:#888;border-top:1px
solid #c8d8c8;padding-top:4px">

Milestones: <b style="color:#27ae60">${msCompleted} Done</b> ·


<b style="color:#2980b9">${msInProgress} Active</b> · <b
style="color:#bdc3c7">${msUpcoming} Planned</b>

&nbsp;·&nbsp; Total Activities: <b style="color:#0a3d1f">$


{actTotal}</b>

</div>

</div>

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:4px;letter-spacing:.3px">BY PROJECT</div>

${projStatusRows}`;

// Milestones and Activity Log are now in Project Control module

// renderMilestonesOv() — kept for backward compat, no-op for hidden div

// renderActivityOv() — kept for backward compat, no-op for hidden div

// ── editable milestones data ──────────────────────────────────

let OV_MILESTONES = [

{m:"Ayisha Substation Commissioning",d:"Aug 2025",s:"upcoming"},

{m:"Indode Rail Link-1 Track Complete",d:"Sep 2025",s:"upcoming"},

{m:"Dawanle Terminal Shell Complete",d:"Nov 2025",s:"future"},

{m:"AMG Ballast & Track Laying",d:"Dec 2025",s:"future"},

{m:"Indode Bulk Cargo Crane Install",d:"Feb 2026",s:"future"},

{m:"All Projects Final Handover",d:"Mar 2026",s:"future"},

];
// ── Active status filter for critical milestones ──────────────

window._msFilter = "critical"; // "critical" | "all"

function renderMilestonesOv() {

const ml = [Link]("ov-milestones");

if (!ml) return;

const showAll = [Link]("ms-show-all") ?


[Link]("ms-show-all").checked : false;

const today = new Date();

// Month parsing helper

const MONTH_MAP =
{Jan:0,Feb:1,Mar:2,Apr:3,May:4,Jun:5,Jul:6,Aug:7,Sep:8,Oct:9,Nov:10,Dec:11}
;

function parseMonthYear(str) {

if (!str) return null;

const p = [Link]().split(" ");

if ([Link] === 2 && MONTH_MAP[p[0]] !== undefined) {

return new Date(parseInt(p[1]), MONTH_MAP[p[0]], 15);

return null;

function calcDays(dateStr) {

const d = parseMonthYear(dateStr);

return d ? [Link]((d - today) / 86400000) : null;

}
// ── Build flat list of milestones linked to projects & activities ──

let rows = [];

[Link](window.MILESTONE_DATA_BY_PROJECT ||
{}).forEach(([schedKey, msList]) => {

// Resolve to full PROJECTS entry

const proj = [Link](p =>

[Link]().includes([Link]().split(" ")[0]) ||

[Link]().includes([Link]().split(" ")[0])

);

const projName = proj ? [Link] : schedKey;

const projColor = proj ? [Link] : "#0a3d1f";

const projectManager = proj ? [Link] : "—";

const manager = projectManager;

const projStatus= proj ? [Link] : "—";

[Link](ms => {

if (ms.s === "completed") return; // skip completed

if (!showAll && ![Link]) return; // show only critical unless toggled

const baselineDays = calcDays([Link]);

const forecastDays = calcDays([Link] || [Link]);

// Derive forecast date: if behind schedule, shift forecast

const forecastDate = [Link] || [Link];

const isDelayed = (forecastDays !== null && baselineDays !== null &&
forecastDays > baselineDays);

const variance = (forecastDays !== null && baselineDays !== null) ?


forecastDays - baselineDays : 0;
// Resolve linked major activity name (first activity ID in list)

const actIds = [Link] || [];

const schedActs = (window.SCHEDULE_ACTIVITIES || {})[schedKey] || [];

const linkedAct = [Link](a => [Link]([Link]));

const majorActivity = [Link] || (linkedAct ? [Link] :


actIds[0] || "—");

[Link]({

projName, projColor, manager, projStatus, schedKey,

msName: ms.m,

majorActivity,

baselineDate: [Link],

forecastDate,

baselineDays,

forecastDays,

isDelayed,

variance,

status: ms.s,

actPct: [Link] || 0,

planPct: [Link] || 0,

critical: [Link],

sortKey: forecastDays !== null ? forecastDays : 9999

});

});

});
// Sort by nearest forecast due date

[Link]((a, b) => [Link] - [Link]);

// Summary badge

const critCount = [Link](r => [Link]).length;

const overdue = [Link](r => [Link] !== null &&


[Link] < 0).length;

const due30 = [Link](r => [Link] !== null &&


[Link] >= 0 && [Link] <= 30).length;

const delayed = [Link](r => [Link] && [Link] >=


0).length;

const badge = [Link]("ms-summary-badge");

if (badge) [Link] = `${[Link]} milestone${[Link] !


== 1 ? "s" : ""} · ${overdue} overdue · ${due30} due ≤30d · ${delayed}
delayed`;

if (![Link]) {

[Link] = `<div class="cms-empty">No ${showAll ? "upcoming" :


"critical upcoming"} milestones found.</div>`;

return;

// ── Build table ──────────────────────────────────────────────

const tableRows = [Link]((r, i) => {

const fd = [Link];

const isOverdue = fd !== null && fd < 0;

const isDue30 = fd !== null && fd >= 0 && fd <= 30;

// Row class
const rowClass = isOverdue ? "cms-row-overdue"

: isDue30 ? "cms-row-due30"

: [Link] ? "cms-row-critical"

: "";

// Days remaining badge

const daysBadgeClass = isOverdue ? "cms-days-overdue" : isDue30 ?


"cms-days-due30" : "cms-days-normal";

const daysLabel = isOverdue

? `▲ ${[Link](fd)}d overdue`

: fd === 0 ? "Due today"

: fd !== null ? `${fd}d`

: "—";

// Status badge

const statusCfg = {

"in-progress": { bg: "#d6eaf8", color: "#1a5276", label: "▶ In


Progress" },

"planned": { bg: "#eaecee", color: "#555", label: "◷ Planned" },

"delayed": { bg: "#fadbd8", color: "#c0392b", label: "⚠ Delayed" }

};

const sCfg = statusCfg[[Link]] || statusCfg["planned"];

// Forecast date styling

const forecastClass = [Link] ? "cms-date-delayed" : "cms-date-


normal";

const varianceHtml = [Link]


? `<div class="cms-variance" style="color:#e74c3c">+${[Link]}d
slip</div>`

: [Link] < 0

? `<div class="cms-variance" style="color:#27ae60">${[Link]}d


early</div>`

: "";

// Project colour chip

const chipBg = [Link] + "22";

// Critical flag

const critFlag = [Link] ? `<span style="color:#e74c3c;font-


size:9px;margin-right:3px" title="Critical milestone">🚩</span>` : "";

return `<tr class="${rowClass}">

<td style="min-width:160px">

<div style="display:inline-block;max-width:155px;overflow:hidden;text-
overflow:ellipsis;white-space:nowrap;

padding:2px 7px;border-radius:3px;font-size:8px;font-
weight:800;background:${chipBg};

color:${[Link]};border-left:3px solid ${[Link]}" title="$


{[Link]}">${[Link]}</div>

</td>

<td style="min-width:150px">

<div style="font-size:9px;color:#1a6b3a;font-weight:700;line-
height:1.3">${[Link]}</div>

</td>

<td style="min-width:170px">

${critFlag}<span class="cms-ms-name">${[Link]}</span>
</td>

<td class="cms-date-col">

<div class="cms-date-normal">${[Link]}</div>

</td>

<td class="cms-date-col">

<div class="${forecastClass}">${[Link]}</div>

${varianceHtml}

</td>

<td style="min-width:80px">

<span class="cms-days-badge
${daysBadgeClass}">${daysLabel}</span>

</td>

<td>

<span class="cms-status-badge" style="background:${[Link]};color:


${[Link]}">${[Link]}</span>

</td>

</tr>`;

}).join("");

[Link] = `

<div class="cms-filter-bar">

<span style="font-size:8.5px;font-weight:800;color:#0a3d1f;letter-
spacing:.3px">FILTER:</span>

<span style="display:flex;align-items:center;gap:4px;font-
size:8px;color:#555;margin-left:4px">

<span style="width:10px;height:10px;background:#fdf0ef;border:1px
solid #e74c3c;border-radius:2px;display:inline-block"></span>Overdue
<span style="width:10px;height:10px;background:#fffbf0;border:1px
solid #f39c12;border-radius:2px;display:inline-block;margin-left:6px"></
span>Due ≤30d

<span style="width:10px;height:10px;background:#fff8f6;border:1px
solid #e8a090;border-radius:2px;display:inline-block;margin-left:6px"></
span>Delayed

</span>

<span style="margin-left:auto;font-size:8px;color:#888;font-
style:italic">Sorted by nearest forecast date · 🚩 = Critical path
milestone</span>

</div>

<table class="cms-table">

<thead>

<tr>

<th>Project</th>

<th>Major Activity</th>

<th>Critical Milestone</th>

<th>Baseline Date</th>

<th>Forecast Date</th>

<th>Days Remaining</th>

<th>Status</th>

</tr>

</thead>

<tbody>${tableRows}</tbody>

</table>`;

function renderActivityOv() {

const ac = [Link]("ov-activity");
if(!ac) return;

// Build activity log entries from SCHEDULE_ACTIVITIES (completed and in-


progress)

const entries = [];

[Link](window.SCHEDULE_ACTIVITIES || {}).forEach(([projKey, acts])


=> {

const proj = [Link](p =>

[Link]().includes([Link]().split(" ")[0]) ||

[Link]().includes([Link]().split(" ")[0])

);

const projName = proj ? [Link] : projKey;

[Link](act => {

if([Link] === "completed" || [Link] === "in-progress") {

const typeIcon = [Link] === "completed" ? "✅" : "▶";

const typeLabel = [Link] === "completed" ? "Completed" : "In


Progress";

const typeColor = [Link] === "completed" ? "#27ae60" :


"#2980b9";

// Use finish date as timestamp reference

[Link]({

date: [Link] || [Link],

projName,

actName: [Link],

owner: [Link] || "—",

status: typeLabel,
statusColor: typeColor,

icon: typeIcon,

physPct: [Link],

variance: [Link] || 0,

sortDate: [Link] || [Link]

});

});

// Add completed milestones

const msList = (window.MILESTONE_DATA_BY_PROJECT || {})[projKey] || [];

[Link](ms => {

if(ms.s === "completed") {

[Link]({

date: [Link],

projName,

actName: "🏁 Milestone: " + ms.m,

owner: proj ? [Link] : "—",

status: "Milestone Achieved",

statusColor: "#8e44ad",

icon: "🏁",

physPct: 100,

variance: 0,

sortDate: [Link],

isMilestone: true

});

}
});

});

// Sort most recent first (by date string desc)

[Link]((a, b) => ([Link] || "").localeCompare([Link] || ""));

// Show top 15

const shown = [Link](0, 15);

if(![Link]) {

[Link] = '<div style="text-


align:center;color:#bbb;padding:20px;font-size:10px">No recent activity
data</div>';

return;

[Link] = `

<table class="tbl" style="font-size:9px">

<thead>

<tr>

<th>Date</th>

<th>Project</th>

<th>Activity / Milestone</th>

<th>Responsible</th>

<th>Progress</th>

<th>Status</th>

</tr>
</thead>

<tbody>

${[Link](e => {

const varColor = [Link] < 0 ? "#e74c3c" : [Link] > 0 ?


"#27ae60" : "#555";

const varLabel = [Link] < 0 ? `<span style="color:#e74c3c;font-


size:8px">${[Link]}d delay</span>` : [Link] > 0 ? `<span
style="color:#27ae60;font-size:8px">+${[Link]}d ahead</span>` : "";

return `<tr>

<td style="white-space:nowrap;color:#555;font-size:9px">${[Link]
|| "—"}</td>

<td style="max-width:140px;overflow:hidden;text-
overflow:ellipsis;white-space:nowrap;font-size:9px" title="${[Link]}">$
{[Link]>22?[Link](0,20)+"…":[Link]}</td>

<td style="max-width:200px;font-size:9px">${[Link]}</td>

<td style="font-size:9px;color:#1a5276">${[Link]}</td>

<td style="font-size:9px">${[Link]}% ${varLabel}</td>

<td><span style="padding:2px 7px;border-radius:8px;font-


size:8px;font-weight:800;background:${[Link]}20;color:$
{[Link]};border:1px solid ${[Link]}40">${[Link]} $
{[Link]}</span></td>

</tr>`;

}).join("")}

</tbody>

</table>`;

function addActivityOv() {

// Legacy compat stub

toast("ℹ Activity log is now driven from project activity data.");

}
//
═══════════════════════════════════════════════════════
════════
// PORTFOLIO

//
═══════════════════════════════════════════════════════
════════
//
═══════════════════════════════════════════════════════
════════
// PROJECT CONTROL — CRITICAL MILESTONES BY PROJECT

//
═══════════════════════════════════════════════════════
════════
// Milestone filter state: null / "overdue" / "duesoon" / "delayed"

window._msStatusFilter = null;

function setMilestoneFilter(filter) {

window._msStatusFilter = (filter === "all") ? null : filter;

// Update button styles

["all","overdue","duesoon","delayed"].forEach(f => {

const btn = [Link]("ms-filter-" + f);

if (!btn) return;

const isActive = (f === "all" && !window._msStatusFilter) || f ===


window._msStatusFilter;

[Link] = isActive ? "rgba(255,255,255,.25)" : "transparent";

[Link] = isActive ? "#fff" : "rgba(255,255,255,.75)";

[Link] = isActive ? "1px solid rgba(255,255,255,.5)" : "1px


solid rgba(255,255,255,.3)";
});

renderPCMilestones();

function renderPCMilestones() {

const wrap = [Link]("pc-milestones-wrap");

if (!wrap) return;

const showAll = [Link]("pc-ms-show-all") ?


[Link]("pc-ms-show-all").checked : false;

const statusFilter = window._msStatusFilter || null;

const today = new Date();

const MONTH_MAP =
{Jan:0,Feb:1,Mar:2,Apr:3,May:4,Jun:5,Jul:6,Aug:7,Sep:8,Oct:9,Nov:10,Dec:11}
;

function parseMonthYear(str) {

if (!str) return null;

const p = [Link]().split(" ");

if ([Link] === 2 && MONTH_MAP[p[0]] !== undefined) return new


Date(parseInt(p[1]), MONTH_MAP[p[0]], 15);

return null;

function calcDays(dateStr) {

const d = parseMonthYear(dateStr);

return d ? [Link]((d - today) / 86400000) : null;

// Get selected project from global project selector


const selectedProj = _getSelectedProject ? _getSelectedProject() : "";

const isAllProjects = !selectedProj || selectedProj === "ALL" || selectedProj


=== "";

// Update section header title to reflect selected project

const titleEl = [Link]("pc-ms-section-title");

if (titleEl) {

[Link] = isAllProjects

? "🚩 UPCOMING CRITICAL MILESTONES — BY PROJECT"

: `🚩 UPCOMING CRITICAL MILESTONES — $


{[Link]()}`;

// Group milestones by project

const byProject = [];

[Link](window.MILESTONE_DATA_BY_PROJECT ||
{}).forEach(([schedKey, msList]) => {

const proj = [Link](p =>

[Link]().includes([Link]().split(" ")[0]) ||

[Link]().includes([Link]().split(" ")[0])

);

const projName = proj ? [Link] : schedKey;

const projColor = proj ? [Link] : "#0a3d1f";

const projectManager = proj ? [Link] : "—";

const manager = projectManager;

// Filter: if a specific project is selected, only show that project's milestones

if (!isAllProjects) {
const keyMatch = schedKey === selectedProj ||

projName === selectedProj ||

[Link]().includes([Link]().split(" ")
[0]) ||

[Link]().includes([Link]().split(" ")
[0]);

if (!keyMatch) return;

const rows = [];

[Link](ms => {

if (ms.s === "completed") return;

if (!showAll && ![Link]) return;

const baselineDays = calcDays([Link]);

const forecastDays = calcDays([Link] || [Link]);

const forecastDate = [Link] || [Link];

const isDelayed = (forecastDays !== null && baselineDays !== null &&
forecastDays > baselineDays);

const variance = (forecastDays !== null && baselineDays !== null) ?


forecastDays - baselineDays : 0;

const schedActs = (window.SCHEDULE_ACTIVITIES || {})[schedKey] || [];

const linkedAct = [Link](a => ([Link]||[]).includes([Link]));

const majorActivity = [Link] || (linkedAct ? [Link] :


([Link]||[])[0] || "—");

// Apply status filter

if (statusFilter) {

const isOverdue = forecastDays !== null && forecastDays < 0;


const isDueSoon = forecastDays !== null && forecastDays >= 0 &&
forecastDays <= 30;

if (statusFilter === "overdue" && !isOverdue) return;

if (statusFilter === "duesoon" && !isDueSoon) return;

if (statusFilter === "delayed" && !isDelayed) return;

[Link]({ ms, projName, projColor, manager, majorActivity,


baselineDays, forecastDays, forecastDate, isDelayed, variance, sortKey:
forecastDays !== null ? forecastDays : 9999 });

});

[Link]((a,b) => [Link] - [Link]);

if ([Link]) [Link]({ projName, projColor, manager, rows });

});

// Summary badge

const allRows = [Link](p => [Link]);

const overdue = [Link](r => [Link] !== null &&


[Link] < 0).length;

const due30 = [Link](r => [Link] !== null &&


[Link] >= 0 && [Link] <= 30).length;

const delayed = [Link](r => [Link] && [Link] >=


0).length;

const badge = [Link]("pc-ms-summary-badge");

if (badge) [Link] = `${[Link]} milestone$


{[Link] !== 1 ? "s" : ""} · ${overdue} overdue · ${due30} due
≤30d · ${delayed} delayed`;

if (![Link]) {
const msg = isAllProjects

? `No ${showAll ? "upcoming" : "critical upcoming"} milestones found.`

: `No ${showAll ? "upcoming" : "critical upcoming"} milestones found for


<strong>${selectedProj}</strong>. Select another project or enable "Show
all upcoming".`;

[Link] = `<div class="cms-empty" style="padding:20px;text-


align:center">${msg}</div>`;

return;

const statusCfg = {

"in-progress": { bg: "#d6eaf8", color: "#1a5276", label: "▶ In Progress" },

"planned": { bg: "#eaecee", color: "#555", label: "◷ Planned" },

"delayed": { bg: "#fadbd8", color: "#c0392b", label: "⚠ Delayed" }

};

const html = [Link](({projName, projColor, manager, rows}) => {

const tableRows = [Link](r => {

const {ms, majorActivity, forecastDays: fd, baselineDays, forecastDate,


isDelayed, variance} = r;

const isOverdue = fd !== null && fd < 0;

const isDue30 = fd !== null && fd >= 0 && fd <= 30;

const rowClass = isOverdue ? "cms-row-overdue" : isDue30 ? "cms-row-


due30" : isDelayed ? "cms-row-critical" : "";

const daysBadgeClass = isOverdue ? "cms-days-overdue" : isDue30 ?


"cms-days-due30" : "cms-days-normal";

const daysLabel = isOverdue ? `▲ ${[Link](fd)}d overdue` : fd ===


0 ? "Due today" : fd !== null ? `${fd}d` : "—";

const sCfg = statusCfg[ms.s] || statusCfg["planned"];


const forecastClass = isDelayed ? "cms-date-delayed" : "cms-date-
normal";

const varianceHtml = isDelayed ? `<div class="cms-variance"


style="color:#e74c3c">+${variance}d slip</div>` : variance < 0 ? `<div
class="cms-variance" style="color:#27ae60">${variance}d early</div>` :
"";

const critFlag = [Link] ? `<span style="color:#e74c3c;font-


size:9px;margin-right:3px" title="Critical milestone">🚩</span>` : "";

return `<tr class="${rowClass}">

<td style="min-width:150px"><div style="font-


size:9px;color:#1a6b3a;font-weight:700;line-height:1.3">$
{majorActivity}</div></td>

<td style="min-width:170px">${critFlag}<span class="cms-ms-


name">${ms.m}</span></td>

<td class="cms-date-col"><div class="cms-date-normal">$


{[Link]}</div></td>

<td class="cms-date-col"><div class="${forecastClass}">$


{forecastDate}</div>${varianceHtml}</td>

<td style="min-width:80px"><span class="cms-days-badge $


{daysBadgeClass}">${daysLabel}</span></td>

<td><span class="cms-status-badge" style="background:$


{[Link]};color:${[Link]}">${[Link]}</span></td>

</tr>`;

}).join("");

// Only show project header if viewing all projects (single project is


obvious)

const projHeader = isAllProjects ? `

<div style="display:flex;align-items:center;gap:10px;padding:7px
12px;background:${projColor}18;border-left:4px solid ${projColor};border-
bottom:2px solid ${projColor}40;border-radius:4px 4px 0 0">
<span style="font-size:10px;font-weight:800;color:${projColor}">● $
{projName}</span>

<span style="font-size:9px;color:#666;font-weight:600">Project
Manager: ${manager}</span>

<span style="margin-left:auto;background:${projColor}20;border:1px
solid ${projColor}40;border-radius:3px;padding:2px 8px;font-size:8px;font-
weight:700;color:${projColor}">${[Link]} milestone$
{[Link]>1?"s":""}</span>

</div>` : `

<div style="display:flex;align-items:center;gap:10px;padding:7px
12px;background:${projColor}18;border-left:4px solid ${projColor};border-
bottom:2px solid ${projColor}40;border-radius:4px 4px 0 0">

<span style="font-size:10px;font-weight:800;color:${projColor}">● $
{projName}</span>

<span style="font-size:9px;color:#666;font-weight:600">Project
Manager: ${manager}</span>

<span style="margin-left:auto;background:${projColor}20;border:1px
solid ${projColor}40;border-radius:3px;padding:2px 8px;font-size:8px;font-
weight:700;color:${projColor}">${[Link]} ${showAll ? "upcoming" :
"critical"} milestone${[Link]>1?"s":""}</span>

<span style="background:#e8f5e9;color:#1b5e20;border-
radius:3px;padding:2px 8px;font-size:8px;font-weight:700">✔ Selected
Project</span>

</div>`;

return `<div style="margin-bottom:${isAllProjects ? "16px" : "8px"}">

${projHeader}

<div style="overflow-x:auto">

<table class="cms-table">

<thead><tr>

<th>Major Activity</th>
<th>Critical Milestone</th>

<th>Baseline Date</th>

<th>Forecast Date</th>

<th>Days Remaining</th>

<th>Status</th>

</tr></thead>

<tbody>${tableRows}</tbody>

</table>

</div>

</div>`;

}).join("");

const footerNote = isAllProjects

? "Grouped by project · Sorted by nearest forecast date · 🚩 = Critical path"

: `Showing milestones for: <strong>${selectedProj}</strong> · Sorted by


nearest forecast date · 🚩 = Critical path`;

[Link] = `<div style="padding:8px 10px">

<div class="cms-filter-bar" style="margin-bottom:10px">

<span style="display:flex;align-items:center;gap:4px;font-
size:8px;color:#555">

<span style="width:10px;height:10px;background:#fdf0ef;border:1px
solid #e74c3c;border-radius:2px;display:inline-block"></span>Overdue

<span style="width:10px;height:10px;background:#fffbf0;border:1px
solid #f39c12;border-radius:2px;display:inline-block;margin-left:6px"></
span>Due ≤30d

<span style="width:10px;height:10px;background:#fff8f6;border:1px
solid #e8a090;border-radius:2px;display:inline-block;margin-left:6px"></
span>Delayed
</span>

<span style="margin-left:auto;font-size:8px;color:#888;font-
style:italic">${footerNote}</span>

</div>

${html}

</div>`;

//
═══════════════════════════════════════════════════════
════════
// PROJECT CONTROL — ACHIEVEMENTS & ACTIVITY LOGS BY PROJECT

//
═══════════════════════════════════════════════════════
════════
function renderPCActivityByProject() {

const wrap = [Link]("pc-activity-by-project");

if (!wrap) return;

// Activity section follows the global project selector (no separate filter)

const globalProject = _getSelectedProject ? _getSelectedProject() : "";

const projFilter = globalProject && globalProject !== "" ? globalProject :


"ALL";

const typeFilter = ([Link]("pc-activity-type-filter")||


{}).value || "all";

// Update the project label in the header

const projLabel = [Link]("pc-activity-proj-label");

if (projLabel) {
[Link] = projFilter === "ALL" ? "📂 All Projects" : "📂 " +
([Link] > 30 ? [Link](0,28)+"…" : projFilter);

// Build per-project grouped data

const projectGroups = [];

[Link](window.SCHEDULE_ACTIVITIES || {}).forEach(([schedKey,
acts]) => {

const proj = [Link](p =>

[Link]().includes([Link]().split(" ")[0]) ||

[Link]().includes([Link]().split(" ")[0])

);

const projName = proj ? [Link] : schedKey;

const projColor = proj ? [Link] : "#0a3d1f";

const projectManager = proj ? [Link] : "—";

const manager = projectManager;

// Match filter against project name

if (projFilter !== "ALL") {

const filterLower = [Link]();

const projNameLower = [Link]();

const schedKeyLower = [Link]();

const matched = projName === projFilter ||

[Link]([Link](" ")[0]) ||

[Link]([Link](" ")[0]) ||

[Link]([Link](" ")[0]);

if (!matched) return;
}

const entries = [];

if (typeFilter !== "milestone") {

[Link](a => [Link] === "completed" || [Link] === "in-


progress").forEach(act => {

[Link]({

date: [Link] || [Link],

actName: [Link],

owner: [Link] || "—",

status: [Link] === "completed" ? "Completed" : "In Progress",

statusColor: [Link] === "completed" ? "#27ae60" : "#2980b9",

icon: [Link] === "completed" ? "✅" : "▶",

physPct: [Link],

variance: [Link] || 0,

type: "activity"

});

});

if (typeFilter !== "activity") {

const msList = (window.MILESTONE_DATA_BY_PROJECT || {})[schedKey] ||


[];

[Link](ms => ms.s === "completed").forEach(ms => {

[Link]({

date: [Link],
actName: "🏁 Milestone: " + ms.m,

owner: manager,

status: "Milestone Achieved",

statusColor: "#8e44ad",

icon: "🏁",

physPct: 100,

variance: 0,

type: "milestone"

});

});

[Link]((a,b) => ([Link]||"").localeCompare([Link]||""));

if ([Link]) [Link]({ projName, projColor, manager,


entries, proj });

});

if (![Link]) {

[Link] = '<div style="text-


align:center;color:#bbb;padding:20px;font-size:10px">No activity data
available</div>';

return;

const html = [Link](({projName, projColor, manager, entries,


proj}) => {

const completed = [Link](e => [Link] === "Completed").length;


const inProgress = [Link](e => [Link] === "In Progress").length;

const milestones = [Link](e => [Link] === "milestone").length;

const rows = [Link](e => {

const varLabel = [Link] < 0 ? `<span style="color:#e74c3c;font-


size:8px">${[Link]}d delay</span>` : [Link] > 0 ? `<span
style="color:#27ae60;font-size:8px">+${[Link]}d ahead</span>` : "";

return `<tr>

<td style="white-space:nowrap;color:#555;font-size:9px">${[Link] ||
"—"}</td>

<td style="max-width:220px;font-size:9px">${[Link]}</td>

<td style="font-size:9px;color:#1a5276">${[Link]}</td>

<td style="font-size:9px">${[Link]}% ${varLabel}</td>

<td><span style="padding:2px 7px;border-radius:8px;font-


size:8px;font-weight:800;background:${[Link]}20;color:$
{[Link]};border:1px solid ${[Link]}40">${[Link]} $
{[Link]}</span></td>

</tr>`;

}).join("");

return `<div style="margin-bottom:18px;border:1px solid $


{projColor}30;border-radius:5px;overflow:hidden">

<div style="display:flex;align-items:center;gap:10px;padding:8px
12px;background:${projColor}15;border-left:4px solid ${projColor}">

<span style="font-size:10px;font-weight:800;color:${projColor}">● $
{projName}</span>

<span style="font-size:9px;color:#666;font-weight:600">Project
Manager: ${manager}</span>

<div style="margin-left:auto;display:flex;gap:6px;flex-wrap:wrap">

<span style="background:#d4efdf;border-radius:3px;padding:2px
7px;font-size:8px;font-weight:700;color:#1e8449">✓ ${completed}
Done</span>
<span style="background:#d6eaf8;border-radius:3px;padding:2px
7px;font-size:8px;font-weight:700;color:#1a5276">▶ ${inProgress}
Ongoing</span>

${milestones ? `<span style="background:#e8daef;border-


radius:3px;padding:2px 7px;font-size:8px;font-weight:700;color:#6c3483">🏁
${milestones} Milestone${milestones>1?"s":""}</span>` : ""}

</div>

</div>

<div style="overflow-x:auto">

<table class="tbl" style="font-size:9px">

<thead><tr>

<th>Date</th>

<th>Activity / Milestone</th>

<th>Responsible</th>

<th>Progress</th>

<th>Status</th>

</tr></thead>

<tbody>${rows}</tbody>

</table>

</div>

</div>`;

}).join("");

[Link] = html;

// Populate the project filter dropdown for PC Activity

function populatePCActivityFilter() {
const sel = [Link]("pc-activity-proj-filter");

if (!sel) return;

while ([Link] > 1) [Link](1);

[Link](p => {

const opt = [Link]("option");

[Link] = [Link];

[Link] = [Link] > 32 ? [Link](0,30)+"…" :


[Link];

[Link](opt);

});

function renderPortfolio() {

// ── A. Progress by Project — Vertical Bar Chart ──────────────

const pb = [Link]("port-progress-bars");

if(pb) {

const maxH = 140;

const bars = [Link](p => {

const barH = [Link](([Link] / 100) * maxH);

const barColor = [Link] === "On Track" ? "#27ae60" : [Link] ===


"At Risk" ? "#f39c12" : "#e74c3c";

const shortName = [Link] > 18 ? [Link](0,16)+"…" :


[Link];

return `<div style="display:flex;flex-direction:column;align-


items:center;flex:1;min-width:0;gap:3px">

<div style="font-size:9px;font-weight:800;color:${barColor}">$
{[Link]}%</div>

<div style="height:${maxH}px;display:flex;align-items:flex-
end;width:100%">
<div style="width:100%;height:${barH}px;background:$
{barColor};border-radius:3px 3px 0 0;transition:height .4s;position:relative"
title="${[Link]} — ${[Link]}% (${[Link]})">

</div>

</div>

<div style="font-size:8px;text-align:center;color:#555;word-
break:break-word;line-height:1.2;width:100%;padding:0 1px" title="$
{[Link]}">${shortName}</div>

<span style="display:inline-block;padding:1px 5px;border-


radius:8px;font-size:7px;font-weight:800;background:${barColor}20;color:$
{barColor};border:1px solid ${barColor}40">${[Link]}</span>

</div>`;

}).join("");

[Link] = `

<div style="display:flex;gap:4px;margin-bottom:6px;flex-wrap:wrap">

<div style="display:flex;align-items:center;gap:3px"><div
style="width:9px;height:9px;background:#27ae60;border-radius:2px"></
div><span style="font-size:8px;color:#555;font-weight:700">On
Track</span></div>

<div style="display:flex;align-items:center;gap:3px"><div
style="width:9px;height:9px;background:#f39c12;border-radius:2px"></
div><span style="font-size:8px;color:#555;font-weight:700">At
Risk</span></div>

<div style="display:flex;align-items:center;gap:3px"><div
style="width:9px;height:9px;background:#e74c3c;border-radius:2px"></
div><span
style="font-size:8px;color:#555;font-weight:700">Delayed</span></div>

</div>

<div style="display:flex;gap:6px;align-items:flex-end;padding:0 4px">$


{bars}</div>

<div style="border-top:2px solid #c8d8c8;margin-top:4px;padding-


top:3px;text-align:center;font-size:8px;color:#888">Completion %</div>`;
}

// ── B. Budget Utilization — Vertical Bar Chart ────────────────

const bb = [Link]("port-budget-bars");

if(bb) {

const maxBudget = [Link](...[Link](p => [Link]));

const maxH = 130;

const bars2 = [Link](p => {

const utilPct = [Link]([Link] / [Link] * 100);

const barColor = utilPct > 90 ? "#e74c3c" : utilPct > 75 ? "#f39c12" :


"#2980b9";

const budgetH = [Link](([Link] / maxBudget) * maxH);

const spentH = [Link](([Link] / maxBudget) * maxH);

const shortName = [Link] > 18 ? [Link](0,16)+"…" :


[Link];

return `<div style="display:flex;flex-direction:column;align-


items:center;flex:1;min-width:0;gap:3px">

<div style="font-size:9px;font-weight:800;color:${barColor}">$
{utilPct}%</div>

<div style="height:${maxH}px;display:flex;align-items:flex-
end;gap:2px;width:100%">

<div style="flex:1;height:$
{budgetH}px;background:#d6eaf855;border:1px solid #aed6f1;border-
radius:3px 3px 0 0" title="Budget: ETB
${([Link]/1e6).toFixed(0)}M"></div>

<div style="flex:1;height:${spentH}px;background:$
{barColor};border-radius:3px 3px 0 0;transition:height .4s" title="Spent: ETB
${([Link]/1e6).toFixed(0)}M (${utilPct}%)"></div>

</div>
<div style="font-size:8px;text-align:center;color:#555;word-
break:break-word;line-height:1.2;width:100%;padding:0 1px" title="$
{[Link]}">${shortName}</div>

</div>`;

}).join("");

[Link] = `

<div style="display:flex;gap:10px;margin-bottom:6px;flex-wrap:wrap">

<div style="display:flex;align-items:center;gap:3px"><div
style="width:9px;height:9px;background:#d6eaf855;border:1px solid
#aed6f1;border-radius:2px"></div><span style="font-
size:8px;color:#555;font-weight:700">Allocated</span></div>

<div style="display:flex;align-items:center;gap:3px"><div
style="width:9px;height:9px;background:#2980b9;border-radius:2px"></
div><span style="font-size:8px;color:#555;font-weight:700">Utilized
(Normal)</span></div>

<div style="display:flex;align-items:center;gap:3px"><div
style="width:9px;height:9px;background:#f39c12;border-radius:2px"></
div><span style="font-size:8px;color:#555;font-weight:700">Utilized
(&gt;75%)</span></div>

<div style="display:flex;align-items:center;gap:3px"><div
style="width:9px;height:9px;background:#e74c3c;border-radius:2px"></
div><span style="font-size:8px;color:#555;font-weight:700">Utilized
(&gt;90%)</span></div>

</div>

<div style="display:flex;gap:6px;align-items:flex-end;padding:0 4px">$


{bars2}</div>

<div style="border-top:2px solid #c8d8c8;margin-top:4px;padding-


top:3px;text-align:center;font-size:8px;color:#888">Budget Allocated vs
Utilized</div>`;

}
//
═══════════════════════════════════════════════════════
════════
// SCHEDULE

//
═══════════════════════════════════════════════════════
════════
// Master project schedule data for 2026 Gantt

const GANTT_PROJECTS_2026 = [

// {name, start(0-11 month index), dur(months), pct, color, statusColor,


critical, baseline_start, baseline_dur}

{name:"Ayisha Substation Maintenance", start:0, dur:8, pct:72,


color:"#27ae60", critical:false, baseline_start:0, baseline_dur:7,
statusKey:"On Track"},

{name:"Dewante Freight Terminal Constr.", start:1, dur:11, pct:38,


color:"#e74c3c", critical:true, baseline_start:0, baseline_dur:10,
statusKey:"Critical"},

{name:"Indode Link-1 Pavement Constr.", start:1, dur:7, pct:85,


color:"#2980b9", critical:false, baseline_start:1, baseline_dur:6,
statusKey:"On Track"},

{name:"Indode Link-2 Rail Extension", start:3, dur:8, pct:42,


color:"#f39c12", critical:false, baseline_start:2, baseline_dur:7,
statusKey:"Delayed"},

{name:"Indode Link-1 Rail Extension", start:2, dur:7, pct:58,


color:"#1abc9c", critical:false, baseline_start:2, baseline_dur:6,
statusKey:"On Track"},

{name:"AMG OC Construction", start:3, dur:9, pct:35,


color:"#8e44ad", critical:true, baseline_start:2, baseline_dur:8,
statusKey:"At Risk"},

{name:"AMG FY Construction", start:4, dur:8, pct:28,


color:"#d35400", critical:true, baseline_start:3, baseline_dur:7,
statusKey:"Critical"},
{name:"Sebeta Power Line Construction", start:2, dur:6, pct:62,
color:"#16a085", critical:false, baseline_start:2, baseline_dur:5,
statusKey:"On Track"},

];

const STATUS_COLORS_2026 = {

"On Track":"#27ae60","Delayed":"#f39c12","Critical":"#e74c3c","At
Risk":"#d35400","Completed":"#2980b9"

};

const MONTH_LABELS =
["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];

//
═══════════════════════════════════════════════════════
════════
// S-CURVE — PER-PROJECT PROGRESS DATA

// Structure: projectProgressData[projectName] = { monthly, weekly, daily }

// monthly: 12 entries (Jan–Dec), weekly: 52 entries, daily: 365 entries

// Each entry: { planned: number, actual: number|null, forecast: number|


null }

// Add any new project here and the dropdown will automatically include it.

//
═══════════════════════════════════════════════════════
════════

(function buildSCurveData() {

// ── Utility: generate smooth S-curve values ─────────────────

// Returns n values from 0→100 following a logistic (S) shape,


// offset by `startFrac` and clipped to `endFrac` of the range.

function sCurve(n, startFrac, endFrac, sharpness) {

sharpness = sharpness || 8;

const vals = [];

for (let i = 0; i < n; i++) {

const t = i / (n - 1); // 0..1 over the full axis

const x = (t - 0.5) * sharpness;

const logistic = 1 / (1 + [Link](-x));

// Scale logistic (0..1) → (startFrac..endFrac) of 0–100

const v = startFrac * 100 + (endFrac - startFrac) * 100 * logistic;

[Link]([Link]([Link](100, [Link](0, v))));

return vals;

// ── Utility: add realistic noise for actual vs planned ───────

function addNoise(vals, actualUpToIdx, lag) {

// Returns array: null for future, actual = planned ± lag variation

lag = lag || 0;

return [Link]((v, i) => {

if (i > actualUpToIdx) return null;

const noise = ([Link](i * 2.7) * lag);

return [Link]([Link](100, [Link](0, v + noise)));

});

// ── Utility: build forecast from last actual to 100 ─────────


function buildForecast(actual, planned, actualUpToIdx) {

const result = [Link](v => null); // null everywhere first

if (actualUpToIdx < 0 || actualUpToIdx >= [Link]) return result;

const lastVal = actual[actualUpToIdx];

const remaining = [Link] - 1 - actualUpToIdx;

if (remaining <= 0) return result;

result[actualUpToIdx] = lastVal; // anchor at last actual point

for (let i = actualUpToIdx + 1; i < [Link]; i++) {

const frac = (i - actualUpToIdx) / remaining;

result[i] = [Link](lastVal + (100 - lastVal) * frac);

return result;

// ── TODAY indices ────────────────────────────────────────────

// May 2026: month index 4 (0-based), week ~20, day ~140

const TODAY_MONTH = 4;

const TODAY_WEEK = 20;

const TODAY_DAY = 140;

// ── Per-project definitions ──────────────────────────────────

// lag > 0 = ahead, lag < 0 = behind schedule

const projectDefs = [

{ name: "Ayisha Substation Maintenance", sharpness: 7, lag: 2,


startFrac:.02, endFrac:.97 },

{ name: "Dewante Freight Terminal Constr.", sharpness: 9, lag: -8,


startFrac:.05, endFrac:.92 },
{ name: "Indode Link-1 Pavement Constr.", sharpness: 6, lag: 4,
startFrac:.03, endFrac:.98 },

{ name: "Indode Link-2 Rail Extension", sharpness: 8, lag: -5,


startFrac:.04, endFrac:.95 },

{ name: "Indode Link-1 Rail Extension", sharpness: 7, lag: 1,


startFrac:.02, endFrac:.96 },

{ name: "AMG OC Construction", sharpness: 10, lag: -6,


startFrac:.06, endFrac:.93 },

{ name: "AMG FY Construction", sharpness: 9, lag: -9,


startFrac:.05, endFrac:.91 },

{ name: "Sebeta Power Line Construction", sharpness: 7, lag: 3,


startFrac:.03, endFrac:.97 },

];

[Link] = {};

[Link](function(def) {

// ── Monthly (12 points) ──────────────────────────────────

const mPlanned = sCurve(12, [Link], [Link], [Link]);

const mActual = addNoise(mPlanned, TODAY_MONTH, [Link]);

const mForecast= buildForecast(mActual, mPlanned, TODAY_MONTH);

// ── Weekly (52 points) ──────────────────────────────────

const wPlanned = sCurve(52, [Link], [Link], [Link]);

const wActual = addNoise(wPlanned, TODAY_WEEK, [Link]);

const wForecast= buildForecast(wActual, wPlanned, TODAY_WEEK);

// ── Daily (365 points) ──────────────────────────────────


const dPlanned = sCurve(365, [Link], [Link], [Link] *
1.1);

const dActual = addNoise(dPlanned, TODAY_DAY, [Link]);

const dForecast= buildForecast(dActual, dPlanned, TODAY_DAY);

// Pack into arrays of objects

function pack(planned, actual, forecast) {

return [Link](function(p, i) {

return { planned: p, actual: actual[i], forecast: forecast[i] };

});

[Link][[Link]] = {

monthly: pack(mPlanned, mActual, mForecast),

weekly: pack(wPlanned, wActual, wForecast),

daily: pack(dPlanned, dActual, dForecast),

lag: [Link]

};

});

// ── State: persist user selections across navigation ────────

window._scurveState = {

project: projectDefs[0].name, // default to first project

view: "monthly"

};

})();
// S-Curve data (cumulative %) — legacy globals kept for backward
compatibility

const SCURVE_PLANNED = [4,10,18,28,40,52,62,72,82,90,96,100];

const SCURVE_ACTUAL = [3,8,14,22,33,43,51,60,null,null,null,null];

// Milestone data

const MILESTONES_2026 = [

{m:"Ayisha Foundation Inspection", proj:"Ayisha Substation


Maintenance", due:"Jan 2026", s:"completed", daysLeft:-30},

{m:"Indode Pavement Layer 1 Complete", proj:"Indode Link-1 Pavement


Constr.", due:"Mar 2026", s:"completed", daysLeft:-10},

{m:"Dewante Terminal Design Approved", proj:"Dewante Freight Terminal",


due:"Apr 2026", s:"completed", daysLeft:-5},

{m:"Sebeta Power Line Phase 1", proj:"Sebeta Power Line


Construction", due:"May 2026", s:"in-progress",daysLeft:10},

{m:"AMG OC Track Survey Completion", proj:"AMG OC Construction",


due:"Jun 2026", s:"in-progress",daysLeft:25},

{m:"Indode Rail Link-2 Subgrade Done", proj:"Indode Link-2 Rail


Extension", due:"Jul 2026", s:"planned", daysLeft:55},

{m:"AMG FY Civil Works 50% Complete", proj:"AMG FY Construction",


due:"Aug 2026", s:"planned", daysLeft:85},

{m:"Dewante Terminal Shell Complete", proj:"Dewante Freight Terminal",


due:"Sep 2026", s:"planned", daysLeft:110},

{m:"Ayisha Electrical Systems Test", proj:"Ayisha Substation


Maintenance", due:"Sep 2026", s:"planned", daysLeft:115},

{m:"Indode Link-1 Rail Laying Done", proj:"Indode Link-1 Rail Extension",


due:"Oct 2026", s:"planned", daysLeft:145},

{m:"Sebeta Power Line Full Commission", proj:"Sebeta Power Line


Construction", due:"Oct 2026", s:"planned", daysLeft:148},
{m:"All Projects Final Handover", proj:"All Projects",
due:"Dec 2026", s:"planned", daysLeft:200},

];

// Phase data

const PHASES_2026 = [

{ph:"Survey & Investigation", pct:100, status:"completed",


color:"#27ae60"},

{ph:"Design", pct:88, status:"active", color:"#2980b9"},

{ph:"Procurement", pct:74, status:"active", color:"#1abc9c"},

{ph:"Civil Works", pct:58, status:"active", color:"#f39c12"},

{ph:"Track Works", pct:32, status:"active", color:"#d35400"},

{ph:"Electrical & Systems", pct:18, status:"pending", color:"#8e44ad"},

{ph:"Testing & Commissioning",pct:5, status:"pending",


color:"#e74c3c"},

{ph:"Final Handover", pct:0, status:"pending", color:"#bdc3c7"},

];

// Delay data

const DELAY_ITEMS_2026 = [

{proj:"Dewante Freight Terminal", activity:"Foundation Works",


delay:22, float:0, severity:"critical", type:"Critical Path"},

{proj:"AMG FY Construction", activity:"Track Alignment Survey",


delay:14, float:3, severity:"critical", type:"Critical Path"},

{proj:"AMG OC Construction", activity:"Earthworks Phase 2",


delay:10, float:5, severity:"warning", type:"Near-Critical"},

{proj:"Indode Link-2 Rail Ext.", activity:"Land Acquisition Delay", delay:18,


float:2, severity:"critical", type:"Critical Path"},
{proj:"Sebeta Power Line", activity:"Equipment Delivery", delay:6,
float:12, severity:"warning", type:"Near-Critical"},

];

[Link] = [Link] ||
MILESTONES_2026.map((m,i)=>({id:i+1,...m}));

//
═══════════════════════════════════════════════════════
════════
// SCHEDULE v7 — PROJECT-BASED ACTIVITY & MILESTONE DATA

//
═══════════════════════════════════════════════════════
════════

// Per-project activity data (imported from schedule or demo)

window.SCHEDULE_ACTIVITIES = {

"Ayisha Substation Maintenance": [

{id:"AYS-001",name:"Site Mobilisation",start:"2026-01-05",finish:"2026-01-
25",physPct:100,finPct:100,status:"completed",variance:0,owner:"Eng.
Tesfaye"},

{id:"AYS-002",name:"Foundation Excavation",start:"2026-01-
20",finish:"2026-02-28",physPct:100,finPct:98,status:"completed",variance:-
2,owner:"Eng. Kebede"},

{id:"AYS-003",name:"Concrete Pouring Phase 1",start:"2026-02-


15",finish:"2026-03-
30",physPct:100,finPct:100,status:"completed",variance:0,owner:"Eng.
Tesfaye"},

{id:"AYS-004",name:"Steel Structure Erection",start:"2026-03-


10",finish:"2026-04-30",physPct:88,finPct:82,status:"in-progress",variance:-
5,owner:"Eng. Dawit"},
{id:"AYS-005",name:"Electrical System Install",start:"2026-04-
15",finish:"2026-06-30",physPct:42,finPct:38,status:"in-progress",variance:-
8,owner:"Eng. Selam"},

{id:"AYS-006",name:"Transformer Installation",start:"2026-06-
01",finish:"2026-07-
31",physPct:10,finPct:5,status:"upcoming",variance:0,owner:"Eng. Dawit"},

{id:"AYS-007",name:"Testing & Commissioning",start:"2026-08-


01",finish:"2026-08-
31",physPct:0,finPct:0,status:"upcoming",variance:0,owner:"Eng. Selam"},

],

"Dewante Freight Terminal Constr.": [

{id:"DFT-001",name:"Land Clearing & Grubbing",start:"2026-02-


01",finish:"2026-02-
28",physPct:100,finPct:100,status:"completed",variance:0,owner:"Eng.
Almaz"},

{id:"DFT-002",name:"Foundation Works",start:"2026-02-20",finish:"2026-
04-30",physPct:60,finPct:50,status:"delayed",variance:-22,owner:"Eng.
Solomon"},

{id:"DFT-003",name:"Structural Frame — Bay A",start:"2026-04-


01",finish:"2026-06-30",physPct:20,finPct:15,status:"critical",variance:-
18,owner:"Eng. Almaz"},

{id:"DFT-004",name:"Structural Frame — Bay B",start:"2026-05-


15",finish:"2026-08-31",physPct:5,finPct:3,status:"critical",variance:-
14,owner:"Eng. Solomon"},

{id:"DFT-005",name:"Roofing System",start:"2026-08-01",finish:"2026-10-
31",physPct:0,finPct:0,status:"upcoming",variance:0,owner:"Eng. Almaz"},

{id:"DFT-006",name:"Rail Siding Connection",start:"2026-09-


01",finish:"2026-11-
30",physPct:0,finPct:0,status:"upcoming",variance:0,owner:"Eng. Haile"},

{id:"DFT-007",name:"Terminal MEP Works",start:"2026-10-


01",finish:"2026-12-
15",physPct:0,finPct:0,status:"upcoming",variance:0,owner:"Eng. Solomon"},

],
"Indode Link-1 Pavement Constr.": [

{id:"ILP-001",name:"Subgrade Preparation",start:"2026-02-
01",finish:"2026-03-
15",physPct:100,finPct:100,status:"completed",variance:0,owner:"Eng.
Berhane"},

{id:"ILP-002",name:"Sub-base Layer Compaction",start:"2026-03-


01",finish:"2026-04-
15",physPct:100,finPct:100,status:"completed",variance:0,owner:"Eng.
Berhane"},

{id:"ILP-003",name:"Base Course Paving",start:"2026-04-01",finish:"2026-


05-31",physPct:92,finPct:90,status:"in-progress",variance:3,owner:"Eng.
Yonas"},

{id:"ILP-004",name:"Asphalt Wearing Course",start:"2026-05-


15",finish:"2026-07-15",physPct:30,finPct:25,status:"in-
progress",variance:2,owner:"Eng. Yonas"},

{id:"ILP-005",name:"Road Markings & Signage",start:"2026-07-


01",finish:"2026-08-
15",physPct:0,finPct:0,status:"upcoming",variance:0,owner:"Eng. Berhane"},

{id:"ILP-006",name:"Drainage Completion",start:"2026-07-
15",finish:"2026-08-
31",physPct:0,finPct:0,status:"upcoming",variance:0,owner:"Eng. Yonas"},

],

"Indode Link-2 Rail Extension": [

{id:"ILR-001",name:"Topographic Survey",start:"2026-04-01",finish:"2026-
04-30",physPct:100,finPct:100,status:"completed",variance:0,owner:"Eng.
Girma"},

{id:"ILR-002",name:"Land Acquisition",start:"2026-04-01",finish:"2026-06-
30",physPct:55,finPct:40,status:"delayed",variance:-18,owner:"Eng. Alem"},

{id:"ILR-003",name:"Earthworks — Embankment",start:"2026-05-
01",finish:"2026-07-31",physPct:28,finPct:22,status:"delayed",variance:-
12,owner:"Eng. Girma"},

{id:"ILR-004",name:"Culverts & Drainage",start:"2026-06-01",finish:"2026-


08-31",physPct:10,finPct:8,status:"in-progress",variance:-5,owner:"Eng.
Alem"},
{id:"ILR-005",name:"Ballast & Track Laying",start:"2026-09-
01",finish:"2026-11-
30",physPct:0,finPct:0,status:"upcoming",variance:0,owner:"Eng. Girma"},

],

"Indode Link-1 Rail Extension": [

{id:"ILX-001",name:"Route Alignment Finalisation",start:"2026-03-


01",finish:"2026-03-
31",physPct:100,finPct:100,status:"completed",variance:0,owner:"Eng.
Mekdes"},

{id:"ILX-002",name:"Subgrade Earthworks",start:"2026-03-
15",finish:"2026-05-31",physPct:80,finPct:75,status:"in-
progress",variance:2,owner:"Eng. Mekdes"},

{id:"ILX-003",name:"Ballast Laying",start:"2026-05-01",finish:"2026-07-
31",physPct:35,finPct:30,status:"in-progress",variance:1,owner:"Eng.
Tadesse"},

{id:"ILX-004",name:"Track Welding & Fastening",start:"2026-07-


01",finish:"2026-09-
30",physPct:0,finPct:0,status:"upcoming",variance:0,owner:"Eng. Tadesse"},

{id:"ILX-005",name:"Signalling Installation",start:"2026-09-
01",finish:"2026-10-
31",physPct:0,finPct:0,status:"upcoming",variance:0,owner:"Eng. Mekdes"},

],

"AMG OC Construction": [

{id:"AOC-001",name:"Clearing & Demolition",start:"2026-04-


01",finish:"2026-04-
30",physPct:100,finPct:100,status:"completed",variance:0,owner:"Eng.
Biruk"},

{id:"AOC-002",name:"Track Survey — Phase 1",start:"2026-04-


15",finish:"2026-06-30",physPct:50,finPct:42,status:"delayed",variance:-
10,owner:"Eng. Biruk"},

{id:"AOC-003",name:"Earthworks Phase 2",start:"2026-05-


01",finish:"2026-08-31",physPct:22,finPct:18,status:"delayed",variance:-
10,owner:"Eng. Hana"},
{id:"AOC-004",name:"Concrete Box Culverts",start:"2026-07-
01",finish:"2026-09-
30",physPct:0,finPct:0,status:"upcoming",variance:0,owner:"Eng. Biruk"},

{id:"AOC-005",name:"Rail Track Installation",start:"2026-09-


01",finish:"2026-11-
30",physPct:0,finPct:0,status:"upcoming",variance:0,owner:"Eng. Hana"},

],

"AMG FY Construction": [

{id:"AFY-001",name:"Access Road Construction",start:"2026-05-


01",finish:"2026-06-30",physPct:45,finPct:40,status:"in-progress",variance:-
9,owner:"Eng. Leul"},

{id:"AFY-002",name:"Track Alignment Survey",start:"2026-05-


01",finish:"2026-06-30",physPct:38,finPct:30,status:"delayed",variance:-
14,owner:"Eng. Tigist"},

{id:"AFY-003",name:"Embankment Construction",start:"2026-06-
01",finish:"2026-09-30",physPct:10,finPct:8,status:"critical",variance:-
9,owner:"Eng. Leul"},

{id:"AFY-004",name:"Bridge Superstructure",start:"2026-08-
01",finish:"2026-11-
30",physPct:0,finPct:0,status:"upcoming",variance:0,owner:"Eng. Tigist"},

{id:"AFY-005",name:"Signal & Telecom Works",start:"2026-10-


01",finish:"2026-12-
31",physPct:0,finPct:0,status:"upcoming",variance:0,owner:"Eng. Leul"},

],

"Sebeta Power Line Construction": [

{id:"SPL-001",name:"Tower Foundation Design",start:"2026-03-


01",finish:"2026-03-
31",physPct:100,finPct:100,status:"completed",variance:0,owner:"Eng.
Rekik"},

{id:"SPL-002",name:"Tower Erection — Section A",start:"2026-03-


15",finish:"2026-04-
30",physPct:100,finPct:100,status:"completed",variance:0,owner:"Eng.
Rekik"},
{id:"SPL-003",name:"Conductor Stringing",start:"2026-04-15",finish:"2026-
06-30",physPct:60,finPct:55,status:"in-progress",variance:3,owner:"Eng.
Yeshi"},

{id:"SPL-004",name:"Equipment Delivery & Install",start:"2026-05-


01",finish:"2026-07-31",physPct:35,finPct:25,status:"in-progress",variance:-
6,owner:"Eng. Yeshi"},

{id:"SPL-005",name:"HV Testing & Commissioning",start:"2026-08-


01",finish:"2026-09-
30",physPct:0,finPct:0,status:"upcoming",variance:0,owner:"Eng. Rekik"},

{id:"SPL-006",name:"Final Energisation",start:"2026-10-01",finish:"2026-
10-31",physPct:0,finPct:0,status:"upcoming",variance:0,owner:"Eng. Yeshi"},

],

};

// Per-project financial progress data (parallel to physical)

[Link] = {};

(function buildFinancialData() {

const offsets = {

"Ayisha Substation Maintenance": { lag: 1, startFrac:.03, endFrac:.96 },

"Dewante Freight Terminal Constr.":{ lag: -10,startFrac:.05, endFrac:.90 },

"Indode Link-1 Pavement Constr.": { lag: 3, startFrac:.04, endFrac:.97 },

"Indode Link-2 Rail Extension": { lag: -7, startFrac:.04, endFrac:.94 },

"Indode Link-1 Rail Extension": { lag: 2, startFrac:.03, endFrac:.95 },

"AMG OC Construction": { lag: -8, startFrac:.06, endFrac:.92 },

"AMG FY Construction": { lag: -11,startFrac:.05, endFrac:.90 },

"Sebeta Power Line Construction": { lag: 2, startFrac:.03, endFrac:.96 },

};

function sCurve(n,s,e,k){k=k||8;return [Link]({length:n},(_,i)=>{const


t=i/(n-1),x=(t-.5)*k,l=1/(1+[Link](-x));return
[Link]([Link](100,[Link](0,s*100+(e-s)*100*l)));});}
function addNoise(vals,upTo,lag){return [Link]((v,i)=>i>upTo?
null:[Link]([Link](100,[Link](0,v+([Link](i*3.1)*lag)))));}

function buildForecast(actual,upTo){const
r=[Link](()=>null);if(upTo<0)return r;const lv=actual[upTo];const
rem=[Link]-1-upTo;r[upTo]=lv;for(let i=upTo+1;i<[Link];i++){const f=(i-
upTo)/rem;r[i]=[Link](lv+(100-lv)*f);}return r;}

[Link]([Link]||{}).forEach(name=>{

const def=offsets[name]||{lag:0,startFrac:.04,endFrac:.95};

const mP=sCurve(12,[Link],[Link],8);

const mA=addNoise(mP,4,[Link]);

const mF=buildForecast(mA,4);

const wP=sCurve(52,[Link],[Link],8);

const wA=addNoise(wP,20,[Link]);

const wF=buildForecast(wA,20);

const dP=sCurve(365,[Link],[Link],8.8);

const dA=addNoise(dP,140,[Link]);

const dF=buildForecast(dA,140);

function pack(p,a,f){return
[Link]((v,i)=>({planned:v,actual:a[i],forecast:f[i]}));}

[Link][name]={monthly:pack(mP,mA,mF),weekly:pack
(wP,wA,wF),daily:pack(dP,dA,dF),lag:[Link]};

});

})();

// Milestone data indexed by project

// Fields: id, m (milestone name), majorActivity, due (baseline), forecastDue,


s (status), actPct, planPct, daysLeft, activities[], critical

window.MILESTONE_DATA_BY_PROJECT = {
"Ayisha Substation Maintenance": [

{id:"M1",m:"Foundation Inspection Complete",majorActivity:"Foundation


Excavation",due:"Jan 2026",forecastDue:"Jan
2026",s:"completed",actPct:100,planPct:100,daysLeft:-90,activities:["AYS-
001","AYS-002"],critical:false},

{id:"M2",m:"Steel Structure 50% Complete",majorActivity:"Steel Structure


Erection",due:"Apr 2026",forecastDue:"Apr
2026",s:"completed",actPct:88,planPct:90,daysLeft:-10,activities:["AYS-
003","AYS-004"],critical:false},

{id:"M3",m:"Electrical System Ready",majorActivity:"Electrical System


Install",due:"Jul 2026",forecastDue:"Aug 2026",s:"in-
progress",actPct:42,planPct:55,daysLeft:55,activities:["AYS-005","AYS-
006"],critical:true},

{id:"M4",m:"Full Commissioning",majorActivity:"Testing &


Commissioning",due:"Sep 2026",forecastDue:"Oct
2026",s:"planned",actPct:0,planPct:0,daysLeft:115,activities:["AYS-
007"],critical:true},

],

"Dewante Freight Terminal Constr.": [

{id:"M1",m:"Site Clearing & Grubbing Done",majorActivity:"Land Clearing


& Grubbing",due:"Mar 2026",forecastDue:"Mar
2026",s:"completed",actPct:100,planPct:100,daysLeft:-60,activities:["DFT-
001"],critical:false},

{id:"M2",m:"Foundation Works Complete",majorActivity:"Foundation


Works",due:"May 2026",forecastDue:"Jun 2026",s:"in-
progress",actPct:60,planPct:90,daysLeft:18,activities:["DFT-
002"],critical:true},

{id:"M3",m:"Terminal Shell Complete",majorActivity:"Structural


Frame",due:"Sep 2026",forecastDue:"Nov
2026",s:"planned",actPct:0,planPct:0,daysLeft:110,activities:["DFT-003","DFT-
004","DFT-005"],critical:true},

{id:"M4",m:"Rail Siding Ready",majorActivity:"Rail Siding


Connection",due:"Nov 2026",forecastDue:"Jan
2027",s:"planned",actPct:0,planPct:0,daysLeft:165,activities:["DFT-006","DFT-
007"],critical:true},
],

"Indode Link-1 Pavement Constr.": [

{id:"M1",m:"Sub-base Layers Done",majorActivity:"Sub-base Layer


Compaction",due:"Apr 2026",forecastDue:"Apr
2026",s:"completed",actPct:100,planPct:100,daysLeft:-30,activities:["ILP-
001","ILP-002"],critical:false},

{id:"M2",m:"Base Course 100% Complete",majorActivity:"Base Course


Paving",due:"Jun 2026",forecastDue:"Jun 2026",s:"in-
progress",actPct:92,planPct:100,daysLeft:28,activities:["ILP-
003"],critical:true},

{id:"M3",m:"Wearing Course & Markings",majorActivity:"Asphalt Wearing


Course",due:"Aug 2026",forecastDue:"Aug
2026",s:"planned",actPct:0,planPct:0,daysLeft:85,activities:["ILP-004","ILP-
005","ILP-006"],critical:true},

],

"Indode Link-2 Rail Extension": [

{id:"M1",m:"Survey & Land Acquisition",majorActivity:"Land


Acquisition",due:"Jun 2026",forecastDue:"Jul 2026",s:"in-
progress",actPct:55,planPct:80,daysLeft:25,activities:["ILR-001","ILR-
002"],critical:true},

{id:"M2",m:"Earthworks Complete",majorActivity:"Earthworks —
Embankment",due:"Aug 2026",forecastDue:"Sep
2026",s:"planned",actPct:0,planPct:0,daysLeft:80,activities:["ILR-003","ILR-
004"],critical:true},

{id:"M3",m:"Track Laying Done",majorActivity:"Ballast & Track


Laying",due:"Dec 2026",forecastDue:"Dec
2026",s:"planned",actPct:0,planPct:0,daysLeft:200,activities:["ILR-
005"],critical:false},

],

"Indode Link-1 Rail Extension": [

{id:"M1",m:"Alignment Finalised",majorActivity:"Route Alignment


Finalisation",due:"Mar 2026",forecastDue:"Mar
2026",s:"completed",actPct:100,planPct:100,daysLeft:-65,activities:["ILX-
001"],critical:false},
{id:"M2",m:"Ballast & Subgrade 80% Done",majorActivity:"Subgrade
Earthworks",due:"Jun 2026",forecastDue:"Jun 2026",s:"in-
progress",actPct:58,planPct:65,daysLeft:30,activities:["ILX-002","ILX-
003"],critical:true},

{id:"M3",m:"Track Welding Complete",majorActivity:"Track Welding &


Fastening",due:"Oct 2026",forecastDue:"Oct
2026",s:"planned",actPct:0,planPct:0,daysLeft:145,activities:["ILX-004","ILX-
005"],critical:true},

],

"AMG OC Construction": [

{id:"M1",m:"Clearing & Survey Done",majorActivity:"Track Survey — Phase


1",due:"May 2026",forecastDue:"Jun 2026",s:"in-
progress",actPct:50,planPct:70,daysLeft:10,activities:["AOC-001","AOC-
002"],critical:true},

{id:"M2",m:"Earthworks 100% Complete",majorActivity:"Earthworks Phase


2",due:"Sep 2026",forecastDue:"Oct
2026",s:"planned",actPct:0,planPct:0,daysLeft:110,activities:["AOC-
003","AOC-004"],critical:true},

{id:"M3",m:"Rail Track Installation Done",majorActivity:"Rail Track


Installation",due:"Dec 2026",forecastDue:"Dec
2026",s:"planned",actPct:0,planPct:0,daysLeft:200,activities:["AOC-
005"],critical:false},

],

"AMG FY Construction": [

{id:"M1",m:"Access Road Complete",majorActivity:"Access Road


Construction",due:"Jun 2026",forecastDue:"Aug 2026",s:"in-
progress",actPct:38,planPct:60,daysLeft:25,activities:["AFY-001","AFY-
002"],critical:true},

{id:"M2",m:"Embankment & Bridge Done",majorActivity:"Embankment


Construction",due:"Nov 2026",forecastDue:"Dec
2026",s:"planned",actPct:0,planPct:0,daysLeft:165,activities:["AFY-003","AFY-
004"],critical:true},

{id:"M3",m:"Full Signal & Handover",majorActivity:"Signal & Telecom


Works",due:"Dec 2026",forecastDue:"Dec
2026",s:"planned",actPct:0,planPct:0,daysLeft:200,activities:["AFY-
005"],critical:false},

],

"Sebeta Power Line Construction": [

{id:"M1",m:"Tower Erection Section A Done",majorActivity:"Tower Erection


— Section A",due:"Apr 2026",forecastDue:"Apr
2026",s:"completed",actPct:100,planPct:100,daysLeft:-35,activities:["SPL-
001","SPL-002"],critical:false},

{id:"M2",m:"Conductor Stringing 100%",majorActivity:"Conductor


Stringing",due:"Jun 2026",forecastDue:"Jul 2026",s:"in-
progress",actPct:60,planPct:75,daysLeft:25,activities:["SPL-003","SPL-
004"],critical:true},

{id:"M3",m:"Full Energisation",majorActivity:"HV Testing &


Commissioning",due:"Oct 2026",forecastDue:"Oct
2026",s:"planned",actPct:0,planPct:0,daysLeft:148,activities:["SPL-005","SPL-
006"],critical:true},

],

};

// Delay data indexed by project

window.DELAY_DATA_BY_PROJECT = {

"Ayisha Substation Maintenance": [],

"Dewante Freight Terminal Constr.": [

{actId:"DFT-002",activity:"Foundation Works",plannedFinish:"2026-04-
30",forecastFinish:"2026-05-22",delay:22,severity:"critical",type:"Critical
Path",progress:60,owner:"Eng. Solomon"},

{actId:"DFT-003",activity:"Structural Frame — Bay A",plannedFinish:"2026-


06-30",forecastFinish:"2026-07-18",delay:18,severity:"critical",type:"Critical
Path",progress:20,owner:"Eng. Almaz"},

],

"Indode Link-1 Pavement Constr.": [],


"Indode Link-2 Rail Extension": [

{actId:"ILR-002",activity:"Land Acquisition",plannedFinish:"2026-06-
30",forecastFinish:"2026-07-18",delay:18,severity:"critical",type:"Critical
Path",progress:55,owner:"Eng. Alem"},

{actId:"ILR-003",activity:"Earthworks —
Embankment",plannedFinish:"2026-07-31",forecastFinish:"2026-08-
12",delay:12,severity:"warning",type:"Near-Critical",progress:28,owner:"Eng.
Girma"},

],

"Indode Link-1 Rail Extension": [],

"AMG OC Construction": [

{actId:"AOC-002",activity:"Track Survey — Phase 1",plannedFinish:"2026-


06-30",forecastFinish:"2026-07-10",delay:10,severity:"warning",type:"Near-
Critical",progress:50,owner:"Eng. Biruk"},

{actId:"AOC-003",activity:"Earthworks Phase 2",plannedFinish:"2026-08-


31",forecastFinish:"2026-09-10",delay:10,severity:"warning",type:"Near-
Critical",progress:22,owner:"Eng. Hana"},

],

"AMG FY Construction": [

{actId:"AFY-002",activity:"Track Alignment Survey",plannedFinish:"2026-


06-30",forecastFinish:"2026-07-14",delay:14,severity:"critical",type:"Critical
Path",progress:38,owner:"Eng. Tigist"},

{actId:"AFY-003",activity:"Embankment
Construction",plannedFinish:"2026-09-30",forecastFinish:"2026-10-
09",delay:9,severity:"critical",type:"Critical Path",progress:10,owner:"Eng.
Leul"},

],

"Sebeta Power Line Construction": [

{actId:"SPL-004",activity:"Equipment Delivery &


Install",plannedFinish:"2026-07-31",forecastFinish:"2026-08-
06",delay:6,severity:"warning",type:"Near-Critical",progress:35,owner:"Eng.
Yeshi"},
],

};

// ─── INITIALISE GLOBAL PROJECT SELECTOR


─────────────────────────────────────

function _initGlobalProjectSelector() {

const sel = [Link]("sched-global-project");

if (!sel || [Link] > 0) return;

const projNames = [Link]([Link] || {});

[Link](name => {

const opt = [Link]("option");

[Link] = name;

[Link] = name;

[Link](opt);

});

// Also keep the hidden scurve-project-select in sync

const sc = [Link]("scurve-project-select");

if (sc && [Link] === 0) {

[Link](name => {

const opt = [Link]("option");

[Link] = name;

[Link] = name;

[Link](opt);

});

[Link] = window._scurveState ? window._scurveState.project :


projNames[0];
}

function onScheduleProjectChange() {

const projSel = [Link]("sched-global-project");

const viewSel = [Link]("sched-global-view");

if (!projSel || !viewSel) return;

const proj = [Link];

const view = [Link];

// Sync hidden selects

const sc = [Link]("scurve-project-select");

if (sc) [Link] = proj;

const sv = [Link]("scurve-view-select");

if (sv) [Link] = view;

if (window._scurveState) { window._scurveState.project = proj;


window._scurveState.view = view; }

// Refresh all schedule sections for this project

_renderSCurve();

_renderFinancialSCurve();

_renderActivityDashboard();

_renderMilestonesV7();

_renderDelayAnalysisV7();

_renderSchedKPIsV7();

_updateProjectTags();

// Re-render milestones and activity log filtered by selected project

renderPCMilestones();

renderPCActivityByProject();

}
function _updateProjectTags() {

const proj = _getSelectedProject();

const projData = ([Link]||{})[proj];

const finData = ([Link]||{})[proj];

const acts = (window.SCHEDULE_ACTIVITIES||{})[proj]||[];

const delays = (window.DELAY_DATA_BY_PROJECT||{})[proj]||[];

// Physical progress at latest actual

let physPct = "—";

if (projData) {

const ds = [Link];

const lastAct = [Link](d=>[Link]!==null).pop();

if (lastAct) physPct = [Link] + "%";

// SPI: avg actual / avg planned

let spi = "—";

if (projData) {

const ds = [Link];

const actuals = [Link](d=>[Link]!==null);

if ([Link]) {

const avgA = [Link]((s,d)=>s+[Link],0)/[Link];

const avgP = [Link]((s,d)=>s+[Link],0)/[Link];

spi = (avgP>0?(avgA/avgP).toFixed(2):"—");

const critCount = [Link](d=>[Link]==="critical").length;


const statusText = critCount > 0 ? "Critical" : [Link] > 0 ? "At Risk" :
"On Track";

const el = id => [Link](id);

if (el("sched-proj-status-tag")) el("sched-proj-status-tag").textContent =
statusText;

if (el("sched-proj-progress-tag")) el("sched-proj-progress-tag").textContent
= physPct + " Physical";

if (el("sched-proj-spi-tag")) el("sched-proj-spi-tag").textContent = "SPI: " +


spi;

if (el("phys-scurve-proj-label")) el("phys-scurve-proj-label").textContent =
proj;

if (el("fin-scurve-proj-label")) el("fin-scurve-proj-label").textContent = proj;

function _getSelectedProject() {

const sel = [Link]("sched-global-project");

return sel ? [Link] : (window._scurveState ?


window._scurveState.project : "");

function _getSelectedView() {

const sel = [Link]("sched-global-view");

return sel ? [Link] : "monthly";

// ─── KPI STRIP


───────────────────────────────────────────────────────────────

function _renderSchedKPIsV7() {

const proj = _getSelectedProject();

const acts = (window.SCHEDULE_ACTIVITIES||{})[proj]||[];


const delays = (window.DELAY_DATA_BY_PROJECT||{})[proj]||[];

const milestones = (window.MILESTONE_DATA_BY_PROJECT||{})[proj]||[];

const delayed = [Link](a=>[Link]==="delayed"||


[Link]==="critical").length;

const critical = [Link](a=>[Link]==="critical").length;

const avgPct = [Link] ?


[Link]([Link]((s,a)=>s+[Link],0)/[Link]) : 0;

const completedMS = [Link](m=>m.s==="completed").length;

const maxDelay = [Link] ? [Link](...[Link](d=>[Link])) :


0;

const projData = ([Link]||{})[proj];

let spi = 0.94;

if (projData) {

const ds = [Link];

const actuals = [Link](d=>[Link]!==null);

if ([Link]) {

const avgA = [Link]((s,d)=>s+[Link],0)/[Link];

const avgP = [Link]((s,d)=>s+[Link],0)/[Link];

spi = avgP > 0 ? parseFloat((avgA/avgP).toFixed(2)) : 0.94;

const el = id => [Link](id);

if(el("sk-total")) el("sk-total").textContent = [Link];

if(el("sk-delayed")) el("sk-delayed").textContent = delayed;

if(el("sk-critical")) el("sk-critical").textContent = critical;


if(el("sk-progress")) el("sk-progress").textContent = avgPct+"%";

if(el("sk-spi")) el("sk-spi").textContent = [Link](2);

if(el("sk-variance")) el("sk-variance").textContent = maxDelay ?


"-"+maxDelay+"d" : "0d";

if(el("sk-milestones")) el("sk-milestones").textContent =
completedMS+"/"+[Link];

// ─── FINANCIAL S-CURVE


───────────────────────────────────────────────────────

function _renderFinancialSCurve() {

const svg = [Link]("fin-scurve-svg");

if (!svg) return;

const proj = _getSelectedProject();

const viewMode= _getSelectedView();

const projData= ([Link]||{})[proj];

if (!projData) { [Link]=""; return; }

const dataset = projData[viewMode]||[Link];

const n = [Link];

const MONTH_LABELS2 =
["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];

function getLabel(i) {

if(viewMode==="monthly") return MONTH_LABELS2[i]||"";

if(viewMode==="weekly") return "W"+(i+1);

const ms=[0,31,59,90,120,151,181,212,243,273,304,334];

const idx=[Link](i); return idx>=0?MONTH_LABELS2[idx]:"";

}
const todayIdx = viewMode==="monthly"?4:viewMode==="weekly"?
20:140;

const W=720,H=155,padL=42,padR=14,padT=14,padB=28;

const cW=W-padL-padR, cH=H-padT-padB;

const planned = [Link](d=>[Link]);

const actData = [Link]((d,i)=>[Link]!==null?


{i,v:[Link]}:null).filter(Boolean);

const foreData = [Link]((d,i)=>[Link]!


==null&&[Link]===null?{i,v:[Link]}:null).filter(Boolean);

function toX(i){ return padL + (i/(n-1))*cW; }

function toY(v){ return padT + cH - (v/100)*cH; }

// Grid lines

const steps = viewMode==="monthly"?12:viewMode==="weekly"?13:12;

const gridStep = [Link](n/steps);

let gridH="",gridV="";

for(let v=0;v<=100;v+=25) {

const y=toY(v);

gridH+=`<line x1="${padL}" y1="${y}" x2="${W-padR}" y2="${y}"


stroke="#c8d8c8" stroke-width="0.5"/>`;

gridH+=`<text x="${padL-4}" y="${y+3}" text-anchor="end" font-


size="7" fill="#888">${v}%</text>`;

for(let i=0;i<n;i+=gridStep) {

const x=toX(i), lbl=getLabel(i);

if(lbl){
gridV+=`<line x1="${x}" y1="${padT}" x2="${x}" y2="${padT+cH}"
stroke="#d8e8d8" stroke-width="0.5"/>`;

gridV+=`<text x="${x}" y="${H-6}" text-anchor="middle" font-


size="7" fill="#888">${lbl}</text>`;

// Planned line

const planPts = [Link]((v,i)=>toX(i)+","+toY(v)).join(" ");

const planLine= [Link]((v,i)=>(i===0?"M":"L")+toX(i)+"


"+toY(v)).join(" ");

const planAreaPts=toX(0)+","+(padT+cH)+" "+[Link]((v,i)=>toX(i)


+","+toY(v)).join(" ")+" "+toX(n-1)+","+(padT+cH);

// Actual line

let actSvg="", actAreaSvg="";

if([Link]>0){

const path=[Link]((p,i)=>(i===0?"M":"L")+toX(p.i)+"
"+toY(p.v)).join(" ");

const area=toX(0)+","+(padT+cH)+" "+[Link](p=>toX(p.i)


+","+toY(p.v)).join(" ")+" "+toX(actData[[Link]-1].i)+","+
(padT+cH);

actSvg=`<path d="${path}" fill="none" stroke="#2ecc71" stroke-


width="2.5"/>`;

actAreaSvg=`<polygon points="${area}" fill="url(#finActGrad)"/>`;

// Forecast

let forecastSvg="";
if([Link]>0){

const anchor=[Link]>0?actData[[Link]-1]:null;

let fp=anchor?`M${toX(anchor.i)} ${toY(anchor.v)}`:"";

fp+=[Link](p=>`L${toX(p.i)} ${toY(p.v)}`).join(" ");

forecastSvg=`<path d="${fp}" fill="none" stroke="#f39c12" stroke-


width="1.8" stroke-dasharray="5 3"/>`;

// Variance fill

let varSvg="";

if([Link]>0){

const lastI=actData[[Link]-1].i;

const planSeg=[Link](0,lastI+1);

const actSeg=[Link](d=>d.v);

const topPts=[Link]((v,i)=>toX(i)+","+toY(v)).join(" ");

const botPts=[Link]((v,i)=>toX(i)+","+toY(v)).reverse().join(" ");

if(topPts&&botPts) varSvg=`<polygon points="${topPts} ${botPts}"


fill="rgba(231,76,60,.08)"/>`;

// Today marker

const todayX=toX([Link](todayIdx,n-1));

const todaySvg=`<line x1="${todayX}" y1="${padT}" x2="${todayX}"


y2="${padT+cH}" stroke="#e74c3c" stroke-width="1.5" stroke-
dasharray="4 3"/>`

+`<text x="${todayX+3}" y="${padT+8}" font-size="7" fill="#e74c3c"


font-weight="700">TODAY</text>`;
[Link]=

`<defs>`

+`<linearGradient id="finPlanGrad" x1="0" y1="0" x2="0"


y2="1"><stop offset="0%" stop-color="#1a5276"
stop-opacity=".15"/><stop offset="100%" stop-color="#1a5276" stop-
opacity=".03"/></linearGradient>`

+`<linearGradient id="finActGrad" x1="0" y1="0" x2="0" y2="1"><stop


offset="0%" stop-color="#2ecc71" stop-opacity=".20"/><stop
offset="100%" stop-color="#2ecc71"
stop-opacity=".03"/></linearGradient>`

+`</defs>`

+gridH+gridV

+`<polygon points="${planAreaPts}" fill="url(#finPlanGrad)"/>`

+varSvg+actAreaSvg

+`<path d="${planLine}" fill="none" stroke="#1a5276" stroke-


width="2.5" stroke-dasharray="6 3"/>`

+actSvg+forecastSvg+todaySvg;

// Stats

const lastActEntry = [Link]>0?actData[[Link]-1]:null;

const lastPlanVal = lastActEntry?planned[lastActEntry.i]:planned[n-1];

const lastActVal = lastActEntry?lastActEntry.v:null;

const variance = lastActVal!==null?lastActVal-lastPlanVal:null;

const periodLabel = viewMode==="monthly"?


MONTH_LABELS2[lastActEntry?lastActEntry.i:0]+"
2026":viewMode==="weekly"?"Week "+(lastActEntry?
lastActEntry.i+1:1):"Day "+(lastActEntry?lastActEntry.i+1:1);

const statsEl=[Link]("fin-scurve-stats");

if(statsEl){
[Link]=

`<div style="flex:1;min-width:80px;text-align:center;border-right:1px
solid #b0cce8;padding:0 8px"><div style="font-size:16px;font-
weight:800;color:#1a5276">${lastPlanVal}%</div><div style="font-
size:8px;color:#666;font-weight:600">PLANNED FINANCIAL ($
{periodLabel})</div></div>`

+`<div style="flex:1;min-width:80px;text-align:center;border-right:1px
solid #b0cce8;padding:0 8px"><div style="font-size:16px;font-
weight:800;color:#27ae60">${lastActVal!==null?lastActVal+"%":"—"}</
div><div style="font-size:8px;color:#666;font-weight:600">ACTUAL
FINANCIAL (${periodLabel})</div></div>`

+`<div style="flex:1;min-width:80px;text-align:center;border-right:1px
solid #b0cce8;padding:0 8px"><div style="font-size:16px;font-
weight:800;color:${variance!==null?
(variance<0?"#e74c3c":"#27ae60"):"#888"}">${variance!==null?
(variance>0?"+":"")+variance+"%":"—"}</div><div style="font-
size:8px;color:#666;font-weight:600">VARIANCE</div></div>`

+`<div style="flex:1;min-width:80px;text-align:center;padding:0
8px"><div style="font-size:12px;font-weight:800;color:$
{variance===null?"#888":variance<-
5?"#e74c3c":variance<0?"#f39c12":"#27ae60"}">${variance===null?"No
Data":variance<-5?"🔴 Behind Spend":variance<0?"🟡 Slightly Behind":"🟢 On
Budget"}</div><div style="font-size:8px;color:#666;font-
weight:600">FINANCIAL STATUS</div></div>`;

// ─── ACTIVITY PERFORMANCE DASHBOARD


─────────────────────────────────────────

function renderActivityDashboard() { _renderActivityDashboard(); }

function _renderActivityDashboard() {

const proj = _getSelectedProject();

const acts = (window.SCHEDULE_ACTIVITIES||{})[proj]||[];


const search = ([Link]("act-search")||{}).value||"";

const filter = ([Link]("act-status-filter")||


{}).value||"all";

const tbody = [Link]("activity-dashboard-tbody");

if (!tbody) return;

const filtered = [Link](a => {

const matchSearch = !search ||


[Link]().includes([Link]()) ||
[Link]().includes([Link]());

const matchStatus = filter==="all" || [Link]===filter;

return matchSearch && matchStatus;

});

const statusLabel = {completed:"Completed","in-progress":"In


Progress",upcoming:"Upcoming",delayed:"Delayed",critical:"Critical"};

[Link] = [Link](a => {

const varColor =
[Link]===0?"#555":[Link]>0?"#27ae60":"#e74c3c";

const varTxt =
[Link]===0?"0d":[Link]>0?"+"+[Link]+"d":[Link]+"d";

return `<tr>

<td title="${[Link]}">${[Link]>30?
[Link](0,28)+"..":[Link]}</td>

<td style="color:#0a3d1f;font-weight:700">${[Link]}</td>

<td>${[Link]}</td>

<td>${[Link]}</td>

<td>

<div style="display:flex;align-items:center;gap:4px">
<div style="width:50px;height:7px;background:#e8f0e8;border-
radius:3px;overflow:hidden">

<div style="width:${[Link]}%;height:100%;background:$
{[Link]>=80?"#27ae60":[Link]>=40?"#f39c12":"#2980b9"};border-
radius:3px"></div>

</div>

<span
style="font-weight:700;color:#0a3d1f">${[Link]}%</span>

</div>

</td>

<td>

<div style="display:flex;align-items:center;gap:4px">

<div style="width:50px;height:7px;background:#e8eef8;border-
radius:3px;overflow:hidden">

<div style="width:${[Link]}
%;height:100%;background:#1a5276;border-radius:3px"></div>

</div>

<span style="font-weight:700;color:#1a5276">${[Link]}%</span>

</div>

</td>

<td><span class="act-status ${[Link]}">${statusLabel[[Link]]||


[Link]}</span></td>

<td style="color:${varColor};font-weight:700">${varTxt}</td>

<td style="font-size:8px;color:#555">${[Link]||"—"}</td>

</tr>`;

}).join("") || `<tr><td colspan="9" style="text-


align:center;color:#888;padding:16px;font-size:10px">No activities found for
this project.</td></tr>`;

// Summary strip
const strip = [Link]("activity-summary-strip");

if (strip) {

const counts = {completed:0,"in-


progress":0,upcoming:0,delayed:0,critical:0};

[Link](a=>{ if(counts[[Link]]!==undefined) counts[[Link]]+


+; });

const cfg = [

["completed","✅ Completed","#d4efdf","#1e8449"],

["in-progress","🔵 In Progress","#d6eaf8","#1a5276"],

["upcoming","⬜ Upcoming","#eaecee","#555"],

["delayed","⚠ Delayed","#fdebd0","#d35400"],

["critical","🔴 Critical","#fadbd8","#c0392b"],

];

[Link] = [Link](([k,lbl,bg,col])=>`<div style="background:$


{bg};border-radius:4px;padding:4px 10px;font-size:9px;font-
weight:700;color:${col}">${lbl}: ${counts[k]}</div>`).join("");

// ─── MILESTONE & ACTIVITY DASHBOARD


─────────────────────────────────────────

function _renderMilestonesV7() {

const proj = _getSelectedProject();

const milestones = (window.MILESTONE_DATA_BY_PROJECT||{})[proj]||[];

const acts = (window.SCHEDULE_ACTIVITIES||{})[proj]||[];

const sm = [Link]("sched-milestones");

if (!sm) return;
if (editMode) {

const btn = [Link]("add-milestone-btn");

if (btn) [Link]="";

const actById = {};

[Link](a => actById[[Link]] = a);

function msGroup(title, items, cls) {

if (![Link]) return "";

let html = `<div class="ms-group-hdr ${cls}">${title} <span


style="background:rgba(0,0,0,.12);border-radius:8px;padding:1px 7px;font-
size:9px">${[Link]}</span></div>`;

[Link]((m,idx) => {

const variance = [Link] - [Link];

const varColor = variance>=0?"#1e8449":"#c0392b";

const daysRemTxt = [Link]>0 ? [Link]+"d remaining" :


[Link]===0 ? "Due Today" : [Link]([Link])+"d ago";

// Related activities

const relActs = ([Link]||[]).map(aid => actById[aid]).filter(Boolean);

const actChips = [Link](a=>`<span class="ms-activity-chip"


title="${[Link]} — ${[Link]}% physical">${[Link]}:
${[Link]}%</span>`).join("");

html += `<div class="ms-row" style="flex-direction:column;align-


items:stretch;gap:4px;padding-bottom:8px">

<div style="display:flex;align-items:center;gap:7px">

<div class="ms-icon $
{cls==='completed'?'completed':cls==='ongoing'?'in-
progress':'planned'}">${cls==='completed'?'✅':cls==='ongoing'?'🔵':'⬜'}</
div>

<div class="ms-content">

<div class="ms-name">${m.m}</div>

<div class="ms-meta">Due: ${[Link]} · ${daysRemTxt}</div>

</div>

<span class="ms-status-badge $
{cls==='completed'?'completed':cls==='ongoing'?'in-
progress':'planned'}">$
{cls==='completed'?'Completed':cls==='ongoing'?'In
Progress':'Upcoming'}</span>

${editMode?`<button class="edit-btn" style="margin-left:4px;font-


size:8px;padding:1px 5px" onclick="toast('Edit milestone: $
{m.m}')">✏</button>`:""}

</div>

${cls!=='planned'?`<div style="padding-left:33px">

<div style="display:flex;gap:12px;font-size:9px;margin-bottom:4px">

<span>Planned: <b
style="color:#2980b9">${[Link]}%</b></span>

<span>Actual: <b
style="color:#27ae60">${[Link]}%</b></span>

${cls==='ongoing'?`<span>Variance: <b style="color:$


{varColor}">${variance>=0?"+":""}${variance}%</b></span>`:""}

</div>

<div style="height:6px;background:#e8f0e8;border-
radius:3px;overflow:hidden;margin-bottom:4px">

<div style="height:100%;width:${[Link]}%;background:$
{variance<-10?"#e74c3c":"#27ae60"};border-radius:3px"></div>

</div>

${actChips?`<div style="margin-top:3px">${actChips}</div>`:""}
</div>`:`<div style="padding-left:33px;font-
size:8px;color:#888">Planned Start: ${[Link]}${actChips?`<div
style="margin-top:3px">${actChips}</div>`:""}</div>`}

</div>`;

});

return html;

const completed = [Link](m=>m.s==="completed");

const ongoing = [Link](m=>m.s==="in-progress");

const upcoming = [Link](m=>m.s==="planned");

[Link] =

msGroup("✅ COMPLETED MILESTONES", completed, "completed") +

msGroup("🔵 ONGOING MILESTONES", ongoing, "ongoing") +

msGroup("⬜ UPCOMING MILESTONES", upcoming, "upcoming") +

([Link]===0?`<div style="text-
align:center;color:#888;padding:20px;font-size:11px">No milestone data for
this project. Upload a schedule to populate.</div>`:"");

// ─── DELAY & CRITICAL ACTIVITIES v7


─────────────────────────────────────────

function _renderDelayAnalysisV7() {

const proj = _getSelectedProject();

const delays = (window.DELAY_DATA_BY_PROJECT||{})[proj]||[];

const da = [Link]("delay-analysis");

if (!da) return;
const critCount = [Link](d=>[Link]==="critical").length;

const warnCount = [Link](d=>[Link]==="warning").length;

const okCount = ((window.SCHEDULE_ACTIVITIES||{})[proj]||[]).length -


[Link];

let html = `<div style="display:flex;gap:6px;margin-bottom:8px;flex-


wrap:wrap">

<div style="flex:1;min-width:70px;background:#fdf3f3;border:1px solid


#fadbd8;border-radius:4px;padding:6px 8px;text-align:center">

<div style="font-size:18px;font-weight:800;color:#c0392b">$
{critCount}</div>

<div
style="font-size:8px;font-weight:700;color:#c0392b">CRITICAL</div>

</div>

<div style="flex:1;min-width:70px;background:#fffbf0;border:1px solid


#fdebd0;border-radius:4px;padding:6px 8px;text-align:center">

<div style="font-size:18px;font-weight:800;color:#d35400">$
{warnCount}</div>

<div
style="font-size:8px;font-weight:700;color:#d35400">WARNING</div>

</div>

<div style="flex:1;min-width:70px;background:#f4f9f2;border:1px solid


#c8d8c8;border-radius:4px;padding:6px 8px;text-align:center">

<div style="font-size:18px;font-weight:800;color:#0a3d1f">$
{[Link](0,okCount)}</div>

<div style="font-size:8px;font-weight:700;color:#1e8449">ON
TRACK</div>

</div>

</div>`;
if ([Link] === 0) {

html += `<div style="text-align:center;padding:20px;font-


size:10px;color:#888">🟢 No delays or critical activities for this
project.</div>`;

} else {

html += `<div style="overflow-x:auto"><table class="delay-tbl">

<thead><tr>

<th>Activity</th><th>ID</th><th>Planned Finish</th><th>Forecast
Finish</th>

<th>Delay</th><th>Criticality</th><th>Progress</th><th>Owner</th>

</tr></thead><tbody>

${[Link](d=>`<tr>

<td style="font-size:8px;max-width:120px;overflow:hidden;text-
overflow:ellipsis;white-space:nowrap"
title="${[Link]}">${[Link]}</td>

<td style="font-weight:700;color:#7b241c">${[Link]}</td>

<td>${[Link]}</td>

<td style="color:#c0392b;font-weight:700">${[Link]}</td>

<td><span style="background:$
{[Link]==="critical"?"#fadbd8":"#fdebd0"};color:$
{[Link]==="critical"?"#c0392b":"#d35400"};border-
radius:8px;padding:2px 7px;font-weight:800;font-size:8px">+$
{[Link]}d</span></td>

<td><span class="bdg ${[Link]==="critical"?"r":"o"}"


style="font-size:8px">${[Link]}</span></td>

<td>

<div style="display:flex;align-items:center;gap:3px">

<div style="width:40px;height:7px;background:#e8f0e8;border-
radius:3px;overflow:hidden">
<div style="width:${[Link]}%;height:100%;background:$
{[Link]==="critical"?"#e74c3c":"#f39c12"};border-radius:3px"></div>

</div>

<span
style="font-size:8px;font-weight:700">${[Link]}%</span>

</div>

</td>

<td style="font-size:8px;color:#555">${[Link]||"—"}</td>

</tr>`).join("")}

</tbody></table></div>`;

[Link] = html;

// ─── IMPORT HANDLERS FOR NEW UPLOAD BUTTONS


──────────────────────────────────

function importMasterSchedule(input) {

const file = [Link][0]; if(!file) return;

toast("📂 Schedule file '"+[Link]+"' received. Parsing & refreshing


dashboards…");

setTimeout(()=>{ toast("✅ Schedule imported successfully! All dashboards


updated."); onScheduleProjectChange(); }, 1200);

[Link] = "";

function importActivitySchedule(input) { importMasterSchedule(input); }

function importMilestoneSchedule(input) { importMasterSchedule(input); }

function importDelaySchedule(input) { importMasterSchedule(input); }


function renderSchedule() {

_initGlobalProjectSelector();

_renderGantt2026();

_renderSCurve();

_renderFinancialSCurve();

_renderActivityDashboard();

_renderMilestonesV7();

_renderDelayAnalysisV7();

_renderSchedKPIsV7();

_updateProjectTags();

populatePCActivityFilter();

renderPCMilestones();

renderPCActivityByProject();

function _renderSchedKPIs() {

const delayed =
GANTT_PROJECTS_2026.filter(p=>[Link]==="Delayed"||
[Link]==="Critical").length;

const critical =
DELAY_ITEMS_2026.filter(d=>[Link]==="critical").length;

const avgPct =
[Link](GANTT_PROJECTS_2026.reduce((s,p)=>s+[Link],0)/GANTT_PROJE
CTS_2026.length);

const completed =
MILESTONES_2026.filter(m=>m.s==="completed").length;

const el = id => [Link](id);

if(el("sk-total")) el("sk-total").textContent =
GANTT_PROJECTS_2026.length;
if(el("sk-delayed")) el("sk-delayed").textContent = delayed;

if(el("sk-critical")) el("sk-critical").textContent = critical;

if(el("sk-progress")) el("sk-progress").textContent = avgPct+"%";

if(el("sk-milestones")) el("sk-milestones").textContent =
completed+"/"+MILESTONES_2026.length;

function _renderGantt2026() {

const hdr = [Link]("gantt-months-hdr");

if(hdr) {

[Link] = "g26-hdr";

[Link] = MONTH_LABELS.map(m=>`<div class="g26-mon">$


{m}</div>`).join("");

const leg = [Link]("g26-legend");

if(leg) [Link] = `

<div class="g26-leg-item"><div class="g26-leg-dot"


style="background:#27ae60"></div>On Track</div>

<div class="g26-leg-item"><div class="g26-leg-dot"


style="background:#f39c12"></div>Delayed</div>

<div class="g26-leg-item"><div class="g26-leg-dot"


style="background:#e74c3c"></div>Critical</div>

<div class="g26-leg-item"><div class="g26-leg-dot"


style="background:#d35400"></div>At Risk</div>

<div class="g26-leg-item"><div class="g26-leg-dot"


style="background:#2980b9"></div>Completed</div>

<div class="g26-leg-item"><div class="g26-leg-dot"


style="background:#bdc3c7"></div>Not Started</div>
<div class="g26-leg-item"><div
style="width:12px;height:5px;background:#555;opacity:.4;border-
radius:2px"></div>Baseline</div>

<div class="g26-leg-item"><div
style="width:12px;height:12px;background:#e74c3c;border-
radius:50%;border:2px solid #fff"></div>Milestone</div>`;

const gc = [Link]("gantt-chart");

if(!gc) return;

// Today marker: May 2026 ≈ month index 4.9

const todayPct = (4.9/12*100).toFixed(1);

// Build rows

let html = "";

GANTT_PROJECTS_2026.forEach((p,i) => {

const leftPct = ([Link]/12*100).toFixed(2);

const widthPct = ([Link]/12*100).toFixed(2);

const blLeftPct= (p.baseline_start/12*100).toFixed(2);

const blWidthPct=(p.baseline_dur/12*100).toFixed(2);

const barColor = STATUS_COLORS_2026[[Link]] || [Link];

const isCritical = [Link];

const ms = MILESTONES_2026.filter(m=>[Link]([Link](" ")


[0]));

// Grid lines

let gridLines = "";

for(let m=1;m<12;m++) gridLines += `<div class="g26-grid-line"


style="left:${(m/12*100).toFixed(1)}%"></div>`;
// Milestone dots

let msDots = [Link](mil=>{

const milMonth = MONTH_LABELS.indexOf([Link](" ")[0]);

if(milMonth<0) return "";

const milPct = ((milMonth+0.5)/12*100).toFixed(1);

const dotColor = mil.s==="completed"?"#27ae60":mil.s==="in-


progress"?"#2980b9":"#e74c3c";

return `<div class="g26-milestone-dot" style="left:${milPct}


%;background:${dotColor}" title="◆ ${mil.m} — ${[Link]}"></div>`;

}).join("");

// Critical path overlay

const cpOverlay = isCritical ? `<div class="g26-cp-badge"></div>` : "";

html += `<div class="g26-row" onmouseover="showG26Tooltip(event,'$


{[Link]}','${[Link]}',${[Link]},'${[Link]||'Dec 2026'}')"
onmouseout="hideG26Tooltip()">

<div class="g26-lbl" title="${[Link]}">${isCritical?'🔴 ':''}<span


style="color:${barColor}">${[Link]}</span></div>

<div class="g26-track" style="position:relative">

${gridLines}

<div class="g26-today-line" style="left:${todayPct}%"></div>

<div class="g26-bar" style="left:${leftPct}%;width:${widthPct}


%;background:linear-gradient(90deg,${barColor}dd,${barColor}99)"

onclick="showG26Tooltip(event,'${[Link]}','${[Link]}',$
{[Link]},'Dec 2026')">

${cpOverlay}

${[Link]>8?[Link]+'%':''}
</div>

<div class="g26-baseline" style="left:${blLeftPct}%;width:$


{blWidthPct}%;background:#555;bottom:-4px"></div>

${msDots}

<div class="g26-pct-badge" style="left:${(parseFloat(leftPct)


+parseFloat(widthPct)+1)}%">${[Link]}%</div>

</div>

${editMode?`<button class="edit-btn" style="margin-left:42px;font-


size:8px;padding:1px 5px" onclick="openModal('edit-task',$
{i+1})">✏</button>`:''}

</div>`;

});

// Also render original TASKS if any were added via import

if(TASKS && [Link]) {

[Link](g=>{

const left=([Link]/12*100).toFixed(1);

const width=([Link]/12*100).toFixed(1);

html += `<div class="g26-row">

<div class="g26-lbl" title="${[Link]}" style="font-


style:italic;color:#888">${[Link]}</div>

<div class="g26-track" style="position:relative">

<div class="g26-bar" style="left:${left}%;width:${width}


%;background:${[Link]}">${[Link]>0?[Link]+'%':''}</div>

</div>

${editMode?`<button class="edit-btn" style="margin-left:42px;font-


size:8px;padding:1px 5px" onclick="openModal('edit-task',$
{[Link]})">✏</button>`:''}

</div>`;
});

[Link] = html;

function showG26Tooltip(e, name, status, pct, due) {

const tip = [Link]("g26-tooltip");

if(!tip) return;

const sc = STATUS_COLORS_2026[status]||"#555";

[Link] = `<div style="font-weight:800;margin-bottom:4px;font-


size:11px">${name}</div>

<div>Status: <span
style="color:${sc};font-weight:700">${status}</span></div>

<div>Physical Progress: <strong>${pct}%</strong></div>

<div>Planned Completion: <strong>${due}</strong></div>`;

[Link] = "block";

[Link] = [Link]([Link]+12, [Link]-240)+"px";

[Link] = ([Link]-40)+"px";

function hideG26Tooltip() {

const tip = [Link]("g26-tooltip");

if(tip) [Link]="none";

//
═══════════════════════════════════════════════════════
════════
// S-CURVE CONTROLS — populate dropdowns & handle changes
//
═══════════════════════════════════════════════════════
════════

function _initSCurveControls() {

var sel = [Link]("scurve-project-select");

if (!sel || [Link] > 0) return; // already populated

// Derive project list dynamically from projectProgressData keys

[Link]([Link] || {}).forEach(function(name) {

var opt = [Link]("option");

[Link] = name;

[Link] = name;

[Link](opt);

});

// Restore previously selected values (survives tab navigation)

var state = window._scurveState;

if (state) {

[Link] = [Link];

var viewSel = [Link]("scurve-view-select");

if (viewSel) [Link] = [Link];

function onSCurveControlChange() {

var projSel = [Link]("scurve-project-select");


var viewSel = [Link]("scurve-view-select");

if (!projSel || !viewSel) return;

// Persist selection

window._scurveState.project = [Link];

window._scurveState.view = [Link];

// Sync global selectors

var gp = [Link]("sched-global-project");

var gv = [Link]("sched-global-view");

if (gp) [Link] = [Link];

if (gv) [Link] = [Link];

_renderSCurve();

if (typeof _renderFinancialSCurve === "function") _renderFinancialSCurve();

if (typeof _renderActivityDashboard === "function")


_renderActivityDashboard();

if (typeof _renderMilestonesV7 === "function") _renderMilestonesV7();

if (typeof _renderDelayAnalysisV7 === "function")


_renderDelayAnalysisV7();

if (typeof _renderSchedKPIsV7 === "function") _renderSchedKPIsV7();

if (typeof _updateProjectTags === "function") _updateProjectTags();

//
═══════════════════════════════════════════════════════
════════
// _renderSCurve — main chart renderer

//
═══════════════════════════════════════════════════════
════════
function _renderSCurve() {

_initSCurveControls();

var svg = [Link]("scurve-svg");

if (!svg) return;

// ── Read current selections ────────────────────────────────

var state = window._scurveState;

var projectKey = [Link];

var viewMode = [Link]; // "monthly" | "weekly" | "daily"

var projData = ([Link] || {})[projectKey];

if (!projData) return;

var dataset = projData[viewMode] || [Link];

var n = [Link];

// ── Axis label generators ──────────────────────────────────

function getLabel(i) {

if (viewMode === "monthly") {

return MONTH_LABELS[i] || "";

} else if (viewMode === "weekly") {

return "W" + (i + 1);

} else {

// Daily: show month boundary labels to avoid overclutter

var monthStarts = [0,31,59,90,120,151,181,212,243,273,304,334];

var idx = [Link](i);


return idx >= 0 ? MONTH_LABELS[idx] : "";

// TODAY marker index

var todayIdx = viewMode === "monthly" ? 4

: viewMode === "weekly" ? 20

: 140;

// ── Chart geometry ─────────────────────────────────────────

var W = 720, H = 180, padL = 42, padR = 14, padT = 16, padB = 32;

var chartW = W - padL - padR;

var chartH = H - padT - padB;

function toX(i) { return padL + (i / (n - 1)) * chartW; }

function toY(v) { return padT + chartH - (v / 100) * chartH; }

// ── Separate planned / actual / forecast arrays ────────────

var planned = [Link](function(d) { return [Link]; });

var actual = [Link](function(d) { return [Link]; });

var forecast = [Link](function(d) { return [Link]; });

var actData = [Link](function(d, i) { return { v: [Link], i:


i }; }).filter(function(d) { return d.v !== null; });

var foreData = [Link](function(d, i) { return { v: [Link], i:


i }; }).filter(function(d) { return d.v !== null; });
// ── Decide x-tick density based on view mode ──────────────

// Daily: show only month-boundary ticks; Weekly: every 4; Monthly: every 1

var tickStep = viewMode === "daily" ? 1 : 1; // used below per-label

function shouldShowTick(i) {

if (viewMode === "monthly") return true;

if (viewMode === "weekly") return i % 4 === 0;

// daily: show only at month starts

var monthStarts = [0,31,59,90,120,151,181,212,243,273,304,334];

return [Link](i) >= 0;

// ── Grid ──────────────────────────────────────────────────

var gridH = "", gridV = "";

for (var y = 0; y <= 100; y += 20) {

var yy = toY(y);

gridH += '<line x1="' + padL + '" y1="' + yy + '" x2="' + (padL +


chartW) + '" y2="' + yy + '" stroke="#e0e8e0" stroke-width="1"/>';

gridH += '<text x="' + (padL - 4) + '" y="' + (yy + 3) + '" text-


anchor="end" font-size="9" fill="#888">' + y + '%</text>';

for (var i = 0; i < n; i++) {

if (!shouldShowTick(i)) continue;

var xx = toX(i);

gridV += '<line x1="' + xx + '" y1="' + padT + '" x2="' + xx + '" y2="' +
(padT + chartH) + '" stroke="#e8f0e8" stroke-width="1"/>';

var lbl = getLabel(i);

if (lbl) {
gridV += '<text x="' + xx + '" y="' + (padT + chartH + 12) + '" text-
anchor="middle" font-size="9" fill="#555">' + lbl + '</text>';

// ── Planned area + line ────────────────────────────────────

var planPts = [Link](function(v, i) { return toX(i) + "," +


toY(v); }).join(" ");

var planAreaPts = padL + "," + (padT + chartH) + " " + planPts + " " +
(padL + chartW) + "," + (padT + chartH);

var planLine = [Link](function(v, i) { return (i === 0 ? "M" : "L") +


toX(i) + "," + toY(v); }).join(" ");

// ── Actual area + line ─────────────────────────────────────

var actSvg = "", actAreaSvg = "";

if ([Link] > 0) {

var actPts = [Link](function(d) { return toX(d.i) + "," +


toY(d.v); }).join(" ");

var lastActPt = actData[[Link] - 1];

var actAreaPts = padL + "," + (padT + chartH) + " " + actPts + " " +
toX(lastActPt.i) + "," + (padT + chartH);

var actLine = [Link](function(d, j) { return (j === 0 ? "M" : "L") +


toX(d.i) + "," + toY(d.v); }).join(" ");

actAreaSvg = '<polygon points="' + actAreaPts + '"


fill="url(#actGrad)"/>';

actSvg = '<path d="' + actLine + '" fill="none" stroke="#27ae60"


stroke-width="2.5"/>';

// ── Variance fill ──────────────────────────────────────────


var varSvg = "";

if ([Link] > 0) {

var lastActIdx = actData[[Link] - 1].i;

var varPts = [];

for (var k = 0; k <= lastActIdx; k++) [Link](toX(k) + "," +


toY(planned[k]));

for (var k = lastActIdx; k >= 0; k--) { if (actual[k] !== null)


[Link](toX(k) + "," + toY(actual[k])); }

varSvg = '<polygon points="' + [Link](" ") + '" fill="#e74c3c" fill-


opacity=".10"/>';

// ── Forecast dashed line ───────────────────────────────────

var forecastSvg = "";

if ([Link] > 1) {

var foreLine = [Link](function(d, j) { return (j === 0 ? "M" : "L") +


toX(d.i) + "," + toY(d.v); }).join(" ");

forecastSvg = '<path d="' + foreLine + '" fill="none" stroke="#8e44ad"


stroke-width="2" stroke-dasharray="5 4" opacity=".8"/>';

// ── Today line ─────────────────────────────────────────────

var todayX = toX([Link](todayIdx, n - 1));

var todaySvg = '<line x1="' + todayX + '" y1="' + padT + '" x2="' +
todayX + '" y2="' + (padT + chartH) + '" stroke="#e74c3c" stroke-
width="2" stroke-dasharray="4 3"/>'

+ '<text x="' + (todayX + 4) + '" y="' + (padT + 10) + '" font-


size="8" fill="#e74c3c" font-weight="800">TODAY</text>';
// ── Data dots on actual (skip for daily — too many) ────────

var dotsSvg = "";

if (viewMode !== "daily") {

dotsSvg = [Link](function(d) {

return '<circle cx="' + toX(d.i) + '" cy="' + toY(d.v) + '" r="4"


fill="#27ae60" stroke="#fff" stroke-width="1.5"/>'

+ '<text x="' + toX(d.i) + '" y="' + (toY(d.v) - 7) + '" text-


anchor="middle" font-size="8" fill="#1e8449" font-weight="700">' + d.v +
'%</text>';

}).join("");

} else {

// Daily: one dot at today position only

if ([Link] > 0) {

var lastD = actData[[Link] - 1];

dotsSvg = '<circle cx="' + toX(lastD.i) + '" cy="' + toY(lastD.v) + '"


r="5" fill="#27ae60" stroke="#fff" stroke-width="2"/>'

+ '<text x="' + toX(lastD.i) + '" y="' + (toY(lastD.v) - 8) + '" text-


anchor="middle" font-size="8" fill="#1e8449" font-weight="700">' +
lastD.v + '%</text>';

// ── Tooltip overlay (invisible rects for hover on daily) ───

// For monthly/weekly the dots are visible; for daily we add a scanline
overlay

var tooltipSvg = "";

if (viewMode === "daily") {

// Semi-transparent scanline every 10 days for tooltip interaction


tooltipSvg = '<rect id="scurve-hover-overlay" x="' + padL + '" y="' +
padT + '" width="' + chartW + '" height="' + chartH + '" fill="transparent" '

+ 'onmousemove="scurveMouseMove(event,' + n + ',' + padL + ',' +


chartW + ')" onmouseleave="scurveHideTooltip()"/>';

// ── Assemble SVG ───────────────────────────────────────────

[Link] =

'<defs>'

+ '<linearGradient id="planGrad" x1="0" y1="0" x2="0" y2="1">'

+ ' <stop offset="0%" stop-color="#2980b9" stop-opacity=".18"/>'

+ ' <stop offset="100%" stop-color="#2980b9" stop-opacity=".04"/>'

+ '</linearGradient>'

+ '<linearGradient id="actGrad" x1="0" y1="0" x2="0" y2="1">'

+ ' <stop offset="0%" stop-color="#27ae60" stop-opacity=".22"/>'

+ ' <stop offset="100%" stop-color="#27ae60" stop-opacity=".04"/>'

+ '</linearGradient>'

+ '</defs>'

+ gridH + gridV

+ '<polygon points="' + planAreaPts + '" fill="url(#planGrad)"/>'

+ varSvg

+ actAreaSvg

+ '<path d="' + planLine + '" fill="none" stroke="#2980b9" stroke-


width="2.5" stroke-dasharray="6 3"/>'

+ actSvg

+ forecastSvg

+ todaySvg

+ dotsSvg
+ tooltipSvg;

// Store dataset reference for tooltip access

svg._scDataset = dataset;

svg._scPadL = padL;

svg._scChartW = chartW;

svg._scPadT = padT;

svg._scChartH = chartH;

svg._scN = n;

svg._scGetLabel = getLabel;

svg._scViewMode = viewMode;

// ── Stats cards ────────────────────────────────────────────

var lastActEntry = [Link] > 0 ? actData[[Link] - 1] : null;

var lastPlanVal = lastActEntry ? planned[lastActEntry.i] :


planned[[Link] - 1];

var lastActVal = lastActEntry ? lastActEntry.v : null;

var variance = lastActVal !== null ? lastActVal - lastPlanVal : null;

// Period label for the stat cards

var periodLabel;

if (viewMode === "monthly") {

periodLabel = MONTH_LABELS[lastActEntry ? lastActEntry.i : 0] + " 2026";

} else if (viewMode === "weekly") {

periodLabel = "Week " + (lastActEntry ? lastActEntry.i + 1 : 1);

} else {

periodLabel = "Day " + (lastActEntry ? lastActEntry.i + 1 : 1);


}

var statusText, statusColor;

if (variance === null) {

statusText = "No Data"; statusColor = "#888";

} else if (variance < -5) {

statusText = "🔴 Behind"; statusColor = "#e74c3c";

} else if (variance < 0) {

statusText = "🟡 Slightly Behind"; statusColor = "#f39c12";

} else if (variance === 0) {

statusText = "🟢 On Track"; statusColor = "#27ae60";

} else {

statusText = "🟢 Ahead"; statusColor = "#1e8449";

var statsEl = [Link]("scurve-stats");

if (statsEl) {

[Link] =

'<div style="flex:1;min-width:80px;text-align:center;border-right:1px
solid #c8d8c8;padding:0 8px">'

+ ' <div style="font-size:16px;font-weight:800;color:#2980b9">' +


lastPlanVal + '%</div>'

+ ' <div style="font-size:8px;color:#666;font-weight:600">PLANNED (' +


periodLabel + ')</div>'

+ '</div>'

+ '<div style="flex:1;min-width:80px;text-align:center;border-right:1px
solid #c8d8c8;padding:0 8px">'
+ ' <div style="font-size:16px;font-weight:800;color:#27ae60">' +
(lastActVal !== null ? lastActVal + "%" : "—") + '</div>'

+ ' <div style="font-size:8px;color:#666;font-weight:600">ACTUAL (' +


periodLabel + ')</div>'

+ '</div>'

+ '<div style="flex:1;min-width:80px;text-align:center;border-right:1px
solid #c8d8c8;padding:0 8px">'

+ ' <div style="font-size:16px;font-weight:800;color:' + (variance !==


null ? (variance < 0 ? "#e74c3c" : "#27ae60") : "#888") + '">'

+ (variance !== null ? (variance > 0 ? "+" : "") + variance + "%" : "—")

+ ' </div>'

+ ' <div
style="font-size:8px;color:#666;font-weight:600">VARIANCE</div>'

+ '</div>'

+ '<div style="flex:1;min-width:80px;text-align:center;padding:0 8px">'

+ ' <div style="font-size:13px;font-weight:800;color:' + statusColor +


'">' + statusText + '</div>'

+ ' <div
style="font-size:8px;color:#666;font-weight:600">STATUS</div>'

+ '</div>';

// ── Daily-mode hover tooltip ────────────────────────────────────

function scurveMouseMove(evt, n, padL, chartW) {

var svg = [Link]("scurve-svg");

if (!svg || !svg._scDataset) return;

var rect = [Link]();

var svgW = [Link];


var relX = [Link] - [Link];

var frac = (relX - padL * svgW / 720) / (chartW * svgW / 720);

var idx = [Link](frac * (n - 1));

idx = [Link](0, [Link](n - 1, idx));

var d = svg._scDataset[idx];

if (!d) return;

var lbl = svg._scGetLabel(idx) || (svg._scViewMode === "daily" ? "Day "


+ (idx + 1) : "");

var tip = [Link]("scurve-tooltip");

if (!tip) return;

var variance = [Link] !== null ? ([Link] - [Link]) : null;

[Link] =

'<div style="font-weight:800;margin-bottom:3px;color:#0a3d1f">' + lbl +


'</div>'

+ '<div style="font-size:10px">📐 Planned: <strong>' + [Link] +


'%</strong></div>'

+ ([Link] !== null ? '<div style="font-size:10px">📍 Actual: <strong


style="color:#27ae60">' + [Link] + '%</strong></div>' : '')

+ ([Link] !== null && [Link] === null ? '<div style="font-


size:10px">🔮 Forecast: <strong style="color:#8e44ad">' + [Link] +
'%</strong></div>' : '')

+ (variance !== null ? '<div style="font-size:10px">Δ Variance: <strong


style="color:' + (variance < 0 ? "#e74c3c" : "#27ae60") + '">' + (variance
> 0 ? "+" : "") + variance + '%</strong></div>' : '');

[Link] = "block";

[Link] = [Link]([Link] + 14, [Link] - 180) + "px";

[Link] = ([Link] - 60) + "px";

}
function scurveHideTooltip() {

var tip = [Link]("scurve-tooltip");

if (tip) [Link] = "none";

function _renderMilestones2026() {

const sm = [Link]("sched-milestones");

if(!sm) return;

if(editMode) {

const btn = [Link]("add-milestone-btn");

if(btn) [Link]="";

const statusIcon = {completed:"✅","in-


progress":"🔵",planned:"⬜",critical:"🔴"};

[Link] = ([Link]||
MILESTONES_2026).map((m,idx)=>{

const s = m.s||"planned";

const iconClass = s==="completed"?"completed":s==="in-progress"?"in-


progress":[Link]<30&&[Link]>0?"critical":"planned";

return `<div class="ms-row">

<div class="ms-icon ${iconClass}">${statusIcon[iconClass]||"⬜"}</div>

<div class="ms-content">

<div class="ms-name" title="${m.m}">${m.m}</div>

<div class="ms-meta">${[Link]||""} · ${[Link]||m.d||""}</div>

</div>

<span class="ms-status-badge ${iconClass}">${s==="in-progress"?"In


Progress":[Link](0).toUpperCase()+[Link](1)}</span>
${editMode?`<button class="edit-btn" style="margin-left:4px;font-
size:8px;padding:1px 5px" onclick="editMilestone($
{idx})">✏</button><button class="edit-btn red" style="margin-
left:2px;font-size:8px;padding:1px 5px" onclick="deleteMilestone($
{idx})">✕</button>`:""}

</div>`;

}).join("") + (editMode?`<button class="add-btn" onclick="addMilestone()"


style="width:100%;margin-top:6px;font-size:9px;padding:4px">+ Add
Milestone</button>`:"");

function _renderPhases2026() {

// Phase cards grid

const pg = [Link]("phase-grid");

if(pg) {

const
statusLabels={completed:"Completed",active:"Active",pending:"Pending",del
ayed:"Delayed"};

const
statusColors={completed:"#2980b9",active:"#27ae60",pending:"#bdc3c7",
delayed:"#e74c3c"};

[Link] = PHASES_2026.map(ph=>`

<div class="phase-card ${[Link]}">

<div class="phase-card-title">${[Link]}</div>

<div class="phase-card-pct" style="color:$


{statusColors[[Link]]}">${[Link]}%</div>

<div class="phase-bar-bg"><div class="phase-bar-fill" style="width:$


{[Link]}%;background:${statusColors[[Link]]}"></div></div>

<div class="phase-card-status" style="color:$


{statusColors[[Link]]}">${statusLabels[[Link]]||[Link]}</div>

</div>`).join("");
}

// Per-project phase bars

const sp = [Link]("sched-phases");

if(sp) {

const phaseOrder=["Survey & Investigation","Design","Procurement","Civil


Works","Track Works","Electrical & Systems","Testing &
Commissioning","Final Handover"];

const
phaseColors=["#27ae60","#2980b9","#1abc9c","#f39c12","#d35400","#8e
44ad","#e74c3c","#bdc3c7"];

const phaseMap={

"On Track": [100,88,72,58,32,18,5,0],

"Delayed": [100,80,60,40,20,5,0,0],

"Critical": [100,70,50,30,15,0,0,0],

"At Risk": [100,82,65,45,22,8,0,0],

"Completed": [100,100,100,100,100,100,100,100],

};

[Link] = GANTT_PROJECTS_2026.map(p=>{

const pcts = phaseMap[[Link]] || phaseMap["On Track"];

return `<div style="margin-bottom:7px;padding-bottom:6px;border-


bottom:1px solid #e8f0e8">

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:3px"><span style="color:${STATUS_COLORS_2026[[Link]]||
[Link]}">●</span> ${[Link]}</div>

${[Link]((ph,i)=>`<div class="hbr" style="margin-


bottom:2px"><div class="hbr-lbl" style="width:155px;font-size:8px">$
{ph}</div><div class="hbr-track" style="height:11px"><div class="hbr-fill"
style="width:${pcts[i]}%;background:${phaseColors[i]};font-size:7px">$
{pcts[i]>12?pcts[i]+'%':''}</div></div><div class="hbr-num">${pcts[i]}
%</div></div>`).join("")}
</div>`;

}).join("");

function _renderDelayAnalysis() {

const da = [Link]("delay-analysis");

if(!da) return;

// Summary badges

const critCount =
DELAY_ITEMS_2026.filter(d=>[Link]==="critical").length;

const warnCount =
DELAY_ITEMS_2026.filter(d=>[Link]==="warning").length;

let html=`<div style="display:flex;gap:6px;margin-bottom:8px;flex-


wrap:wrap">

<div style="flex:1;min-width:70px;background:#fdf3f3;border:1px solid


#fadbd8;border-radius:4px;padding:6px 8px;text-align:center">

<div style="font-size:18px;font-weight:800;color:#c0392b">$
{critCount}</div>

<div
style="font-size:8px;font-weight:700;color:#c0392b">CRITICAL</div>

</div>

<div style="flex:1;min-width:70px;background:#fffbf0;border:1px solid


#fdebd0;border-radius:4px;padding:6px 8px;text-align:center">

<div style="font-size:18px;font-weight:800;color:#d35400">$
{warnCount}</div>

<div
style="font-size:8px;font-weight:700;color:#d35400">WARNING</div>

</div>
<div style="flex:1;min-width:70px;background:#f4f9f2;border:1px solid
#c8d8c8;border-radius:4px;padding:6px 8px;text-align:center">

<div style="font-size:18px;font-weight:800;color:#0a3d1f">$
{GANTT_PROJECTS_2026.length-critCount-warnCount}</div>

<div style="font-size:8px;font-weight:700;color:#1e8449">ON
TRACK</div>

</div>

</div>`;

DELAY_ITEMS_2026.forEach(d=>{

const maxDelay=25;

const fillW=[Link](100,[Link]/maxDelay*100);

html+=`<div class="delay-card ${[Link]}">

<div class="delay-heat ${[Link]}"></div>

<div style="flex:1;min-width:0">

<div style="font-size:9px;font-weight:800;color:#0a3d1f;white-
space:nowrap;overflow:hidden;text-overflow:ellipsis">${[Link]}</div>

<div style="font-size:8px;color:#888;margin-bottom:3px">${[Link]} ·
<span style="font-weight:700;color:$
{[Link]==="critical"?"#c0392b":"#d35400"}">${[Link]}</span></
div>

<div style="display:flex;align-items:center;gap:5px">

<div class="float-bar"><div class="float-fill" style="width:${fillW}


%;background:${[Link]==="critical"?"#e74c3c":"#f39c12"}"></
div></div>

<span style="font-size:8px;color:#555;white-space:nowrap;font-
weight:700">+${[Link]}d delay</span>

</div>

<div style="font-size:8px;color:#888;margin-top:2px">Free Float:


<b>${[Link]}d</b></div>
</div>

<span class="bdg ${[Link]==="critical"?"r":"o"}" style="font-


size:8px">${[Link]()}</span>

</div>`;

});

[Link]=html;

function _renderCalendar2026() {

const cal = [Link]("sched-calendar");

if(!cal) return;

const taskDays=[4,8,12,15,18,22,25,28];const overDays=[3,7];

const days=["Su","Mo","Tu","We","Th","Fr","Sa"];

let h=`<table
class="cal"><thead><tr>${[Link](d=>`<th>${d}</th>`).join("")}</tr
></thead><tbody><tr>`;

let d=1,start=5,col=start;

for(let i=0;i<start;i++) h+="<td></td>";

while(d<=31){

const isT=d===28,hasE=[Link](d),isO=[Link](d);

h+=`<td class="${isT?"today":isO?"overdue":hasE?"has-ev":""}" title="$


{hasE?"Milestone/Task due "+d+' May 2026':isO?"Overdue activity!":""}">$
{d}</td>`;

col++;if(col===7&&d<31){h+="</tr><tr>";col=0;}

d++;

h+="</tr></tbody></table>";

[Link]=h;
}

function renderCost() {

// Initialise dropdown on first render

_initCostProjectDropdown();

// Get filtered project set

var filtered = _getCostFilteredProjects();

// Ensure correct view mode is set

var sel = [Link]("cost-project-select");

var val = sel ? [Link] : "ALL";

_toggleCostViewMode(val);

// ── 1. Project Cost Summary Panel (primary KPI block) ──

_updateProjectCostSummary(filtered);

// ── 2. Legacy KPI tile updater (hidden elements, backward compat) ──

_updateCostKPIs(filtered);

// ── 3. EVM Table — always rendered, filtered by selection ──

_renderEVM(filtered);

// ── 4. Cost Variance Analysis — always rendered, filtered ──

_renderCostVarianceAnalysis(filtered);

// ── 5. Budget vs Actual — always rendered, filtered ──


_renderBudgetCommitmentActual(filtered);

// ── 6. Cash Flow Forecast — always rendered, filtered by project ──

_renderCashFlowForecast(filtered);

// ── 7. Detailed cost breakdown chart — always rendered, filtered ──

var cbc = [Link]("cost-breakdown-chart");

if(cbc) {

var maxBudget = [Link](null, [Link](function(p){return


[Link];}));

var barH = 22;

var chartW = 520;

var labelW = 150;

var chartRows = [Link](function(p){

var budgetW = [Link](([Link]/maxBudget)*(chartW-labelW-60));

var spentW = [Link](([Link] /maxBudget)*(chartW-labelW-60));

return '<div style="display:flex;align-items:center;gap:5px;margin-


bottom:5px">'+

'<div style="width:'+labelW+'px;font-size:9px;color:#333;font-
weight:600;text-align:right;flex-shrink:0;overflow:hidden;text-
overflow:ellipsis;white-space:nowrap" title="'+[Link]+'">'+
([Link]>22?[Link](0,21)+"…":[Link])+'</div>'+

'<div style="position:relative;flex:1;min-width:0">'+

'<div style="height:'+barH+'px;background:#e8f0e8;border-
radius:3px;overflow:hidden;position:relative">'+

'<div
style="height:100%;width:'+budgetW+'px;background:'+[Link]+'22;border:
1.5px solid
'+[Link]+';border-radius:3px;position:absolute;left:0;top:0"></div>'+
'<div
style="height:100%;width:'+spentW+'px;background:'+[Link]+';border-
radius:3px;position:absolute;left:0;top:0;display:flex;align-
items:center;padding-left:5px">'+

'<span style="font-size:9px;color:#fff;font-weight:700;white-
space:nowrap">ETB '+([Link]/1e6).toFixed(0)+'M</span>'+

'</div>'+

'</div>'+

'</div>'+

'<div style="font-size:9px;color:#555;width:70px;flex-shrink:0;text-
align:right">Budget: ETB '+([Link]/1e6).toFixed(0)+'M</div>'+

'</div>';

}).join("");

[Link] =

'<div style="display:flex;align-items:center;gap:12px;margin-
bottom:6px;margin-left:'+(labelW+5)+'px">'+

'<div style="display:flex;align-items:center;gap:4px"><div
style="width:14px;height:10px;background:#27ae6022;border:1.5px solid
#27ae60;border-radius:2px"></div><span style="font-
size:9px;color:#555">Budget (outline)</span></div>'+

'<div style="display:flex;align-items:center;gap:4px"><div
style="width:14px;height:10px;background:#27ae60;border-
radius:2px"></div><span style="font-size:9px;color:#555">Spent
(filled)</span></div>'+

'</div>'+chartRows;

// ── 8. Detailed cost table — always rendered, filtered ──

var ct = [Link]("cost-tbody");

// Update "Project" header for single-project context

var costTbl = [Link]("cost-table");


if (costTbl) {

var firstCostTh = [Link]("thead tr th:first-child");

if (firstCostTh) [Link] = [Link] === 1 ?


"Activity" : "Project";

if(ct) {

if ([Link] === 1) {

// Single project: show activity-level breakdown

var singleP = filtered[0];

var actBreakdown = [

{name:"Civil Works", budgetFrac:0.38, spentFrac:0.88,


category:"Earthworks & Foundations"},

{name:"Track Laying", budgetFrac:0.22, spentFrac:0.76,


category:"Rail Superstructure"},

{name:"Structures", budgetFrac:0.14, spentFrac:0.72,


category:"Bridges & Culverts"},

{name:"Electrical & Systems", budgetFrac:0.11, spentFrac:0.65,


category:"E&M Works"},

{name:"Procurement", budgetFrac:0.08, spentFrac:0.91,


category:"Materials & Equipment"},

{name:"Testing & Comm.", budgetFrac:0.04, spentFrac:0.45,


category:"QA/QC & Handover"},

{name:"Management & HSE", budgetFrac:0.03, spentFrac:0.74,


category:"Overhead & Safety"},

];

[Link] = [Link](function(act){

var actBudget = [Link]([Link] * [Link]);

var actActual = [Link]([Link] * [Link] *


[Link] / ([Link]/[Link]));

var actForecast = [Link](actBudget * 0.97);


var v = [Link](actActual/actBudget*100);

var var_ = actBudget - actActual;

var actEVM = {cpi: actActual>0 ?


parseFloat(([Link](actBudget*([Link]/100))/actActual).toFixed(
2)) : 1.00};

var actStatus = v>90?"Delayed":v>75?"At Risk":"On Track";

return '<tr>'+

'<td style="font-weight:700;color:#0a3d1f">'+[Link]+'</td>'+

'<td>'+[Link]+'</td>'+

'<td>ETB '+(actBudget/1e6).toFixed(0)+'M</td>'+

'<td>ETB '+(actActual/1e6).toFixed(0)+'M</td>'+

'<td>ETB '+(actForecast/1e6).toFixed(0)+'M</td>'+

'<td style="color:'+(var_>0?"#1e8449":"#c0392b")+';font-
weight:700">'+(var_>0?"+":"-")+'ETB
'+[Link](var_/1e6).toFixed(0)+'M</td>'+

'<td><div class="pbar"><div class="pbar-f"


style="width:'+v+'%;background:'+
(v>90?"#e74c3c":v>75?"#f39c12":"#27ae60")+'"></div></div>'+v+'%</
td>'+

'<td style="color:'+([Link]>=1?"#1e8449":"#c0392b")+';font-
weight:700">'+[Link]+'</td>'+

'<td><span class="bdg '+(actStatus==="On


Track"?"g":actStatus==="At
Risk"?"o":"r")+'">'+actStatus+'</span></td>'+

'</tr>';

}).join("");

} else {

[Link] = [Link](function(p){

var v=[Link]([Link]/[Link]*100);

var var_=[Link];
var dEVM=_getEVMData(p);

var cpi=[Link](2);

return '<tr>'+

'<td>'+([Link]>30?[Link](0,29)+"…":[Link])
+'</td>'+

'<td>Civil Works</td>'+

'<td>ETB '+([Link]/1e6).toFixed(0)+'M</td>'+

'<td>ETB '+([Link]/1e6).toFixed(0)+'M</td>'+

'<td>ETB '+([Link]*0.97/1e6).toFixed(0)+'M</td>'+

'<td style="color:'+(var_>0?"#1e8449":"#c0392b")+';font-
weight:700">'+(var_>0?"+":"-")+'ETB
'+[Link](var_/1e6).toFixed(0)+'M</td>'+

'<td><div class="pbar"><div class="pbar-f"


style="width:'+v+'%;background:'+
(v>90?"#e74c3c":v>75?"#f39c12":"#27ae60")+'"></div></div>'+v+'%</
td>'+

'<td style="color:'+(parseFloat(cpi)>=1?"#1e8449":"#c0392b")
+';font-weight:700">'+cpi+'</td>'+

'<td><span class="bdg '+([Link]==="On Track"?"g":"o")


+'">'+[Link]+'</span></td>'+

'</tr>';

}).join("");

//
═══════════════════════════════════════════════════════
════════
// RESOURCE MODULE — Comprehensive Data & Render Engine
//
═══════════════════════════════════════════════════════
════════

// ── Extended Resource Data Sets ──────────────────────────────

const RES_EQUIPMENT = [

{id:"EQ-001",name:"Excavator CAT 336",type:"Earthworks",project:"Indode


Rail Link-1 / Indode Pavement Construction-
1",status:"Operating",util:88,nextMaint:"Jun 15,
2026",hours:1240,fuel:"Diesel"},

{id:"EQ-002",name:"Crawler Crane 50T",type:"Lifting",project:"Dawanle


Freight Terminal Expansion Project",status:"Operating",util:72,nextMaint:"Jun
20, 2026",hours:980,fuel:"Diesel"},

{id:"EQ-003",name:"Concrete Batching
Plant",type:"Concrete",project:"Indode Rail Link-1 / Indode Pavement
Construction-1",status:"Operating",util:91,nextMaint:"Jul 1,
2026",hours:1560,fuel:"Electric"},

{id:"EQ-004",name:"Motor Grader CAT


140",type:"Earthworks",project:"AMG Link Rail
Project",status:"Idle",util:35,nextMaint:"Jun 10,
2026",hours:620,fuel:"Diesel"},

{id:"EQ-005",name:"Diesel Generator 500KVA",type:"Power",project:"Ayisha


Substation Building Maintenance
Project",status:"Operating",util:78,nextMaint:"Jun 25,
2026",hours:2100,fuel:"Diesel"},

{id:"EQ-006",name:"Vibro Roller BOMAG",type:"Compaction",project:"AMG


Link Rail Project",status:"Under Maintenance",util:0,nextMaint:"Jun 8,
2026",hours:880,fuel:"Diesel"},

{id:"EQ-007",name:"Track Laying Machine",type:"Track


Works",project:"Indode Rail Link-1 / Indode Pavement Construction-
1",status:"Operating",util:94,nextMaint:"Jun 30,
2026",hours:340,fuel:"Diesel"},

{id:"EQ-008",name:"Dump Truck HOWO


20T",type:"Haulage",project:"Dawanle Freight Terminal Expansion
Project",status:"Operating",util:82,nextMaint:"Jul 5,
2026",hours:1780,fuel:"Diesel"},

{id:"EQ-009",name:"Welding Machine
Set",type:"Metalworks",project:"Ayisha Substation Building Maintenance
Project",status:"Idle",util:20,nextMaint:"Aug 1,
2026",hours:410,fuel:"Electric"},

{id:"EQ-010",name:"Backhoe Loader
JCB",type:"Earthworks",project:"Indode Bulk Cargo Construction
Project",status:"Operating",util:65,nextMaint:"Jun 18,
2026",hours:1050,fuel:"Diesel"},

];

const RES_MATERIALS = [

{name:"Ballast (Track
Grade)",unit:"m³",planned:45000,consumed:32000,stock:8500,reorder:1000
0,project:"Indode Rail Link-1 / Indode Pavement Construction-1"},

{name:"Concrete
(C35/45)",unit:"m³",planned:22000,consumed:16800,stock:2200,reorder:300
0,project:"Dawanle Freight Terminal Expansion Project"},

{name:"Steel Rebar (Grade


60)",unit:"Tonnes",planned:3800,consumed:2950,stock:420,reorder:600,proje
ct:"All Projects"},

{name:"Sleepers
(Concrete)",unit:"pcs",planned:68000,consumed:41500,stock:12000,reorder:
15000,project:"Indode Rail Link-1 / Indode Pavement Construction-1"},

{name:"Rail (60kg/m
UIC60)",unit:"metres",planned:28000,consumed:18400,stock:3800,reorder:5
000,project:"AMG Link Rail Project"},

{name:"Bitumen (60/70
Pen)",unit:"Tonnes",planned:1200,consumed:880,stock:95,reorder:200,projec
t:"Ayisha Substation Building Maintenance Project"},

{name:"Structural
Steel",unit:"Tonnes",planned:850,consumed:610,stock:180,reorder:200,proje
ct:"Dawanle Freight Terminal Expansion Project"},
{name:"Electrical
Cable",unit:"metres",planned:35000,consumed:21000,stock:8000,reorder:50
00,project:"Ayisha Substation Building Maintenance Project"},

];

const RES_FUEL = [

{name:"Diesel (B5
Blend)",unit:"Litres",mtdConsumption:128400,mtdCost:18820800,stock:3500
0,efficiency:4.2,activity:"Earthworks & Transport",project:"All Projects"},

{name:"Petrol
(RON95)",unit:"Litres",mtdConsumption:12600,mtdCost:2016000,stock:8000,
efficiency:null,activity:"Light Vehicles",project:"All Projects"},

{name:"Lubricating
Oil",unit:"Litres",mtdConsumption:2400,mtdCost:720000,stock:1200,efficienc
y:null,activity:"Equipment Maintenance",project:"All Projects"},

{name:"LPG
Cylinders",unit:"Cylinders",mtdConsumption:180,mtdCost:108000,stock:60,e
fficiency:null,activity:"Welding & Cutting",project:"All Projects"},

{name:"Hydraulic
Fluid",unit:"Litres",mtdConsumption:840,mtdCost:336000,stock:400,efficienc
y:null,activity:"Heavy Equipment",project:"All Projects"},

];

// Monthly trend data (Jan–Jun 2026)

const RES_MONTHLY = {

months: ["Jan","Feb","Mar","Apr","May","Jun*"],

mpPlanned: [245,248,252,258,262,265],

mpActual: [238,241,249,255,258,null],

matPlanned: [8200,9400,10800,11200,12500,13000],

matConsumed: [7800,9100,10500,10900,12100,null],

fuelCostK: [2850,3100,3380,3210,3650,null],
fuelBudgetK: [3000,3000,3500,3500,3800,3800],

};

// Weekly utilization heatmap data (last 8 weeks × 4 resource types)

const RES_HEATMAP = {

weeks: ["W46","W47","W48","W49","W50","W51","W52","W1 Jun"],

rows: [

{label:"Manpower", values:[74,76,79,82,85,80,77,83]},

{label:"Equipment", values:[68,71,75,78,82,74,69,77]},

{label:"Materials", values:[82,85,88,79,84,90,87,86]},

{label:"Fuel", values:[71,74,78,80,83,76,72,80]},

};

let RES_ACTIVE_PROJECT = "ALL"; // global filter state

let RES_ACTIVE_VIEW = "summary";

// ── Populate Project Dropdown ────────────────────────────────

function populateResourceDropdown() {

const sel = [Link]("res-project-select");

if(!sel) return;

// Clear and rebuild

[Link] = '<option value="ALL">— All Projects —</option>';

[Link](p => {

const opt = [Link]("option");

[Link] = String([Link]);
[Link] = [Link] > 45 ? [Link](0,43)+"…" :
[Link];

[Link](opt);

});

[Link] = RES_ACTIVE_PROJECT;

function handleResourceFileUpload(input) {

const file = [Link][0];

if(!file) return;

const status = [Link]("res-file-status");

if(status) {

[Link] = "● " + [Link];

[Link] = "#a8d5b5";

toast("📂 File '" + [Link] + "' loaded. Resource data updated from
upload.");

// In production: parse XLSX/CSV/XML here with SheetJS or similar

// For now refresh with current data

renderResources();

function filterResourcesByProject(val) {

RES_ACTIVE_PROJECT = val;

renderResources();

}
function setResView(v) {

RES_ACTIVE_VIEW = v;

["summary","detail","forecast"].forEach(name => {

const panel = [Link]("res-view-"+name+"-panel");

const btn = [Link]("res-view-"+name);

if(panel) [Link] = name === v ? "" : "none";

if(btn){

[Link] = name === v ? "#fff" : "rgba(255,255,255,.2)";

[Link] = name === v ? "#0a3d1f" : "#fff";

[Link] = name === v ? "800" : "700";

});

renderResources();

function _getFilteredMembers() {

if(RES_ACTIVE_PROJECT === "ALL") return MEMBERS;

const proj = [Link](p=>String([Link])===RES_ACTIVE_PROJECT);

if(!proj) return MEMBERS;

const kw = [Link](" ").filter(w=>[Link]>3);

return [Link](m => {

if([Link]==="All Projects") return true;

return [Link](k => [Link]().includes([Link]())


||

[Link]().includes([Link]().split("/")
[0].trim().toLowerCase()));

});
}

function _getFilteredEquipment() {

if(RES_ACTIVE_PROJECT === "ALL") return RES_EQUIPMENT;

const proj = [Link](p=>String([Link])===RES_ACTIVE_PROJECT);

if(!proj) return RES_EQUIPMENT;

const kw = [Link](" ").filter(w=>[Link]>3);

return RES_EQUIPMENT.filter(e =>

[Link]==="All Projects" ||

[Link](k => [Link]().includes([Link]()))

);

function _getFilteredMaterials() {

if(RES_ACTIVE_PROJECT === "ALL") return RES_MATERIALS;

const proj = [Link](p=>String([Link])===RES_ACTIVE_PROJECT);

if(!proj) return RES_MATERIALS;

const kw = [Link](" ").filter(w=>[Link]>3);

return RES_MATERIALS.filter(m =>

[Link]==="All Projects" ||

[Link](k => [Link]().includes([Link]()))

);

function _utilColor(u) {

return u > 90 ? "#e74c3c" : u > 75 ? "#f39c12" : u > 0 ? "#27ae60" :


"#aaa";
}

function _projLabel() {

if(RES_ACTIVE_PROJECT==="ALL") return "";

const p = [Link](p=>String([Link])===RES_ACTIVE_PROJECT);

return p ? "📁 " + ([Link]>30?


[Link](0,28)+"…":[Link]) : "";

// ── SVG Donut Helper ─────────────────────────────────────────

function _drawDonut(svgId, pct, color, centerText) {

const svg = [Link](svgId);

if(!svg) return;

const r = 38, cx = 50, cy = 50;

const circ = 2 * [Link] * r;

const dash = (pct / 100) * circ;

[Link] =

`<circle cx="${cx}" cy="${cy}" r="${r}" fill="none" stroke="#e8f0e8"


stroke-width="12"/>` +

`<circle cx="${cx}" cy="${cy}" r="${r}" fill="none" stroke="${color}"


stroke-width="12"

stroke-dasharray="${dash} ${circ}" stroke-dashoffset="${circ*0.25}"


stroke-linecap="round"/>` +

`<text x="${cx}" y="${cy-5}" text-anchor="middle" style="font-


size:13px;font-weight:800;fill:${color}">${pct}%</text>` +

`<text x="${cx}" y="${cy+8}" text-anchor="middle" style="font-


size:7px;fill:#555">${centerText}</text>`;

}
// ── SVG Pie Helper ───────────────────────────────────────────

function _drawPie(svgId, data) {

const svg = [Link](svgId);

if(!svg) return;

const cx=55, cy=55, r=42;

let total = [Link]((s,d)=>s+[Link],0);

let startAngle = -[Link]/2;

let paths = "";

[Link](d => {

const angle = ([Link]/total)*2*[Link];

const x1=cx+r*[Link](startAngle), y1=cy+r*[Link](startAngle);

const x2=cx+r*[Link](startAngle+angle),
y2=cy+r*[Link](startAngle+angle);

const large=angle>[Link]?1:0;

paths += `<path d="M${cx},${cy} L${x1},${y1} A${r},${r} 0 $


{large},1 ${x2},${y2} Z" fill="${[Link]}" opacity=".9"/>`;

startAngle += angle;

});

[Link] = paths + `<circle cx="${cx}" cy="${cy}" r="22"


fill="#fff"/>` +

`<text x="${cx}" y="${cy-3}" text-anchor="middle" style="font-


size:8px;font-weight:800;fill:#0a3d1f">COST</text>` +

`<text x="${cx}" y="${cy+7}" text-anchor="middle" style="font-


size:7px;fill:#555">SPLIT</text>`;

// ── Mini sparkline chart ─────────────────────────────────────

function _drawSparkline(containerId, values, color, maxOverride) {


const el = [Link](containerId);

if(!el) return;

const valid = [Link](v=>v!==null);

const mx = maxOverride || [Link](...valid)*1.15;

const mn = [Link](...valid)*0.85;

const w=[Link]||200, h=parseInt([Link])||50;

const pts = [Link]((v,i) => {

if(v===null) return null;

const x = (i/([Link]-1))*w;

const y = h - ((v-mn)/(mx-mn))*h*0.85 - 4;

return `${x},${y}`;

}).filter(p=>p!==null).join(" ");

[Link] = `<svg width="100%" height="${h}" viewBox="0 0 ${w} $


{h}" preserveAspectRatio="none">

<polyline points="${pts}" fill="none" stroke="${color}" stroke-width="2"


stroke-linejoin="round"/>

${[Link]((v,i)=>{

const x=(i/([Link]-1))*w;

const y=h-((v-mn)/(mx-mn))*h*0.85-4;

return `<circle cx="${x}" cy="${y}" r="3" fill="${color}"/>

<text x="${x}" y="${y-5}" text-anchor="middle" style="font-


size:7px;fill:#555">${v}</text>`;

}).join("")}

</svg>`;

// ── Alerts Banner ────────────────────────────────────────────

function _renderResAlerts(members, equipment, materials) {


const el = [Link]("res-alerts-banner");

if(!el) return;

const alerts = [];

// Manpower alerts

const overloaded = [Link](m=>[Link]>90);

if([Link]) [Link]({type:"r",icon:"🔴",msg:`OVERUTILIZATION:
${[Link](m=>[Link](" ")[0]).join(", ")} exceed 90%
utilization — schedule relief immediately`});

// Equipment alerts

const maintenance = [Link](e=>[Link]==="Under


Maintenance");

if([Link]) [Link]({type:"o",icon:"🔧",msg:`MAINTENANCE:
${[Link](e=>[Link]).join(", ")} currently under maintenance —
assess impact on schedule`});

const idle = [Link](e=>[Link]==="Idle"&&[Link]<40);

if([Link]>1) [Link]({type:"b",icon:"⚠",msg:`IDLE EQUIPMENT: $


{[Link](e=>[Link]).join(", ")} idle — consider redeployment or standby
cost review`});

// Material alerts

const lowStock = [Link](m=>[Link]<=[Link]);

if([Link]) [Link]({type:"r",icon:"📦",msg:`LOW STOCK ALERT: $


{[Link](m=>[Link]).join(", ")} at or below reorder level — initiate
procurement`});

if(![Link]){ [Link]=""; return; }

const colors = {r:"#fadbd8",o:"#fdebd0",b:"#d6eaf8"};

const borders = {r:"#e74c3c",o:"#d35400",b:"#2980b9"};

[Link] = `<div style="display:flex;flex-direction:column;gap:4px">`


+

[Link](a=>`<div style="background:${colors[[Link]]};border-
left:3px solid ${borders[[Link]]};border-radius:3px;padding:5px
10px;display:flex;align-items:center;gap:8px">
<span style="font-size:11px">${[Link]}</span>

<span
style="font-size:9px;font-weight:700;color:#333">${[Link]}</span>

</div>`).join("") + `</div>`;

// ── Main render function ─────────────────────────────────────

function renderResources() {

populateResourceDropdown();

const members = _getFilteredMembers();

const equipment = _getFilteredEquipment();

const materials = _getFilteredMaterials();

const projLabel = _projLabel();

// Update project labels across panels

["mp","eq","mat","fuel","cost","detail","fc"].forEach(id => {

const el = [Link]("res-proj-label-"+id);

if(el) [Link] = projLabel;

});

_renderResAlerts(members, equipment, materials);

if(RES_ACTIVE_VIEW === "summary") {

_renderResKPICards(members, equipment, materials);

_renderManpower(members);

_renderEquipment(equipment);
_renderMaterials(materials);

_renderFuel();

_renderHeatmap();

_renderCostAnalysis(members, equipment, materials);

} else if(RES_ACTIVE_VIEW === "detail") {

_renderDetailView(members, equipment, materials);

renderPerProjectResources();

} else if(RES_ACTIVE_VIEW === "forecast") {

_renderForecastView(members);

_renderTrendView();

// ── KPI Cards (8) ────────────────────────────────────────────

function _renderResKPICards(members, equipment, materials) {

const row = [Link]("res-kpi-row");

if(!row) return;

const totalMP = [Link];

const avgUtil = [Link] ?


[Link]([Link]((s,m)=>s+[Link],0)/[Link]) : 0;

const overloaded= [Link](m=>[Link]>90).length;

const available = [Link](m=>[Link]<60).length;

const eqTotal = [Link];

const eqOperating = [Link](e=>[Link]==="Operating").length;

const eqUtil = [Link] ?


[Link]([Link]((s,e)=>s+[Link],0)/[Link]) : 0;

const matConsumed = [Link]((s,m)=>s+[Link],0);


const matPlanned = [Link]((s,m)=>s+[Link],0);

const matUtil = matPlanned ?


[Link](matConsumed/matPlanned*100) : 0;

const fuelMTD = RES_FUEL.reduce((s,f)=>s+[Link],0);

const cards = [

{val:totalMP, lbl:"Total Manpower", icon:"👷",cls:"green-kpi",sub:"Active


personnel"},

{val:avgUtil+"%",lbl:"Avg MP Utilization",icon:"📊",cls:avgUtil>85?"red-
kpi":avgUtil>70?"orange-kpi":"green-kpi",sub:overloaded+" overloaded"},

{val:available, lbl:"Available (< 60%)", icon:"✅",cls:"blue-kpi", sub:"Low


utilization"},

{val:eqOperating+"/"+eqTotal,lbl:"Equipment
Operating",icon:"🚧",cls:"green-kpi",sub:"Total "+eqTotal+" units"},

{val:eqUtil+"%", lbl:"Equip Utilization", icon:"⚙",cls:eqUtil>85?"red-


kpi":eqUtil>70?"orange-kpi":"green-kpi",sub:"Fleet average"},

{val:matUtil+"%",lbl:"Material Consumed",icon:"🧱",cls:matUtil>90?"red-
kpi":matUtil>70?"orange-kpi":"green-kpi",sub:"vs planned qty"},

{val:"ETB "+(fuelMTD/1e6).toFixed(1)+"M",lbl:"Fuel Cost


MTD",icon:"⛽",cls:"orange-kpi",sub:"Month-to-date"},

{val:[Link](m=>[Link]<=[Link]).length,lbl:"Low Stock
Alerts",icon:"📦",cls:"red-kpi",sub:"Need reorder"},

];

[Link] = [Link](c=>`

<div class="widget" style="flex:0 0 calc(12.5% - 6px);min-width:110px">

<div class="wb" style="padding:8px;text-align:center">

<div style="font-size:18px;margin-bottom:2px">${[Link]}</div>

<div class="kpi ${[Link]}" style="border-radius:4px;padding:6px 4px">


<div class="kpi-val" style="font-size:16px;line-height:1.1">$
{[Link]}</div>

<div class="kpi-lbl" style="font-size:8px">${[Link]}</div>

</div>

<div style="font-size:8px;color:#888;margin-top:3px">${[Link]}</div>

</div>

</div>`).join("");

// ── Manpower Panel ───────────────────────────────────────────

function _renderManpower(members) {

// KPI grid

const grid = [Link]("mp-kpi-grid");

if(grid) {

const total = [Link];

const assigned = [Link](m=>[Link]>=60).length;

const available = [Link](m=>[Link]<60).length;

const avgUtil = [Link] ?


[Link]([Link]((s,m)=>s+[Link],0)/[Link]):0;

[Link] = [

{v:total,l:"Total",c:"green-kpi"},{v:assigned,l:"Assigned",c:"blue-kpi"},

{v:available,l:"Available",c:"orange-kpi"},{v:avgUtil+"%",l:"Avg
Util",c:avgUtil>85?"red-kpi":"green-kpi"}

].map(k=>`<div class="kpi ${k.c}" style="padding:5px;text-


align:center"><div class="kpi-val"
style="font-size:14px">${k.v}</div><div
class="kpi-lbl">${k.l}</div></div>`).join("");

}
// Planned vs Actual bar chart

const pa = [Link]("mp-planned-actual");

if(pa) {

const months = RES_MONTHLY.months;

const plan = RES_MONTHLY.mpPlanned;

const actual = RES_MONTHLY.mpActual;

const max = [Link](...plan)*1.05;

[Link] = `<div style="display:flex;align-items:flex-


end;gap:4px;height:55px;padding-bottom:14px;position:relative">` +

[Link]((m,i)=>{

const pH = [Link]((plan[i]/max)*45);

const aH = actual[i]!==null ? [Link]((actual[i]/max)*45) : 0;

const isCur = [Link]("*");

return `<div style="flex:1;display:flex;flex-direction:column;align-


items:center;gap:1px">

<div style="display:flex;align-items:flex-end;gap:1px;height:45px">

<div title="Planned: ${plan[i]}"


style="width:8px;background:#d6eaf8;border-radius:2px 2px 0 0;height:$
{pH}px"></div>

${actual[i]!==null?`<div title="Actual: ${actual[i]}"


style="width:8px;background:$
{actual[i]>=plan[i]?"#e74c3c":"#27ae60"};border-radius:2px 2px 0
0;height:${aH}px"></div>`:

`<div style="width:8px;background:#fdebd0;border-radius:2px 2px 0


0;height:${[Link](pH*0.95)}px;opacity:.6"></div>`}

</div>

<div style="font-size:7px;color:${isCur?"#e74c3c":"#555"};font-
weight:${isCur?"800":"600"};white-space:nowrap">${m}</div>

</div>`;

}).join("") +
`</div><div style="display:flex;gap:8px;font-size:7px;color:#555">

<span><span style="display:inline-
block;width:8px;height:6px;background:#d6eaf8;vertical-
align:middle;margin-right:2px"></span>Planned</span>

<span><span style="display:inline-
block;width:8px;height:6px;background:#27ae60;vertical-
align:middle;margin-right:2px"></span>Actual</span>

<span><span style="display:inline-
block;width:8px;height:6px;background:#fdebd0;vertical-
align:middle;margin-right:2px;opacity:.8"></span>Forecast</span>

</div>`;

// Productivity

const prod = [Link]("mp-productivity");

if(prod) {

const items = [

{lbl:"Civil Engineers",val:87},

{lbl:"Electrical Eng.",val:82},

{lbl:"QA Inspectors",val:74},

{lbl:"Site Supervisors",val:91},

];

[Link] = [Link](it=>`<div class="hbr" style="margin-


bottom:3px">

<div class="hbr-lbl sm"


style="font-size:8px;width:100px">${[Link]}</div>

<div class="hbr-track"><div class="hbr-fill" style="width:${[Link]}


%;background:${_utilColor([Link])}">${[Link]}%</div></div>

</div>`).join("");

}
// Upcoming demand

const upd = [Link]("mp-upcoming-demand");

if(upd) {

const wks = [

{wk:"Wk 1",demand:268,avail:258},

{wk:"Wk 2",demand:275,avail:258},

{wk:"Wk 3",demand:260,avail:263},

{wk:"Wk 4",demand:270,avail:263},

];

[Link] = [Link](w=>{

const gap = [Link] - [Link];

return `<div style="display:flex;align-items:center;gap:5px;margin-


bottom:3px;font-size:9px">

<span
style="width:28px;font-weight:700;color:#0a3d1f">${[Link]}</span>

<span style="color:#555">Need: <b>${[Link]}</b></span>

<span style="color:#555">Have: <b>${[Link]}</b></span>

<span class="bdg ${gap>0?"r":"g"}" style="margin-left:auto">$


{gap>0?"+"+gap+" SHORT":[Link](gap)+" OK"}</span>

</div>`;

}).join("");

// Team table

const tbody = [Link]("res-tbody");

if(tbody) [Link] = [Link]((m,i)=>{

const gi = [Link](m);
const productivity = [Link](100,[Link]([Link]*0.95+
([Link]()*10-5)));

return `<tr>

<td><span class="${editMode?"editable":""}" ${editMode?


`contenteditable="true" onblur="MEMBERS[$
{gi}].name=[Link]"`:''}>${[Link]}</span></td>

<td style="font-size:8px;color:#555">${[Link]}</td>

<td style="font-size:8px;color:#555;max-
width:100px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"
title="${[Link]}">${[Link](0,20)}$
{[Link]>20?"…":""}</td>

<td><div style="display:flex;align-items:center;gap:3px"><div
class="pbar" style="width:50px"><div class="pbar-f" style="width:$
{[Link]}%;background:${_utilColor([Link])}"></div></div>${editMode?
`<input type="number" min="0" max="100" value="${[Link]}"
onchange="MEMBERS[${gi}].util=+[Link];renderResources()"
style="width:32px;font-size:8px;border:1px solid #c8d8c8;border-
radius:2px;padding:1px;font-family:inherit">%`:`<span style="font-
size:9px;font-weight:700;color:${_utilColor([Link])}">${[Link]}%</
span>`}</div></td>

<td style="text-align:center">${[Link]}</td>

<td><div class="pbar" style="width:40px"><div class="pbar-f"


style="width:${productivity}%;background:#2980b9"></div></div><span
style="font-size:8px;color:#2980b9">${productivity}%</span></td>

<td><span class="bdg $
{[Link]==="Active"?"g":[Link]==="Overloaded"?"r":"o"}">$
{[Link]}</span></td>

${editMode?`<td><button class="edit-btn" onclick="openModal('edit-


member',${gi})">✏</button></td>`:""}

</tr>`;

}).join("");

}
// ── Equipment Panel ──────────────────────────────────────────

function _renderEquipment(equipment) {

// KPI grid

const grid = [Link]("eq-kpi-grid");

if(grid) {

const operating = [Link](e=>[Link]==="Operating").length;

const idle = [Link](e=>[Link]==="Idle").length;

const maint = [Link](e=>[Link]==="Under


Maintenance").length;

const avgUtil = [Link] ?


[Link]([Link]((s,e)=>s+[Link],0)/[Link]):0;

[Link] = [

{v:operating,l:"Operating",c:"green-kpi"},{v:idle,l:"Idle",c:"blue-kpi"},

{v:maint,l:"Maintenance",c:"red-kpi"},{v:avgUtil+"%",l:"Avg
Util",c:avgUtil>85?"red-kpi":"green-kpi"}

].map(k=>`<div class="kpi ${k.c}" style="padding:5px;text-


align:center"><div class="kpi-val"
style="font-size:14px">${k.v}</div><div
class="kpi-lbl">${k.l}</div></div>`).join("");

// Equipment status donut

const total = [Link];

const avgUtil2 = total ?


[Link]([Link]((s,e)=>s+[Link],0)/total) : 0;

_drawDonut("eq-donut", avgUtil2, _utilColor(avgUtil2), "Fleet");

// Status list

const sl = [Link]("eq-status-list");
if(sl) {

const statuses = [

{s:"Operating",c:"#27ae60"},

{s:"Idle",c:"#2980b9"},

{s:"Under Maintenance",c:"#e74c3c"},

];

[Link] = [Link](st=>{

const cnt = [Link](e=>[Link]===st.s).length;

const pct = total ? [Link](cnt/total*100) : 0;

return `<div class="hbr" style="margin-bottom:3px">

<div class="hbr-lbl sm"


style="font-size:8px;width:90px">${st.s}</div>

<div class="hbr-track"><div class="hbr-fill" style="width:${pct}


%;background:${st.c}">${cnt}</div></div>

<div class="hbr-num">${pct}%</div>

</div>`;

}).join("");

// Equipment table

const tbody = [Link]("eq-tbody");

if(tbody) [Link] = [Link](e=>`<tr>

<td style="font-weight:700">${[Link]}</td>

<td style="font-size:8px;color:#555">${[Link]}</td>

<td style="font-size:8px;color:#555;max-
width:90px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"
title="${[Link]}">${[Link](0,18)}$
{[Link]>18?"…":""}</td>
<td><span class="bdg $
{[Link]==="Operating"?"g":[Link]==="Idle"?"b":"r"}">${[Link]}</
span></td>

<td><div class="pbar" style="width:50px"><div class="pbar-f"


style="width:${[Link]}%;background:${_utilColor([Link])}"></div></
div><span
style="font-size:8px;color:${_utilColor([Link])}">${[Link]}%</span></td>

<td style="font-size:8px;color:#555">${[Link]}</td>

</tr>`).join("");

// ── Materials Panel ──────────────────────────────────────────

function _renderMaterials(materials) {

// KPI grid

const grid = [Link]("mat-kpi-grid");

if(grid) {

const totalPlan = [Link]((s,m)=>s+[Link],0);

const totalCons = [Link]((s,m)=>s+[Link],0);

const totalStock= [Link]((s,m)=>s+[Link],0);

const lowStock = [Link](m=>[Link]<=[Link]).length;

[Link] = [

{v:[Link](),l:"Total Planned",c:"blue-kpi"},

{v:[Link](),l:"Total Consumed",c:"green-kpi"},

{v:[Link](),l:"Remaining Stock",c:"orange-kpi"},

{v:lowStock,l:"Low Stock",c:"red-kpi"}

].map(k=>`<div class="kpi ${k.c}" style="padding:5px;text-


align:center"><div class="kpi-val"
style="font-size:12px">${k.v}</div><div
class="kpi-lbl">${k.l}</div></div>`).join("");
}

// Stacked bars: planned vs consumed vs remaining

const sbEl = [Link]("mat-stacked-bars");

if(sbEl) {

[Link] = [Link](0,5).map(m=>{

const maxV = [Link];

const consPct = [Link]([Link]/maxV*100);

const remainPct =
[Link]([Link]([Link],[Link])/maxV*100);

const lowAlert = [Link]<=[Link];

return `<div class="hbr" style="margin-bottom:4px">

<div class="hbr-lbl" style="font-size:8px;width:110px">$


{[Link]>16?[Link](0,14)+"…":[Link]}</div>

<div style="flex:1;height:16px;background:#e8f0e8;border-
radius:2px;overflow:hidden;position:relative;display:flex">

<div style="height:100%;background:#27ae60;width:${consPct}
%;display:flex;align-items:center;justify-content:center">

<span style="font-size:7px;color:#fff;font-weight:700">${consPct}
%</span>

</div>

<div style="height:100%;background:$
{lowAlert?"#e74c3c":"#2980b9"};width:${remainPct}%;display:flex;align-
items:center;justify-content:center">

<span style="font-size:7px;color:#fff;font-weight:700">$
{remainPct}%</span>

</div>

</div>
${lowAlert?`<span style="font-size:8px;color:#e74c3c;font-
weight:800;margin-left:4px">⚠</span>`:`<span
style="width:12px"></span>`}

</div>`;

}).join("") +

`<div style="display:flex;gap:8px;font-size:7px;color:#555;margin-
top:3px">

<span><span style="display:inline-
block;width:8px;height:6px;background:#27ae60;margin-right:2px;vertical-
align:middle"></span>Consumed</span>

<span><span style="display:inline-
block;width:8px;height:6px;background:#2980b9;margin-right:2px;vertical-
align:middle"></span>Remaining Stock</span>

<span><span style="display:inline-
block;width:8px;height:6px;background:#e74c3c;margin-right:2px;vertical-
align:middle"></span>Low Stock Warning</span>

</div>`;

// Material trend — mini sparkline

_drawSparkline("mat-trend-chart", RES_MONTHLY.matConsumed,
"#27ae60", [Link](...RES_MONTHLY.matPlanned)*1.05);

// Material table

const tbody = [Link]("mat-tbody");

if(tbody) [Link] = [Link](m=>{

const pct = [Link]([Link]/[Link]*100);

const low = [Link]<=[Link];

return `<tr>

<td style="font-weight:700;font-size:8px">${[Link]}</td>
<td style="font-size:8px;color:#555">${[Link]}</td>

<td style="font-size:8px">${[Link]()}</td>

<td><div class="pbar" style="width:45px"><div class="pbar-f"


style="width:${pct}%;background:${pct>90?"#e74c3c":"#27ae60"}"></di
v></div><span
style="font-size:8px">${[Link]()}</span></td>

<td style="color:${low?"#e74c3c":"#1e8449"};font-weight:700;font-
size:8px">${[Link]()}</td>

<td
style="font-size:8px;color:#555">${[Link]()}</td>

<td><span class="bdg ${low?"r":"g"}">${low?"⚠ Low":"In


Stock"}</span></td>

</tr>`;

}).join("");

// ── Fuel Panel ───────────────────────────────────────────────

function _renderFuel() {

// KPI grid

const grid = [Link]("fuel-kpi-grid");

if(grid) {

const totalConsumption = RES_FUEL[0].mtdConsumption;

const totalCostK =
[Link](RES_FUEL.reduce((s,f)=>s+[Link],0)/1000);

const efficiency = RES_FUEL[0].efficiency;

const criticalFuel =
RES_FUEL.filter(f=>[Link]<[Link]*0.3).length;

[Link] = [

{v:[Link]()+"L",l:"Diesel MTD",c:"orange-kpi"},
{v:"ETB "+totalCostK+"K",l:"Total Cost MTD",c:"red-kpi"},

{v:efficiency+"L/Hr",l:"Efficiency",c:"blue-kpi"},

{v:criticalFuel,l:"Critical Low",c:"red-kpi"}

].map(k=>`<div class="kpi ${k.c}" style="padding:5px;text-


align:center"><div class="kpi-val"
style="font-size:11px">${k.v}</div><div
class="kpi-lbl">${k.l}</div></div>`).join("");

// Fuel by activity

const fac = [Link]("fuel-activity-chart");

if(fac) {

const activities = [

{act:"Earthworks",pct:42,color:"#d35400"},

{act:"Track Laying",pct:23,color:"#784212"},

{act:"Concrete Works",pct:15,color:"#e67e22"},

{act:"Transport",pct:14,color:"#f39c12"},

{act:"Other",pct:6,color:"#aaa"},

];

[Link] = [Link](a=>`<div class="hbr" style="margin-


bottom:3px">

<div class="hbr-lbl sm"


style="font-size:8px;width:85px">${[Link]}</div>

<div class="hbr-track"><div class="hbr-fill" style="width:${[Link]}


%;background:${[Link]}">${[Link]}%</div></div>

</div>`).join("");

// Efficiency trend
_drawSparkline("fuel-efficiency-chart", [4.8,4.6,4.5,4.3,4.2,null], "#d35400",
5.5);

// Cost trend

_drawSparkline("fuel-cost-chart", RES_MONTHLY.[Link]((v,i)=>v!
==null?[Link](v):null), "#e74c3c");

// Fuel table

const tbody = [Link]("fuel-tbody");

if(tbody) [Link] = RES_FUEL.map(f=>{

const stockPct = [Link]([Link]/([Link]*0.5)*100);

const low = [Link] < [Link]*0.3;

return `<tr>

<td style="font-weight:700;font-size:8px">${[Link]}</td>

<td style="font-size:8px;color:#555">${[Link]}</td>

<td style="font-size:8px">${[Link]()}</td>

<td style="font-size:8px">ETB ${([Link]/1000).toFixed(0)}K</td>

<td><div class="pbar" style="width:45px"><div class="pbar-f"


style="width:${[Link](100,stockPct)}%;background:$
{low?"#e74c3c":"#27ae60"}"></div></div><span style="font-size:8px">$
{[Link]()}</span></td>

<td style="font-size:8px;color:#555">${[Link]!==null?
[Link]+" L/Hr":"—"}</td>

<td><span class="bdg ${low?"r":"g"}">${low?"⚠


Critical":"Adequate"}</span></td>

</tr>`;

}).join("");

// ── Utilization Heatmap ──────────────────────────────────────


function _renderHeatmap() {

const el = [Link]("util-heatmap");

if(!el) return;

const {weeks, rows} = RES_HEATMAP;

const cellColor = v => {

if(v>=90) return "#e74c3c";

if(v>=80) return "#f39c12";

if(v>=70) return "#27ae60";

if(v>=55) return "#1abc9c";

return "#d6eaf8";

};

// Header

let html = `<div style="display:flex;margin-bottom:4px;margin-


left:70px;gap:2px">` +

[Link](w=>`<div style="flex:1;text-align:center;font-size:8px;font-
weight:700;color:#0a3d1f">${w}</div>`).join("") +

`</div>`;

[Link](row => {

html += `<div style="display:flex;align-items:center;gap:2px;margin-


bottom:2px">

<div style="width:68px;font-size:8px;font-weight:700;color:#333;text-
align:right;padding-right:4px;flex-shrink:0">${[Link]}</div>` +

[Link](v=>`<div style="flex:1;height:22px;background:$
{cellColor(v)};border-radius:2px;display:flex;align-items:center;justify-
content:center">

<span style="font-size:8px;font-weight:800;color:#fff;text-shadow:0
1px 2px rgba(0,0,0,.3)">${v}%</span>

</div>`).join("") +

`</div>`;
});

// Legend

html += `<div style="display:flex;gap:8px;margin-top:6px;flex-


wrap:wrap">` +

[{c:"#e74c3c",l:"≥90% Critical"},{c:"#f39c12",l:"80-89% High"},


{c:"#27ae60",l:"70-79% Normal"},{c:"#1abc9c",l:"55-69% Low"},
{c:"#d6eaf8",l:"<55% Idle"}]

.map(i=>`<span style="display:flex;align-items:center;gap:3px;font-
size:8px;color:#555">

<span style="display:inline-block;width:10px;height:10px;background:$
{i.c};border-radius:2px"></span>${i.l}

</span>`).join("") +

`</div>`;

[Link] = html;

// ── Resource Cost Analysis ───────────────────────────────────

function _renderCostAnalysis(members, equipment, materials) {

// Cost breakdown pie

const costData = [

{label:"Labour",val:45,color:"#0a3d1f"},

{label:"Equipment",val:28,color:"#2980b9"},

{label:"Materials",val:18,color:"#27ae60"},

{label:"Fuel",val:9,color:"#d35400"},

];

_drawPie("res-cost-pie", costData);

const legend = [Link]("res-cost-legend");


if(legend) [Link] = [Link](d=>`<div
style="display:flex;align-items:center;gap:4px;margin-bottom:2px">

<span style="display:inline-block;width:9px;height:9px;background:$
{[Link]};border-radius:2px"></span>

<span style="font-size:8px;color:#333">${[Link]}: ${[Link]}%</span>

</div>`).join("");

// Monthly cost bars

const cmc = [Link]("res-cost-monthly");

if(cmc) {

const mons = RES_MONTHLY.months;

const costs = RES_MONTHLY.fuelCostK;

const budgets = RES_MONTHLY.fuelBudgetK;

const max = [Link](...budgets)*1.1;

const h = 80;

[Link] = `<div style="display:flex;align-items:flex-


end;gap:3px;height:${h}px">` +

[Link]((m,i)=>{

const bH = [Link]((budgets[i]/max)*h*0.9);

const cH = costs[i]!==null?[Link]((costs[i]/max)*h*0.9):0;

const over = costs[i]!==null && costs[i]>budgets[i];

return `<div style="flex:1;display:flex;flex-direction:column;align-


items:center">

<div style="display:flex;align-items:flex-end;gap:1px;height:$
{h*0.9}px">

<div title="Budget: ETB ${budgets[i]}K"


style="width:10px;background:#d6eaf8;border:1px solid #2980b9;border-
radius:2px 2px 0 0;height:${bH}px"></div>
${costs[i]!==null?`<div title="Actual: ETB ${costs[i]}K"
style="width:10px;background:${over?"#e74c3c":"#0a3d1f"};border-
radius:2px 2px 0 0;height:${cH}px"></div>`:

`<div style="width:10px;background:#fdebd0;opacity:.7;border-
radius:2px 2px 0 0;height:${[Link](bH*0.93)}px"></div>`}

</div>

<div style="font-size:7px;color:#555;margin-top:2px">${m}</div>

</div>`;

}).join("") +

`</div><div style="display:flex;gap:8px;font-
size:7px;color:#555;margin-top:3px">

<span><span style="display:inline-
block;width:8px;height:6px;background:#d6eaf8;border:1px solid
#2980b9;vertical-align:middle;margin-right:2px"></span>Budget</span>

<span><span style="display:inline-
block;width:8px;height:6px;background:#0a3d1f;vertical-
align:middle;margin-right:2px"></span>Actual</span>

<span><span style="display:inline-
block;width:8px;height:6px;background:#fdebd0;vertical-
align:middle;margin-right:2px"></span>Forecast</span>

</div>`;

// Cost summary

const cs = [Link]("res-cost-summary");

if(cs) {

const labourCostM = 12.4;

const equiptCostM = 7.8;

const matCostM = 5.1;

const fuelCostM = RES_FUEL.reduce((s,f)=>s+[Link],0)/1e6;


const totalM = labourCostM+equiptCostM+matCostM+fuelCostM;

[Link] = [

{lbl:"Labour (MTD)",val:"ETB "+labourCostM+"M",c:"#0a3d1f"},

{lbl:"Equipment (MTD)",val:"ETB "+equiptCostM+"M",c:"#2980b9"},

{lbl:"Materials (MTD)",val:"ETB "+matCostM+"M",c:"#27ae60"},

{lbl:"Fuel & Consumables",val:"ETB


"+[Link](1)+"M",c:"#d35400"},

{lbl:"TOTAL RESOURCE COST",val:"ETB


"+[Link](1)+"M",c:"#0a3d1f",bold:true},

].map(r=>`<div style="display:flex;justify-content:space-
between;padding:3px 0;border-bottom:1px solid #e8f0e8;font-size:$
{[Link]?"10":"9"}px;font-weight:${[Link]?"800":"600"}">

<span style="color:#555">${[Link]}</span>

<span style="color:${r.c}">${[Link]}</span>

</div>`).join("");

// ── Detail View (Planned vs Actual full register) ────────────

function _renderDetailView(members, equipment, materials) {

const el = [Link]("res-detail-content");

if(!el) return;

[Link] = `

<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px">

<div>

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:6px;letter-spacing:.3px">👷 MANPOWER — PLANNED vs
ACTUAL</div>

<table class="tbl" style="font-size:9px">


<thead><tr><th>Name</th><th>Planned Hrs</th><th>Actual
Hrs</th><th>Variance</th><th>Util
%</th><th>Status</th></tr></thead>

<tbody>${[Link](m=>{

const plannedH = [Link]([Link]*1.1*16);

const actualH = [Link]*16;

const varH = [Link](actualH-plannedH);

return `<tr>

<td style="font-weight:700">${[Link](" ")[0]}</td>

<td>${plannedH}</td>

<td>${[Link](actualH)}</td>

<td style="color:${varH>0?"#e74c3c":"#1e8449"};font-
weight:700">${varH>0?"+":""} ${varH} hrs</td>

<td><div class="pbar" style="width:40px"><div class="pbar-f"


style="width:${[Link]}%;background:${_utilColor([Link])}"></div></div>$
{[Link]}%</td>

<td><span class="bdg $
{[Link]==="Active"?"g":[Link]==="Overloaded"?"r":"o"}">$
{[Link]}</span></td>

</tr>`;

}).join("")}</tbody>

</table>

</div>

<div>

<div style="font-size:9px;font-weight:800;color:#0e6655;margin-
bottom:6px;letter-spacing:.3px">🚧 EQUIPMENT — OPERATING HOURS vs
PLANNED</div>

<table class="tbl" style="font-size:9px">

<thead><tr><th>Equipment</th><th>Planned Hrs</th><th>Actual
Hrs</th><th>Util %</th><th>Status</th></tr></thead>
<tbody>${[Link](e=>{

const plannedH = [Link]([Link]*1.08);

return `<tr>

<td style="font-weight:700;font-size:8px">$
{[Link](0,20)}</td>

<td>${plannedH}</td>

<td>${[Link]}</td>

<td><div class="pbar" style="width:35px"><div class="pbar-f"


style="width:${[Link]}%;background:${_utilColor([Link])}"></div></div>$
{[Link]}%</td>

<td><span class="bdg $
{[Link]==="Operating"?"g":[Link]==="Idle"?"b":"r"}">$
{[Link](0,8)}</span></td>

</tr>`;

}).join("")}</tbody>

</table>

</div>

<div>

<div style="font-size:9px;font-weight:800;color:#1e8449;margin-
bottom:6px;letter-spacing:.3px">🧱 MATERIALS — PLANNED vs CONSUMED vs
STOCK</div>

<table class="tbl" style="font-size:9px">

<thead><tr><th>Material</th><th>Planned</th><th>Consumed</th><t
h>Stock</th><th>Reorder</th><th>Health</th></tr></thead>

<tbody>${[Link](m=>{

const low = [Link]<=[Link];

return `<tr>

<td style="font-weight:700;font-size:8px">$
{[Link](0,18)}</td>
<td>${[Link]()}</td>

<td>${[Link]()}</td>

<td style="color:${low?"#e74c3c":"#1e8449"};font-weight:700">$
{[Link]()}</td>

<td style="font-size:8px;color:#555">$
{[Link]()}</td>

<td><span class="bdg ${low?"r":"g"}">${low?"⚠


Low":"OK"}</span></td>

</tr>`;

}).join("")}</tbody>

</table>

</div>

<div>

<div style="font-size:9px;font-weight:800;color:#d35400;margin-
bottom:6px;letter-spacing:.3px">⛽ FUEL & CONSUMABLES — MONTHLY
DETAIL</div>

<table class="tbl" style="font-size:9px">

<thead><tr><th>Item</th><th>Consumption</th><th>Cost
MTD</th><th>Stock</th><th>Status</th></tr></thead>

<tbody>${RES_FUEL.map(f=>{

const low = [Link] < [Link]*0.3;

return `<tr>

<td style="font-weight:700;font-size:8px">$
{[Link](0,16)}</td>

<td>${[Link]()} ${[Link]}</td>

<td>ETB ${([Link]/1000).toFixed(0)}K</td>

<td style="color:${low?"#e74c3c":"#1e8449"};font-weight:700">$
{[Link]()}</td>

<td><span class="bdg ${low?"r":"g"}">${low?"⚠


Critical":"OK"}</span></td>
</tr>`;

}).join("")}</tbody>

</table>

</div>

</div>`;

// ── Forecast View ────────────────────────────────────────────

function _renderForecastView(members) {

const el = [Link]("res-forecast-content");

if(!el) return;

const weeks = ["Wk 1 Jun","Wk 2 Jun","Wk 3 Jun","Wk 4 Jun"];

const demandData = {

manpower: [268,275,260,270],

equipment: [8,9,8,9],

materials: [2850,3100,2900,3200],

fuelK: [980,1050,920,1100],

};

const avail = {

manpower: [258,258,263,263],

equipment: [8,7,9,9],

};

[Link] = `

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:8px">4-WEEK DEMAND vs AVAILABILITY FORECAST</div>

<table class="tbl" style="font-size:9px;margin-bottom:10px">


<thead><tr><th>Resource Type</th>${[Link](w=>`<th>$
{w}</th>`).join("")}</tr></thead>

<tbody>

<tr style="background:#f0f8f0">

<td style="font-weight:800;color:#0a3d1f">👷 Manpower


Demand</td>

${[Link]((v,i)=>{const gap=v-
[Link][i];return `<td><b>${v}</b> <span style="font-
size:8px;color:${gap>0?"#e74c3c":"#27ae60"};font-weight:700">$
{gap>0?"▲+"+gap:"✓"}</span></td>`}).join("")}

</tr>

<tr>

<td style="color:#2980b9;font-weight:600;font-size:8px"> Available


(incl. planned hires)</td>

${[Link](v=>`<td
style="color:#2980b9">${v}</td>`).join("")}

</tr>

<tr style="background:#f0f8f8">

<td style="font-weight:800;color:#0e6655">🚧 Equipment Units


Needed</td>

${[Link]((v,i)=>{const gap=v-
[Link][i];return `<td><b>${v}</b> <span style="font-
size:8px;color:${gap>0?"#e74c3c":"#27ae60"};font-weight:700">$
{gap>0?"▲+"+gap:"✓"}</span></td>`}).join("")}

</tr>

<tr>

<td style="color:#2980b9;font-weight:600;font-size:8px"> Available


Equipment</td>

${[Link](v=>`<td
style="color:#2980b9">${v}</td>`).join("")}

</tr>
<tr style="background:#f8f0f0">

<td style="font-weight:800;color:#1e8449">🧱 Material Requirement


(units)</td>

${[Link](v=>`<td><b>$
{[Link]()}</b></td>`).join("")}

</tr>

<tr style="background:#fff8f0">

<td style="font-weight:800;color:#d35400">⛽ Fuel Forecast (ETB


'000)</td>

${[Link](v=>`<td><b>${v}</b></td>`).join("")}

</tr>

</tbody>

</table>

<div style="padding:8px;background:#fef9e7;border-
radius:4px;border:1px solid #f1c40f">

<div style="font-size:9px;font-weight:800;color:#784212;margin-
bottom:4px">⚡ FORECAST ACTIONS REQUIRED</div>

<div style="font-size:8px;color:#555;line-height:1.6">

• <b>Wk 2:</b> Manpower shortfall of 17 — initiate standby crew


activation for Indode site<br>

• <b>Wk 3:</b> Equipment unit shortage expected — coordinate


crane redeployment from Dawanle<br>

• <b>Wk 4:</b> Fuel consumption spike forecast — pre-order 30,000L


diesel by Wk 2<br>

• <b>Materials:</b> Ballast and sleeper procurement needed to


maintain 4-week buffer stock

</div>

</div>`;

}
// ── Trend Analysis View ──────────────────────────────────────

function _renderTrendView() {

const el = [Link]("res-trend-content");

if(!el) return;

const months = RES_MONTHLY.months;

// Monthly utilization trend table

[Link] = `

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:6px">MONTHLY RESOURCE UTILIZATION TREND — JAN–JUN
2026</div>

<table class="tbl" style="font-size:9px;margin-bottom:10px">

<thead><tr><th>Month</th><th>Manpower Dep.</th><th>MP Util


%</th><th>Equip Util %</th><th>Mat Consumed</th><th>Fuel Cost
K</th></tr></thead>

<tbody>

${[Link]((m,i)=>{

const mpU = RES_MONTHLY.mpActual[i]!==null?


[Link](RES_MONTHLY.mpActual[i]/RES_MONTHLY.mpPlanned[i]*100):null;

const eqU = [68,71,75,78,82,null][i];

const isCur = [Link]("*");

return `<tr ${isCur?"style='background:#fff8e1;font-


weight:700'":""}>

<td style="font-weight:700;color:${isCur?"#e74c3c":"#0a3d1f"}">$
{m}</td>

<td>${RES_MONTHLY.mpActual[i]!==null?
RES_MONTHLY.mpActual[i]:`<span style="color:#888">$
{RES_MONTHLY.mpPlanned[i]}*</span>`}</td>
<td>${mpU!==null?`<span style="color:${_utilColor(mpU)};font-
weight:700">${mpU}%</span>`:'<span
style="color:#888">Fcst</span>'}</td>

<td>${eqU!==null?`<span style="color:${_utilColor(eqU)};font-
weight:700">${eqU}%</span>`:'<span
style="color:#888">Fcst</span>'}</td>

<td>${RES_MONTHLY.matConsumed[i]!==null?
RES_MONTHLY.matConsumed[i].toLocaleString():`<span
style="color:#888">${RES_MONTHLY.matPlanned[i].toLocaleString()}*</
span>`}</td>

<td>${RES_MONTHLY.fuelCostK[i]!==null?`ETB $
{RES_MONTHLY.fuelCostK[i]}K`:'<span
style="color:#888">Fcst</span>'}</td>

</tr>`;

}).join("")}

</tbody>

</table>

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:4px">WEEKLY UTILIZATION — CURRENT WEEK SNAPSHOT</div>

<div style="display:grid;grid-template-columns:repeat(5,1fr);gap:4px">

${["Mon","Tue","Wed","Thu","Fri"].map((d,i)=>{

const vals = [82,85,80,88,86];

const c = _utilColor(vals[i]);

return `<div style="background:${c};border-radius:4px;padding:8px


4px;text-align:center">

<div
style="font-size:11px;font-weight:800;color:#fff">${vals[i]}%</div>

<div style="font-size:8px;color:rgba(255,255,255,.85)">${d}</div>

</div>`;

}).join("")}

</div>
<div style="font-size:8px;color:#888;margin-top:4px">* Current week
overall resource utilization across all resource types</div>`;

// ── Per-Project Section (Detail View) ────────────────────────

function renderPerProjectResources() {

const container = [Link]("res-per-project-sections");

if(!container) return;

const wh_colors = ["blue","green","teal","red","dark","orange","purple"];

const projectsToShow = RES_ACTIVE_PROJECT === "ALL" ? PROJECTS :


[Link](p=>String([Link])===RES_ACTIVE_PROJECT);

let html = `<div style="margin-top:6px"><div style="background:linear-


gradient(90deg,#1a252f,#2c3e50);color:#fff;padding:6px 10px;font-
size:10px;font-weight:800;letter-spacing:.6px;border-radius:5px 5px 0
0;margin-bottom:1px">📊 PER-PROJECT RESOURCE UTILIZATION
DETAIL</div></div>`;

[Link]((proj, pi) => {

const color = wh_colors[pi % wh_colors.length];

const keywords = [Link](" ").filter(w=>[Link]>3);

const projMembers = [Link](m => {

if([Link] === "All Projects") return true;

return [Link](k =>


[Link]().includes([Link]()) ||
[Link]().includes([Link]().split("/")
[0].trim().toLowerCase()));

});
const projEquipment = RES_EQUIPMENT.filter(e => [Link]==="All
Projects" ||
[Link](k=>[Link]().includes([Link]())));

const projMaterials = RES_MATERIALS.filter(m => [Link]==="All


Projects" ||
[Link](k=>[Link]().includes([Link]())));

const avgUtil = [Link] ?


[Link]([Link]((s,m)=>s+[Link],0)/[Link]) :
0;

const totalTasks = [Link]((s,m)=>s+[Link],0);

const eqOperating =
[Link](e=>[Link]==="Operating").length;

const lowStockCount =
[Link](m=>[Link]<=[Link]).length;

html += `<div class="row" style="margin-bottom:8px">

<div class="widget f1">

<div class="wh ${color}" style="display:flex;align-items:center;justify-


content:space-between">

<span>📁 ${[Link]()}</span>

<span style="font-size:9px;opacity:.85">Project Manager: $


{[Link]} &nbsp;|&nbsp; Phase: ${[Link]} &nbsp;|&nbsp;
Progress: ${[Link]}%</span>

</div>

<div class="wb">

<div style="display:flex;gap:6px;margin-bottom:8px;flex-wrap:wrap">

<div class="kpi green-kpi" style="min-width:80px;padding:5px


8px"><div class="kpi-val" style="font-size:14px">$
{[Link]}</div><div class="kpi-lbl">Personnel</div></div>

<div class="kpi blue-kpi" style="min-width:80px;padding:5px


8px"><div class="kpi-val" style="font-size:14px">${avgUtil}%</div><div
class="kpi-lbl">MP Utilization</div></div>
<div class="kpi orange-kpi" style="min-width:80px;padding:5px
8px"><div class="kpi-val" style="font-size:14px">${totalTasks}</div><div
class="kpi-lbl">Active Tasks</div></div>

<div class="kpi $
{[Link](m=>[Link]==="Overloaded").length>0?"red-
kpi":"green-kpi"}" style="min-width:80px;padding:5px 8px"><div
class="kpi-val" style="font-size:14px">$
{[Link](m=>[Link]==="Overloaded").length}</div><div
class="kpi-lbl">Overloaded</div></div>

<div class="kpi teal-kpi" style="min-width:80px;padding:5px


8px;border-left-color:#17a589"><div class="kpi-val" style="font-
size:14px;color:#17a589">${eqOperating}/${[Link]}</
div><div class="kpi-lbl">Equip Active</div></div>

<div class="kpi ${lowStockCount>0?"red-kpi":"green-kpi"}"


style="min-width:80px;padding:5px 8px"><div class="kpi-val" style="font-
size:14px">${lowStockCount}</div><div class="kpi-lbl">Low
Stock</div></div>

</div>

<div style="display:flex;gap:8px;flex-wrap:wrap">

<div style="flex:2;min-width:250px">

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:4px">TEAM ALLOCATION</div>

<table class="tbl" style="font-size:9px">

<thead><tr><th>Name</th><th>Role</th><th>Utilization</th><th>Tas
ks</th><th>Status</th>${editMode?"<th>Edit</th>":""}</tr></thead>

<tbody>${[Link]((m,mi)=>{

const gi=[Link](m);

return `<tr>

<td>${[Link](" ")[0]}</td>

<td style="font-size:8px;color:#555">${[Link]}</td>
<td><div style="display:flex;align-items:center;gap:3px"><div
class="pbar" style="width:50px"><div class="pbar-f" style="width:$
{[Link]}%;background:${_utilColor([Link])}"></div></div>${editMode?
`<input type="number" min="0" max="100" value="${[Link]}"
onchange="MEMBERS[${gi}].util=+[Link];renderResources()"
style="width:32px;font-size:8px;border:1px solid #c8d8c8;border-
radius:2px;padding:1px;font-family:inherit">%`:`<span style="font-
size:8px;color:${_utilColor([Link])}">${[Link]}%</span>`}</div></td>

<td style="text-align:center">${[Link]}</td>

<td><span class="bdg $
{[Link]==="Active"?"g":[Link]==="Overloaded"?"r":"o"}">$
{[Link]}</span></td>

${editMode?`<td><button class="edit-btn"
onclick="openModal('edit-member',${gi})">✏</button></td>`:""}

</tr>`;

}).join("")}</tbody>

</table>

</div>

<div style="flex:1;min-width:140px">

<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:4px">UTILIZATION CHART</div>

${[Link](m=>`<div class="hbr" style="margin-


bottom:2px">

<div class="hbr-lbl sm" style="font-size:8px;width:70px">$


{[Link](" ")[0]}</div>

<div class="hbr-track"><div class="hbr-fill" style="width:$


{[Link]}%;background:${_utilColor([Link])}">${[Link]}%</div></div>

</div>`).join("")}

<div style="font-size:9px;font-
weight:800;color:#0e6655;margin:8px 0 4px">EQUIPMENT STATUS</div>

${[Link](0,3).map(e=>`<div style="display:flex;align-
items:center;gap:5px;margin-bottom:2px;font-size:8px">
<span class="bdg $
{[Link]==="Operating"?"g":[Link]==="Idle"?"b":"r"}" style="font-
size:7px">${[Link](0,4)}</span>

<span style="color:#333;overflow:hidden;text-
overflow:ellipsis;white-space:nowrap">${[Link](0,18)}</span>

</div>`).join("")}

${editMode?`<div style="margin-top:6px"><textarea
onblur="[Link]='1'" style="width:100%;height:36px;font-
size:8px;border:1px solid #c8d8c8;border-radius:3px;padding:3px;font-
family:inherit;resize:none" placeholder="Add resource
notes..."></textarea></div>`:""}

</div>

</div>

</div>

</div>

</div>`;

});

[Link] = html;

//
═══════════════════════════════════════════════════════
════════
// RISKS

//
═══════════════════════════════════════════════════════
════════
function renderRisks() {

const open=[Link](r=>[Link]==="Open").length;

const high=[Link](r=>[Link]==="High"&&[Link]==="Open").length;
const
med=[Link](r=>[Link]==="Medium"&&[Link]==="Open").length;

const low=[Link](r=>[Link]==="Low"&&[Link]==="Open").length;

const mit=[Link](r=>[Link]==="Mitigated").length;

const rc=[Link]("risk-count"); if(rc)


[Link]=open;

const rh=[Link]("risk-high-count"); if(rh)


[Link]=high;

const rm=[Link]("risk-med-count"); if(rm)


[Link]=med;

const rl=[Link]("risk-low-count"); if(rl)


[Link]=low;

const rmit=[Link]("risk-mit-count"); if(rmit)


[Link]=mit;

const kpiRisks=[Link]("kpi-risks"); if(kpiRisks)


[Link]=open;

const tbody=[Link]("risk-tbody");

if(!tbody) return;

[Link]=[Link]((r,i)=>`<tr>

<td style="font-weight:700;color:#0a3d1f">${[Link]}</td>

<td>${[Link]}</td>

<td style="font-size:9px">${[Link](0,25)}...</td>

<td><span class="bdg $
{[Link]==="High"?"r":[Link]==="Medium"?"o":"g"}">${[Link]}</span></td>

<td>${[Link]}</td>

<td>${[Link]}</td>

<td><span class="bdg
${[Link]==="Open"?"r":"g"}">${[Link]}</span></td>

<td>${[Link](" ")[0]}</td>
<td style="font-size:9px;color:#555">${[Link]}</td>

<td style="font-size:9px;color:#555;max-
width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"
title="${[Link]}">${[Link]}</td>

${editMode?`<td><button class="edit-btn" onclick="openModal('edit-


risk',${i})">✏</button> <button class="edit-btn red" onclick="deleteRisk($
{i})">✕</button></td>`:""}

</tr>`).join("");

//
═══════════════════════════════════════════════════════
════════
// SETTINGS

//
═══════════════════════════════════════════════════════
════════
// User Management Tab switcher

function showUMTab(tab) {

["users","roles","assign","audit"].forEach(t => {

const panel = [Link]("umpanel-"+t);

const btn = [Link]("umtab-"+t);

if (panel) [Link] = t === tab ? "" : "none";

if (btn) {

[Link] = t === tab ? "#0a3d1f" : "transparent";

[Link] = t === tab ? "#fff" : "#0a3d1f";

[Link]= t === tab ? "2px solid #27ae60" : "2px solid


transparent";

});
// Populate the selected panel

if (tab === "assign") _renderAssignments();

if (tab === "audit") _renderUMAudit();

function _renderAssignments() {

const tb = [Link]("assign-tbody");

if (!tb) return;

[Link] = [Link](p => {

const statusClass = [Link]==="On Track"?"g":[Link]==="At


Risk"?"o":"r";

return `<tr>

<td style="font-weight:700;color:#0a3d1f;max-
width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"
title="${[Link]}">${[Link]>28?
[Link](0,26)+"…":[Link]}</td>

<td style="font-weight:700;color:#1a5276">👤 ${[Link]}</td>

<td><span class="bdg b" style="font-size:8px">${[Link]>12?


[Link](0,11)+"…":[Link]}</span></td>

<td><div style="display:flex;align-items:center;gap:4px"><div
class="pbar" style="flex:1;min-width:40px"><div class="pbar-f"
style="width:${[Link]}%;background:${[Link]}"></div></div><span
style="font-size:9px;font-weight:700">${[Link]}%</span></div></td>

<td><span class="bdg ${statusClass}">${[Link]}</span></td>

</tr>`;

}).join("");

function _renderUMAudit() {
const tb = [Link]("um-audit-tbody");

const sm = [Link]("um-audit-summary");

if (!tb) return;

const recent = (AUDIT_LOG || []).slice(0, 15);

[Link] = [Link](e => {

const actionColors =
{"Login":"#d6eaf8","Logout":"#eaecee","Add":"#d4efdf","Edit":"#fff3cd","D
elete":"#fadbd8","Report Generated":"#e8daef","Settings
Modified":"#fdebd0"};

const ac = actionColors[[Link]] || "#f4f9f2";

return `<tr>

<td style="font-size:9px;white-space:nowrap;color:#555">${[Link]}</td>

<td style="font-weight:600;font-size:9px">${[Link]}</td>

<td><span style="display:inline-block;padding:2px 7px;border-


radius:10px;font-size:8px;font-weight:800;background:${ac};color:#333">$
{[Link]}</span></td>

<td style="font-size:9px;color:#0a3d1f;font-weight:700">$
{[Link]}</td>

<td style="font-size:9px;color:#555;max-
width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"
title="${[Link]}">${[Link]}</td>

</tr>`;

}).join("") || `<tr><td colspan="5" style="text-


align:center;color:#bbb;padding:15px;">No audit entries found</td></tr>`;

if (sm) {

const loginCount = (AUDIT_LOG||[]).filter(e=>[Link]==="Login").length;

const editCount = (AUDIT_LOG||


[]).filter(e=>["Add","Edit","Delete"].includes([Link])).length;

[Link] = [
["🔐 Logins",loginCount,"#2980b9"],

["✏ Changes",editCount,"#27ae60"],

["📋 Total",( AUDIT_LOG||[]).length,"#0a3d1f"],

].map(([l,v,c])=>`<div style="background:#f8fdf8;border:1px solid


#c8d8c8;border-radius:4px;padding:5px 10px;display:flex;flex-
direction:column;align-items:center;border-left:3px solid ${c}">

<div style="font-size:15px;font-weight:800;color:${c}">${v}</div>

<div style="font-size:8px;color:#555;font-weight:700;white-
space:nowrap">${l}</div>

</div>`).join("");

// ── canManageUsers: only admin-tier roles may manage other users ──

function canManageUsers() {

return currentUser && ([Link] === "chief_admin" ||


[Link] === "admin");

// ── renderUsersTable: respects RBAC, search & filter ──

function renderUsersTable() {

const ut = [Link]("users-tbody");

if (!ut) return;

// Access-restriction notice

const notice = [Link]("um-restricted-notice");

const addBtn = [Link]("um-add-btn");

if (notice) [Link] = canManageUsers() ? "none" : "";


if (addBtn) [Link] = canManageUsers() ? "" : "none";

// Filters

const q = ([Link]("um-search")||{}).value||"";

const roleF = ([Link]("um-filter-role")||{}).value||"";

const statF = ([Link]("um-filter-status")||{}).value||"";

let list = USERS;

// Non-admins can only see their own record

if (!canManageUsers() && currentUser) {

list = [Link](u => [Link] === [Link] || [Link]


=== [Link]);

if (q) list = [Link](u => ([Link]+[Link]+[Link]+[Link]+


([Link]||[]).join(",")).toLowerCase().includes([Link]()));

if (roleF) list = [Link](u => [Link] === roleF);

if (statF) list = [Link](u => [Link] === statF);

const roleColor = r => r==="Administrator"?"#c0392b":r==="Project


Manager"?"#1e8449":"#2980b9";

const roleBadge = r => r==="Administrator"?"r":r==="Project


Manager"?"g":"b";

[Link] = [Link]((u, i) => {

const globalIdx = [Link](u);

const projects = ([Link]||[]).join(", ") || "—";

const pwHash = [Link] || "—";

const isMe = currentUser && ([Link] === [Link]);


const canAct = canManageUsers();

return `<tr style="${isMe?"background:#f0fff4;":""}" title="${isMe?"Your


account":""}">

<td style="color:#888;font-size:9px">${i+1}</td>

<td style="font-weight:700;color:#0a3d1f;white-space:nowrap">$
{[Link]}${isMe?' <span style="font-
size:8px;background:#d4efdf;color:#1e8449;padding:1px 5px;border-
radius:8px;font-weight:600">you</span>':''}</td>

<td style="font-size:9px;color:#555;font-family:monospace">$
{[Link]}</td>

<td><a href="[Link] style="color:#2980b9;font-


size:9px">${[Link]}</a></td>

<td><span class="bdg ${roleBadge([Link])}" style="background:$


{roleColor([Link])}22;color:${roleColor([Link])};border:1px solid $
{roleColor([Link])}44">${[Link]}</span></td>

<td style="font-size:8px;color:#555;max-width:120px;white-
space:nowrap;overflow:hidden;text-overflow:ellipsis" title="${projects}">$
{projects}</td>

<td style="font-family:monospace;font-size:9px;color:#333">$
{pwHash}</td>

<td><span class="bdg ${[Link]==="Active"?"g":"gr"}">$


{[Link]}</span></td>

<td style="font-size:9px;color:#555;white-space:nowrap">$
{[Link]||"—"}</td>

<td style="font-size:9px;color:#555;white-space:nowrap">$
{[Link]||"—"}</td>

<td style="white-space:nowrap">

${canAct ? `<button class="edit-btn" onclick="openUserModal('edit',$


{globalIdx})" title="Edit user">✏</button>

<button class="edit-btn" onclick="toggleUserStatus(${globalIdx})"


title="${[Link]==='Active'?'Deactivate':'Activate'}" style="background:$
{[Link]==='Active'?'#f39c12':'#27ae60'};color:#fff;border-color:$
{[Link]==='Active'?'#d68910':'#1e8449'}">$
{[Link]==='Active'?'⏸':'▶'}</button>

<button class="edit-btn red" onclick="deleteUserConfirm($


{globalIdx})" title="Delete user">✕</button>` : `<span style="font-
size:9px;color:#aaa">—</span>`}

</td>

</tr>`;

}).join("") || `<tr><td colspan="11" style="text-


align:center;color:#bbb;padding:16px;font-size:10px">No users match the
current filters.</td></tr>`;

// Footer count

const foot = [Link]("um-table-footer");

if (foot) [Link] = `Showing ${[Link]} of ${[Link]}


users`;

// KPI strip

const kpi = [Link]("um-kpi-strip");

if (kpi) {

const active = [Link](u=>[Link]==="Active").length;

const admins = [Link](u=>[Link]==="Administrator").length;

const pms = [Link](u=>[Link]==="Project Manager").length;

const viewers = [Link](u=>[Link]==="Viewer").length;

[Link] = [

["👥 Total Users", [Link], "#0a3d1f"],

["✅ Active", active, "#27ae60"],

[" Administrators", admins, "#c0392b"],

["👤 Project Managers", pms, "#1e8449"],

[" Viewers", viewers, "#2980b9"],


].map(([l,v,c])=>`<div style="background:#f8fdf8;border:1px solid
#c8d8c8;border-radius:4px;padding:5px 10px;display:flex;flex-
direction:column;align-items:center;min-width:72px;border-left:3px solid $
{c}">

<div style="font-size:15px;font-weight:800;color:${c}">${v}</div>

<div style="font-size:7.5px;color:#555;font-weight:700;white-
space:nowrap;text-align:center">${l}</div>

</div>`).join("");

function renderSettings() {

// Show Chief Admin panel if logged in as Chief Admin

const caPanel = [Link]("chief-admin-panel");

if(caPanel) [Link] = (currentUser && [Link] ===


"chief_admin") ? "" : "none";

// Render the full user table

renderUsersTable();

// Email digest

const ed=[Link]("email-digest-list");

if(ed) [Link]=[Link]((m,i)=>`<div style="display:flex;align-


items:center;gap:6px;padding:5px 0;border-bottom:1px solid #e8f0e8;flex-
wrap:wrap">

<div style="width:110px;font-size:9px;font-weight:700;color:#0a3d1f;flex-
shrink:0">${[Link](" ").slice(0,2).join(" ")}</div>

<input value="${[Link]}" onchange="MEMBERS[$


{i}].email=[Link]" style="flex:1;min-width:160px;font-
size:9px;border:1px solid #c8d8c8;border-radius:3px;padding:3px 6px;font-
family:inherit"/>

<label style="display:flex;align-items:center;gap:3px;font-
size:9px;cursor:pointer"><input type="checkbox" checked/> Digest</label>

<label style="display:flex;align-items:center;gap:3px;font-
size:9px;cursor:pointer"><input type="checkbox" $
{[Link]("Manager")||[Link]("Director")||
[Link]("Chief")?"checked":""}/> Alerts</label>

</div>`).join("");

// Notification prefs

const np=[Link]("notif-prefs");

if(np) [Link]=[

["Daily Email Digest","on"],["Risk Escalation Alerts","on"],["Budget


Warning (>80%)","on"],

["Milestone Reminders (3 days)","on"],["Overdue Task Alerts","on"],


["Weekly PMO Report","on"],["Monthly Executive Summary","off"],

].map(([l,s])=>`<div class="notif-row">

<span style="font-size:10px">${l}</span>

<div class="toggle-sw ${s==="on"?"on":""}"


onclick="[Link]('on')"><div
class="toggle-thumb"></div></div>

</div>`).join("");

// Integrations

const il=[Link]("integrations-list");

if(il) [Link]=[

["Microsoft Teams","Connected","g"],["Email (SMTP)","Connected","g"],


["SharePoint","Connected","g"],
["GIS Mapping","Connected","g"],["SAP Finance
System","Disconnected","gr"],["Primavera P6","Disconnected","gr"],

].map(([n,s,c])=>`<div class="notif-row"><span style="font-size:10px">$


{n}</span><span class="bdg ${c}">${s}</span></div>`).join("");

function renderReportHistory() {

const tb=[Link]("report-history-tbody");

if(!tb) return;

[Link]=REPORT_HISTORY.map((r,i)=>`<tr>

<td style="max-width:200px;overflow:hidden;text-overflow:ellipsis;white-
space:nowrap;" title="${[Link]}">${[Link]}</td>

<td><span class="bdg b">${[Link]}</span></td>

<td>${[Link]}</td><td>${[Link]}</td>

<td style="font-size:9px;color:#555">${[Link]}</td>

<td><span class="bdg g">${[Link]}</span></td>

<td><span
class="rpt-ver-badge">v${(REPORT_HISTORY.length-i)}</span></td>

<td style="white-space:nowrap;display:flex;gap:3px;flex-wrap:wrap;">

<button class="rpt-action-mini green"


onclick="downloadHistoryReport('${[Link](/'/g,"\\'")}','$
{[Link]}',this)">⬇ Download</button>

<button class="rpt-action-mini blue" onclick="toast('👁 Viewing: $


{[Link](0,30).replace(/'/g,"\\'")}')">👁 View</button>

<button class="rpt-action-mini orange" onclick="toast('📧 Emailing: $


{[Link](0,30).replace(/'/g,"\\'")}')">📧 Email</button>

<button class="rpt-action-mini gray" onclick="toast('🗄 Archived: $


{[Link](0,30).replace(/'/g,"\\'")}')">🗄 Archive</button>

<button class="rpt-action-mini red" onclick="REPORT_HISTORY.splice($


{i},1);renderReportHistory();toast('🗑 Deleted')">✕</button>
</td>

</tr>`).join("");

// ── PMO Report Module v2 helpers ─────────────────────────────

function _rptFmt(v){ return v==null||isNaN(v)?"N/A":"ETB


"+(v>=1e9?(v/1e9).toFixed(2)+"B":(v/1e6).toFixed(0)+"M"); }

function _rptPct(a,b){ return


(!a||!b||isNaN(a)||isNaN(b))?"N/A":[Link](a/b*100)+"%"; }

function _rptStatusBadge(pct){

if(isNaN(pct)) return '<span class="rpt-status-badge


rsb-warning">N/A</span>';

if(pct>90) return '<span class="rpt-status-badge rsb-critical">🔴


Critical</span>';

if(pct>70) return '<span class="rpt-status-badge rsb-warning">🟡


Warning</span>';

return '<span class="rpt-status-badge rsb-healthy">🟢 Healthy</span>';

// Sort state

var _rptSortCol=-1, _rptSortAsc=true, _rptFiltered=null;

var rptPage=1, rptRowsPerPage=10;

function _getRptProjects(){

return (_rptFiltered!==null ? _rptFiltered : (typeof PROJECTS!


=="undefined"?PROJECTS:[]));

}
function initRptModule(){

_buildRptFilters();

renderRptKPIs();

renderRptExecSummary();

renderRptCharts();

renderRptTable();

renderRptPhiGrid();

function _buildRptFilters(){

if(typeof PROJECTS==="undefined") return;

var ps=[Link]("rptf-project");

var ms=[Link]("rptf-manager");

if(ps && [Link]<=1) [Link](p=>{var


o=[Link]("option");[Link]=[Link];[Link]=[Link]
ngth>40?[Link](0,38)+"…":[Link];[Link](o);});

if(ms && [Link]<=1){var seen={};[Link](p=>{if(!


seen[[Link]]){seen[[Link]]=1;var
o=[Link]("option");[Link]=[Link];[Link]=p.
manager;[Link](o);}});}

function applyRptFilters(){

if(typeof PROJECTS==="undefined") return;

var proj=[Link]("rptf-project").value;

var stat=[Link]("rptf-status").value;

var mgr =[Link]("rptf-manager").value;

var phase=[Link]("rptf-phase").value;
var bud =[Link]("rptf-budget").value;

_rptFiltered=[Link](p=>{

if(proj && [Link]!=proj) return false;

if(stat && [Link]!==stat) return false;

if(mgr && [Link]!==mgr) return false;

if(phase && [Link]!==phase) return false;

if(bud){

var bM=[Link]/1e6;

if(bud==="0-500" && bM>=500) return false;

if(bud==="500-800" && (bM<500||bM>=800)) return false;

if(bud==="800+" && bM<800) return false;

return true;

});

rptPage=1;

renderRptKPIs(); renderRptExecSummary(); renderRptCharts();


renderRptTable();

function clearRptFilters(){

["rptf-project","rptf-status","rptf-manager","rptf-phase","rptf-
budget"].forEach(id=>{var
el=[Link](id);if(el)[Link]="";});

_rptFiltered=null; rptPage=1;

renderRptKPIs(); renderRptExecSummary(); renderRptCharts();


renderRptTable();

}
function renderRptKPIs(){

var projs=_getRptProjects(); if(![Link]) return;

var totBudget=[Link]((s,p)=>s+([Link]||0),0);

var totSpent =[Link]((s,p)=>s+([Link]||0),0);

var remaining=totBudget-totSpent;

var utilPct =totBudget>0?[Link](totSpent/totBudget*100):0;

var atRisk =[Link](p=>[Link]==="At Risk"||


[Link]==="Delayed").length;

var overBudget=[Link](p=>[Link]>[Link]).length;

var el=[Link]("rpt-kpi-strip"); if(!el) return;

[Link]=`

<div class="rpt-kpi-card"><div class="rpt-kpi-icon">💰</div><div


class="rpt-kpi-body"><div
class="rpt-kpi-val">${_rptFmt(totBudget)}</div><div class="rpt-kpi-
lbl">Total Portfolio Budget</div><div class="rpt-kpi-sub">${[Link]}
Active Projects</div></div></div>

<div class="rpt-kpi-card blue"><div class="rpt-kpi-icon">📤</div><div


class="rpt-kpi-body"><div
class="rpt-kpi-val">${_rptFmt(totSpent)}</div><div class="rpt-kpi-
lbl">Total Spent (Actual)</div><div class="rpt-kpi-sub">${utilPct}%
Portfolio Utilization</div></div></div>

<div class="rpt-kpi-card teal"><div class="rpt-kpi-icon">💵</div><div


class="rpt-kpi-body"><div
class="rpt-kpi-val">${_rptFmt(remaining)}</div><div class="rpt-kpi-
lbl">Remaining Budget</div><div class="rpt-kpi-sub">${100-utilPct}%
Available</div></div></div>

<div class="rpt-kpi-card"><div class="rpt-kpi-icon">📁</div><div


class="rpt-kpi-body"><div class="rpt-kpi-val">${[Link]}</div><div
class="rpt-kpi-lbl">Active Projects</div><div class="rpt-kpi-sub">In
Portfolio</div></div></div>

<div class="rpt-kpi-card ${atRisk>0?"red":""}"><div class="rpt-kpi-


icon">⚠</div><div class="rpt-kpi-body"><div class="rpt-kpi-val">$
{atRisk}</div><div class="rpt-kpi-lbl">Projects At Risk</div><div
class="rpt-kpi-sub">Require Attention</div></div></div>

<div class="rpt-kpi-card ${overBudget>0?"orange":""}"><div class="rpt-


kpi-icon">📈</div><div class="rpt-kpi-body"><div class="rpt-kpi-val">$
{overBudget}</div><div class="rpt-kpi-lbl">Over Budget</div><div
class="rpt-kpi-sub">Exceeding Approved</div></div></div>

`;

function renderRptExecSummary(){

var projs=_getRptProjects(); if(![Link]) return;

var totBudget=[Link]((s,p)=>s+([Link]||0),0);

var totSpent =[Link]((s,p)=>s+([Link]||0),0);

var utilPct =totBudget>0?[Link](totSpent/totBudget*100):0;

var atRisk =[Link](p=>[Link]==="At Risk"||


[Link]==="Delayed");

var overBudget=[Link](p=>[Link]>[Link]);

var avgCPI
=[Link]((s,p)=>s+([Link]>0?([Link]/100*[Link])/[Link]),
0)/[Link];

var attention = [Link]+[Link];

var el=[Link]("rpt-exec-summary-panel"); if(!el) return;

var warnTxt = attention>0

? `<strong>${attention} project${attention>1?"s":""} require$


{attention===1?"s":""} management attention</strong> — $
{[Link]} at risk${[Link]>0?", "+[Link]+"
over budget":""}.`

: "All projects are within budget and on track.";

[Link]=`
<div class="rpt-exec-summary-hdr">📝 Automated Executive
Summary</div>

<div class="rpt-exec-summary-text">

The total EDR project portfolio budget is <strong>$


{_rptFmt(totBudget)}</strong> across <strong>${[Link]} active
projects</strong>.

Current total expenditure is <strong>${_rptFmt(totSpent)}</strong>,


representing <strong>${utilPct}% portfolio utilisation</strong>.

The remaining unspent balance is <strong>${_rptFmt(totBudget-


totSpent)}</strong>.

The aggregate Cost Performance Index (CPI) is <strong>$


{[Link](2)}</strong> — ${avgCPI>=1?"indicating cost efficiency
above target":"indicating costs are running above planned value"}.

${warnTxt}

</div>`;

// data quality check

var incomplete=[Link](p=>![Link]||![Link]||isNaN([Link])||
isNaN([Link]));

var wEl=[Link]("rpt-data-warn");

var wTxt=[Link]("rpt-data-warn-text");

if(wEl&&wTxt){

if([Link]>0){[Link]="flex";[Link]=`Data
quality: ${[Link]} project(s) have missing or invalid
budget/expenditure data. Some values shown as N/A.`;}

else{[Link]="none";}

function renderRptCharts(){

var projs=_getRptProjects(); if(![Link]) return;


var totBudget=[Link]((s,p)=>s+([Link]||0),0);

var totSpent =[Link]((s,p)=>s+([Link]||0),0);

// 1. Budget vs Actual bar chart

var bva=[Link]("rpt-chart-bva"); if(bva){

var maxB=[Link](null,[Link](p=>[Link]([Link]||
0,[Link]||0)));

[Link]=[Link](p=>{

var bn=[Link](([Link]||0)/1e6); var


sn=[Link](([Link]||0)/1e6);

var bw=maxB>0?[Link](([Link]||0)/maxB*100):0; var


sw=maxB>0?[Link](([Link]||0)/maxB*100):0;

var pct=[Link]>0?[Link]([Link]/[Link]*100):0;

var col=pct>90?"#e74c3c":pct>70?"#f39c12":"#27ae60";

var nm=[Link]>32?[Link](0,30)+"…":[Link];

return `<div class="rpt-bar-row" title="${[Link]} — Budget: ETB $


{bn}M, Actual: ETB ${sn}M">

<div class="rpt-bar-lbl">${nm}</div>

<div style="flex:1;display:flex;flex-direction:column;gap:2px;">

<div class="rpt-bar-track" title="Budget: ETB ${bn}M"><div


class="rpt-bar-fill" style="width:${bw}%;background:#27ae6033;border:1px
solid #27ae60;"></div></div>

<div class="rpt-bar-track" title="Actual: ETB ${sn}M"><div


class="rpt-bar-fill"
style="width:${sw}%;background:${col};"></div></div>

</div>

<div class="rpt-bar-pct" style="color:${col}">${pct}%</div>

</div>`;

}).join("")+`<div style="display:flex;gap:12px;margin-top:6px;font-
size:8px;"><span><span style="display:inline-
block;width:10px;height:6px;background:#27ae6033;border:1px solid
#27ae60;border-radius:1px;margin-right:3px;vertical-align:middle;"></
span>Budget</span><span><span style="display:inline-
block;width:10px;height:6px;background:#27ae60;border-radius:1px;margin-
right:3px;vertical-align:middle;"></span>Actual</span></div>`;

// 2. Donut chart (cost utilization)

var donut=[Link]("rpt-chart-donut"); if(donut){

var pct=totBudget>0?[Link](totSpent/totBudget*100):0;

var r=44, cx=54, cy=54, circ=2*[Link]*r;

var col=pct>90?"#e74c3c":pct>70?"#f39c12":"#27ae60";

var dash=circ*pct/100;

[Link]=`<div class="rpt-donut-wrap">

<svg width="108" height="108" viewBox="0 0 108 108">

<circle cx="${cx}" cy="${cy}" r="${r}" fill="none" stroke="#e8f0e8"


stroke-width="14"/>

<circle cx="${cx}" cy="${cy}" r="${r}" fill="none" stroke="${col}"


stroke-width="14"

stroke-dasharray="${dash} ${circ}" stroke-dashoffset="${circ/4}"


stroke-linecap="round" style="transition:stroke-dasharray .8s ease;"/>

<text x="${cx}" y="${cy-6}" text-anchor="middle" style="font-


size:16px;font-weight:800;fill:${col}">${pct}%</text>

<text x="${cx}" y="${cy+10}" text-anchor="middle" style="font-


size:8px;fill:#888">Used</text>

</svg>

<div class="rpt-donut-legend">

<div class="rpt-donut-leg-item"><div class="rpt-donut-dot"


style="background:${col}"></div>Spent: ${_rptFmt(totSpent)}</div>
<div class="rpt-donut-leg-item"><div class="rpt-donut-dot"
style="background:#e8f0e8"></div>Remaining: ${_rptFmt(totBudget-
totSpent)}</div>

<div class="rpt-donut-leg-item"><div class="rpt-donut-dot"


style="background:#0a3d1f"></div>Total: ${_rptFmt(totBudget)}</div>

</div>

</div>`;

// 3. Monthly trend

var trend=[Link]("rpt-chart-trend"); if(trend){

var
months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","
Dec"];

var planned=[240,280,310,330,360,350,380,390,400,390,360,340];

var actual =[220,260,295,310,null,null,null,null,null,null,null,null];

var maxV=[Link](null,planned);

[Link]=`<div class="rpt-trend-row">${[Link]((m,i)=>{

var pw=[Link]((planned[i]||0)/maxV*100);

var aw=actual[i]!=null?[Link](actual[i]/maxV*100):0;

var col=actual[i]!=null?
(actual[i]>planned[i]?"#e74c3c":"#27ae60"):"#c8d8c8";

return `<div class="rpt-trend-bar-wrap" title="${m}: Plan $


{planned[i]}M${actual[i]!=null?', Actual '+actual[i]+'M':''}">

<div style="display:flex;align-items:flex-end;gap:1px;height:72px;">

<div class="rpt-trend-bar" style="height:${pw}


%;background:#27ae6033;border:1px solid #27ae60;width:8px;border-
radius:2px 2px 0 0;"></div>

${actual[i]!=null?`<div class="rpt-trend-bar" style="height:${aw}


%;background:${col};width:8px;"></div>`:""}
</div>

<div class="rpt-trend-lbl">${m}</div>

</div>`;

}).join("")}</div>

<div style="display:flex;gap:12px;margin-top:4px;font-size:8px;justify-
content:center;">

<span><span style="display:inline-
block;width:8px;height:8px;background:#27ae6033;border:1px solid
#27ae60;border-radius:1px;margin-right:2px;vertical-align:middle;"></
span>Planned</span>

<span><span style="display:inline-
block;width:8px;height:8px;background:#27ae60;border-radius:1px;margin-
right:2px;vertical-align:middle;"></span>Actual</span>

</div>`;

// 4. Variance chart

var varc=[Link]("rpt-chart-variance"); if(varc){

[Link]=[Link](p=>{

var v=([Link]||0)-([Link]||0); var vM=[Link](v/1e6);

var maxV2=[Link](null,[Link](x=>[Link](([Link]||0)-
([Link]||0))));

var w=maxV2>0?[Link]([Link](v)/maxV2*50):0;

var col=v<0?"#e74c3c":v<[Link]*0.1?"#f39c12":"#27ae60";

var left=v<0?50-w:50; var dir=v<0?"right":"left";

var nm=[Link]>20?[Link](0,18)+"…":[Link];

return `<div class="rpt-variance-row" title="${[Link]}: Variance ETB $


{vM}M">

<div class="rpt-var-lbl">${nm}</div>
<div class="rpt-var-track">

<div class="rpt-var-zero"></div>

<div class="rpt-var-fill" style="width:${w}%;left:${left}


%;background:${col};"></div>

</div>

<div class="rpt-var-amt" style="color:${col}">${v>=0?"+":""}$


{vM}M</div>

</div>`;

}).join("");

function renderRptTable(){

var projs=_getRptProjects();

// search filter

var q=([Link]("rpt-tbl-search")||{}).value||"";

if(q)
{ projs=[Link](p=>[Link]().includes([Link]())||
[Link]().includes([Link]())); }

// sort

if(_rptSortCol>=0){

projs=[...projs].sort((a,b)=>{

var va,vb;

if(_rptSortCol===0){va=[Link];vb=[Link];}

else if(_rptSortCol===1){va=[Link]||0;vb=[Link]||0;}

else if(_rptSortCol===2){va=[Link]||0;vb=[Link]||0;}

else
if(_rptSortCol===3){va=[Link]>0?[Link]/[Link];vb=[Link]>0?
[Link]/[Link];}
else if(_rptSortCol===4){va=([Link]||0)-([Link]||0);vb=([Link]||
0)-([Link]||0);}

else
if(_rptSortCol===5){va=[Link]>0?([Link]/100*[Link])/[Link];vb
=[Link]>0?([Link]/100*[Link])/[Link];}

else if(_rptSortCol===6){va=[Link];vb=[Link];}

if(typeof va==="string") return _rptSortAsc?


[Link](vb):[Link](va);

return _rptSortAsc?va-vb:vb-va;

});

// paginate

var total=[Link],
pages=[Link](1,[Link](total/rptRowsPerPage));

if(rptPage>pages) rptPage=pages;

var start=(rptPage-1)*rptRowsPerPage,
end=[Link](start+rptRowsPerPage,total);

var pg=[Link](start,end);

var tb=[Link]("rpt-cost-tbody"); if(!tb) return;

[Link]=[Link](p=>{

var bud=[Link]||0, spt=[Link]||0;

var pct=bud>0?[Link](spt/bud*100):NaN;

var variance=bud-spt; var vM=[Link](variance/1e6);

var cpi=spt>0?parseFloat((([Link]/100*bud)/spt).toFixed(2)):1.00;

var
spi=parseFloat(([Link]/100/([Link]([Link]/100+0.05,1))).toFixed(
2));

var eac=cpi>0?[Link](bud/cpi):bud;

var
vcol=variance<0?"#c0392b":variance<bud*0.1?"#d35400":"#1e8449";
var cpicol=cpi>=1?"#1e8449":"#c0392b";

return `<tr>

<td title="${[Link]}">${[Link]>35?
[Link](0,33)+"…":[Link]}</td>

<td>${_rptFmt(bud)}</td>

<td>${_rptFmt(spt)}</td>

<td><div style="display:flex;align-items:center;gap:4px;">

<div style="flex:1;height:8px;background:#e8f0e8;border-
radius:3px;overflow:hidden;min-width:40px;"><div
style="height:100%;width:${[Link](isNaN(pct)?0:pct,100)}
%;background:${pct>90?"#e74c3c":pct>70?"#f39c12":"#27ae60"};border-
radius:3px;"></div></div>

<span style="font-size:9px;font-weight:700;color:$
{pct>90?"#c0392b":pct>70?"#d35400":"#1e8449"}">${isNaN(pct)?"N/
A":pct+"%"}</span>

</div></td>

<td style="color:${vcol};font-weight:700">${isNaN(variance)||!
bud?"N/A":(variance>=0?"+":"")+vM+"M"}</td>

<td
style="color:${cpicol};font-weight:700">${isNaN(cpi)||!spt?"N/A":cpi}</td>

<td style="font-weight:700">${isNaN(spi)?"N/A":spi}</td>

<td>${_rptStatusBadge(pct)}</td>

<td style="font-size:9px">${_rptFmt(eac)}</td>

<td style="font-size:9px;color:#555">${[Link]||"N/A"}</td>

</tr>`;

}).join("")||`<tr><td colspan="10" style="text-


align:center;color:#bbb;padding:20px;">No projects match the current
filters.</td></tr>`;

// pager

var pi=[Link]("rpt-pg-info"); if(pi) [Link]=`Page


${rptPage} of ${pages} · ${total} project${total!==1?"s":""}`;
var pp=[Link]("rpt-pg-prev"); if(pp)
[Link]=rptPage<=1;

var pn=[Link]("rpt-pg-next"); if(pn)


[Link]=rptPage>=pages;

// sort arrows

[Link](".rpt-cost-tbl th").forEach((th,i)=>{

[Link]("sorted",i===_rptSortCol);

var arr=[Link](".sort-arrow");

if(arr) [Link]=i===_rptSortCol?(_rptSortAsc?"↑":"↓"):"↕";

});

function sortRptTable(col){

if(_rptSortCol===col) _rptSortAsc=!_rptSortAsc;

else { _rptSortCol=col; _rptSortAsc=true; }

renderRptTable();

function rptTableSearch(){ rptPage=1; renderRptTable(); }

function rptPageChange(d){ rptPage+=d; renderRptTable(); }

function renderRptPhiGrid(){

var projs=_getRptProjects(); if(![Link]) return;

var totBudget=[Link]((s,p)=>s+([Link]||0),0);

var totSpent =[Link]((s,p)=>s+([Link]||0),0);

var totEV =[Link]((s,p)=>s+[Link](([Link]||


0)*([Link]/100)),0);

var cpi=totSpent>0?parseFloat((totEV/totSpent).toFixed(2)):1.00;
var
spi=totSpent>0?parseFloat((totEV/(totBudget*([Link]((s,p)=>s+[Link]
gress,0)/[Link]/100+0.05))).toFixed(2)):1.00;

var
avgProg=[Link]([Link]((s,p)=>s+[Link],0)/[Link]);

var phi=[Link]("rpt-phi-grid"); if(!phi) return;

[Link]=[

["CPI",[Link](2),cpi>=1?"#1e8449":"#c0392b"],

["SPI",[Link](2),spi>=0.95?"#1e8449":spi>=0.85?"#d35400":"#c0392b
"],

["Avg Progress",avgProg+"%","#1a5276"],

["EV","ETB "+[Link](totEV/1e9*100)/100+"B","#0e6655"],

["Utilization",[Link](totSpent/totBudget*100)+"%",totSpent/totBudget>
0.9?"#c0392b":totSpent/totBudget>0.7?"#d35400":"#27ae60"],

].map(([l,v,c])=>`<div class="rpt-phi-card"><div class="rpt-phi-val"


style="color:${c}">${v}</div><div
class="rpt-phi-lbl">${l}</div></div>`).join("");

function exportRptTableCSV(){

var projs=_getRptProjects();

var rows=[["Project","Budget (ETB)","Actual Cost (ETB)","%


Utilized","Variance (ETB)","CPI","SPI","Status","EAC","Project Manager"]];

[Link](p=>{

var pct=[Link]>0?[Link]([Link]/[Link]*100):0;

var
cpi=[Link]>0?parseFloat((([Link]/100*[Link])/[Link]).toFixed(2)):1;
[Link]([[Link],[Link],[Link],pct+"%",([Link]-
[Link]),cpi,[Link],pct>90?"Critical":pct>70?"Warning":"Healthy",Math.r
ound([Link]/cpi),[Link]]);

});

var csv=[Link](r=>[Link](c=>`"${c}"`).join(",")).join("\n");

var a=[Link]("a"); [Link]="data:text/csv;charset=utf-


8,"+encodeURIComponent(csv);

[Link]="EDR_Cost_Report_"+new Date().toISOString().split("T")
[0]+".csv"; [Link]();

toast("✅ CSV exported!");

function setActiveRptBtn(btn){

[Link](".rpt-type-
btn").forEach(b=>[Link]("active"));

if(btn) [Link]("active");

function downloadHistoryReport(name, type, btn) {

// Try to find stored HTML content first

const entry = REPORT_HISTORY.find(r => [Link] === name);

if(entry && [Link]) {

downloadReportFromHistory(name, [Link]);

return;

// Fallback: generate fresh content for this report type

const typeMap =
{Status:"status",Cost:"cost",Risk:"risk",Resource:"resource",Schedule:"sched
ule",Executive:"executive",KPI:"kpi"};
const rtype = typeMap[type] || "status";

// Temporarily generate report content without showing in preview

const titles={status:"Weekly Status Report",cost:"Cost Analysis


Report",risk:"Risk Register Report",resource:"Resource Utilization
Report",schedule:"Schedule & Progress Report",executive:"Executive
Summary",kpi:"KPI Dashboard Report"};

const now = new Date().toLocaleDateString("en-GB",


{day:"numeric",month:"short",year:"numeric"});

let content = `<div style="text-align:center;border-bottom:3px solid


#27ae60;padding-bottom:12px;margin-bottom:12px">

<div style="font-size:14px;font-weight:800;color:#0a3d1f">ETHIO-
DJIBOUTI RAILWAY S.C.</div>

<div
style="font-size:12px;font-weight:700;color:#1a6b3a">${name}</div>

<div style="font-size:10px;color:#555">Generated: ${now} | System


Administrator</div></div>`;

if(rtype==="status"||rtype==="executive") {

content+=`<h3 style="font-size:11px;color:#0a3d1f">PROJECT STATUS


SUMMARY</h3><table><thead><tr><th>Project</th><th>Project
Manager</th><th>Progress</th><th>Status</th><th>Budget
Used</th></tr></thead><tbody>${[Link](p=>`<tr><td>$
{[Link]}</td><td>${[Link]}</td><td>${[Link]}%</td><td>$
{[Link]}</td><td>${[Link]([Link]/[Link]*100)}%</td></
tr>`).join("")}</tbody></table>`;

if(rtype==="risk"||rtype==="executive") {

content+=`<h3 style="font-size:11px;color:#0a3d1f">RISK
REGISTER</h3><table><thead><tr><th>ID</th><th>Risk</th><th>Sev
erity</th><th>Status</th><th>Owner</th></tr></thead><tbody>$
{[Link](r=>`<tr><td>${[Link]}</td><td>${[Link]}</td><td>$
{[Link]}</td><td>${[Link]}</td><td>${[Link]}</td></
tr>`).join("")}</tbody></table>`;

}
if(rtype==="cost"||rtype==="executive") {

content+=`<h3 style="font-size:11px;color:#0a3d1f">COST
SUMMARY</h3><table><thead><tr><th>Project</th><th>Budget</th><
th>Spent</th><th>% Used</th></tr></thead><tbody>$
{[Link](p=>`<tr><td>${[Link]}</td><td>ETB
${([Link]/1e6).toFixed(0)}M</td><td>ETB
${([Link]/1e6).toFixed(0)}M</td><td>${[Link]([Link]/[Link]*100
)}%</td></tr>`).join("")}</tbody></table>`;

if(rtype==="resource") {

content+=`<h3 style="font-size:11px;color:#0a3d1f">RESOURCE
UTILIZATION</h3><table><thead><tr><th>Name</th><th>Role</th><t
h>Utilization</th><th>Tasks</th><th>Status</th></tr></
thead><tbody>${[Link](m=>`<tr><td>${[Link]}</td><td>$
{[Link]}</td><td>${[Link]}%</td><td>${[Link]}</td><td>$
{[Link]}</td></tr>`).join("")}</tbody></table>`;

if(rtype==="schedule"||rtype==="kpi") {

content+=`<h3 style="font-size:11px;color:#0a3d1f">SCHEDULE
STATUS</h3><table><thead><tr><th>Task</th><th>Project</th><th>A
ssignee</th><th>Completion</th></tr></thead><tbody>$
{[Link](t=>`<tr><td>${[Link]}</td><td>${[Link]}</td><td>$
{[Link]}</td><td>${[Link]}%</td></tr>`).join("")}</tbody></table>`;

downloadReportFromHistory(name, content);

//
═══════════════════════════════════════════════════════
════════
// REPORTS
//
═══════════════════════════════════════════════════════
════════
function generateReport(type) {

const now = new Date().toLocaleDateString("en-GB",


{day:"numeric",month:"short",year:"numeric"});

const titles={status:"Weekly Status Report",cost:"Cost Analysis


Report",risk:"Risk Register Report",resource:"Resource Utilization
Report",schedule:"Schedule & Progress Report",executive:"Executive
Summary",kpi:"KPI Dashboard Report"};

const area=[Link]("report-preview-area");

let content=`<div class="report-preview" id="printable-report">

<div style="text-align:center;border-bottom:3px solid #27ae60;padding-


bottom:12px;margin-bottom:12px">

<img src="${LOGO_SRC}"
style="height:45px;margin-bottom:6px"/><br/>

<div style="font-size:14px;font-weight:800;color:#0a3d1f">ETHIO-
DJIBOUTI RAILWAY S.C.</div>

<div style="font-size:12px;font-weight:700;color:#1a6b3a">$
{titles[type]}</div>

<div style="font-size:10px;color:#555">Generated: ${now} | System


Administrator</div>

</div>`;

if(type==="status"||type==="executive") {

content+=`<div style="font-size:11px;font-
weight:700;color:#0a3d1f;margin-bottom:6px">PROJECT STATUS
SUMMARY</div>

<table class="tbl" style="font-size:10px">

<thead><tr><th>Project</th><th>Project
Manager</th><th>Progress</th><th>Status</th><th>Budget
Used</th></tr></thead>
<tbody>${[Link](p=>`<tr><td>${[Link]}</td><td>$
{[Link]}</td><td>${[Link]}%</td><td>${[Link]}</td><td>$
{[Link]([Link]/[Link]*100)}%</td></tr>`).join("")}</tbody>

</table>`;

if(type==="risk"||type==="executive") {

content+=`<div style="font-size:11px;font-
weight:700;color:#0a3d1f;margin:10px 0 6px">TOP RISKS</div>

<table class="tbl" style="font-size:10px">

<thead><tr><th>ID</th><th>Risk</th><th>Project</th><th>Severity</
th><th>Status</th><th>Owner</th></tr></thead>

<tbody>${[Link](0,5).map(r=>`<tr><td>${[Link]}</td><td>$
{[Link]}</td><td>${[Link](0,25)}...</td><td>${[Link]}</
td><td>${[Link]}</td><td>${[Link]}</td></tr>`).join("")}</tbody>

</table>`;

if(type==="cost"||type==="executive") {

content+=`<div style="font-size:11px;font-
weight:700;color:#0a3d1f;margin:10px 0 6px">COST SUMMARY</div>

<table class="tbl" style="font-size:10px">

<thead><tr><th>Project</th><th>Budget</th><th>Spent</th><th>
% Used</th><th>Variance</th></tr></thead>

<tbody>${[Link](p=>`<tr><td>${[Link](0,30)}</td>
<td>ETB ${([Link]/1e6).toFixed(0)}M</td><td>ETB
${([Link]/1e6).toFixed(0)}M</td><td>${[Link]([Link]/[Link]*100
)}%</td><td style="color:${[Link]>[Link]?"green":"red"}">ETB $
{(([Link])/1e6).toFixed(0)}M</td></tr>`).join("")}</tbody>

</table>`;

}
if(type==="resource") {

content+=`<div style="font-size:11px;font-
weight:700;color:#0a3d1f;margin-bottom:6px">RESOURCE
UTILIZATION</div>

<table class="tbl" style="font-size:10px">

<thead><tr><th>Name</th><th>Role</th><th>Utilization</th><th>Tas
ks</th><th>Status</th></tr></thead>

<tbody>${[Link](m=>`<tr><td>${[Link]}</td><td>$
{[Link]}</td><td>${[Link]}%</td><td>${[Link]}</td><td>$
{[Link]}</td></tr>`).join("")}</tbody>

</table>`;

if(type==="schedule"||type==="kpi") {

content+=`<div style="font-size:11px;font-
weight:700;color:#0a3d1f;margin-bottom:6px">SCHEDULE STATUS</div>

<table class="tbl" style="font-size:10px">

<thead><tr><th>Task</th><th>Project</th><th>Assigned
To</th><th>Completion</th></tr></thead>

<tbody>${[Link](t=>`<tr><td>${[Link]}</td><td>$
{[Link]}</td><td>${[Link]}</td><td>${[Link]}%</td></
tr>`).join("")}</tbody>

</table>`;

content+=`<div style="margin-top:14px;padding-top:10px;border-top:1px
solid #c8d8c8;font-size:9px;color:#888;display:flex;justify-content:space-
between">

<span>EDR Engineering PMO · Confidential</span>

<span>Report generated: ${now}</span>

<span>Authorized: System Administrator</span>


</div></div>`;

[Link]=content;

REPORT_HISTORY.unshift({name:`${titles[type]} — $
{now}`,type:titles[type].split(" ")[0],date:now,by:"System
Administrator",to:"Executive Leadership",fmt:"HTML",html:content});

renderReportHistory();

logAudit("Report Generated", "Reports", titles[type] + " generated");

toast("📊 "+titles[type]+" generated!");

function printReport() {

const c=[Link]("printable-report");

if(!c){toast("Generate a report first");return;}

const w=[Link]("","_blank");

[Link](`<html><head><title>EDR
Report</title><style>body{font-family:Segoe UI,Arial,sans-serif;font-
size:11px;color:#1a2a1a}table{width:100%;border-
collapse:collapse}th{background:#0a3d1f;color:#fff;padding:4px 7px;font-
size:9px}td{padding:3px 7px;border-bottom:1px solid #dde8d0}tr:nth-
child(even) td{background:#f4f9f2}.tbl{width:100%;border-
collapse:collapse}</style></head><body>${[Link]}</body></
html>`);

[Link]();[Link]();

function downloadReport() {

const c = [Link]("printable-report");

if(!c) { toast("⚠ Generate a report first, then download"); return; }


const now = new Date().toLocaleDateString("en-GB",
{day:"numeric",month:"short",year:"numeric"}).replace(/ /g,"-");

const title = [Link]("div > div:nth-


child(2)")?.textContent?.replace(/\s+/g," ").trim() || "EDR-Report";

const filename = [Link](/[^a-zA-Z0-9]+/g,"-") + "-" + now + ".html";

const fullHtml = `<!DOCTYPE html><html><head><meta charset="UTF-


8"/><title>${title}</title><style>

body{font-family:"Segoe UI",Arial,sans-serif;font-
size:11px;color:#1a2a1a;margin:20px;background:#fff}

table{width:100%;border-collapse:collapse;margin-bottom:10px}

th{background:#0a3d1f;color:#fff;padding:5px 7px;font-size:9px;font-
weight:700;text-align:left}

td{padding:4px 7px;border-bottom:1px solid #dde8d0;vertical-


align:middle}

tr:nth-child(even) td{background:#f4f9f2}

.bdg{display:inline-block;padding:2px 7px;border-radius:10px;font-
size:9px;font-weight:700}

.g{background:#d4efdf;color:#1e8449}.r{background:#fadbd8;color:#c0
392b}

.o{background:#fdebd0;color:#d35400}.b{background:#d6eaf8;color:#1
a5276}

@media print{body{margin:0}}

</style></head><body>$
{[Link]}<script>[Link]=function(){[Link]()}<\/
script></body></html>`;

const blob = new Blob([fullHtml], {type:"text/html;charset=utf-8"});

const url = [Link](blob);

const a = [Link]("a");

[Link] = url; [Link] = filename; [Link]();

setTimeout(()=>[Link](url), 2000);
toast("✅ Report downloaded: " + filename);

function downloadReportFromHistory(name, content) {

const filename = [Link](/[^a-zA-Z0-9]+/g,"-") + ".html";

const fullHtml = `<!DOCTYPE html><html><head><meta charset="UTF-


8"/><title>${name}</title><style>

body{font-family:"Segoe UI",Arial,sans-serif;font-
size:11px;color:#1a2a1a;margin:20px;background:#fff}

table{width:100%;border-collapse:collapse;margin-bottom:10px}

th{background:#0a3d1f;color:#fff;padding:5px 7px;font-size:9px;font-
weight:700;text-align:left}

td{padding:4px 7px;border-bottom:1px solid #dde8d0;vertical-


align:middle}

tr:nth-child(even) td{background:#f4f9f2}

@media print{body{margin:0}}

</style></head><body>${content || "<p>Report: " + name +


"</p>"}</body></html>`;

const blob = new Blob([fullHtml], {type:"text/html;charset=utf-8"});

const url = [Link](blob);

const a = [Link]("a"); [Link] = url; [Link] =


filename; [Link]();

setTimeout(()=>[Link](url), 2000);

toast("✅ Downloaded: " + name);

function generateRiskReport() { generateReport("risk");


showPageById("reports"); }

function showPageById(id) {
[Link](".page").forEach(p=>[Link]("active")
);

[Link]("page-"+id).[Link]("active");

[Link](".nav-
tab").forEach((t,i)=>{if([Link]("onclick")&&[Link]("onclick").in
cludes(id)) [Link]("active"); else [Link]("active");});

//
═══════════════════════════════════════════════════════
════════
// MODALS

//
═══════════════════════════════════════════════════════
════════
function projOptions() { return
[Link](p=>`<option>${[Link]}</option>`).join(""); }

function openModal(type, id) {

const body=[Link]("modal-body");

if(type==="add-project") {

[Link]=`<h3>➕ New Project</h3>

<div class="mf-row"><div class="mf"><label>PROJECT


NAME</label><input id="m-pname" placeholder="Project
name"/></div><div class="mf"><label>PHASE</label><select id="m-
pphase"><option>Initiation</option><option>Planning</option><option>
Execution</option><option>Monitoring &
Controlling</option><option>Closing / Testing &
Commissioning</option></select></div></div>

<div class="mf-row"><div class="mf"><label>PROJECT


MANAGER</label><select id="m-pmgr"><option>Taye
Abu</option><option>Tewodros Alemayehu</option><option>Wakuma
Ensermu</option><option>Dawit Diriba</option><option>Nigisti
Hailu</option></select></div><div class="mf"><label>BASELINE
START</label><input id="m-pstart" placeholder="e.g. Jan
2025"/></div></div>

<div class="mf-row"><div class="mf"><label>BASELINE


FINISH</label><input id="m-pend" placeholder="e.g. Dec
2026"/></div><div class="mf"><label>BUDGET (ETB)</label><input
id="m-pbgt" type="number" placeholder="500000000"/></div></div>

<div class="mf-row"><div class="mf"><label>STATUS</label><select


id="m-pstat"><option>On Track</option><option>At
Risk</option><option>Delayed</option></select></div></div>

<div class="mbtns"><button class="mbtn c"


onclick="closeModal()">Cancel</button><button class="mbtn p"
onclick="saveProject()">Create Project</button></div>`;

} else if(type==="edit-project") {

const p=[Link](x=>[Link]===id);if(!p) return;

[Link]=`<h3>✏ Edit Project</h3>

<div class="mf"><label>PROJECT NAME</label><input id="m-pname"


value="${[Link]}"/></div>

<div class="mf-row"><div
class="mf"><label>MANAGER</label><input id="m-pmgr" value="$
{[Link]}"/></div><div class="mf"><label>PHASE</label><select
id="m-pphase"><option${[Link]==="Initiation"?"
selected":""}>Initiation</option><option${[Link]==="Planning"?"
selected":""}>Planning</option><option${[Link]==="Execution"?"
selected":""}>Execution</option><option${[Link]==="Monitoring &
Controlling"?" selected":""}>Monitoring & Controlling</option><option$
{[Link]==="Closing / Testing & Commissioning"?" selected":""}>Closing /
Testing & Commissioning</option></select></div></div>

<div class="mf-row"><div class="mf"><label>PROGRESS


%</label><input id="m-pprog" type="number" value="${[Link]}"
min="0" max="100"/></div><div
class="mf"><label>STATUS</label><select id="m-pstat"><option$
{[Link]==="On Track"?" selected":""}>On Track</option><option$
{[Link]==="At Risk"?" selected":""}>At Risk</option><option$
{[Link]==="Delayed"?" selected":""}>Delayed</option><option$
{[Link]==="Completed"?"
selected":""}>Completed</option></select></div></div>

<div class="mf-row"><div class="mf"><label>BUDGET


(ETB)</label><input id="m-pbgt" type="number"
value="${[Link]}"/></div><div class="mf"><label>SPENT
(ETB)</label><input id="m-pspent" type="number"
value="${[Link]}"/></div></div>

<div class="mf-row"><div class="mf"><label>BASELINE


START</label><input id="m-pstart" value="${[Link]}"/></div><div
class="mf"><label>BASELINE FINISH</label><input id="m-pend" value="$
{[Link]}"/></div></div>

<div class="mbtns"><button class="mbtn c"


onclick="closeModal()">Cancel</button><button class="mbtn r"
onclick="deleteProject(${id})">Delete</button><button class="mbtn p"
onclick="updateProject(${id})">Save Changes</button></div>`;

} else if(type==="add-risk") {

[Link]=`<h3>⚠ Add Risk</h3>

<div class="mf"><label>RISK DESCRIPTION</label><textarea id="m-


rtxt" placeholder="Describe the risk in detail..."></textarea></div>

<div class="mf"><label>PROJECT</label><select id="m-rproj">$


{projOptions()}</select></div>

<div class="mf-row"><div
class="mf"><label>SEVERITY</label><select id="m-
rsev"><option>High</option><option>Medium</option><option>Low</
option></select></div><div
class="mf"><label>PROBABILITY</label><select id="m-
rprob"><option>Almost
Certain</option><option>Likely</option><option>Possible</option><opti
on>Unlikely</option><option>Rare</option></select></div></div>

<div class="mf-row"><div class="mf"><label>IMPACT</label><select


id="m-rimp"><option>Catastrophic</option><option>Major</option><opt
ion>Moderate</option><option>Minor</option><option>Negligible</
option></select></div><div class="mf"><label>OWNER</label><select
id="m-rown"><option>Taye Abu</option><option>Tewodros
Alemayehu</option><option>Wakuma Ensermu</option><option>Dawit
Diriba</option><option>Nigisti Hailu</option></select></div></div>

<div class="mf-row"><div class="mf"><label>DUE


DATE</label><input id="m-rdue" placeholder="e.g. Jun 2025"/></div><div
class="mf"><label>STATUS</label><select id="m-
rstat"><option>Open</option><option>Mitigated</option><option>Close
d</option></select></div></div>

<div class="mf"><label>MITIGATION PLAN</label><input id="m-rmit"


placeholder="Describe mitigation strategy..."/></div>

<div class="mbtns"><button class="mbtn c"


onclick="closeModal()">Cancel</button><button class="mbtn p"
onclick="saveRisk()">Add Risk</button></div>`;

} else if(type==="edit-risk") {

const r=RISKS[id];if(!r) return;

[Link]=`<h3>✏ Edit Risk ${[Link]}</h3>

<div class="mf"><label>RISK DESCRIPTION</label><textarea id="m-


rtxt">${[Link]}</textarea></div>

<div class="mf"><label>PROJECT</label><select id="m-rproj">$


{projOptions()}</select></div>

<div class="mf-row"><div
class="mf"><label>SEVERITY</label><select id="m-rsev"><option$
{[Link]==="High"?" selected":""}>High</option><option$
{[Link]==="Medium"?" selected":""}>Medium</option><option$
{[Link]==="Low"?" selected":""}>Low</option></select></div><div
class="mf"><label>STATUS</label><select id="m-rstat"><option$
{[Link]==="Open"?" selected":""}>Open</option><option$
{[Link]==="Mitigated"?" selected":""}>Mitigated</option><option$
{[Link]==="Closed"?"
selected":""}>Closed</option></select></div></div>

<div class="mf"><label>MITIGATION PLAN</label><input id="m-rmit"


value="${[Link]}"/></div>

<div class="mf"><label>OWNER</label><input id="m-rown" value="$


{[Link]}"/></div>
<div class="mbtns"><button class="mbtn c"
onclick="closeModal()">Cancel</button><button class="mbtn r"
onclick="deleteRisk(${id})">Delete</button><button class="mbtn p"
onclick="updateRisk(${id})">Save Changes</button></div>`;

} else if(type==="add-member") {

[Link]=`<h3>👤 Add Team Member</h3>

<div class="mf-row"><div class="mf"><label>FULL


NAME</label><input id="m-mname" placeholder="Name"/></div><div
class="mf"><label>ROLE</label><input id="m-mrole" placeholder="e.g.
Site Engineer"/></div></div>

<div class="mf"><label>EMAIL</label><input id="m-memail"


placeholder="name@[Link]"/></div>

<div class="mf-row"><div class="mf"><label>PROJECT


ASSIGNMENT</label><select
id="m-mproj">${projOptions()}</select></div><div
class="mf"><label>UTILIZATION %</label><input id="m-mutil"
type="number" value="80" min="0" max="100"/></div></div>

<div class="mbtns"><button class="mbtn c"


onclick="closeModal()">Cancel</button><button class="mbtn p"
onclick="saveMember()">Add Member</button></div>`;

} else if(type==="add-user") {

// redirect to new modal system

openUserModal('add');

return;

} else if(type==="edit-user") {

openUserModal('edit', id);

return;

} else if(type==="add-task") {

[Link]=`<h3>📅 Add Task / Activity</h3>

<div class="mf"><label>TASK NAME</label><input id="m-tname"


placeholder="Task description"/></div>
<div class="mf"><label>PROJECT</label><select id="m-tproj">$
{projOptions()}</select></div>

<div class="mf-row"><div
class="mf"><label>ASSIGNEE</label><select id="m-
tassign"><option>Taye Abu</option><option>Tewodros
Alemayehu</option><option>Wakuma Ensermu</option><option>Dawit
Diriba</option><option>Nigisti Hailu</option></select></div><div
class="mf"><label>COMPLETION %</label><input id="m-tpct"
type="number" value="0" min="0" max="100"/></div></div>

<div class="mf-row"><div class="mf"><label>START (months from


Jan)</label><input id="m-tstart" type="number" value="0" min="0"
max="9"/></div><div class="mf"><label>DURATION
(months)</label><input id="m-tdur" type="number" value="2" min="0.5"
max="10" step="0.5"/></div></div>

<div class="mbtns"><button class="mbtn c"


onclick="closeModal()">Cancel</button><button class="mbtn p"
onclick="saveTask()">Add Task</button></div>`;

[Link]("modal-bg").[Link]("open");

// SAVE FUNCTIONS

function saveProject() {

const name=[Link]("m-pname").[Link]();

if(!name){toast("❌ Project name required");return;}

const
colors=["#27ae60","#2980b9","#e74c3c","#f39c12","#8e44ad","#1abc9c",
"#d35400","#16a085"];

[Link]({id:nextId+
+,name,manager:[Link]("m-
pmgr").value,phase:[Link]("m-
pphase").value,start:[Link]("m-
pstart").value||"2025",end:[Link]("m-
pend").value||"2026",budget:+[Link]("m-pbgt").value||
0,spent:0,progress:0,status:[Link]("m-
pstat").value,color:colors[[Link]%[Link]]});

closeModal();renderAll();logAudit("Add","Projects","New project added:


"+name);toast("✅ Project created!");

function updateProject(id) {

const p=[Link](x=>[Link]===id);if(!p) return;

[Link]=[Link]("m-pname").value;

[Link]=[Link]("m-pmgr").value;

[Link]=[Link]("m-pphase").value;

[Link]=+[Link]("m-pprog").value;

[Link]=[Link]("m-pstat").value;

[Link]=+[Link]("m-pbgt").value;

[Link]=+[Link]("m-pspent").value;

[Link]=[Link]("m-pstart").value;

[Link]=[Link]("m-pend").value;

closeModal();renderAll();logAudit("Edit","Projects","Project updated:
"+[Link]);toast("✅ Project updated!");

function deleteProject(id) {

if(!confirm("Delete this project?")) return;

const p=[Link](x=>[Link]===id);

const pname=p?[Link]:"ID "+id;

PROJECTS=[Link](p=>[Link]!
==id);closeModal();renderAll();logAudit("Delete","Projects","Project deleted:
"+pname);toast("🗑 Project deleted");

function saveRisk() {
const txt=[Link]("m-rtxt").[Link]();

if(!txt){toast("❌ Risk description required");return;}

[Link]({id:"R-
0"+String([Link]+1).padStart(2,"0"),text:txt,project:[Link]
mentById("m-rproj").value,sev:[Link]("m-
rsev").value,prob:[Link]("m-
rprob").value,impact:[Link]("m-
rimp").value,status:[Link]("m-
rstat").value,owner:[Link]("m-
rown").value,due:[Link]("m-
rdue").value||"TBD",mitigation:[Link]("m-
rmit").value||"TBD"});

closeModal();renderRisks();logAudit("Add","Risks","Risk added:
"+[Link](0,50));toast("✅ Risk added!");

function updateRisk(idx) {

const r=RISKS[idx];

[Link]=[Link]("m-rtxt").value;

[Link]=[Link]("m-rsev").value;

[Link]=[Link]("m-rstat").value;

[Link]=[Link]("m-rmit").value;

[Link]=[Link]("m-rown").value;

closeModal();renderRisks();logAudit("Edit","Risks","Risk updated:
"+[Link]);toast("✅ Risk updated!");

function deleteRisk(idx) {

if(!confirm("Delete this risk?")) return;

const r=RISKS[idx];

[Link](idx,1);closeModal();renderRisks();logAudit("Delete","Risks","Risk
deleted: "+(r?[Link]:""));toast("🗑 Risk deleted");
}

function saveMember() {

const name=[Link]("m-mname").[Link]();

if(!name){toast("❌ Name required");return;}

[Link]({name,role:[Link]("m-
mrole").value,projects:[Link]("m-mproj").value,util:
+[Link]("m-mutil").value||
80,tasks:0,status:"Active",email:[Link]("m-
memail").value});

closeModal();renderResources();toast("✅ Member added!");

//
═══════════════════════════════════════════════════════
════════
// USER MANAGEMENT — Full CRUD with RBAC

//
═══════════════════════════════════════════════════════
════════

// Map role → access level string (legacy compat)

function roleToAccess(role) {

if(role==="Administrator") return "Admin";

if(role==="Project Manager") return "Editor";

return "Viewer";

// Generate next user ID

function nextUserId() {

const nums = [Link](u => parseInt(([Link]||"U000").replace("U",""))||0);

return "U" + String([Link](...nums, 0) + 1).padStart(3,"0");


}

// Project options for multi-select (checkbox list)

function projectCheckboxes(selected) {

const all = [Link](p=>[Link]);

return [Link](n=>`<label style="display:flex;align-


items:center;gap:5px;font-size:9px;padding:2px 0;cursor:pointer">

<input type="checkbox" name="um-proj" value="${n}" ${(selected||


[]).includes(n)?"checked":""}/> ${n}

</label>`).join("") + `<label style="display:flex;align-


items:center;gap:5px;font-size:9px;padding:2px 0;cursor:pointer">

<input type="checkbox" name="um-proj" value="All Projects" $


{(selected||[]).includes("All Projects")?"checked":""}/> All Projects

</label>`;

function openUserModal(mode, idx) {

if (!canManageUsers()) { toast("❌ Administrator access required to manage


users"); return; }

const body = [Link]("modal-body");

const now = new Date();

const today = `${[Link]()}-${String([Link]()


+1).padStart(2,"0")}-${String([Link]()).padStart(2,"0")}`;

if (mode === "add") {

[Link] = `

<h3>🔐 Create New User Account</h3>


<div style="background:#f0f8f4;border:1px solid #c8d8c8;border-
radius:4px;padding:8px 10px;margin-bottom:10px;font-
size:9px;color:#555">

<strong style="color:#0a3d1f">Password Policy:</strong> Min. 8


chars. Stored encrypted — never shown in plain text after creation.

</div>

<div class="mf-row">

<div class="mf"><label>FULL NAME <span


style="color:#e74c3c">*</span></label><input id="um-fname"
placeholder="e.g. Abebe Girma" style="width:100%"/></div>

<div class="mf"><label>USERNAME <span


style="color:#e74c3c">*</span></label><input id="um-uname"
placeholder="e.g. [Link]" style="width:100%"/></div>

</div>

<div class="mf-row">

<div class="mf"><label>EMAIL <span


style="color:#e74c3c">*</span></label><input id="um-email"
type="email" placeholder="name@[Link]" style="width:100%"/></div>

<div class="mf"><label>ROLE <span


style="color:#e74c3c">*</span></label>

<select id="um-role" style="width:100%;padding:5px 8px;border:1px


solid #c8d8c8;border-radius:3px;font-family:inherit;font-size:10px"
onchange="umRoleChanged()">

<option>Project Manager</option>

<option>Administrator</option>

<option>Viewer</option>

</select>

</div>

</div>

<div class="mf-row">
<div class="mf"><label>PASSWORD <span
style="color:#e74c3c">*</span></label>

<div style="position:relative">

<input id="um-pw" type="password" placeholder="Min. 8


characters" style="width:100%;padding-right:30px"/>

<span onclick="[Link]('um-
pw').type=[Link]('um-
pw').type==='password'?'text':'password'"
style="position:absolute;right:6px;top:50%;transform:translateY(-
50%);cursor:pointer;font-size:11px">👁</span>

</div>

</div>

<div class="mf"><label>CONFIRM PASSWORD <span


style="color:#e74c3c">*</span></label><input id="um-pw2"
type="password" placeholder="Re-enter password"
style="width:100%"/></div>

</div>

<div class="mf"><label>STATUS</label>

<select id="um-status" style="width:100%;padding:5px 8px;border:1px


solid #c8d8c8;border-radius:3px;font-family:inherit;font-size:10px">

<option>Active</option><option>Inactive</option>

</select>

</div>

<div class="mf" id="um-proj-wrap"><label>ASSIGNED


PROJECT(S)</label>

<div style="max-height:110px;overflow-y:auto;border:1px solid


#c8d8c8;border-radius:3px;padding:6px 8px;background:#f9fdf9">

${projectCheckboxes([])}

</div>

</div>
<div id="um-val-msg" style="color:#e74c3c;font-size:9px;min-
height:14px;margin-bottom:4px"></div>

<div class="mbtns">

<button class="mbtn c" onclick="closeModal()">Cancel</button>

<button class="mbtn p" onclick="saveUserNew()">✅ Create


User</button>

</div>`;

[Link]("modal-bg").[Link]("open");

umRoleChanged();

} else if (mode === "edit") {

const u = USERS[idx]; if (!u) return;

[Link] = `

<h3>✏ Edit User — <span style="color:#0a3d1f">${[Link]}</span>


<span style="font-size:9px;font-weight:400;color:#888">(ID:
${[Link]})</span></h3>

<div class="mf-row">

<div class="mf"><label>FULL NAME <span


style="color:#e74c3c">*</span></label><input id="um-fname" value="$
{[Link]}" style="width:100%"/></div>

<div class="mf"><label>USERNAME</label><input id="um-uname"


value="${[Link]}" style="width:100%;background:#f0f0f0" readonly
title="Username cannot be changed"/></div>

</div>

<div class="mf-row">

<div class="mf"><label>EMAIL</label><input id="um-email"


type="email" value="${[Link]}" style="width:100%"/></div>

<div class="mf"><label>ROLE</label>

<select id="um-role" style="width:100%;padding:5px 8px;border:1px


solid #c8d8c8;border-radius:3px;font-family:inherit;font-size:10px"
onchange="umRoleChanged()">
<option${[Link]==="Project Manager"?" selected":""}>Project
Manager</option>

<option${[Link]==="Administrator"?"
selected":""}>Administrator</option>

<option${[Link]==="Viewer"?" selected":""}>Viewer</option>

</select>

</div>

</div>

<div class="mf-row">

<div class="mf"><label>RESET PASSWORD <span


style="color:#888;font-weight:400">(leave blank to keep)</span></label>

<div style="position:relative">

<input id="um-pw" type="password" placeholder="New password…"


style="width:100%;padding-right:30px"/>

<span onclick="[Link]('um-
pw').type=[Link]('um-
pw').type==='password'?'text':'password'"
style="position:absolute;right:6px;top:50%;transform:translateY(-
50%);cursor:pointer;font-size:11px">👁</span>

</div>

</div>

<div class="mf"><label>STATUS</label>

<select id="um-status" style="width:100%;padding:5px


8px;border:1px solid #c8d8c8;border-radius:3px;font-family:inherit;font-
size:10px">

<option${[Link]==="Active"?" selected":""}>Active</option>

<option${[Link]==="Inactive"?" selected":""}>Inactive</option>

</select>

</div>

</div>
<div class="mf" id="um-proj-wrap"><label>ASSIGNED
PROJECT(S)</label>

<div style="max-height:110px;overflow-y:auto;border:1px solid


#c8d8c8;border-radius:3px;padding:6px 8px;background:#f9fdf9">

${projectCheckboxes([Link]||[])}

</div>

</div>

<div style="background:#f8fdf8;border:1px solid #c8d8c8;border-


radius:4px;padding:6px 10px;font-size:9px;color:#555;margin-bottom:8px">

<strong>Date Created:</strong> ${[Link]||"—"} &nbsp;|


&nbsp; <strong>Last Login:</strong> ${[Link]||"—"}

</div>

<div id="um-val-msg" style="color:#e74c3c;font-size:9px;min-


height:14px;margin-bottom:4px"></div>

<div class="mbtns">

<button class="mbtn c" onclick="closeModal()">Cancel</button>

<button class="mbtn r" onclick="deleteUserConfirm(${idx})">🗑


Delete</button>

<button class="mbtn" onclick="toggleUserStatus(${idx});closeModal()"


style="background:#f39c12;color:#fff;border-color:#d68910">$
{[Link]==="Active"?"⏸ Deactivate":"▶ Activate"}</button>

<button class="mbtn p" onclick="updateUserNew(${idx})">💾 Save


Changes</button>

</div>`;

[Link]("modal-bg").[Link]("open");

umRoleChanged();

function umRoleChanged() {
const role = ([Link]("um-role")||{}).value || "";

const wrap = [Link]("um-proj-wrap");

if (wrap) [Link] = (role === "Administrator") ? "none" : "";

function getSelectedProjects() {

return [Link]([Link]('input[name="um-
proj"]:checked')).map(c => [Link]);

function saveUserNew() {

const name = ([Link]("um-fname")||


{}).value?.trim()||"";

const uname = ([Link]("um-uname")||


{}).value?.trim()||"";

const email = ([Link]("um-email")||


{}).value?.trim()||"";

const role = ([Link]("um-role")||{}).value||"Project


Manager";

const pw = ([Link]("um-pw")||{}).value||"";

const pw2 = ([Link]("um-pw2")||{}).value||"";

const stat = ([Link]("um-status")||{}).value||"Active";

const projs = role==="Administrator" ? ["All Projects"] :


getSelectedProjects();

const msg = [Link]("um-val-msg");

if (!name) { if(msg) [Link]="❌ Full name is required."; return; }

if (!uname) { if(msg) [Link]="❌ Username is required."; return; }


if ([Link](u=>[Link]===uname)) { if(msg)
[Link]="❌ Username already exists."; return; }

if (!email) { if(msg) [Link]="❌ Email is required."; return; }

if (!pw || [Link] < 8) { if(msg) [Link]="❌ Password must be at


least 8 characters."; return; }

if (pw !== pw2) { if(msg) [Link]="❌ Passwords do not match.";


return; }

const now = new Date();

const today = `${[Link]()}-${String([Link]()


+1).padStart(2,"0")}-${String([Link]()).padStart(2,"0")}`;

[Link]({

id: nextUserId(), name, username: uname, role, email,

access: roleToAccess(role), assignedProjects: projs,

status: stat, dateCreated: today, lastLogin: "—", pw

});

closeModal();

renderSettings();

logAudit("Add","User Management",`User created: ${name} (${uname}) —


Role: ${role}`);

toast(`✅ User "${name}" created successfully!`);

function updateUserNew(idx) {

if (!canManageUsers()) { toast("❌ Access denied"); return; }

const u = USERS[idx]; if (!u) return;

const name = ([Link]("um-fname")||{}).value?.trim()||


[Link];
const email = ([Link]("um-email")||{}).value?.trim()||
[Link];

const role = ([Link]("um-role")||{}).value||[Link];

const pw = ([Link]("um-pw")||{}).value||"";

const stat = ([Link]("um-status")||{}).value||[Link];

const projs = role==="Administrator" ? ["All Projects"] :


getSelectedProjects();

const msg = [Link]("um-val-msg");

if (!name) { if(msg) [Link]="❌ Full name is required."; return; }

if (pw && [Link] < 8) { if(msg) [Link]="❌ New password must


be at least 8 characters."; return; }

[Link] = name;

[Link] = email;

[Link] = role;

[Link] = roleToAccess(role);

[Link] = projs;

[Link] = stat;

if (pw) [Link] = pw;

closeModal();

renderSettings();

logAudit("Edit","User Management",`User updated: ${name} ($


{[Link]}) — Role: ${role}, Status: ${stat}`);

toast(`✅ User "${name}" updated!`);

function toggleUserStatus(idx) {
if (!canManageUsers()) { toast("❌ Access denied"); return; }

const u = USERS[idx]; if (!u) return;

[Link] = [Link] === "Active" ? "Inactive" : "Active";

renderSettings();

logAudit("Edit","User Management",`User $
{[Link]==="Active"?"activated":"deactivated"}: ${[Link]}`);

toast(`${[Link]==="Active"?"✅ User activated":"⏸ User deactivated"}: $


{[Link]}`);

function deleteUserConfirm(idx) {

if (!canManageUsers()) { toast("❌ Access denied"); return; }

const u = USERS[idx]; if (!u) return;

if (!confirm(`Delete user "${[Link]}" (${[Link]})?\n\nThis action


cannot be undone.`)) return;

const name = [Link];

[Link](idx, 1);

closeModal();

renderSettings();

logAudit("Delete","User Management",`User deleted: ${name}`);

toast(`🗑 User "${name}" deleted`);

function saveUser() {

const name=[Link]("m-uname")?.value?.trim()||"";

if(!name){toast("❌ Name required");return;}

const role = [Link]("m-urole")?.value||"Project


Manager";
const now = new Date();

const today = `${[Link]()}-${String([Link]()


+1).padStart(2,"0")}-${String([Link]()).padStart(2,"0")}`;

[Link]({

id: nextUserId(), name, username: [Link]("m-


uuser")?.value||[Link]().replace(/\s+/,"_"),

role, email: [Link]("m-uemail")?.value||"",

access: [Link]("m-uaccess")?.value||"Viewer",

assignedProjects:[], status:"Active", dateCreated: today, lastLogin:"—",

pw: [Link]("m-upw")?.value||""

});

closeModal();renderSettings();toast("✅ User created!");

function updateUser(idx) {

const u=USERS[idx]; if(!u) return;

[Link]=[Link]("m-uname")?.value||[Link];

[Link]=[Link]("m-uemail")?.value||[Link];

[Link]=[Link]("m-urole")?.value||[Link];

[Link]=[Link]("m-uaccess")?.value||[Link];

[Link]=[Link]("m-ustat")?.value||[Link];

const np=[Link]("m-upw")?.value;if(np) [Link]=np;

closeModal();renderSettings();toast("✅ User updated!");

function deleteUser(idx) {

if(!confirm("Delete this user?")) return;


[Link](idx,1);closeModal();renderSettings();toast("🗑 User deleted");

function saveTask() {

const name=[Link]("m-tname").[Link]();

if(!name){toast("❌ Task name required");return;}

const colors=["#0a3d1f","#27ae60","#2980b9","#f39c12","#8e44ad"];

[Link]({id:nextId++,task:name,project:[Link]("m-
tproj").value,start:+[Link]("m-tstart").value,dur:
+[Link]("m-
tdur").value,assignee:[Link]("m-tassign").value,pct:
+[Link]("m-tpct").value,color:colors[[Link]
%[Link]]});

closeModal();renderSchedule();toast("✅ Task added to Gantt!");

// MILESTONE MANAGEMENT

function editMilestone(idx) {

const m=MILESTONES[idx];

const newTitle=prompt("Edit Milestone Title:",m.m);

if(newTitle===null)return;

const newDate=prompt("Edit Milestone Date (e.g., Aug 2025):",m.d);

if(newDate===null)return;

const newStatus=prompt("Edit Status (upcoming/future/completed):",m.s);

if(newStatus===null)return;

m.m=[Link]()||m.m;

m.d=[Link]()||m.d;

m.s=[Link]()||m.s;

renderSchedule();toast("✅ Milestone updated!");


}

function addMilestone() {

const title=prompt("Milestone Title:");

if(!title)return;

const date=prompt("Target Date (e.g., Jun 2026):");

if(!date)return;

const status=prompt("Status (upcoming/future):", "future");

if(!status)return;

if(!MILESTONES)MILESTONES=[];

const nextId=[Link](...[Link](m=>[Link]||0),0)+1;

[Link]({id:nextId,m:title,d:date,s:status});

renderSchedule();toast("✅ Milestone added!");

function deleteMilestone(idx) {

if(!confirm("Delete this milestone?"))return;

[Link](idx,1);

renderSchedule();toast("🗑 Milestone deleted");

function closeModal() { [Link]("modal-


bg").[Link]("open"); }

function closeMbg(e) { if([Link]===[Link]("modal-


bg")) closeModal(); }

//
═══════════════════════════════════════════════════════
════════
// UTILS
//
═══════════════════════════════════════════════════════
════════
function exportCostCSV() {

let csv="Project,Budget (ETB),Spent (ETB),% Used,Variance (ETB),Status\n";

[Link](p=>{

const pct=[Link]([Link]/[Link]*100);

const v=[Link];

csv+=`"${[Link]}","${[Link]}","${[Link]}","${pct}%","${v}","$
{[Link]}"\n`;

});

const
a=[Link]("a");[Link]="data:text/csv,"+encodeURICompon
ent(csv);[Link]="EDR_Cost_Report.csv";[Link]();

toast("✅ Cost report CSV exported!");

function exportScheduleCSV() {

let csv="Task,Project,Assignee,Start (month),Duration (months),Completion


%\n";

[Link](t=>csv+=`"${[Link]}","${[Link]}","${[Link]}","$
{[Link]}","${[Link]}","${[Link]}%"\n`);

const
a=[Link]("a");[Link]="data:text/csv,"+encodeURICompon
ent(csv);[Link]="EDR_Schedule.csv";[Link]();

toast("✅ Schedule exported!");

function importScheduleCSV(input) {

const file=[Link][0];if(!file)return;

const reader=new FileReader();

[Link]=function(e){
const lines=[Link]("\n").filter(l=>[Link]());

if([Link]<2){toast("❌ Invalid CSV file");[Link]="";return;}

const colors=["#0a3d1f","#27ae60","#2980b9","#f39c12","#8e44ad"];

let added=0;

for(let i=1;i<[Link];i++){

const cols=lines[i].match(/(".*?"|[^,]+)(?=\s*,|\s*$)/g);

if(!cols||[Link]<6)continue;

const clean=[Link](c=>[Link](/^"|"$/g,"").trim());

const task=clean[0],project=clean[1],assignee=clean[2];

const start=parseInt(clean[3])||1,dur=parseInt(clean[4])||1;

const pct=parseInt((clean[5]||"0").replace("%",""))||0;

if(!task)continue;

[Link]({id:nextId+
+,task,project,start,dur,assignee,pct,color:colors[[Link]
%[Link]]});

added++;

[Link]="";

if(added>0){renderSchedule();toast("✅ "+added+" task(s) imported!");}

else toast("❌ No valid rows found in CSV");

};

[Link](file);

function showMSPHelp(){[Link]('msp-help-
overlay').[Link]='flex';}

function importMSProject(input) {

const file = [Link][0]; if(!file) return;

// Guard: reject .mpp binary files


if([Link]().endsWith('.mpp')) {

toast("❌ .mpp files cannot be read in the browser. Please export as XML
from MS Project first.");

[Link] = ""; return;

if(![Link]().endsWith('.xml')) {

toast("❌ Please upload an XML file exported from Microsoft Project.");

[Link] = ""; return;

const reader = new FileReader();

[Link] = function(e) {

const content = [Link];

const colors =
["#0a3d1f","#27ae60","#2980b9","#f39c12","#8e44ad","#c0392b","#16a0
85"];

let added = 0;

try {

const xmlDoc = new DOMParser().parseFromString(content, "text/xml");

// Check for XML parse errors

const parseErr = [Link]("parsererror");

if(parseErr) { toast("❌ Invalid XML file. Please re-export from MS


Project."); [Link]=""; return; }

// Support both namespace-prefixed and plain MS Project XML schemas

const ns = "[Link]

let tasks = [Link]([Link](ns,"Task"));

if(![Link]) tasks =
[Link]([Link]("Task"));
if(![Link]) { toast("❌ No tasks found. Ensure the file is an MS
Project XML export."); [Link]=""; return; }

// Helper: get text content of first matching child tag (tries ns then plain)

const getVal = (el, tag) => {

let node = [Link](ns, tag)[0] ||


[Link](tag)[0];

return node ? [Link]() : "";

};

// Parse project start date for offset calculation

let projStartDate = null;

const projNode = [Link](ns,"Project")[0] ||


[Link]("Project")[0];

if(projNode) {

const psRaw = getVal(projNode,"StartDate") || getVal(projNode,"Start");

if(psRaw) projStartDate = new Date(psRaw);

const baseDate = projStartDate || new Date("2025-01-01");

[Link]((t, idx) => {

const uid = getVal(t,"UID");

if(uid === "0") return; // skip summary task 0

const name = getVal(t,"Name");

if(!name) return;
// Duration: MS Project stores as PT#H#M#S or in minutes (480 mins =
1 day)

let durDays = 1;

const durRaw = getVal(t,"Duration");

if(durRaw) {

const ptMatch = [Link](/PT(\d+)H/); // ISO 8601 duration

if(ptMatch) durDays = [Link](1, [Link](parseInt(ptMatch[1]) /


8));

else { const d = parseInt(durRaw); if(!isNaN(d)) durDays =


[Link](1, [Link](d / 480)); }

// Start offset from project base

const startRaw = getVal(t,"Start");

let startOffset = 1;

if(startRaw) {

const st = new Date(startRaw);

if(!isNaN(st)) startOffset = [Link](1, [Link]((st - baseDate) /


86400000) + 1);

const pct = parseInt(getVal(t,"PercentComplete") ||


getVal(t,"PercentWorkComplete") || "0") || 0;

const assignee = getVal(t,"ResourceName") || "TBD";

// Status badge

const isCrit = getVal(t,"Critical") === "1";

const status = pct >= 100 ? "Done" : pct > 0 ? "In Progress" : isCrit ?
"Critical" : "Not Started";
[Link]({

id: nextId++,

task: name,

project: "MS-Import",

start: startOffset,

dur: durDays,

assignee,

pct,

status,

color: colors[([Link]) % [Link]]

});

added++;

});

[Link] = "";

if(added > 0) { renderSchedule(); toast("✅ " + added + " task(s)


imported from MS Project XML!"); }

else toast("❌ No valid tasks found in the MS Project XML file.");

} catch(err) {

toast("❌ Error parsing MS Project XML: " + [Link]);

[Link] = "";

};

[Link] = () => { toast("❌ Could not read file."); [Link] = ""; };

[Link](file);

}
function importExcelSchedule(input) {

const file=[Link][0];if(!file)return;

const reader=new FileReader();

[Link]=function(e){

const data=new Uint8Array([Link]);

try {

if(![Link]){toast("❌ Excel library not available. Use CSV format


instead.");return;}

const workbook=[Link](data,{type:"array"});

const sheet=[Link][[Link][0]];

const json=[Link].sheet_to_json(sheet);

const colors=["#0a3d1f","#27ae60","#2980b9","#f39c12","#8e44ad"];

let added=0;

[Link](row=>{

const task=row["Task"]||row["Task Name"]||row["Name"];

const project=row["Project"]||"Imported-Excel";

const assignee=row["Assignee"]||row["Resource"]||"TBD";

const start=parseInt(row["Start"])||parseInt(row["Start Month"])||1;

const dur=parseInt(row["Duration"])||1;

const pct=parseInt((row["% Complete"]||


row["%"]||"0").toString().replace("%",""))||0;

if(!task)return;

[Link]({id:nextId+
+,task,project,start,dur,assignee,pct,color:colors[[Link]
%[Link]]});

added++;

});

[Link]="";
if(added>0){renderSchedule();toast("✅ "+added+" Excel task(s)
imported!");}

else toast("❌ No valid data found in Excel file");

}catch(err){toast("❌ Error parsing Excel file. Upload as .xlsx or .xls


format.");}

};

[Link](file);

function exportTable() {

let csv="Project,Manager,Phase,Start,End,Budget,Spent,Progress,Status\n";

[Link](p=>csv+=`"${[Link]}","${[Link]}","$
{[Link]}","${[Link]}","${[Link]}","${[Link]}","${[Link]}","$
{[Link]}%","${[Link]}"\n`);

const
a=[Link]("a");[Link]="data:text/csv,"+encodeURICompon
ent(csv);[Link]="EDR_Projects.csv";[Link]();

toast("✅ CSV exported!");

function exportRisks() {

let
csv="ID,Description,Project,Severity,Probability,Impact,Status,Owner,Mitigati
on\n";

[Link](r=>csv+=`"${[Link]}","${[Link]}","${[Link]}","${[Link]}","$
{[Link]}","${[Link]}","${[Link]}","${[Link]}","${[Link]}"\n`);

const
a=[Link]("a");[Link]="data:text/csv,"+encodeURICompon
ent(csv);[Link]="EDR_Risks.csv";[Link]();

toast("✅ Risk register exported!");

function changePass() {
const p=[Link]("new-pass").value;

const c=[Link]("conf-pass").value;

if(!p||p!==c){toast("❌ Passwords do not match");return;}

toast("✅ Password updated successfully!");

//
═══════════════════════════════════════════════════════
════════
// NEW FEATURES: Excel Upload, Photos, Completed Projects, Upcoming
Works

//
═══════════════════════════════════════════════════════
════════

// Excel Project Report Import

function importProjectReport(input) {

const file=[Link][0];if(!file)return;

const reader=new FileReader();

[Link]=function(e){

const data=new Uint8Array([Link]);

try {

if(![Link]){toast("❌ Excel library not available. Please install


SheetJS library.");return;}

const workbook=[Link](data,{type:"array"});

const sheet=[Link][[Link][0]];

const json=[Link].sheet_to_json(sheet);

let added=0;

[Link](row=>{
const reportName=row["Report Name"]||row["Name"]||"Imported
Report";

const reportType=row["Type"]||"Custom";

const dateStr=new Date().toLocaleDateString();

if(reportName){

const historyTable=[Link]("report-history-tbody");

const tr=[Link]("tr");

[Link]=`<td>${reportName}</td><td>${reportType}</td><td>$
{dateStr}</td><td>${currentUser?.name||'System'}</
td><td>Stakeholders</td><td>📊 Excel</td><td><button class="edit-btn"
onclick="downloadReport()">📥 Download</button></td>`;

[Link](tr);

added++;

});

[Link]="";

if(added>0){toast("✅ "+added+" report(s) imported from Excel!");}

else toast("❌ No valid report entries found");

}catch(err){toast("❌ Error parsing Excel file. Ensure it's in .xlsx format.");}

};

[Link](file);

// Project Photo Gallery

function addProjectPhoto(input) {

const file=[Link][0];if(!file)return;

const reader=new FileReader();


[Link]=function(e){

const gallery=[Link]("photo-gallery");

if([Link]===1){[Link]="";}

const photoDiv=[Link]("div");

[Link]="border:1px solid #c8d8c8;border-


radius:4px;overflow:hidden;cursor:pointer;transition:transform .2s";

[Link]=function(){[Link]="scale(1.05)"};

[Link]=function(){[Link]="scale(1)"};

const img=[Link]("img");

[Link]=[Link];

[Link]="width:100%;height:120px;object-fit:cover";

[Link]=function(){[Link]([Link])};

[Link](img);

const caption=[Link]("div");

[Link]="padding:5px;background:#f4f9f2;font-
size:8px;text-align:center;color:#555";

[Link]=new Date().toLocaleDateString();

[Link](caption);

[Link](photoDiv);

[Link]="";

toast("✅ Photo uploaded!");

};

[Link](file);

// Completed Projects

let COMPLETED_PROJECTS=[
{name:"Ambo BarWaaq Secondary School
Project",status:"Completed",year:2024,budget:2500000000,spent:24800000
00,manager:"Eng. Solomon",reports:"PDF,Excel"},

{name:"AMG Link Rail


Project",status:"Completed",year:2024,budget:1800000000,spent:17950000
00,manager:"Eng. Abebe",reports:"PDF,Excel"},

{name:"Ayisha Health
Center",status:"Completed",year:2025,budget:850000000,spent:840000000,
manager:"Eng. Metakal",reports:"PDF,Excel"},

{name:"Ambo Gravel Road


Project",status:"Completed",year:2025,budget:620000000,spent:610000000,
manager:"Eng. Tesfaye",reports:"PDF,Excel"},

{name:"Indode Rigid Pavement


Project",status:"Completed",year:2025,budget:730000000,spent:725000000,
manager:"Eng. Biruk",reports:"PDF,Excel"}

];

function renderCompletedProjects() {

const filter=[Link]("completed-filter").value;

const filtered=filter==="All"?
COMPLETED_PROJECTS:COMPLETED_PROJECTS.filter(p=>[Link]==filter);

let html="";

[Link](p=>{

const spent=[Link]([Link]/[Link]*100);

html+=`<div style="padding:8px;border:1px solid #c8d8c8;border-


radius:4px;margin-bottom:6px;background:#f4f9f2">

<div style="font-size:10px;font-weight:700;color:#0a3d1f">$
{[Link]}</div>

<div style="font-size:9px;color:#555;margin:3px 0">Project Manager: $


{[Link]} | Year: ${[Link]}</div>

<div style="display:flex;gap:8px;margin:4px 0"><span style="font-


size:9px">Budget: ${([Link]/1000000).toFixed(0)}M ETB</span><span
style="font-size:9px">Spent: ${spent}%</span></div>
<button class="edit-btn" onclick="toast('📥 Downloading historical
reports for ${[Link]}...')" style="font-size:8px;padding:3px 6px">📋 View
Historical Reports</button>

<button class="edit-btn blue" onclick="toast('📄 Generating financial


report...')" style="font-size:8px;padding:3px 6px;margin-left:4px">📊
Financial Report</button>

</div>`;

});

[Link]("completed-projects-
list").innerHTML=html||"<div style='text-
align:center;color:#888;padding:20px;font-size:11px'>No completed projects
for selected year.</div>";

// Upcoming Engineering & Construction Works

let UPCOMING_WORKS=[

{id:1,item:"Stadium Development",start:"2026-08-15",end:"2027-12-
31",scope:"Sports complex with 80,000
capacity",budget:3500000000,status:"🔵 Planned"},

{id:2,item:"Second Ring Road (Phase 2)",start:"2026-10-01",end:"2028-06-


30",scope:"32km highway expansion",budget:4200000000,status:"🔵
Planned"},

{id:3,item:"Metro Light Rail Extension",start:"2026-09-15",end:"2029-03-


31",scope:"15km additional line",budget:2800000000,status:"🟡 In
Preparation"}

];

function renderUpcomingWorks() {

const tbody=[Link]("upcoming-works-tbody");

[Link]=UPCOMING_WORKS.map(w=>`<tr>

<td>${[Link]}</td>

<td>${[Link]}</td>
<td>${[Link]}</td>

<td style="font-size:8px">${[Link]}</td>

<td>${([Link]/1000000).toFixed(0)}M</td>

<td>${[Link]}</td>

</tr>`).join("");

function showUpcomingWorksModal() {

const newWork={

item:prompt("Enter work item name:"),

start:new Date().toISOString().split("T")[0],

end:"",

scope:prompt("Enter scope of work:"),

budget:parseInt(prompt("Enter budget in ETB:"))||0,

status:"🔵 Planned"

};

if([Link]&&[Link]){

UPCOMING_WORKS.push({id:[Link](...UPCOMING_WORKS.map(w=>[Link]||
0),0)+1,...newWork});

renderUpcomingWorks();

toast("✅ Work item added!");

// Download Page as HTML

function downloadPageHTML() {

const html=[Link];
const a=[Link]("a");

[Link]="data:text/html,"+encodeURIComponent(html);

[Link]="EDR_Reports_Page_"+new Date().toISOString().split("T")
[0]+".html";

[Link]();

toast("✅ Page exported as HTML!");

// Download Page as Excel (basic format)

function downloadPageExcel() {

if(![Link]){

toast("❌ Excel library not available. Install SheetJS from:


[Link]

return;

const wb=[Link].book_new();

// Report History Sheet

const historyData=[["Report Name","Type","Generated Date","Generated


By","Distributed To","Format","Action"]];

[Link]("#report-history-tbody tr").forEach(tr=>{

const cells=[];

[Link]("td").forEach((td,idx)=>{

if(idx<6)[Link]([Link]);

});

if([Link]>0)[Link](cells);

});
[Link].book_append_sheet(wb,[Link].aoa_to_sheet(historyData),"Rep
ort History");

// Completed Projects Sheet

const completedData=[["Project Name","Status","Year","Budget


(ETB)","Spent (ETB)","% Spent","Project Manager"]];

COMPLETED_PROJECTS.forEach(p=>{

const spent=[Link]([Link]/[Link]*100);

[Link]([[Link],[Link],[Link],[Link],[Link],spent+"%",p.
manager]);

});

[Link].book_append_sheet(wb,[Link].aoa_to_sheet(completedData),"
Completed Projects");

// Upcoming Works Sheet

const upcomingData=[["Work Item","Planned Start","Planned


End","Scope","Budget (ETB)","Status"]];

UPCOMING_WORKS.forEach(w=>{

[Link]([[Link],[Link],[Link],[Link],[Link],[Link]]);

});

[Link].book_append_sheet(wb,[Link].aoa_to_sheet(upcomingData),"U
pcoming Works");

[Link](wb,"EDR_Reports_"+new Date().toISOString().split("T")
[0]+".xlsx");

toast("✅ Page exported as Excel!");


}

// Initialize new sections on page load

[Link]("load",function(){

if([Link]("upcoming-works-
tbody"))renderUpcomingWorks();

if([Link]("completed-projects-
list"))renderCompletedProjects();

});

//
═══════════════════════════════════════════════════════
════════
// COST MODULE ENHANCEMENTS v10

//
═══════════════════════════════════════════════════════
════════

// ── Populate Cost Project Dropdown ──────────────────────────────

function _initCostProjectDropdown() {

var sel = [Link]("cost-project-select");

if (!sel) return;

// Preserve the current selection before rebuilding options

var prevVal = [Link];

// Remove old project options (keep "ALL" option)

while ([Link] > 1) [Link](1);

[Link](function(p) {

var opt = [Link]("option");

[Link] = [Link];
[Link] = [Link];

[Link](opt);

});

// Restore the previously selected value if it still exists

if (prevVal && prevVal !== "ALL") {

[Link] = prevVal;

// Fall back to ALL if the value no longer exists

if ([Link] !== prevVal) [Link] = "ALL";

// ── Called when cost project dropdown changes ────────────────────

function onCostProjectChange() {

var sel = [Link]("cost-project-select");

if (!sel) return;

var val = [Link];

// Update selector bar tags

var tagPhase = [Link]("cost-sel-tag-phase");

var tagMgr = [Link]("cost-sel-tag-manager");

var tagStat = [Link]("cost-sel-tag-status");

if (val === "ALL") {

[tagPhase, tagMgr, tagStat].forEach(function(t){ if(t) [Link] =


"none"; });

} else {

var p = [Link](function(x){ return [Link] == val; });

if (p) {
if (tagPhase) { [Link] = "📌 " + [Link] + " Phase";
[Link] = ""; }

if (tagMgr) { [Link] = "👤 " + [Link];


[Link] = ""; }

if (tagStat) { [Link] = "● " + [Link];


[Link] = ""; }

// Legacy badge (hidden div, kept for compat)

var badge = [Link]("cost-project-badge");

if (badge) [Link] = "none";

// Toggle portfolio vs project view visibility

_toggleCostViewMode(val);

renderCost();

// ── Toggle between Portfolio View and Project View ───────────────

function _toggleCostViewMode(val) {

var isAll = (val === "ALL");

// All main cost sections are always visible — they are filtered by selection

var mainRows = ["cost-row-evm","cost-row-variance","cost-row-


cashflow","cost-row-breakdown"];

[Link](function(id){

var el = [Link](id);

if (el) [Link] = "";

});

// The legacy project-specific panel is always hidden (data now shown in


main sections)
var pvPanel = [Link]("cost-project-view");

if (pvPanel) [Link] = "none";

// Update section headers to reflect current context

_updateCostSectionHeaders(val);

// ── Update section headers based on selected project ─────────────

function _updateCostSectionHeaders(val) {

var isAll = (val === "ALL");

var projName = "";

if (!isAll) {

var p = [Link](function(x){ return [Link] == val; });

if (p) projName = [Link];

var prefix = isAll ? "" : ("— " + ([Link] > 35 ?


[Link](0,33)+"…" : projName) + " ");

var evmHdr = [Link]("#cost-row-evm .wh");

if (evmHdr) [Link] = "📐 EARNED VALUE MANAGEMENT (EVM) "


+ prefix + (isAll ? "— DETAILED TABLE" : "— PROJECT DETAIL");

var varHdr = [Link]("#cost-row-variance .fw2:first-


child .wh");

if (varHdr) [Link] = "📊 COST VARIANCE ANALYSIS" + (isAll ? "" :


" — " + ([Link]>25?[Link](0,23)+"…":projName));

var bcaHdr = [Link]("#cost-row-variance .fw2:last-


child .wh");

if (bcaHdr) [Link] = "💼 BUDGET vs ACTUAL" + (isAll ? "" : "");

var cfHdr = [Link]("#cost-row-cashflow .wh");


if (cfHdr) [Link] = isAll ? "📅 CASH FLOW FORECAST — PLANNED
EXPENDITURES BY PERIOD" : "📅 CASH FLOW FORECAST — " +
([Link]>40?[Link](0,38)+"…":projName);

var bdHdr = [Link]("#cost-row-breakdown .wh");

if (bdHdr) [Link] = isAll ? "📋 DETAILED COST BREAKDOWN" : "📋


DETAILED COST BREAKDOWN — " + ([Link]>35?
[Link](0,33)+"…":projName);

// ── Get filtered projects based on dropdown ──────────────────────

function _getCostFilteredProjects() {

var sel = [Link]("cost-project-select");

if (!sel || [Link] === "ALL") return PROJECTS;

var id = parseInt([Link]);

return [Link](function(p){ return [Link] === id; });

// ── EVM Data helper (derives EVM metrics from project data) ──────

function _getEVMData(p) {

// BAC = Budget at Completion

var bac = [Link];

// PV = Planned Value = BAC * (progress% as planned). Use spent ratio as


proxy for planned

var plannedPct = [Link]([Link] / 100 + 0.05, 1); // slightly ahead of


actual progress

var pv = [Link](bac * plannedPct);

// EV = Earned Value = BAC * physical % complete

var ev = [Link](bac * ([Link] / 100));

// AC = Actual Cost = [Link]


var ac = [Link];

// CV = Cost Variance = EV - AC

var cv = ev - ac;

// SV = Schedule Variance = EV - PV

var sv = ev - pv;

// CPI = EV / AC

var cpi = ac > 0 ? parseFloat((ev / ac).toFixed(2)) : 1.00;

// SPI = EV / PV

var spi = pv > 0 ? parseFloat((ev / pv).toFixed(2)) : 1.00;

// EAC = Estimate at Completion = BAC / CPI

var eac = cpi > 0 ? [Link](bac / cpi) : bac;

// VAC = Variance at Completion = BAC - EAC

var vac = bac - eac;

return { bac:bac, pv:pv, ev:ev, ac:ac, cv:cv, sv:sv, cpi:cpi, spi:spi, eac:eac,
vac:vac };

// ── Update Project Cost Summary Panel ───────────────────────────

function _updateProjectCostSummary(projects) {

function fmt(v){ return "ETB


"+(v>=1e9?(v/1e9).toFixed(2)+"B":(v/1e6).toFixed(0)+"M"); }

var sel = [Link]("cost-project-select");

var isAll = !sel || [Link] === "ALL";

var isSingle = [Link] === 1;

// Aggregate EVM metrics

var totBAC=0, totPV=0, totEV=0, totAC=0;


[Link](function(p){

var d = _getEVMData(p);

totBAC += [Link]; totPV += [Link]; totEV += [Link]; totAC += [Link];

});

var aggCPI = totAC>0 ? parseFloat((totEV/totAC).toFixed(2)) : 1.00;

var aggSPI = totPV>0 ? parseFloat((totEV/totPV).toFixed(2)) : 1.00;

var eac = aggCPI>0 ? [Link](totBAC/aggCPI) : totBAC;

var vac = totBAC - eac;

var utilPct = totBAC>0 ? [Link](totAC/totBAC*100) : 0;

// Determine overall status

var overallStatus, statusClass;

if (aggCPI >= 1.0 && aggSPI >= 1.0) { overallStatus = "✅ HEALTHY";
statusClass = "healthy"; }

else if (aggCPI >= 0.9 && aggSPI >= 0.85) { overallStatus = "⚠ WARNING";
statusClass = "warning"; }

else { overallStatus = "🔴 AT RISK"; statusClass = "critical"; }

if (isAll) { overallStatus = "PORTFOLIO VIEW"; statusClass = "portfolio"; }

// Update panel title

var titleEl = [Link]("pcs-title");

if (titleEl) {

if (isSingle) [Link] = "📊 PROJECT COST SUMMARY — " +


projects[0].[Link]();

else [Link] = "📊 PROJECT COST SUMMARY — ALL PROJECTS


(PORTFOLIO)";

}
// Update status badge

var badgeEl = [Link]("pcs-status-badge");

if (badgeEl) {

[Link] = overallStatus;

[Link] = "pcs-status-badge " + statusClass;

// Helper to set cell value

function setCell(id, val) { var el=[Link](id); if(el)


[Link]=val; }

function setStyle(id, prop, val) { var el=[Link](id); if(el)


[Link][prop]=val; }

var cpiColor =
aggCPI>=1?"#1e8449":aggCPI>=0.9?"#d35400":"#c0392b";

var spiColor =
aggSPI>=1?"#1e8449":aggSPI>=0.9?"#d35400":"#c0392b";

var vacColor = vac>=0?"#1e8449":"#c0392b";

var utilColor = utilPct>90?"#e74c3c":utilPct>75?"#f39c12":"#27ae60";

setCell("pcs-bac", fmt(totBAC));

setCell("pcs-ac", fmt(totAC));

setCell("pcs-ev", fmt(totEV));

setCell("pcs-pv", fmt(totPV));

setCell("pcs-cpi", [Link](2));

setStyle("pcs-cpi", "color", cpiColor);

setCell("pcs-cpi-sub", aggCPI>=1?"✅ Efficient":"⚠ Over Budget");


setStyle("pcs-cpi-sub", "color", cpiColor);

setCell("pcs-spi", [Link](2));

setStyle("pcs-spi", "color", spiColor);

setCell("pcs-spi-sub", aggSPI>=1?"✅ On Schedule":"⚠ Behind");

setStyle("pcs-spi-sub", "color", spiColor);

setCell("pcs-eac", fmt(eac));

setCell("pcs-vac", (vac>=0?"+":"")+fmt([Link](vac)));

setStyle("pcs-vac", "color", vacColor);

var vacPct = totBAC>0 ? [Link]([Link](vac/totBAC*100)) : 0;

setCell("pcs-vac-sub", (vac>=0?"▼ "+vacPct+"% under budget":"▲


"+vacPct+"% over budget"));

setStyle("pcs-vac-sub", "color", vacColor);

setCell("pcs-util", utilPct+"%");

setStyle("pcs-util", "color", utilColor);

var barEl = [Link]("pcs-util-bar");

if (barEl) { [Link] = [Link](utilPct,100)+"%";


[Link] = utilColor; }

setCell("pcs-util-sub", fmt(totAC)+" of "+fmt(totBAC)+" spent");

// ── Excel Cost Import ────────────────────────────────────────────

function importCostExcel(input) {

var file = [Link][0]; if(!file) return;

var reader = new FileReader();


[Link] = function(e) {

var data = new Uint8Array([Link]);

try {

if(![Link]) { toast("❌ Excel library not available. Using CSV format


instead."); return; }

var workbook = [Link](data, {type:"array"});

var sheet = [Link][[Link][0]];

var json = [Link].sheet_to_json(sheet);

var added = 0, updated = 0;

var colors =
["#0a3d1f","#27ae60","#2980b9","#f39c12","#8e44ad","#e74c3c","#16a0
85","#d35400"];

[Link](function(row) {

var name = row["Project"]||row["Project Name"]||row["Name"];

if (!name) return;

var budget = parseFloat((row["Budget"]||row["BAC"]||row["Budget


(ETB)"]||"0").toString().replace(/[^0-9.]/g,""))||0;

var spent = parseFloat((row["Actual"]||row["AC"]||row["Spent"]||


row["Actual (ETB)"]||"0").toString().replace(/[^0-9.]/g,""))||0;

var prog = parseInt((row["Progress"]||row["%


Complete"]||"0").toString().replace(/[^0-9]/g,""))||0;

var mgr = row["Project Manager"]||row["Project Manager"]||"TBD";

var stat = row["Status"]||"On Track";

var phase = row["Phase"]||"Build";

var existing = [Link](function(p){ return


[Link]()===[Link](); });

if (existing) {

if(budget>0) [Link] = budget;

if(spent>0) [Link] = spent;


if(prog>0) [Link] = prog;

[Link] = mgr; [Link] = stat; [Link] =


phase;

updated++;

} else if (budget > 0) {

[Link]({id:nextId+
+,name:name,manager:mgr,phase:phase,start:"2026-01",end:"2026-
12",budget:budget,spent:spent||[Link](budget*0.3),progress:prog||
30,status:stat,priority:"Medium",risks:0,color:colors[[Link]
%[Link]]});

added++;

});

[Link] = "";

_initCostProjectDropdown();

renderCost();

toast("✅ Cost data imported: "+added+" new, "+updated+" updated


projects!");

} catch(err) { toast("❌ Error parsing Excel: "+[Link]); }

};

[Link](file);

// ── MS Project XML Cost Import ───────────────────────────────────

function importCostMSP(input) {

var file = [Link][0]; if(!file) return;

if(![Link]().endsWith('.xml')) { toast("❌ Please upload an


XML file exported from Microsoft Project."); [Link]=""; return; }

var reader = new FileReader();


[Link] = function(e) {

var content = [Link];

try {

var xmlDoc = new DOMParser().parseFromString(content, "text/xml");

var ns = "[Link]

var tasks = [Link]([Link](ns,"Task"));

if(![Link]) tasks =
[Link]([Link]("Task"));

if(![Link]) { toast("❌ No tasks found in XML file."); [Link]="";


return; }

var getVal = function(el,tag){ var


node=[Link](ns,tag)[0]||
[Link](tag)[0]; return node?
[Link]():""; };

var added = 0;

var colors =
["#27ae60","#2980b9","#f39c12","#8e44ad","#e74c3c","#16a085"];

// Group tasks by their WBS/project name for budget aggregation

[Link](function(t) {

var uid = getVal(t,"UID"); if(uid==="0") return;

var name = getVal(t,"Name"); if(!name) return;

var pct = parseInt(getVal(t,"PercentComplete")||"0")||0;

var isSummary = getVal(t,"Summary")==="1";

if(isSummary) {

var budgetRaw = parseFloat(getVal(t,"Cost")||"0");

var actualRaw = parseFloat(getVal(t,"ActualCost")||"0");

if(budgetRaw>0) {

var existing = [Link](function(p){ return


[Link]()===[Link](); });
if(existing) { [Link]=[Link](budgetRaw);
[Link]=[Link](actualRaw); [Link]=pct; }

else { [Link]({id:nextId+
+,name:name,manager:"TBD",phase:"Build",start:"2026-01",end:"2026-
12",budget:[Link](budgetRaw),spent:[Link](actualRaw)||
[Link](budgetRaw*0.3),progress:pct||30,status:"On
Track",priority:"Medium",risks:0,color:colors[[Link]
%[Link]]}); added++; }

});

[Link] = "";

_initCostProjectDropdown();

renderCost();

if(added>0) toast("✅ "+added+" project(s) imported from MS Project


XML!");

else toast("ℹ️Cost data updated from MS Project XML (matched to existing


projects).");

} catch(err) { toast("❌ Error parsing MS Project XML: "+[Link]); }

};

[Link](file);

// ── Render EVM Section ───────────────────────────────────────────

function _renderEVM(projects) {

var grid = [Link]("evm-kpi-grid");

var tbody = [Link]("evm-tbody");

if (!tbody) return;
var isSingle = [Link] === 1;

// Update "Project" column header if in single-project mode

var evmTbl = [Link]("evm-table");

if (evmTbl) {

var firstTh = [Link]("thead tr th:first-child");

if (firstTh) [Link] = isSingle ? "Project / Activity" : "Project";

// Aggregate for KPI strip

var totBAC=0, totPV=0, totEV=0, totAC=0;

[Link](function(p){

var d = _getEVMData(p);

totBAC += [Link]; totPV += [Link]; totEV += [Link]; totAC += [Link];

});

var aggCPI = totAC>0 ? parseFloat((totEV/totAC).toFixed(2)) : 1.00;

var aggSPI = totPV>0 ? parseFloat((totEV/totPV).toFixed(2)) : 1.00;

var cpiColor = aggCPI >= 1 ? "#1e8449" : aggCPI >= 0.9 ? "#d35400" :


"#c0392b";

var spiColor = aggSPI >= 1 ? "#1e8449" : aggSPI >= 0.9 ? "#d35400" :


"#c0392b";

function fmt(v){ return "ETB


"+(v>=1e9?(v/1e9).toFixed(2)+"B":(v/1e6).toFixed(0)+"M"); }

if (grid) {

[Link] =
'<div class="evm-kpi bac"><div class="evm-kpi-val"
style="color:#0a3d1f">'+fmt(totBAC)+'</div><div class="evm-kpi-
lbl">BAC</div><div class="evm-kpi-sub">Budget at
Completion</div></div>'+

'<div class="evm-kpi pv"><div class="evm-kpi-val"


style="color:#2980b9">'+fmt(totPV)+'</div><div class="evm-kpi-
lbl">PV</div><div class="evm-kpi-sub">Planned Value</div></div>'+

'<div class="evm-kpi ev"><div class="evm-kpi-val"


style="color:#27ae60">'+fmt(totEV)+'</div><div class="evm-kpi-
lbl">EV</div><div class="evm-kpi-sub">Earned Value</div></div>'+

'<div class="evm-kpi ac"><div class="evm-kpi-val"


style="color:#d35400">'+fmt(totAC)+'</div><div class="evm-kpi-
lbl">AC</div><div class="evm-kpi-sub">Actual Cost</div></div>'+

'<div class="evm-kpi cpi"><div class="evm-kpi-val"


style="color:'+cpiColor+'">'+aggCPI+'</div><div class="evm-kpi-
lbl">CPI</div><div class="evm-kpi-sub">'+(aggCPI>=1?"✅ Efficient":"⚠
Over Budget")+'</div></div>'+

'<div class="evm-kpi spi"><div class="evm-kpi-val"


style="color:'+spiColor+'">'+aggSPI+'</div><div class="evm-kpi-
lbl">SPI</div><div class="evm-kpi-sub">'+(aggSPI>=1?"✅ On
Schedule":"⚠ Behind Schedule")+'</div></div>';

// For single project: break down into activity categories

var rows = [];

if (isSingle) {

var p = projects[0];

var d = _getEVMData(p);

// Simulate activity-level EVM breakdown (representative split of the


project budget)

var activities = [

{name:"Civil Works", budgetFrac:0.38, progressFrac:0.96},


{name:"Track Laying", budgetFrac:0.22, progressFrac:0.88},

{name:"Structures", budgetFrac:0.14, progressFrac:0.82},

{name:"Electrical & Systems", budgetFrac:0.11, progressFrac:0.72},

{name:"Procurement", budgetFrac:0.08, progressFrac:0.94},

{name:"Testing & Comm.", budgetFrac:0.04, progressFrac:0.55},

{name:"Management & HSE", budgetFrac:0.03, progressFrac:0.78},

];

rows = [Link](function(act){

var actBac = [Link]([Link] * [Link]);

var actPv = [Link](actBac * ([Link]/100 + 0.05) *


[Link]);

var actEv = [Link](actBac * ([Link]/100) * [Link]);

var actAc = [Link]([Link] * [Link] * (0.90 +


[Link] * 0.15));

var actCv = actEv - actAc;

var actSv = actEv - actPv;

var actCpi = actAc>0 ? parseFloat((actEv/actAc).toFixed(2)) : 1.00;

var actSpi = actPv>0 ? parseFloat((actEv/actPv).toFixed(2)) : 1.00;

var actEac = actCpi>0 ? [Link](actBac/actCpi) : actBac;

var actVac = actBac - actEac;

var cvColor = actCv>=0?"#1e8449":"#c0392b";

var svColor = actSv>=0?"#1e8449":"#c0392b";

var cpiC = actCpi>=1?"#1e8449":actCpi>=0.9?"#d35400":"#c0392b";

var spiC = actSpi>=1?"#1e8449":actSpi>=0.9?"#d35400":"#c0392b";

var vacColor = actVac>=0?"#1e8449":"#c0392b";

return '<tr>'+

'<td style="font-weight:700;color:#0a3d1f">'+[Link]+'</td>'+
'<td>'+fmt(actBac)+'</td>'+

'<td>'+fmt(actPv)+'</td>'+

'<td>'+fmt(actEv)+'</td>'+

'<td>'+fmt(actAc)+'</td>'+

'<td style="color:'+cvColor+';font-weight:700">'+(actCv>=0?"+":"")
+fmt([Link](actCv))+'</td>'+

'<td style="color:'+svColor+';font-weight:700">'+(actSv>=0?"+":"")
+fmt([Link](actSv))+'</td>'+

'<td style="color:'+cpiC+';font-weight:800">'+actCpi+'</td>'+

'<td style="color:'+spiC+';font-weight:800">'+actSpi+'</td>'+

'<td>'+fmt(actEac)+'</td>'+

'<td style="color:'+vacColor+';font-weight:700">'+(actVac>=0?"+":"")
+fmt([Link](actVac))+'</td>'+

'</tr>';

});

// Append totals row

[Link]('<tr style="background:#f0f8f0;font-weight:800;border-top:2px
solid #0a3d1f">'+

'<td style="color:#0a3d1f">TOTAL — '+[Link](0,25)+


([Link]>25?"…":"")+'</td>'+

'<td>'+fmt([Link])+'</td>'+

'<td>'+fmt([Link])+'</td>'+

'<td>'+fmt([Link])+'</td>'+

'<td>'+fmt([Link])+'</td>'+

'<td style="color:'+([Link]>=0?"#1e8449":"#c0392b")+';font-
weight:800">'+([Link]>=0?"+":"")+fmt([Link]([Link]))+'</td>'+

'<td style="color:'+([Link]>=0?"#1e8449":"#c0392b")+';font-
weight:800">'+([Link]>=0?"+":"")+fmt([Link]([Link]))+'</td>'+
'<td style="color:'+
([Link]>=1?"#1e8449":[Link]>=0.9?"#d35400":"#c0392b")+';font-
weight:800">'+[Link]+'</td>'+

'<td style="color:'+
([Link]>=1?"#1e8449":[Link]>=0.9?"#d35400":"#c0392b")+';font-
weight:800">'+[Link]+'</td>'+

'<td style="font-weight:800">'+fmt([Link])+'</td>'+

'<td style="color:'+([Link]>=0?"#1e8449":"#c0392b")+';font-
weight:800">'+([Link]>=0?"+":"")+fmt([Link]([Link]))+'</td>'+

'</tr>');

} else {

rows = [Link](function(p){

var d = _getEVMData(p);

var cvColor = [Link]>=0?"#1e8449":"#c0392b";

var svColor = [Link]>=0?"#1e8449":"#c0392b";

var cpiC = [Link]>=1?"#1e8449":[Link]>=0.9?"#d35400":"#c0392b";

var spiC = [Link]>=1?"#1e8449":[Link]>=0.9?"#d35400":"#c0392b";

var vacColor = [Link]>=0?"#1e8449":"#c0392b";

var sname = [Link]>30?[Link](0,28)+"..":[Link];

return '<tr>'+

'<td title="'+[Link]+'">'+sname+'</td>'+

'<td>'+fmt([Link])+'</td>'+

'<td>'+fmt([Link])+'</td>'+

'<td>'+fmt([Link])+'</td>'+

'<td>'+fmt([Link])+'</td>'+

'<td style="color:'+cvColor+';font-weight:700">'+([Link]>=0?"+":"")
+fmt([Link]([Link]))+'</td>'+

'<td style="color:'+svColor+';font-weight:700">'+([Link]>=0?"+":"")
+fmt([Link]([Link]))+'</td>'+
'<td style="color:'+cpiC+';font-weight:800">'+[Link]+'</td>'+

'<td style="color:'+spiC+';font-weight:800">'+[Link]+'</td>'+

'<td>'+fmt([Link])+'</td>'+

'<td style="color:'+vacColor+';font-weight:700">'+([Link]>=0?"+":"")
+fmt([Link]([Link]))+'</td>'+

'</tr>';

});

[Link] = [Link]("");

// ── Render Cost Variance Analysis ───────────────────────────────

//
═══════════════════════════════════════════════════════
════════
// PROJECT COST VIEW — renders single-project cost details

//
═══════════════════════════════════════════════════════
════════
function _renderProjectCostView(projects) {

if (!projects || [Link] === 0) return;

var p = projects[0];

var d = _getEVMData(p);

function fmt(v){ return "ETB


"+(v>=1e9?(v/1e9).toFixed(2)+"B":(v/1e6).toFixed(0)+"M"); }

// Derived values

var commitFactor = 0.87 + ([Link]/100)*0.08;


var committed = [Link]([Link]([Link] * commitFactor),
[Link]);

var forecast = [Link]([Link] * 0.97);

var utilPct = [Link]([Link]/[Link]*100);

var utilColor = utilPct>90?"#e74c3c":utilPct>75?"#f39c12":"#27ae60";

var cpiColor = [Link]>=1?"#1e8449":[Link]>=0.9?"#d35400":"#c0392b";

var spiColor = [Link]>=1?"#1e8449":[Link]>=0.9?"#d35400":"#c0392b";

var vacColor = [Link]>=0?"#1e8449":"#c0392b";

// ── KPI tiles ──

var kpiGrid = [Link]("pv-kpi-grid");

if (kpiGrid) {

[Link] =

'<div class="kpi green-kpi"><div


class="kpi-val">'+fmt([Link])+'</div><div class="kpi-lbl">Approved
Budget (BAC)</div></div>'+

'<div class="kpi blue-kpi"><div class="kpi-val"


style="color:#2980b9">'+fmt([Link])+'</div><div class="kpi-lbl">Actual
Cost (AC)</div></div>'+

/* Committed Cost KPI removed - replaced by Budget vs Actual focus */

''+ // Committed cost removed

'<div class="kpi orange-kpi"><div


class="kpi-val">'+fmt(forecast)+'</div><div class="kpi-lbl">Forecast to
Complete</div></div>'+

'<div class="kpi '+([Link]>=1?"green-kpi":"red-kpi")+'"><div class="kpi-


val" style="color:'+cpiColor+'">'+[Link](2)+'</div><div class="kpi-
lbl">CPI '+([Link]>=1?"✅ Efficient":"⚠ Over Budget")+'</div></div>'+

'<div class="kpi '+([Link]>=1?"green-kpi":"orange-kpi")+'"><div


class="kpi-val" style="color:'+spiColor+'">'+[Link](2)+'</div><div
class="kpi-lbl">SPI '+([Link]>=1?"✅ On Schedule":"⚠
Behind")+'</div></div>'+
'<div class="kpi orange-kpi"><div
class="kpi-val">'+fmt([Link])+'</div><div class="kpi-lbl">EAC (Estimate at
Completion)</div></div>'+

'<div class="kpi '+([Link]>=0?"green-kpi":"red-kpi")+'"><div class="kpi-


val" style="color:'+vacColor+'">'+([Link]>=0?"+":"")+fmt([Link]([Link]))
+'</div><div class="kpi-lbl">VAC '+([Link]>=0?"▼ Under Budget":"▲ Over
Budget")+'</div></div>';

// ── Budget vs Actual ──

var baEl = [Link]("pv-budget-actual");

if (baEl) {

var barW = [Link](utilPct,100);

[Link] =

'<div style="margin-bottom:12px">'+

'<div style="display:flex;justify-content:space-between;margin-
bottom:4px">'+

'<span style="font-size:10px;font-weight:800;color:#0a3d1f">Budget
Utilization</span>'+

'<span style="font-size:11px;font-
weight:800;color:'+utilColor+'">'+utilPct+'%</span>'+

'</div>'+

'<div style="height:14px;background:#e8f0e8;border-
radius:7px;overflow:hidden">'+

'<div
style="height:100%;width:'+barW+'%;background:'+utilColor+';border-
radius:7px;transition:width .4s"></div>'+

'</div>'+

'<div style="display:flex;justify-content:space-between;margin-
top:4px;font-size:9px;color:#777">'+

'<span>ETB 0</span><span>'+fmt([Link])+'</span>'+
'</div>'+

'</div>'+

'<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px">'+

'<div style="background:#f4f9f2;border:1px solid #c8d8c8;border-


radius:4px;padding:8px;text-align:center">'+

'<div style="font-size:15px;font-
weight:800;color:#0a3d1f">'+fmt([Link])+'</div>'+

'<div style="font-size:8px;color:#777;font-weight:700">APPROVED
BUDGET</div>'+

'</div>'+

'<div style="background:#d6eaf8;border:1px solid #aed6f1;border-


radius:4px;padding:8px;text-align:center">'+

'<div style="font-size:15px;font-
weight:800;color:#2980b9">'+fmt([Link])+'</div>'+

'<div style="font-size:8px;color:#777;font-weight:700">ACTUAL COST


TO DATE</div>'+

'</div>'+

'</div>'+

'<div style="margin-top:8px;font-
size:9px;color:#555;background:#fafafa;border:1px solid #e8f0e8;border-
radius:3px;padding:5px 8px">'+

'<b>Progress:</b> '+[Link]+'% complete &nbsp;|&nbsp;


<b>Phase:</b> '+[Link]+' &nbsp;|&nbsp; <b>Project Manager:</b>
'+[Link]+

'</div>';

// ── Committed & Forecast ──

var cfEl = [Link]("pv-committed-forecast"); // Now


shows Budget vs Actual breakdown
if (cfEl) {

var commitPct = [Link](committed/[Link]*100);

var forecastPct = [Link](forecast/[Link]*100);

[Link] =

'<div style="font-size:9px;font-weight:800;color:#0a3d1f;margin-
bottom:6px;letter-spacing:.3px">BUDGET vs ACTUAL COST
BREAKDOWN</div>'+

'<div class="hbr" style="margin-bottom:10px">'+

'<div class="hbr-lbl sm">Budget</div>'+

'<div class="hbr-track"><div class="hbr-fill"


style="width:100%;background:#0a3d1f22;border:1px solid
#0a3d1f">'+fmt([Link])+'</div></div>'+

'<div class="hbr-num">100%</div>'+

'</div>'+

'<div class="hbr" style="margin-bottom:10px">'+

'<div class="hbr-lbl sm" style="color:#2980b9">Actual</div>'+

'<div class="hbr-track"><div class="hbr-fill"


style="width:'+utilPct+'%;background:#2980b9">'+fmt([Link])+'</div></
div>'+

'<div class="hbr-num" style="color:#2980b9">'+utilPct+'%</div>'+

'</div>'+

'<div class="hbr" style="margin-bottom:10px">'+

'<div class="hbr-lbl sm" style="color:#d35400">Forecast EAC</div>'+

'<div class="hbr-track"><div class="hbr-fill"


style="width:'+forecastPct+'%;background:#d35400">'+fmt(forecast)+'</
div></div>'+

'<div class="hbr-num"
style="color:#d35400">'+forecastPct+'%</div>'+

'</div>'+
'<div style="margin-top:8px;padding:6px
8px;background:#f4f9f2;border-radius:4px;border:1px solid #c8d8c8;font-
size:9px">'+

'<span style="color:#0a3d1f;font-weight:700">Budget Remaining:


</span>'+

'<span style="color:'+([Link]>=0?"#1e8449":"#c0392b")
+';font-weight:800">'+

([Link]>=0?"+":"")+fmt([Link]([Link]))+

'</span>'+

'</div>';

// ── Variance ──

var varEl = [Link]("pv-variance");

if (varEl) {

var cv = [Link]; var sv = [Link];

var cvColor = cv>=0?"#1e8449":"#c0392b";

var svColor = sv>=0?"#1e8449":"#c0392b";

[Link] =

'<div style="margin-bottom:10px">'+

'<div style="font-size:9px;font-weight:800;color:#555;margin-
bottom:3px">COST VARIANCE (CV = EV - AC)</div>'+

'<div style="font-size:20px;font-weight:800;color:'+cvColor+'">'+
(cv>=0?"+":"")+fmt([Link](cv))+'</div>'+

'<div style="font-size:8px;color:'+cvColor+'">'+(cv>=0?"✅ Under


budget by "+[Link](cv/[Link]*100)+"%":"⚠ Over budget by
"+[Link]([Link](cv)/[Link]*100)+"%")+'</div>'+

'</div>'+

'<div>'+
'<div style="font-size:9px;font-weight:800;color:#555;margin-
bottom:3px">SCHEDULE VARIANCE (SV = EV - PV)</div>'+

'<div style="font-size:20px;font-weight:800;color:'+svColor+'">'+
(sv>=0?"+":"")+fmt([Link](sv))+'</div>'+

'<div style="font-size:8px;color:'+svColor+'">'+(sv>=0?"✅ Ahead of


plan":"⚠ Behind plan by "+[Link]([Link](sv)/[Link]*100)+"%")
+'</div>'+

'</div>';

// ── CPI panel ──

var cpiEl = [Link]("pv-cpi");

if (cpiEl) {

var cpiBarW = [Link]([Link]([Link]*60), 100);

var spiBarW = [Link]([Link]([Link]*60), 100);

[Link] =

'<div style="margin-bottom:12px">'+

'<div style="display:flex;justify-content:space-between;align-
items:center;margin-bottom:3px">'+

'<span style="font-size:9px;font-weight:800;color:#555">CPI (Earned


Value / Actual Cost)</span>'+

'<span style="font-size:18px;font-
weight:800;color:'+cpiColor+'">'+[Link](2)+'</span>'+

'</div>'+

'<div style="height:8px;background:#e8f0e8;border-
radius:4px;overflow:hidden">'+

'<div
style="height:100%;width:'+cpiBarW+'%;background:'+cpiColor+';border-
radius:4px"></div>'+

'</div>'+
'<div style="font-size:8px;color:'+cpiColor+';margin-top:2px">'+
([Link]>=1?"Efficient — for every ETB 1 spent, ETB "+[Link](2)+" of
value earned":"Cost overrun — "+(([Link])*100).toFixed(0)+"% over plan
per ETB spent")+'</div>'+

'</div>'+

'<div>'+

'<div style="display:flex;justify-content:space-between;align-
items:center;margin-bottom:3px">'+

'<span style="font-size:9px;font-weight:800;color:#555">SPI (Earned


Value / Planned Value)</span>'+

'<span style="font-size:18px;font-
weight:800;color:'+spiColor+'">'+[Link](2)+'</span>'+

'</div>'+

'<div style="height:8px;background:#e8f0e8;border-
radius:4px;overflow:hidden">'+

'<div
style="height:100%;width:'+spiBarW+'%;background:'+spiColor+';border-
radius:4px"></div>'+

'</div>'+

'<div style="font-size:8px;color:'+spiColor+';margin-top:2px">'+
([Link]>=1?"On / ahead of schedule":"Behind schedule — "+((1-
[Link])*100).toFixed(0)+"% slower than planned")+'</div>'+

'</div>';

// ── EAC panel ──

var eacEl = [Link]("pv-eac");

if (eacEl) {

var eacPct = [Link]([Link]([Link])/[Link]*100);

[Link] =
'<div style="text-align:center;padding:8px 0">'+

'<div style="font-size:9px;font-weight:800;color:#555;margin-
bottom:4px">ESTIMATE AT COMPLETION (EAC = BAC / CPI)</div>'+

'<div style="font-size:26px;font-
weight:800;color:#d35400">'+fmt([Link])+'</div>'+

'<div style="font-size:9px;color:#777;margin-top:2px">Original
Budget: '+fmt([Link])+'</div>'+

'</div>'+

'<div style="background:'+([Link]>=0?"#d4efdf":"#fadbd8")
+';border:1px solid '+([Link]>=0?"#a9dfbf":"#f1948a")+';border-
radius:4px;padding:8px;text-align:center;margin-top:4px">'+

'<div style="font-size:14px;font-weight:800;color:'+vacColor+'">'+
([Link]>=0?"▼ UNDER BUDGET":"▲ OVER BUDGET")+' BY
'+eacPct+'%</div>'+

'<div style="font-size:10px;font-weight:700;color:'+vacColor+'">VAC =
'+([Link]>=0?"+":"")+fmt([Link]([Link]))+'</div>'+

'</div>';

// ── Project Cash Flow chart ──

var pcfEl = [Link]("pv-cashflow");

var hdr = [Link]("pv-cashflow-header");

if (hdr) [Link] = "📅 " + [Link] + " — CASH FLOW: PLANNED vs


ACTUAL";

if (pcfEl) {

var months =
["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];

var chartH2 = 80;

var budgetShare = [Link];

var mPlan = [Link](function(m,i){


var f; if(i<2) f=0.055; else if(i<4) f=0.075; else if(i<6) f=0.095;

else if(i<8) f=0.095; else if(i<10) f=0.075; else f=0.055;

return [Link](budgetShare * f / 1e6);

});

var mAct = [Link](function(m,i){

if(i>4) return null;

var f; if(i<2) f=0.050; else if(i<4) f=0.080; else if(i<5) f=0.085; else
f=null;

return f ? [Link](budgetShare * f / 1e6) : null;

});

var maxV2 = [Link](null, [Link]([Link](function(v)


{return v!==null;})));

var barsHtml2 = [Link](function(m,i){

var plan=mPlan[i]; var actual=mAct[i];

var planH=[Link]((plan/maxV2)*chartH2);

var actH=actual!==null?[Link]((actual/maxV2)*chartH2):0;

var isPast=i<=4; var isCurrent=i===4;

var bStyle=isCurrent?"border:1.5px solid #e74c3c;border-


radius:4px;padding:2px;background:#fff8f8;":"";

return '<div class="cf-month" style="'+bStyle+'">'+

'<div style="display:flex;align-items:flex-
end;gap:2px;height:'+chartH2+'px">'+

'<div style="width:12px;background:#d6eaf8;border-radius:3px 3px 0


0;height:'+planH+'px" title="Planned: ETB '+plan+'M"></div>'+

(isPast?'<div style="width:12px;background:'+
(actual>plan?'#e74c3c':'#27ae60')+';border-radius:3px 3px 0
0;height:'+actH+'px" title="Actual: ETB '+actual+'M"></div>':

'<div style="width:12px;background:#fdebd0;border-radius:3px
3px 0 0;height:'+[Link](planH*0.9)+'px;opacity:.7"
title="Forecast"></div>')+
'</div>'+

'<div class="cf-lbl">'+(isCurrent?'<span style="color:#e74c3c;font-


weight:800">'+m+'*</span>':m)+'</div>'+

'<div class="cf-amt">'+plan+'M</div>'+

'</div>';

}).join("");

[Link] =

'<div style="display:flex;align-items:center;gap:12px;margin-
bottom:8px;flex-wrap:wrap">'+

'<div style="display:flex;align-items:center;gap:4px"><div
style="width:12px;height:9px;background:#d6eaf8;border-radius:2px"></
div><span
style="font-size:9px;color:#555;font-weight:600">Planned</span></div>'+

'<div style="display:flex;align-items:center;gap:4px"><div
style="width:12px;height:9px;background:#27ae60;border-radius:2px"></
div><span style="font-size:9px;color:#555;font-weight:600">Actual
(on/under)</span></div>'+

'<div style="display:flex;align-items:center;gap:4px"><div
style="width:12px;height:9px;background:#e74c3c;border-radius:2px"></
div><span style="font-size:9px;color:#555;font-weight:600">Actual
(over)</span></div>'+

'<div style="display:flex;align-items:center;gap:4px"><div
style="width:12px;height:9px;background:#fdebd0;border-radius:2px"></
div><span
style="font-size:9px;color:#555;font-weight:600">Forecast</span></div>'+

'<span style="font-size:9px;color:#e74c3c;font-weight:700;margin-
left:auto">* Current Month (May 2026)</span>'+

'</div>'+

'<div class="cf-chart-wrap">'+barsHtml2+'</div>'+

'<div style="font-size:8px;color:#888;margin-top:6px;border-top:1px
solid #e8f0e8;padding-top:4px">'+

'Total Budget: ETB '+([Link]/1e9).toFixed(2)+'B &nbsp;|&nbsp; '+


'YTD Planned: ETB '+[Link](0,5).reduce(function(a,b){return
a+b;},0)+'M &nbsp;|&nbsp; '+

'YTD Actual: ETB '+[Link](function(v){return v!


==null;}).reduce(function(a,b){return a+b;},0)+'M'+

'</div>';

// ── Breakdown chart ──

var pvBc = [Link]("pv-breakdown-chart");

if (pvBc) {

var bH2=22; var cW2=520; var lW2=150;

var maxB2=[Link];

var bW2=[Link](([Link]/maxB2)*(cW2-lW2-60));

var sW2=[Link](([Link]/maxB2)*(cW2-lW2-60));

[Link] =

'<div style="display:flex;align-items:center;gap:12px;margin-
bottom:6px;margin-left:'+(lW2+5)+'px">'+

'<div style="display:flex;align-items:center;gap:4px"><div
style="width:14px;height:10px;background:'+[Link]+'22;border:1.5px solid
'+[Link]+';border-radius:2px"></div><span style="font-
size:9px;color:#555">Budget (outline)</span></div>'+

'<div style="display:flex;align-items:center;gap:4px"><div
style="width:14px;height:10px;background:'+[Link]+';border-
radius:2px"></div><span style="font-size:9px;color:#555">Spent
(filled)</span></div>'+

'</div>'+

'<div style="display:flex;align-items:center;gap:5px;margin-
bottom:5px">'+

'<div style="width:'+lW2+'px;font-size:9px;color:#333;font-
weight:600;text-align:right;flex-shrink:0;overflow:hidden;text-
overflow:ellipsis;white-space:nowrap" title="'+[Link]+'">'+
([Link]>22?[Link](0,21)+"…":[Link])+'</div>'+

'<div style="position:relative;flex:1;min-width:0">'+

'<div style="height:'+bH2+'px;background:#e8f0e8;border-
radius:3px;overflow:hidden;position:relative">'+

'<div
style="height:100%;width:'+bW2+'px;background:'+[Link]+'22;border:1.5p
x solid
'+[Link]+';border-radius:3px;position:absolute;left:0;top:0"></div>'+

'<div
style="height:100%;width:'+sW2+'px;background:'+[Link]+';border-
radius:3px;position:absolute;left:0;top:0;display:flex;align-
items:center;padding-left:5px">'+

'<span style="font-size:9px;color:#fff;font-weight:700">ETB '+


([Link]/1e6).toFixed(0)+'M</span>'+

'</div>'+

'</div>'+

'</div>'+

'<div style="font-size:9px;color:#555;width:70px;flex-shrink:0;text-
align:right">Budget: ETB '+([Link]/1e6).toFixed(0)+'M</div>'+

'</div>';

// ── Breakdown table header update ──

var pvBH = [Link]("pv-breakdown-header");

if (pvBH) [Link] = "📋 " + [Link] + " — COST BREAKDOWN";

// ── Breakdown table ──

var pvTbody = [Link]("pv-cost-tbody");

if (pvTbody) {
var v2=[Link]([Link]/[Link]*100);

var var2=[Link];

var cpi2=([Link]/[Link]).toFixed(2);

var eacFmt = fmt([Link]);

[Link] = '<tr>'+

'<td>'+([Link]>30?[Link](0,29)+"…":[Link])+'</td>'+

'<td>Civil Works</td>'+

'<td>ETB '+([Link]/1e6).toFixed(0)+'M</td>'+

'<td>ETB '+([Link]/1e6).toFixed(0)+'M</td>'+

'<td>ETB '+(forecast/1e6).toFixed(0)+'M</td>'+

'<td style="color:'+(var2>0?"#1e8449":"#c0392b")+';font-
weight:700">'+(var2>0?"+":"-")+'ETB
'+[Link](var2/1e6).toFixed(0)+'M</td>'+

'<td><div class="pbar"><div class="pbar-f"


style="width:'+v2+'%;background:'+
(v2>90?"#e74c3c":v2>75?"#f39c12":"#27ae60")+'"></div></
div>'+v2+'%</td>'+

'<td style="color:'+(parseFloat(cpi2)>=1?"#1e8449":"#c0392b")+';font-
weight:700">'+cpi2+'</td>'+

'<td>'+eacFmt+'</td>'+

'<td><span class="bdg '+([Link]==="On Track"?"g":"o")


+'">'+[Link]+'</span></td>'+

'</tr>';

//
═══════════════════════════════════════════════════════
════════
function _renderCostVarianceAnalysis(projects) {

var el = [Link]("cost-variance-analysis");

if (!el) return;

var isSingle = [Link] === 1;

if (isSingle) {

// Single-project: show activity-level variance

var p = projects[0];

var activities = [

{name:"Civil Works", budgetFrac:0.38, spentFrac:0.95},

{name:"Track Laying", budgetFrac:0.22, spentFrac:0.83},

{name:"Structures", budgetFrac:0.14, spentFrac:0.78},

{name:"Electrical & Systems", budgetFrac:0.11, spentFrac:0.72},

{name:"Procurement", budgetFrac:0.08, spentFrac:0.91},

{name:"Testing & Comm.", budgetFrac:0.04, spentFrac:0.50},

{name:"Management & HSE", budgetFrac:0.03, spentFrac:0.74},

];

var summary = {ok:0, warn:0, over:0};

var rows = [Link](function(act){

var actBudget = [Link]([Link] * [Link]);

var actSpent = [Link]([Link] * [Link] / ([Link]/[Link])


* [Link]);

var pct = [Link](actSpent/actBudget*100);

var variance = actBudget - actSpent;

var varPct = [Link](variance/actBudget*100);

var status, statusClass, color;


if (pct <= 80) { status = "✅ Within Budget"; statusClass = "ok"; color =
"#27ae60"; [Link]++; }

else if (pct <= 95) { status = "⚠ Warning"; statusClass = "warn"; color =
"#d35400"; [Link]++; }

else { status = "🔴 Over Budget"; statusClass = "over"; color =


"#e74c3c"; [Link]++; }

var barW = [Link](pct, 100);

var barColor = pct>95?"#e74c3c":pct>80?"#f39c12":"#27ae60";

return '<div class="cv-row">'+

'<div class="cv-dot" style="background:'+[Link]+'"></div>'+

'<div class="cv-name" title="'+[Link]+'">'+[Link]+'</div>'+

'<div class="cv-bar-track"><div class="cv-bar-fill"


style="width:'+barW+'%;background:'+barColor+';height:8px;border-
radius:3px"></div></div>'+

'<div class="cv-variance" style="color:'+color+';font-size:9px">'+


(variance>=0?"+":"")+'ETB '+([Link](variance)/1e6).toFixed(0)+'M
('+varPct+'%)</div>'+

'<span class="cv-status-badge '+statusClass+'">'+status+'</span>'+

'</div>';

});

var summaryHtml = '<div style="font-size:9px;font-


weight:800;color:#0a3d1f;margin-bottom:8px;letter-spacing:.3px">ACTIVITY-
WISE VARIANCE — '+[Link](0,30)+([Link]>30?"…":"")
+'</div>'+

'<div style="display:flex;gap:8px;margin-bottom:10px;flex-
wrap:wrap">'+

'<div style="flex:1;min-width:80px;background:#d4efdf;border:1px solid


#a9dfbf;border-radius:4px;padding:6px 8px;text-align:center">'+

'<div style="font-size:18px;font-
weight:800;color:#1e8449">'+[Link]+'</div>'+
'<div style="font-size:8px;font-weight:700;color:#1e8449">WITHIN
BUDGET</div></div>'+

'<div style="flex:1;min-width:80px;background:#fdebd0;border:1px solid


#f9c784;border-radius:4px;padding:6px 8px;text-align:center">'+

'<div style="font-size:18px;font-
weight:800;color:#d35400">'+[Link]+'</div>'+

'<div style="font-size:8px;font-
weight:700;color:#d35400">WARNING</div></div>'+

'<div style="flex:1;min-width:80px;background:#fadbd8;border:1px solid


#f1948a;border-radius:4px;padding:6px 8px;text-align:center">'+

'<div style="font-size:18px;font-
weight:800;color:#c0392b">'+[Link]+'</div>'+

'<div style="font-size:8px;font-weight:700;color:#c0392b">OVER
BUDGET</div></div>'+

'</div>';

[Link] = summaryHtml + [Link]("");

return;

// Portfolio view: show per-project variance (original logic)

var summary2 = {ok:0, warn:0, over:0};

var rows2 = [Link](function(p){

var pct = [Link]([Link]/[Link]*100);

var variance = [Link] - [Link];

var varPct = [Link](variance/[Link]*100);

var status, statusClass, color;

if (pct <= 80) { status = "✅ Within Budget"; statusClass = "ok"; color =
"#27ae60"; [Link]++; }

else if (pct <= 95) { status = "⚠ Warning"; statusClass = "warn"; color =
"#d35400"; [Link]++; }
else { status = "🔴 Over Budget"; statusClass = "over"; color = "#e74c3c";
[Link]++; }

var sname = [Link]>32?[Link](0,30)+"..":[Link];

var barW = [Link](pct, 100);

var barColor = pct>95?"#e74c3c":pct>80?"#f39c12":"#27ae60";

return '<div class="cv-row">'+

'<div class="cv-dot" style="background:'+[Link]+'"></div>'+

'<div class="cv-name" title="'+[Link]+'">'+sname+'</div>'+

'<div class="cv-bar-track"><div class="cv-bar-fill"


style="width:'+barW+'%;background:'+barColor+';height:8px;border-
radius:3px"></div></div>'+

'<div class="cv-variance" style="color:'+color+';font-size:9px">'+


(variance>=0?"+":"")+'ETB '+([Link](variance)/1e6).toFixed(0)+'M
('+varPct+'%)</div>'+

'<span class="cv-status-badge '+statusClass+'">'+status+'</span>'+

'</div>';

}).join("");

var summaryHtml2 = '<div style="display:flex;gap:8px;margin-


bottom:10px;flex-wrap:wrap">'+

'<div style="flex:1;min-width:80px;background:#d4efdf;border:1px solid


#a9dfbf;border-radius:4px;padding:6px 8px;text-align:center">'+

'<div style="font-size:18px;font-
weight:800;color:#1e8449">'+[Link]+'</div>'+

'<div style="font-size:8px;font-weight:700;color:#1e8449">WITHIN
BUDGET</div></div>'+

'<div style="flex:1;min-width:80px;background:#fdebd0;border:1px solid


#f9c784;border-radius:4px;padding:6px 8px;text-align:center">'+
'<div style="font-size:18px;font-
weight:800;color:#d35400">'+[Link]+'</div>'+

'<div style="font-size:8px;font-
weight:700;color:#d35400">WARNING</div></div>'+

'<div style="flex:1;min-width:80px;background:#fadbd8;border:1px solid


#f1948a;border-radius:4px;padding:6px 8px;text-align:center">'+

'<div style="font-size:18px;font-
weight:800;color:#c0392b">'+[Link]+'</div>'+

'<div style="font-size:8px;font-weight:700;color:#c0392b">OVER
BUDGET</div></div>'+

'</div>';

[Link] = summaryHtml2 + rows2;

// ── Render Cash Flow Forecast ────────────────────────────────────

function _renderCashFlowForecast(projects) {

var el = [Link]("cash-flow-forecast");

if (!el) return;

var isSingle = [Link] === 1;

var months =
["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];

// Use the total budget of the filtered project(s)

var totBudget = [Link](function(s,p){return s+[Link];},0);

// Distribute budget across months using a bell-curve-like distribution

var monthlyPlan = [Link](function(m,i){


var factor;

if (i<2) factor=0.055; else if (i<4) factor=0.075; else if (i<6) factor=0.095;

else if (i<8) factor=0.095; else if (i<10) factor=0.075; else factor=0.055;

return [Link](totBudget * factor / 1e6); // in millions

});

var monthlyActual = [Link](function(m,i){

if (i>4) return null;

var factor;

if (i<2) factor=0.050; else if (i<4) factor=0.080; else if (i<5) factor=0.085;

else factor=null;

return factor ? [Link](totBudget * factor / 1e6) : null;

});

var maxVal = [Link](null,


[Link]([Link](function(v){return v!==null;})));

var chartH = 80;

var barsHtml = [Link](function(m, i){

var plan = monthlyPlan[i];

var actual = monthlyActual[i];

var planH = [Link]((plan/maxVal)*chartH);

var actH = actual !== null ? [Link]((actual/maxVal)*chartH) : 0;

var isPast = i <= 4;

var isCurrent = i === 4;

var borderStyle = isCurrent ? "border:1.5px solid #e74c3c;border-


radius:4px;padding:2px;background:#fff8f8;" : "";
return '<div class="cf-month" style="'+borderStyle+'">'+

'<div style="display:flex;align-items:flex-
end;gap:2px;height:'+chartH+'px">'+

'<div style="width:12px;background:#d6eaf8;border-radius:3px 3px 0


0;height:'+planH+'px;position:relative" title="Planned: ETB '+plan+'M">'+

'</div>'+

(isPast?'<div style="width:12px;background:'+
(actual>plan?'#e74c3c':'#27ae60')+';border-radius:3px 3px 0
0;height:'+actH+'px" title="Actual: ETB '+actual+'M"></div>':

'<div style="width:12px;background:#fdebd0;border-radius:3px
3px 0 0;height:'+[Link](planH*0.9)+'px;opacity:.7" title="Forecast: ETB
'+([Link](plan*0.9))+'M"></div>')+

'</div>'+

'<div class="cf-lbl">'+(isCurrent?'<span style="color:#e74c3c;font-


weight:800">'+m+'*</span>':m)+'</div>'+

'<div class="cf-amt">'+plan+'M</div>'+

'</div>';

}).join("");

var projLabel = isSingle ? (' — ' + projects[0].[Link](0,35) +


(projects[0].[Link]>35?"…":"")) : '';

[Link] =

'<div style="display:flex;align-items:center;gap:12px;margin-
bottom:8px;flex-wrap:wrap">'+

'<div style="display:flex;align-items:center;gap:4px"><div
style="width:12px;height:9px;background:#d6eaf8;border-radius:2px"></
div><span
style="font-size:9px;color:#555;font-weight:600">Planned</span></div>'+

'<div style="display:flex;align-items:center;gap:4px"><div
style="width:12px;height:9px;background:#27ae60;border-radius:2px"></
div><span style="font-size:9px;color:#555;font-weight:600">Actual
(on/under)</span></div>'+
'<div style="display:flex;align-items:center;gap:4px"><div
style="width:12px;height:9px;background:#e74c3c;border-radius:2px"></
div><span style="font-size:9px;color:#555;font-weight:600">Actual
(over)</span></div>'+

'<div style="display:flex;align-items:center;gap:4px"><div
style="width:12px;height:9px;background:#fdebd0;border-radius:2px"></
div><span
style="font-size:9px;color:#555;font-weight:600">Forecast</span></div>'+

'<span style="font-size:9px;color:#e74c3c;font-weight:700;margin-
left:auto">* Current Month (May 2026)</span>'+

'</div>'+

'<div class="cf-chart-wrap">'+barsHtml+'</div>'+

'<div style="font-size:8px;color:#888;margin-top:6px;border-top:1px solid


#e8f0e8;padding-top:4px">'+

(isSingle ? '<b style="color:#0a3d1f">Project:</b>


'+projects[0].name+' &nbsp;|&nbsp; ' : '')+

'Total Budget: ETB '+(totBudget/1e9).toFixed(2)+'B &nbsp;|&nbsp; '+

'YTD Planned: ETB '+([Link](0,5).reduce(function(a,b){return


a+b;},0))+'M &nbsp;|&nbsp; '+

'YTD Actual: ETB '+([Link](function(v){return v!


==null;}).reduce(function(a,b){return a+b;},0))+'M'+

'</div>';

// ── Render Budget vs Actual ────────────────────────

function _renderBudgetCommitmentActual(projects) {

var el = [Link]("budget-commitment-actual");

if (!el) return;

var isSingle = [Link] === 1;


var legend = '<div style="display:flex;gap:10px;margin-bottom:10px;flex-
wrap:wrap">'+

'<div style="display:flex;align-items:center;gap:4px"><div
style="width:12px;height:9px;background:#27ae6022;border:1px solid
#27ae60;border-radius:2px"></div><span style="font-size:9px;font-
weight:700;color:#0a3d1f">Approved Budget</span></div>'+

'<div style="display:flex;align-items:center;gap:4px"><div
style="width:12px;height:9px;background:#8e44ad;border-radius:2px"></
div><span style="font-size:9px;font-weight:700;color:#8e44ad">Committed
Cost</span></div>'+

'<div style="display:flex;align-items:center;gap:4px"><div
style="width:12px;height:9px;background:#2980b9;border-radius:2px"></
div><span style="font-size:9px;font-weight:700;color:#2980b9">Actual
Expenditure</span></div>'+

'</div>';

if (isSingle) {

var p = projects[0];

var activities = [

{name:"Civil Works", budgetFrac:0.38, commitFrac:0.92,


spentFrac:0.88},

{name:"Track Laying", budgetFrac:0.22, commitFrac:0.85,


spentFrac:0.76},

{name:"Structures", budgetFrac:0.14, commitFrac:0.80,


spentFrac:0.72},

{name:"Electrical & Systems", budgetFrac:0.11, commitFrac:0.75,


spentFrac:0.65},

{name:"Procurement", budgetFrac:0.08, commitFrac:0.95,


spentFrac:0.91},

{name:"Testing & Comm.", budgetFrac:0.04, commitFrac:0.55,


spentFrac:0.45},
{name:"Management & HSE", budgetFrac:0.03, commitFrac:0.82,
spentFrac:0.76},

];

var maxBudget = [Link]; // largest segment is whole budget

var rows = [Link](function(act){

var actBudget = [Link]([Link] * [Link]);

var actCommit = [Link](actBudget * [Link]);

var actActual = [Link]([Link] * [Link] * [Link] /


([Link]/[Link]));

var budgetW = [Link]((actBudget/maxBudget)*100);

var commitW = [Link]((actCommit/maxBudget)*100);

var actualW = [Link]((actActual/maxBudget)*100);

var commitPct = [Link](actCommit/actBudget*100);

var actualPct = [Link](actActual/actBudget*100);

var sname = [Link]>22?


[Link](0,20)+"..":[Link];

return '<div class="bca-row">'+

'<div class="bca-name" title="'+[Link]+'">'+sname+'</div>'+

'<div class="bca-bars">'+

'<div class="bca-bar-row"><div class="bca-bar-label"


style="color:#0a3d1f">Budget</div><div class="bca-bar-track"><div
class="bca-bar-fill"
style="width:'+budgetW+'%;background:'+[Link]+'22;border:1px solid
'+[Link]+'"></div></div><div class="bca-pct"
style="color:#0a3d1f">100%</div></div>'+

'<div class="bca-bar-row"><div class="bca-bar-label"


style="color:#8e44ad">Commit</div><div class="bca-bar-track"><div
class="bca-bar-fill"
style="width:'+commitW+'%;background:#8e44ad"></div></div><div
class="bca-pct" style="color:#8e44ad">'+commitPct+'%</div></div>'+
'<div class="bca-bar-row"><div class="bca-bar-label"
style="color:#2980b9">Actual</div><div class="bca-bar-track"><div
class="bca-bar-fill"
style="width:'+actualW+'%;background:#2980b9"></div></div><div
class="bca-pct" style="color:#2980b9">'+actualPct+'%</div></div>'+

'</div>'+

'</div>';

});

[Link] = legend + [Link]("");

return;

// Portfolio: original multi-project logic

var maxBudget2 = [Link](null, [Link](function(p){return


[Link];}));

var rows2 = [Link](function(p){

var budgetW = [Link](([Link] /maxBudget2)*100);

var actualW = [Link](([Link] /maxBudget2)*100);

var actualPct = [Link]([Link]/[Link]*100);

var variance = [Link] - [Link];

var varColor = variance >= 0 ? "#1e8449" : "#c0392b";

var sname = [Link]>28?[Link](0,26)+"..":[Link];

return '<div class="bca-row">'+

'<div class="bca-name" title="'+[Link]+'">'+sname+'</div>'+

'<div class="bca-bars">'+

'<div class="bca-bar-row"><div class="bca-bar-label"


style="color:#0a3d1f">Budget</div><div class="bca-bar-track"><div
class="bca-bar-fill"
style="width:'+budgetW+'%;background:'+[Link]+'22;border:1px solid
'+[Link]+'"></div></div><div class="bca-pct"
style="color:#0a3d1f">100%</div></div>'+

'<div class="bca-bar-row"><div class="bca-bar-label"


style="color:#2980b9">Actual</div><div class="bca-bar-track"><div
class="bca-bar-fill"
style="width:'+actualW+'%;background:#2980b9"></div></div><div
class="bca-pct" style="color:#2980b9">'+actualPct+'%</div></div>'+

'</div>'+

'</div>';

}).join("");

[Link] = legend + rows2;

// ── Update top KPI tiles based on filtered projects ──────────────

function _updateCostKPIs(projects) {

var totBudget = [Link](function(s,p){return s+[Link];},0);

var totSpent = [Link](function(s,p){return s+[Link];},0);

var utilPct = [Link](totSpent/totBudget*100);

// Aggregate CPI

var totEV = [Link](function(s,p){return


s+[Link]([Link]*([Link]/100));},0);

var aggCPI = totSpent>0 ? parseFloat((totEV/totSpent).toFixed(2)) : 1.00;

var eac = aggCPI>0 ? [Link](totBudget/aggCPI) : totBudget;

var totalVariance = totBudget - totSpent;

var eacDiff = totBudget - eac;

var eacDiffPct = [Link]([Link](eacDiff)/totBudget*100);


function fmt(v){return "ETB
"+(v>=1e9?(v/1e9).toFixed(2)+"B":(v/1e6).toFixed(0)+"M");}

var budgetEl = [Link]("cost-kpi-budget");

if(budgetEl) [Link] = fmt(totBudget);

var budgetLbl = [Link]("cost-kpi-budget-lbl");

if(budgetLbl) [Link] = [Link]===1?


projects[0].name+" Budget":"Approved Portfolio Budget";

var budgetBar = [Link]("cost-kpi-budget-bar");

if(budgetBar){ [Link]=utilPct+"%";
[Link]=utilPct>90?"#e74c3c":utilPct>75?"#f39c12":"
#27ae60"; }

var budgetUtil = [Link]("cost-kpi-budget-util");

if(budgetUtil) [Link] = utilPct+"% utilized";

var spentEl = [Link]("cost-kpi-spent");

if(spentEl){ [Link] = fmt(totSpent);


[Link]="#1e8449"; }

var spentLbl = [Link]("cost-kpi-spent-lbl");

if(spentLbl) [Link] = [Link]===1?"This project":"All


active projects";

var spentBar = [Link]("cost-kpi-spent-bar");

if(spentBar) [Link]=utilPct+"%";

var eacEl = [Link]("cost-kpi-eac");

if(eacEl) [Link] = fmt(eac);

var eacLbl = [Link]("cost-kpi-eac-lbl");

if(eacLbl){
[Link] = (eacDiff>=0?"▼ "+eacDiffPct+"% under budget":"▲
"+eacDiffPct+"% over budget");

[Link] = eacDiff>=0?"#27ae60":"#e74c3c";

var varEl = [Link]("cost-kpi-variance");

if(varEl){

[Link] = (totalVariance>=0?"+":"")
+fmt([Link](totalVariance));

[Link] = totalVariance>=0?"#1e8449":"#c0392b";

var cpiLbl = [Link]("cost-kpi-cpi-lbl");

if(cpiLbl){

[Link] = "CPI: "+aggCPI+" "+(aggCPI>=1?"↑ Healthy":"↓ At


Risk");

[Link] = aggCPI>=1?"#27ae60":"#e74c3c";

//
═══════════════════════════════════════════════════════
════════
// AUDIT LOG RENDER

//
═══════════════════════════════════════════════════════
════════
function renderAuditLog() {

const tbody = [Link]("audit-log-tbody");

if(!tbody) return;
const q = ([Link]("audit-search")||{}).value||"";

const modF = ([Link]("audit-filter-module")||


{}).value||"";

const actF = ([Link]("audit-filter-action")||{}).value||"";

let entries = AUDIT_LOG;

if(q) entries = [Link](e =>


([Link]+[Link]+[Link]+[Link]).toLowerCase().includes([Link]
()));

if(modF) entries = [Link](e => [Link] === modF);

if(actF) entries = [Link](e => [Link] === actF);

// Summary strip

const strip = [Link]("audit-summary-strip");

if(strip) {

const loginCount = AUDIT_LOG.filter(e=>[Link]==="Login").length;

const editCount =
AUDIT_LOG.filter(e=>["Add","Edit","Delete"].includes([Link])).length;

const rptCount = AUDIT_LOG.filter(e=>[Link]==="Report


Generated").length;

const settCount = AUDIT_LOG.filter(e=>[Link]==="Settings


Modified").length;

[Link] = [

["🔐 Logins",loginCount,"#2980b9"],

["✏ Data Changes",editCount,"#27ae60"],

["📊 Reports",rptCount,"#8e44ad"],

["⚙ Settings",settCount,"#d35400"],

["📋 Total Events",AUDIT_LOG.length,"#0a3d1f"],

].map(([l,v,c])=>`<div style="background:#f8fdf8;border:1px solid


#c8d8c8;border-radius:4px;padding:6px 12px;display:flex;flex-
direction:column;align-items:center;min-width:80px;border-left:3px solid $
{c}">

<div style="font-size:16px;font-weight:800;color:${c}">${v}</div>

<div style="font-size:8px;color:#555;font-weight:700;white-
space:nowrap">${l}</div>

</div>`).join("");

const actionColors = {

"Login":"#d6eaf8","Logout":"#eaecee","Add":"#d4efdf","Edit":"#fff3cd",

"Delete":"#fadbd8","Report Generated":"#e8daef","Settings
Modified":"#fdebd0"

};

[Link] = [Link] ? [Link]((e,i)=>{

const ac = actionColors[[Link]]||"#f4f9f2";

return `<tr>

<td style="color:#888;font-size:9px">${i+1}</td>

<td style="font-size:9px;white-space:nowrap;color:#555">${[Link]}</td>

<td style="font-weight:600;font-size:9px">${[Link]}</td>

<td><span style="display:inline-block;padding:2px 8px;border-


radius:10px;font-size:8px;font-weight:800;background:${ac};color:#333">$
{[Link]}</span></td>

<td style="font-size:9px;color:#0a3d1f;font-weight:700">$
{[Link]}</td>

<td style="font-size:9px;color:#555">${[Link]}</td>

</tr>`;

}).join("") : `<tr><td colspan="6" style="text-


align:center;color:#bbb;padding:20px;">No audit log entries match the
current filters.</td></tr>`;
const countEl = [Link]("audit-count");

if(countEl) [Link] = `Showing ${[Link]} of $


{AUDIT_LOG.length} log entries`;

function exportAuditLog(){

let csv = "Timestamp,User,Action,Module,Detail\n";

AUDIT_LOG.forEach(e => csv+=`"${[Link]}","${[Link]}","${[Link]}","$


{[Link]}","${[Link]}"\n`);

const
a=[Link]("a");[Link]="data:text/csv,"+encodeURICompon
ent(csv);

[Link]="EDR_Audit_Log_"+new Date().toISOString().split("T")
[0]+".csv";[Link]();

toast("✅ Audit log exported!");

//
═══════════════════════════════════════════════════════
════════
// TOAST

function toast(msg) {

const wrap=[Link]("toast-wrap");

const el=[Link]("div");

[Link]="toast";

[Link]=msg;

[Link](el);

setTimeout(()=>[Link](),3500);
}

// HEADER DATE

var _hdrDate=[Link]("hdr-date"); if(_hdrDate)


_hdrDate.textContent=new Date().toLocaleDateString("en-GB",
{weekday:"short",day:"numeric",month:"short",year:"numeric"});

/* ── Flush queued login calls now that all functions are defined ── */

window._selectRoleReady = true;

(window._loginQueue||[]).forEach(function(item){

if(item[0]==='selectRole') window._selectRoleImpl(item[1]);

else if(item[0]==='doLogin') window._doLoginImpl();

else if(item[0]==='togglePwVisibility') window._togglePwImpl();

});

window._loginQueue = [];

</script>

</body>

</html>

You might also like