4232 lines
250 KiB
HTML
4232 lines
250 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||
<title>English Course 10</title>
|
||
<script src="https://cdn.tailwindcss.com"></script>
|
||
<script>
|
||
tailwind.config = {
|
||
theme: {
|
||
extend: {
|
||
colors: {
|
||
surface: '#F8F9FA',
|
||
surfaceElevated: '#FFFFFF',
|
||
onSurface: '#202124',
|
||
primary: '#4285F4',
|
||
secondary: '#34A853',
|
||
tertiary: '#FBBC05',
|
||
error: '#EA4335',
|
||
outline: '#DADCE0'
|
||
},
|
||
boxShadow: {
|
||
focus: '0 0 0 3px rgba(66,133,244,.25)'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
<link href="https://fonts.googleapis.com/css2?family=Black+Ops+One&family=Carter+One&family=Fredoka:wght@400;700&family=Nunito:wght@400;600;800&display=swap" rel="stylesheet">
|
||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,1,0" rel="stylesheet">
|
||
<script src="assets_map.js"></script>
|
||
<style>
|
||
:root {
|
||
/* Palette: Playful & Modern */
|
||
--primary: #4D96FF; /* Soft Blue */
|
||
--primary-dark: #1B6ADE;
|
||
--accent: #FFD93D; /* Sunny Yellow */
|
||
--accent-dark: #E6C200;
|
||
--success: #6BCB77; /* Mint Green */
|
||
--success-dark: #3B9E59;
|
||
--danger: #FF6B6B; /* Soft Red */
|
||
--danger-dark: #D94545;
|
||
--background: #F0F4F8; /* Very light blue-grey */
|
||
--surface: #FFFFFF;
|
||
--text-main: #2D3748;
|
||
--text-light: #718096;
|
||
|
||
--shadow-sm: 0 2px 4px rgba(0,0,0,0.05);
|
||
--shadow-md: 0 4px 6px rgba(0,0,0,0.07);
|
||
--shadow-lg: 0 10px 15px rgba(0,0,0,0.1);
|
||
--shadow-xl: 0 20px 25px rgba(0,0,0,0.1);
|
||
|
||
--radius-sm: 12px;
|
||
--radius-md: 20px;
|
||
--radius-lg: 32px;
|
||
}
|
||
|
||
body {
|
||
font-family: 'Nunito', sans-serif;
|
||
background-color: var(--background);
|
||
color: var(--text-main);
|
||
overflow-y: auto;
|
||
margin: 0;
|
||
height: auto;
|
||
min-height: 100vh;
|
||
touch-action: pan-y;
|
||
user-select: none;
|
||
-webkit-user-select: none;
|
||
/* New Immersive Background */
|
||
background-image: url('assets/bg_world.jpg');
|
||
background-size: cover;
|
||
background-position: center;
|
||
background-attachment: fixed;
|
||
background-repeat: no-repeat;
|
||
}
|
||
|
||
/* Overlay to ensure text readability on busy backgrounds if needed */
|
||
body::before {
|
||
content: '';
|
||
position: fixed;
|
||
top: 0; left: 0; right: 0; bottom: 0;
|
||
background: rgba(240, 244, 248, 0.4); /* Slight tint */
|
||
backdrop-filter: blur(3px); /* Dreamy effect */
|
||
z-index: -1;
|
||
}
|
||
|
||
h1, h2, h3, .font-hero { font-family: 'Fredoka', sans-serif; font-weight: 700; text-shadow: 0 2px 4px rgba(255,255,255,0.8); }
|
||
.font-tech { font-family: 'Nunito', sans-serif; font-weight: 800; text-transform: uppercase; letter-spacing: 0.05em; }
|
||
|
||
#app {
|
||
position: relative;
|
||
width: 100%;
|
||
min-height: 100vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
max-width: 100%;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
.screen {
|
||
flex: 1;
|
||
display: none;
|
||
flex-direction: column;
|
||
padding: 20px;
|
||
animation: slideUpFade 0.6s cubic-bezier(0.16, 1, 0.3, 1); /* Slower, smoother entry */
|
||
width: 100%;
|
||
max-width: 900px; /* Slightly wider for the new layout */
|
||
margin: 0 auto;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.screen.active {
|
||
display: flex;
|
||
}
|
||
|
||
@keyframes slideUpFade {
|
||
from { opacity: 0; transform: translateY(40px) scale(0.95); }
|
||
to { opacity: 1; transform: translateY(0) scale(1); }
|
||
}
|
||
|
||
/* Modern Card Style - Glassmorphism update */
|
||
.card {
|
||
background: rgba(255, 255, 255, 0.85);
|
||
backdrop-filter: blur(12px);
|
||
border-radius: var(--radius-md);
|
||
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.15);
|
||
border: 1px solid rgba(255, 255, 255, 0.6);
|
||
padding: 24px;
|
||
transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.3s ease;
|
||
}
|
||
|
||
.card:hover {
|
||
transform: translateY(-4px);
|
||
box-shadow: 0 12px 40px 0 rgba(31, 38, 135, 0.2);
|
||
}
|
||
|
||
/* Juicy Buttons */
|
||
.btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: var(--radius-sm);
|
||
font-family: 'Fredoka', sans-serif;
|
||
font-weight: 600;
|
||
font-size: 1.1rem;
|
||
padding: 12px 24px;
|
||
cursor: pointer;
|
||
transition: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1); /* Bouncy */
|
||
border: none;
|
||
border-bottom: 5px solid rgba(0,0,0,0.15); /* Thicker bottom */
|
||
transform: translateY(0);
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.btn::after {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0; left: 0; width: 100%; height: 100%;
|
||
background: linear-gradient(rgba(255,255,255,0.2), transparent);
|
||
opacity: 0;
|
||
transition: opacity 0.2s;
|
||
}
|
||
|
||
.btn:hover::after { opacity: 1; }
|
||
|
||
.btn:active {
|
||
transform: translateY(3px);
|
||
border-bottom-width: 2px;
|
||
margin-top: 3px;
|
||
}
|
||
|
||
/* ... colors ... */
|
||
.btn-primary { background-color: var(--primary); color: white; border-bottom-color: var(--primary-dark); }
|
||
.btn-success { background-color: var(--success); color: white; border-bottom-color: var(--success-dark); }
|
||
.btn-accent { background-color: var(--accent); color: var(--text-main); border-bottom-color: var(--accent-dark); }
|
||
.btn-danger { background-color: var(--danger); color: white; border-bottom-color: var(--danger-dark); }
|
||
|
||
/* Login Hero Layout */
|
||
.login-grid {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 2rem;
|
||
align-items: center;
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.login-grid { grid-template-columns: 1fr; }
|
||
.login-hero-img { display: none; /* Hide hero on small mobile to save space, or stack it */ }
|
||
}
|
||
|
||
.floating-element {
|
||
animation: float 6s ease-in-out infinite;
|
||
}
|
||
|
||
@keyframes float {
|
||
0% { transform: translateY(0px); }
|
||
50% { transform: translateY(-15px); }
|
||
100% { transform: translateY(0px); }
|
||
}
|
||
|
||
/* Level Cards */
|
||
.level-card {
|
||
background: rgba(255, 255, 255, 0.9);
|
||
backdrop-filter: blur(8px);
|
||
border-radius: var(--radius-md);
|
||
padding: 20px;
|
||
margin-bottom: 16px;
|
||
box-shadow: var(--shadow-md);
|
||
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||
cursor: pointer;
|
||
border: 3px solid transparent;
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.level-card:hover {
|
||
transform: scale(1.03) translateY(-4px);
|
||
border-color: var(--primary);
|
||
box-shadow: var(--shadow-xl);
|
||
z-index: 10;
|
||
}
|
||
|
||
/* ... existing styles ... */
|
||
|
||
.level-card.locked {
|
||
opacity: 0.7;
|
||
background: #E2E8F0;
|
||
pointer-events: none;
|
||
filter: grayscale(1);
|
||
}
|
||
|
||
/* Progress Bar */
|
||
.progress-container {
|
||
height: 16px;
|
||
background: #E2E8F0;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
margin: 10px 0;
|
||
box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
|
||
}
|
||
|
||
.progress-fill {
|
||
height: 100%;
|
||
background: linear-gradient(90deg, var(--success), var(--primary));
|
||
border-radius: 8px;
|
||
transition: width 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||
}
|
||
|
||
/* Question Layout */
|
||
.question-card {
|
||
background: var(--surface);
|
||
border-radius: var(--radius-lg);
|
||
padding: 32px;
|
||
box-shadow: var(--shadow-xl);
|
||
text-align: center;
|
||
max-width: 600px;
|
||
margin: 20px auto;
|
||
}
|
||
|
||
.answer-grid {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 16px;
|
||
margin-top: 24px;
|
||
}
|
||
|
||
@media (max-width: 600px) {
|
||
.answer-grid { grid-template-columns: 1fr; }
|
||
.question-card { padding: 20px; }
|
||
}
|
||
|
||
.answer-btn {
|
||
background: #FFFFFF;
|
||
border: 2px solid #E2E8F0;
|
||
border-radius: var(--radius-sm);
|
||
padding: 16px;
|
||
font-size: 1.1rem;
|
||
font-weight: 600;
|
||
color: var(--text-main);
|
||
transition: all 0.2s;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
min-height: 60px;
|
||
}
|
||
|
||
.answer-btn:hover {
|
||
border-color: var(--primary);
|
||
background: #F7FAFC;
|
||
transform: translateY(-2px);
|
||
box-shadow: var(--shadow-md);
|
||
}
|
||
|
||
.answer-btn.correct {
|
||
background: var(--success);
|
||
border-color: var(--success-dark);
|
||
color: white;
|
||
animation: pop 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||
}
|
||
|
||
.answer-btn.incorrect {
|
||
background: var(--danger);
|
||
border-color: var(--danger-dark);
|
||
color: white;
|
||
animation: shake 0.5s ease;
|
||
}
|
||
|
||
@keyframes pop {
|
||
0% { transform: scale(1); }
|
||
50% { transform: scale(1.1); }
|
||
100% { transform: scale(1); }
|
||
}
|
||
|
||
@keyframes shake {
|
||
0%, 100% { transform: translateX(0); }
|
||
20%, 60% { transform: translateX(-6px); }
|
||
40%, 80% { transform: translateX(6px); }
|
||
}
|
||
|
||
/* Mascot */
|
||
.mascot {
|
||
position: fixed;
|
||
bottom: 20px;
|
||
right: 20px;
|
||
width: 140px;
|
||
height: 140px;
|
||
background-image: url('assets/mascot_main.svg');
|
||
background-size: contain;
|
||
background-repeat: no-repeat;
|
||
background-position: center;
|
||
filter: drop-shadow(0 4px 8px rgba(0,0,0,0.2));
|
||
z-index: 100;
|
||
transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||
pointer-events: none;
|
||
}
|
||
|
||
.mascot:hover { transform: scale(1.1) rotate(5deg); }
|
||
|
||
.mascot-message {
|
||
position: fixed;
|
||
bottom: 140px;
|
||
right: 30px;
|
||
background: var(--surface);
|
||
padding: 16px;
|
||
border-radius: 16px;
|
||
border-bottom-right-radius: 4px;
|
||
box-shadow: var(--shadow-lg);
|
||
max-width: 250px;
|
||
font-size: 1rem;
|
||
color: var(--text-main);
|
||
z-index: 99;
|
||
animation: slideInUp 0.3s ease-out;
|
||
pointer-events: none;
|
||
}
|
||
|
||
@keyframes slideInUp {
|
||
from { opacity: 0; transform: translateY(10px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
.image-wrap { position: relative; display: inline-block; border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--shadow-md); background: white; padding: 10px; }
|
||
.image-wrap img { display: block; }
|
||
.report-dot { position: absolute; top: 10px; right: 10px; width: 24px; height: 24px; border-radius: 50%; background: var(--danger); border: 2px solid white; cursor: pointer; z-index: 20; display: flex; align-items: center; justify-content: center; color: white; font-size: 12px; font-weight: bold; opacity: 0; transition: opacity 0.2s; }
|
||
.image-wrap:hover .report-dot { opacity: 1; }
|
||
|
||
/* Utilities */
|
||
.text-gradient { background: linear-gradient(135deg, var(--primary), var(--success)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
|
||
|
||
/* Floating notification */
|
||
.achievement-notification {
|
||
position: fixed;
|
||
top: 24px;
|
||
right: 24px; /* Default position */
|
||
left: 50%; /* Center horizontally */
|
||
transform: translateX(-50%); /* Adjust for centering */
|
||
background: var(--surface);
|
||
border-left: 6px solid var(--accent);
|
||
border-radius: 12px;
|
||
padding: 16px 24px;
|
||
box-shadow: var(--shadow-xl);
|
||
z-index: 2000;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
min-width: 300px;
|
||
animation: slideDown 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||
}
|
||
|
||
/* Override specific positioning for desktop if needed, but centering is safe for mobile */
|
||
@media (min-width: 768px) {
|
||
.achievement-notification {
|
||
left: auto;
|
||
right: 24px;
|
||
transform: none;
|
||
}
|
||
}
|
||
|
||
@keyframes slideDown {
|
||
from { transform: translateY(-100%); opacity: 0; }
|
||
to { transform: translateY(0); opacity: 1; }
|
||
}
|
||
|
||
.secret-input {
|
||
background: #F7FAFC;
|
||
border: 2px solid #E2E8F0;
|
||
border-radius: var(--radius-sm);
|
||
color: var(--text-main);
|
||
padding: 12px;
|
||
font-family: 'Black Ops One', monospace; /* Keep for effect */
|
||
font-size: 1.2rem;
|
||
text-align: center;
|
||
letter-spacing: 2px;
|
||
width: 100%;
|
||
transition: all 0.2s;
|
||
}
|
||
.secret-input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(77, 150, 255, 0.2); }
|
||
|
||
</style>
|
||
</head>
|
||
<body class="bg-[#FDFCF5] text-onSurface min-h-screen">
|
||
<div id="app">
|
||
<nav class="w-full bg-surfaceElevated backdrop-blur border-b border-outline">
|
||
<div class="max-w-6xl mx-auto px-4 py-3 flex items-center justify-between">
|
||
<div class="flex items-center gap-2">
|
||
<span class="text-2xl font-hero text-tertiary">ENGLISH COURSE 10</span>
|
||
<span class="ml-3 text-sm text-onSurface/70">Total immersion, friendly guidance</span>
|
||
</div>
|
||
<div class="hidden md:flex items-center gap-4 text-sm">
|
||
<button onclick="GAME.goToMap()" class="px-3 py-2 rounded-md hover:bg-surface/70 flex items-center gap-2">
|
||
<span class="material-symbols-outlined text-lg">map</span> Map
|
||
</button>
|
||
<button onclick="GAME.openFocusTools()" class="px-3 py-2 rounded-md bg-primary/10 hover:bg-primary/20 border border-outline flex items-center gap-2">
|
||
<span class="material-symbols-outlined text-lg">psychology</span> Focus Tools
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
<!-- Login Screen -->
|
||
<div id="screen-login" class="screen active">
|
||
<div class="flex flex-col items-center justify-center min-h-full py-10">
|
||
|
||
<div class="card w-full max-w-5xl mx-auto mb-8 p-0 overflow-hidden">
|
||
<div class="login-grid">
|
||
<!-- Left Side: Hero Image -->
|
||
<div class="login-hero-img h-full bg-blue-50 flex items-center justify-center p-8 relative overflow-hidden">
|
||
<div class="absolute inset-0 bg-gradient-to-br from-blue-400/20 to-purple-400/20 z-0"></div>
|
||
<img src="assets/login_hero.png" alt="Welcome Friend" class="floating-element relative z-10 w-full max-w-[350px] object-contain drop-shadow-xl">
|
||
</div>
|
||
|
||
<!-- Right Side: Login Form -->
|
||
<div class="p-8 md:p-12 flex flex-col justify-center">
|
||
<div class="text-center mb-8">
|
||
<h1 class="text-4xl md:text-5xl font-hero text-primary mb-2 drop-shadow-sm tracking-wide">ENGLISH<br>COURSE 10</h1>
|
||
<p class="text-text-light text-lg font-medium mt-2">Start your adventure! / Начни приключение!</p>
|
||
</div>
|
||
|
||
<h2 class="text-2xl font-bold text-center mb-6 text-text-main">WHO ARE YOU? / КТО ТЫ?</h2>
|
||
|
||
<label class="flex items-center justify-center mb-6 cursor-pointer text-text-light hover:text-primary transition group">
|
||
<div class="w-6 h-6 border-2 border-gray-300 rounded-md mr-3 flex items-center justify-center transition group-hover:border-primary bg-white">
|
||
<input type="checkbox" id="has-code" class="opacity-0 w-0 h-0">
|
||
<span class="material-symbols-outlined text-lg opacity-0 text-primary transition" id="check-icon">check</span>
|
||
</div>
|
||
<span class="font-bold">I have a secret code / У меня есть код</span>
|
||
</label>
|
||
|
||
<div id="login-new" class="space-y-4">
|
||
<input type="text" id="username" placeholder="Your Name / Твоё Имя"
|
||
class="secret-input text-left font-sans font-bold placeholder-gray-400 bg-gray-50 border-gray-200 focus:bg-white focus:border-primary text-lg h-14">
|
||
<input type="number" id="age" placeholder="Your Age / Твой Возраст" min="6" max="15"
|
||
class="secret-input text-left font-sans font-bold placeholder-gray-400 bg-gray-50 border-gray-200 focus:bg-white focus:border-primary text-lg h-14">
|
||
</div>
|
||
|
||
<div id="login-existing" style="display:none;" class="space-y-4">
|
||
<input type="text" id="login-secret-code" placeholder="Secret Code / Секретный Код" maxlength="16"
|
||
class="secret-input text-left font-sans font-bold placeholder-gray-400 bg-gray-50 border-gray-200 focus:bg-white focus:border-primary text-lg h-14">
|
||
</div>
|
||
|
||
<button onclick="GAME.login()" class="btn btn-primary w-full text-xl py-4 mt-8 shadow-lg hover:shadow-xl transform transition-all">
|
||
<span class="material-symbols-outlined mr-2">rocket_launch</span>
|
||
START / НАЧАТЬ
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 w-full max-w-5xl px-4">
|
||
<div class="card p-6 text-center transform hover:-translate-y-2 transition-all duration-300">
|
||
<div class="w-20 h-20 mx-auto mb-4">
|
||
<img src="assets/ui/icon_learn.svg" alt="Learn" class="w-full h-full object-contain drop-shadow-md">
|
||
</div>
|
||
<div class="font-bold text-primary mb-2 text-lg">Learn Basics</div>
|
||
<div class="text-sm text-text-light">Start from zero and become a hero!</div>
|
||
</div>
|
||
<div class="card p-6 text-center transform hover:-translate-y-2 transition-all duration-300 delay-100">
|
||
<div class="w-20 h-20 mx-auto mb-4">
|
||
<img src="assets/ui/icon_speak.svg" alt="Speak" class="w-full h-full object-contain drop-shadow-md">
|
||
</div>
|
||
<div class="font-bold text-success mb-2 text-lg">Speak Up</div>
|
||
<div class="text-sm text-text-light">Talk like a pro with confidence!</div>
|
||
</div>
|
||
<div class="card p-6 text-center transform hover:-translate-y-2 transition-all duration-300 delay-200">
|
||
<div class="w-20 h-20 mx-auto mb-4">
|
||
<img src="assets/ui/icon_stories.svg" alt="Stories" class="w-full h-full object-contain drop-shadow-md">
|
||
</div>
|
||
<div class="font-bold text-accent-dark mb-2 text-lg">Explore Stories</div>
|
||
<div class="text-sm text-text-light">Discover new worlds through words!</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Placement Test Screen -->
|
||
<div id="screen-placement" class="screen">
|
||
<div class="flex flex-col h-full items-center">
|
||
<header class="text-center mb-8 w-full max-w-2xl">
|
||
<h1 class="text-3xl font-hero text-accent drop-shadow-sm">PLACEMENT TEST / ТЕСТ</h1>
|
||
<p class="text-primary font-bold mt-2">Let's find your perfect starting level!</p>
|
||
<div class="progress-container mt-4">
|
||
<div id="placement-progress" class="progress-fill" style="width: 0%"></div>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="flex-1 w-full flex flex-col items-center">
|
||
<div class="question-card w-full">
|
||
<div class="flex justify-center mb-6">
|
||
<div class="image-wrap bg-white p-4 rounded-3xl shadow-sm">
|
||
<img id="placement-image" class="w-48 h-48 object-contain" alt="Question Image">
|
||
<button id="placement-report-dot" class="report-dot" aria-label="Report wrong image">!</button>
|
||
</div>
|
||
</div>
|
||
<h2 id="placement-question" class="text-2xl font-bold text-center mb-8 text-text-main"></h2>
|
||
<div id="placement-answers" class="answer-grid">
|
||
<!-- Answer buttons will be generated here -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Map Screen -->
|
||
<div id="screen-map" class="screen">
|
||
<div class="flex flex-col h-full">
|
||
<header class="text-center mb-8">
|
||
<h1 class="text-4xl font-hero text-accent drop-shadow-sm">LEVELS / УРОВНИ</h1>
|
||
<p class="text-primary mt-2 font-bold">Personalized route tailored to your goals</p>
|
||
<div class="progress-container mt-4 max-w-2xl mx-auto">
|
||
<div id="progress-fill" class="progress-fill" style="width: 0%"></div>
|
||
</div>
|
||
<div id="stats-panel" class="bg-white rounded-xl shadow-sm border border-gray-100 mt-4 inline-flex items-center px-6 py-3 gap-6">
|
||
<div class="flex items-center gap-2">
|
||
<img src="assets/ui/icon_points.svg" class="w-8 h-8 object-contain">
|
||
<span class="font-bold text-text-main">Points: <span id="points-value" class="text-primary">0</span></span>
|
||
</div>
|
||
<div class="flex items-center gap-2">
|
||
<img src="assets/ui/icon_badges.svg" class="w-8 h-8 object-contain">
|
||
<span class="font-bold text-text-main">Badges: <span id="badges-count" class="text-accent-dark">0</span></span>
|
||
</div>
|
||
<button onclick="GAME.openFocusTools()" class="btn btn-primary text-sm py-2 px-4">Focus Tools</button>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="flex-1 overflow-y-auto pb-20">
|
||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 p-4 max-w-7xl mx-auto">
|
||
<!-- Level 1: Forest -->
|
||
<div class="level-card" data-level="1">
|
||
<div class="flex items-center gap-4 mb-4">
|
||
<img src="assets/ui/level_forest.svg" class="w-16 h-16 rounded-full border-4 border-success/20">
|
||
<div>
|
||
<h3 class="text-2xl font-bold text-text-main m-0">Forest / Лес</h3>
|
||
<div class="h-2 rounded-full bg-success/20 w-32 mt-2"></div>
|
||
</div>
|
||
</div>
|
||
<div class="bg-gray-50 rounded-lg p-3 mb-2 border border-gray-100">
|
||
<span class="text-primary font-bold">Class 1A:</span> Basic Animals
|
||
</div>
|
||
<div class="bg-gray-50 rounded-lg p-3 mb-4 border border-gray-100">
|
||
<span class="text-primary font-bold">Class 1B:</span> Nature Words
|
||
</div>
|
||
<button onclick="GAME.startLevel(1)" class="btn btn-primary w-full text-lg">START / НАЧАТЬ</button>
|
||
</div>
|
||
|
||
<!-- Level 2: City -->
|
||
<div class="level-card" data-level="2">
|
||
<div class="flex items-center gap-4 mb-4">
|
||
<img src="assets/ui/level_city.svg" class="w-16 h-16 rounded-full border-4 border-primary/20">
|
||
<div>
|
||
<h3 class="text-2xl font-bold text-text-main m-0">City / Город</h3>
|
||
<div class="h-2 rounded-full bg-primary/20 w-32 mt-2"></div>
|
||
</div>
|
||
</div>
|
||
<div class="bg-gray-50 rounded-lg p-3 mb-2 border border-gray-100">
|
||
<span class="text-primary font-bold">Class 2A:</span> Buildings
|
||
</div>
|
||
<div class="bg-gray-50 rounded-lg p-3 mb-4 border border-gray-100">
|
||
<span class="text-primary font-bold">Class 2B:</span> Transportation
|
||
</div>
|
||
<button onclick="GAME.startLevel(2)" class="btn btn-success w-full text-lg">START / НАЧАТЬ</button>
|
||
</div>
|
||
|
||
<!-- Level 3: Space Station -->
|
||
<div class="level-card" data-level="3">
|
||
<div class="flex items-center gap-4 mb-4">
|
||
<img src="assets/ui/level_space.svg" class="w-16 h-16 rounded-full border-4 border-accent/20">
|
||
<div>
|
||
<h3 class="text-2xl font-bold text-text-main m-0">Space Station / Космос</h3>
|
||
<div class="h-2 rounded-full bg-accent/20 w-32 mt-2"></div>
|
||
</div>
|
||
</div>
|
||
<div class="bg-gray-50 rounded-lg p-3 mb-2 border border-gray-100">
|
||
<span class="text-primary font-bold">Class 3A:</span> Space Objects
|
||
</div>
|
||
<div class="bg-gray-50 rounded-lg p-3 mb-4 border border-gray-100">
|
||
<span class="text-primary font-bold">Class 3B:</span> Technology
|
||
</div>
|
||
<button onclick="GAME.startLevel(3)" class="btn btn-primary w-full text-lg">START / НАЧАТЬ</button>
|
||
</div>
|
||
|
||
<!-- Level 4: Secret Zone -->
|
||
<div class="level-card locked" data-level="4" id="secret-level">
|
||
<div class="flex items-center gap-4 mb-4">
|
||
<img src="assets/ui/level_secret.svg" class="w-16 h-16 rounded-full border-4 border-gray-300 grayscale opacity-70">
|
||
<h3 class="text-2xl font-bold text-text-light m-0">Secret Zone / Секретно</h3>
|
||
</div>
|
||
<div class="bg-gray-100 rounded-lg p-3 mb-2 text-text-light">
|
||
<span>Class 4A:</span> ???
|
||
</div>
|
||
<div class="bg-gray-100 rounded-lg p-3 mb-4 text-text-light">
|
||
<span>Class 4B:</span> ???
|
||
</div>
|
||
<input type="text" id="secret-code" placeholder="Enter secret code"
|
||
class="secret-input mb-4" maxlength="10">
|
||
<button onclick="GAME.checkSecretCode()" class="btn btn-accent w-full text-lg">UNLOCK / ОТКРЫТЬ</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="text-center mt-4 mb-8">
|
||
<button onclick="GAME.logout()" class="btn btn-danger">LOGOUT / ВЫХОД</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Test Screen -->
|
||
<div id="screen-test" class="screen">
|
||
<div class="flex flex-col h-full items-center">
|
||
<header class="text-center mb-6 w-full max-w-2xl">
|
||
<h1 class="text-3xl font-hero text-accent drop-shadow-sm">TEST / ТЕСТ</h1>
|
||
<div class="progress-container mt-4">
|
||
<div id="test-progress" class="progress-fill" style="width: 0%"></div>
|
||
</div>
|
||
<p class="text-text-light font-bold mt-2">Question <span id="current-question" class="text-primary">1</span> of <span id="total-questions">10</span></p>
|
||
</header>
|
||
|
||
<div class="flex-1 w-full flex flex-col items-center">
|
||
<div class="question-card w-full">
|
||
<div class="flex justify-center mb-6">
|
||
<div class="image-wrap bg-white p-4 rounded-3xl shadow-sm">
|
||
<img id="question-image" class="w-48 h-48 object-contain" alt="Question Image">
|
||
<button id="question-report-dot" class="report-dot" aria-label="Report wrong image">!</button>
|
||
</div>
|
||
</div>
|
||
|
||
<h2 id="question-text" class="text-2xl font-bold text-center mb-4 text-text-main"></h2>
|
||
|
||
<!-- Hint Section -->
|
||
<div id="hint-controls" class="mb-6 flex justify-center">
|
||
<button id="hint-btn" class="btn btn-accent text-sm py-2 px-6 rounded-full shadow-sm hover:shadow-md transition-all flex items-center gap-2">
|
||
<span class="material-symbols-outlined text-lg">lightbulb</span>
|
||
SHOW HINT / ПОДСКАЗКА
|
||
</button>
|
||
</div>
|
||
<div id="hint-area" class="text-center mb-6 p-4 bg-yellow-50 text-orange-800 rounded-xl border border-yellow-200 font-medium hidden"></div>
|
||
|
||
<div id="answers-container" class="answer-grid">
|
||
<!-- Answer buttons will be generated here -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="text-center mb-8">
|
||
<button onclick="GAME.goToMap()" class="btn btn-secondary text-sm">BACK TO MAP / НАЗАД</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Mascot -->
|
||
<div id="mascot" class="mascot">🤖</div>
|
||
<div id="mascot-message" class="mascot-message" style="display: none;"></div>
|
||
|
||
<!-- Focus Tools Dialog (Radix-style) -->
|
||
<div id="focus-overlay" class="fixed inset-0 bg-black/50 hidden items-start justify-center" role="dialog" aria-modal="true" aria-labelledby="focus-title">
|
||
<div id="focus-panel" class="bg-surfaceElevated border border-outline rounded-2xl p-6 shadow-xl mt-24 w-[95%] max-w-3xl">
|
||
<div class="flex items-center justify-between mb-4">
|
||
<h3 id="focus-title" class="text-2xl font-tech text-primary">Focus Tools / Инструменты фокуса</h3>
|
||
<button onclick="GAME.closeFocusTools()" class="px-3 py-2 rounded-md bg-primary/10 hover:bg-primary/20 border border-outline">Close</button>
|
||
</div>
|
||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
<div>
|
||
<label class="block mb-2"><input type="checkbox" id="toggle-focus" class="mr-2">Focus Mode</label>
|
||
<label class="block mb-2"><input type="checkbox" id="toggle-motion" class="mr-2">Reduce Motion</label>
|
||
<label class="block mb-2"><input type="checkbox" id="toggle-dnd" class="mr-2">Do Not Disturb</label>
|
||
</div>
|
||
<div>
|
||
<div class="mb-2">
|
||
<select id="music-type" class="secret-input w-full">
|
||
<option value="white">White Noise</option>
|
||
<option value="brown">Brown Noise</option>
|
||
<option value="binaural">Binaural Beats</option>
|
||
</select>
|
||
</div>
|
||
<div class="mb-2">
|
||
<input id="music-volume" type="range" min="0" max="1" step="0.05" value="0.2" class="w-full"/>
|
||
</div>
|
||
<div class="mb-2">
|
||
<input id="music-mins" type="number" min="5" max="60" value="20" class="secret-input w-full" placeholder="Minutes"/>
|
||
</div>
|
||
<div class="mb-2 grid grid-cols-3 gap-2">
|
||
<input id="work-mins" type="number" min="5" max="45" value="20" class="secret-input" placeholder="Work"/>
|
||
<input id="break-mins" type="number" min="3" max="15" value="5" class="secret-input" placeholder="Break"/>
|
||
<select id="pace" class="secret-input">
|
||
<option value="normal">Pace: Normal</option>
|
||
<option value="slow">Pace: Slow</option>
|
||
<option value="fast">Pace: Fast</option>
|
||
</select>
|
||
</div>
|
||
<div class="flex flex-wrap gap-2">
|
||
<button id="music-start" class="rune-btn">Start Audio</button>
|
||
<button id="music-stop" class="rune-btn">Stop Audio</button>
|
||
<button id="pom-start" class="rune-btn">Start Pomodoro</button>
|
||
<button id="pom-stop" class="rune-btn">Stop Pomodoro</button>
|
||
</div>
|
||
<div id="pom-status" class="text-brand-blue mt-2">Pomodoro: idle</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="secret-code-overlay" class="fixed inset-0 bg-black/60 hidden items-center justify-center" role="dialog" aria-modal="true" aria-labelledby="secret-code-label">
|
||
<div class="modal-anim bg-white border border-outline rounded-3xl shadow-xl w-[92%] max-w-md p-8 text-center">
|
||
<h3 id="secret-code-label" class="text-2xl font-extrabold mb-3 text-[#FFD93D]"></h3>
|
||
<div id="secret-code-value" class="text-3xl font-extrabold tracking-wider mb-6 text-onSurface"></div>
|
||
<div class="flex items-center justify-center gap-3">
|
||
<button id="secret-code-copy" class="w-32 h-12 rounded-2xl bg-[#6BCB77] text-white font-extrabold" style="border-bottom:4px solid #3B9E59">Copy / Скопировать</button>
|
||
<button id="secret-code-close" class="w-32 h-12 rounded-2xl bg-[#4D96FF] text-white font-extrabold" style="border-bottom:4px solid #1B6ADE">Close</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// Game State
|
||
const GAME = {
|
||
user: null,
|
||
currentLevel: null,
|
||
currentQuestion: 0,
|
||
score: 0,
|
||
secretCode: 'ENGLISH10',
|
||
imageCache: {},
|
||
imageURLs: {},
|
||
|
||
// Placement Test Questions
|
||
PLACEMENT_QUESTIONS: [
|
||
{
|
||
question: "What is your name? / Как тебя зовут?",
|
||
answers: ["My name is...", "I am...", "He/She is...", "What is your name?"],
|
||
correct: 0,
|
||
imageKey: "question"
|
||
},
|
||
{
|
||
question: "How old are you? / Сколько тебе лет?",
|
||
answers: ["6-8 years", "9-10 years", "11-12 years", "13+ years"],
|
||
correct: 1,
|
||
imageKey: "age"
|
||
},
|
||
{
|
||
question: "What color is the sky? / Какого цвета небо?",
|
||
answers: ["Red", "Blue", "Green", "Yellow"],
|
||
correct: 1,
|
||
imageKey: "sky"
|
||
},
|
||
{
|
||
question: "What animal says 'meow'? / Какое животное говорит 'мяу'?",
|
||
answers: ["Dog", "Cat", "Bird", "Fish"],
|
||
correct: 1,
|
||
imageKey: "cat"
|
||
},
|
||
{
|
||
question: "What number comes after 5? / Какое число идет после 5?",
|
||
answers: ["4", "6", "7", "8"],
|
||
correct: 1,
|
||
imageKey: "number"
|
||
}
|
||
],
|
||
|
||
// Test Questions Database
|
||
QUESTIONS: {
|
||
1: { // Forest Level - 45 questions total (3 groups of 15)
|
||
groupA: [
|
||
{
|
||
question: "What animal says 'woof'?",
|
||
answers: ["Dog", "Cat", "Bird", "Fish"],
|
||
correct: 0,
|
||
imageKey: "dog"
|
||
},
|
||
{
|
||
question: "What color are leaves?",
|
||
answers: ["Red", "Blue", "Green", "Yellow"],
|
||
correct: 2,
|
||
imageKey: "leaf"
|
||
},
|
||
{
|
||
question: "Where do birds live?",
|
||
answers: ["In water", "In nests", "In ground", "In caves"],
|
||
correct: 1,
|
||
imageKey: "bird"
|
||
},
|
||
{
|
||
question: "What animal says 'meow'?",
|
||
answers: ["Dog", "Cat", "Lion", "Tiger"],
|
||
correct: 1,
|
||
imageKey: "cat"
|
||
},
|
||
{
|
||
question: "What do cows say?",
|
||
answers: ["Moo", "Baa", "Roar", "Hiss"],
|
||
correct: 0,
|
||
imageKey: "cow"
|
||
},
|
||
{
|
||
question: "What animal flies?",
|
||
answers: ["Eagle", "Dog", "Cat", "Fish"],
|
||
correct: 0,
|
||
imageKey: "eagle"
|
||
},
|
||
{
|
||
question: "What animal lives in water?",
|
||
answers: ["Lion", "Fish", "Elephant", "Monkey"],
|
||
correct: 1,
|
||
imageKey: "fish"
|
||
},
|
||
{
|
||
question: "What animal has stripes?",
|
||
answers: ["Lion", "Tiger", "Elephant", "Bear"],
|
||
correct: 1,
|
||
imageKey: "tiger"
|
||
},
|
||
{
|
||
question: "What animal is king of jungle?",
|
||
answers: ["Lion", "Tiger", "Elephant", "Monkey"],
|
||
correct: 0,
|
||
imageKey: "lion"
|
||
},
|
||
{
|
||
question: "What animal eats bananas?",
|
||
answers: ["Dog", "Cat", "Monkey", "Bird"],
|
||
correct: 2,
|
||
imageKey: "monkey"
|
||
},
|
||
{
|
||
question: "What animal gives milk?",
|
||
answers: ["Cow", "Pig", "Chicken", "Sheep"],
|
||
correct: 0,
|
||
imageKey: "cow"
|
||
},
|
||
{
|
||
question: "What animal has trunk?",
|
||
answers: ["Lion", "Tiger", "Elephant", "Bear"],
|
||
correct: 2,
|
||
imageKey: "elephant"
|
||
},
|
||
{
|
||
question: "What animal hops?",
|
||
answers: ["Kangaroo", "Rabbit", "Dog", "Cat"],
|
||
correct: 0,
|
||
imageKey: "kangaroo"
|
||
},
|
||
{
|
||
question: "What animal is wise?",
|
||
answers: ["Owl", "Eagle", "Parrot", "Crow"],
|
||
correct: 0,
|
||
imageKey: "owl"
|
||
},
|
||
{
|
||
question: "What animal has long neck?",
|
||
answers: ["Giraffe", "Elephant", "Horse", "Zebra"],
|
||
correct: 0,
|
||
imageKey: "giraffe"
|
||
},
|
||
{
|
||
question: "What animal swims in ocean?",
|
||
answers: ["Shark", "Dolphin", "Whale", "Octopus"],
|
||
correct: 1,
|
||
imageKey: "dolphin"
|
||
},
|
||
{
|
||
question: "What animal has shell?",
|
||
answers: ["Turtle", "Snail", "Crab", "Fish"],
|
||
correct: 0,
|
||
imageKey: "turtle"
|
||
},
|
||
{
|
||
question: "What animal is black and white?",
|
||
answers: ["Panda", "Zebra", "Penguin", "Skunk"],
|
||
correct: 0,
|
||
imageKey: "panda"
|
||
}
|
||
],
|
||
groupB: [
|
||
{
|
||
question: "What do trees have?",
|
||
answers: ["Leaves", "Branches", "Roots", "Flowers"],
|
||
correct: 0,
|
||
imageKey: "tree"
|
||
},
|
||
{
|
||
question: "What falls from trees?",
|
||
answers: ["Leaves", "Snow", "Rain", "Fruit"],
|
||
correct: 0,
|
||
imageKey: "leaf"
|
||
},
|
||
{
|
||
question: "What grows from seeds?",
|
||
answers: ["Flowers", "Trees", "Grass", "Mushrooms"],
|
||
correct: 1,
|
||
imageKey: "flower"
|
||
},
|
||
{
|
||
question: "What is green and grows?",
|
||
answers: ["Grass", "Flowers", "Trees", "Rocks"],
|
||
correct: 0,
|
||
imageKey: "grass"
|
||
},
|
||
{
|
||
question: "What gives us oxygen?",
|
||
answers: ["Trees", "Cars", "Oceans", "Factories"],
|
||
correct: 0,
|
||
imageKey: "tree"
|
||
},
|
||
{
|
||
question: "What changes color in autumn?",
|
||
answers: ["Leaves", "Sky", "Grass", "Flowers"],
|
||
correct: 0,
|
||
imageKey: "autumn"
|
||
},
|
||
{
|
||
question: "What needs water to grow?",
|
||
answers: ["Plants", "Animals", "Rocks", "Buildings"],
|
||
correct: 0,
|
||
imageKey: "plant"
|
||
},
|
||
{
|
||
question: "What is in forest?",
|
||
answers: ["Trees", "Animals", "Rocks", "Rivers"],
|
||
correct: 1,
|
||
imageKey: "forest"
|
||
},
|
||
{
|
||
question: "What do bees make?",
|
||
answers: ["Honey", "Milk", "Paper", "Sound"],
|
||
correct: 0,
|
||
imageKey: "honey"
|
||
},
|
||
{
|
||
question: "What is red fruit?",
|
||
answers: ["Apple", "Banana", "Orange", "Grape"],
|
||
correct: 0,
|
||
imageKey: "apple"
|
||
},
|
||
{
|
||
question: "What is yellow fruit?",
|
||
answers: ["Banana", "Apple", "Orange", "Lemon"],
|
||
correct: 0,
|
||
imageKey: "banana"
|
||
},
|
||
{
|
||
question: "What has many seeds?",
|
||
answers: ["Watermelon", "Apple", "Orange", "Grape"],
|
||
correct: 0,
|
||
imageKey: "watermelon"
|
||
},
|
||
{
|
||
question: "What grows on vine?",
|
||
answers: ["Grapes", "Apples", "Oranges", "Tomatoes"],
|
||
correct: 0,
|
||
imageKey: "grapes"
|
||
},
|
||
{
|
||
question: "What is citrus?",
|
||
answers: ["Orange", "Apple", "Banana", "Grape"],
|
||
correct: 0,
|
||
imageKey: "orange"
|
||
}
|
||
],
|
||
groupC: [
|
||
{
|
||
question: "What is weather?",
|
||
answers: ["Sun", "Rain", "Wind", "Snow"],
|
||
correct: 0,
|
||
imageKey: "sun"
|
||
},
|
||
{
|
||
question: "What falls from sky?",
|
||
answers: ["Rain", "Snow", "Leaves", "Apples"],
|
||
correct: 0,
|
||
imageKey: "rain"
|
||
},
|
||
{
|
||
question: "What is cold?",
|
||
answers: ["Snow", "Ice", "Wind", "Rain"],
|
||
correct: 0,
|
||
imageKey: "snow"
|
||
},
|
||
{
|
||
question: "What blows?",
|
||
answers: ["Wind", "Rain", "Sun", "Clouds"],
|
||
correct: 0,
|
||
imageKey: "wind"
|
||
},
|
||
{
|
||
question: "What are clouds?",
|
||
answers: ["Water", "Ice", "Smoke", "Fire"],
|
||
correct: 0,
|
||
imageKey: "clouds"
|
||
},
|
||
{
|
||
question: "What is frozen water?",
|
||
answers: ["Ice", "Snow", "Rain", "Steam"],
|
||
correct: 0,
|
||
imageKey: "ice"
|
||
},
|
||
{
|
||
question: "What makes rainbow?",
|
||
answers: ["Rain", "Sun", "Wind", "Clouds"],
|
||
correct: 0,
|
||
imageKey: "rainbow"
|
||
},
|
||
{
|
||
question: "What is lightning?",
|
||
answers: ["Electricity", "Fire", "Light", "Sound"],
|
||
correct: 0,
|
||
imageKey: "lightning"
|
||
},
|
||
{
|
||
question: "What is fog?",
|
||
answers: ["Clouds", "Rain", "Wind", "Smoke"],
|
||
correct: 0,
|
||
imageKey: "fog"
|
||
},
|
||
{
|
||
question: "What is temperature?",
|
||
answers: ["Hot", "Cold", "Warm", "Cool"],
|
||
correct: 0,
|
||
imageKey: "temperature"
|
||
},
|
||
{
|
||
question: "What is season?",
|
||
answers: ["Spring", "Summer", "Autumn", "Winter"],
|
||
correct: 0,
|
||
imageKey: "spring"
|
||
},
|
||
{
|
||
question: "What is thunder?",
|
||
answers: ["Sound", "Light", "Wind", "Rain"],
|
||
correct: 0,
|
||
imageKey: "thunder"
|
||
}
|
||
]
|
||
},
|
||
2: { // City Level - 45 questions total (3 groups of 15)
|
||
groupA: [
|
||
{
|
||
question: "Where do people live?",
|
||
answers: ["Hospital", "School", "House", "Store"],
|
||
correct: 2,
|
||
imageKey: "house"
|
||
},
|
||
{
|
||
question: "What drives on roads?",
|
||
answers: ["Airplane", "Car", "Boat", "Train"],
|
||
correct: 1,
|
||
imageKey: "car"
|
||
},
|
||
{
|
||
question: "Where do you learn?",
|
||
answers: ["Park", "School", "Restaurant", "Gym"],
|
||
correct: 1,
|
||
imageKey: "school"
|
||
},
|
||
{
|
||
question: "Where do doctors work?",
|
||
answers: ["Hospital", "School", "Office", "Store"],
|
||
correct: 0,
|
||
imageKey: "hospital"
|
||
},
|
||
{
|
||
question: "What has many books?",
|
||
answers: ["Library", "School", "Store", "Hospital"],
|
||
correct: 0,
|
||
imageKey: "library"
|
||
},
|
||
{
|
||
question: "Where do you buy food?",
|
||
answers: ["Store", "Market", "Farm", "Factory"],
|
||
correct: 0,
|
||
imageKey: "store"
|
||
},
|
||
{
|
||
question: "What has many classrooms?",
|
||
answers: ["School", "Hospital", "Office", "Library"],
|
||
correct: 0,
|
||
imageKey: "school"
|
||
},
|
||
{
|
||
question: "Where do you see movies?",
|
||
answers: ["Cinema", "Theater", "Park", "Library"],
|
||
correct: 0,
|
||
imageKey: "cinema"
|
||
},
|
||
{
|
||
question: "What has wheels?",
|
||
answers: ["Car", "Bicycle", "Train", "Airplane"],
|
||
correct: 0,
|
||
imageKey: "car"
|
||
},
|
||
{
|
||
question: "What flies in sky?",
|
||
answers: ["Airplane", "Bird", "Kite", "Balloon"],
|
||
correct: 0,
|
||
imageKey: "airplane"
|
||
},
|
||
{
|
||
question: "Where do you exercise?",
|
||
answers: ["Gym", "Park", "School", "Home"],
|
||
correct: 0,
|
||
imageKey: "gym"
|
||
},
|
||
{
|
||
question: "What has many beds?",
|
||
answers: ["Hospital", "Hotel", "School", "House"],
|
||
correct: 1,
|
||
imageKey: "hotel"
|
||
},
|
||
{
|
||
question: "What serves food?",
|
||
answers: ["Restaurant", "Store", "Cafe", "Factory"],
|
||
correct: 0,
|
||
imageKey: "restaurant"
|
||
},
|
||
{
|
||
question: "What has many workers?",
|
||
answers: ["Office", "Hospital", "Factory", "School"],
|
||
correct: 2,
|
||
imageKey: "office"
|
||
},
|
||
{
|
||
question: "What has many shops?",
|
||
answers: ["Market", "Mall", "Street", "Hospital"],
|
||
correct: 0,
|
||
imageKey: "market"
|
||
},
|
||
{
|
||
question: "What moves underground?",
|
||
answers: ["Subway", "Car", "Train", "Bus"],
|
||
correct: 0,
|
||
imageKey: "subway"
|
||
},
|
||
{
|
||
question: "What has many patients?",
|
||
answers: ["Hospital", "Clinic", "Office", "School"],
|
||
correct: 0,
|
||
imageKey: "hospital"
|
||
}
|
||
],
|
||
groupB: [
|
||
{
|
||
question: "What stops at red lights?",
|
||
answers: ["Car", "Bus", "Train", "Bicycle"],
|
||
correct: 0,
|
||
imageKey: "traffic"
|
||
},
|
||
{
|
||
question: "What runs on tracks?",
|
||
answers: ["Train", "Car", "Bus", "Airplane"],
|
||
correct: 0,
|
||
imageKey: "train"
|
||
},
|
||
{
|
||
question: "What has two wheels?",
|
||
answers: ["Bicycle", "Car", "Bus", "Motorcycle"],
|
||
correct: 1,
|
||
imageKey: "bicycle"
|
||
},
|
||
{
|
||
question: "What has many passengers?",
|
||
answers: ["Bus", "Car", "Train", "Airplane"],
|
||
correct: 0,
|
||
imageKey: "bus"
|
||
},
|
||
{
|
||
question: "What has wings?",
|
||
answers: ["Airplane", "Bird", "Kite", "Drone"],
|
||
correct: 0,
|
||
imageKey: "airplane"
|
||
},
|
||
{
|
||
question: "What travels on water?",
|
||
answers: ["Boat", "Car", "Train", "Airplane"],
|
||
correct: 0,
|
||
imageKey: "boat"
|
||
},
|
||
{
|
||
question: "What has sirens?",
|
||
answers: ["Ambulance", "Police", "Fire", "Taxi"],
|
||
correct: 0,
|
||
imageKey: "ambulance"
|
||
},
|
||
{
|
||
question: "What delivers mail?",
|
||
answers: ["Truck", "Car", "Bicycle", "Train"],
|
||
correct: 0,
|
||
imageKey: "truck"
|
||
},
|
||
{
|
||
question: "What carries many people?",
|
||
answers: ["Bus", "Car", "Train", "Airplane"],
|
||
correct: 0,
|
||
imageKey: "bus"
|
||
},
|
||
{
|
||
question: "What has propeller?",
|
||
answers: ["Helicopter", "Airplane", "Drone", "Boat"],
|
||
correct: 0,
|
||
imageKey: "helicopter"
|
||
},
|
||
{
|
||
question: "What has conductor?",
|
||
answers: ["Train", "Bus", "Airplane", "Car"],
|
||
correct: 0,
|
||
imageKey: "train"
|
||
},
|
||
{
|
||
question: "What has schedule?",
|
||
answers: ["Bus", "Train", "Airplane", "Boat"],
|
||
correct: 0,
|
||
imageKey: "bus"
|
||
},
|
||
{
|
||
question: "What has engine?",
|
||
answers: ["Car", "Bicycle", "Train", "Horse"],
|
||
correct: 0,
|
||
imageKey: "car"
|
||
},
|
||
{
|
||
question: "What has tickets?",
|
||
answers: ["Cinema", "Theater", "Bus", "Train"],
|
||
correct: 0,
|
||
imageKey: "tickets"
|
||
}
|
||
],
|
||
groupC: [
|
||
{
|
||
question: "What has traffic lights?",
|
||
answers: ["Street", "Highway", "Park", "Building"],
|
||
correct: 0,
|
||
imageKey: "traffic"
|
||
},
|
||
{
|
||
question: "What has sidewalks?",
|
||
answers: ["Street", "Bridge", "Park", "Building"],
|
||
correct: 0,
|
||
imageKey: "street"
|
||
},
|
||
{
|
||
question: "What has buildings?",
|
||
answers: ["City", "Forest", "Park", "Ocean"],
|
||
correct: 0,
|
||
imageKey: "city"
|
||
},
|
||
{
|
||
question: "What has crosswalks?",
|
||
answers: ["Street", "Bridge", "Park", "Building"],
|
||
correct: 0,
|
||
imageKey: "crosswalk"
|
||
},
|
||
{
|
||
question: "What has many stores?",
|
||
answers: ["Market", "Hospital", "School", "Library"],
|
||
correct: 0,
|
||
imageKey: "market"
|
||
},
|
||
{
|
||
question: "What has many cars?",
|
||
answers: ["Street", "Highway", "Park", "Building"],
|
||
correct: 0,
|
||
imageKey: "street"
|
||
},
|
||
{
|
||
question: "What has many people?",
|
||
answers: ["City", "Village", "Forest", "Farm"],
|
||
correct: 0,
|
||
imageKey: "city"
|
||
},
|
||
{
|
||
question: "What has many roads?",
|
||
answers: ["City", "Forest", "Park", "Building"],
|
||
correct: 0,
|
||
imageKey: "city"
|
||
},
|
||
{
|
||
question: "What has many buildings?",
|
||
answers: ["City", "Village", "Forest", "Farm"],
|
||
correct: 0,
|
||
imageKey: "city"
|
||
},
|
||
{
|
||
question: "What has many lights?",
|
||
answers: ["City", "Forest", "Park", "Building"],
|
||
correct: 0,
|
||
imageKey: "city"
|
||
},
|
||
{
|
||
question: "What has many shops?",
|
||
answers: ["Market", "Hospital", "School", "Library"],
|
||
correct: 0,
|
||
imageKey: "market"
|
||
},
|
||
{
|
||
question: "What has many streets?",
|
||
answers: ["City", "Village", "Forest", "Farm"],
|
||
correct: 0,
|
||
imageKey: "city"
|
||
},
|
||
{
|
||
question: "What has many homes?",
|
||
answers: ["City", "Village", "Forest", "Farm"],
|
||
correct: 0,
|
||
imageKey: "city"
|
||
}
|
||
]
|
||
},
|
||
3: { // Space Station Level - 45 questions total (3 groups of 15)
|
||
groupA: [
|
||
{
|
||
question: "What orbits the Earth?",
|
||
answers: ["Moon", "Sun", "Mars", "Venus"],
|
||
correct: 0,
|
||
imageKey: "moon"
|
||
},
|
||
{
|
||
question: "What do astronauts use?",
|
||
answers: ["Bicycle", "Rocket", "Car", "Boat"],
|
||
correct: 1,
|
||
imageKey: "rocket"
|
||
},
|
||
{
|
||
question: "What is in space?",
|
||
answers: ["Trees", "Stars", "Fish", "Buildings"],
|
||
correct: 1,
|
||
imageKey: "star"
|
||
},
|
||
{
|
||
question: "What is red planet?",
|
||
answers: ["Mars", "Venus", "Jupiter", "Saturn"],
|
||
correct: 0,
|
||
imageKey: "mars"
|
||
},
|
||
{
|
||
question: "What is biggest planet?",
|
||
answers: ["Jupiter", "Saturn", "Earth", "Mars"],
|
||
correct: 0,
|
||
imageKey: "jupiter"
|
||
},
|
||
{
|
||
question: "What has rings?",
|
||
answers: ["Saturn", "Jupiter", "Mars", "Earth"],
|
||
correct: 0,
|
||
imageKey: "saturn"
|
||
},
|
||
{
|
||
question: "What is blue planet?",
|
||
answers: ["Earth", "Mars", "Jupiter", "Saturn"],
|
||
correct: 0,
|
||
imageKey: "earth"
|
||
},
|
||
{
|
||
question: "What is closest star?",
|
||
answers: ["Sun", "Moon", "Mars", "Venus"],
|
||
correct: 0,
|
||
imageKey: "sun"
|
||
},
|
||
{
|
||
question: "What explores space?",
|
||
answers: ["Astronaut", "Pilot", "Scientist", "Engineer"],
|
||
correct: 0,
|
||
imageKey: "astronaut"
|
||
},
|
||
{
|
||
question: "What floats in space?",
|
||
answers: ["Astronaut", "Satellite", "Rocket", "Planet"],
|
||
correct: 1,
|
||
imageKey: "astronaut"
|
||
},
|
||
{
|
||
question: "What transmits signals?",
|
||
answers: ["Satellite", "Rocket", "Planet", "Star"],
|
||
correct: 0,
|
||
imageKey: "satellite"
|
||
},
|
||
{
|
||
question: "What has solar panels?",
|
||
answers: ["Satellite", "Rocket", "Planet", "Station"],
|
||
correct: 0,
|
||
imageKey: "satellite"
|
||
},
|
||
{
|
||
question: "What is space station?",
|
||
answers: ["ISS", "Hubble", "Apollo", "Sputnik"],
|
||
correct: 0,
|
||
imageKey: "station"
|
||
},
|
||
{
|
||
question: "What studies stars?",
|
||
answers: ["Telescope", "Microscope", "Rocket", "Computer"],
|
||
correct: 0,
|
||
imageKey: "telescope"
|
||
},
|
||
{
|
||
question: "What is galaxy?",
|
||
answers: ["Milky Way", "Solar System", "Universe", "Andromeda"],
|
||
correct: 0,
|
||
imageKey: "galaxy"
|
||
}
|
||
],
|
||
groupB: [
|
||
{
|
||
question: "What is computer?",
|
||
answers: ["Laptop", "Phone", "Tablet", "TV"],
|
||
correct: 0,
|
||
imageKey: "computer"
|
||
},
|
||
{
|
||
question: "What connects to internet?",
|
||
answers: ["Router", "Computer", "Phone", "Tablet"],
|
||
correct: 0,
|
||
imageKey: "router"
|
||
},
|
||
{
|
||
question: "What is software?",
|
||
answers: ["Program", "Game", "Movie", "Music"],
|
||
correct: 0,
|
||
imageKey: "software"
|
||
},
|
||
{
|
||
question: "What has keyboard?",
|
||
answers: ["Computer", "Phone", "Tablet", "TV"],
|
||
correct: 0,
|
||
imageKey: "computer"
|
||
},
|
||
{
|
||
question: "What has screen?",
|
||
answers: ["Phone", "Computer", "Tablet", "TV"],
|
||
correct: 0,
|
||
imageKey: "phone"
|
||
},
|
||
{
|
||
question: "What processes data?",
|
||
answers: ["Computer", "Phone", "Tablet", "TV"],
|
||
correct: 0,
|
||
imageKey: "computer"
|
||
},
|
||
{
|
||
question: "What stores information?",
|
||
answers: ["Hard Drive", "Memory", "Processor", "Screen"],
|
||
correct: 0,
|
||
imageKey: "storage"
|
||
},
|
||
{
|
||
question: "What has mouse?",
|
||
answers: ["Computer", "Phone", "Tablet", "TV"],
|
||
correct: 0,
|
||
imageKey: "computer"
|
||
},
|
||
{
|
||
question: "What has apps?",
|
||
answers: ["Phone", "Computer", "Tablet", "TV"],
|
||
correct: 0,
|
||
imageKey: "phone"
|
||
},
|
||
{
|
||
question: "What has battery?",
|
||
answers: ["Phone", "Computer", "Tablet", "TV"],
|
||
correct: 0,
|
||
imageKey: "phone"
|
||
},
|
||
{
|
||
question: "What takes photos?",
|
||
answers: ["Camera", "Phone", "Computer", "Tablet"],
|
||
correct: 0,
|
||
imageKey: "camera"
|
||
},
|
||
{
|
||
question: "What prints documents?",
|
||
answers: ["Printer", "Computer", "Phone", "Tablet"],
|
||
correct: 0,
|
||
imageKey: "printer"
|
||
}
|
||
],
|
||
groupC: [
|
||
{
|
||
question: "What is electricity?",
|
||
answers: ["Power", "Battery", "Magnet", "Light"],
|
||
correct: 0,
|
||
imageKey: "electricity"
|
||
},
|
||
{
|
||
question: "What powers devices?",
|
||
answers: ["Electricity", "Battery", "Solar", "Wind"],
|
||
correct: 0,
|
||
imageKey: "electricity"
|
||
},
|
||
{
|
||
question: "What conducts electricity?",
|
||
answers: ["Metal", "Water", "Plastic", "Wood"],
|
||
correct: 0,
|
||
imageKey: "metal"
|
||
},
|
||
{
|
||
question: "What is circuit?",
|
||
answers: ["Path", "Switch", "Wire", "Battery"],
|
||
correct: 0,
|
||
imageKey: "circuit"
|
||
},
|
||
{
|
||
question: "What measures voltage?",
|
||
answers: ["Meter", "Oscilloscope", "Timer", "Computer"],
|
||
correct: 0,
|
||
imageKey: "meter"
|
||
},
|
||
{
|
||
question: "What stores electricity?",
|
||
answers: ["Battery", "Capacitor", "Resistor", "Inductor"],
|
||
correct: 0,
|
||
imageKey: "battery"
|
||
},
|
||
{
|
||
question: "What transforms power?",
|
||
answers: ["Transformer", "Generator", "Motor", "Battery"],
|
||
correct: 0,
|
||
imageKey: "transformer"
|
||
},
|
||
{
|
||
question: "What is current?",
|
||
answers: ["Flow", "Voltage", "Resistance", "Power"],
|
||
correct: 0,
|
||
imageKey: "current"
|
||
},
|
||
{
|
||
question: "What is resistance?",
|
||
answers: ["Opposition", "Help", "Support", "Conductance"],
|
||
correct: 0,
|
||
imageKey: "resistance"
|
||
},
|
||
{
|
||
question: "What generates power?",
|
||
answers: ["Generator", "Battery", "Solar", "Wind"],
|
||
correct: 0,
|
||
imageKey: "generator"
|
||
},
|
||
{
|
||
question: "What controls electricity?",
|
||
answers: ["Switch", "Wire", "Battery", "Resistor"],
|
||
correct: 0,
|
||
imageKey: "switch"
|
||
}
|
||
]
|
||
},
|
||
4: { // Secret Level - 45 questions total (3 groups of 15)
|
||
groupA: [
|
||
{
|
||
question: "What is the secret word?",
|
||
answers: ["ENGLISH", "SECRET", "CODE", "LEVEL"],
|
||
correct: 0,
|
||
imageKey: "secret"
|
||
},
|
||
{
|
||
question: "Complete: English _____ 10",
|
||
answers: ["Class", "Course", "Lesson", "Book"],
|
||
correct: 1,
|
||
imageKey: "course"
|
||
},
|
||
{
|
||
question: "What unlocks secrets?",
|
||
answers: ["Key", "Lock", "Door", "Window"],
|
||
correct: 0,
|
||
imageKey: "key"
|
||
},
|
||
{
|
||
question: "What is hidden?",
|
||
answers: ["Treasure", "Secret", "Message", "Code"],
|
||
correct: 0,
|
||
imageKey: "treasure"
|
||
},
|
||
{
|
||
question: "What is mystery?",
|
||
answers: ["Puzzle", "Question", "Secret", "Answer"],
|
||
correct: 0,
|
||
imageKey: "mystery"
|
||
},
|
||
{
|
||
question: "What needs password?",
|
||
answers: ["Account", "File", "Folder", "Document"],
|
||
correct: 0,
|
||
imageKey: "password"
|
||
},
|
||
{
|
||
question: "What is encrypted?",
|
||
answers: ["Code", "Message", "Text", "Image"],
|
||
correct: 0,
|
||
imageKey: "encryption"
|
||
},
|
||
{
|
||
question: "What is classified?",
|
||
answers: ["Secret", "Public", "Private", "Open"],
|
||
correct: 0,
|
||
imageKey: "classified"
|
||
},
|
||
{
|
||
question: "What is invisible?",
|
||
answers: ["Air", "Ghost", "Secret", "Hidden"],
|
||
correct: 0,
|
||
imageKey: "invisible"
|
||
},
|
||
{
|
||
question: "What is unknown?",
|
||
answers: ["Mystery", "Secret", "Question", "Answer"],
|
||
correct: 0,
|
||
imageKey: "mystery"
|
||
},
|
||
{
|
||
question: "What is protected?",
|
||
answers: ["Password", "Secret", "Guard", "Lock"],
|
||
correct: 0,
|
||
imageKey: "password"
|
||
},
|
||
{
|
||
question: "What is special?",
|
||
answers: ["Unique", "Secret", "Rare", "Common"],
|
||
correct: 0,
|
||
imageKey: "special"
|
||
},
|
||
{
|
||
question: "What is exclusive?",
|
||
answers: ["Secret", "Private", "Limited", "Open"],
|
||
correct: 0,
|
||
imageKey: "exclusive"
|
||
},
|
||
{
|
||
question: "What is advanced?",
|
||
answers: ["Expert", "Secret", "Master", "Beginner"],
|
||
correct: 0,
|
||
imageKey: "expert"
|
||
}
|
||
],
|
||
groupB: [
|
||
{
|
||
question: "What is achievement?",
|
||
answers: ["Success", "Progress", "Grade", "Score"],
|
||
correct: 0,
|
||
imageKey: "achievement"
|
||
},
|
||
{
|
||
question: "What is certificate?",
|
||
answers: ["Diploma", "Award", "Medal", "Prize"],
|
||
correct: 0,
|
||
imageKey: "certificate"
|
||
},
|
||
{
|
||
question: "What is excellence?",
|
||
answers: ["Perfect", "Great", "Good", "Average"],
|
||
correct: 0,
|
||
imageKey: "excellence"
|
||
},
|
||
{
|
||
question: "What is mastery?",
|
||
answers: ["Expert", "Skilled", "Professional", "Beginner"],
|
||
correct: 0,
|
||
imageKey: "mastery"
|
||
},
|
||
{
|
||
question: "What is graduation?",
|
||
answers: ["Complete", "Finish", "Pass", "Quit"],
|
||
correct: 0,
|
||
imageKey: "graduation"
|
||
},
|
||
{
|
||
question: "What is knowledge?",
|
||
answers: ["Learning", "Study", "Teaching", "Wisdom"],
|
||
correct: 0,
|
||
imageKey: "knowledge"
|
||
},
|
||
{
|
||
question: "What is wisdom?",
|
||
answers: ["Experience", "Knowledge", "Study", "Learning"],
|
||
correct: 0,
|
||
imageKey: "wisdom"
|
||
},
|
||
{
|
||
question: "What is skill?",
|
||
answers: ["Ability", "Talent", "Practice", "Theory"],
|
||
correct: 0,
|
||
imageKey: "skill"
|
||
},
|
||
{
|
||
question: "What is talent?",
|
||
answers: ["Gift", "Skill", "Practice", "Ability"],
|
||
correct: 0,
|
||
imageKey: "talent"
|
||
},
|
||
{
|
||
question: "What is genius?",
|
||
answers: ["Expert", "Master", "Professional", "Skilled"],
|
||
correct: 0,
|
||
imageKey: "genius"
|
||
},
|
||
{
|
||
question: "What is brilliance?",
|
||
answers: ["Excellence", "Perfect", "Great", "Good"],
|
||
correct: 0,
|
||
imageKey: "brilliance"
|
||
},
|
||
{
|
||
question: "What is victory?",
|
||
answers: ["Success", "Win", "Achieve", "Complete"],
|
||
correct: 0,
|
||
imageKey: "victory"
|
||
}
|
||
],
|
||
groupC: [
|
||
{
|
||
question: "What is future?",
|
||
answers: ["Tomorrow", "Yesterday", "Today", "Now"],
|
||
correct: 0,
|
||
imageKey: "future"
|
||
},
|
||
{
|
||
question: "What is dream?",
|
||
answers: ["Goal", "Reality", "Past", "Present"],
|
||
correct: 0,
|
||
imageKey: "dream"
|
||
},
|
||
{
|
||
question: "What is ambition?",
|
||
answers: ["Success", "Money", "Power", "Knowledge"],
|
||
correct: 0,
|
||
imageKey: "ambition"
|
||
},
|
||
{
|
||
question: "What is destiny?",
|
||
answers: ["Future", "Past", "Present", "Choice"],
|
||
correct: 0,
|
||
imageKey: "destiny"
|
||
},
|
||
{
|
||
question: "What is potential?",
|
||
answers: ["Future", "Past", "Present", "Ability"],
|
||
correct: 0,
|
||
imageKey: "potential"
|
||
},
|
||
{
|
||
question: "What is opportunity?",
|
||
answers: ["Chance", "Obstacle", "Past", "Present"],
|
||
correct: 0,
|
||
imageKey: "opportunity"
|
||
},
|
||
{
|
||
question: "What is possibility?",
|
||
answers: ["Future", "Past", "Present", "Reality"],
|
||
correct: 0,
|
||
imageKey: "possibility"
|
||
},
|
||
{
|
||
question: "What is hope?",
|
||
answers: ["Future", "Past", "Present", "Despair"],
|
||
correct: 0,
|
||
imageKey: "hope"
|
||
},
|
||
{
|
||
question: "What is aspiration?",
|
||
answers: ["Goal", "Dream", "Reality", "Past"],
|
||
correct: 0,
|
||
imageKey: "aspiration"
|
||
},
|
||
{
|
||
question: "What is vision?",
|
||
answers: ["Future", "Past", "Present", "Reality"],
|
||
correct: 0,
|
||
imageKey: "vision"
|
||
},
|
||
{
|
||
question: "What is imagination?",
|
||
answers: ["Creativity", "Logic", "Memory", "Reality"],
|
||
correct: 0,
|
||
imageKey: "imagination"
|
||
},
|
||
{
|
||
question: "What is innovation?",
|
||
answers: ["Future", "Past", "Present", "Tradition"],
|
||
correct: 0,
|
||
imageKey: "innovation"
|
||
}
|
||
]
|
||
}
|
||
},
|
||
|
||
RU_TRANSLATIONS: {
|
||
"What animal says 'woof'?": "Какое животное говорит 'гав'?",
|
||
"What color are leaves?": "Какого цвета листья?",
|
||
"Where do birds live?": "Где живут птицы?",
|
||
"What animal says 'meow'?": "Какое животное говорит 'мяу'?",
|
||
"What do cows say?": "Что говорят коровы?",
|
||
"What animal flies?": "Какое животное летает?",
|
||
"What animal lives in water?": "Какое животное живет в воде?",
|
||
"What animal has stripes?": "У какого животного есть полоски?",
|
||
"What animal is king of jungle?": "Какое животное — король джунглей?",
|
||
"What animal eats bananas?": "Какое животное ест бананы?",
|
||
"What animal gives milk?": "Какое животное дает молоко?",
|
||
"What animal has trunk?": "У какого животного есть хобот?",
|
||
"What animal hops?": "Какое животное прыгает?",
|
||
"What animal is wise?": "Какое животное мудрое?",
|
||
"What animal has long neck?": "У какого животного длинная шея?",
|
||
"What animal swims in ocean?": "Какое животное плавает в океане?",
|
||
"What animal has shell?": "У какого животного есть панцирь?",
|
||
"What animal is black and white?": "Какое животное черно-белое?",
|
||
"What do trees have?": "Что есть у деревьев?",
|
||
"What falls from trees?": "Что падает с деревьев?",
|
||
"What grows from seeds?": "Что растет из семян?",
|
||
"What is green and grows?": "Что зеленое и растет?",
|
||
"What gives us oxygen?": "Что дает нам кислород?",
|
||
"What changes color in autumn?": "Что меняет цвет осенью?",
|
||
"What needs water to grow?": "Чему нужна вода, чтобы расти?",
|
||
"What is in forest?": "Что есть в лесу?",
|
||
"What do bees make?": "Что делают пчелы?",
|
||
"What is red fruit?": "Какой фрукт красный?",
|
||
"What is yellow fruit?": "Какой фрукт желтый?",
|
||
"What has many seeds?": "У чего много семян?",
|
||
"What grows on vine?": "Что растет на лозе?",
|
||
"What is citrus?": "Что является цитрусом?",
|
||
"What is weather?": "Что такое погода?",
|
||
"What falls from sky?": "Что падает с неба?",
|
||
"What is cold?": "Что холодное?",
|
||
"What blows?": "Что дует?",
|
||
"What are clouds?": "Что такое облака?",
|
||
"What is frozen water?": "Что такое замерзшая вода?",
|
||
"What makes rainbow?": "Что создает радугу?",
|
||
"What is lightning?": "Что такое молния?",
|
||
"What is fog?": "Что такое туман?",
|
||
"What is temperature?": "Что такое температура?",
|
||
"What is season?": "Что такое сезон?",
|
||
"What is thunder?": "Что такое гром?",
|
||
"Where do people live?": "Где живут люди?",
|
||
"What drives on roads?": "Что ездит по дорогам?",
|
||
"Where do you learn?": "Где ты учишься?"
|
||
},
|
||
init() {
|
||
this.loadUser();
|
||
this.updateMascot('happy', 'Welcome! / Добро пожаловать!');
|
||
this.preloadAllImages();
|
||
const toggle = document.getElementById('has-code');
|
||
if (toggle) {
|
||
toggle.onchange = () => {
|
||
const isExisting = toggle.checked;
|
||
document.getElementById('login-existing').style.display = isExisting ? '' : 'none';
|
||
document.getElementById('login-new').style.display = isExisting ? 'none' : '';
|
||
};
|
||
}
|
||
},
|
||
|
||
// User Management
|
||
loadUser() {
|
||
const savedUser = localStorage.getItem('englishCourseUser');
|
||
if (savedUser) {
|
||
this.user = JSON.parse(savedUser);
|
||
this.showScreen('screen-map');
|
||
this.updateProgress();
|
||
}
|
||
},
|
||
|
||
saveUser() {
|
||
localStorage.setItem('englishCourseUser', JSON.stringify(this.user));
|
||
},
|
||
|
||
login() {
|
||
const hasCodeToggle = document.getElementById('has-code');
|
||
const useCode = hasCodeToggle && hasCodeToggle.checked;
|
||
if (useCode) {
|
||
const code = (document.getElementById('login-secret-code').value || '').trim();
|
||
if (!code) { this.updateMascot('thinking', 'Enter code / Введите код'); return; }
|
||
const data = localStorage.getItem('englishCourseUser_' + code);
|
||
if (!data) { this.updateMascot('thinking', 'Code not found / Код не найден'); return; }
|
||
this.user = JSON.parse(data);
|
||
localStorage.setItem('englishCourseUser', JSON.stringify(this.user));
|
||
this.showScreen('screen-map');
|
||
this.updateProgress();
|
||
this.updateMascot('happy', 'Welcome back! / С возвращением!');
|
||
return;
|
||
}
|
||
const username = document.getElementById('username').value.trim();
|
||
const age = document.getElementById('age').value;
|
||
|
||
if (!username) {
|
||
this.updateMascot('thinking', 'Please enter your name / Пожалуйста, введите ваше имя');
|
||
return;
|
||
}
|
||
|
||
if (!age || age < 6 || age > 15) {
|
||
this.updateMascot('thinking', 'Please enter valid age (6-15) / Пожалуйста, введите корректный возраст (6-15)');
|
||
return;
|
||
}
|
||
|
||
this.user = {
|
||
name: username,
|
||
age: parseInt(age),
|
||
progress: {},
|
||
scores: {},
|
||
secretUnlocked: false,
|
||
placementTest: null
|
||
};
|
||
|
||
this.saveUser();
|
||
this.showPlacementTest();
|
||
},
|
||
|
||
logout() {
|
||
this.user = null;
|
||
this.showScreen('screen-login');
|
||
this.updateMascot('happy', 'Goodbye! / До свидания!');
|
||
|
||
// Reset login UI state
|
||
const checkbox = document.getElementById('has-code');
|
||
const checkIcon = document.getElementById('check-icon');
|
||
const newSection = document.getElementById('login-new');
|
||
const existingSection = document.getElementById('login-existing');
|
||
|
||
if (checkbox && newSection && existingSection) {
|
||
checkbox.checked = false;
|
||
newSection.style.display = 'block';
|
||
existingSection.style.display = 'none';
|
||
if (checkIcon) checkIcon.style.opacity = '0';
|
||
|
||
// Bind toggle listener
|
||
checkbox.onchange = (e) => {
|
||
if (checkIcon) checkIcon.style.opacity = e.target.checked ? '1' : '0';
|
||
if (e.target.checked) {
|
||
newSection.style.display = 'none';
|
||
existingSection.style.display = 'block';
|
||
existingSection.classList.add('fade-in');
|
||
} else {
|
||
newSection.style.display = 'block';
|
||
existingSection.style.display = 'none';
|
||
newSection.classList.add('fade-in');
|
||
}
|
||
};
|
||
}
|
||
},
|
||
|
||
// Screen Management
|
||
showScreen(screenId) {
|
||
document.querySelectorAll('.screen').forEach(screen => {
|
||
screen.classList.remove('active');
|
||
});
|
||
document.getElementById(screenId).classList.add('active');
|
||
},
|
||
|
||
// Placement Test Management
|
||
showPlacementTest() {
|
||
this.showScreen('screen-placement');
|
||
this.currentPlacementQuestion = 0;
|
||
this.placementScore = 0;
|
||
this.renderPlacementQuestion();
|
||
this.updateMascot('excited', 'Let\'s find your perfect level! / Давайте найдем ваш идеальный уровень!');
|
||
},
|
||
|
||
renderPlacementQuestion() {
|
||
const questions = this.PLACEMENT_QUESTIONS;
|
||
if (!questions || this.currentPlacementQuestion >= questions.length) {
|
||
this.completePlacementTest();
|
||
return;
|
||
}
|
||
|
||
const question = questions[this.currentPlacementQuestion];
|
||
document.getElementById('placement-question').textContent = question.question;
|
||
document.getElementById('placement-image').src = this.getCachedImageSrc(question.imageKey);
|
||
this.setupReportDot('placement-report-dot', document.getElementById('placement-image'), {
|
||
level: 'placement',
|
||
index: this.currentPlacementQuestion,
|
||
imageKey: question.imageKey
|
||
});
|
||
|
||
// Update progress bar
|
||
const progress = ((this.currentPlacementQuestion + 1) / questions.length) * 100;
|
||
document.getElementById('placement-progress').style.width = `${progress}%`;
|
||
|
||
// Generate answer buttons
|
||
const answersContainer = document.getElementById('placement-answers');
|
||
answersContainer.innerHTML = '';
|
||
|
||
// Shuffle answers while keeping track of original indices
|
||
let answersWithIndex = question.answers.map((answer, index) => ({ answer, index }));
|
||
answersWithIndex = this.shuffleArray(answersWithIndex);
|
||
|
||
answersWithIndex.forEach(item => {
|
||
const button = document.createElement('button');
|
||
button.className = 'answer-btn';
|
||
button.textContent = item.answer;
|
||
button.dataset.originalIndex = item.index;
|
||
button.onclick = (e) => this.checkPlacementAnswer(item.index, e.currentTarget);
|
||
answersContainer.appendChild(button);
|
||
});
|
||
},
|
||
|
||
checkPlacementAnswer(answerIndex, btnElement) {
|
||
const questions = this.PLACEMENT_QUESTIONS;
|
||
const question = questions[this.currentPlacementQuestion];
|
||
const buttons = document.querySelectorAll('#placement-answers .answer-btn');
|
||
this.playClick();
|
||
|
||
if (answerIndex === question.correct) {
|
||
btnElement.classList.add('correct');
|
||
this.placementScore++;
|
||
this.showFloatingText('Correct! / Верно!', '#00ff00');
|
||
} else {
|
||
btnElement.classList.add('incorrect');
|
||
// Find the button that corresponds to the correct answer
|
||
const correctBtn = Array.from(buttons).find(b => parseInt(b.dataset.originalIndex) === question.correct);
|
||
if (correctBtn) correctBtn.classList.add('correct');
|
||
this.showFloatingText('Wrong! / Неверно!', '#ff0000');
|
||
}
|
||
|
||
// Disable all buttons
|
||
buttons.forEach(btn => btn.disabled = true);
|
||
|
||
// Move to next question after delay
|
||
setTimeout(() => {
|
||
this.currentPlacementQuestion++;
|
||
this.renderPlacementQuestion();
|
||
}, this.getAnswerDelay());
|
||
},
|
||
|
||
completePlacementTest() {
|
||
// Calculate recommended level based on score
|
||
const percentage = (this.placementScore / this.PLACEMENT_QUESTIONS.length) * 100;
|
||
let recommendedLevel = 1;
|
||
|
||
if (percentage >= 80) recommendedLevel = 3;
|
||
else if (percentage >= 60) recommendedLevel = 2;
|
||
else if (percentage >= 40) recommendedLevel = 1;
|
||
|
||
// Save placement test results
|
||
this.user.placementTest = {
|
||
score: this.placementScore,
|
||
percentage: percentage,
|
||
recommendedLevel: recommendedLevel
|
||
};
|
||
|
||
this.saveUser();
|
||
|
||
// Show results
|
||
this.showFloatingText(`Recommended Level: ${recommendedLevel} / Рекомендуемый уровень: ${recommendedLevel}`, '#ffff00');
|
||
this.updateMascot('excited', `Test complete! / Тест завершен!`);
|
||
const code = this.generateSecretCode();
|
||
this.user.secretCode = code;
|
||
localStorage.setItem('englishCourseUser_' + code, JSON.stringify(this.user));
|
||
this.saveUser();
|
||
this.showSecretCodeModal(code);
|
||
|
||
// Go to map after delay
|
||
setTimeout(() => {
|
||
this.showScreen('screen-map');
|
||
this.updateProgress();
|
||
}, 2000);
|
||
},
|
||
|
||
generateSecretCode() {
|
||
const base = (this.user.name || 'EN')
|
||
.replace(/\s+/g,'').slice(0,2).toUpperCase();
|
||
const rand = Math.random().toString(36).slice(2,8).toUpperCase();
|
||
const age = (this.user.age || 10).toString().padStart(2,'0');
|
||
return base + age + '-' + rand;
|
||
},
|
||
|
||
showSecretCodeModal(code) {
|
||
const overlay = document.getElementById('secret-code-overlay');
|
||
const label = document.getElementById('secret-code-label');
|
||
const value = document.getElementById('secret-code-value');
|
||
const copyBtn = document.getElementById('secret-code-copy');
|
||
const closeBtn = document.getElementById('secret-code-close');
|
||
if (!overlay || !label || !value || !copyBtn || !closeBtn) return;
|
||
label.textContent = 'Your Secret Code / Ваш секретный код';
|
||
value.textContent = code;
|
||
overlay.classList.remove('hidden');
|
||
copyBtn.onclick = () => {
|
||
navigator.clipboard.writeText(code).then(() => {
|
||
copyBtn.textContent = 'Copied! / Скопировано!';
|
||
setTimeout(() => { copyBtn.textContent = 'Copy / Скопировать'; }, 2000);
|
||
});
|
||
};
|
||
closeBtn.onclick = () => { overlay.classList.add('hidden'); };
|
||
},
|
||
|
||
// Level Management
|
||
startLevel(level) {
|
||
// Check if placement test was completed and use recommended level
|
||
let actualLevel = level;
|
||
if (this.user.placementTest && level === this.user.placementTest.recommendedLevel) {
|
||
actualLevel = this.user.placementTest.recommendedLevel;
|
||
this.updateMascot('excited', `Starting recommended level ${actualLevel}! / Начинаем рекомендуемый уровень ${actualLevel}!`);
|
||
} else {
|
||
this.updateMascot('excited', `Level ${level} started! / Уровень ${level} начат!`);
|
||
}
|
||
|
||
this.currentLevel = actualLevel;
|
||
this.currentQuestion = 0;
|
||
this.score = 0;
|
||
|
||
// Initialize adaptive question ordering based on placement test results
|
||
this.initializeAdaptiveQuestions(actualLevel);
|
||
|
||
this.showScreen('screen-test');
|
||
this.renderQuestion();
|
||
},
|
||
|
||
getHintIntensity() {
|
||
let m = 0;
|
||
if (this.currentLevel === 1) m = 2; else if (this.currentLevel === 2) m = 1; else m = 0;
|
||
if (this.user && this.user.placementTest) {
|
||
const p = this.user.placementTest.percentage;
|
||
if (p < 60) m = Math.min(2, m + 1);
|
||
if (p >= 80) m = Math.max(0, m - 1);
|
||
}
|
||
if (this.currentQuestion >= 15 && m > 0) m = m - 1;
|
||
return m;
|
||
},
|
||
|
||
getQuestionTextWithHints(question) {
|
||
const m = this.getHintIntensity();
|
||
if (!m) return question.question;
|
||
const ru = this.RU_TRANSLATIONS[question.question];
|
||
if (!ru) return question.question;
|
||
if (m === 2) return `${question.question} / ${ru}`;
|
||
if (m === 1) return this.currentQuestion % 2 === 0 ? `${question.question} / ${ru}` : question.question;
|
||
return question.question;
|
||
},
|
||
|
||
getHintForQuestion(question) {
|
||
const ru = this.RU_TRANSLATIONS[question.question];
|
||
const correct = typeof question.correct === 'number' && question.answers ? question.answers[question.correct] : '';
|
||
const tip = correct ? `Tip: starts with "${correct.charAt(0)}"` : '';
|
||
if (ru && tip) return `${ru} • ${tip}`;
|
||
return ru || tip || 'Think about the context!';
|
||
},
|
||
|
||
// Test Management
|
||
initializeAdaptiveQuestions(level) {
|
||
const levelQuestions = this.QUESTIONS[level];
|
||
if (!levelQuestions) return;
|
||
|
||
// Default question order if no placement test data
|
||
if (!this.user.placementTest) {
|
||
this.adaptiveQuestions = [
|
||
...levelQuestions.groupA,
|
||
...levelQuestions.groupB,
|
||
...levelQuestions.groupC
|
||
];
|
||
return;
|
||
}
|
||
|
||
// Analyze placement test results to determine weak areas
|
||
const placementScore = this.user.placementTest.percentage;
|
||
const recommendedLevel = this.user.placementTest.recommendedLevel;
|
||
|
||
// Prioritize question groups based on placement test performance
|
||
let groupPriority = ['groupA', 'groupB', 'groupC'];
|
||
|
||
// If user scored low, prioritize easier groups first
|
||
if (placementScore < 50) {
|
||
groupPriority = this.getGroupPriority(level, 'beginner');
|
||
}
|
||
// If user scored medium, balance difficulty
|
||
else if (placementScore < 80) {
|
||
groupPriority = this.getGroupPriority(level, 'intermediate');
|
||
}
|
||
// If user scored high, prioritize harder groups
|
||
else {
|
||
groupPriority = this.getGroupPriority(level, 'advanced');
|
||
}
|
||
|
||
// Create adaptive question order
|
||
this.adaptiveQuestions = [];
|
||
groupPriority.forEach(group => {
|
||
if (levelQuestions[group]) {
|
||
this.adaptiveQuestions.push(...levelQuestions[group]);
|
||
}
|
||
});
|
||
|
||
this.adaptiveQuestions = this.makeVariedQuestions(this.adaptiveQuestions);
|
||
|
||
// Store adaptive metadata for tracking
|
||
this.adaptiveMetadata = {
|
||
level: level,
|
||
groupPriority: groupPriority,
|
||
placementScore: placementScore
|
||
};
|
||
},
|
||
getCategoryForKey(key) {
|
||
const A = ['dog','cat','bird','fish','cow','eagle','tiger','lion','monkey','elephant','kangaroo','owl','giraffe','dolphin','turtle','panda'];
|
||
const N = ['tree','leaf','flower','grass','forest','honey','apple','banana','watermelon','grapes','orange','autumn','plant'];
|
||
const W = ['sun','rain','snow','wind','clouds','ice','rainbow','lightning','fog','temperature','spring','thunder'];
|
||
const Cb = ['house','school','hospital','library','store','cinema','gym','hotel','restaurant','office','market','city','street','crosswalk'];
|
||
const Ct = ['car','airplane','subway','train','bicycle','bus','boat','ambulance','truck','helicopter','tickets','traffic'];
|
||
const S = ['moon','rocket','star','mars','jupiter','saturn','earth','sun','astronaut','satellite','station','telescope','galaxy'];
|
||
const T = ['computer','router','software','phone','storage','camera','printer'];
|
||
const E = ['electricity','metal','circuit','meter','battery','transformer','current','resistance','generator','switch'];
|
||
const X = ['secret','course','key','treasure','mystery','password','encryption','classified','certificate','excellence','achievement','mastery','graduation','knowledge','wisdom','skill','talent','genius','brilliance','victory','future','dream','ambition','destiny','potential','opportunity','possibility','hope','aspiration','vision','imagination','innovation'];
|
||
if (A.includes(key)) return 'animals';
|
||
if (N.includes(key)) return 'nature';
|
||
if (W.includes(key)) return 'weather';
|
||
if (Cb.includes(key)) return 'buildings';
|
||
if (Ct.includes(key)) return 'transport';
|
||
if (S.includes(key)) return 'space';
|
||
if (T.includes(key)) return 'tech';
|
||
if (E.includes(key)) return 'electro';
|
||
if (X.includes(key)) return 'meta';
|
||
return 'other';
|
||
},
|
||
shuffleArray(arr) {
|
||
for (let i = arr.length - 1; i > 0; i--) {
|
||
const j = Math.floor(Math.random() * (i + 1));
|
||
[arr[i], arr[j]] = [arr[j], arr[i]];
|
||
}
|
||
return arr;
|
||
},
|
||
makeVariedQuestions(list) {
|
||
const q = this.shuffleArray(list.slice());
|
||
const used = {};
|
||
const out = [];
|
||
let lastCat = '';
|
||
for (let i = 0; i < q.length; i++) {
|
||
const item = q[i];
|
||
const correct = typeof item.correct === 'number' ? (item.answers[item.correct] || '') : '';
|
||
const key = item.imageKey || '';
|
||
const cat = this.getCategoryForKey(key);
|
||
const count = used[correct] || 0;
|
||
if (count > 0) continue;
|
||
if (cat === lastCat) continue;
|
||
out.push(item);
|
||
used[correct] = count + 1;
|
||
lastCat = cat;
|
||
if (out.length >= 15) break;
|
||
}
|
||
if (out.length < Math.min(15, list.length)) {
|
||
for (let i = 0; i < q.length && out.length < Math.min(15, list.length); i++) {
|
||
const item = q[i];
|
||
const correct = typeof item.correct === 'number' ? (item.answers[item.correct] || '') : '';
|
||
const key = item.imageKey || '';
|
||
const cat = this.getCategoryForKey(key);
|
||
const count = used[correct] || 0;
|
||
if (count > 1) continue;
|
||
if (cat === lastCat) continue;
|
||
out.push(item);
|
||
used[correct] = count + 1;
|
||
lastCat = cat;
|
||
}
|
||
}
|
||
return out.length ? out : list;
|
||
},
|
||
|
||
getGroupPriority(level, difficulty) {
|
||
// Define group priorities based on level and difficulty
|
||
const priorities = {
|
||
1: { // Forest Level
|
||
beginner: ['groupA', 'groupB', 'groupC'], // Animals first, then nature, then weather
|
||
intermediate: ['groupA', 'groupC', 'groupB'], // Mix animals with weather
|
||
advanced: ['groupC', 'groupB', 'groupA'] // Weather and nature for challenge
|
||
},
|
||
2: { // City Level
|
||
beginner: ['groupA', 'groupB', 'groupC'], // Buildings first, then transport, then infrastructure
|
||
intermediate: ['groupB', 'groupA', 'groupC'], // Mix transport with buildings
|
||
advanced: ['groupC', 'groupB', 'groupA'] // Infrastructure and transport for challenge
|
||
},
|
||
3: { // Space Station Level
|
||
beginner: ['groupA', 'groupB', 'groupC'], // Space first, then technology, then electricity
|
||
intermediate: ['groupB', 'groupA', 'groupC'], // Mix technology with space
|
||
advanced: ['groupC', 'groupB', 'groupA'] // Electricity and technology for challenge
|
||
},
|
||
4: { // Secret Level
|
||
beginner: ['groupA', 'groupB', 'groupC'], // Secrets first, then achievements, then future
|
||
intermediate: ['groupB', 'groupA', 'groupC'], // Mix achievements with secrets
|
||
advanced: ['groupC', 'groupB', 'groupA'] // Future and achievements for challenge
|
||
}
|
||
};
|
||
|
||
return priorities[level]?.[difficulty] || ['groupA', 'groupB', 'groupC'];
|
||
},
|
||
|
||
renderQuestion() {
|
||
// Use adaptive questions if available, otherwise fall back to default
|
||
const questions = this.adaptiveQuestions || this.QUESTIONS[this.currentLevel];
|
||
if (!questions || this.currentQuestion >= questions.length) {
|
||
this.completeLevel();
|
||
return;
|
||
}
|
||
|
||
const question = questions[this.currentQuestion];
|
||
// reset wrong attempts per question
|
||
this.wrongAttempts = 0;
|
||
// set question text (bilingual policy still applies)
|
||
document.getElementById('question-text').textContent = this.getQuestionTextWithHints(question);
|
||
|
||
// reset and hide hint UI initially
|
||
const hintControls = document.getElementById('hint-controls');
|
||
const hintArea = document.getElementById('hint-area');
|
||
const hintBtn = document.getElementById('hint-btn');
|
||
|
||
// Always show hint button now
|
||
if (hintControls) hintControls.style.display = '';
|
||
if (hintArea) { hintArea.style.display = 'none'; hintArea.textContent = ''; }
|
||
|
||
if (hintBtn) {
|
||
hintBtn.disabled = false;
|
||
hintBtn.onclick = () => {
|
||
hintArea.textContent = this.getHintForQuestion(question);
|
||
hintArea.style.display = 'block';
|
||
hintArea.classList.remove('hidden');
|
||
};
|
||
}
|
||
|
||
document.getElementById('current-question').textContent = this.currentQuestion + 1;
|
||
document.getElementById('total-questions').textContent = questions.length;
|
||
|
||
// Update progress bar
|
||
const progress = ((this.currentQuestion + 1) / questions.length) * 100;
|
||
document.getElementById('test-progress').style.width = `${progress}%`;
|
||
|
||
// Generate and display image
|
||
const questionImage = document.getElementById('question-image');
|
||
questionImage.src = this.getCachedImageSrc(question.imageKey);
|
||
this.setupReportDot('question-report-dot', questionImage, {
|
||
level: this.currentLevel,
|
||
index: this.currentQuestion,
|
||
imageKey: question.imageKey
|
||
});
|
||
this.setupReportDot('question-report-dot', questionImage, {
|
||
level: this.currentLevel,
|
||
index: this.currentQuestion,
|
||
imageKey: question.imageKey
|
||
});
|
||
|
||
// Generate answer buttons
|
||
const answersContainer = document.getElementById('answers-container');
|
||
answersContainer.innerHTML = '';
|
||
|
||
// Shuffle answers while keeping track of original indices
|
||
let answersWithIndex = question.answers.map((answer, index) => ({ answer, index }));
|
||
answersWithIndex = this.shuffleArray(answersWithIndex);
|
||
|
||
answersWithIndex.forEach(item => {
|
||
const button = document.createElement('button');
|
||
button.className = 'answer-btn';
|
||
button.textContent = item.answer;
|
||
button.dataset.originalIndex = item.index;
|
||
button.onclick = (e) => this.checkAnswer(item.index, e.currentTarget);
|
||
answersContainer.appendChild(button);
|
||
});
|
||
},
|
||
|
||
checkAnswer(answerIndex, btnElement) {
|
||
const questions = this.adaptiveQuestions || [];
|
||
const question = questions[this.currentQuestion];
|
||
const buttons = document.querySelectorAll('#answers-container .answer-btn');
|
||
this.playClick();
|
||
|
||
if (answerIndex === question.correct) {
|
||
btnElement.classList.add('correct');
|
||
this.score++;
|
||
this.user.points = (this.user.points || 0) + 10;
|
||
this.saveUser();
|
||
this.showFloatingText('Correct! / Верно!', '#00ff00');
|
||
this.spawnReward();
|
||
} else {
|
||
btnElement.classList.add('incorrect');
|
||
// Find the button that corresponds to the correct answer
|
||
const correctBtn = Array.from(buttons).find(b => parseInt(b.dataset.originalIndex) === question.correct);
|
||
if (correctBtn) correctBtn.classList.add('correct');
|
||
this.showFloatingText('Wrong! / Неверно!', '#ff0000');
|
||
// track wrong attempts
|
||
this.wrongAttempts = (this.wrongAttempts || 0) + 1;
|
||
}
|
||
|
||
// Disable all buttons
|
||
buttons.forEach(btn => btn.disabled = true);
|
||
|
||
// Move to next question after delay
|
||
setTimeout(() => {
|
||
this.currentQuestion++;
|
||
this.renderQuestion();
|
||
}, this.getAnswerDelay());
|
||
},
|
||
|
||
playClick() {
|
||
if (!this.audioCtx) this.audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
||
const ctx = this.audioCtx;
|
||
const osc = ctx.createOscillator();
|
||
const gain = ctx.createGain();
|
||
osc.frequency.value = 440;
|
||
gain.gain.value = 0.05;
|
||
osc.connect(gain);
|
||
gain.connect(ctx.destination);
|
||
osc.start();
|
||
setTimeout(() => { try { osc.stop(); } catch(_){} }, 80);
|
||
},
|
||
|
||
spawnReward() {
|
||
const star = document.createElement('div');
|
||
star.textContent = '⭐';
|
||
star.style.position = 'fixed';
|
||
star.style.left = '50%';
|
||
star.style.top = '60%';
|
||
star.style.transform = 'translate(-50%, -50%)';
|
||
star.style.fontSize = '2rem';
|
||
star.style.animation = 'floatUp 1.5s ease-out forwards';
|
||
document.body.appendChild(star);
|
||
setTimeout(() => { if (star.parentNode) star.parentNode.removeChild(star); }, 1500);
|
||
},
|
||
|
||
completeLevel() {
|
||
// Save progress
|
||
if (!this.user.progress) this.user.progress = {};
|
||
if (!this.user.scores) this.user.scores = {};
|
||
|
||
this.user.progress[this.currentLevel] = true;
|
||
this.user.scores[this.currentLevel] = this.score;
|
||
this.user.badges = this.user.badges || [];
|
||
const badge = `Level ${this.currentLevel} Completed`;
|
||
if (!this.user.badges.includes(badge)) this.user.badges.push(badge);
|
||
|
||
// Update adaptive learning data
|
||
this.updateAdaptiveLearning();
|
||
|
||
this.saveUser();
|
||
this.updateProgress();
|
||
|
||
// Check for secret unlock
|
||
if (this.currentLevel === 3) {
|
||
this.checkSecretUnlock();
|
||
}
|
||
|
||
// Show completion message
|
||
this.showFloatingText(`Level ${this.currentLevel} Complete! / Уровень ${this.currentLevel} пройден!`, '#ffff00');
|
||
this.updateMascot('excited', 'Great job! / Отличная работа!');
|
||
|
||
// Return to map
|
||
setTimeout(() => {
|
||
this.goToMap();
|
||
}, 2000);
|
||
},
|
||
|
||
|
||
updateAdaptiveLearning() {
|
||
// Track performance for adaptive learning
|
||
if (!this.user.adaptiveLearning) {
|
||
this.user.adaptiveLearning = {};
|
||
}
|
||
|
||
if (!this.user.adaptiveLearning[this.currentLevel]) {
|
||
this.user.adaptiveLearning[this.currentLevel] = {
|
||
attempts: 0,
|
||
scores: [],
|
||
averageScore: 0,
|
||
improvement: 0
|
||
};
|
||
}
|
||
|
||
const levelData = this.user.adaptiveLearning[this.currentLevel];
|
||
levelData.attempts++;
|
||
levelData.scores.push(this.score);
|
||
|
||
// Calculate average score
|
||
const sum = levelData.scores.reduce((a, b) => a + b, 0);
|
||
levelData.averageScore = sum / levelData.scores.length;
|
||
|
||
// Calculate improvement
|
||
if (levelData.scores.length > 1) {
|
||
const previousAverage = levelData.scores.slice(0, -1).reduce((a, b) => a + b, 0) / (levelData.scores.length - 1);
|
||
levelData.improvement = levelData.averageScore - previousAverage;
|
||
}
|
||
|
||
// Update placement test recommendation if significant improvement
|
||
if (levelData.improvement > 10 && this.user.placementTest) {
|
||
const newRecommendedLevel = Math.min(4, this.currentLevel + 1);
|
||
if (newRecommendedLevel > this.user.placementTest.recommendedLevel) {
|
||
this.user.placementTest.recommendedLevel = newRecommendedLevel;
|
||
this.updateMascot('excited', `Great improvement! New recommended level: ${newRecommendedLevel}! / Отличный прогресс! Новый рекомендуемый уровень: ${newRecommendedLevel}!`);
|
||
}
|
||
}
|
||
},
|
||
|
||
// Secret Code Management
|
||
checkSecretCode() {
|
||
const input = document.getElementById('secret-code').value.toUpperCase();
|
||
|
||
// Check if user has completed all three main levels
|
||
if (!this.user.progress[1] || !this.user.progress[2] || !this.user.progress[3]) {
|
||
this.showFloatingText('Complete all levels first! / Сначала пройдите все уровни!', '#ff0000');
|
||
this.updateMascot('thinking', 'You must complete levels 1, 2, and 3 first! / Сначала пройдите уровни 1, 2 и 3!');
|
||
return;
|
||
}
|
||
|
||
// Check if secret code is correct
|
||
if (input === this.secretCode) {
|
||
this.user.secretUnlocked = true;
|
||
this.saveUser();
|
||
|
||
// Update secret level button
|
||
const secretLevelBtn = document.getElementById('secret-level');
|
||
if (secretLevelBtn) {
|
||
secretLevelBtn.classList.remove('locked');
|
||
secretLevelBtn.classList.add('unlocked');
|
||
secretLevelBtn.disabled = false;
|
||
}
|
||
|
||
// Show success message
|
||
this.showFloatingText('Secret Level Unlocked! / Секретный уровень открыт!', '#ff00ff');
|
||
this.updateMascot('excited', 'Welcome to the secret zone! / Добро пожаловать в секретную зону!');
|
||
|
||
// Update map for secret level
|
||
this.updateMapForSecretLevel();
|
||
|
||
// Start secret level after delay
|
||
setTimeout(() => this.startLevel(4), 1500);
|
||
} else {
|
||
this.showFloatingText('Wrong code! / Неверный код!', '#ff0000');
|
||
this.updateMascot('sad', 'Try again! / Попробуйте еще раз!');
|
||
}
|
||
},
|
||
|
||
checkSecretUnlock() {
|
||
// Check if all three main levels are completed
|
||
if (this.user.progress[1] && this.user.progress[2] && this.user.progress[3]) {
|
||
this.user.secretUnlocked = true;
|
||
this.saveUser();
|
||
|
||
// Update the secret level button on the map
|
||
const secretLevelBtn = document.getElementById('secret-level');
|
||
if (secretLevelBtn) {
|
||
secretLevelBtn.classList.remove('locked');
|
||
secretLevelBtn.classList.add('unlocked');
|
||
secretLevelBtn.disabled = false;
|
||
}
|
||
|
||
// Show floating notification
|
||
this.showFloatingText('Secret Zone Available! / Секретная зона доступна!', '#ff00ff');
|
||
this.updateMascot('excited', 'You can unlock the secret level! / Вы можете открыть секретный уровень!');
|
||
|
||
// Update map to show secret level
|
||
this.updateMapForSecretLevel();
|
||
}
|
||
},
|
||
|
||
updateMapForSecretLevel() {
|
||
// Add visual indicators for secret level availability
|
||
const mapContainer = document.querySelector('.map-container');
|
||
if (mapContainer && this.user.secretUnlocked) {
|
||
// Add glowing effect to secret level
|
||
const secretLevel = document.getElementById('secret-level');
|
||
if (secretLevel) {
|
||
secretLevel.style.animation = 'glow 2s infinite';
|
||
}
|
||
|
||
// Add achievement notification
|
||
const achievement = document.createElement('div');
|
||
achievement.className = 'achievement-notification';
|
||
achievement.innerHTML =
|
||
'<h3>🏆 Achievement Unlocked! / Достижение разблокировано!</h3>' +
|
||
'<p>Secret Level Available! / Секретный уровень доступен!</p>';
|
||
if (!this.settings || !this.settings.doNotDisturb) {
|
||
mapContainer.appendChild(achievement);
|
||
}
|
||
|
||
// Remove notification after 5 seconds
|
||
setTimeout(() => {
|
||
if (achievement.parentNode) {
|
||
achievement.parentNode.removeChild(achievement);
|
||
}
|
||
}, 5000);
|
||
}
|
||
},
|
||
|
||
// Navigation
|
||
goToMap() {
|
||
this.showScreen('screen-map');
|
||
this.updateProgress();
|
||
this.updateMascot('happy', 'Choose your level! / Выберите уровень!');
|
||
this.ensureFocusPanel();
|
||
},
|
||
|
||
// Progress Management
|
||
updateProgress() {
|
||
if (!this.user) return;
|
||
|
||
const completedLevels = Object.keys(this.user.progress).length;
|
||
const totalLevels = 4;
|
||
const progress = (completedLevels / totalLevels) * 100;
|
||
|
||
document.getElementById('progress-fill').style.width = `${progress}%`;
|
||
|
||
// Update level cards
|
||
document.querySelectorAll('.level-card').forEach(card => {
|
||
const level = parseInt(card.dataset.level);
|
||
if (this.user.progress[level]) {
|
||
card.style.borderColor = 'var(--neon-green)';
|
||
card.style.boxShadow = '0 0 20px var(--neon-green)';
|
||
}
|
||
});
|
||
|
||
// Update secret level card
|
||
const secretLevelCard = document.getElementById('secret-level');
|
||
if (secretLevelCard) {
|
||
if (this.user.secretUnlocked) {
|
||
secretLevelCard.classList.remove('locked');
|
||
secretLevelCard.classList.add('unlocked');
|
||
secretLevelCard.style.borderColor = 'var(--neon-pink)';
|
||
secretLevelCard.style.boxShadow = '0 0 20px var(--neon-pink)';
|
||
} else {
|
||
secretLevelCard.classList.add('locked');
|
||
secretLevelCard.classList.remove('unlocked');
|
||
}
|
||
}
|
||
|
||
// Show recommended level after placement test
|
||
if (this.user.placementTest) {
|
||
const recommendedLevel = this.user.placementTest.recommendedLevel;
|
||
const recommendedCard = document.querySelector(`[data-level="${recommendedLevel}"]`);
|
||
if (recommendedCard) {
|
||
recommendedCard.style.borderColor = 'var(--neon-yellow)';
|
||
recommendedCard.style.boxShadow = '0 0 20px var(--neon-yellow)';
|
||
}
|
||
}
|
||
|
||
const points = (this.user.points || 0);
|
||
const badges = (this.user.badges || []).length;
|
||
const pv = document.getElementById('points-value');
|
||
const bc = document.getElementById('badges-count');
|
||
if (pv) pv.textContent = points;
|
||
if (bc) bc.textContent = badges;
|
||
},
|
||
|
||
ensureFocusPanel() { this.bindFocusControls(); },
|
||
|
||
bindFocusControls() {
|
||
const focus = document.getElementById('toggle-focus');
|
||
const motion = document.getElementById('toggle-motion');
|
||
const dnd = document.getElementById('toggle-dnd');
|
||
const start = document.getElementById('music-start');
|
||
const stop = document.getElementById('music-stop');
|
||
const pomStart = document.getElementById('pom-start');
|
||
const pomStop = document.getElementById('pom-stop');
|
||
const paceSel = document.getElementById('pace');
|
||
if (focus) focus.onchange = (e) => { document.body.classList.toggle('focus-mode', e.target.checked); };
|
||
if (motion) motion.onchange = (e) => { document.body.classList.toggle('reduce-motion', e.target.checked); };
|
||
if (dnd) dnd.onchange = (e) => { this.settings = this.settings || {}; this.settings.doNotDisturb = e.target.checked; };
|
||
if (start) start.onclick = () => {
|
||
const type = document.getElementById('music-type').value;
|
||
const vol = parseFloat(document.getElementById('music-volume').value);
|
||
const mins = parseInt(document.getElementById('music-mins').value, 10);
|
||
this.startFocusAudio(type, vol, mins);
|
||
};
|
||
if (stop) stop.onclick = () => this.stopFocusAudio();
|
||
if (pomStart) pomStart.onclick = () => {
|
||
const w = parseInt(document.getElementById('work-mins').value, 10);
|
||
const b = parseInt(document.getElementById('break-mins').value, 10);
|
||
this.startPomodoro(w, b);
|
||
};
|
||
if (pomStop) pomStop.onclick = () => this.stopPomodoro();
|
||
if (paceSel) paceSel.onchange = (e) => { this.settings = this.settings || {}; this.settings.pace = e.target.value; };
|
||
},
|
||
|
||
openFocusTools() {
|
||
const overlay = document.getElementById('focus-overlay');
|
||
if (overlay) overlay.classList.remove('hidden');
|
||
},
|
||
|
||
closeFocusTools() {
|
||
const overlay = document.getElementById('focus-overlay');
|
||
if (overlay) overlay.classList.add('hidden');
|
||
},
|
||
|
||
startFocusAudio(type, volume, minutes) {
|
||
if (!this.audioCtx) this.audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
||
this.stopFocusAudio();
|
||
const ctx = this.audioCtx;
|
||
const gain = ctx.createGain();
|
||
gain.gain.value = volume || 0.2;
|
||
gain.connect(ctx.destination);
|
||
if (type === 'binaural') {
|
||
const oscL = ctx.createOscillator();
|
||
const oscR = ctx.createOscillator();
|
||
oscL.frequency.value = 200;
|
||
oscR.frequency.value = 204;
|
||
oscL.connect(gain);
|
||
oscR.connect(gain);
|
||
oscL.start(); oscR.start();
|
||
this.audioNodes = [oscL, oscR, gain];
|
||
} else {
|
||
const bufferSize = 2 * ctx.sampleRate;
|
||
const noiseBuffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate);
|
||
const output = noiseBuffer.getChannelData(0);
|
||
for (let i = 0; i < bufferSize; i++) {
|
||
const white = Math.random() * 2 - 1;
|
||
output[i] = type === 'brown' ? ((output[i-1] || 0) * 0.98 + white * 0.02) : white * 0.3;
|
||
}
|
||
const source = ctx.createBufferSource();
|
||
source.buffer = noiseBuffer;
|
||
source.loop = true;
|
||
source.connect(gain);
|
||
source.start();
|
||
this.audioNodes = [source, gain];
|
||
}
|
||
if (minutes && minutes > 0) {
|
||
clearTimeout(this.audioTimer);
|
||
this.audioTimer = setTimeout(() => this.stopFocusAudio(), minutes * 60000);
|
||
}
|
||
},
|
||
|
||
stopFocusAudio() {
|
||
if (this.audioNodes) {
|
||
this.audioNodes.forEach(n => { try { if (n.stop) n.stop(); if (n.disconnect) n.disconnect(); } catch(_){} });
|
||
}
|
||
this.audioNodes = null;
|
||
if (this.audioTimer) { clearTimeout(this.audioTimer); this.audioTimer = null; }
|
||
},
|
||
|
||
startPomodoro(workMins, breakMins) {
|
||
this.stopPomodoro();
|
||
this.pomodoro = { phase: 'work', workMins, breakMins, remaining: workMins * 60 };
|
||
this.updatePomStatus();
|
||
this.pomInterval = setInterval(() => {
|
||
this.pomodoro.remaining--;
|
||
if (this.pomodoro.remaining <= 0) {
|
||
if (this.pomodoro.phase === 'work') {
|
||
this.pomodoro.phase = 'break';
|
||
this.pomodoro.remaining = breakMins * 60;
|
||
this.updateMascot('thinking', 'Break time! / Перерыв!');
|
||
this.showBreathingOverlay();
|
||
this.beep(880, 200);
|
||
} else {
|
||
this.pomodoro.phase = 'work';
|
||
this.pomodoro.remaining = workMins * 60;
|
||
this.updateMascot('excited', 'Back to work! / Возвращаемся к делу!');
|
||
this.beep(660, 200);
|
||
}
|
||
}
|
||
this.updatePomStatus();
|
||
}, 1000);
|
||
},
|
||
|
||
stopPomodoro() {
|
||
if (this.pomInterval) clearInterval(this.pomInterval);
|
||
this.pomInterval = null; this.pomodoro = null;
|
||
const el = document.getElementById('pom-status'); if (el) el.textContent = 'Pomodoro: idle';
|
||
},
|
||
|
||
updatePomStatus() {
|
||
const el = document.getElementById('pom-status');
|
||
if (!el || !this.pomodoro) return;
|
||
const m = Math.floor(this.pomodoro.remaining / 60);
|
||
const s = String(this.pomodoro.remaining % 60).padStart(2,'0');
|
||
el.textContent = `Pomodoro: ${this.pomodoro.phase} ${m}:${s}`;
|
||
},
|
||
|
||
showBreathingOverlay() {
|
||
const overlay = document.createElement('div');
|
||
overlay.style.position = 'fixed'; overlay.style.left = 0; overlay.style.top = 0; overlay.style.right = 0; overlay.style.bottom = 0;
|
||
overlay.style.background = 'rgba(0,0,0,0.5)'; overlay.style.zIndex = 999;
|
||
const circle = document.createElement('div');
|
||
circle.style.width = '100px'; circle.style.height = '100px'; circle.style.borderRadius = '50%';
|
||
circle.style.margin = '20% auto'; circle.style.background = 'var(--neon-blue)';
|
||
circle.style.animation = 'pulse 6s ease-in-out 3';
|
||
overlay.appendChild(circle);
|
||
document.body.appendChild(overlay);
|
||
setTimeout(() => { if (overlay.parentNode) overlay.parentNode.removeChild(overlay); }, 18000);
|
||
},
|
||
|
||
beep(freq, duration) {
|
||
if (!this.audioCtx) this.audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
||
const ctx = this.audioCtx; const osc = ctx.createOscillator(); const gain = ctx.createGain();
|
||
osc.frequency.value = freq; gain.gain.value = 0.05; osc.connect(gain); gain.connect(ctx.destination);
|
||
osc.start(); setTimeout(() => { try { osc.stop(); } catch(_){} }, duration || 120);
|
||
},
|
||
|
||
getAnswerDelay() {
|
||
const pace = (this.settings && this.settings.pace) || 'normal';
|
||
if (pace === 'slow') return 2000;
|
||
if (pace === 'fast') return 800;
|
||
return 1500;
|
||
},
|
||
|
||
// Mascot Management
|
||
updateMascot(mood, message) {
|
||
const mascot = document.getElementById('mascot');
|
||
const messageEl = document.getElementById('mascot-message');
|
||
|
||
// Update mascot appearance based on mood
|
||
const moods = {
|
||
happy: 'assets/ui/mascot_happy.svg',
|
||
excited: 'assets/ui/mascot_excited.svg',
|
||
thinking: 'assets/ui/mascot_thinking.svg',
|
||
sad: 'assets/ui/mascot_sad.svg'
|
||
};
|
||
|
||
const bgImage = moods[mood] || 'assets/mascot_main.svg';
|
||
mascot.style.backgroundImage = `url('${bgImage}')`;
|
||
mascot.textContent = ''; // Clear emoji if present
|
||
|
||
if (message) {
|
||
messageEl.textContent = message;
|
||
messageEl.style.display = 'block';
|
||
setTimeout(() => {
|
||
messageEl.style.display = 'none';
|
||
}, 3000);
|
||
}
|
||
},
|
||
|
||
// Visual Effects
|
||
showFloatingText(text, color) {
|
||
const floatingText = document.createElement('div');
|
||
floatingText.className = 'floating-text';
|
||
floatingText.textContent = text;
|
||
floatingText.style.color = color;
|
||
floatingText.style.left = '50%';
|
||
floatingText.style.top = '50%';
|
||
floatingText.style.transform = 'translate(-50%, -50%)';
|
||
|
||
document.body.appendChild(floatingText);
|
||
|
||
setTimeout(() => {
|
||
floatingText.remove();
|
||
}, 2000);
|
||
},
|
||
|
||
getTraeImageUrl(prompt, size = 'square') {
|
||
const encoded = encodeURIComponent(prompt);
|
||
return `https://trae-api-us.mchost.guru/api/ide/v1/text_to_image?prompt=${encoded}&image_size=${size}`;
|
||
},
|
||
|
||
getImageSrc(key) {
|
||
// Check local assets first
|
||
if (window.LOCAL_ASSETS && window.LOCAL_ASSETS[key]) {
|
||
return window.LOCAL_ASSETS[key];
|
||
}
|
||
|
||
// FORCE OFFLINE MODE: Return default if missing
|
||
console.warn('Missing asset for key:', key);
|
||
return window.LOCAL_ASSETS['question'] || 'assets/vocab/question.jpg';
|
||
|
||
const prompts = {
|
||
question: 'question mark 3d icon cute cartoon game asset, white background',
|
||
age: 'number ten colorful 3d icon game asset, white background',
|
||
sky: 'blue sky with fluffy white clouds cute cartoon illustration, white background',
|
||
number: 'number six blue glossy 3d icon game asset, white background',
|
||
dog: 'puppy dog cute 3d render cartoon icon game asset, white background',
|
||
leaf: 'fresh green leaf single object cute 3d icon game asset, white background',
|
||
bird: 'blue bird flying cute 3d render cartoon icon, white background',
|
||
cat: 'kitten cat cute 3d render cartoon icon, white background',
|
||
cow: 'cow farm animal cute 3d render cartoon icon, white background',
|
||
eagle: 'eagle bird wings spread heroic 3d render, white background',
|
||
fish: 'tropical fish underwater cute 3d render, white background',
|
||
tiger: 'tiger animal striped cute 3d render, white background',
|
||
lion: 'lion animal majestic cute 3d render, white background',
|
||
monkey: 'monkey holding banana cute 3d render, white background',
|
||
elephant: 'elephant big animal cute 3d render, white background',
|
||
kangaroo: 'kangaroo animal jumping cute 3d render, white background',
|
||
owl: 'owl bird with big eyes cute 3d render, white background',
|
||
giraffe: 'giraffe long neck cute 3d render, white background',
|
||
dolphin: 'dolphin jumping cute 3d render, white background',
|
||
turtle: 'turtle reptile cute 3d render, white background',
|
||
panda: 'panda bear cute 3d render, white background',
|
||
tree: 'tree single object cute 3d icon, white background',
|
||
flower: 'flower blossom cute 3d icon, white background',
|
||
grass: 'grass tuft cute 3d icon, white background',
|
||
autumn: 'autumn fall leaves orange cute 3d icon, white background',
|
||
plant: 'potted plant cute 3d icon, white background',
|
||
forest: 'forest trees stylized cute illustration, white background',
|
||
honey: 'jar of honey with dipper cute 3d icon, white background',
|
||
apple: 'red apple fruit cute 3d render, white background',
|
||
banana: 'banana fruit cute 3d render, white background',
|
||
watermelon: 'watermelon slice cute 3d render, white background',
|
||
grapes: 'grapes bunch cute 3d render, white background',
|
||
orange: 'orange fruit cute 3d render, white background',
|
||
sun: 'sun shining cute 3d icon, white background',
|
||
rain: 'rain cloud with drops cute 3d icon, white background',
|
||
snow: 'snowflake cute 3d icon, white background',
|
||
wind: 'wind swirl lines cute 3d icon, white background',
|
||
clouds: 'fluffy clouds cute 3d icon, white background',
|
||
ice: 'ice cube cute 3d icon, white background',
|
||
rainbow: 'rainbow arc cute 3d icon, white background',
|
||
lightning: 'lightning bolt cute 3d icon, white background',
|
||
fog: 'fog mist stylized illustration, white background',
|
||
temperature: 'thermometer cute 3d icon, white background',
|
||
spring: 'spring flowers cute 3d icon, white background',
|
||
thunder: 'thunderstorm cloud with bolt cute 3d icon, white background',
|
||
house: 'house home facade cute 3d render cartoon icon, white background',
|
||
car: 'red car cute 3d render cartoon icon, white background',
|
||
school: 'school building front view cute 3d render icon, white background',
|
||
hospital: 'hospital building with red cross cute 3d render icon, white background',
|
||
library: 'bookshelf library cute 3d icon, white background',
|
||
store: 'grocery store facade cute 3d render icon, white background',
|
||
cinema: 'cinema movie theater sign and tickets cute 3d icon, white background',
|
||
airplane: 'airplane flying cute 3d render, white background',
|
||
gym: 'dumbbells gym equipment cute 3d icon, white background',
|
||
hotel: 'hotel building with sign cute 3d render, white background',
|
||
restaurant: 'restaurant plate fork knife cute 3d icon, white background',
|
||
office: 'office desk with computer cute 3d icon, white background',
|
||
market: 'street market stalls cute 3d icon, white background',
|
||
subway: 'subway train underground cute 3d render, white background',
|
||
train: 'train locomotive cute 3d render, white background',
|
||
bicycle: 'bicycle two wheels cute 3d render, white background',
|
||
bus: 'bus vehicle cute 3d render, white background',
|
||
boat: 'boat sailboat cute 3d render, white background',
|
||
ambulance: 'ambulance vehicle with siren cute 3d render, white background',
|
||
truck: 'delivery truck cute 3d render, white background',
|
||
helicopter: 'helicopter with rotors cute 3d render, white background',
|
||
tickets: 'movie tickets stub cute 3d icon, white background',
|
||
traffic: 'traffic lights red yellow green cute 3d icon, white background',
|
||
street: 'city street crosswalk cute 3d icon, white background',
|
||
city: 'city skyline buildings cute 3d icon, white background',
|
||
crosswalk: 'zebra crossing crosswalk cute 3d icon, white background',
|
||
moon: 'moon crescent cute 3d render, white background',
|
||
rocket: 'rocket ship blasting off cute 3d render, white background',
|
||
star: 'gold star cute 3d render, white background',
|
||
mars: 'mars red planet cute 3d render, white background',
|
||
jupiter: 'jupiter gas giant cute 3d render, white background',
|
||
saturn: 'saturn planet with rings cute 3d render, white background',
|
||
earth: 'planet earth globe cute 3d render, white background',
|
||
sun: 'sun star glowing cute 3d render, white background',
|
||
astronaut: 'astronaut floating in space cute 3d render, white background',
|
||
satellite: 'satellite with solar panels cute 3d render, white background',
|
||
station: 'international space station cute 3d render, white background',
|
||
telescope: 'telescope looking at stars cute 3d icon, white background',
|
||
galaxy: 'spiral galaxy night sky cute 3d render, white background',
|
||
computer: 'laptop computer cute 3d render, white background',
|
||
router: 'wifi router with antennas cute 3d icon, white background',
|
||
software: 'code window software UI cute 3d icon, white background',
|
||
phone: 'smartphone screen cute 3d render, white background',
|
||
storage: 'hard drive storage cute 3d icon, white background',
|
||
camera: 'photo camera cute 3d render, white background',
|
||
printer: 'printer device cute 3d render, white background',
|
||
electricity: 'electric bolt symbol cute 3d icon, white background',
|
||
metal: 'metal gear cog cute 3d icon, white background',
|
||
circuit: 'circuit board chip cute 3d icon, white background',
|
||
meter: 'electric meter gauge cute 3d icon, white background',
|
||
battery: 'battery charge cute 3d icon, white background',
|
||
transformer: 'electric transformer box cute 3d icon, white background',
|
||
current: 'electric current symbol cute 3d icon, white background',
|
||
resistance: 'resistor electronic component cute 3d icon, white background',
|
||
generator: 'electric generator machine cute 3d icon, white background',
|
||
switch: 'light switch cute 3d icon, white background',
|
||
secret: 'locked secret folder cute 3d icon, white background',
|
||
course: 'course book with bookmark cute 3d icon, white background',
|
||
key: 'gold key cute 3d render, white background',
|
||
treasure: 'treasure chest open gold coins cute 3d render, white background',
|
||
mystery: 'mystery box glowing cute 3d render, white background',
|
||
password: 'password field with dots cute 3d icon, white background',
|
||
encryption: 'padlock and code matrix cute 3d icon, white background',
|
||
classified: 'classified stamp file cute 3d icon, white background',
|
||
invisible: 'invisible cloak silhouette cute 3d icon, white background',
|
||
special: 'special badge ribbon cute 3d icon, white background',
|
||
exclusive: 'exclusive medal ribbon cute 3d icon, white background',
|
||
expert: 'expert star medal cute 3d icon, white background',
|
||
achievement: 'trophy cup achievement cute 3d render, white background',
|
||
certificate: 'certificate diploma scroll cute 3d icon, white background',
|
||
excellence: 'gold trophy excellence cute 3d render, white background',
|
||
mastery: 'laurel wreath medal mastery cute 3d render, white background',
|
||
graduation: 'graduation cap mortarboard cute 3d render, white background',
|
||
knowledge: 'open book pages cute 3d icon, white background',
|
||
wisdom: 'owl on book wisdom cute 3d icon, white background',
|
||
skill: 'toolbox tools skill cute 3d icon, white background',
|
||
talent: 'star medal talent cute 3d icon, white background',
|
||
genius: 'brain with lightbulb genius cute 3d icon, white background',
|
||
brilliance: 'shining star brilliance cute 3d icon, white background',
|
||
victory: 'winner trophy victory cute 3d render, white background',
|
||
future: 'futuristic city skyline cute 3d illustration, white background',
|
||
dream: 'dream cloud and moon cute 3d render, white background',
|
||
ambition: 'goal flag on mountain ambition cute 3d icon, white background',
|
||
destiny: 'compass destiny cute 3d icon, white background',
|
||
potential: 'seed sprout potential cute 3d icon, white background',
|
||
opportunity: 'open door opportunity cute 3d icon, white background',
|
||
possibility: 'question boxes possibility cute 3d icon, white background',
|
||
hope: 'hope ribbon cute 3d icon, white background',
|
||
aspiration: 'rocket aspiration cute 3d icon, white background',
|
||
vision: 'eye vision cute 3d icon, white background',
|
||
imagination: 'magic sparkles imagination cute 3d icon, white background',
|
||
innovation: 'lightbulb with gear innovation cute 3d icon, white background'
|
||
};
|
||
|
||
const prompt = prompts[key] || `${key} 3d render cute cartoon icon game asset, white background, single object`;
|
||
return this.getTraeImageUrl(prompt, 'square');
|
||
},
|
||
getCachedImageSrc(key) {
|
||
if (this.imageURLs[key]) return this.imageURLs[key];
|
||
const url = this.getImageSrc(key);
|
||
this.imageURLs[key] = url;
|
||
return url;
|
||
},
|
||
collectAllImageKeys() {
|
||
const keys = new Set();
|
||
(this.PLACEMENT_QUESTIONS || []).forEach(q => { if (q.imageKey) keys.add(q.imageKey); });
|
||
const levels = this.QUESTIONS || {};
|
||
Object.keys(levels).forEach(lvl => {
|
||
['groupA','groupB','groupC'].forEach(g => {
|
||
const arr = levels[lvl][g] || [];
|
||
arr.forEach(q => { if (q.imageKey) keys.add(q.imageKey); });
|
||
});
|
||
});
|
||
return Array.from(keys);
|
||
},
|
||
preloadAllImages() {
|
||
try {
|
||
const keys = this.collectAllImageKeys();
|
||
keys.forEach(k => {
|
||
const url = this.getCachedImageSrc(k);
|
||
const link = document.createElement('link');
|
||
link.rel = 'preload';
|
||
link.as = 'image';
|
||
link.href = url;
|
||
document.head.appendChild(link);
|
||
const img = new Image();
|
||
img.decoding = 'async';
|
||
img.referrerPolicy = 'no-referrer';
|
||
img.src = url;
|
||
this.imageCache[k] = img;
|
||
});
|
||
} catch(_) {}
|
||
},
|
||
|
||
setupReportDot(dotId, imgEl, meta) {
|
||
const dot = document.getElementById(dotId);
|
||
if (!dot) return;
|
||
dot.title = 'Report image issue';
|
||
dot.onclick = () => {
|
||
const payload = {
|
||
type: 'image_report',
|
||
level: this.currentLevel ?? meta.level ?? null,
|
||
questionIndex: this.currentQuestion ?? meta.index ?? null,
|
||
imageKey: meta.imageKey ?? null,
|
||
imageSrc: imgEl?.src ?? null,
|
||
questionText: (document.getElementById('question-text')?.textContent || document.getElementById('placement-question')?.textContent || '').trim(),
|
||
timestamp: new Date().toISOString()
|
||
};
|
||
|
||
try {
|
||
const logs = JSON.parse(localStorage.getItem('image_reports') || '[]');
|
||
logs.push(payload);
|
||
localStorage.setItem('image_reports', JSON.stringify(logs));
|
||
} catch(_) {}
|
||
|
||
try { console.info('IMAGE_REPORT', payload); } catch(_) {}
|
||
|
||
this.showFloatingText('Reported / Отправлено', '#EA4335');
|
||
};
|
||
},
|
||
|
||
// Legacy SVGs kept for fallback if ever needed
|
||
generateSVG(key) {
|
||
const svgMap = {
|
||
dog: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="50" r="40" fill="#8B4513"/>
|
||
<circle cx="35" cy="40" r="5" fill="black"/>
|
||
<circle cx="65" cy="40" r="5" fill="black"/>
|
||
<ellipse cx="50" cy="60" rx="10" ry="5" fill="black"/>
|
||
<path d="M20 30 Q10 20 15 10" stroke="#8B4513" stroke-width="8" fill="none"/>
|
||
<path d="M80 30 Q90 20 85 10" stroke="#8B4513" stroke-width="8" fill="none"/>
|
||
</svg>`,
|
||
question: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="15" y="25" width="70" height="35" rx="10" fill="#4285F4"/>
|
||
<path d="M25 70 C25 70 25 80 35 80 H75" stroke="#4285F4" stroke-width="6" fill="none"/>
|
||
<circle cx="35" cy="40" r="3" fill="#fff"/>
|
||
<circle cx="65" cy="40" r="3" fill="#fff"/>
|
||
<text x="50" y="48" text-anchor="middle" fill="#FFFFFF" font-size="16" font-weight="700">?</text>
|
||
</svg>`,
|
||
age: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="18" y="30" width="20" height="20" rx="4" fill="#FBBC05"/>
|
||
<rect x="40" y="30" width="22" height="22" rx="4" fill="#34A853"/>
|
||
<rect x="64" y="30" width="18" height="18" rx="4" fill="#4285F4"/>
|
||
<text x="28" y="44" text-anchor="middle" fill="#111" font-size="12" font-weight="700">6</text>
|
||
<text x="51" y="45" text-anchor="middle" fill="#fff" font-size="12" font-weight="700">10</text>
|
||
<text x="73" y="43" text-anchor="middle" fill="#fff" font-size="12" font-weight="700">15</text>
|
||
</svg>`,
|
||
sky: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect width="100" height="70" fill="#88C5F7"/>
|
||
<circle cx="20" cy="20" r="10" fill="#FFD93D"/>
|
||
<ellipse cx="50" cy="35" rx="20" ry="10" fill="#FFFFFF"/>
|
||
<ellipse cx="75" cy="28" rx="16" ry="8" fill="#FFFFFF"/>
|
||
<rect y="70" width="100" height="30" fill="#FDFCF5"/>
|
||
</svg>`,
|
||
number: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="15" y="28" width="70" height="44" rx="8" fill="#6B74E6"/>
|
||
<text x="50" y="56" text-anchor="middle" fill="#FFFFFF" font-size="22" font-weight="800">6</text>
|
||
<text x="32" y="56" text-anchor="middle" fill="#DDE3FF" font-size="14" font-weight="700">5</text>
|
||
<text x="68" y="56" text-anchor="middle" fill="#DDE3FF" font-size="14" font-weight="700">7</text>
|
||
</svg>`,
|
||
cat: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="52" r="28" fill="#FFB45A"/>
|
||
<polygon points="32,28 40,38 36,42" fill="#FFB45A"/>
|
||
<polygon points="68,28 60,38 64,42" fill="#FFB45A"/>
|
||
<circle cx="42" cy="50" r="3" fill="#111"/>
|
||
<circle cx="58" cy="50" r="3" fill="#111"/>
|
||
<path d="M43 58 Q50 62 57 58" stroke="#111" stroke-width="2" fill="none"/>
|
||
<path d="M45 55 L38 60 M55 55 L62 60" stroke="#111" stroke-width="1"/>
|
||
</svg>`,
|
||
bird: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="50" rx="25" ry="20" fill="#4169E1"/>
|
||
<circle cx="40" cy="45" r="3" fill="black"/>
|
||
<polygon points="25,50 10,45 15,55" fill="#FFA500"/>
|
||
<polygon points="75,50 90,45 85,55" fill="#FFA500"/>
|
||
<path d="M50 50 Q60 45 70 50" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
fish: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="50" rx="30" ry="15" fill="#00CED1"/>
|
||
<circle cx="35" cy="45" r="3" fill="black"/>
|
||
<polygon points="75,50 90,35 90,65" fill="#00CED1"/>
|
||
<path d="M30 50 Q20 45 25 55" stroke="#00CED1" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
leaf: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M50 20 Q30 40 50 80 Q70 40 50 20" fill="#228B22"/>
|
||
<line x1="50" y1="20" x2="50" y2="80" stroke="#006400" stroke-width="2"/>
|
||
</svg>`,
|
||
house: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 80,50 20,50" fill="#8B4513"/>
|
||
<rect x="30" y="50" width="40" height="30" fill="#D2691E"/>
|
||
<rect x="40" y="60" width="10" height="20" fill="#654321"/>
|
||
<rect x="60" y="55" width="8" height="8" fill="#87CEEB"/>
|
||
</svg>`,
|
||
car: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="40" width="60" height="20" fill="#FF0000"/>
|
||
<rect x="30" y="25" width="40" height="15" fill="#FF0000"/>
|
||
<circle cx="30" cy="65" r="8" fill="#333"/>
|
||
<circle cx="70" cy="65" r="8" fill="#333"/>
|
||
<rect x="35" y="30" width="10" height="8" fill="#87CEEB"/>
|
||
<rect x="55" y="30" width="10" height="8" fill="#87CEEB"/>
|
||
</svg>`,
|
||
school: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="25" y="40" width="50" height="40" fill="#F0E68C"/>
|
||
<polygon points="50,20 75,40 25,40" fill="#8B4513"/>
|
||
<rect x="35" y="50" width="10" height="10" fill="#87CEEB"/>
|
||
<rect x="55" y="50" width="10" height="10" fill="#87CEEB"/>
|
||
<rect x="45" y="65" width="10" height="15" fill="#654321"/>
|
||
</svg>`,
|
||
moon: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="50" r="30" fill="#F0E68C"/>
|
||
<circle cx="60" cy="40" r="25" fill="#0B002B"/>
|
||
</svg>`,
|
||
rocket: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,60 50,80 40,60" fill="#C0C0C0"/>
|
||
<polygon points="40,60 30,80 40,70" fill="#FF0000"/>
|
||
<polygon points="60,60 70,80 60,70" fill="#FF0000"/>
|
||
<circle cx="50" cy="40" r="5" fill="#87CEEB"/>
|
||
</svg>`,
|
||
star: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,15 61,41 89,41 67,59 78,85 50,67 22,85 33,59 11,41 39,41" fill="#FFD700"/>
|
||
</svg>`,
|
||
secret: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="30" y="40" width="40" height="40" fill="#FF00FF"/>
|
||
<path d="M50 30 Q40 40 50 50 Q60 40 50 30" fill="#FF00FF"/>
|
||
<circle cx="50" cy="55" r="3" fill="#FFF"/>
|
||
</svg>`,
|
||
course: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="30" width="60" height="40" fill="#4169E1"/>
|
||
<rect x="25" y="35" width="50" height="5" fill="white"/>
|
||
<rect x="25" y="45" width="50" height="5" fill="white"/>
|
||
<rect x="25" y="55" width="50" height="5" fill="white"/>
|
||
</svg>`,
|
||
key: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="30" cy="50" r="15" fill="#FFD700"/>
|
||
<rect x="30" y="45" width="40" height="10" fill="#FFD700"/>
|
||
<rect x="60" y="45" width="5" height="5" fill="#FFD700"/>
|
||
<rect x="65" y="45" width="5" height="5" fill="#FFD700"/>
|
||
</svg>`
|
||
};
|
||
|
||
const svg = svgMap[key] || this.generateCustomSVG(key);
|
||
return 'data:image/svg+xml;base64,' + btoa(svg);
|
||
},
|
||
|
||
generateCustomSVG(key) {
|
||
const customSVGs = {
|
||
// Animals
|
||
cow: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="50" rx="35" ry="25" fill="#8B4513"/>
|
||
<circle cx="35" cy="40" r="3" fill="black"/>
|
||
<circle cx="65" cy="40" r="3" fill="black"/>
|
||
<ellipse cx="50" cy="65" rx="15" ry="8" fill="black"/>
|
||
<path d="M30 50 Q40 45 50 55" stroke="black" stroke-width="2" fill="none"/>
|
||
<path d="M20 60 Q50 50 80 60" stroke="black" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
eagle: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="50" rx="30" ry="20" fill="#8B4513"/>
|
||
<circle cx="40" cy="45" r="3" fill="black"/>
|
||
<polygon points="25,50 10,45 15,55" fill="#FFA500"/>
|
||
<polygon points="75,50 90,45 85,55" fill="#FFA500"/>
|
||
<path d="M30 40 Q50 30 70 40" stroke="white" stroke-width="2" fill="none"/>
|
||
<path d="M20 60 Q50 50 80 60" stroke="white" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
fish: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="50" rx="30" ry="15" fill="#00CED1"/>
|
||
<circle cx="35" cy="45" r="3" fill="black"/>
|
||
<polygon points="75,50 90,35 90,65" fill="#00CED1"/>
|
||
<path d="M30 50 Q20 45 25 55" stroke="#00CED1" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
tiger: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="50" rx="35" ry="25" fill="#FF8C00"/>
|
||
<circle cx="40" cy="40" r="3" fill="black"/>
|
||
<path d="M30 50 L70 50" stroke="black" stroke-width="3" fill="none"/>
|
||
<path d="M30 50 L70 50" stroke="black" stroke-width="3" fill="none"/>
|
||
<circle cx="65" cy="40" r="3" fill="black"/>
|
||
</svg>`,
|
||
elephant: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="50" rx="35" ry="30" fill="#8B4513"/>
|
||
<circle cx="35" cy="40" r="3" fill="black"/>
|
||
<path d="M30 50 Q40 45 20 50" stroke="black" stroke-width="3" fill="none"/>
|
||
<circle cx="65" cy="40" r="3" fill="black"/>
|
||
<path d="M50 50 Q60 45 80 50" stroke="black" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
kangaroo: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="50" rx="30" ry="25" fill="#8B4513"/>
|
||
<circle cx="40" cy="45" r="3" fill="black"/>
|
||
<circle cx="60" cy="40" r="3" fill="black"/>
|
||
<path d="M30 50 Q40 45 20 50" stroke="black" stroke-width="3" fill="none"/>
|
||
<path d="M60 50 Q80 45 90 50" stroke="black" stroke-width="3" fill="none"/>
|
||
<path d="M50 50 L60 30" stroke="black" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
owl: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="50" rx="30" ry="25" fill="#8B4513"/>
|
||
<circle cx="40" cy="40" r="3" fill="black"/>
|
||
<circle cx="60" cy="40" r="3" fill="black"/>
|
||
<path d="M30 50 Q40 45 20 50" stroke="black" stroke-width="3" fill="none"/>
|
||
<path d="M60 50 Q80 45 90 50" stroke="black" stroke-width="3" fill="none"/>
|
||
<path d="M50 50 L60 30" stroke="black" stroke-width="3" fill="none"/>
|
||
<circle cx="50" cy="30" r="5" fill="#FFD700"/>
|
||
</svg>`,
|
||
giraffe: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="50" rx="25" ry="35" fill="#8B4513"/>
|
||
<circle cx="40" cy="40" r="3" fill="black"/>
|
||
<circle cx="60" cy="40" r="3" fill="black"/>
|
||
<path d="M30 50 Q40 45 20 50" stroke="black" stroke-width="3" fill="none"/>
|
||
<path d="M60 50 Q80 45 90 50" stroke="black" stroke-width="3" fill="none"/>
|
||
<path d="M50 50 L60 30" stroke="black" stroke-width="3" fill="none"/>
|
||
<path d="M50 50 L50 20" stroke="black" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
dolphin: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="50" rx="30" ry="15" fill="#00CED1"/>
|
||
<circle cx="35" cy="45" r="3" fill="black"/>
|
||
<path d="M30 50 Q40 45 20 50" stroke="#00CED1" stroke-width="3" fill="none"/>
|
||
<path d="M60 50 Q80 45 90 50" stroke="#00CED1" stroke-width="3" fill="none"/>
|
||
<path d="M50 50 L60 30" stroke="#00CED1" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
turtle: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="50" rx="30" ry="20" fill="#8B4513"/>
|
||
<circle cx="40" cy="45" r="3" fill="black"/>
|
||
<path d="M30 50 Q40 45 20 50" stroke="black" stroke-width="3" fill="none"/>
|
||
<path d="M60 50 Q80 45 90 50" stroke="black" stroke-width="3" fill="none"/>
|
||
<path d="M50 50 L60 30" stroke="black" stroke-width="3" fill="none"/>
|
||
<path d="M30 50 L70 50" stroke="black" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
panda: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="50" rx="30" ry="25" fill="#8B4513"/>
|
||
<circle cx="40" cy="40" r="3" fill="black"/>
|
||
<circle cx="60" cy="40" r="3" fill="black"/>
|
||
<path d="M30 50 Q40 45 20 50" stroke="black" stroke-width="3" fill="none"/>
|
||
<path d="M60 50 Q80 45 90 50" stroke="black" stroke-width="3" fill="none"/>
|
||
<path d="M50 50 L60 30" stroke="black" stroke-width="3" fill="none"/>
|
||
<circle cx="50" cy="30" r="8" fill="white"/>
|
||
<circle cx="50" cy="70" r="8" fill="white"/>
|
||
</svg>`,
|
||
monkey: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="50" rx="30" ry="25" fill="#8B4513"/>
|
||
<circle cx="40" cy="40" r="3" fill="black"/>
|
||
<circle cx="60" cy="40" r="3" fill="black"/>
|
||
<path d="M30 50 Q40 45 20 50" stroke="black" stroke-width="3" fill="none"/>
|
||
<path d="M60 50 Q80 45 90 50" stroke="black" stroke-width="3" fill="none"/>
|
||
<path d="M50 50 L60 30" stroke="black" stroke-width="3" fill="none"/>
|
||
<path d="M50 50 L60 70" stroke="black" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
|
||
// Nature
|
||
tree: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="30" y="20" width="40" height="60" fill="#228B22"/>
|
||
<circle cx="20" cy="20" r="8" fill="#FFD700"/>
|
||
<path d="M20 20 L30 50" stroke="#654321" stroke-width="3" fill="none"/>
|
||
<path d="M30 50 L20 80" stroke="#654321" stroke-width="3" fill="none"/>
|
||
<path d="M30 50 L70 80" stroke="#654321" stroke-width="3" fill="none"/>
|
||
<path d="M70 50 L30 80" stroke="#654321" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
flower: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="40" r="15" fill="#FF69B4"/>
|
||
<circle cx="35" cy="30" r="5" fill="#FFD700"/>
|
||
<circle cx="65" cy="30" r="5" fill="#FFD700"/>
|
||
<path d="M35 30 L50 40" stroke="#654321" stroke-width="2" fill="none"/>
|
||
<path d="M50 40 L65 30" stroke="#654321" stroke-width="2" fill="none"/>
|
||
<path d="M65 30 L50 40" stroke="#654321" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
forest: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><polygon points="20,70 30,40 40,70" fill="#228B22"/><polygon points="40,70 50,35 60,70" fill="#2E8B57"/><polygon points="60,70 70,45 80,70" fill="#3CB371"/><rect x="22" y="70" width="6" height="10" fill="#654321"/><rect x="52" y="70" width="6" height="10" fill="#654321"/><rect x="72" y="70" width="6" height="10" fill="#654321"/></svg>`,
|
||
grass: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="10" y="30" width="80" height="40" fill="#90EE90"/>
|
||
<path d="M10 30 Q20 20 30 70" stroke="#228B22" stroke-width="2" fill="none"/>
|
||
<path d="M20 70 Q30 80 30 70" stroke="#228B22" stroke-width="2" fill="none"/>
|
||
<path d="M30 70 Q40 80 40 70" stroke="#228B22" stroke-width="2" fill="none"/>
|
||
<path d="M40 70 Q50 80 30 70" stroke="#228B22" stroke-width="2" fill="none"/>
|
||
<path d="M50 70 Q60 80 20 70" stroke="#228B22" stroke-width="2" fill="none"/>
|
||
<path d="M60 70 Q70 80 10 70" stroke="#228B22" stroke-width="2" fill="none"/>
|
||
<path d="M70 70 Q80 80 30 70" stroke="#228B22" stroke-width="2" fill="none"/>
|
||
<path d="M80 70 L90 30" stroke="#228B22" stroke-width="2" fill="none"/>
|
||
<path d="M90 30 L80 70" stroke="#228B22" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
autumn: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="30" cy="50" r="10" fill="#FFA500"/><circle cx="50" cy="45" r="12" fill="#FF8C00"/><circle cx="70" cy="55" r="9" fill="#DAA520"/><rect x="48" y="58" width="4" height="12" fill="#8B4513"/></svg>`,
|
||
plant: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="30" width="60" height="40" fill="#228B22"/>
|
||
<circle cx="35" cy="25" r="5" fill="#90EE90"/>
|
||
<circle cx="65" cy="25" r="5" fill="#90EE90"/>
|
||
<path d="M35 25 L50 35" stroke="#90EE90" stroke-width="2" fill="none"/>
|
||
<path d="M50 35 L65 25" stroke="#90EE90" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
honey: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="30" cy="60" rx="20" ry="15" fill="#FFD700"/>
|
||
<ellipse cx="50" cy="40" rx="25" ry="20" fill="#FFA500"/>
|
||
<ellipse cx="70" cy="60" rx="20" ry="15" fill="#FFD700"/>
|
||
<path d="M30 60 Q50 50 40 50" stroke="#8B4513" stroke-width="2" fill="none"/>
|
||
<path d="M50 40 Q70 50 30 50" stroke="#8B4513" stroke-width="2" fill="none"/>
|
||
<path d="M70 60 Q50 70 40 50" stroke="#8B4513" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
apple: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="40" r="20" fill="#FF0000"/>
|
||
<path d="M30 40 Q50 20 50 40" stroke="#8B0000" stroke-width="2" fill="none"/>
|
||
<path d="M50 40 Q70 20 50 40" stroke="#8B0000" stroke-width="2" fill="none"/>
|
||
<path d="M70 40 Q50 20 50 40" stroke="#8B0000" stroke-width="2" fill="none"/>
|
||
<circle cx="40" cy="60" r="5" fill="#90EE90"/>
|
||
<circle cx="60" cy="60" r="5" fill="#90EE90"/>
|
||
</svg>`,
|
||
banana: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="40" rx="20" ry="30" fill="#FFE135"/>
|
||
<path d="M30 40 Q50 20 50 40" stroke="#8B7500" stroke-width="2" fill="none"/>
|
||
<path d="M50 40 Q70 20 50 40" stroke="#8B7500" stroke-width="2" fill="none"/>
|
||
<path d="M70 40 Q50 20 50 40" stroke="#8B7500" stroke-width="2" fill="none"/>
|
||
<circle cx="40" cy="60" r="5" fill="#90EE90"/>
|
||
<circle cx="60" cy="60" r="5" fill="#90EE90"/>
|
||
</svg>`,
|
||
watermelon: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="40" rx="30" ry="25" fill="#90EE90"/>
|
||
<path d="M20 40 Q50 20 50 40" stroke="#90EE90" stroke-width="2" fill="none"/>
|
||
<path d="M50 40 Q80 20 50 40" stroke="#90EE90" stroke-width="2" fill="none"/>
|
||
<path d="M80 40 Q50 20 50 40" stroke="#90EE90" stroke-width="2" fill="none"/>
|
||
<circle cx="40" cy="60" r="5" fill="#FF0000"/>
|
||
<circle cx="60" cy="60" r="5" fill="#FF0000"/>
|
||
</svg>`,
|
||
grapes: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="30" cy="40" r="8" fill="#8B0000"/>
|
||
<circle cx="50" cy="30" r="8" fill="#8B0000"/>
|
||
<circle cx="70" cy="40" r="8" fill="#8B0000"/>
|
||
<path d="M30 30 Q50 20 50 30" stroke="#8B0000" stroke-width="2" fill="none"/>
|
||
<path d="M50 30 Q70 20 50 30" stroke="#8B0000" stroke-width="2" fill="none"/>
|
||
<path d="M70 30 Q50 20 50 30" stroke="#8B0000" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
orange: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="40" r="20" fill="#FFA500"/>
|
||
<path d="M30 40 Q50 20 50 40" stroke="#8B7500" stroke-width="2" fill="none"/>
|
||
<path d="M50 40 Q70 20 50 40" stroke="#8B7500" stroke-width="2" fill="none"/>
|
||
<path d="M70 40 Q50 20 50 40" stroke="#8B7500" stroke-width="2" fill="none"/>
|
||
<circle cx="40" cy="60" r="5" fill="#90EE90"/>
|
||
<circle cx="60" cy="60" r="5" fill="#90EE90"/>
|
||
</svg>`,
|
||
|
||
// Weather
|
||
sun: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="30" r="25" fill="#FFD700"/>
|
||
<path d="M25 30 Q50 20 50 30" stroke="#FFA500" stroke-width="3" fill="none"/>
|
||
<path d="M50 30 Q75 20 50 30" stroke="#FFA500" stroke-width="3" fill="none"/>
|
||
<path d="M75 30 Q50 20 50 30" stroke="#FFA500" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
rain: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M10 20 Q50 40 30 60" stroke="#4169E1" stroke-width="3" fill="none"/>
|
||
<path d="M50 40 Q30 60 70 40" stroke="#4169E1" stroke-width="3" fill="none"/>
|
||
<path d="M90 40 Q50 60 10 40" stroke="#4169E1" stroke-width="3" fill="none"/>
|
||
<circle cx="30" cy="70" r="5" fill="#87CEEB"/>
|
||
<circle cx="50" cy="70" r="5" fill="#87CEEB"/>
|
||
<circle cx="70" cy="70" r="5" fill="#87CEEB"/>
|
||
</svg>`,
|
||
snow: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="30" r="20" fill="#FFFFFF"/>
|
||
<path d="M30 30 Q50 20 50 30" stroke="#87CEEB" stroke-width="3" fill="none"/>
|
||
<path d="M50 30 Q70 20 50 30" stroke="#87CEEB" stroke-width="3" fill="none"/>
|
||
<path d="M70 30 Q50 20 50 30" stroke="#87CEEB" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
wind: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M20 50 Q50 30 70 40" stroke="#87CEEB" stroke-width="3" fill="none"/>
|
||
<path d="M50 50 Q30 70 60 40" stroke="#87CEEB" stroke-width="3" fill="none"/>
|
||
<path d="M80 50 Q30 70 20 40" stroke="#87CEEB" stroke-width="3" fill="none"/>
|
||
<circle cx="30" cy="30" r="5" fill="#FFFFFF"/>
|
||
<circle cx="50" cy="30" r="5" fill="#FFFFFF"/>
|
||
<circle cx="70" cy="30" r="5" fill="#FFFFFF"/>
|
||
</svg>`,
|
||
clouds: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="30" cy="40" rx="20" ry="15" fill="#FFFFFF"/>
|
||
<ellipse cx="50" cy="40" rx="25" ry="15" fill="#FFFFFF"/>
|
||
<ellipse cx="70" cy="40" rx="20" ry="15" fill="#FFFFFF"/>
|
||
</svg>`,
|
||
ice: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 70,20 30,40" fill="#87CEEB"/>
|
||
<polygon points="30,40 20,60 10,40" fill="#87CEEB"/>
|
||
<polygon points="70,40 80,60 90,40" fill="#87CEEB"/>
|
||
</svg>`,
|
||
rainbow: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M10 50 Q30 30 50 70" stroke="#FF0000" stroke-width="5" fill="none"/>
|
||
<path d="M50 50 Q30 70 50 30" stroke="#00FF00" stroke-width="5" fill="none"/>
|
||
<path d="M90 50 Q70 30 50 70" stroke="#00FF00" stroke-width="5" fill="none"/>
|
||
</svg>`,
|
||
lightning: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M50 20 L30 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 20 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M30 80 L50 20" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M70 80 L50 20" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
fog: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="30" cy="40" rx="20" ry="15" fill="#E0E0E0"/>
|
||
<ellipse cx="50" cy="40" rx="25" ry="15" fill="#E0E0E0"/>
|
||
<ellipse cx="70" cy="40" rx="20" ry="15" fill="#E0E0E0"/>
|
||
</svg>`,
|
||
temperature: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="30" width="60" height="40" fill="#FF4500"/>
|
||
<circle cx="30" cy="25" r="8" fill="#FF0000"/>
|
||
<text x="30" y="30" text-anchor="middle" fill="white" font-size="12">HOT</text>
|
||
<circle cx="50" cy="25" r="8" fill="#FF0000"/>
|
||
<text x="50" y="30" text-anchor="middle" fill="white" font-size="12">WARM</text>
|
||
<circle cx="70" cy="25" r="8" fill="#0000FF"/>
|
||
<text x="70" y="30" text-anchor="middle" fill="white" font-size="12">COLD</text>
|
||
</svg>`,
|
||
spring: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="10" y="30" width="80" height="40" fill="#90EE90"/>
|
||
<circle cx="30" cy="25" r="8" fill="#FF69B4"/>
|
||
<circle cx="50" cy="25" r="8" fill="#FF69B4"/>
|
||
<circle cx="70" cy="25" r="8" fill="#FF69B4"/>
|
||
<path d="M30 25 L50 40" stroke="#FF69B4" stroke-width="2" fill="none"/>
|
||
<path d="M50 40 L70 40" stroke="#FF69B4" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
thunder: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M30 50 L70 50" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<circle cx="50" cy="30" r="5" fill="#FFD700"/>
|
||
<path d="M30 30 Q20 40 10 50" stroke="#FFD700" stroke-width="2" fill="none"/>
|
||
<path d="M70 30 Q20 40 90 50" stroke="#FFD700" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
|
||
// City
|
||
hospital: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="30" width="60" height="40" fill="#FFFFFF"/>
|
||
<rect x="30" y="20" width="40" height="60" fill="#FF0000"/>
|
||
<rect x="40" y="40" width="20" height="20" fill="#87CEEB"/>
|
||
<path d="M30 50 L40 40" stroke="#FF0000" stroke-width="3" fill="none"/>
|
||
<path d="M40 40 L30 60" stroke="#FF0000" stroke-width="3" fill="none"/>
|
||
<circle cx="50" cy="25" r="5" fill="#FF0000"/>
|
||
<path d="M50 25 L60 40" stroke="#FF0000" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
library: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="20" width="60" height="60" fill="#8B4513"/>
|
||
<rect x="30" y="30" width="40" height="40" fill="#D2691E"/>
|
||
<rect x="40" y="40" width="20" height="20" fill="#FFF8DC"/>
|
||
<path d="M30 50 L40 40" stroke="#654321" stroke-width="2" fill="none"/>
|
||
<path d="M40 40 L30 60" stroke="#654321" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
market: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect x="20" y="50" width="60" height="30" fill="#8B4513"/><rect x="20" y="40" width="60" height="12" fill="#FF6347"/><rect x="22" y="40" width="10" height="12" fill="#FFD93D"/><rect x="34" y="40" width="10" height="12" fill="#34A853"/><rect x="46" y="40" width="10" height="12" fill="#4285F4"/><rect x="58" y="40" width="10" height="12" fill="#EA4335"/><rect x="70" y="40" width="10" height="12" fill="#FBBC05"/></svg>`,
|
||
store: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="30" width="60" height="40" fill="#4169E1"/>
|
||
<polygon points="20,30 40,20 40,70 20,70" fill="#FFD700"/>
|
||
<path d="M40 30 L60 30" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 30 L40 70" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<circle cx="50" cy="20" r="5" fill="#FFF8DC"/>
|
||
</svg>`,
|
||
traffic: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect x="40" y="15" width="20" height="70" rx="10" fill="#333"/><circle cx="50" cy="30" r="8" fill="#EA4335"/><circle cx="50" cy="50" r="8" fill="#FBBC05"/><circle cx="50" cy="70" r="8" fill="#34A853"/></svg>`,
|
||
street: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect x="20" y="20" width="60" height="60" fill="#555"/><rect x="48" y="20" width="4" height="60" fill="#FFD93D"/><rect x="36" y="45" width="28" height="10" fill="#FFF"/></svg>`,
|
||
city: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100" fill="#88C5F7"/><rect x="15" y="50" width="15" height="35" fill="#2D3748"/><rect x="35" y="40" width="20" height="45" fill="#4A5568"/><rect x="60" y="55" width="25" height="30" fill="#1A202C"/><rect x="20" y="55" width="6" height="6" fill="#FFD93D"/><rect x="42" y="48" width="6" height="6" fill="#FFD93D"/><rect x="67" y="60" width="6" height="6" fill="#FFD93D"/></svg>`,
|
||
crosswalk: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect x="10" y="30" width="80" height="40" fill="#222"/><rect x="15" y="32" width="10" height="36" fill="#FFF"/><rect x="30" y="32" width="10" height="36" fill="#FFF"/><rect x="45" y="32" width="10" height="36" fill="#FFF"/><rect x="60" y="32" width="10" height="36" fill="#FFF"/><rect x="75" y="32" width="10" height="36" fill="#FFF"/></svg>`,
|
||
gym: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="30" width="60" height="40" fill="#FF6347"/>
|
||
<circle cx="35" cy="25" r="5" fill="#000000"/>
|
||
<circle cx="65" cy="25" r="5" fill="#000000"/>
|
||
<path d="M35 25 L65 25" stroke="#000000" stroke-width="3" fill="none"/>
|
||
<path d="M35 40 L65 40" stroke="#000000" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
cinema: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="30" width="60" height="40" fill="#000000"/>
|
||
<polygon points="30,30 50,20 70,30" fill="#FFD700"/>
|
||
<path d="M50 30 L50 70" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<circle cx="40" cy="20" r="5" fill="#FFFFFF"/>
|
||
<circle cx="60" cy="20" r="5" fill="#FFFFFF"/>
|
||
</svg>`,
|
||
hotel: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="30" width="60" height="40" fill="#4169E1"/>
|
||
<rect x="30" y="20" width="40" height="60" fill="#87CEEB"/>
|
||
<rect x="40" y="40" width="20" height="20" fill="#FFF8DC"/>
|
||
<path d="M30 50 L40 40" stroke="#654321" stroke-width="2" fill="none"/>
|
||
<path d="M40 40 L30 60" stroke="#654321" stroke-width="2" fill="none"/>
|
||
<circle cx="50" cy="25" r="5" fill="#FFF8DC"/>
|
||
<path d="M50 25 L60 40" stroke="#654321" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
restaurant: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="30" width="60" height="40" fill="#8B4513"/>
|
||
<circle cx="35" cy="25" r="5" fill="#FFFFFF"/>
|
||
<circle cx="65" cy="25" r="5" fill="#FFFFFF"/>
|
||
<path d="M35 25 L65 25" stroke="#FFFFFF" stroke-width="3" fill="none"/>
|
||
<path d="M35 40 L65 40" stroke="#FFFFFF" stroke-width="3" fill="none"/>
|
||
<circle cx="50" cy="20" r="5" fill="#FF6347"/>
|
||
<path d="M50 20 L50 40" stroke="#FF6347" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
office: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="30" width="60" height="40" fill="#708090"/>
|
||
<rect x="30" y="20" width="40" height="60" fill="#D2691E"/>
|
||
<rect x="40" y="40" width="20" height="20" fill="#FFF8DC"/>
|
||
<path d="M30 50 L40 40" stroke="#654321" stroke-width="2" fill="none"/>
|
||
<path d="M40 40 L30 60" stroke="#654321" stroke-width="2" fill="none"/>
|
||
<circle cx="50" cy="25" r="5" fill="#FFF8DC"/>
|
||
<path d="M50 25 L60 40" stroke="#654321" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
subway: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="10" y="40" width="80" height="20" fill="#708090"/>
|
||
<path d="M10 50 L30 40" stroke="#000000" stroke-width="3" fill="none"/>
|
||
<path d="M30 40 L50 40" stroke="#000000" stroke-width="3" fill="none"/>
|
||
<path d="M50 40 L70 40" stroke="#000000" stroke-width="3" fill="none"/>
|
||
<path d="M70 40 L90 40" stroke="#000000" stroke-width="3" fill="none"/>
|
||
<circle cx="20" cy="60" r="5" fill="#FFFFFF"/>
|
||
<circle cx="80" cy="60" r="5" fill="#FFFFFF"/>
|
||
</svg>`,
|
||
bicycle: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="30" cy="65" r="12" fill="#333"/><circle cx="70" cy="65" r="12" fill="#333"/><path d="M30 65 L45 45 L60 45 L70 65" stroke="#2D3748" stroke-width="4" fill="none"/></svg>`,
|
||
bus: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect x="18" y="40" width="64" height="28" rx="6" fill="#F56565"/><rect x="24" y="45" width="50" height="12" fill="#87CEEB"/><circle cx="32" cy="72" r="6" fill="#333"/><circle cx="68" cy="72" r="6" fill="#333"/></svg>`,
|
||
boat: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><polygon points="20,70 80,70 60,80 40,80" fill="#8B4513"/><polygon points="50,30 50,65 30,65" fill="#87CEEB"/></svg>`,
|
||
tickets: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect x="25" y="40" width="20" height="14" fill="#FBD38D"/><rect x="55" y="46" width="20" height="14" fill="#FBD38D"/><circle cx="45" cy="47" r="3" fill="#EA4335"/><circle cx="65" cy="53" r="3" fill="#EA4335"/></svg>`,
|
||
truck: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect x="20" y="45" width="40" height="20" fill="#718096"/><rect x="60" y="50" width="20" height="15" fill="#4A5568"/><circle cx="30" cy="68" r="6" fill="#333"/><circle cx="58" cy="68" r="6" fill="#333"/></svg>`,
|
||
helicopter: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><ellipse cx="50" cy="55" rx="20" ry="10" fill="#4A5568"/><rect x="35" y="40" width="30" height="4" fill="#2D3748"/><rect x="48" y="35" width="4" height="10" fill="#2D3748"/></svg>`,
|
||
ambulance: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="30" width="60" height="40" fill="#FFFFFF"/>
|
||
<rect x="30" y="20" width="40" height="60" fill="#FF0000"/>
|
||
<circle cx="50" cy="40" r="8" fill="#87CEEB"/>
|
||
<path d="M30 40 L70 40" stroke="#FF0000" stroke-width="3" fill="none"/>
|
||
<path d="M70 40 L70 60" stroke="#FF0000" stroke-width="3" fill="none"/>
|
||
<path d="M70 60 L30 60" stroke="#FF0000" stroke-width="3" fill="none"/>
|
||
<path d="M30 60 L30 40" stroke="#FF0000" stroke-width="3" fill="none"/>
|
||
<text x="50" y="45" text-anchor="middle" fill="white" font-size="10">+</text>
|
||
</svg>`,
|
||
|
||
// Space Station
|
||
rocket: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M50 20 L60 70 L40 70 Z" fill="#FF4500"/>
|
||
<circle cx="50" cy="30" r="5" fill="#87CEEB"/>
|
||
<path d="M40 70 L30 90" stroke="#FF4500" stroke-width="3" fill="none"/>
|
||
<path d="M60 70 L70 90" stroke="#FF4500" stroke-width="3" fill="none"/>
|
||
<path d="M45 50 L55 50" stroke="#FFFFFF" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
earth: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="25" fill="#2E8B57"/><path d="M30 50 Q50 30 70 50 Q50 70 30 50" fill="#87CEEB"/></svg>`,
|
||
mars: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="25" fill="#B22222"/><circle cx="40" cy="45" r="4" fill="#8B0000"/><circle cx="60" cy="55" r="3" fill="#8B0000"/></svg>`,
|
||
jupiter: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="28" fill="#DEB887"/><path d="M22 42 H78" stroke="#A0522D" stroke-width="4"/><path d="M20 52 H80" stroke="#A0522D" stroke-width="3"/></svg>`,
|
||
saturn: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="22" fill="#DAA520"/><ellipse cx="50" cy="50" rx="35" ry="8" fill="#B8860B"/></svg>`,
|
||
sun: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="30" r="25" fill="#FFD700"/><path d="M25 30 L15 30 M75 30 L85 30 M50 5 L50 15 M50 45 L50 55" stroke="#FFA500" stroke-width="3"/></svg>`,
|
||
astronaut: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="40" r="20" fill="#FFFFFF"/>
|
||
<circle cx="50" cy="40" r="15" fill="#87CEEB"/>
|
||
<rect x="40" y="60" width="20" height="30" fill="#FFFFFF"/>
|
||
<path d="M40 70 L30 90" stroke="#FFFFFF" stroke-width="3" fill="none"/>
|
||
<path d="M60 70 L70 90" stroke="#FFFFFF" stroke-width="3" fill="none"/>
|
||
<circle cx="45" cy="40" r="3" fill="#000000"/>
|
||
<circle cx="55" cy="40" r="3" fill="#000000"/>
|
||
</svg>`,
|
||
planet: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="50" r="25" fill="#FF6347"/>
|
||
<ellipse cx="50" cy="50" rx="35" ry="8" fill="#FF6347"/>
|
||
<circle cx="40" cy="45" r="5" fill="#FFA500"/>
|
||
<circle cx="60" cy="55" r="3" fill="#FFA500"/>
|
||
</svg>`,
|
||
star: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M50 20 L60 40 L80 40 L65 55 L70 75 L50 60 L30 75 L35 55 L20 40 L40 40 Z" fill="#FFD700"/>
|
||
</svg>`,
|
||
moon: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="50" r="25" fill="#F0F0F0"/>
|
||
<circle cx="40" cy="45" r="5" fill="#D0D0D0"/>
|
||
<circle cx="60" cy="55" r="3" fill="#D0D0D0"/>
|
||
<path d="M65 40 Q75 50 65 60" stroke="#D0D0D0" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
satellite: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="40" y="40" width="20" height="20" fill="#708090"/>
|
||
<path d="M20 50 L40 50" stroke="#4169E1" stroke-width="3" fill="none"/>
|
||
<path d="M60 50 L80 50" stroke="#4169E1" stroke-width="3" fill="none"/>
|
||
<circle cx="50" cy="50" r="5" fill="#FF0000"/>
|
||
<path d="M30 30 L70 70" stroke="#4169E1" stroke-width="2" fill="none"/>
|
||
<path d="M70 30 L30 70" stroke="#4169E1" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
galaxy: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="50" rx="40" ry="15" fill="#9370DB" transform="rotate(30 50 50)"/>
|
||
<circle cx="40" cy="45" r="3" fill="#FFD700"/>
|
||
<circle cx="60" cy="55" r="2" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="2" fill="#FFFFFF"/>
|
||
</svg>`,
|
||
comet: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="30" cy="50" r="8" fill="#87CEEB"/>
|
||
<path d="M30 50 L70 30" stroke="#87CEEB" stroke-width="4" fill="none"/>
|
||
<path d="M30 50 L70 40" stroke="#87CEEB" stroke-width="3" fill="none"/>
|
||
<path d="M30 50 L70 50" stroke="#87CEEB" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
asteroid: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="50" r="15" fill="#8B4513"/>
|
||
<circle cx="45" cy="45" r="3" fill="#654321"/>
|
||
<circle cx="55" cy="55" r="2" fill="#654321"/>
|
||
<circle cx="50" cy="50" r="2" fill="#654321"/>
|
||
</svg>`,
|
||
telescope: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="45" width="60" height="10" fill="#708090"/>
|
||
<circle cx="20" cy="50" r="8" fill="#4169E1"/>
|
||
<circle cx="80" cy="50" r="12" fill="#4169E1"/>
|
||
<rect x="45" y="30" width="10" height="30" fill="#708090"/>
|
||
<rect x="40" y="25" width="20" height="5" fill="#708090"/>
|
||
</svg>`,
|
||
orbit: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="50" r="30" fill="none" stroke="#4169E1" stroke-width="2"/>
|
||
<circle cx="50" cy="50" r="20" fill="none" stroke="#4169E1" stroke-width="2"/>
|
||
<circle cx="50" cy="50" r="10" fill="none" stroke="#4169E1" stroke-width="2"/>
|
||
<circle cx="50" cy="50" r="5" fill="#FFD700"/>
|
||
<circle cx="80" cy="50" r="3" fill="#87CEEB"/>
|
||
<circle cx="70" cy="50" r="2" fill="#87CEEB"/>
|
||
</svg>`,
|
||
meteor: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="30" cy="30" r="5" fill="#FF4500"/>
|
||
<path d="M30 30 L70 70" stroke="#FF4500" stroke-width="3" fill="none"/>
|
||
<path d="M30 30 L65 65" stroke="#FFA500" stroke-width="2" fill="none"/>
|
||
<path d="M30 30 L60 60" stroke="#FFD700" stroke-width="1" fill="none"/>
|
||
</svg>`,
|
||
space: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect width="100" height="100" fill="#000033"/>
|
||
<circle cx="20" cy="20" r="2" fill="#FFFFFF"/>
|
||
<circle cx="80" cy="30" r="1" fill="#FFFFFF"/>
|
||
<circle cx="40" cy="60" r="2" fill="#FFFFFF"/>
|
||
<circle cx="70" cy="80" r="1" fill="#FFFFFF"/>
|
||
<circle cx="30" cy="70" r="1" fill="#FFFFFF"/>
|
||
<circle cx="60" cy="40" r="2" fill="#FFFFFF"/>
|
||
</svg>`,
|
||
universe: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect width="100" height="100" fill="#000033"/>
|
||
<circle cx="50" cy="50" r="20" fill="#9370DB"/>
|
||
<circle cx="30" cy="30" r="5" fill="#FFD700"/>
|
||
<circle cx="70" cy="70" r="3" fill="#FFD700"/>
|
||
<circle cx="20" cy="60" r="2" fill="#FFFFFF"/>
|
||
<circle cx="80" cy="40" r="2" fill="#FFFFFF"/>
|
||
</svg>`,
|
||
|
||
// Technology
|
||
computer: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="20" width="60" height="40" fill="#708090"/>
|
||
<rect x="25" y="25" width="50" height="30" fill="#000033"/>
|
||
<rect x="40" y="65" width="20" height="10" fill="#708090"/>
|
||
<rect x="30" y="75" width="40" height="5" fill="#708090"/>
|
||
<text x="50" y="45" text-anchor="middle" fill="#00FF00" font-size="8">HELLO</text>
|
||
</svg>`,
|
||
robot: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="35" y="30" width="30" height="40" fill="#708090"/>
|
||
<circle cx="45" cy="40" r="5" fill="#FF0000"/>
|
||
<circle cx="55" cy="40" r="5" fill="#FF0000"/>
|
||
<rect x="40" y="50" width="20" height="5" fill="#87CEEB"/>
|
||
<rect x="30" y="70" width="10" height="20" fill="#708090"/>
|
||
<rect x="60" y="70" width="10" height="20" fill="#708090"/>
|
||
</svg>`,
|
||
internet: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="50" r="30" fill="none" stroke="#4169E1" stroke-width="2"/>
|
||
<circle cx="30" cy="30" r="5" fill="#4169E1"/>
|
||
<circle cx="70" cy="30" r="5" fill="#4169E1"/>
|
||
<circle cx="30" cy="70" r="5" fill="#4169E1"/>
|
||
<circle cx="70" cy="70" r="5" fill="#4169E1"/>
|
||
<circle cx="50" cy="50" r="5" fill="#FF0000"/>
|
||
<path d="M30 30 L50 50" stroke="#4169E1" stroke-width="1" fill="none"/>
|
||
<path d="M70 30 L50 50" stroke="#4169E1" stroke-width="1" fill="none"/>
|
||
<path d="M30 70 L50 50" stroke="#4169E1" stroke-width="1" fill="none"/>
|
||
<path d="M70 70 L50 50" stroke="#4169E1" stroke-width="1" fill="none"/>
|
||
</svg>`,
|
||
software: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="20" width="60" height="60" fill="#708090"/>
|
||
<rect x="30" y="30" width="40" height="40" fill="#000033"/>
|
||
<text x="50" y="45" text-anchor="middle" fill="#00FF00" font-size="8">{ }</text>
|
||
<text x="50" y="55" text-anchor="middle" fill="#00FF00" font-size="8">( )</text>
|
||
<text x="50" y="65" text-anchor="middle" fill="#00FF00" font-size="8">[ ]</text>
|
||
</svg>`,
|
||
app: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="25" y="25" width="50" height="50" rx="10" fill="#FF6347"/>
|
||
<circle cx="50" cy="50" r="15" fill="#FFFFFF"/>
|
||
<path d="M45 50 L55 50" stroke="#FF6347" stroke-width="3" fill="none"/>
|
||
<path d="M50 45 L50 55" stroke="#FF6347" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
data: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="20" width="15" height="60" fill="#4169E1"/>
|
||
<rect x="42" y="30" width="15" height="50" fill="#4169E1"/>
|
||
<rect x="65" y="40" width="15" height="40" fill="#4169E1"/>
|
||
<text x="27" y="55" text-anchor="middle" fill="#FFFFFF" font-size="8">A</text>
|
||
<text x="49" y="55" text-anchor="middle" fill="#FFFFFF" font-size="8">B</text>
|
||
<text x="72" y="60" text-anchor="middle" fill="#FFFFFF" font-size="8">C</text>
|
||
</svg>`,
|
||
code: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="20" width="60" height="60" fill="#000033"/>
|
||
<text x="30" y="40" fill="#00FF00" font-size="10"></></text>
|
||
<text x="30" y="55" fill="#FF6347" font-size="10">{...}</text>
|
||
<text x="30" y="70" fill="#87CEEB" font-size="10">( )</text>
|
||
</svg>`,
|
||
algorithm: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="35" y="20" width="30" height="15" fill="#4169E1"/>
|
||
<path d="M50 35 L50 45" stroke="#000000" stroke-width="2" fill="none"/>
|
||
<polygon points="35,45 65,45 50,60" fill="#FF6347"/>
|
||
<path d="M50 60 L50 70" stroke="#000000" stroke-width="2" fill="none"/>
|
||
<rect x="35" y="70" width="30" height="15" fill="#32CD32"/>
|
||
</svg>`,
|
||
program: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="20" width="60" height="60" fill="#708090"/>
|
||
<rect x="30" y="30" width="40" height="5" fill="#00FF00"/>
|
||
<rect x="30" y="40" width="30" height="5" fill="#FF6347"/>
|
||
<rect x="30" y="50" width="35" height="5" fill="#87CEEB"/>
|
||
<rect x="30" y="60" width="25" height="5" fill="#FFD700"/>
|
||
<rect x="30" y="70" width="40" height="5" fill="#FF69B4"/>
|
||
</svg>`,
|
||
binary: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="20" width="60" height="60" fill="#000033"/>
|
||
<text x="30" y="35" fill="#00FF00" font-size="8">0110</text>
|
||
<text x="50" y="35" fill="#00FF00" font-size="8">1001</text>
|
||
<text x="30" y="50" fill="#00FF00" font-size="8">1100</text>
|
||
<text x="50" y="50" fill="#00FF00" font-size="8">0011</text>
|
||
<text x="30" y="65" fill="#00FF00" font-size="8">1010</text>
|
||
<text x="50" y="65" fill="#00FF00" font-size="8">0101</text>
|
||
</svg>`,
|
||
database: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<ellipse cx="50" cy="30" rx="25" ry="10" fill="#4169E1"/>
|
||
<rect x="25" y="30" width="50" height="40" fill="#4169E1"/>
|
||
<ellipse cx="50" cy="70" rx="25" ry="10" fill="#4169E1"/>
|
||
<ellipse cx="50" cy="50" rx="25" ry="10" fill="#6495ED"/>
|
||
<ellipse cx="50" cy="40" rx="25" ry="10" fill="#6495ED"/>
|
||
<ellipse cx="50" cy="60" rx="25" ry="10" fill="#6495ED"/>
|
||
</svg>`,
|
||
network: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="50" r="8" fill="#FF0000"/>
|
||
<circle cx="20" cy="20" r="5" fill="#4169E1"/>
|
||
<circle cx="80" cy="20" r="5" fill="#4169E1"/>
|
||
<circle cx="20" cy="80" r="5" fill="#4169E1"/>
|
||
<circle cx="80" cy="80" r="5" fill="#4169E1"/>
|
||
<path d="M50 50 L20 20" stroke="#4169E1" stroke-width="2" fill="none"/>
|
||
<path d="M50 50 L80 20" stroke="#4169E1" stroke-width="2" fill="none"/>
|
||
<path d="M50 50 L20 80" stroke="#4169E1" stroke-width="2" fill="none"/>
|
||
<path d="M50 50 L80 80" stroke="#4169E1" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
|
||
// Electricity
|
||
electricity: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M30 50 L40 30 L50 70 L60 30 L70 50" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<circle cx="30" cy="50" r="3" fill="#FFD700"/>
|
||
<circle cx="70" cy="50" r="3" fill="#FFD700"/>
|
||
</svg>`,
|
||
battery: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="30" width="50" height="40" fill="#708090"/>
|
||
<rect x="70" y="40" width="10" height="20" fill="#708090"/>
|
||
<rect x="25" y="35" width="30" height="30" fill="#32CD32"/>
|
||
<text x="40" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">100%</text>
|
||
</svg>`,
|
||
power: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="50" r="30" fill="none" stroke="#FF0000" stroke-width="3"/>
|
||
<path d="M50 30 L50 50" stroke="#FF0000" stroke-width="3" fill="none"/>
|
||
<path d="M35 65 Q50 50 65 65" stroke="#FF0000" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
energy: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M30 50 L40 30 L50 70 L60 30 L70 50" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<circle cx="30" cy="50" r="3" fill="#FFD700"/>
|
||
<circle cx="70" cy="50" r="3" fill="#FFD700"/>
|
||
<path d="M30 50 L70 50" stroke="#FFA500" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
circuit: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="20" width="60" height="60" fill="#708090"/>
|
||
<circle cx="35" cy="35" r="5" fill="#FF0000"/>
|
||
<circle cx="65" cy="35" r="5" fill="#000000"/>
|
||
<circle cx="35" cy="65" r="5" fill="#000000"/>
|
||
<circle cx="65" cy="65" r="5" fill="#32CD32"/>
|
||
<path d="M35 35 L65 35" stroke="#000000" stroke-width="2" fill="none"/>
|
||
<path d="M65 35 L65 65" stroke="#000000" stroke-width="2" fill="none"/>
|
||
<path d="M65 65 L35 65" stroke="#000000" stroke-width="2" fill="none"/>
|
||
<path d="M35 65 L35 35" stroke="#000000" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
voltage: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M30 50 L40 30 L50 70 L60 30 L70 50" stroke="#FF0000" stroke-width="3" fill="none"/>
|
||
<circle cx="30" cy="50" r="3" fill="#FF0000"/>
|
||
<circle cx="70" cy="50" r="3" fill="#FF0000"/>
|
||
<text x="50" y="85" text-anchor="middle" fill="#FF0000" font-size="10">V</text>
|
||
</svg>`,
|
||
current: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M30 50 L40 30 L50 70 L60 30 L70 50" stroke="#4169E1" stroke-width="3" fill="none"/>
|
||
<circle cx="30" cy="50" r="3" fill="#4169E1"/>
|
||
<circle cx="70" cy="50" r="3" fill="#4169E1"/>
|
||
<text x="50" y="85" text-anchor="middle" fill="#4169E1" font-size="10">A</text>
|
||
</svg>`,
|
||
resistance: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="30" y="40" width="40" height="20" fill="#8B4513"/>
|
||
<path d="M20 50 L30 50" stroke="#000000" stroke-width="3" fill="none"/>
|
||
<path d="M70 50 L80 50" stroke="#000000" stroke-width="3" fill="none"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">Ω</text>
|
||
</svg>`,
|
||
magnet: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="30" width="30" height="40" fill="#FF0000"/>
|
||
<rect x="50" y="30" width="30" height="40" fill="#4169E1"/>
|
||
<text x="35" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">N</text>
|
||
<text x="65" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">S</text>
|
||
</svg>`,
|
||
charge: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="35" cy="50" r="15" fill="#FF0000"/>
|
||
<text x="35" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">+</text>
|
||
<circle cx="65" cy="50" r="15" fill="#4169E1"/>
|
||
<text x="65" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">-</text>
|
||
</svg>`,
|
||
wire: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M20 50 L80 50" stroke="#000000" stroke-width="5" fill="none"/>
|
||
<circle cx="30" cy="50" r="3" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="3" fill="#FFD700"/>
|
||
<circle cx="70" cy="50" r="3" fill="#FFD700"/>
|
||
</svg>`,
|
||
electron: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="50" r="20" fill="none" stroke="#4169E1" stroke-width="2"/>
|
||
<circle cx="50" cy="30" r="5" fill="#FF0000"/>
|
||
<text x="50" y="35" text-anchor="middle" fill="#FFFFFF" font-size="8">e-</text>
|
||
<path d="M50 30 L50 70" stroke="#4169E1" stroke-width="1" fill="none" stroke-dasharray="2,2"/>
|
||
</svg>`,
|
||
|
||
// Secret Level
|
||
secret: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="30" width="60" height="40" fill="#8B008B"/>
|
||
<circle cx="50" cy="50" r="15" fill="#FFD700"/>
|
||
<path d="M45 50 L55 50" stroke="#8B008B" stroke-width="3" fill="none"/>
|
||
<path d="M50 45 L50 55" stroke="#8B008B" stroke-width="3" fill="none"/>
|
||
<path d="M40 40 L60 60" stroke="#FFD700" stroke-width="2" fill="none"/>
|
||
<path d="M60 40 L40 60" stroke="#FFD700" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
mystery: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="50" cy="50" r="30" fill="#8B008B"/>
|
||
<circle cx="50" cy="40" r="15" fill="#9370DB"/>
|
||
<path d="M40 40 Q50 30 60 40" stroke="#FFD700" stroke-width="2" fill="none"/>
|
||
<circle cx="45" cy="40" r="3" fill="#000000"/>
|
||
<circle cx="55" cy="40" r="3" fill="#000000"/>
|
||
<path d="M45 50 Q50 55 55 50" stroke="#FFD700" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
hidden: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="20" width="60" height="60" fill="#8B008B"/>
|
||
<rect x="30" y="30" width="40" height="40" fill="#9370DB"/>
|
||
<circle cx="50" cy="50" r="15" fill="#FFD700"/>
|
||
<path d="M45 50 L55 50" stroke="#8B008B" stroke-width="3" fill="none"/>
|
||
<path d="M50 45 L50 55" stroke="#8B008B" stroke-width="3" fill="none"/>
|
||
<path d="M40 40 L60 60" stroke="#FFD700" stroke-width="2" fill="none"/>
|
||
<path d="M60 40 L40 60" stroke="#FFD700" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
treasure: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="40" width="60" height="40" fill="#8B4513"/>
|
||
<path d="M20 40 L50 20 L80 40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF0000"/>
|
||
<path d="M45 50 L55 50" stroke="#FFFFFF" stroke-width="2" fill="none"/>
|
||
<path d="M50 45 L50 55" stroke="#FFFFFF" stroke-width="2" fill="none"/>
|
||
</svg>`,
|
||
key: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="30" cy="50" r="10" fill="#FFD700"/>
|
||
<rect x="30" y="45" width="40" height="10" fill="#FFD700"/>
|
||
<rect x="60" y="45" width="5" height="5" fill="#FFD700"/>
|
||
<rect x="65" y="45" width="5" height="5" fill="#FFD700"/>
|
||
<circle cx="30" cy="50" r="5" fill="#8B008B"/>
|
||
</svg>`,
|
||
lock: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="30" y="50" width="40" height="30" fill="#8B4513"/>
|
||
<path d="M40 50 L40 40 Q40 30 50 30 Q60 30 60 40 L60 50" stroke="#8B4513" stroke-width="5" fill="none"/>
|
||
<circle cx="50" cy="65" r="5" fill="#FFD700"/>
|
||
</svg>`,
|
||
password: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="30" width="60" height="40" fill="#708090"/>
|
||
<circle cx="35" cy="50" r="5" fill="#000000"/>
|
||
<circle cx="50" cy="50" r="5" fill="#000000"/>
|
||
<circle cx="65" cy="50" r="5" fill="#000000"/>
|
||
<text x="50" y="85" text-anchor="middle" fill="#000000" font-size="10">***</text>
|
||
</svg>`,
|
||
codebreaker: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="20" width="60" height="60" fill="#8B008B"/>
|
||
<text x="50" y="40" text-anchor="middle" fill="#FFD700" font-size="10">A=1</text>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFD700" font-size="10">B=2</text>
|
||
<text x="50" y="70" text-anchor="middle" fill="#FFD700" font-size="10">C=3</text>
|
||
</svg>`,
|
||
puzzle: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="20" width="30" height="30" fill="#FF6347"/>
|
||
<rect x="50" y="20" width="30" height="30" fill="#4169E1"/>
|
||
<rect x="20" y="50" width="30" height="30" fill="#32CD32"/>
|
||
<rect x="50" y="50" width="30" height="30" fill="#FFD700"/>
|
||
<circle cx="35" cy="35" r="5" fill="#FFFFFF"/>
|
||
<circle cx="65" cy="35" r="5" fill="#FFFFFF"/>
|
||
<circle cx="35" cy="65" r="5" fill="#FFFFFF"/>
|
||
<circle cx="65" cy="65" r="5" fill="#FFFFFF"/>
|
||
</svg>`,
|
||
achievement: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">A+</text>
|
||
</svg>`,
|
||
excellence: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<polygon points="50,30 55,40 65,40 57,48 60,58 50,50 40,58 43,48 35,40 45,40" fill="#FF6347"/>
|
||
<circle cx="50" cy="50" r="5" fill="#FFFFFF"/>
|
||
</svg>`,
|
||
champion: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">1</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
master: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">M</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
expert: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">E</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
genius: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">G</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
future: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="20" width="60" height="60" fill="#8B008B"/>
|
||
<circle cx="50" cy="50" r="20" fill="#FFD700"/>
|
||
<path d="M40 50 L60 50" stroke="#8B008B" stroke-width="3" fill="none"/>
|
||
<path d="M50 40 L50 60" stroke="#8B008B" stroke-width="3" fill="none"/>
|
||
<path d="M40 40 L60 60" stroke="#FFD700" stroke-width="2" fill="none"/>
|
||
<path d="M60 40 L40 60" stroke="#FFD700" stroke-width="2" fill="none"/>
|
||
<circle cx="50" cy="30" r="5" fill="#FF6347"/>
|
||
<circle cx="50" cy="70" r="5" fill="#FF6347"/>
|
||
<circle cx="30" cy="50" r="5" fill="#FF6347"/>
|
||
<circle cx="70" cy="50" r="5" fill="#FF6347"/>
|
||
</svg>`,
|
||
dream: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="20" width="60" height="60" fill="#8B008B"/>
|
||
<circle cx="50" cy="50" r="20" fill="#FFD700"/>
|
||
<path d="M40 50 L60 50" stroke="#8B008B" stroke-width="3" fill="none"/>
|
||
<path d="M50 40 L50 60" stroke="#8B008B" stroke-width="3" fill="none"/>
|
||
<path d="M40 40 L60 60" stroke="#FFD700" stroke-width="2" fill="none"/>
|
||
<path d="M60 40 L40 60" stroke="#FFD700" stroke-width="2" fill="none"/>
|
||
<circle cx="35" cy="35" r="3" fill="#FF6347"/>
|
||
<circle cx="65" cy="35" r="3" fill="#FF6347"/>
|
||
<circle cx="35" cy="65" r="3" fill="#FF6347"/>
|
||
<circle cx="65" cy="65" r="3" fill="#FF6347"/>
|
||
</svg>`,
|
||
goal: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="20" width="60" height="60" fill="#8B008B"/>
|
||
<circle cx="50" cy="50" r="20" fill="#FFD700"/>
|
||
<path d="M40 50 L60 50" stroke="#8B008B" stroke-width="3" fill="none"/>
|
||
<path d="M50 40 L50 60" stroke="#8B008B" stroke-width="3" fill="none"/>
|
||
<path d="M40 40 L60 60" stroke="#FFD700" stroke-width="2" fill="none"/>
|
||
<path d="M60 40 L40 60" stroke="#FFD700" stroke-width="2" fill="none"/>
|
||
<circle cx="50" cy="30" r="5" fill="#FF6347"/>
|
||
<circle cx="50" cy="70" r="5" fill="#FF6347"/>
|
||
<circle cx="30" cy="50" r="5" fill="#FF6347"/>
|
||
<circle cx="70" cy="50" r="5" fill="#FF6347"/>
|
||
</svg>`,
|
||
success: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<rect x="20" y="20" width="60" height="60" fill="#8B008B"/>
|
||
<circle cx="50" cy="50" r="20" fill="#FFD700"/>
|
||
<path d="M40 50 L60 50" stroke="#8B008B" stroke-width="3" fill="none"/>
|
||
<path d="M50 40 L50 60" stroke="#8B008B" stroke-width="3" fill="none"/>
|
||
<path d="M40 40 L60 60" stroke="#FFD700" stroke-width="2" fill="none"/>
|
||
<path d="M60 40 L40 60" stroke="#FFD700" stroke-width="2" fill="none"/>
|
||
<circle cx="35" cy="35" r="3" fill="#FF6347"/>
|
||
<circle cx="65" cy="35" r="3" fill="#FF6347"/>
|
||
<circle cx="35" cy="65" r="3" fill="#FF6347"/>
|
||
<circle cx="65" cy="65" r="3" fill="#FF6347"/>
|
||
</svg>`,
|
||
victory: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">V</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
wisdom: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">W</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
knowledge: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">K</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
discovery: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">D</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
innovation: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">I</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
inspiration: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">I</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
creativity: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">C</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
imagination: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">I</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
adventure: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">A</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
journey: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">J</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
exploration: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">E</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
breakthrough: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">B</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
transformation: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">T</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
evolution: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">E</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
progress: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">P</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
growth: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">G</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
learning: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">L</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
development: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">D</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
improvement: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">I</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
advancement: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">A</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
achievement_unlocked: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">!</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
milestone: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||
<polygon points="50,20 60,40 80,40 65,55 70,75 50,60 30,75 35,55 20,40 40,40" fill="#FFD700"/>
|
||
<circle cx="50" cy="50" r="10" fill="#FF6347"/>
|
||
<text x="50" y="55" text-anchor="middle" fill="#FFFFFF" font-size="10">M</text>
|
||
<path d="M30 80 L70 80" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M40 80 L40 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M50 80 L50 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
<path d="M60 80 L60 90" stroke="#FFD700" stroke-width="3" fill="none"/>
|
||
</svg>`,
|
||
certificate: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect x="25" y="35" width="50" height="30" fill="#FFFFFF" stroke="#2D3748"/><circle cx="70" cy="50" r="6" fill="#EA4335"/></svg>`,
|
||
mastery: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><path d="M20 70 Q50 40 80 70" stroke="#34A853" stroke-width="6" fill="none"/></svg>`,
|
||
graduation: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><polygon points="20,40 80,40 50,28" fill="#2D3748"/><rect x="40" y="40" width="20" height="10" fill="#2D3748"/></svg>`,
|
||
knowledge: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect x="28" y="40" width="44" height="20" fill="#FBD38D"/><path d="M28 40 L50 50 L72 40" stroke="#A0522D" stroke-width="3" fill="none"/></svg>`,
|
||
wisdom: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><ellipse cx="50" cy="55" rx="18" ry="12" fill="#8B4513"/><circle cx="44" cy="52" r="3" fill="#FFFFFF"/><circle cx="56" cy="52" r="3" fill="#FFFFFF"/></svg>`,
|
||
skill: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect x="30" y="50" width="40" height="20" fill="#718096"/><rect x="35" y="45" width="30" height="8" fill="#4A5568"/></svg>`,
|
||
talent: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><polygon points="50,25 60,45 82,45 65,58 72,80 50,67 28,80 35,58 18,45 40,45" fill="#FBBC05"/></svg>`,
|
||
brilliance: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="6" fill="#FFD93D"/><path d="M50 25 L50 15 M50 85 L50 75 M25 50 L15 50 M85 50 L75 50" stroke="#FFD93D" stroke-width="3"/></svg>`,
|
||
victory: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect x="40" y="30" width="20" height="25" fill="#FBBC05"/><rect x="35" y="55" width="30" height="12" fill="#A0522D"/></svg>`,
|
||
future: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100" fill="#88C5F7"/><rect x="20" y="50" width="15" height="30" fill="#2D3748"/><rect x="40" y="40" width="20" height="40" fill="#4A5568"/><rect x="65" y="55" width="15" height="25" fill="#1A202C"/></svg>`,
|
||
dream: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><ellipse cx="50" cy="55" rx="28" ry="16" fill="#E0E0FF"/><circle cx="35" cy="45" r="6" fill="#E0E0FF"/><circle cx="65" cy="45" r="6" fill="#E0E0FF"/><circle cx="70" cy="35" r="6" fill="#FFD93D"/></svg>`,
|
||
ambition: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><polygon points="30,75 50,35 70,75" fill="#A0AEC0"/><rect x="49" y="45" width="2" height="20" fill="#EA4335"/><polygon points="50,45 62,52 50,58" fill="#EA4335"/></svg>`,
|
||
destiny: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="22" fill="#CBD5E0"/><path d="M50 35 L50 65 M35 50 L65 50" stroke="#2D3748" stroke-width="3"/></svg>`,
|
||
potential: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect x="48" y="60" width="4" height="12" fill="#8B4513"/><ellipse cx="50" cy="55" rx="8" ry="12" fill="#34A853"/></svg>`,
|
||
opportunity: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect x="30" y="30" width="40" height="40" fill="#E2E8F0"/><rect x="45" y="30" width="10" height="40" fill="#FFFFFF"/></svg>`,
|
||
possibility: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect x="30" y="35" width="12" height="12" fill="#4169E1"/><rect x="46" y="35" width="12" height="12" fill="#FBBC05"/><rect x="62" y="35" width="12" height="12" fill="#34A853"/><text x="50" y="70" text-anchor="middle" font-size="14" fill="#2D3748">?</text></svg>`,
|
||
hope: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect x="40" y="30" width="20" height="40" fill="#E91E63"/><rect x="45" y="70" width="10" height="15" fill="#E91E63"/></svg>`,
|
||
aspiration: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><path d="M50 20 L60 70 L40 70 Z" fill="#FF4500"/></svg>`,
|
||
vision: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><ellipse cx="50" cy="50" rx="26" ry="16" fill="#CBD5E0"/><circle cx="50" cy="50" r="6" fill="#2D3748"/></svg>`,
|
||
imagination: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="5" fill="#FFD93D"/><circle cx="35" cy="40" r="3" fill="#FBBC05"/><circle cx="65" cy="42" r="4" fill="#34A853"/><circle cx="60" cy="65" r="3" fill="#4285F4"/></svg>`,
|
||
innovation: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="42" r="10" fill="#FFD93D"/><rect x="46" y="52" width="8" height="12" fill="#FFD93D"/><circle cx="70" cy="60" r="6" fill="#A0AEC0"/><path d="M56 48 L66 56" stroke="#A0AEC0" stroke-width="3"/></svg>`
|
||
};
|
||
const fallback = '<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100" fill="#222"/><text x="50" y="55" text-anchor="middle" fill="#fff" font-size="12">SVG</text></svg>';
|
||
return customSVGs[key] || fallback;
|
||
},
|
||
|
||
};
|
||
|
||
// Initialize game when page loads
|
||
window.onload = () => {
|
||
GAME.init();
|
||
};
|
||
</script>
|
||
</body>
|
||
</html>
|