| 1 |
(function () { |
| 2 |
'use strict'; |
| 3 |
|
| 4 |
var QUESTIONS = [ |
| 5 |
// ---- Science & Nature ---- |
| 6 |
{ cat: 'science', q: 'How many bones are in the adult human body?', choices: ['206', '187', '215', '232'], answer: 0, exp: 'Adults have 206 bones. Babies are born with around 270-300 bones, many of which fuse together.' }, |
| 7 |
{ cat: 'science', q: 'What is the chemical symbol for gold?', choices: ['Au', 'Ag', 'Gd', 'Go'], answer: 0, exp: 'Au comes from the Latin word "aurum" meaning gold.' }, |
| 8 |
{ cat: 'science', q: 'What planet is known as the Red Planet?', choices: ['Mars', 'Jupiter', 'Saturn', 'Venus'], answer: 0, exp: 'Mars appears red due to iron oxide (rust) on its surface.' }, |
| 9 |
{ cat: 'science', q: 'How many chromosomes does a typical human cell contain?', choices: ['46', '23', '48', '36'], answer: 0, exp: 'Humans have 23 pairs (46 total) chromosomes. Sperm and egg cells have just 23.' }, |
| 10 |
{ cat: 'science', q: 'What is the speed of light in a vacuum (approx.)?', choices: ['300,000 km/s', '150,000 km/s', '3,000 km/s', '1,080,000 km/s'], answer: 0, exp: 'The speed of light is approximately 299,792 km/s, often rounded to 300,000 km/s.' }, |
| 11 |
{ cat: 'science', q: 'Which gas makes up about 78% of Earth\'s atmosphere?', choices: ['Nitrogen', 'Oxygen', 'Carbon Dioxide', 'Argon'], answer: 0, exp: 'Nitrogen (N₂) makes up ~78% of the atmosphere. Oxygen is only ~21%.' }, |
| 12 |
{ cat: 'science', q: 'What is the powerhouse of the cell?', choices: ['Mitochondria', 'Nucleus', 'Ribosome', 'Endoplasmic reticulum'], answer: 0, exp: 'Mitochondria produce ATP, which powers cellular processes.' }, |
| 13 |
{ cat: 'science', q: 'Which element has the atomic number 1?', choices: ['Hydrogen', 'Helium', 'Lithium', 'Carbon'], answer: 0, exp: 'Hydrogen is the lightest and most abundant element in the universe.' }, |
| 14 |
{ cat: 'science', q: 'What is the hardest natural substance on Earth?', choices: ['Diamond', 'Quartz', 'Topaz', 'Corundum'], answer: 0, exp: 'Diamond scores 10 on the Mohs hardness scale, the highest possible.' }, |
| 15 |
{ cat: 'science', q: 'How long does it take light from the Sun to reach Earth?', choices: ['~8 minutes', '~1 second', '~1 hour', '~24 minutes'], answer: 0, exp: 'Light from the Sun takes approximately 8 minutes and 20 seconds to reach Earth.' }, |
| 16 |
// ---- History ---- |
| 17 |
{ cat: 'history', q: 'In which year did World War II end?', choices: ['1945', '1944', '1946', '1918'], answer: 0, exp: 'World War II ended in 1945 — V-E Day was May 8 and V-J Day was September 2.' }, |
| 18 |
{ cat: 'history', q: 'Who was the first President of the United States?', choices: ['George Washington', 'John Adams', 'Thomas Jefferson', 'Benjamin Franklin'], answer: 0, exp: 'George Washington served as the first U.S. President from 1789 to 1797.' }, |
| 19 |
{ cat: 'history', q: 'The Great Wall of China was primarily built during which dynasty?', choices: ['Ming Dynasty', 'Han Dynasty', 'Qin Dynasty', 'Tang Dynasty'], answer: 0, exp: 'The most iconic sections were built during the Ming Dynasty (1368–1644).' }, |
| 20 |
{ cat: 'history', q: 'In which city was the Titanic built?', choices: ['Belfast', 'Southampton', 'London', 'Liverpool'], answer: 0, exp: 'RMS Titanic was built at the Harland and Wolff shipyard in Belfast, Ireland.' }, |
| 21 |
{ cat: 'history', q: 'Which empire was ruled by Julius Caesar?', choices: ['Roman', 'Greek', 'Byzantine', 'Ottoman'], answer: 0, exp: 'Julius Caesar was a Roman general and statesman who greatly expanded the Roman Republic.' }, |
| 22 |
{ cat: 'history', q: 'The Berlin Wall fell in which year?', choices: ['1989', '1991', '1985', '1979'], answer: 0, exp: 'The Berlin Wall fell on November 9, 1989, marking the end of the Cold War era in Europe.' }, |
| 23 |
{ cat: 'history', q: 'Napoleon Bonaparte was exiled to which island?', choices: ['Saint Helena', 'Elba', 'Corsica', 'Malta'], answer: 0, exp: 'After his final defeat at Waterloo, Napoleon was exiled to Saint Helena in 1815.' }, |
| 24 |
{ cat: 'history', q: 'Which civilization built Machu Picchu?', choices: ['Inca', 'Aztec', 'Maya', 'Olmec'], answer: 0, exp: 'Machu Picchu was built by the Inca Empire around 1450 CE in the Andes Mountains of Peru.' }, |
| 25 |
{ cat: 'history', q: 'The first atomic bomb was dropped on which city?', choices: ['Hiroshima', 'Nagasaki', 'Tokyo', 'Osaka'], answer: 0, exp: 'The first atomic bomb ("Little Boy") was dropped on Hiroshima on August 6, 1945.' }, |
| 26 |
{ cat: 'history', q: 'Who painted the Sistine Chapel ceiling?', choices: ['Michelangelo', 'Leonardo da Vinci', 'Raphael', 'Botticelli'], answer: 0, exp: 'Michelangelo painted the Sistine Chapel ceiling between 1508 and 1512 for Pope Julius II.' }, |
| 27 |
// ---- Geography ---- |
| 28 |
{ cat: 'geography', q: 'What is the capital of Australia?', choices: ['Canberra', 'Sydney', 'Melbourne', 'Perth'], answer: 0, exp: 'Canberra is Australia\'s capital. Sydney is the largest city, but Canberra was purpose-built as the capital.' }, |
| 29 |
{ cat: 'geography', q: 'Which is the longest river in the world?', choices: ['Nile', 'Amazon', 'Yangtze', 'Mississippi'], answer: 0, exp: 'The Nile River in Africa is traditionally considered the world\'s longest river at ~6,650 km.' }, |
| 30 |
{ cat: 'geography', q: 'Mount Everest is located on the border of which two countries?', choices: ['Nepal and China', 'India and Nepal', 'China and India', 'Nepal and Bhutan'], answer: 0, exp: 'Everest sits on the border of Nepal (south side) and Tibet/China (north side).' }, |
| 31 |
{ cat: 'geography', q: 'Which country has the most natural lakes?', choices: ['Canada', 'Russia', 'USA', 'Finland'], answer: 0, exp: 'Canada has an estimated 2 million+ lakes, more than any other country on Earth.' }, |
| 32 |
{ cat: 'geography', q: 'What is the smallest country in the world?', choices: ['Vatican City', 'Monaco', 'San Marino', 'Liechtenstein'], answer: 0, exp: 'Vatican City, with an area of just 0.44 km², is the world\'s smallest independent state.' }, |
| 33 |
{ cat: 'geography', q: 'The Sahara Desert is primarily located on which continent?', choices: ['Africa', 'Asia', 'Australia', 'South America'], answer: 0, exp: 'The Sahara is the world\'s largest hot desert, spanning about 9 million km² across North Africa.' }, |
| 34 |
{ cat: 'geography', q: 'Which ocean is the largest?', choices: ['Pacific', 'Atlantic', 'Indian', 'Arctic'], answer: 0, exp: 'The Pacific Ocean covers about 165 million km², nearly half of the world\'s total ocean area.' }, |
| 35 |
{ cat: 'geography', q: 'In which country is the Amazon rainforest primarily located?', choices: ['Brazil', 'Peru', 'Colombia', 'Bolivia'], answer: 0, exp: 'About 60% of the Amazon rainforest is in Brazil; the remainder extends into 8 other nations.' }, |
| 36 |
// ---- Pop Culture & Entertainment ---- |
| 37 |
{ cat: 'popculture', q: 'What movie features the quote "To infinity and beyond!"?', choices: ['Toy Story', 'Buzz Lightyear', 'Interstellar', 'Gravity'], answer: 0, exp: 'Buzz Lightyear\'s catchphrase first appeared in the 1995 Pixar film Toy Story.' }, |
| 38 |
{ cat: 'popculture', q: 'How many strings does a standard guitar have?', choices: ['6', '4', '7', '12'], answer: 0, exp: 'A standard acoustic or electric guitar has 6 strings, tuned E-A-D-G-B-E.' }, |
| 39 |
{ cat: 'popculture', q: 'Who wrote the Harry Potter book series?', choices: ['J.K. Rowling', 'Tolkien', 'C.S. Lewis', 'Roald Dahl'], answer: 0, exp: 'J.K. Rowling wrote the seven Harry Potter novels published between 1997 and 2007.' }, |
| 40 |
{ cat: 'popculture', q: 'Which TV show is set in the fictional town of Hawkins, Indiana?', choices: ['Stranger Things', 'Dark', 'The OA', 'Twin Peaks'], answer: 0, exp: 'Stranger Things, the Netflix sci-fi horror series, is set in Hawkins, Indiana.' }, |
| 41 |
{ cat: 'popculture', q: 'In chess, which piece can only move diagonally?', choices: ['Bishop', 'Rook', 'Queen', 'Knight'], answer: 0, exp: 'The Bishop can only move diagonally, staying on one color for the entire game.' }, |
| 42 |
{ cat: 'popculture', q: 'What band was Freddie Mercury the lead singer of?', choices: ['Queen', 'Led Zeppelin', 'The Who', 'Aerosmith'], answer: 0, exp: 'Freddie Mercury was the charismatic lead vocalist of the British rock band Queen.' }, |
| 43 |
{ cat: 'popculture', q: 'Super Mario first appeared in which 1981 arcade game?', choices: ['Donkey Kong', 'Mario Bros', 'Space Invaders', 'Pac-Man'], answer: 0, exp: 'Mario (then "Jumpman") debuted in Donkey Kong in 1981, though "Mario Bros." named him in 1983.' }, |
| 44 |
// ---- Sports ---- |
| 45 |
{ cat: 'sports', q: 'How many players are on a standard basketball team on the court at once?', choices: ['5', '6', '7', '4'], answer: 0, exp: 'Each basketball team has 5 players on the court simultaneously.' }, |
| 46 |
{ cat: 'sports', q: 'In which sport would you perform a "slam dunk"?', choices: ['Basketball', 'Volleyball', 'Tennis', 'Handball'], answer: 0, exp: 'A slam dunk is a powerful basketball shot where the player dunks the ball through the hoop.' }, |
| 47 |
{ cat: 'sports', q: 'How many holes are in a standard round of golf?', choices: ['18', '9', '24', '36'], answer: 0, exp: 'A standard round of golf is played over 18 holes. A "half round" is 9 holes.' }, |
| 48 |
{ cat: 'sports', q: 'Which country won the 2022 FIFA World Cup?', choices: ['Argentina', 'France', 'Croatia', 'Morocco'], answer: 0, exp: 'Argentina won the 2022 FIFA World Cup, defeating France in the final on penalties.' }, |
| 49 |
{ cat: 'sports', q: 'In tennis, what is the term for a score of 40-40?', choices: ['Deuce', 'Tie', 'Love-all', 'Match point'], answer: 0, exp: 'When both players reach 40, the score is called "Deuce." The next point is then an "Advantage."' }, |
| 50 |
// ---- Technology ---- |
| 51 |
{ cat: 'technology', q: 'What does "HTTP" stand for?', choices: ['HyperText Transfer Protocol', 'High Transfer Text Protocol', 'HyperText Transmission Protocol', 'Host Transfer Text Protocol'], answer: 0, exp: 'HTTP (HyperText Transfer Protocol) is the foundation of data communication on the World Wide Web.' }, |
| 52 |
{ cat: 'technology', q: 'Who co-founded Apple Inc. with Steve Jobs?', choices: ['Steve Wozniak', 'Bill Gates', 'Mark Zuckerberg', 'Jeff Bezos'], answer: 0, exp: 'Steve Wozniak co-founded Apple Inc. in 1976 with Steve Jobs and Ronald Wayne.' }, |
| 53 |
{ cat: 'technology', q: 'In computing, what does "RAM" stand for?', choices: ['Random Access Memory', 'Rapid Access Memory', 'Read Access Module', 'Random Application Memory'], answer: 0, exp: 'RAM (Random Access Memory) is your computer\'s short-term working memory.' }, |
| 54 |
{ cat: 'technology', q: 'What programming language is known as the "language of the web"?', choices: ['JavaScript', 'Python', 'Java', 'C++'], answer: 0, exp: 'JavaScript is the primary scripting language of the web, running natively in all browsers.' }, |
| 55 |
{ cat: 'technology', q: 'What does "AI" stand for in the context of computing?', choices: ['Artificial Intelligence', 'Automated Interface', 'Algorithmic Integration', 'Advanced Iteration'], answer: 0, exp: 'AI stands for Artificial Intelligence — the simulation of human intelligence processes by computers.' }, |
| 56 |
{ cat: 'technology', q: 'Which company created the Android operating system?', choices: ['Google', 'Apple', 'Samsung', 'Microsoft'], answer: 0, exp: 'Android was developed by Android Inc. and purchased by Google in 2005. It launched publicly in 2008.' } |
| 57 |
]; |
| 58 |
|
| 59 |
var CAT_NAMES = { |
| 60 |
science: 'Science & Nature', |
| 61 |
history: 'History', |
| 62 |
geography: 'Geography', |
| 63 |
popculture: 'Pop Culture', |
| 64 |
sports: 'Sports', |
| 65 |
technology: 'Technology', |
| 66 |
mixed: 'Mix' |
| 67 |
}; |
| 68 |
|
| 69 |
var CAT_EMOJIS = { |
| 70 |
science: '🔬', history: '🏛️', geography: '🌍', popculture: '🎬', sports: '⚽', technology: '💻', mixed: '🎯' |
| 71 |
}; |
| 72 |
|
| 73 |
function shuffle(arr) { |
| 74 |
var a = arr.slice(); |
| 75 |
for (var i = a.length - 1; i > 0; i--) { |
| 76 |
var j = Math.floor(Math.random() * (i + 1)); |
| 77 |
var tmp = a[i]; a[i] = a[j]; a[j] = tmp; |
| 78 |
} |
| 79 |
return a; |
| 80 |
} |
| 81 |
|
| 82 |
function getQuestions(category, count) { |
| 83 |
var pool = category === 'mixed' ? QUESTIONS : QUESTIONS.filter(function (q) { return q.cat === category; }); |
| 84 |
if (!pool.length) pool = QUESTIONS; |
| 85 |
var shuffled = shuffle(pool); |
| 86 |
return shuffled.slice(0, Math.min(count, shuffled.length)); |
| 87 |
} |
| 88 |
|
| 89 |
function shuffleAnswers(q) { |
| 90 |
var pairs = q.choices.map(function (c, i) { return { text: c, correct: i === q.answer }; }); |
| 91 |
var shuffledPairs = shuffle(pairs); |
| 92 |
return { choices: shuffledPairs.map(function (p) { return p.text; }), answer: shuffledPairs.findIndex(function (p) { return p.correct; }) }; |
| 93 |
} |
| 94 |
|
| 95 |
function initBlock(root) { |
| 96 |
var optsRaw = root.getAttribute('data-opts'); |
| 97 |
var opts; |
| 98 |
try { opts = JSON.parse(optsRaw); } catch (e) { opts = {}; } |
| 99 |
|
| 100 |
var accent = opts.accentColor || '#6366f1'; |
| 101 |
var correctCol = opts.correctColor || '#22c55e'; |
| 102 |
var wrongCol = opts.wrongColor || '#ef4444'; |
| 103 |
var cardBg = opts.cardBg || '#ffffff'; |
| 104 |
var titleColor = opts.titleColor || '#1e1b4b'; |
| 105 |
var sectionBg = opts.sectionBg || '#f0f4ff'; |
| 106 |
var maxQ = opts.questionsPerRound || 10; |
| 107 |
var timeSec = opts.timePerQuestion || 20; |
| 108 |
var catSetting = opts.category || 'mixed'; |
| 109 |
|
| 110 |
if (sectionBg) root.style.background = sectionBg; |
| 111 |
|
| 112 |
var titleEl = root.querySelector('.bkbg-trv-title'); |
| 113 |
if (titleEl) { titleEl.style.color = titleColor; } |
| 114 |
var subEl = root.querySelector('.bkbg-trv-subtitle'); |
| 115 |
if (subEl) { subEl.style.color = titleColor; } |
| 116 |
|
| 117 |
// ---- Game container ---- |
| 118 |
var wrap = document.createElement('div'); |
| 119 |
wrap.className = 'bkbg-trv-game'; |
| 120 |
root.appendChild(wrap); |
| 121 |
|
| 122 |
// ---- Game state ---- |
| 123 |
var questions, qIndex, score, correct_, wrong_, timerVal, timerInterval, answered; |
| 124 |
|
| 125 |
function startGame(category) { |
| 126 |
questions = getQuestions(category, maxQ).map(function (q) { |
| 127 |
var s = shuffleAnswers(q); |
| 128 |
return Object.assign({}, q, { choices: s.choices, answer: s.answer }); |
| 129 |
}); |
| 130 |
qIndex = 0; |
| 131 |
score = 0; |
| 132 |
correct_ = 0; |
| 133 |
wrong_ = 0; |
| 134 |
showQuestion(); |
| 135 |
} |
| 136 |
|
| 137 |
function stopTimer() { |
| 138 |
clearInterval(timerInterval); |
| 139 |
} |
| 140 |
|
| 141 |
function startTimer() { |
| 142 |
stopTimer(); |
| 143 |
timerVal = timeSec; |
| 144 |
updateTimer(); |
| 145 |
timerInterval = setInterval(function () { |
| 146 |
timerVal--; |
| 147 |
updateTimer(); |
| 148 |
if (timerVal <= 0) { |
| 149 |
stopTimer(); |
| 150 |
revealTimeUp(); |
| 151 |
} |
| 152 |
}, 1000); |
| 153 |
} |
| 154 |
|
| 155 |
// ---- Render functions ---- |
| 156 |
function showStart() { |
| 157 |
wrap.innerHTML = ''; |
| 158 |
var startDiv = document.createElement('div'); |
| 159 |
startDiv.className = 'bkbg-trv-start'; |
| 160 |
|
| 161 |
var heading = document.createElement('div'); |
| 162 |
heading.style.cssText = 'font-size:15px;font-weight:700;color:' + accent + ';margin-bottom:10px;'; |
| 163 |
heading.textContent = catSetting === 'mixed' ? '🎯 Choose a Category' : CAT_EMOJIS[catSetting] + ' ' + CAT_NAMES[catSetting]; |
| 164 |
startDiv.appendChild(heading); |
| 165 |
|
| 166 |
var cats = catSetting === 'mixed' |
| 167 |
? ['mixed','science','history','geography','popculture','sports','technology'] |
| 168 |
: [catSetting]; |
| 169 |
|
| 170 |
var grid = document.createElement('div'); |
| 171 |
grid.className = 'bkbg-trv-cat-grid'; |
| 172 |
|
| 173 |
cats.forEach(function (cat) { |
| 174 |
var btn = document.createElement('button'); |
| 175 |
btn.className = 'bkbg-trv-cat-btn'; |
| 176 |
btn.style.background = accent + '18'; |
| 177 |
btn.style.color = titleColor; |
| 178 |
btn.style.borderColor = accent + '44'; |
| 179 |
btn.innerHTML = '<div style="font-size:28px;margin-bottom:6px">' + (CAT_EMOJIS[cat] || '🎯') + '</div>' + CAT_NAMES[cat]; |
| 180 |
btn.addEventListener('click', function () { startGame(cat); }); |
| 181 |
grid.appendChild(btn); |
| 182 |
}); |
| 183 |
startDiv.appendChild(grid); |
| 184 |
|
| 185 |
var hint = document.createElement('p'); |
| 186 |
hint.style.cssText = 'font-size:13px;color:' + titleColor + ';opacity:0.5;'; |
| 187 |
hint.textContent = maxQ + ' questions · ' + timeSec + 's per question'; |
| 188 |
startDiv.appendChild(hint); |
| 189 |
|
| 190 |
wrap.appendChild(startDiv); |
| 191 |
} |
| 192 |
|
| 193 |
// Progress elements (re-used) |
| 194 |
var progressWrap, progressFill, progressLabel, timerWrap, timerPill, timerDot, timerSpan; |
| 195 |
var card, catLabel, questionEl, choicesGrid; |
| 196 |
var nextBtn, explanationDiv; |
| 197 |
|
| 198 |
function buildGameUI() { |
| 199 |
wrap.innerHTML = ''; |
| 200 |
|
| 201 |
// Score bar |
| 202 |
var scoreBar = document.createElement('div'); |
| 203 |
scoreBar.className = 'bkbg-trv-score-bar'; |
| 204 |
function makeScoreItem(id, label) { |
| 205 |
var item = document.createElement('div'); |
| 206 |
item.className = 'bkbg-trv-score-item'; |
| 207 |
item.style.color = titleColor; |
| 208 |
var num = document.createElement('div'); |
| 209 |
num.className = 'bkbg-trv-score-num'; |
| 210 |
num.id = 'bkbg-trv-' + id + '-' + Date.now(); |
| 211 |
num.textContent = '0'; |
| 212 |
var lbl = document.createElement('div'); |
| 213 |
lbl.className = 'bkbg-trv-score-lbl'; |
| 214 |
lbl.textContent = label; |
| 215 |
item.appendChild(num); |
| 216 |
item.appendChild(lbl); |
| 217 |
scoreBar.appendChild(item); |
| 218 |
return num; |
| 219 |
} |
| 220 |
var scoreNumEl = makeScoreItem('score', 'Score'); |
| 221 |
var correctNumEl = makeScoreItem('correct', '✓ Correct'); |
| 222 |
var wrongNumEl = makeScoreItem('wrong', '✗ Wrong'); |
| 223 |
wrap.appendChild(scoreBar); |
| 224 |
|
| 225 |
function updateScoreBar() { |
| 226 |
scoreNumEl.textContent = score; |
| 227 |
correctNumEl.textContent = correct_; |
| 228 |
wrongNumEl.textContent = wrong_; |
| 229 |
scoreNumEl.style.color = accent; |
| 230 |
correctNumEl.style.color = correctCol; |
| 231 |
wrongNumEl.style.color = wrongCol; |
| 232 |
} |
| 233 |
|
| 234 |
// Progress |
| 235 |
if (opts.showProgress !== false) { |
| 236 |
progressWrap = document.createElement('div'); |
| 237 |
progressWrap.className = 'bkbg-trv-progress-wrap'; |
| 238 |
var pgBg = document.createElement('div'); |
| 239 |
pgBg.className = 'bkbg-trv-progress-bar-bg'; |
| 240 |
progressFill = document.createElement('div'); |
| 241 |
progressFill.className = 'bkbg-trv-progress-bar-fill'; |
| 242 |
progressFill.style.background = accent; |
| 243 |
progressFill.style.width = '0%'; |
| 244 |
pgBg.appendChild(progressFill); |
| 245 |
progressLabel = document.createElement('span'); |
| 246 |
progressLabel.className = 'bkbg-trv-progress-label'; |
| 247 |
progressLabel.style.color = titleColor; |
| 248 |
progressWrap.appendChild(pgBg); |
| 249 |
progressWrap.appendChild(progressLabel); |
| 250 |
wrap.appendChild(progressWrap); |
| 251 |
} |
| 252 |
|
| 253 |
// Timer |
| 254 |
if (opts.showTimer !== false) { |
| 255 |
timerWrap = document.createElement('div'); |
| 256 |
timerWrap.className = 'bkbg-trv-timer-wrap'; |
| 257 |
timerPill = document.createElement('div'); |
| 258 |
timerPill.className = 'bkbg-trv-timer-pill'; |
| 259 |
timerPill.style.background = accent + '18'; |
| 260 |
timerDot = document.createElement('div'); |
| 261 |
timerDot.className = 'bkbg-trv-timer-dot'; |
| 262 |
timerDot.style.background = accent; |
| 263 |
timerSpan = document.createElement('span'); |
| 264 |
timerSpan.className = 'bkbg-trv-timer-value'; |
| 265 |
timerSpan.style.color = accent; |
| 266 |
timerPill.appendChild(timerDot); |
| 267 |
timerPill.appendChild(timerSpan); |
| 268 |
timerWrap.appendChild(timerPill); |
| 269 |
wrap.appendChild(timerWrap); |
| 270 |
} |
| 271 |
|
| 272 |
// Card |
| 273 |
card = document.createElement('div'); |
| 274 |
card.className = 'bkbg-trv-card'; |
| 275 |
card.style.background = cardBg; |
| 276 |
|
| 277 |
catLabel = document.createElement('div'); |
| 278 |
catLabel.className = 'bkbg-trv-cat-label'; |
| 279 |
catLabel.style.color = accent; |
| 280 |
card.appendChild(catLabel); |
| 281 |
|
| 282 |
questionEl = document.createElement('div'); |
| 283 |
questionEl.className = 'bkbg-trv-question'; |
| 284 |
questionEl.style.color = titleColor; |
| 285 |
card.appendChild(questionEl); |
| 286 |
|
| 287 |
choicesGrid = document.createElement('div'); |
| 288 |
choicesGrid.className = 'bkbg-trv-choices'; |
| 289 |
card.appendChild(choicesGrid); |
| 290 |
|
| 291 |
explanationDiv = document.createElement('div'); |
| 292 |
explanationDiv.className = 'bkbg-trv-explanation'; |
| 293 |
explanationDiv.style.display = 'none'; |
| 294 |
explanationDiv.style.background = accent + '14'; |
| 295 |
explanationDiv.style.color = titleColor; |
| 296 |
card.appendChild(explanationDiv); |
| 297 |
|
| 298 |
wrap.appendChild(card); |
| 299 |
|
| 300 |
// Next button |
| 301 |
nextBtn = document.createElement('button'); |
| 302 |
nextBtn.className = 'bkbg-trv-action-btn'; |
| 303 |
nextBtn.style.background = accent; |
| 304 |
nextBtn.style.color = '#fff'; |
| 305 |
nextBtn.style.display = 'none'; |
| 306 |
nextBtn.addEventListener('click', function () { |
| 307 |
qIndex++; |
| 308 |
if (qIndex >= questions.length) { |
| 309 |
showResults(); |
| 310 |
} else { |
| 311 |
showQuestion(); |
| 312 |
} |
| 313 |
}); |
| 314 |
wrap.appendChild(nextBtn); |
| 315 |
|
| 316 |
// re-expose updateScoreBar |
| 317 |
wrap._updateScore = updateScoreBar; |
| 318 |
return updateScoreBar; |
| 319 |
} |
| 320 |
|
| 321 |
var updateScoreBar; |
| 322 |
|
| 323 |
function updateTimer() { |
| 324 |
if (!timerSpan) return; |
| 325 |
timerSpan.textContent = timerVal + 's'; |
| 326 |
var ratio = timerVal / timeSec; |
| 327 |
var col = ratio > 0.5 ? correctCol : ratio > 0.25 ? '#f59e0b' : wrongCol; |
| 328 |
timerSpan.style.color = col; |
| 329 |
timerDot.style.background = col; |
| 330 |
timerPill.style.background = col + '18'; |
| 331 |
} |
| 332 |
|
| 333 |
function showQuestion() { |
| 334 |
answered = false; |
| 335 |
var q = questions[qIndex]; |
| 336 |
if (!card || !questionEl) { updateScoreBar = buildGameUI(); } |
| 337 |
|
| 338 |
if (progressFill) { progressFill.style.width = (qIndex / questions.length * 100) + '%'; } |
| 339 |
if (progressLabel) { progressLabel.textContent = (qIndex + 1) + ' / ' + questions.length; } |
| 340 |
|
| 341 |
catLabel.textContent = (CAT_EMOJIS[q.cat] || '') + ' ' + (CAT_NAMES[q.cat] || q.cat); |
| 342 |
questionEl.textContent = q.q; |
| 343 |
|
| 344 |
choicesGrid.innerHTML = ''; |
| 345 |
explanationDiv.style.display = 'none'; |
| 346 |
nextBtn.style.display = 'none'; |
| 347 |
|
| 348 |
q.choices.forEach(function (choice, i) { |
| 349 |
var btn = document.createElement('button'); |
| 350 |
btn.className = 'bkbg-trv-choice'; |
| 351 |
btn.style.color = titleColor; |
| 352 |
btn.textContent = choice; |
| 353 |
btn.addEventListener('click', function () { pickAnswer(i, q, btn); }); |
| 354 |
choicesGrid.appendChild(btn); |
| 355 |
}); |
| 356 |
|
| 357 |
startTimer(); |
| 358 |
} |
| 359 |
|
| 360 |
function pickAnswer(i, q, btn) { |
| 361 |
if (answered) return; |
| 362 |
answered = true; |
| 363 |
stopTimer(); |
| 364 |
revealAnswer(i, q); |
| 365 |
} |
| 366 |
|
| 367 |
function revealTimeUp() { |
| 368 |
if (answered) return; |
| 369 |
answered = true; |
| 370 |
wrong_++; |
| 371 |
if (wrap._updateScore) wrap._updateScore(); |
| 372 |
revealAnswer(-1, questions[qIndex]); |
| 373 |
} |
| 374 |
|
| 375 |
function revealAnswer(chosen, q) { |
| 376 |
var allBtns = choicesGrid.querySelectorAll('.bkbg-trv-choice'); |
| 377 |
allBtns.forEach(function (b, i) { |
| 378 |
b.disabled = true; |
| 379 |
if (i === q.answer) { |
| 380 |
b.classList.add('bkbg-trv-correct'); |
| 381 |
b.style.background = correctCol; |
| 382 |
b.style.color = '#fff'; |
| 383 |
} else if (i === chosen) { |
| 384 |
b.classList.add('bkbg-trv-wrong'); |
| 385 |
b.style.background = wrongCol; |
| 386 |
b.style.color = '#fff'; |
| 387 |
} else { |
| 388 |
b.style.opacity = '0.4'; |
| 389 |
} |
| 390 |
}); |
| 391 |
|
| 392 |
if (chosen === q.answer) { |
| 393 |
score += Math.max(10, Math.round(timerVal / timeSec * 100)); |
| 394 |
correct_++; |
| 395 |
} else if (chosen !== -1) { |
| 396 |
wrong_++; |
| 397 |
} else { |
| 398 |
// time up |
| 399 |
score = Math.max(0, score); |
| 400 |
} |
| 401 |
if (wrap._updateScore) wrap._updateScore(); |
| 402 |
|
| 403 |
if (opts.showExplanation !== false && q.exp) { |
| 404 |
explanationDiv.textContent = '💡 ' + q.exp; |
| 405 |
explanationDiv.style.display = 'block'; |
| 406 |
} |
| 407 |
|
| 408 |
nextBtn.textContent = qIndex + 1 >= questions.length ? 'See Results →' : 'Next Question →'; |
| 409 |
nextBtn.style.display = 'block'; |
| 410 |
} |
| 411 |
|
| 412 |
function showResults() { |
| 413 |
stopTimer(); |
| 414 |
wrap.innerHTML = ''; |
| 415 |
|
| 416 |
var pct = Math.round(correct_ / questions.length * 100); |
| 417 |
var trophy = pct >= 80 ? '🏆' : pct >= 50 ? '⭐' : '� |
| 418 |
'; |
| 419 |
|
| 420 |
var res = document.createElement('div'); |
| 421 |
res.className = 'bkbg-trv-results'; |
| 422 |
res.style.color = titleColor; |
| 423 |
|
| 424 |
var trophyEl = document.createElement('div'); |
| 425 |
trophyEl.className = 'bkbg-trv-trophy'; |
| 426 |
trophyEl.textContent = trophy; |
| 427 |
res.appendChild(trophyEl); |
| 428 |
|
| 429 |
var finalScore = document.createElement('div'); |
| 430 |
finalScore.className = 'bkbg-trv-final-score'; |
| 431 |
finalScore.style.color = accent; |
| 432 |
finalScore.textContent = score; |
| 433 |
res.appendChild(finalScore); |
| 434 |
|
| 435 |
var finalLabel = document.createElement('div'); |
| 436 |
finalLabel.className = 'bkbg-trv-final-label'; |
| 437 |
finalLabel.textContent = 'Total Score'; |
| 438 |
res.appendChild(finalLabel); |
| 439 |
|
| 440 |
var breakdown = document.createElement('div'); |
| 441 |
breakdown.className = 'bkbg-trv-breakdown'; |
| 442 |
[ |
| 443 |
{ label: '✓ Correct', val: correct_, col: correctCol }, |
| 444 |
{ label: '✗ Wrong', val: wrong_, col: wrongCol }, |
| 445 |
{ label: 'Accuracy', val: pct + '%', col: accent } |
| 446 |
].forEach(function (item) { |
| 447 |
var d = document.createElement('div'); |
| 448 |
d.className = 'bkbg-trv-breakdown-item'; |
| 449 |
d.innerHTML = '<span style="font-weight:700;font-size:22px;color:' + item.col + '">' + item.val + '</span><br><span style="opacity:0.6;font-size:12px">' + item.label + '</span>'; |
| 450 |
breakdown.appendChild(d); |
| 451 |
}); |
| 452 |
res.appendChild(breakdown); |
| 453 |
|
| 454 |
var pMsg = pct >= 80 ? 'Outstanding! You\'re a true trivia master! 🎉' : pct >= 60 ? 'Good job! Keep practicing!' : pct >= 40 ? 'Not bad! Try again to improve.' : 'Better luck next time! Try again.'; |
| 455 |
var msg = document.createElement('p'); |
| 456 |
msg.style.cssText = 'font-size:15px;margin-bottom:20px;opacity:0.75;'; |
| 457 |
msg.textContent = pMsg; |
| 458 |
res.appendChild(msg); |
| 459 |
|
| 460 |
var playBtn = document.createElement('button'); |
| 461 |
playBtn.className = 'bkbg-trv-action-btn'; |
| 462 |
playBtn.style.background = accent; |
| 463 |
playBtn.style.color = '#fff'; |
| 464 |
playBtn.style.maxWidth = '300px'; |
| 465 |
playBtn.textContent = '↩ Play Again'; |
| 466 |
playBtn.addEventListener('click', function () { showStart(); }); |
| 467 |
res.appendChild(playBtn); |
| 468 |
|
| 469 |
wrap.appendChild(res); |
| 470 |
} |
| 471 |
|
| 472 |
// Initialize |
| 473 |
updateScoreBar = function () {}; |
| 474 |
if (catSetting !== 'mixed') { |
| 475 |
startGame(catSetting); |
| 476 |
} else { |
| 477 |
showStart(); |
| 478 |
} |
| 479 |
} |
| 480 |
|
| 481 |
document.querySelectorAll('.bkbg-trv-app').forEach(function (root) { |
| 482 |
initBlock(root); |
| 483 |
}); |
| 484 |
})(); |
| 485 |
|