1upmedia.com
Latest snapshot
2025-08-15 15:46:42 · 200
HTML text
Reclassify Content as Capital | URL Ledger™ Audit in 60s Skip to content Welcome to 1UP Media 500 King St W, Toronto contact@1upmedia.com (647) 998-5187 Linkedin X-twitter Facebook-f Youtube Home
About
Solutions
Case Studies
Blog
Contact × Search Book Demo Home
About
Solutions
Case Studies
Blog
Contact Home
About
Solutions
Case Studies
Blog
Contact × Search Request for Call Back Home
About
Solutions
Case Studies
Blog
Contact × Search Book Demo Inspired by Moody’s. Powered Like Bloomberg. Managed Like QuickBooks. Revenue Recovery We upgrade your website to a performance-grade balance sheet. Our Cluster Ledger™ issues Content Credit Scores and Yield Curves for each URL. Run the 60s Content Portfolio Screener Every URL you’ve ever published has hidden alpha. Are you capturing it? 70¢ of every content dollar vanishes within 90 days. Your dashboards may flash green, but your balance sheet is quietly hemorrhaging equity you’ve already paid for. Prime URLs suffer asset dilution from look-alike pages that siphon authority. Flagship assets sit half-priced. Stuck far below their intrinsic value. Domain strength stagnates while competitors compound content capital each quarter. Google’s surface metrics act like fresh paint on a rusted hull, masking the mark-to-market losses beneath. Map the 4-Step Recovery The URL Ledger underwrites every page like a bond, assigns a Content Credit Score, and plots an Alpha-Yield Curve—so you can buy, hold, or divest before depreciation compounds into permanent write-offs. Here’s the execution path: 1. Quick ScanFrom decay velocity to liquidity half-life, latent losses surface in 60 seconds. 2. Guided DemoFrom funnel asymmetry to psychographic drift, we price the delta on 100 flagship URLs. 3. Full AuditFrom blended cost of capital to alpha-yield curves, every asset is mark-to-model. 4. Live AUMFrom variance alerts to auto-rebalancing, earnings compound while you sleep. Meet the 60s Content Portfolio Screener Run a quick scan of your content assets to reveal aging, at-risk, or idle URLs—before they start compounding loss. Content Decay Calculator Domain Total Investment ($) Days Window 90 days Find Decay Content Freshness Summary Content Age Distribution 🔬 Decay Model Analysis 🎯 Domain-Specific Risk Factors 💡 Content Maintenance Insights 📈 Summary Statistics 💡 Analysis Summary 📥 Download Audit 📅 Schedule a Call Unlock Full Report Enter your email to view complete analysis & insights Unlock Total URLs ${cache.fresh.total} Total content pieces analyzed 💰 Current Value $${valueNow.toFixed(0)} Content value after decay 📉 Decay % ${decayPct}% Percentage value lost ⚠️ Loss ($) $${loss.toFixed(0)} Estimated financial impact `; /* freshness bars (rebuild every time for new data) */ renderFreshnessData(); /* decay model cards (scaled) */ // Calculate the actual money values for each model (to match React implementation) const baselineValue = cache.investment * (1 - cache.modelBases.baseline * scale); const cannibalValue = cache.investment * (1 - cache.modelBases.cannibal * scale); const mismatchValue = cache.investment * (1 - cache.modelBases.mismatch * scale); const plateauValue = cache.investment * (1 - cache.modelBases.plateau * scale); const modelData = [ ['Baseline Model', 'Normal ranking decay', cache.modelBases.baseline * scale, baselineValue], ['Cannibalization', 'Content competition', cache.modelBases.cannibal * scale, cannibalValue], ['DA vs KD Mismatch', 'Authority challenges', cache.modelBases.mismatch * scale, mismatchValue], ['Content Plateau', 'Relevance steps', cache.modelBases.plateau * scale, plateauValue] ]; const cards = modelData.map(r => { // Cap the maximum displayed percentage at 50% for visual clarity const scaledImpact = Math.min(r[2], 0.5); const isHighImpact = (scaledImpact * 100) > 10; const impactClass = isHighImpact ? 'high-impact' : ''; const costValue = (cache.investment * scaledImpact).toFixed(0); const impactValue = (scaledImpact * 100).toFixed(1); const remainingValue = r[3].toFixed(0); return ` ${r[0]} ${r[1]} ${impactValue}% Value: $${remainingValue} Loss: $${(cache.investment - r[3]).toFixed(0)} `; }).join(''); decayTable.innerHTML = ` ${cards} `; blurbEl.textContent = `Window: ${days} days • four decay models + domain factors • overall risk ${cache.overallRisk}×.`; } /* static tables (only once) */ function renderRiskTable() { const riskFactors = [ { factor: 'Domain Age', value: '1.00', description: 'Neutral', critical: false }, { factor: 'Content Density', value: cache.density.toFixed(2), description: 'Thin content risk', critical: cache.density > 1.2 }, { factor: 'Business Model', value: '1.10', description: 'Lead-gen site', critical: false }, { factor: 'Site Scale', value: cache.siteScale.toFixed(2), description: 'Size adjustment', critical: cache.siteScale > 1.1 }, { factor: 'Competition Level', value: '1.00', description: 'Standard competition', critical: false }, { factor: 'Overall Risk', value: cache.overallRisk, description: 'Combined', critical: true } ]; const riskCards = riskFactors.map(factor => { const cardClass = factor.critical ? 'critical' : ''; return ` ${factor.factor} ${factor.description} ${factor.value} `; }).join(''); riskTable.innerHTML = ` ${riskCards} `; } /* Generate content insights similar to DecayCalculator.js */ function renderBaseInsights() { // Calculate decay percentage based on cached data const days = parseInt(dayRange.value, 10); const scale = days / 18; const loss = cache.baseLoss * scale; const decayPercent = ((loss / cache.investment) * 100); // Generate insights using the new function const insights = generateContentInsights( decayPercent, cache.fresh, cache.avgAge, cache.domain ); // Create markup for insights const insightsMarkup = insights.map(insight => { return ` ${insight.icon} ${insight.title} ${insight.description} `; }).join(''); insightsEl.innerHTML = ` ${insightsMarkup} `; } function generateContentInsights(decayPercent, fresh, avgAgeDays, domain) { const insights = []; // Calculate percentages for key age buckets const totalContent = fresh.total; const last7Percent = (fresh.last7 / totalContent * 100).toFixed(1); const over730Percent = ((fresh.over730 + fresh.never) / totalContent * 100).toFixed(1); const contentWithDates = totalContent - fresh.never; const contentWithoutDates = fresh.never; const withoutDatesPercent = (contentWithoutDates / totalContent * 100).toFixed(1); // Freshness insights if (avgAgeDays > 365) { insights.push({ type: "warning", icon: "⚠️", title: "Content Aging Issue", description: `Your average content age is ${Math.round(avgAgeDays)} days (over a year), which is contributing to increased decay.` }); } if (last7Percent < 5) { insights.push({ type: "warning", icon: "⚠️", title: "Low Content Freshness", description: "Less than 5% of your content has been updated in the last week. Regular content updates help maintain visibility." }); } if (over730Percent > 40) { insights.push({ type: "critical", icon: "🔥", title: "Severe Content Aging", description: "Over 40% of your content is older than 2 years and likely experiencing significant decay." }); } // Decay insights if (decayPercent > 60) { insights.push({ type: "critical", icon: "📉", title: "Critical Decay Level", description: `Your content is experiencing ${decayPercent.toFixed(0)}% decay, which represents significant lost value.` }); } else if (decayPercent > 40) { insights.push({ type: "warning", icon: "📉", title: "Moderate Decay Level", description: `At ${decayPercent.toFixed(0)}% decay, your content value is diminishing and should be addressed.` }); } // Strategy recommendations if (contentWithoutDates > contentWithDates * 0.3) { insights.push({ type: "recommendation", icon: "💡", title: "Add Last-Modified Headers", description: `${withoutDatesPercent}% of your pages lack last-modified dates. Adding these helps search engines understand content freshness.` }); } if (decayPercent > 30) { const priority = decayPercent > 50 ? "urgently" : "soon"; insights.push({ type: "recommendation", icon: "�", title: "Content Refresh Strategy", description: `Your site ${priority} needs a content refresh strategy focused on high-value pages showing decay.` }); } // Success insight (if any) if (decayPercent < 30) { if (avgAgeDays < 180) { insights.push({ type: "success", icon: "✅", title: "Good Content Health", description: "Your content freshness and decay levels are within healthy ranges. Continue your current update strategy." }); } } // Always include the default insight about refreshing old content if (!insights.some(insight => insight.title.includes("Content Refresh"))) { insights.push({ type: "recommendation", icon: "🔄", title: "Regular Content Updates", description: `Refresh the ${fresh.over365} oldest pages first, then iterate quarterly for best results.` }); } return insights; } function renderStats() { const statsData = [ { metric: 'Domain', value: cache.domain, description: 'Website being analyzed', highlight: false, prefix: '', suffix: '' }, { metric: 'Total URLs', value: cache.urlsLen, description: 'Pages in sitemap', highlight: true, prefix: '', suffix: '' }, { metric: 'Unique Content Pages', value: cache.uniqueCount, description: 'Unique pathnames', highlight: false, prefix: '', suffix: '' }, { metric: 'Average Content Age', value: cache.avgAge.toFixed(0), description: 'Average days since last update', highlight: true, prefix: '', suffix: ' days' }, { metric: 'Cost per URL', value: cache.costPerURL?.toFixed(2) ?? (cache.investment / cache.urlsLen).toFixed(2), description: 'Estimated content cost per page', highlight: false, prefix: '$', suffix: '' }, { metric: 'Content Freshness Score', value: Math.max(0, 100 - (cache.fresh.over365 / cache.fresh.total * 100)).toFixed(1), description: 'Based on age distribution', highlight: true, prefix: '', suffix: '%' } ]; const statCards = statsData.map(stat => { const cardClass = stat.highlight ? 'high-impact' : ''; return ` ${stat.metric} ${stat.prefix}${stat.value}${stat.suffix} ${stat.description} `; }).join(''); statsTable.innerHTML = ` ${statCards} `; } /* Action buttons */ const downloadAuditBtn = document.getElementById('download-audit'); downloadAuditBtn.addEventListener('click', async function (e) { e.preventDefault(); if (cache) { // Show loading state const originalText = this.innerHTML; this.innerHTML = '⏳ Generating PDF...'; this.disabled = true; try { // Check if jsPDF is loaded, if not, load it dynamically if (typeof jspdf === 'undefined') { await loadScript('https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js'); await loadScript('https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.5.25/jspdf.plugin.autotable.min.js'); } // Generate the PDF once scripts are loaded await generatePDF(); } catch (error) { console.error('PDF generation failed:', error); alert('Could not generate PDF. Downloading text version instead.'); downloadTextVersion(); } finally { // Restore button state this.innerHTML = originalText; this.disabled = false; } } else { alert('Please run the decay analysis first'); } // Helper function to load scripts dynamically async function loadScript(url) { return new Promise((resolve, reject) => { const script = document.createElement('script'); script.src = url; script.onload = resolve; script.onerror = reject; document.head.appendChild(script); }); } // Generate and download PDF with styling that matches UI async function generatePDF() { const { jsPDF } = window.jspdf; const domain = cache.domain; const date = new Date().toLocaleDateString(); const days = parseInt(dayRange.value, 10); const decayPct = cache.modelBases.weightedDecay * (days / 180) * 100; // Calculate values needed for the report const currentValue = cache.investment * (1 - (cache.modelBases.weightedDecay * days / 180)); const financialImpact = cache.investment * cache.modelBases.weightedDecay * days / 180; const freshnessPct = Math.max(0, 100 - (cache.fresh.over365 / cache.fresh.total * 100)).toFixed(1); // Create a new PDF document const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4', }); // Add custom fonts - using system fonts that should be available doc.setFont('helvetica', 'bold'); // Colors to match UI const primaryColor = [0, 0, 0]; // Black const secondaryColor = [26, 43, 72]; // #1a2b48 const tertiaryColor = [51, 65, 85]; // #334155 const accentColor = [59, 130, 246]; // #3b82f6 // Header with logo doc.setFillColor(0, 0, 0); doc.rect(0, 0, 210, 40, 'F'); doc.setTextColor(255, 255, 255); doc.setFontSize(24); doc.text('1UP', 20, 20); doc.setFontSize(16); doc.text('CONTENT DECAY AUDIT', 20, 30); // Domain & Date info doc.setTextColor(...secondaryColor); doc.setFontSize(14); doc.text(`Domain: ${domain}`, 20, 50); doc.setFontSize(12); doc.text(`Date: ${date}`, 20, 58); doc.text(`Analysis Period: ${days} days`, 20, 65); // Horizontal line doc.setDrawColor(...accentColor); doc.setLineWidth(0.5); doc.line(20, 70, 190, 70); // Summary statistics section doc.setFontSize(16); doc.setTextColor(...secondaryColor); doc.text('Summary Statistics', 20, 80); // Create summary data table const summaryData = [ ['Total URLs', cache.urlsLen.toString()], ['Unique Content Pages', cache.uniqueCount.toString()], ['Average Content Age', `${cache.avgAge.toFixed(0)} days`], ['Original Content Investment', `$${cache.investment.toFixed(0)}`], ['Estimated Content Value Now', `$${currentValue.toFixed(0)}`], ['Overall Decay Percentage', `${decayPct.toFixed(1)}%`], ['Estimated Financial Impact', `$${financialImpact.toFixed(0)}`], ['Content Freshness Score', `${freshnessPct}%`] ]; doc.autoTable({ startY: 85, head: [], body: summaryData, theme: 'plain', styles: { cellPadding: 3, fontSize: 11, textColor: [...tertiaryColor], }, columnStyles: { 0: { fontStyle: 'bold', textColor: [...secondaryColor] }, }, alternateRowStyles: { fillColor: [245, 250, 255], }, }); // Decay Models section const modelY = doc.previousAutoTable.finalY + 10; doc.setFontSize(16); doc.text('Decay Model Analysis', 20, modelY); // Scale for current time period const scale = days / 180; // Model data const modelData = [ [ 'Baseline Model', 'Normal ranking decay', `${(cache.modelBases.baseline * scale * 100).toFixed(1)}%`, `$${(cache.investment * (1 - cache.modelBases.baseline * scale)).toFixed(0)}`, `$${(cache.investment * cache.modelBases.baseline * scale).toFixed(0)}` ], [ 'Cannibalization', 'Content competition', `${(cache.modelBases.cannibal * scale * 100).toFixed(1)}%`, `$${(cache.investment * (1 - cache.modelBases.cannibal * scale)).toFixed(0)}`, `$${(cache.investment * cache.modelBases.cannibal * scale).toFixed(0)}` ], [ 'DA vs KD Mismatch', 'Authority challenges', `${(cache.modelBases.mismatch * scale * 100).toFixed(1)}%`, `$${(cache.investment * (1 - cache.modelBases.mismatch * scale)).toFixed(0)}`, `$${(cache.investment * cache.modelBases.mismatch * scale).toFixed(0)}` ], [ 'Content Plateau', 'Relevance steps', `${(cache.modelBases.plateau * scale * 100).toFixed(1)}%`, `$${(cache.investment * (1 - cache.modelBases.plateau * scale)).toFixed(0)}`, `$${(cache.investment * cache.modelBases.plateau * scale).toFixed(0)}` ] ]; doc.autoTable({ startY: modelY + 5, head: [['Model', 'Type', 'Decay %', 'Remaining Value', 'Cost Impact']], body: modelData, headStyles: { fillColor: [...accentColor], textColor: [255, 255, 255], fontStyle: 'bold', }, alternateRowStyles: { fillColor: [245, 250, 255], }, }); // Content Freshness section const freshnessY = doc.previousAutoTable.finalY + 10; doc.setFontSize(16); doc.text('Content Freshness', 20, freshnessY); // Freshness data const freshnessData = [ ['Last 30 Days', `${cache.fresh.last30} URLs`, `${((cache.fresh.last30 / cache.fresh.total) * 100).toFixed(1)}%`], ['Last 90 Days', `${cache.fresh.last90} URLs`, `${((cache.fresh.last90 / cache.fresh.total) * 100).toFixed(1)}%`], ['Over 1 Year Old', `${cache.fresh.over365} URLs`, `${((cache.fresh.over365 / cache.fresh.total) * 100).toFixed(1)}%`], ['No Last-Modified Date', `${cache.fresh.never} URLs`, `${((cache.fresh.never / cache.fresh.total) * 100).toFixed(1)}%`] ]; doc.autoTable({ startY: freshnessY + 5, head: [['Content Age', 'Count', 'Percentage']], body: freshnessData, headStyles: { fillColor: [16, 185, 129], // Green textColor: [255, 255, 255], fontStyle: 'bold', }, alternateRowStyles: { fillColor: [240, 253, 244], }, }); // Risk Factors section const riskY = doc.previousAutoTable.finalY + 10; doc.setFontSize(16); doc.text('Domain Risk Factors', 20, riskY); // Risk data const riskData = [ ['Domain Age', cache.factors.domainAge?.toFixed(2) || '1.00', cache.factors.domainAge > 1.1 ? 'High' : 'Normal'], ['Content Density', cache.factors.contentDensity.toFixed(2), cache.factors.contentDensity > 1.1 ? 'High' : 'Normal'], ['Business Model', cache.factors.businessModel.toFixed(2), cache.factors.businessModel > 1.1 ? 'High' : 'Normal'], ['Site Scale', cache.factors.siteScale.toFixed(2), cache.factors.siteScale > 1.1 ? 'High' : 'Normal'], ['Competition', cache.factors.competition?.toFixed(2) || '1.00', cache.factors.competition > 1.1 ? 'High' : 'Normal'], ['Overall Risk', cache.factors.overall.toFixed(2), cache.factors.overall > 1.1 ? 'High' : 'Normal'] ]; doc.autoTable({ startY: riskY + 5, head: [['Factor', 'Value', 'Risk Level']], body: riskData, headStyles: { fillColor: [239, 68, 68], // Red textColor: [255, 255, 255], fontStyle: 'bold', }, alternateRowStyles: { fillColor: [254, 242, 242], }, }); // Add new page for recommendations doc.addPage(); // Recommendations section doc.setFontSize(16); doc.setTextColor(...secondaryColor); doc.text('Recommended Next Steps', 20, 20); // Generate insights const insights = generateContentInsights( decayPct, cache.fresh, cache.avgAge, cache.domain ); // Format insights data const insightsData = insights.map(insight => [ insight.title, insight.description ]); doc.autoTable({ startY: 25, head: [['Insight', 'Description']], body: insightsData, headStyles: { fillColor: [139, 92, 246], // Purple textColor: [255, 255, 255], fontStyle: 'bold', }, columnStyles: { 0: { fontStyle: 'bold', cellWidth: 50 }, 1: { cellWidth: 'auto' } }, }); // Final call to action const ctaY = doc.previousAutoTable.finalY + 10; doc.setFillColor(0, 0, 0); doc.rect(0, ctaY, 210, 40, 'F'); doc.setTextColor(255, 255, 255); doc.setFontSize(14); doc.text('Need Expert Help Improving Your Content Strategy?', 20, ctaY + 15); doc.setFontSize(12); doc.text('Schedule a consultation with our team:', 20, ctaY + 25); doc.setTextColor(59, 130, 246); // Blue for URL doc.text('https://calendly.com/1upmedia', 20, ctaY + 32); // Footer with page numbers const pageCount = doc.getNumberOfPages(); for (let i = 1; i <= pageCount; i++) { doc.setPage(i); doc.setFontSize(10); doc.setTextColor(128, 128, 128); doc.text(`Page ${i} of ${pageCount} | Generated by 1UP Content Decay Calculator`, 20, 287); } // Save the PDF doc.save(`${domain.replace(/[^a-z0-9]/gi, '-')}-decay-audit.pdf`); } // Fallback function to download text version function downloadTextVersion() { const domain = cache.domain; const date = new Date().toLocaleDateString(); const days = parseInt(dayRange.value, 10); const decayPct = cache.modelBases.weightedDecay * (days / 180) * 100; const reportContent = `1UP CONTENT DECAY AUDIT
Domain: ${domain}
Date: ${date}
Analysis Period: ${days} days
SUMMARY STATISTICS:
- Total URLs: ${cache.urlsLen}
- Unique Content Pages: ${cache.uniqueCount}
- Average Content Age: ${cache.avgAge.toFixed(0)} days
- Original Content Investment: $${cache.investment.toFixed(0)}
- Estimated Content Value Now: $${(cache.investment * (1 - (cache.modelBases.weightedDecay * days / 180))).toFixed(0)}
- Overall Decay Percentage: ${decayPct.toFixed(1)}%
- Estimated Financial Impact: $${(cache.investment * cache.modelBases.weightedDecay * days / 180).toFixed(0)}
CONTENT FRESHNESS:
- Content Updated in Last 30 Days: ${cache.fresh.last30} URLs (${((cache.fresh.last30 / cache.fresh.total) * 100).toFixed(1)}%)
- Content Over 1 Year Old: ${cache.fresh.over365} URLs (${((cache.fresh.over365 / cach
DNS now
{
"A": [
"94.23.208.51"
],
"MX": [
{
"exchange": "alt2.aspmx.l.google.com",
"priority": 5
},
{
"exchange": "alt3.aspmx.l.google.com",
"priority": 10
},
{
"exchange": "alt4.aspmx.l.google.com",
"priority": 10
},
{
"exchange": "alt1.aspmx.l.google.com",
"priority": 5
},
{
"exchange": "aspmx.l.google.com",
"priority": 1
}
],
"NS": [
"ns48.domaincontrol.com",
"ns47.domaincontrol.com"
],
"TXT": [
"NETORGFT12115590.onmicrosoft.com",
"v=spf1 include:_spf.google.com ~all",
"google-site-verification=VAtmibKl2HJELMEg7cwwI8ZaOG1i1Q96x06EleqwtPc"
],
"AAAA": []
}