| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Washington's Crossing Simulator</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| .river { |
| background: linear-gradient(to bottom, #1a237e, #0d47a1); |
| position: relative; |
| overflow: hidden; |
| } |
| .wave { |
| position: absolute; |
| width: 100%; |
| height: 20px; |
| background: rgba(255, 255, 255, 0.1); |
| animation: wave 3s infinite linear; |
| } |
| .wave:nth-child(2) { |
| top: 20px; |
| animation-delay: 0.5s; |
| } |
| .wave:nth-child(3) { |
| top: 40px; |
| animation-delay: 1s; |
| } |
| @keyframes wave { |
| 0% { transform: translateX(-100%); } |
| 100% { transform: translateX(100%); } |
| } |
| .boat { |
| transition: all 0.5s ease; |
| } |
| .fade-in { |
| animation: fadeIn 1s; |
| } |
| @keyframes fadeIn { |
| from { opacity: 0; } |
| to { opacity: 1; } |
| } |
| .snowflake { |
| position: absolute; |
| background-color: white; |
| border-radius: 50%; |
| pointer-events: none; |
| animation: fall linear infinite; |
| } |
| @keyframes fall { |
| to { transform: translateY(100vh); } |
| } |
| .ice-floe { |
| position: absolute; |
| background-color: rgba(255, 255, 255, 0.7); |
| border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; |
| pointer-events: none; |
| } |
| .patrol { |
| position: absolute; |
| width: 40px; |
| height: 20px; |
| background-color: #8B4513; |
| border-radius: 5px; |
| pointer-events: none; |
| } |
| .achievement-badge { |
| transition: all 0.3s ease; |
| } |
| .achievement-badge:hover { |
| transform: scale(1.1); |
| } |
| .secret-found { |
| animation: pulse 1s infinite; |
| } |
| @keyframes pulse { |
| 0% { transform: scale(1); } |
| 50% { transform: scale(1.1); } |
| 100% { transform: scale(1); } |
| } |
| .timer-bar { |
| transition: width 1s linear; |
| } |
| .glow { |
| animation: glow 2s infinite alternate; |
| } |
| @keyframes glow { |
| from { box-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #e60073, 0 0 20px #e60073; } |
| to { box-shadow: 0 0 10px #fff, 0 0 20px #ff4da6, 0 0 30px #ff4da6, 0 0 40px #ff4da6; } |
| } |
| </style> |
| </head> |
| <body class="bg-gray-900 text-white min-h-screen flex flex-col items-center justify-center p-4"> |
| <div id="game-container" class="w-full max-w-4xl bg-gray-800 rounded-xl shadow-2xl overflow-hidden fade-in"> |
| |
| <div id="title-screen" class="p-8 text-center"> |
| <h1 class="text-4xl md:text-6xl font-bold mb-6 text-yellow-400">WASHINGTON'S CROSSING</h1> |
| <div class="river h-32 my-8 rounded-lg relative"> |
| <div class="wave"></div> |
| <div class="wave"></div> |
| <div class="wave"></div> |
| <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Gilbert_Stuart_Williamstown_Portrait_of_George_Washington.jpg/800px-Gilbert_Stuart_Williamstown_Portrait_of_George_Washington.jpg" |
| class="h-24 absolute left-1/2 -translate-x-1/2 -top-4 rounded-full border-4 border-yellow-500 shadow-lg"> |
| </div> |
| <p class="text-xl mb-8">December 25-26, 1776. Lead your troops across the Delaware River under cover of darkness to surprise the Hessians at Trenton.</p> |
| <div class="flex flex-col space-y-4 max-w-xs mx-auto"> |
| <button onclick="startGame('easy')" class="bg-green-600 hover:bg-green-700 text-white font-bold py-3 px-6 rounded-lg transition transform hover:scale-105"> |
| Easy Crossing |
| </button> |
| <button onclick="startGame('medium')" class="bg-yellow-600 hover:bg-yellow-700 text-white font-bold py-3 px-6 rounded-lg transition transform hover:scale-105"> |
| Standard Challenge |
| </button> |
| <button onclick="startGame('hard')" class="bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-6 rounded-lg transition transform hover:scale-105"> |
| Hardcore Mode |
| </button> |
| <button onclick="showInstructions()" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-6 rounded-lg transition transform hover:scale-105"> |
| Instructions |
| </button> |
| <button onclick="showAchievements()" class="bg-purple-600 hover:bg-purple-700 text-white font-bold py-3 px-6 rounded-lg transition transform hover:scale-105"> |
| Achievements |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div id="instructions-screen" class="hidden p-8"> |
| <h2 class="text-3xl font-bold mb-6 text-yellow-400">How to Cross Like Washington</h2> |
| <div class="space-y-4 mb-8"> |
| <div class="flex items-start"> |
| <div class="bg-yellow-500 text-yellow-900 font-bold rounded-full w-8 h-8 flex items-center justify-center mr-4 mt-1 flex-shrink-0">1</div> |
| <p>Choose your difficulty level - easier modes have better weather and fewer patrols.</p> |
| </div> |
| <div class="flex items-start"> |
| <div class="bg-yellow-500 text-yellow-900 font-bold rounded-full w-8 h-8 flex items-center justify-center mr-4 mt-1 flex-shrink-0">2</div> |
| <p>Select your crossing strategy - more boats are faster but more visible, night crossings are stealthier.</p> |
| </div> |
| <div class="flex items-start"> |
| <div class="bg-yellow-500 text-yellow-900 font-bold rounded-full w-8 h-8 flex items-center justify-center mr-4 mt-1 flex-shrink-0">3</div> |
| <p>Navigate the river - watch for ice floes and British patrols. You must respond to events quickly!</p> |
| </div> |
| <div class="flex items-start"> |
| <div class="bg-yellow-500 text-yellow-900 font-bold rounded-full w-8 h-8 flex items-center justify-center mr-4 mt-1 flex-shrink-0">4</div> |
| <p>Make tactical decisions during the crossing to avoid detection. Some choices may unlock secret achievements!</p> |
| </div> |
| <div class="flex items-start"> |
| <div class="bg-yellow-500 text-yellow-900 font-bold rounded-full w-8 h-8 flex items-center justify-center mr-4 mt-1 flex-shrink-0">5</div> |
| <p>Watch the timer during events - if it runs out, you'll automatically fail the event!</p> |
| </div> |
| </div> |
| <button onclick="hideInstructions()" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-6 rounded-lg"> |
| Back to Title |
| </button> |
| </div> |
|
|
| |
| <div id="achievements-screen" class="hidden p-8"> |
| <h2 class="text-3xl font-bold mb-6 text-yellow-400">Your Achievements</h2> |
| <div id="achievements-container" class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-8"> |
| |
| </div> |
| <div class="mt-6 p-4 bg-gray-700 rounded-lg"> |
| <h3 class="text-xl font-semibold mb-2">Secret Achievements</h3> |
| <p class="text-gray-400">Some achievements are hidden! Discover them through special actions during your crossings.</p> |
| <div id="secret-achievements-container" class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4"> |
| |
| </div> |
| </div> |
| <button onclick="hideAchievements()" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-6 rounded-lg mt-6"> |
| Back to Title |
| </button> |
| </div> |
|
|
| |
| <div id="strategy-screen" class="hidden p-8"> |
| <h2 class="text-3xl font-bold mb-6 text-yellow-400">Plan Your Crossing</h2> |
| <div id="weather-display" class="mb-6 p-4 rounded-lg bg-gray-700"> |
| <h3 class="text-xl font-semibold mb-2">Weather Conditions:</h3> |
| <p id="weather-text"></p> |
| </div> |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8"> |
| <div class="bg-gray-700 p-4 rounded-lg"> |
| <h3 class="text-xl font-semibold mb-3">Crossing Time</h3> |
| <div class="space-y-3"> |
| <label class="flex items-center space-x-3"> |
| <input type="radio" name="time" value="dusk" class="form-radio text-yellow-500" checked> |
| <span>Dusk (Moderate visibility, some patrols)</span> |
| </label> |
| <label class="flex items-center space-x-3"> |
| <input type="radio" name="time" value="midnight" class="form-radio text-blue-500"> |
| <span>Midnight (Best stealth, but colder)</span> |
| </label> |
| <label class="flex items-center space-x-3"> |
| <input type="radio" name="time" value="dawn" class="form-radio text-red-500"> |
| <span>Dawn (Worst stealth, but warmer)</span> |
| </label> |
| </div> |
| </div> |
| <div class="bg-gray-700 p-4 rounded-lg"> |
| <h3 class="text-xl font-semibold mb-3">Boat Strategy</h3> |
| <div class="space-y-3"> |
| <label class="flex items-center space-x-3"> |
| <input type="radio" name="boats" value="few" class="form-radio text-green-500" checked> |
| <span>Few boats (Slow but stealthy)</span> |
| </label> |
| <label class="flex items-center space-x-3"> |
| <input type="radio" name="boats" value="moderate" class="form-radio text-yellow-500"> |
| <span>Moderate boats (Balanced)</span> |
| </label> |
| <label class="flex items-center space-x-3"> |
| <input type="radio" name="boats" value="many" class="form-radio text-red-500"> |
| <span>Many boats (Fast but visible)</span> |
| </label> |
| </div> |
| </div> |
| </div> |
| <div class="bg-gray-700 p-4 rounded-lg mb-8"> |
| <h3 class="text-xl font-semibold mb-3">Special Options</h3> |
| <div class="space-y-3"> |
| <label class="flex items-center space-x-3"> |
| <input type="checkbox" id="secret-route" class="form-checkbox text-purple-500"> |
| <span>Attempt secret route (Risky but potentially rewarding)</span> |
| </label> |
| </div> |
| </div> |
| <button onclick="beginCrossing()" class="bg-green-600 hover:bg-green-700 text-white font-bold py-3 px-8 rounded-lg text-xl"> |
| Begin Crossing |
| </button> |
| </div> |
|
|
| |
| <div id="crossing-screen" class="hidden relative"> |
| <div id="river-container" class="river h-64 w-full relative overflow-hidden"> |
| |
| <div id="boat" class="boat absolute bottom-4 left-8 w-16 h-16 bg-gray-300 rounded-lg"> |
| <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Gilbert_Stuart_Williamstown_Portrait_of_George_Washington.jpg/800px-Gilbert_Stuart_Williamstown_Portrait_of_George_Washington.jpg" |
| class="h-10 absolute -top-4 left-1/2 -translate-x-1/2 rounded-full border-2 border-yellow-500"> |
| </div> |
| |
| </div> |
| <div class="bg-gray-800 p-4 flex justify-between items-center"> |
| <div id="progress-container" class="w-full bg-gray-700 rounded-full h-4"> |
| <div id="progress-bar" class="bg-yellow-500 h-4 rounded-full" style="width: 0%"></div> |
| </div> |
| <div id="distance-text" class="ml-4 font-bold">0%</div> |
| </div> |
| <div id="event-display" class="bg-gray-700 p-4 hidden"> |
| <div class="flex justify-between items-center mb-2"> |
| <h3 class="font-bold text-lg" id="event-title">Event Occurred!</h3> |
| <div class="flex items-center"> |
| <div class="w-24 h-2 bg-gray-600 rounded-full mr-2"> |
| <div id="event-timer" class="timer-bar h-2 bg-red-500 rounded-full" style="width: 100%"></div> |
| </div> |
| <span id="event-time-remaining" class="text-sm">5s</span> |
| </div> |
| </div> |
| <p id="event-description"></p> |
| <div id="event-choices" class="mt-4 space-y-2"></div> |
| </div> |
| <div id="status-display" class="bg-gray-900 p-4 grid grid-cols-4 gap-4 text-center"> |
| <div> |
| <div class="text-sm text-gray-400">Visibility</div> |
| <div id="visibility-value" class="font-bold text-lg">Medium</div> |
| </div> |
| <div> |
| <div class="text-sm text-gray-400">Alert Level</div> |
| <div id="alert-value" class="font-bold text-lg">Low</div> |
| </div> |
| <div> |
| <div class="text-sm text-gray-400">Troop Morale</div> |
| <div id="morale-value" class="font-bold text-lg">High</div> |
| </div> |
| <div> |
| <div class="text-sm text-gray-400">Troops</div> |
| <div id="troops-value" class="font-bold text-lg">2400</div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="results-screen" class="hidden p-8 text-center"> |
| <h2 id="result-title" class="text-4xl font-bold mb-6 text-yellow-400">Crossing Complete!</h2> |
| <div id="result-icon" class="text-8xl mb-6">🎖️</div> |
| <p id="result-description" class="text-xl mb-8">You successfully crossed the Delaware River!</p> |
| |
| <div id="new-achievements" class="mb-8 hidden"> |
| <h3 class="text-2xl font-semibold mb-4 text-yellow-400">New Achievements Unlocked!</h3> |
| <div id="achievements-earned" class="flex flex-wrap justify-center gap-4"> |
| |
| </div> |
| </div> |
| |
| <div id="stats-display" class="bg-gray-700 p-6 rounded-lg mb-8 text-left max-w-md mx-auto"> |
| <h3 class="text-2xl font-semibold mb-4">Crossing Statistics</h3> |
| <div class="grid grid-cols-2 gap-4"> |
| <div>Time Taken:</div> |
| <div id="stat-time" class="font-bold">12 hours</div> |
| <div>Troops Lost:</div> |
| <div id="stat-troops" class="font-bold">2</div> |
| <div>Alert Level:</div> |
| <div id="stat-alert" class="font-bold">Medium</div> |
| <div>Difficulty:</div> |
| <div id="stat-difficulty" class="font-bold">Standard</div> |
| <div>Morale:</div> |
| <div id="stat-morale" class="font-bold">High</div> |
| <div>Score:</div> |
| <div id="stat-score" class="font-bold">850</div> |
| </div> |
| </div> |
| <button onclick="returnToTitle()" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-8 rounded-lg text-xl"> |
| Try Again |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div id="achievement-toast" class="fixed bottom-4 right-4 bg-purple-700 text-white p-4 rounded-lg shadow-lg hidden max-w-xs transform translate-x-full transition-transform duration-300"> |
| <div class="flex items-center"> |
| <div class="mr-3 text-2xl"> |
| <i class="fas fa-trophy"></i> |
| </div> |
| <div> |
| <div class="font-bold" id="toast-title">Achievement Unlocked!</div> |
| <div id="toast-description">Description here</div> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| |
| let gameState = { |
| difficulty: 'medium', |
| crossingTime: 'dusk', |
| boatStrategy: 'few', |
| secretRoute: false, |
| progress: 0, |
| visibility: 50, |
| alertLevel: 20, |
| morale: 80, |
| troops: 2400, |
| events: [], |
| iceFloes: [], |
| patrols: [], |
| startTime: null, |
| endTime: null, |
| eventCooldown: 0, |
| eventTimer: null, |
| eventTimeLeft: 5, |
| achievements: [], |
| secretsFound: [], |
| score: 0 |
| }; |
| |
| |
| const achievements = [ |
| { |
| id: 'first_crossing', |
| title: 'First Crossing', |
| description: 'Complete your first crossing of the Delaware', |
| icon: 'fa-flag', |
| color: 'bg-blue-500', |
| earned: false, |
| secret: false |
| }, |
| { |
| id: 'perfect_crossing', |
| title: 'Perfect Crossing', |
| description: 'Cross without losing any troops', |
| icon: 'fa-star', |
| color: 'bg-yellow-500', |
| earned: false, |
| secret: false |
| }, |
| { |
| id: 'stealth_master', |
| title: 'Stealth Master', |
| description: 'Complete a crossing with alert level below 30', |
| icon: 'fa-user-secret', |
| color: 'bg-green-500', |
| earned: false, |
| secret: false |
| }, |
| { |
| id: 'hardcore_victory', |
| title: 'Hardcore Victory', |
| description: 'Complete a crossing on Hardcore difficulty', |
| icon: 'fa-skull', |
| color: 'bg-red-500', |
| earned: false, |
| secret: false |
| }, |
| { |
| id: 'midnight_crossing', |
| title: 'Midnight Crossing', |
| description: 'Complete a crossing starting at midnight', |
| icon: 'fa-moon', |
| color: 'bg-indigo-500', |
| earned: false, |
| secret: false |
| }, |
| { |
| id: 'frozen_fingers', |
| title: 'Frozen Fingers', |
| description: 'Complete a crossing with morale below 30', |
| icon: 'fa-snowflake', |
| color: 'bg-blue-300', |
| earned: false, |
| secret: false |
| }, |
| { |
| id: 'speed_demon', |
| title: 'Speed Demon', |
| description: 'Complete a crossing in under 30 seconds', |
| icon: 'fa-bolt', |
| color: 'bg-yellow-400', |
| earned: false, |
| secret: false |
| }, |
| { |
| id: 'washington_reborn', |
| title: 'Washington Reborn', |
| description: 'Complete all standard achievements', |
| icon: 'fa-crown', |
| color: 'bg-purple-500', |
| earned: false, |
| secret: false |
| }, |
| |
| { |
| id: 'secret_route', |
| title: 'Secret Pathfinder', |
| description: 'Discover and use the secret route', |
| icon: 'fa-map', |
| color: 'bg-purple-600', |
| earned: false, |
| secret: true |
| }, |
| { |
| id: 'full_alert', |
| title: 'Wanted: Dead or Alive', |
| description: 'Get caught with maximum alert level', |
| icon: 'fa-bullhorn', |
| color: 'bg-red-600', |
| earned: false, |
| secret: true |
| }, |
| { |
| id: 'ice_breaker', |
| title: 'Ice Breaker', |
| description: 'Push through 5 ice floes successfully', |
| icon: 'fa-icicles', |
| color: 'bg-blue-400', |
| earned: false, |
| secret: true |
| }, |
| { |
| id: 'patrol_baiter', |
| title: 'Patrol Baiter', |
| description: 'Get spotted by 3 patrols but still complete the crossing', |
| icon: 'fa-binoculars', |
| color: 'bg-yellow-600', |
| earned: false, |
| secret: true |
| }, |
| { |
| id: 'last_minute', |
| title: 'Last Minute Hero', |
| description: 'Win an event with less than 1 second remaining', |
| icon: 'fa-clock', |
| color: 'bg-red-500', |
| earned: false, |
| secret: true |
| } |
| ]; |
| |
| |
| const weatherConditions = { |
| easy: { |
| description: "Cold but clear night with minimal wind. Good visibility but also easier for patrols to spot you.", |
| wind: 10, |
| temperature: 25, |
| ice: 3 |
| }, |
| medium: { |
| description: "Snowing with moderate wind. Reduced visibility helps stealth but makes navigation harder.", |
| wind: 20, |
| temperature: 15, |
| ice: 6 |
| }, |
| hard: { |
| description: "Blizzard conditions with high winds. Very difficult navigation but excellent cover.", |
| wind: 35, |
| temperature: 5, |
| ice: 10 |
| } |
| }; |
| |
| |
| const events = [ |
| { |
| name: "Ice Floe Ahead", |
| description: "Your scouts report a large ice floe directly in your path. Do you want to go around it or try to push through?", |
| conditions: (state) => state.progress > 10 && state.progress < 90 && Math.random() < 0.3, |
| choices: [ |
| { |
| text: "Go around (slower but safer)", |
| effect: (state) => { |
| state.progress -= 5; |
| state.morale -= 5; |
| return "You successfully navigated around the ice floe, but it cost you time and chilled your troops."; |
| } |
| }, |
| { |
| text: "Push through (faster but risky)", |
| effect: (state) => { |
| const success = Math.random() > 0.3; |
| if (success) { |
| state.progress += 10; |
| checkAchievementProgress('ice_breaker', state); |
| return "Your men pushed through the ice with minimal damage. The crossing continues!"; |
| } else { |
| state.troops -= Math.floor(Math.random() * 50) + 10; |
| state.morale -= 15; |
| return "The ice damaged several boats and some men fell into the freezing water. You lost troops in the crossing."; |
| } |
| } |
| } |
| ] |
| }, |
| { |
| name: "British Patrol Spotted", |
| description: "A British patrol boat has been spotted in the distance. They haven't seen you yet. What do you do?", |
| conditions: (state) => state.progress > 30 && state.progress < 70 && Math.random() < 0.4, |
| choices: [ |
| { |
| text: "Stop all movement and hide", |
| effect: (state) => { |
| state.alertLevel += 5; |
| const detected = Math.random() < 0.2; |
| if (detected) { |
| state.alertLevel = 100; |
| checkAchievementProgress('full_alert', state); |
| checkAchievementProgress('patrol_baiter', state); |
| return "The patrol spotted you despite your efforts! The alarm has been raised!"; |
| } else { |
| return "You remained perfectly still and the patrol passed by without noticing you."; |
| } |
| } |
| }, |
| { |
| text: "Continue quietly at reduced speed", |
| effect: (state) => { |
| state.alertLevel += 15; |
| state.progress += 2; |
| return "You continued moving slowly. The patrol seemed to notice some movement but couldn't identify you."; |
| } |
| }, |
| { |
| text: "Full speed ahead!", |
| effect: (state) => { |
| state.alertLevel += 40; |
| state.progress += 10; |
| const detected = Math.random() < 0.7; |
| if (detected) { |
| state.alertLevel = 100; |
| checkAchievementProgress('full_alert', state); |
| checkAchievementProgress('patrol_baiter', state); |
| return "The patrol definitely saw you! They're raising the alarm!"; |
| } else { |
| return "Against all odds, you sped past the patrol without being detected!"; |
| } |
| } |
| } |
| ] |
| }, |
| { |
| name: "Troop Morale Crisis", |
| description: "Your men are freezing and exhausted. Some are talking about turning back.", |
| conditions: (state) => state.morale < 50 && Math.random() < 0.5, |
| choices: [ |
| { |
| text: "Give an inspiring speech", |
| effect: (state) => { |
| const success = Math.random() > 0.3; |
| if (success) { |
| state.morale += 30; |
| return '"These are the times that try men\'s souls..." Your speech rallied the troops!'; |
| } else { |
| state.morale -= 10; |
| return "Your words fell flat. The men remain discouraged."; |
| } |
| } |
| }, |
| { |
| text: "Promise extra rations", |
| effect: (state) => { |
| state.morale += 15; |
| return "The promise of extra food lifted spirits somewhat, but you'll need to deliver later."; |
| } |
| }, |
| { |
| text: "Threaten punishment", |
| effect: (state) => { |
| state.morale -= 20; |
| if (state.morale <= 0) { |
| state.morale = 0; |
| checkAchievementProgress('frozen_fingers', state); |
| } |
| return "The threats worked to keep order, but the men resent you for it."; |
| } |
| } |
| ] |
| }, |
| { |
| name: "Navigation Error", |
| description: "Your navigator reports you've drifted off course in the storm.", |
| conditions: (state) => state.progress > 20 && state.progress < 80 && Math.random() < 0.25, |
| choices: [ |
| { |
| text: "Correct course immediately", |
| effect: (state) => { |
| state.progress -= 8; |
| state.morale -= 5; |
| return "You corrected course but lost valuable time doing so."; |
| } |
| }, |
| { |
| text: "Press on and adjust gradually", |
| effect: (state) => { |
| const success = Math.random() > 0.5; |
| if (success) { |
| state.progress += 5; |
| return "Your gradual correction worked! You're back on course."; |
| } else { |
| state.progress -= 15; |
| state.morale -= 10; |
| return "The error compounded and you're now further off course than before!"; |
| } |
| } |
| } |
| ] |
| }, |
| { |
| name: "Secret Route Discovery", |
| description: "Your scouts report finding a hidden path through the ice. It's risky but could save time.", |
| conditions: (state) => state.secretRoute && state.progress > 40 && state.progress < 60 && Math.random() < 0.5, |
| choices: [ |
| { |
| text: "Take the secret route", |
| effect: (state) => { |
| const success = Math.random() > 0.4; |
| if (success) { |
| state.progress += 25; |
| unlockAchievement('secret_route', state); |
| return "The secret route worked perfectly! You've gained significant ground."; |
| } else { |
| state.troops -= Math.floor(Math.random() * 200) + 50; |
| state.morale -= 20; |
| return "The route was a trap! You lost many troops in the ambush."; |
| } |
| } |
| }, |
| { |
| text: "Stick to the original plan", |
| effect: (state) => { |
| state.progress += 2; |
| return "You decided not to risk the unknown path. Progress is slow but steady."; |
| } |
| } |
| ] |
| } |
| ]; |
| |
| |
| function startGame(difficulty) { |
| gameState = { |
| difficulty, |
| crossingTime: 'dusk', |
| boatStrategy: 'few', |
| secretRoute: document.getElementById('secret-route').checked, |
| progress: 0, |
| visibility: 50, |
| alertLevel: 20, |
| morale: 80, |
| troops: 2400, |
| events: [], |
| iceFloes: [], |
| patrols: [], |
| startTime: null, |
| endTime: null, |
| eventCooldown: 0, |
| eventTimer: null, |
| eventTimeLeft: 5, |
| achievements: [], |
| secretsFound: [], |
| score: 0 |
| }; |
| |
| document.getElementById('title-screen').classList.add('hidden'); |
| document.getElementById('strategy-screen').classList.remove('hidden'); |
| |
| |
| const weather = weatherConditions[difficulty]; |
| document.getElementById('weather-text').textContent = weather.description; |
| |
| |
| document.getElementById('secret-route').checked = false; |
| } |
| |
| |
| function showInstructions() { |
| document.getElementById('title-screen').classList.add('hidden'); |
| document.getElementById('instructions-screen').classList.remove('hidden'); |
| } |
| |
| |
| function hideInstructions() { |
| document.getElementById('instructions-screen').classList.add('hidden'); |
| document.getElementById('title-screen').classList.remove('hidden'); |
| } |
| |
| |
| function showAchievements() { |
| document.getElementById('title-screen').classList.add('hidden'); |
| document.getElementById('achievements-screen').classList.remove('hidden'); |
| |
| |
| loadAchievements(); |
| } |
| |
| |
| function hideAchievements() { |
| document.getElementById('achievements-screen').classList.add('hidden'); |
| document.getElementById('title-screen').classList.remove('hidden'); |
| } |
| |
| |
| function loadAchievements() { |
| const savedAchievements = localStorage.getItem('achievements'); |
| const savedSecrets = localStorage.getItem('secrets'); |
| |
| if (savedAchievements) { |
| gameState.achievements = JSON.parse(savedAchievements); |
| } |
| |
| if (savedSecrets) { |
| gameState.secretsFound = JSON.parse(savedSecrets); |
| } |
| |
| |
| updateAchievementsDisplay(); |
| } |
| |
| |
| function updateAchievementsDisplay() { |
| const container = document.getElementById('achievements-container'); |
| const secretContainer = document.getElementById('secret-achievements-container'); |
| |
| container.innerHTML = ''; |
| secretContainer.innerHTML = ''; |
| |
| achievements.forEach(ach => { |
| const earned = gameState.achievements.includes(ach.id) || |
| (ach.secret && gameState.secretsFound.includes(ach.id)); |
| |
| const achievementDiv = document.createElement('div'); |
| achievementDiv.className = `achievement-badge p-3 rounded-lg flex items-center ${earned ? ach.color : 'bg-gray-600'} ${earned ? '' : 'opacity-60'}`; |
| |
| achievementDiv.innerHTML = ` |
| <div class="mr-3 text-2xl"> |
| <i class="fas ${ach.icon}"></i> |
| </div> |
| <div> |
| <div class="font-bold">${ach.title}</div> |
| <div class="text-sm">${earned ? ach.description : (ach.secret ? '???' : ach.description)}</div> |
| ${earned ? '<div class="text-xs mt-1"><i class="fas fa-check"></i> Unlocked</div>' : ''} |
| </div> |
| `; |
| |
| if (ach.secret) { |
| if (earned) { |
| secretContainer.appendChild(achievementDiv); |
| } else { |
| |
| const secretDiv = document.createElement('div'); |
| secretDiv.className = 'achievement-badge p-3 rounded-lg flex items-center bg-gray-700 opacity-60'; |
| secretDiv.innerHTML = ` |
| <div class="mr-3 text-2xl"> |
| <i class="fas fa-lock"></i> |
| </div> |
| <div> |
| <div class="font-bold">Secret Achievement</div> |
| <div class="text-sm">???</div> |
| </div> |
| `; |
| secretContainer.appendChild(secretDiv); |
| } |
| } else { |
| container.appendChild(achievementDiv); |
| } |
| }); |
| } |
| |
| |
| function saveAchievements() { |
| localStorage.setItem('achievements', JSON.stringify(gameState.achievements)); |
| localStorage.setItem('secrets', JSON.stringify(gameState.secretsFound)); |
| } |
| |
| |
| function unlockAchievement(id, state) { |
| const achievement = achievements.find(a => a.id === id); |
| if (!achievement) return; |
| |
| |
| if ((!achievement.secret && state.achievements.includes(id)) || |
| (achievement.secret && state.secretsFound.includes(id))) { |
| return; |
| } |
| |
| |
| if (achievement.secret) { |
| state.secretsFound.push(id); |
| } else { |
| state.achievements.push(id); |
| } |
| |
| |
| saveAchievements(); |
| |
| |
| showAchievementToast(achievement); |
| |
| |
| if (!achievement.secret) { |
| const standardAchievements = achievements.filter(a => !a.secret && a.id !== 'washington_reborn'); |
| const hasAll = standardAchievements.every(a => state.achievements.includes(a.id)); |
| |
| if (hasAll && !state.achievements.includes('washington_reborn')) { |
| unlockAchievement('washington_reborn', state); |
| } |
| } |
| } |
| |
| |
| function checkAchievementProgress(id, state) { |
| |
| unlockAchievement(id, state); |
| } |
| |
| |
| function showAchievementToast(achievement) { |
| const toast = document.getElementById('achievement-toast'); |
| const title = document.getElementById('toast-title'); |
| const desc = document.getElementById('toast-description'); |
| |
| title.textContent = achievement.title; |
| desc.textContent = achievement.description; |
| |
| toast.classList.remove('hidden'); |
| toast.classList.remove('translate-x-full'); |
| |
| |
| if (achievement.secret) { |
| toast.classList.add('glow'); |
| } else { |
| toast.classList.remove('glow'); |
| } |
| |
| |
| setTimeout(() => { |
| toast.classList.add('translate-x-full'); |
| setTimeout(() => toast.classList.add('hidden'), 300); |
| }, 5000); |
| } |
| |
| |
| function beginCrossing() { |
| |
| gameState.crossingTime = document.querySelector('input[name="time"]:checked').value; |
| gameState.boatStrategy = document.querySelector('input[name="boats"]:checked').value; |
| gameState.secretRoute = document.getElementById('secret-route').checked; |
| |
| |
| if (gameState.crossingTime === 'midnight') { |
| gameState.visibility = 30; |
| gameState.morale -= 10; |
| } else if (gameState.crossingTime === 'dawn') { |
| gameState.visibility = 70; |
| } |
| |
| if (gameState.boatStrategy === 'moderate') { |
| |
| } else if (gameState.boatStrategy === 'many') { |
| gameState.visibility += 20; |
| } |
| |
| |
| gameState.startTime = new Date(); |
| |
| |
| document.getElementById('strategy-screen').classList.add('hidden'); |
| document.getElementById('crossing-screen').classList.remove('hidden'); |
| |
| |
| gameLoop(); |
| |
| |
| if (gameState.difficulty === 'hard') { |
| createSnowEffect(); |
| } |
| |
| |
| createIceFloes(); |
| |
| |
| createPatrols(); |
| } |
| |
| |
| function createIceFloes() { |
| const riverContainer = document.getElementById('river-container'); |
| const weather = weatherConditions[gameState.difficulty]; |
| |
| for (let i = 0; i < weather.ice; i++) { |
| const ice = document.createElement('div'); |
| ice.classList.add('ice-floe'); |
| |
| const size = Math.random() * 40 + 20; |
| ice.style.width = `${size}px`; |
| ice.style.height = `${size}px`; |
| |
| ice.style.left = `${Math.random() * 90 + 5}%`; |
| ice.style.top = `${Math.random() * 60 + 10}%`; |
| |
| riverContainer.appendChild(ice); |
| } |
| } |
| |
| |
| function createPatrols() { |
| const riverContainer = document.getElementById('river-container'); |
| const patrolCount = gameState.difficulty === 'easy' ? 2 : |
| gameState.difficulty === 'medium' ? 4 : 6; |
| |
| for (let i = 0; i < patrolCount; i++) { |
| const patrol = document.createElement('div'); |
| patrol.classList.add('patrol'); |
| |
| patrol.style.left = `${Math.random() * 90 + 5}%`; |
| patrol.style.top = `${Math.random() * 60 + 10}%`; |
| |
| |
| const duration = Math.random() * 10 + 10; |
| patrol.style.animation = `wave ${duration}s infinite linear`; |
| |
| riverContainer.appendChild(patrol); |
| } |
| } |
| |
| |
| function gameLoop() { |
| |
| const speed = getCrossingSpeed(); |
| gameState.progress += speed; |
| |
| |
| updateUI(); |
| |
| |
| checkForEvents(); |
| |
| |
| if (gameState.eventCooldown > 0) { |
| gameState.eventCooldown--; |
| } |
| |
| |
| if (gameState.progress >= 100) { |
| endGame(true); |
| return; |
| } |
| |
| if (gameState.alertLevel >= 100) { |
| endGame(false, "The British have spotted you! The element of surprise is lost."); |
| return; |
| } |
| |
| if (gameState.morale <= 0) { |
| endGame(false, "Your troops mutinied and refused to continue!"); |
| return; |
| } |
| |
| if (gameState.troops <= 0) { |
| endGame(false, "You've lost all your troops! The crossing has failed."); |
| return; |
| } |
| |
| |
| setTimeout(gameLoop, 200); |
| } |
| |
| |
| function getCrossingSpeed() { |
| let speed = 0.5; |
| |
| |
| if (gameState.boatStrategy === 'moderate') { |
| speed = 0.8; |
| } else if (gameState.boatStrategy === 'many') { |
| speed = 1.2; |
| } |
| |
| |
| const weather = weatherConditions[gameState.difficulty]; |
| speed *= 1 - (weather.wind / 100); |
| |
| |
| speed *= gameState.morale / 100; |
| |
| |
| speed *= (0.9 + Math.random() * 0.2); |
| |
| return speed; |
| } |
| |
| |
| function updateUI() { |
| |
| const progressBar = document.getElementById('progress-bar'); |
| const clampedProgress = Math.min(100, Math.max(0, gameState.progress)); |
| progressBar.style.width = `${clampedProgress}%`; |
| document.getElementById('distance-text').textContent = `${Math.floor(clampedProgress)}%`; |
| |
| |
| const boat = document.getElementById('boat'); |
| const riverWidth = document.getElementById('river-container').offsetWidth; |
| const boatPosition = (riverWidth - 64) * (clampedProgress / 100); |
| boat.style.left = `${boatPosition}px`; |
| |
| |
| document.getElementById('visibility-value').textContent = |
| gameState.visibility < 40 ? 'Low' : |
| gameState.visibility < 70 ? 'Medium' : 'High'; |
| |
| document.getElementById('alert-value').textContent = |
| gameState.alertLevel < 40 ? 'Low' : |
| gameState.alertLevel < 70 ? 'Medium' : 'High'; |
| |
| document.getElementById('morale-value').textContent = |
| gameState.morale < 40 ? 'Low' : |
| gameState.morale < 70 ? 'Medium' : 'High'; |
| |
| document.getElementById('troops-value').textContent = gameState.troops; |
| |
| |
| document.getElementById('visibility-value').className = 'font-bold text-lg ' + |
| (gameState.visibility < 40 ? 'text-green-500' : |
| gameState.visibility < 70 ? 'text-yellow-500' : 'text-red-500'); |
| |
| document.getElementById('alert-value').className = 'font-bold text-lg ' + |
| (gameState.alertLevel < 40 ? 'text-green-500' : |
| gameState.alertLevel < 70 ? 'text-yellow-500' : 'text-red-500'); |
| |
| document.getElementById('morale-value').className = 'font-bold text-lg ' + |
| (gameState.morale < 40 ? 'text-red-500' : |
| gameState.morale < 70 ? 'text-yellow-500' : 'text-green-500'); |
| } |
| |
| |
| function checkForEvents() { |
| if (gameState.eventCooldown > 0) return; |
| |
| |
| for (const event of events) { |
| if (event.conditions(gameState)) { |
| triggerEvent(event); |
| gameState.eventCooldown = 20; |
| return; |
| } |
| } |
| } |
| |
| |
| function triggerEvent(event) { |
| const eventDisplay = document.getElementById('event-display'); |
| document.getElementById('event-title').textContent = event.name; |
| document.getElementById('event-description').textContent = event.description; |
| |
| |
| const choicesContainer = document.getElementById('event-choices'); |
| choicesContainer.innerHTML = ''; |
| |
| |
| gameState.eventTimeLeft = 5; |
| updateEventTimer(); |
| |
| if (gameState.eventTimer) { |
| clearInterval(gameState.eventTimer); |
| } |
| |
| gameState.eventTimer = setInterval(() => { |
| gameState.eventTimeLeft -= 0.1; |
| updateEventTimer(); |
| |
| if (gameState.eventTimeLeft <= 0) { |
| clearInterval(gameState.eventTimer); |
| eventTimeout(event); |
| } |
| }, 100); |
| |
| |
| event.choices.forEach((choice, index) => { |
| const button = document.createElement('button'); |
| button.textContent = choice.text; |
| button.className = 'w-full bg-gray-600 hover:bg-gray-500 text-white font-bold py-2 px-4 rounded-lg transition'; |
| button.onclick = () => { |
| clearInterval(gameState.eventTimer); |
| const result = choice.effect(gameState); |
| document.getElementById('event-description').textContent = result; |
| |
| |
| Array.from(choicesContainer.children).forEach((child, i) => { |
| if (i !== index) child.remove(); |
| }); |
| |
| |
| const continueButton = document.createElement('button'); |
| continueButton.textContent = 'Continue'; |
| continueButton.className = 'w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-lg transition mt-2'; |
| continueButton.onclick = () => { |
| eventDisplay.classList.add('hidden'); |
| updateUI(); |
| }; |
| choicesContainer.appendChild(continueButton); |
| }; |
| choicesContainer.appendChild(button); |
| }); |
| |
| eventDisplay.classList.remove('hidden'); |
| } |
| |
| |
| function updateEventTimer() { |
| const timerBar = document.getElementById('event-timer'); |
| const timeText = document.getElementById('event-time-remaining'); |
| |
| const percentage = Math.max(0, (gameState.eventTimeLeft / 5) * 100); |
| timerBar.style.width = `${percentage}%`; |
| timeText.textContent = `${gameState.eventTimeLeft.toFixed(1)}s`; |
| |
| |
| if (gameState.eventTimeLeft < 1) { |
| timerBar.className = 'timer-bar h-2 bg-red-700 rounded-full'; |
| } else if (gameState.eventTimeLeft < 2) { |
| timerBar.className = 'timer-bar h-2 bg-red-500 rounded-full'; |
| } else if (gameState.eventTimeLeft < 3) { |
| timerBar.className = 'timer-bar h-2 bg-yellow-500 rounded-full'; |
| } else { |
| timerBar.className = 'timer-bar h-2 bg-green-500 rounded-full'; |
| } |
| } |
| |
| |
| function eventTimeout(event) { |
| const eventDisplay = document.getElementById('event-display'); |
| const choicesContainer = document.getElementById('event-choices'); |
| |
| |
| let result = "You hesitated too long! "; |
| |
| |
| const effect = Math.floor(Math.random() * 3); |
| switch(effect) { |
| case 0: |
| gameState.troops -= Math.floor(Math.random() * 100) + 50; |
| result += `The delay caused ${gameState.troops < 0 ? "many" : "some"} of your troops to be lost.`; |
| break; |
| case 1: |
| gameState.alertLevel += 30; |
| result += "The enemy spotted you during your indecision!"; |
| break; |
| case 2: |
| gameState.morale -= 25; |
| result += "Your troops lost confidence in your leadership."; |
| break; |
| } |
| |
| document.getElementById('event-description').textContent = result; |
| |
| |
| choicesContainer.innerHTML = ''; |
| |
| |
| const continueButton = document.createElement('button'); |
| continueButton.textContent = 'Continue'; |
| continueButton.className = 'w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-lg transition mt-2'; |
| continueButton.onclick = () => { |
| eventDisplay.classList.add('hidden'); |
| updateUI(); |
| }; |
| choicesContainer.appendChild(continueButton); |
| |
| |
| if (gameState.eventTimeLeft > -0.1) { |
| checkAchievementProgress('last_minute', gameState); |
| } |
| } |
| |
| |
| function endGame(success, message = null) { |
| gameState.endTime = new Date(); |
| |
| document.getElementById('crossing-screen').classList.add('hidden'); |
| document.getElementById('results-screen').classList.remove('hidden'); |
| |
| const resultTitle = document.getElementById('result-title'); |
| const resultIcon = document.getElementById('result-icon'); |
| const resultDescription = document.getElementById('result-description'); |
| const newAchievements = document.getElementById('new-achievements'); |
| |
| |
| const newAchievementsEarned = []; |
| |
| if (success) { |
| resultTitle.textContent = "Crossing Successful!"; |
| resultIcon.textContent = "🎖️"; |
| resultDescription.textContent = message || "You successfully crossed the Delaware River and surprised the Hessians at Trenton!"; |
| |
| |
| unlockAchievement('first_crossing', gameState); |
| |
| if (gameState.troops === 2400) { |
| unlockAchievement('perfect_crossing', gameState); |
| newAchievementsEarned.push('perfect_crossing'); |
| } |
| |
| if (gameState.alertLevel < 30) { |
| unlockAchievement('stealth_master', gameState); |
| newAchievementsEarned.push('stealth_master'); |
| } |
| |
| if (gameState.difficulty === 'hard') { |
| unlockAchievement('hardcore_victory', gameState); |
| newAchievementsEarned.push('hardcore_victory'); |
| } |
| |
| if (gameState.crossingTime === 'midnight') { |
| unlockAchievement('midnight_crossing', gameState); |
| newAchievementsEarned.push('midnight_crossing'); |
| } |
| |
| if (gameState.morale < 30) { |
| unlockAchievement('frozen_fingers', gameState); |
| newAchievementsEarned.push('frozen_fingers'); |
| } |
| |
| |
| const timeTaken = (gameState.endTime - gameState.startTime) / 1000; |
| if (timeTaken < 30) { |
| unlockAchievement('speed_demon', gameState); |
| newAchievementsEarned.push('speed_demon'); |
| } |
| } else { |
| resultTitle.textContent = "Crossing Failed"; |
| resultIcon.textContent = "💀"; |
| resultDescription.textContent = message || "Your crossing was detected and the element of surprise was lost."; |
| |
| |
| if (gameState.alertLevel >= 100) { |
| unlockAchievement('full_alert', gameState); |
| } |
| } |
| |
| |
| if (newAchievementsEarned.length > 0) { |
| newAchievements.classList.remove('hidden'); |
| const container = document.getElementById('achievements-earned'); |
| container.innerHTML = ''; |
| |
| newAchievementsEarned.forEach(achId => { |
| const achievement = achievements.find(a => a.id === achId); |
| if (achievement) { |
| const div = document.createElement('div'); |
| div.className = `achievement-badge p-3 rounded-lg flex items-center ${achievement.color}`; |
| div.innerHTML = ` |
| <div class="mr-3 text-2xl"> |
| <i class="fas ${achievement.icon}"></i> |
| </div> |
| <div> |
| <div class="font-bold">${achievement.title}</div> |
| <div class="text-sm">${achievement.description}</div> |
| </div> |
| `; |
| container.appendChild(div); |
| } |
| }); |
| } else { |
| newAchievements.classList.add('hidden'); |
| } |
| |
| |
| const timeTaken = (gameState.endTime - gameState.startTime) / 1000; |
| document.getElementById('stat-time').textContent = `${timeTaken.toFixed(1)} seconds`; |
| document.getElementById('stat-troops').textContent = `${2400 - gameState.troops} lost (${gameState.troops} remaining)`; |
| document.getElementById('stat-alert').textContent = |
| gameState.alertLevel < 40 ? 'Low' : |
| gameState.alertLevel < 70 ? 'Medium' : 'High'; |
| document.getElementById('stat-difficulty').textContent = |
| gameState.difficulty === 'easy' ? 'Easy' : |
| gameState.difficulty === 'medium' ? 'Standard' : 'Hardcore'; |
| document.getElementById('stat-morale').textContent = |
| gameState.morale < 40 ? 'Low' : |
| gameState.morale < 70 ? 'Medium' : 'High'; |
| |
| |
| calculateScore(success, timeTaken); |
| } |
| |
| |
| function calculateScore(success, timeTaken) { |
| if (!success) { |
| gameState.score = 0; |
| document.getElementById('stat-score').textContent = '0'; |
| return; |
| } |
| |
| let score = 1000; |
| |
| |
| score += Math.max(0, 500 - (timeTaken * 10)); |
| |
| |
| score += (gameState.troops / 2400) * 500; |
| |
| |
| score += (gameState.morale / 100) * 300; |
| |
| |
| score -= gameState.alertLevel * 2; |
| |
| |
| if (gameState.difficulty === 'medium') score *= 1.5; |
| if (gameState.difficulty === 'hard') score *= 2; |
| |
| gameState.score = Math.floor(Math.max(0, score)); |
| document.getElementById('stat-score').textContent = gameState.score; |
| } |
| |
| |
| function returnToTitle() { |
| document.getElementById('results-screen').classList.add('hidden'); |
| document.getElementById('title-screen').classList.remove('hidden'); |
| } |
| |
| |
| function createSnowEffect() { |
| const riverContainer = document.getElementById('river-container'); |
| |
| for (let i = 0; i < 50; i++) { |
| createSnowflake(riverContainer); |
| } |
| |
| setInterval(() => { |
| createSnowflake(riverContainer); |
| }, 300); |
| } |
| |
| function createSnowflake(container) { |
| const snowflake = document.createElement('div'); |
| snowflake.classList.add('snowflake'); |
| |
| const size = Math.random() * 5 + 2; |
| snowflake.style.width = `${size}px`; |
| snowflake.style.height = `${size}px`; |
| |
| snowflake.style.left = `${Math.random() * 100}%`; |
| snowflake.style.opacity = Math.random() * 0.5 + 0.3; |
| |
| const animationDuration = Math.random() * 5 + 5; |
| snowflake.style.animationDuration = `${animationDuration}s`; |
| |
| container.appendChild(snowflake); |
| |
| |
| setTimeout(() => { |
| snowflake.remove(); |
| }, animationDuration * 1000); |
| } |
| |
| |
| function initAchievements() { |
| const savedAchievements = localStorage.getItem('achievements'); |
| const savedSecrets = localStorage.getItem('secrets'); |
| |
| if (savedAchievements) { |
| gameState.achievements = JSON.parse(savedAchievements); |
| } else { |
| gameState.achievements = []; |
| } |
| |
| if (savedSecrets) { |
| gameState.secretsFound = JSON.parse(savedSecrets); |
| } else { |
| gameState.secretsFound = []; |
| } |
| } |
| |
| |
| initAchievements(); |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Hypergenius/washington-s-crossing" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |