Shareholder Meeting Proxy Statement Analyzer
Proxy Statement Input
Paste the full text of the proxy statement below to begin the analysis.
Analysis Options
Select the sections you would like to analyze. The tool will scan for key data and potential red flags.
Analyze salary, bonuses, stock awards, and perks for NEOs.
Review director independence, attendance, and diversity.
Summarize shareholder-submitted resolutions (e.g., ESG, governance).
Check auditor tenure and breakdown of fees (audit vs. non-audit).
Simulated Analysis Report
Analyzing statement...
Analysis for Acme Corporation
Report Generated: Nov 17, 2025
Director Attendance: Average 98% attendance at all meetings.
Diversity: 30% female representation on the board.
`; reportContent.innerHTML += createSection("Board of Directors", content); } if (document.getElementById('opt-proposals').checked) { const content = `Proposal 4: Shareholder resolution requesting an annual report on political contributions. (Board recommends a vote AGAINST)
Proposal 5: Shareholder resolution to link executive pay to ESG metrics. (Board recommends a vote AGAINST)
`; reportContent.innerHTML += createSection("Shareholder Proposals", content); } if (document.getElementById('opt-auditor').checked) { const content = `Auditor: Deloitte & Touche LLP (Tenure: 12 years)
Audit Fees: $2,100,000 (USD)
Non-Audit Fees: $450,000 (USD) (21.4% of audit fees)
`; reportContent.innerHTML += createSection("Auditor & Fees", content); } if (reportContent.innerHTML === '') { reportContent.innerHTML = `No analysis options were selected. Please go back to Tab 2 to select items for the report.
`; } // Show report loader.style.display = 'none'; reportOutput.style.display = 'block'; }, 1500); // Simulate 1.5 second analysis } /** * Generates and downloads the PDF document (per spec II.C) */ function downloadPDF() { // Ensure jsPDF and autoTable are loaded if (!window.jspdf || !window.jspdf.jsPDF || !window.jspdfAutoTable) { console.error("jsPDF or jsPDF-AutoTable library not found."); // Show a user-friendly error (no alerts) reportContent.innerHTML += `PDF generation failed. Please try again.
`; return; } const { jsPDF } = window.jspdf; const doc = new jsPDF(); const pageMargin = 15; const pageW = doc.internal.pageSize.getWidth(); let cursorY = pageMargin; // --- PDF Content (per spec II.C.2) --- // Helper to add text and manage cursor const addText = (text, options = {}) => { const { size = 10, style = 'normal', align = 'left', space = 5, color = [0, 0, 0] } = options; doc.setFontSize(size); doc.setFont('helvetica', style); doc.setTextColor(color[0], color[1], color[2]); const textLines = doc.splitTextToSize(text, pageW - (pageMargin * 2)); doc.text(textLines, pageMargin, cursorY, { align: align }); cursorY += (textLines.length * (size * 0.4)) + space; // Move cursor down }; // Title addText('Proxy Statement Analysis Report', { size: 18, style: 'bold', align: 'center', space: 8 }); // Subtitle addText(generatedReportData.company, { size: 14, style: 'normal', align: 'center', space: 5, color: [100, 100, 100] }); addText(`Generated: ${generatedReportData.date}`, { size: 10, style: 'italic', align: 'center', space: 12 }); // Loop through generated sections generatedReportData.sections.forEach(section => { // Check for page break if (cursorY > 250) { doc.addPage(); cursorY = pageMargin; } // Section Title doc.setDrawColor(220, 220, 220); // Light gray doc.setFillColor(245, 245, 245); // Very light gray doc.rect(pageMargin, cursorY - 3, pageW - (pageMargin * 2), 10, 'FD'); addText(section.title, { size: 12, style: 'bold', color: [0, 51, 102], space: 8 }); cursorY += 2; // Add padding after title box // Section Content // Clean HTML tags for PDF const cleanContent = section.content.replace(//g, '• ').replace(/<\/strong>/g, '')
.replace(/<\/p>/g, '\n')
.replace(/ /g, ' [!] ') // Red Flag
.replace(/ /g, '• ')
.replace(/<[^>]+>/g, ''); // Remove all other tags
addText(cleanContent, { size: 10, space: 10 });
});
// --- PDF Download ---
doc.save(`${generatedReportData.company.replace(' ', '_')}_Proxy_Analysis.pdf`);
}
// --- Event Listeners (per spec IV.C) ---
// Navigation button clicks
prevBtn.addEventListener('click', () => {
if (currentTab > 0) {
showTab(currentTab - 1);
}
});
nextBtn.addEventListener('click', () => {
// Check for input on first tab
if (currentTab === 0) {
if (proxyTextInput.value.trim() === '') {
// No alerts, show inline message
proxyTextInput.classList.add('border-red-500');
proxyTextInput.placeholder = 'Please paste the proxy statement text to continue.';
return; // Stop navigation
}
proxyTextInput.classList.remove('border-red-500');
}
if (currentTab < maxTabs) {
showTab(currentTab + 1);
}
});
// Tab button clicks
tabButtons.forEach((button, index) => {
button.addEventListener('click', () => {
// Don't allow clicking to a tab if text isn't entered
if (index > 0 && proxyTextInput.value.trim() === '') {
showTab(0); // Send back to tab 0
proxyTextInput.classList.add('border-red-500');
proxyTextInput.placeholder = 'Please paste the proxy statement text to continue.';
} else {
showTab(index);
}
});
});
// PDF download button click
downloadPdfBtn.addEventListener('click', downloadPDF);
// --- Initialization ---
showTab(0); // Show the first tab by default
});
