ICO Evaluation Framework
A structured checklist to guide your research and self-assessment of Initial Coin Offerings.
Important: This tool is for educational and self-assessment purposes only. ICOs are highly speculative and risky. The scores generated are based solely on your own inputs and subjective ratings and do not constitute investment advice, an endorsement, or a guarantee. Always conduct comprehensive due diligence (DYOR) from multiple reputable sources and consider consulting with a qualified financial advisor before making any investment decisions.
${item.description}
`; tabPanel.appendChild(criterionDiv); }); } this.elements.tabPanelsContainer.appendChild(tabPanel); }); // Re-cache tabLinks and tabPanels after dynamic rendering this.elements.tabLinks = document.querySelectorAll('.ico-tab-link'); this.elements.tabPanels = document.querySelectorAll('.ico-tab-panel'); }, attachEventListeners: function() { // Tab links are handled by openTab via onclick attribute if (this.elements.prevTabBtn) this.elements.prevTabBtn.addEventListener('click', () => this.navigateTabs('prev')); if (this.elements.nextTabBtn) this.elements.nextTabBtn.addEventListener('click', () => this.navigateTabs('next')); // Event listeners for score/notes changes (delegated) this.elements.tabPanelsContainer.addEventListener('change', (event) => { if (event.target.tagName === 'SELECT' && event.target.id.startsWith('score_')) { const categoryId = event.target.dataset.category; const itemId = event.target.dataset.itemid; this.updateScore(categoryId, itemId, 'score', parseInt(event.target.value)); } }); this.elements.tabPanelsContainer.addEventListener('input', (event) => { if (event.target.tagName === 'TEXTAREA' && event.target.id.startsWith('notes_')) { const categoryId = event.target.dataset.category; const itemId = event.target.dataset.itemid; this.updateScore(categoryId, itemId, 'notes', event.target.value); } }); // Attach to dynamically created buttons in results tab this.elements.tabPanelsContainer.addEventListener('click', (event) => { if (event.target.id === 'icoCalculateScoreBtn') { this.calculateAndDisplayResults(); } else if (event.target.id === 'icoDownloadPdfBtn') { this.generatePDF(); } }); }, openTab: function(event, tabId) { this.elements.tabPanels.forEach(panel => panel.classList.remove('active')); this.elements.tabLinks.forEach(link => link.classList.remove('active')); const selectedTabPanel = document.getElementById(tabId); if (selectedTabPanel) selectedTabPanel.classList.add('active'); this.elements.tabLinks.forEach((link, index) => { if (link.getAttribute('onclick') && link.getAttribute('onclick').includes(tabId)) { link.classList.add('active'); this.currentTabIndex = index; } }); // If event exists and it's a direct click on a tab link (not programmatic) if (event && event.currentTarget && event.currentTarget.classList.contains('ico-tab-link')) { this.elements.tabLinks.forEach(l => l.classList.remove('active')); event.currentTarget.classList.add('active'); this.elements.tabLinks.forEach((link, index) => { if (link === event.currentTarget) this.currentTabIndex = index; }); } this.updateNavigationButtons(); }, updateNavigationButtons: function() { if (!this.elements.prevTabBtn || !this.elements.nextTabBtn) return; this.elements.prevTabBtn.disabled = this.currentTabIndex === 0; this.elements.nextTabBtn.disabled = this.currentTabIndex >= this.elements.tabLinks.length - 1; }, navigateTabs: function(direction) { let newTabIndex = this.currentTabIndex; if (direction === 'next' && this.currentTabIndex < this.elements.tabLinks.length - 1) newTabIndex++; else if (direction === 'prev' && this.currentTabIndex > 0) newTabIndex--; const targetTabLink = Array.from(this.elements.tabLinks)[newTabIndex]; // Convert NodeList to Array to use index if (targetTabLink) targetTabLink.click(); }, updateScore: function(categoryId, itemId, field, value) { if (!this.userScores[categoryId]) this.userScores[categoryId] = {}; if (!this.userScores[categoryId][itemId]) this.userScores[categoryId][itemId] = { score: 0, notes: '' }; this.userScores[categoryId][itemId][field] = value; this.saveScores(); }, saveScores: function() { localStorage.setItem('icoUserScores', JSON.stringify(this.userScores)); }, loadScores: function() { const saved = localStorage.getItem('icoUserScores'); if (saved) { this.userScores = JSON.parse(saved); // Populate UI with loaded scores Object.keys(this.userScores).forEach(categoryId => { Object.keys(this.userScores[categoryId]).forEach(itemId => { const itemData = this.userScores[categoryId][itemId]; const scoreSelect = document.getElementById(`score_${categoryId}_${itemId}`); const notesTextarea = document.getElementById(`notes_${categoryId}_${itemId}`); if (scoreSelect) scoreSelect.value = itemData.score; if (notesTextarea) notesTextarea.value = itemData.notes; }); }); } else { // Initialize userScores based on criteriaData this.userScores = {}; Object.keys(this.criteriaData).forEach(catId => { if (!this.criteriaData[catId].isResultTab) { this.userScores[catId] = {}; this.criteriaData[catId].items.forEach(item => { this.userScores[catId][item.id] = { score: 0, notes: '' }; // Default score 0 }); } }); } }, calculateAndDisplayResults: function() { let totalPossibleScore = 0; let totalUserScore = 0; const categoryScores = {}; let resultsHtml = ''; resultsHtml += `Your Overall Evaluation Score
0 / 0 (0%)
Category Scores & Your Ratings:
| Category | Your Score / Max Score | Rating % |
|---|---|---|
| ${category.title} | ||
| ${item.text} | ${userItemData.score} / ${maxItemScore} | |
| Note: ${userItemData.notes.replace(/\n/g, ' ')} | ||
| ${category.title} Subtotal | ${categoryUserScore} / ${categoryMaxScore} | ${categoryPercent.toFixed(1)}% |
Qualitative Observations Based on Your Ratings:
- `;
const overallPercent = totalPossibleScore > 0 ? (totalUserScore / totalPossibleScore * 100) : 0;
if (overallPercent >= 75) {
resultsHtml += `
- Your overall evaluation (${overallPercent.toFixed(1)}%) suggests you perceive this ICO to have strong potential across multiple areas. `; } else if (overallPercent >= 50) { resultsHtml += `
- Your overall evaluation (${overallPercent.toFixed(1)}%) indicates a generally positive assessment, though some areas may warrant closer attention or show average strength. `; } else if (overallPercent >= 25) { resultsHtml += `
- Your overall evaluation (${overallPercent.toFixed(1)}%) suggests several areas of concern or aspects that you rated as weak. Significant further due diligence is advisable. `; } else { resultsHtml += `
- Your overall evaluation (${overallPercent.toFixed(1)}%) is low, indicating you've identified multiple weaknesses or red flags. Extreme caution is warranted. `; } for (const catId in categoryScores) { const cat = categoryScores[catId]; if (cat.percent < 40 && cat.max > 0) { // e.g. less than 2/5 average resultsHtml += `
- The '${cat.title}' category received a relatively low score (${cat.percent.toFixed(1)}%) in your assessment, highlighting potential risks or areas needing significant improvement. `; } else if (cat.percent >= 80 && cat.max > 0) { // e.g. 4/5 average or better resultsHtml += `
- You rated the '${cat.title}' category highly (${cat.percent.toFixed(1)}%), indicating perceived strength in this area. `; } } resultsHtml += `
- Remember, these observations are based on your subjective ratings. ICOs are inherently high-risk. `; resultsHtml += `
ICO Evaluation Report
`; pdfHtml += `Important Reminder: This report reflects your subjective ratings. ICOs are high-risk. This is not investment advice. DYOR.
`;
// Overall Score
const overallScoreText = document.getElementById('icoOverallScoreDisplay') ? document.getElementById('icoOverallScoreDisplay').textContent : 'N/A';
pdfHtml += `Overall Evaluation Score: ${overallScoreText}
`;
// Category Scores & Criteria with Notes
for (const categoryId in this.criteriaData) {
const category = this.criteriaData[categoryId];
if (category.isResultTab) continue;
pdfHtml += `${category.title}
`; let categoryUserScore = 0; let categoryMaxScore = 0; pdfHtml += `| Criterion | Your Score / Max |
|---|---|
| ${item.text} | ${userItemData.score} / ${maxItemScore} |
Note: ${userItemData.notes.replace(/\n/g, ' ')} | |
| Subtotal for ${category.title} | ${categoryUserScore} / ${categoryMaxScore} (${categoryPercent.toFixed(1)}%) |
