/** * CatOS v9.0 (Whiskers Edition) 🐱‍đŸ’ģ * A pseudo desktop operating system portfolio */ // CatOS Core System const CatOS = { // System state windows: new Map(), apps: new Map(), nextWindowId: 1, focusedWindow: null, startMenuOpen: false, // Project data projects: { 'sneaky-cat-proxy': { title: 'Sneaky Cat Proxy', icon: '🔗', description: 'A purr-fessional proxy that helps cats navigate the internet stealthily! đŸ•ĩī¸â€â™€ī¸', technologies: ['Node.js', 'Express', 'Stealth'], features: [ 'Stealth browsing capabilities', 'Cat-safe internet filtering', 'Automatic mouse toy detection', 'Built-in treat dispenser API' ], github: 'https://github.com/catcoder/sneaky-proxy', demo: 'https://sneaky-cat-proxy.vercel.app' }, 'cat-photo-gallery': { title: 'Cat Photo Gallery', icon: '📸', description: 'A claw-some gallery to showcase all your favorite cat pics with purr-fect filtering! đŸ˜ģ', technologies: ['React', 'TypeScript', 'Tailwind'], features: [ 'Advanced cat photo filtering', 'Automatic whisker detection', 'Paw print watermarking', 'Social sharing for cat influencers' ], github: 'https://github.com/catcoder/cat-gallery', demo: 'https://cat-gallery.vercel.app' }, 'robo-cat-manager': { title: 'Robo-Cat Manager', icon: '🤖', description: 'Managing Discord bots like herding cats! Keep your digital kitties in line with style! 🐱‍đŸ’ģ', technologies: ['Discord.js', 'MongoDB', 'Docker'], features: [ 'Multi-bot management dashboard', 'Automatic yarn ball deployment', 'Cat behavior analytics', 'Emergency tuna button' ], github: 'https://github.com/catcoder/robo-cat-manager', demo: 'https://discord-bot-manager.vercel.app' } }, // Initialize CatOS init() { this.showLoadingScreen(); this.setupEventListeners(); this.updateClock(); this.registerApps(); this.setRandomWallpaper(); // Boot sequence setTimeout(() => { this.hideLoadingScreen(); this.playStartupSound(); this.showWelcomeMessage(); }, 3000); }, // Event Listeners setupEventListeners() { // Desktop icon interactions document.querySelectorAll('.desktop-icon').forEach(icon => { icon.addEventListener('dblclick', this.handleIconDoubleClick.bind(this)); icon.addEventListener('click', this.handleIconClick.bind(this)); }); // Start button document.getElementById('start-button').addEventListener('click', this.toggleStartMenu.bind(this)); // Start menu apps document.querySelectorAll('.menu-app').forEach(app => { app.addEventListener('click', this.handleMenuAppClick.bind(this)); }); // Desktop context menu document.getElementById('desktop').addEventListener('contextmenu', this.showContextMenu.bind(this)); // Close context menu on click document.addEventListener('click', this.hideContextMenu.bind(this)); // Close start menu on outside click document.addEventListener('click', (e) => { if (!e.target.closest('.start-button') && !e.target.closest('.start-menu')) { this.hideStartMenu(); } }); // Keyboard shortcuts document.addEventListener('keydown', this.handleKeyboard.bind(this)); // Window container clicks (deselect icons) document.getElementById('windows-container').addEventListener('click', (e) => { if (e.target.id === 'windows-container') { this.deselectAllIcons(); } }); }, // Icon interactions handleIconClick(e) { this.deselectAllIcons(); e.currentTarget.classList.add('selected'); }, handleIconDoubleClick(e) { const icon = e.currentTarget; const appType = icon.dataset.app; const projectId = icon.dataset.project; if (appType === 'project-viewer' && projectId) { this.launchApp('project-viewer', { projectId }); } else { this.launchApp(appType); } }, deselectAllIcons() { document.querySelectorAll('.desktop-icon.selected').forEach(icon => { icon.classList.remove('selected'); }); }, // Start Menu toggleStartMenu() { const menu = document.getElementById('start-menu'); const button = document.getElementById('start-button'); if (this.startMenuOpen) { this.hideStartMenu(); } else { menu.classList.add('show'); button.classList.add('active'); this.startMenuOpen = true; } }, hideStartMenu() { const menu = document.getElementById('start-menu'); const button = document.getElementById('start-button'); menu.classList.remove('show'); button.classList.remove('active'); this.startMenuOpen = false; }, handleMenuAppClick(e) { const appType = e.currentTarget.dataset.app; this.launchApp(appType); this.hideStartMenu(); }, // Context Menu showContextMenu(e) { e.preventDefault(); const menu = document.getElementById('context-menu'); menu.style.left = e.clientX + 'px'; menu.style.top = e.clientY + 'px'; menu.classList.add('show'); }, hideContextMenu() { document.getElementById('context-menu').classList.remove('show'); }, // App Management registerApps() { this.apps.set('terminal', { title: 'Terminal', icon: 'đŸ’ģ', create: () => this.createTerminalApp() }); this.apps.set('project-viewer', { title: 'Project Viewer', icon: '📁', create: (options) => this.createProjectViewerApp(options) }); this.apps.set('about', { title: 'About CatOS', icon: '📋', create: () => this.createAboutApp() }); this.apps.set('contact', { title: 'Contact', icon: '📧', create: () => this.createContactApp() }); this.apps.set('file-explorer', { title: 'File Explorer', icon: '📁', create: () => this.createFileExplorerApp() }); }, launchApp(appType, options = {}) { const app = this.apps.get(appType); if (!app) { this.showNotification(`App '${appType}' not found! 🙀`, 'error'); return; } // Check if app is already running (except project-viewer which can have multiple instances) if (appType !== 'project-viewer') { for (const [windowId, window] of this.windows) { if (window.appType === appType) { this.focusWindow(windowId); return; } } } const content = app.create(options); const windowId = this.createWindow({ title: app.title, icon: app.icon, content: content, appType: appType }); this.addToTaskbar(windowId, app); }, // Window Management createWindow(options) { const windowId = `window-${this.nextWindowId++}`; const window = document.createElement('div'); window.className = 'window focused'; window.id = windowId; window.innerHTML = `
${options.icon} ${options.title}
${options.content}
`; // Position window const offset = (this.nextWindowId - 2) * 30; window.style.left = (100 + offset) + 'px'; window.style.top = (50 + offset) + 'px'; window.style.width = options.width || '600px'; window.style.height = options.height || '400px'; // Add to container document.getElementById('windows-container').appendChild(window); // Store window data this.windows.set(windowId, { element: window, title: options.title, icon: options.icon, appType: options.appType, minimized: false, maximized: false }); // Setup window events this.setupWindowEvents(windowId); this.focusWindow(windowId); return windowId; }, setupWindowEvents(windowId) { const window = this.windows.get(windowId); const element = window.element; // Window controls element.querySelectorAll('.window-control').forEach(btn => { btn.addEventListener('click', (e) => { e.stopPropagation(); const action = btn.dataset.action; switch(action) { case 'minimize': this.minimizeWindow(windowId); break; case 'maximize': this.toggleMaximizeWindow(windowId); break; case 'close': this.closeWindow(windowId); break; } }); }); // Window focus element.addEventListener('mousedown', () => { this.focusWindow(windowId); }); // Window dragging const titlebar = element.querySelector('.window-titlebar'); this.makeDraggable(element, titlebar); // Window resizing this.setupWindowResizing(windowId); }, focusWindow(windowId) { // Unfocus all windows document.querySelectorAll('.window').forEach(w => { w.classList.remove('focused'); }); // Update taskbar document.querySelectorAll('.taskbar-app').forEach(app => { app.classList.remove('focused'); }); // Focus target window const window = this.windows.get(windowId); if (window) { window.element.classList.add('focused'); this.focusedWindow = windowId; // Update taskbar const taskbarApp = document.querySelector(`[data-window-id="${windowId}"]`); if (taskbarApp) { taskbarApp.classList.add('focused'); } } }, minimizeWindow(windowId) { const window = this.windows.get(windowId); if (window) { window.element.classList.add('minimized'); window.minimized = true; // Update taskbar const taskbarApp = document.querySelector(`[data-window-id="${windowId}"]`); if (taskbarApp) { taskbarApp.classList.remove('focused'); } } }, toggleMaximizeWindow(windowId) { const window = this.windows.get(windowId); if (window) { if (window.maximized) { window.element.classList.remove('maximized'); window.maximized = false; } else { window.element.classList.add('maximized'); window.maximized = true; } } }, closeWindow(windowId) { const window = this.windows.get(windowId); if (window) { // Remove from DOM window.element.remove(); // Remove from taskbar const taskbarApp = document.querySelector(`[data-window-id="${windowId}"]`); if (taskbarApp) { taskbarApp.remove(); } // Remove from windows map this.windows.delete(windowId); // Focus another window if this was focused if (this.focusedWindow === windowId) { const remainingWindows = Array.from(this.windows.keys()); if (remainingWindows.length > 0) { this.focusWindow(remainingWindows[remainingWindows.length - 1]); } else { this.focusedWindow = null; } } } }, // Taskbar Management addToTaskbar(windowId, app) { const taskbar = document.getElementById('taskbar-apps'); const taskbarApp = document.createElement('div'); taskbarApp.className = 'taskbar-app focused'; taskbarApp.dataset.windowId = windowId; taskbarApp.innerHTML = ` ${app.icon} ${app.title} `; taskbarApp.addEventListener('click', () => { const window = this.windows.get(windowId); if (window) { if (window.minimized) { window.element.classList.remove('minimized'); window.minimized = false; } this.focusWindow(windowId); } }); taskbar.appendChild(taskbarApp); }, // Dragging functionality makeDraggable(element, handle) { let isDragging = false; let currentX, currentY, initialX, initialY, xOffset = 0, yOffset = 0; const dragStart = (e) => { const window = this.windows.get(element.id); if (window && window.maximized) return; // Can't drag maximized windows if (e.type === "touchstart") { initialX = e.touches[0].clientX - xOffset; initialY = e.touches[0].clientY - yOffset; } else { initialX = e.clientX - xOffset; initialY = e.clientY - yOffset; } if (e.target === handle || handle.contains(e.target)) { isDragging = true; document.body.classList.add('dragging'); } }; const drag = (e) => { if (isDragging) { e.preventDefault(); if (e.type === "touchmove") { currentX = e.touches[0].clientX - initialX; currentY = e.touches[0].clientY - initialY; } else { currentX = e.clientX - initialX; currentY = e.clientY - initialY; } xOffset = currentX; yOffset = currentY; element.style.left = currentX + "px"; element.style.top = currentY + "px"; } }; const dragEnd = () => { initialX = currentX; initialY = currentY; isDragging = false; document.body.classList.remove('dragging'); }; handle.addEventListener("mousedown", dragStart); handle.addEventListener("touchstart", dragStart); document.addEventListener("mousemove", drag); document.addEventListener("touchmove", drag); document.addEventListener("mouseup", dragEnd); document.addEventListener("touchend", dragEnd); }, // Window resizing functionality setupWindowResizing(windowId) { const window = this.windows.get(windowId); const element = window.element; const resizeHandles = element.querySelectorAll('.window-resize-handle'); let isResizing = false; let resizeDirection = ''; let startX, startY, startWidth, startHeight, startLeft, startTop; const resizeStart = (e) => { const windowData = this.windows.get(element.id); if (windowData && windowData.maximized) return; // Can't resize maximized windows e.preventDefault(); e.stopPropagation(); isResizing = true; resizeDirection = e.target.dataset.direction; startX = e.clientX; startY = e.clientY; startWidth = parseInt(getComputedStyle(element).width, 10); startHeight = parseInt(getComputedStyle(element).height, 10); startLeft = parseInt(getComputedStyle(element).left, 10); startTop = parseInt(getComputedStyle(element).top, 10); element.classList.add('resizing'); document.body.style.cursor = e.target.style.cursor; document.body.style.userSelect = 'none'; }; const resize = (e) => { if (!isResizing) return; e.preventDefault(); const deltaX = e.clientX - startX; const deltaY = e.clientY - startY; let newWidth = startWidth; let newHeight = startHeight; let newLeft = startLeft; let newTop = startTop; // Calculate new dimensions based on resize direction if (resizeDirection.includes('e')) { newWidth = Math.max(300, startWidth + deltaX); } if (resizeDirection.includes('w')) { newWidth = Math.max(300, startWidth - deltaX); newLeft = startLeft + (startWidth - newWidth); } if (resizeDirection.includes('s')) { newHeight = Math.max(200, startHeight + deltaY); } if (resizeDirection.includes('n')) { newHeight = Math.max(200, startHeight - deltaY); newTop = startTop + (startHeight - newHeight); } // Apply new dimensions element.style.width = newWidth + 'px'; element.style.height = newHeight + 'px'; element.style.left = newLeft + 'px'; element.style.top = newTop + 'px'; }; const resizeEnd = () => { if (!isResizing) return; isResizing = false; resizeDirection = ''; element.classList.remove('resizing'); document.body.style.cursor = ''; document.body.style.userSelect = ''; }; // Add event listeners to all resize handles resizeHandles.forEach(handle => { handle.addEventListener('mousedown', resizeStart); }); document.addEventListener('mousemove', resize); document.addEventListener('mouseup', resizeEnd); }, // App Creation Functions createTerminalApp() { const terminalId = `terminal-${Date.now()}`; setTimeout(() => { this.initializeTerminal(terminalId); }, 100); return `
CatOS Terminal v9.0
cat@catos:~$ Welcome to CatOS Terminal! 🐱
cat@catos:~$ Type 'help' for available commands or 'meow' for cat wisdom
cat@catos:~$
`; }, createProjectViewerApp(options) { const project = this.projects[options.projectId]; if (!project) { return '

Project not found! 🙀

'; } return `
${project.icon}

${project.title}

${project.description}

đŸ› ī¸ Technologies

${project.technologies.map(tech => `${tech}`).join('')}

✨ Features

    ${project.features.map(feature => `
  • ${feature}
  • `).join('')}
`; }, createAboutApp() { return `

CatOS v9.0 (Whiskers Edition)

A purr-fessional desktop portfolio experience

System Information

Developer: Rafael (Certified Cat Whisperer)
Uptime: 5+ years coding experience
Memory: ∞ GB coffee-powered RAM
Storage: ∞ TB of cat photos and code

Installed Skills

JavaScript
95%
React
90%
Node.js
85%
Cat Psychology
Expert
`; }, createContactApp() { return `
📧

Let's Be Cat Friends!

Got a purr-fect project idea? Want to code together? 🐾

`; }, createFileExplorerApp() { return `
📁
Desktop
📁
Projects
📁
Documents
📁
Pictures
📄
Resume.pdf
🐱
CatWisdom.txt
`; }, // System functions updateClock() { const clockElement = document.querySelector('.time'); const updateTime = () => { const now = new Date(); const time = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: true }); clockElement.textContent = time; }; updateTime(); setInterval(updateTime, 1000); }, showLoadingScreen() { const messages = [ 'Initializing cat-ware...', 'Loading whiskers.dll...', 'Calibrating purr engine...', 'Installing 9 lives protection...', 'Warming up the litter box...', 'Ready to pounce! 🐾' ]; let messageIndex = 0; const messageElement = document.querySelector('.loading-message'); const updateMessage = () => { if (messageIndex < messages.length) { messageElement.textContent = messages[messageIndex]; messageIndex++; setTimeout(updateMessage, 500); } }; updateMessage(); }, hideLoadingScreen() { const loadingScreen = document.getElementById('loading-screen'); loadingScreen.classList.add('hidden'); }, playStartupSound() { // Soft meow sound would go here console.log('🐱 *gentle startup meow*'); }, showWelcomeMessage() { this.showNotification('Welcome to CatOS! Double-click icons to launch apps 🐾', 'success'); }, showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.className = `notification ${type}`; notification.innerHTML = `
${type === 'success' ? '✅' : type === 'error' ? '❌' : 'â„šī¸'} ${message}
`; // Add styles Object.assign(notification.style, { position: 'fixed', top: '20px', right: '20px', background: type === 'error' ? '#fee2e2' : type === 'success' ? '#d1fae5' : '#dbeafe', color: type === 'error' ? '#dc2626' : type === 'success' ? '#059669' : '#1d4ed8', padding: '12px 16px', borderRadius: '8px', border: `1px solid ${type === 'error' ? '#fecaca' : type === 'success' ? '#a7f3d0' : '#bfdbfe'}`, boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)', zIndex: '10000', fontSize: '0.875rem', maxWidth: '300px', animation: 'slideIn 0.3s ease' }); document.body.appendChild(notification); // Auto remove after 3 seconds setTimeout(() => { notification.style.animation = 'slideOut 0.3s ease'; setTimeout(() => { document.body.removeChild(notification); }, 300); }, 3000); }, // Keyboard shortcuts handleKeyboard(e) { // Alt + Tab - Switch windows if (e.altKey && e.key === 'Tab') { e.preventDefault(); this.switchToNextWindow(); } // Ctrl + Alt + T - Open terminal if (e.ctrlKey && e.altKey && e.key.toLowerCase() === 't') { e.preventDefault(); this.launchApp('terminal'); } // Escape - Close context menu / start menu if (e.key === 'Escape') { this.hideContextMenu(); this.hideStartMenu(); } }, switchToNextWindow() { const windowIds = Array.from(this.windows.keys()).filter(id => { const window = this.windows.get(id); return !window.minimized; }); if (windowIds.length === 0) return; const currentIndex = windowIds.indexOf(this.focusedWindow); const nextIndex = (currentIndex + 1) % windowIds.length; this.focusWindow(windowIds[nextIndex]); }, // Random Wallpaper System setRandomWallpaper() { const wallpaperCount = 6; // Update this if you add more wallpapers const randomWallpaper = Math.floor(Math.random() * wallpaperCount) + 1; const wallpaperPath = `./static/wallpapers/wallpaper${randomWallpaper}.png`; // Set the wallpaper as the first background image const desktop = document.getElementById('desktop'); const currentStyle = getComputedStyle(desktop); const patternImage = `url('data:image/svg+xml,🐾')`; desktop.style.backgroundImage = `url('${wallpaperPath}'), ${patternImage}`; // Log which wallpaper was selected (for debugging) console.log(`đŸ–ŧī¸ Selected wallpaper: wallpaper${randomWallpaper}.png`); // Add a subtle fade-in effect desktop.style.opacity = '0'; setTimeout(() => { desktop.style.transition = 'opacity 0.5s ease'; desktop.style.opacity = '1'; }, 100); }, // Terminal System initializeTerminal(terminalId) { const input = document.getElementById(`terminal-input-${terminalId}`); const content = document.getElementById(`terminal-content-${terminalId}`); const prompt = document.getElementById(`prompt-${terminalId}`); if (!input || !content || !prompt) return; // Terminal state const terminal = { currentDirectory: '/home/catcoder', commandHistory: [], historyIndex: -1, visitorInfo: this.getVisitorInfo() }; // Handle command input input.addEventListener('keydown', (e) => { if (e.key === 'Enter') { const command = input.value.trim(); if (command) { this.executeCommand(command, terminal, content, prompt); terminal.commandHistory.push(command); terminal.historyIndex = terminal.commandHistory.length; } input.value = ''; } else if (e.key === 'ArrowUp') { e.preventDefault(); if (terminal.historyIndex > 0) { terminal.historyIndex--; input.value = terminal.commandHistory[terminal.historyIndex]; } } else if (e.key === 'ArrowDown') { e.preventDefault(); if (terminal.historyIndex < terminal.commandHistory.length - 1) { terminal.historyIndex++; input.value = terminal.commandHistory[terminal.historyIndex]; } else { terminal.historyIndex = terminal.commandHistory.length; input.value = ''; } } }); // Keep input focused content.addEventListener('click', () => { input.focus(); }); }, getVisitorInfo() { return { browser: navigator.userAgent.split(' ').pop().split('/')[0] || 'Unknown', platform: navigator.platform || 'Unknown', language: navigator.language || 'en-US', screenWidth: screen.width, screenHeight: screen.height, timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || 'Unknown', connection: navigator.connection?.effectiveType || 'Unknown', visitTime: new Date().toISOString() }; }, executeCommand(command, terminal, content, prompt) { // Add command to terminal this.addTerminalLine(content, `${prompt.textContent} ${command}`); const [cmd, ...args] = command.toLowerCase().split(' '); const fullArgs = args.join(' '); // Command routing switch(cmd) { case 'help': this.terminalHelp(content); break; case 'clear': this.terminalClear(content); break; case 'whoami': this.terminalWhoami(content, terminal.visitorInfo); break; case 'ls': this.terminalLs(content, terminal.currentDirectory, fullArgs); break; case 'cat': this.terminalCat(content, fullArgs, terminal.currentDirectory); break; case 'cd': this.terminalCd(content, terminal, fullArgs); break; case 'pwd': this.terminalPwd(content, terminal.currentDirectory); break; case 'ps': this.terminalPs(content, fullArgs); break; case 'date': this.terminalDate(content); break; case 'uptime': this.terminalUptime(content); break; case 'meow': this.terminalMeow(content, fullArgs); break; case 'purr': this.terminalPurr(content); break; case 'whiskers': this.terminalWhiskers(content); break; case 'nap': this.terminalNap(content); break; case 'fortune': this.terminalFortune(content); break; case 'curl': this.terminalCurl(content, fullArgs); break; case 'git': this.terminalGit(content, fullArgs); break; case 'npm': this.terminalNpm(content, fullArgs); break; case 'history': this.terminalHistory(content, terminal.commandHistory); break; case 'echo': this.terminalEcho(content, fullArgs); break; default: this.terminalUnknown(content, cmd); } // Update prompt based on directory this.updatePrompt(prompt, terminal.currentDirectory); // Scroll to bottom content.scrollTop = content.scrollHeight; }, addTerminalLine(content, text, className = 'terminal-text') { const line = document.createElement('div'); line.className = 'terminal-line'; line.innerHTML = `${text}`; content.appendChild(line); }, addTerminalOutput(content, text) { const line = document.createElement('div'); line.className = 'terminal-line'; line.innerHTML = `${text}`; content.appendChild(line); }, updatePrompt(prompt, currentDirectory) { const dirName = currentDirectory.split('/').pop() || currentDirectory; const shortDir = dirName === 'catcoder' ? '~' : dirName; prompt.textContent = `cat@catos:${shortDir}$`; }, // Terminal Commands terminalHelp(content) { const helpText = ` Available Commands: 📁 Navigation: ls [path] - List directory contents cd [directory] - Change directory pwd - Print working directory cat [file] - Display file contents 🔍 System: whoami - Display visitor information ps aux - Show running processes date - Show current date/time uptime - Show system uptime history - Show command history clear - Clear terminal 🌐 Network: curl [url] - Fetch web content git [command] - Git operations npm [command] - NPM operations 🐱 Cat Commands: meow [message] - Cat responses purr - Show happiness level whiskers - ASCII cat art nap - Activate screensaver fortune - Cat wisdom 💡 Tips: Use ↑/↓ arrows for command history Try: cat projects/sneaky-cat-proxy.md `; this.addTerminalOutput(content, helpText); }, terminalClear(content) { content.innerHTML = ''; }, terminalWhoami(content, visitorInfo) { const info = ` đŸ•ĩī¸ Visitor Detective Results: ┌─────────────────────────────────────┐ │ Browser: ${visitorInfo.browser} │ Platform: ${visitorInfo.platform} │ Screen: ${visitorInfo.screenWidth}x${visitorInfo.screenHeight} │ Language: ${visitorInfo.language} │ Timezone: ${visitorInfo.timezone} │ Connection: ${visitorInfo.connection} │ Visit Time: ${new Date(visitorInfo.visitTime).toLocaleString()} └─────────────────────────────────────┘ *purrs* Nice to meet you, fellow human! 🐱 `; this.addTerminalOutput(content, info); }, terminalLs(content, currentDirectory, args) { const directories = { '/home/catcoder': [ { name: 'Desktop', type: 'dir', icon: '📁' }, { name: 'projects', type: 'dir', icon: '📁' }, { name: 'documents', type: 'dir', icon: '📁' }, { name: 'pictures', type: 'dir', icon: '📁' }, { name: 'resume.pdf', type: 'file', icon: '📄' }, { name: 'cat-wisdom.txt', type: 'file', icon: '🐱' } ], '/home/catcoder/projects': [ { name: 'sneaky-cat-proxy', type: 'dir', icon: '🔗' }, { name: 'cat-photo-gallery', type: 'dir', icon: '📸' }, { name: 'robo-cat-manager', type: 'dir', icon: '🤖' } ], '/home/catcoder/documents': [ { name: 'ideas.md', type: 'file', icon: '💡' }, { name: 'todo.txt', type: 'file', icon: '📝' }, { name: 'cat-facts.json', type: 'file', icon: '🐾' } ], '/home/catcoder/pictures': [ { name: 'profile-cat.jpg', type: 'file', icon: '😸' }, { name: 'project-screenshots', type: 'dir', icon: '📁' }, { name: 'memes', type: 'dir', icon: '😹' } ] }; const contents = directories[currentDirectory] || []; if (contents.length === 0) { this.addTerminalOutput(content, 'Directory is empty... like a cat\'s food bowl at 3am đŸŊī¸'); return; } let output = `📂 Contents of ${currentDirectory}:\n`; contents.forEach(item => { const type = item.type === 'dir' ? 'DIR' : 'FILE'; output += `${item.icon} ${type} ${item.name}\n`; }); this.addTerminalOutput(content, output); }, terminalCat(content, filename, currentDirectory) { const files = { 'resume.pdf': '📄 PDF files need special cat vision! Try opening the About app instead 😸', 'cat-wisdom.txt': `🐱 Cat Wisdom Collection: â€ĸ The early cat gets the tuna â€ĸ In cat we trust, all others bring treats â€ĸ Curiosity didn't kill the cat, it made it a developer â€ĸ A cat's work is never done... mostly because we nap too much â€ĸ Debugging is like herding cats, but the cats are invisible`, 'ideas.md': `💡 Project Ideas: - Cat-themed password manager - Automatic laser pointer for remote work breaks - AI that detects when treats are needed - Social network for cats (MeowSpace) - Smart litter box with analytics dashboard`, 'sneaky-cat-proxy.md': this.getProjectFile('sneaky-cat-proxy'), 'cat-photo-gallery.md': this.getProjectFile('cat-photo-gallery'), 'robo-cat-manager.md': this.getProjectFile('robo-cat-manager') }; // Handle project files if (filename.includes('/')) { const parts = filename.split('/'); const projectName = parts[parts.length - 2]; if (this.projects[projectName]) { this.addTerminalOutput(content, this.getProjectFile(projectName)); return; } } const fileContent = files[filename]; if (fileContent) { this.addTerminalOutput(content, fileContent); } else { this.addTerminalOutput(content, `cat: ${filename}: No such file or directory 🙀\nTry 'ls' to see available files!`); } }, getProjectFile(projectId) { const project = this.projects[projectId]; if (!project) return 'Project not found! 🙀'; return ` ${project.icon} ${project.title} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: ${project.description} Technologies: ${project.technologies.map(tech => `â€ĸ ${tech}`).join('\n')} Features: ${project.features.map(feature => `🐾 ${feature}`).join('\n')} Links: â€ĸ GitHub: ${project.github} â€ĸ Demo: ${project.demo} *purrs approvingly* 😸 `; }, terminalCd(content, terminal, directory) { if (!directory) { terminal.currentDirectory = '/home/catcoder'; this.addTerminalOutput(content, 'Changed to home directory 🏠'); return; } const validDirs = { '~': '/home/catcoder', 'home': '/home/catcoder', 'projects': '/home/catcoder/projects', 'documents': '/home/catcoder/documents', 'pictures': '/home/catcoder/pictures', 'desktop': '/home/catcoder/Desktop', '..': '/home/catcoder' }; if (validDirs[directory]) { terminal.currentDirectory = validDirs[directory]; this.addTerminalOutput(content, `Changed to ${terminal.currentDirectory} 📁`); } else { this.addTerminalOutput(content, `cd: ${directory}: No such directory 🙀`); } }, terminalPwd(content, currentDirectory) { this.addTerminalOutput(content, currentDirectory); }, terminalPs(content, args) { const processes = ` 🔄 CatOS Process Status: USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND cat 1337 15.2 8.5 245760 32156 pts/0 Sl+ 09:30 0:42 /usr/bin/coffee-maker cat 2048 25.1 12.3 512000 45678 pts/1 R+ 09:31 1:23 /bin/cat-nap-scheduler cat 4096 5.8 3.2 128000 12345 pts/2 S 09:32 0:15 /usr/bin/treat-dispenser cat 8192 45.7 25.1 1024000 98765 pts/3 R+ 09:33 2:34 /opt/purr-engine --turbo cat 1024 2.1 1.8 64000 5432 pts/4 S 09:34 0:08 /bin/whiskers-daemon rafael 9999 98.5 75.2 2048000 234567 pts/5 R+ 09:35 5:67 /usr/bin/coding-furiously Current mood: Caffeinated and ready to code! ☕ `; this.addTerminalOutput(content, processes); }, terminalDate(content) { const now = new Date(); const catTime = `${now.toLocaleDateString()} ${now.toLocaleTimeString()}`; this.addTerminalOutput(content, `${catTime} (Cat Standard Time) 🐱⏰`); }, terminalUptime(content) { const uptime = ` âąī¸ System Uptime: Developer: 5+ years of coding experience Coffee Machine: 3 hours since last refill ☕ Cat Nap Counter: 42 naps today 😴 Bug Squashing: 99.9% success rate 🐛 Treat Dispenser: Fully operational 🐟 Purr Engine: Running at optimal frequency 😸 Load average: 1.33, 7.77, 42.00 (that's normal for a cat) 📊 `; this.addTerminalOutput(content, uptime); }, terminalMeow(content, message) { const responses = [ '🐱 *meows back softly*', '😸 Purrfect! I understand completely!', '🐾 *headbutts your screen affectionately*', 'đŸ˜ģ That\'s exactly what I was thinking!', '🙀 You speak fluent cat!', 'đŸ˜ē *slow blinks* - that means "I love you" in cat', '🐱‍đŸ’ģ Meow back! Want to see my latest code?' ]; if (message) { this.addTerminalOutput(content, `🐱 You said: "${message}"`); this.addTerminalOutput(content, `🐾 Translation: "Please give me treats"`); } const response = responses[Math.floor(Math.random() * responses.length)]; this.addTerminalOutput(content, response); }, terminalPurr(content) { this.addTerminalOutput(content, ` 🐱 *PURRRRRRRRRRRRRRRR* 😸 Happiness Level: 95% (needs more treats) 🐾 Satisfaction with website: MAXIMUM đŸ˜ģ Current mood: Content developer cat`); }, terminalWhiskers(content) { const catArt = ` /\\_/\\ ( o.o ) > ^ < /\\_/\\ ( ( ^.^ ) _) <- This is me coding o_(")(") |\\---/| | o_o | <- Me when code works \\_^_/ /\\_____/\\ / o o \\ <- Me reviewing code ( == ^ == ) ) ( ( ) ( ( ) ( ) ) (__(__)___(__)__) `; this.addTerminalOutput(content, catArt); }, terminalNap(content) { this.addTerminalOutput(content, '😴 Activating cat nap mode...'); setTimeout(() => { this.addTerminalOutput(content, '🐱 *stretches and yawns*'); setTimeout(() => { this.addTerminalOutput(content, '😸 Refreshed and ready to code! *tail swish*'); }, 2000); }, 2000); }, terminalFortune(content) { const fortunes = [ '🐱 A cat\'s code is worth a thousand barks.', '😸 Today is a good day to push to production.', '🐾 Your code will run purrfectly... eventually.', 'đŸ˜ģ The best debugging happens at 2 AM with a cat on your keyboard.', '🙀 Error 404: Treats not found. Please refill immediately.', 'đŸ˜ē In the future, all websites will be operated by cats.', '🐱‍đŸ’ģ Curiosity didn\'t kill the cat; it made it a senior developer.', '😹 Your next commit will be legendary... like a cat video.', '🐾 Remember: There are no mistakes, only happy little bugs.', '🐱 The cloud is just other people\'s litter boxes.' ]; const fortune = fortunes[Math.floor(Math.random() * fortunes.length)]; this.addTerminalOutput(content, `🔮 Cat Fortune:\n${fortune}`); }, terminalCurl(content, url) { if (!url) { this.addTerminalOutput(content, 'curl: no URL specified 🙀\nUsage: curl '); return; } this.addTerminalOutput(content, `🌐 Fetching ${url}...`); setTimeout(() => { if (url.includes('cat') || url.includes('meow')) { this.addTerminalOutput(content, `😸 Connection successful! Cat-approved website detected.`); } else if (url.includes('dog')) { this.addTerminalOutput(content, `🙀 Warning: Canine content detected. Proceed with caution.`); } else { this.addTerminalOutput(content, `📡 HTTP/1.1 200 OK - Site looks paw-some!`); } }, 1500); }, terminalGit(content, args) { if (args.startsWith('status')) { this.addTerminalOutput(content, ` On branch main Your branch is up to date with 'origin/main' Changes not staged for commit: modified: life.js (added more cat puns) modified: happiness.css (increased by 200%) Untracked files: cat-treats.json purr-sounds.wav 😸 Working tree status: Purrfect!`); } else if (args.startsWith('log')) { this.addTerminalOutput(content, ` commit a1b2c3d (HEAD -> main) Author: CatDeveloper Date: ${new Date().toDateString()} Fix: Resolved all bugs with strategic cat napping commit d4e5f6g Author: CatDeveloper Date: Yesterday Add: More cat puns to error messages`); } else { this.addTerminalOutput(content, '🐱 Git command executed! *purrs approvingly*'); } }, terminalNpm(content, args) { if (args.startsWith('install')) { this.addTerminalOutput(content, ` đŸ“Ļ Installing cat-packages... 🐾 + cat-utils@9.0.0 😸 + purr-framework@1.2.3 🐱 + meow-validator@0.5.7 đŸ˜ģ + treat-dispenser@2.1.0 added 42 packages in 3.14s (purr time) đŸ˜ē All packages installed successfully!`); } else if (args.startsWith('run')) { this.addTerminalOutput(content, `đŸƒâ€â™€ī¸ Running npm script... *cat runs in circles*`); } else { this.addTerminalOutput(content, 'đŸ“Ļ NPM operation completed! Dependencies are purr-fect! 😸'); } }, terminalHistory(content, commandHistory) { if (commandHistory.length === 0) { this.addTerminalOutput(content, 'History is empty... like a cat\'s promise to stay off the keyboard 😸'); return; } let output = '📚 Command History:\n'; commandHistory.forEach((cmd, index) => { output += `${index + 1}. ${cmd}\n`; }); this.addTerminalOutput(content, output); }, terminalEcho(content, text) { if (!text) { this.addTerminalOutput(content, ''); return; } if (text.toLowerCase().includes('cat') || text.toLowerCase().includes('meow')) { this.addTerminalOutput(content, `${text} 😸`); } else { this.addTerminalOutput(content, text); } }, terminalUnknown(content, command) { const suggestions = [ `🙀 Command '${command}' not found! Did you mean to meow instead?`, `đŸ˜ŋ '${command}' is not a valid command. Try 'help' for available commands!`, `🐱 Unknown command '${command}'. Even cats make typos! Try 'help'.`, `😸 '${command}'? That's not cat language! Type 'help' to see what I understand.`, `🐾 Command '${command}' not recognized. Are you sure you're not a dog? 🐕` ]; const suggestion = suggestions[Math.floor(Math.random() * suggestions.length)]; this.addTerminalOutput(content, suggestion); } }; // Initialize CatOS when DOM is loaded document.addEventListener('DOMContentLoaded', () => { CatOS.init(); }); // Add CSS animations const style = document.createElement('style'); style.textContent = ` @keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } @keyframes slideOut { from { transform: translateX(0); opacity: 1; } to { transform: translateX(100%); opacity: 0; } } .notification-content { display: flex; align-items: center; gap: 8px; } `; document.head.appendChild(style); console.log('🐱‍đŸ’ģ CatOS v9.0 (Whiskers Edition) loaded successfully!'); console.log('💡 Try these keyboard shortcuts:'); console.log(' â€ĸ Alt + Tab: Switch windows'); console.log(' â€ĸ Ctrl + Alt + T: Open terminal'); console.log(' â€ĸ Escape: Close menus');