// Link Validation Script const validateWebsite = { // Core paths that must exist criticalPaths: [ '/', '/projects', '/papers', '/proposals', '/docs', '/api', '/investors' ], // Project paths projectPaths: [ '/projects/analytics', '/projects/autoglaucoma', '/projects/automedical' ], // Paper paths paperPaths: [ '/papers/fermed-vlm.pdf', '/papers/fermed-vlm.html', '/papers/archive' ], // Proposal paths proposalPaths: [ '/proposals/nhs/main', '/proposals/nhs/detailed', '/proposals/nhs/formal', '/proposals/spanish/12oct', '/proposals/spanish/hospital', '/proposals/simple' ], // Documentation paths docPaths: [ '/docs/main', '/docs/internal/emails', '/docs/internal/requirements', '/docs/internal/context', '/docs/references' ], // Validate all links validateLinks() { const results = { working: [], redirects: [], broken: [] }; // Combine all paths const allPaths = [ ...this.criticalPaths, ...this.projectPaths, ...this.paperPaths, ...this.proposalPaths, ...this.docPaths ]; // Check each path allPaths.forEach(path => { try { const response = fetch(path); if (response.ok) { results.working.push(path); } else if (response.status >= 300 && response.status < 400) { results.redirects.push(path); } else { results.broken.push(path); } } catch (error) { results.broken.push(path); } }); return results; }, // Validate navigation consistency validateNavigation() { const navResults = { consistent: [], inconsistent: [] }; // Check navigation elements document.querySelectorAll('nav a').forEach(link => { const href = link.getAttribute('href'); if (href) { const matchingPath = this.allPaths.find(path => path === href); if (matchingPath) { navResults.consistent.push(href); } else { navResults.inconsistent.push(href); } } }); return navResults; }, // Validate breadcrumbs validateBreadcrumbs() { const breadcrumbResults = { valid: [], invalid: [] }; document.querySelectorAll('.breadcrumb').forEach(breadcrumb => { const links = breadcrumb.querySelectorAll('a'); let validPath = true; let currentPath = ''; links.forEach(link => { const href = link.getAttribute('href'); if (href) { currentPath += href === '/' ? '' : href; if (!this.allPaths.includes(currentPath)) { validPath = false; } } }); if (validPath) { breadcrumbResults.valid.push(currentPath); } else { breadcrumbResults.invalid.push(currentPath); } }); return breadcrumbResults; }, // Generate report generateReport() { const linkResults = this.validateLinks(); const navResults = this.validateNavigation(); const breadcrumbResults = this.validateBreadcrumbs(); return { links: linkResults, navigation: navResults, breadcrumbs: breadcrumbResults, summary: { totalLinks: Object.values(linkResults).flat().length, brokenLinks: linkResults.broken.length, inconsistentNav: navResults.inconsistent.length, invalidBreadcrumbs: breadcrumbResults.invalid.length } }; } }; // Export for use in Node.js environments if (typeof module !== 'undefined' && module.exports) { module.exports = validateWebsite; }