-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest-1.html
More file actions
399 lines (369 loc) · 27.5 KB
/
test-1.html
File metadata and controls
399 lines (369 loc) · 27.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
<!doctype html>
<html lang="uz">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"/>
<title>Yo'l harakati testi — Offline</title>
<style>
:root{
--bg:#eef1f4; --card:#ffffff; --text:#0f172a; --muted:#667085;
--primary:#2563eb; --ok:#22c55e; --bad:#ef4444; --ring:#e5e7eb;
}
*{box-sizing:border-box}
html,body{margin:0;background:var(--bg);color:var(--text);font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif}
.app{max-width:1180px;margin:0 auto;padding:14px}
/* === TOP BAR === */
.top{position:sticky;top:0;z-index:10;background:var(--bg);padding:10px 0 8px;display:grid;gap:10px;border-bottom:1px solid var(--ring)}
.row{display:flex;align-items:center;gap:10px}
.left{display:flex;align-items:center;gap:10px;flex:0 0 auto}
.strip{display:flex;align-items:center;gap:10px;flex:1 1 auto;flex-wrap:nowrap;min-width:0}
.langs{display:flex;gap:8px;white-space:nowrap;flex:0 0 auto}
.pill{padding:8px 12px;border-radius:10px;border:1px solid var(--ring);background:var(--card);cursor:pointer;font-weight:600;min-width:96px;text-align:center}
.pill.active{background:#1f2937;color:#fff;border-color:#1f2937}
.actionsTop{display:flex;gap:8px;flex:1 1 auto;flex-wrap:wrap;justify-content:flex-end;min-width:0}
.navbtn{width:44px;height:44px;border-radius:12px;border:0;background:var(--card);box-shadow:0 1px 0 rgba(0,0,0,.03),0 1px 3px rgba(0,0,0,.06);display:grid;place-items:center;cursor:pointer}
.hamb{width:34px;height:34px;border-radius:10px;border:1px solid var(--ring);background:var(--card);display:grid;place-items:center}
.hamb span{display:block;width:16px;height:2px;background:#111;margin:2px 0}
.timer{--p:0;width:90px;height:90px;border-radius:999px;background:conic-gradient(var(--primary) calc(var(--p)*360deg),#e5e7eb 0);display:grid;place-items:center}
.timer-inner{width:74px;height:74px;border-radius:999px;background:var(--card);display:grid;place-items:center;border:3px solid #f3f4f6;font-weight:700}
.status{font-size:13px;color:var(--muted)}
.btn{padding:10px 14px;border-radius:10px;border:0;cursor:pointer;font-weight:700}
.btn.finish{background:#22c55e;color:#fff}
.btn.reset{background:#0ea5e9;color:#fff}
.btn.ghost{background:#fff;border:1px solid var(--ring)}
.btn.danger{background:var(--bad)!important;color:#fff}
.nums{display:flex;gap:8px;flex-wrap:wrap}
.qnum{width:40px;height:40px;border-radius:10px;border:0;cursor:pointer;background:#e5e7eb;color:#111;font-weight:700}
.qnum.active{outline:3px solid var(--primary)}
.qnum.ok{background:var(--ok);color:#fff}
.qnum.bad{background:var(--bad);color:#fff}
/* === CARD === */
.card{margin-top:10px;background:var(--card);border:1px solid var(--ring);border-radius:16px;padding:16px;box-shadow:0 10px 20px rgba(0,0,0,.04)}
.qtitle{font-size:20px;font-weight:700;margin:6px 0 12px}
.grid{display:grid;grid-template-columns:1.2fr 1fr;gap:18px}
@media (max-width:980px){.grid{grid-template-columns:1fr}}
.imgbox{min-height:230px;border-radius:12px;background:#fff;border:1px solid var(--ring);display:grid;place-items:center;overflow:hidden}
.imgbox img{width:100%;height:100%;object-fit:contain;background:#fff}
.imgcap{display:none} /* hide image path under picture */
.opts{display:flex;flex-direction:column;gap:10px}
.opt{display:flex;align-items:flex-start;gap:10px;padding:14px;border-radius:12px;border:1px solid var(--ring);background:#fff;cursor:pointer;text-align:left}
.opt .fkey{min-width:42px;height:30px;border-radius:7px;background:#f1f5f9;border:1px solid var(--ring);display:grid;place-items:center;font-weight:700}
.opt.correct{border-color:var(--ok);background:#ecfdf5}
.opt.wrong{border-color:var(--bad);background:#fef2f2}
.opt.disabled{opacity:.75;pointer-events:none}
/* === Izoh toggle === */
.izoh{margin-top:12px;border-top:1px dashed var(--ring);padding-top:12px}
.izoh .lbl{margin-right:6px;cursor:pointer;user-select:none;display:inline-flex;align-items:center;gap:6px}
.izoh .lbl::after{content:"▼";font-size:12px;transform:translateY(-1px)}
.izoh.collapsed .lbl::after{content:"►"}
.izoh-body{margin-top:6px}
.izoh.collapsed .izoh-body{display:none}
.hint{color:var(--muted);font-size:13px}
</style>
</head>
<body>
<div class="app" id="app-root" data-test-scope="single">
<!-- TOP -->
<div class="top">
<div class="row">
<div class="left">
<div class="hamb" aria-label="menu"><span></span><span></span><span></span></div>
<button class="navbtn" id="prevBtn" title="Oldingi (←)">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M15 18l-6-6 6-6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</button>
<div class="timer" id="timer"><div class="timer-inner" id="timerText">25:00</div></div>
<button class="navbtn" id="nextBtn" title="Keyingi (→)">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M9 18l6-6-6-6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</button>
</div>
<div class="strip">
<div class="langs" id="langs"></div>
<div class="actionsTop">
<button class="btn finish" id="finishBtn">Testni yakunlash</button>
<button class="btn reset" id="resetBtn">Qayta boshlash</button>
<button class="btn ghost" id="showAnsBtn">To‘g‘ri javobni ko‘rsat</button>
<span class="status" id="statusText"></span>
</div>
</div>
</div>
<div class="row" style="justify-content:space-between">
<div class="nums" id="nums"></div>
<span class="hint" id="scriptLabel">Lotin</span>
</div>
</div>
<!-- CONTENT -->
<div class="card">
<div class="qtitle" id="qTitle">Savol</div>
<div class="grid">
<div>
<div class="imgbox"><img id="qImg" alt="Savol rasmi (JPG qo'ying)"/></div>
<div class="imgcap">Rasm: <code id="imgPath"></code></div>
</div>
<div>
<div class="opts" id="opts"></div>
<!-- IZOH: default yashirin, sarlavhani bosganda ochiladi -->
<div class="izoh collapsed" id="izohBox">
<b class="lbl" id="exLabel">Izoh yonidagi strelkani bosing:</b>
<div class="izoh-body"><span id="izohText">—</span></div>
</div>
<details style="margin-top:10px" id="ytDetails">
<summary>🎬 YouTube (ixtiyoriy)</summary>
<div id="videoEmbed" style="margin-top:8px;width:100%;height:0;padding-bottom:56.25%;position:relative;border-radius:12px;overflow:hidden;background:#000"></div>
<div class="hint">YouTube uchun internet kerak bo‘ladi.</div>
</details>
<script>
// YouTube embed link
const YT_LINK = "https://www.youtube.com/embed/fVsqHPSdqP4";
document.getElementById("ytDetails").addEventListener("toggle", e => {
const container = document.getElementById("videoEmbed");
if(e.target.open){
container.innerHTML = `
<iframe src="${YT_LINK}"
style="position:absolute;inset:0;width:100%;height:100%;border:0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen></iframe>`;
} else {
container.innerHTML = ""; // yopilganda tozalansin
}
});
</script>
</div>
<script>
/* === Izolyatsiya va ko‘p marta ishga tushishni bloklash === */
(function(){
if (window.__TEST_APP_INITED) return;
window.__TEST_APP_INITED = true;
/* === UI strings === */
const UI = {
uz:{langName:"O'zbek",script:"Lotin",finish:"Testni yakunlash",restart:"Qayta boshlash",showCorrect:"To‘g‘ri javobni ko‘rsat",question:"Savol",explanation:"Izoh:",incomplete:s=>`Hali ${s} ta savolga javob berilmadi.`,result:(ok,t)=>`Natija: ${ok}/${t} to‘g‘ri.`},
uzCy:{langName:"Ўзбек",script:"Кирилл",finish:"Тестни якунлаш",restart:"Қайта бошлаш",showCorrect:"Тўғри жавобни кўрсат",question:"Савол",explanation:"Изоҳ:",incomplete:s=>`Ҳали ${s} та саволга жавоб берилмади.`,result:(ok,t)=>`Натижа: ${ok}/${t} тўғри.`},
ru:{langName:"Русский",script:"Русский",finish:"Завершить тест",restart:"Начать заново",showCorrect:"Показать правильный ответ",question:"Вопрос",explanation:"Комментарий:",incomplete:s=>`Ещё ${s} без ответа.`,result:(ok,t)=>`Результат: ${ok} из ${t}.`}
};
const Q=(uz,uzCy,ru)=>({uz,uzCy,ru});
/* === Test ID — sahifa nomidan olinadi (masalan, test-1.html -> test-1) === */
const TEST_ID = (()=>{
const m = (location.pathname||"").match(/test-(\d+)/i);
return m ? `test-${m[1]}` : 'test-standalone';
})();
/* === Questions (10) — Har sahifada faqat shu massiv ishlatiladi === */
const QUESTIONS = [
{img:"images/1.jpg",video:"",text:Q("Bunday taniqlik belgisi bilan belgilanadigan transport vositasi:","Бундай таниқлик белгиси билан белгиланадиган транспорт воситаси:","Какое ТС обозначают такой опознавательной табличкой:"),options:[Q("Furgon yukxonasida odamlarni tashuvchi","Фургон юкхонасида одамларни ташувчи","Перевозит людей в кузове фургона"),Q("Uzunligi yuk bilan yoki yuksiz 20 metrdan ortiq bo'lgan transport vositasi","Узунлиги юк билан ёки юксиз 20 метрдан ортиқ бўлган транспорт воситаси","ТС длиной более 20 м (с грузом или без него)"),Q("Og'ir vaznli va yirik o'lchamli yuklarni tashuvchi","Оғир вазнли ва йирик ўлчамли юкларни ташувчи","Перевозит тяжеловесные и крупногабаритные грузы")],correct:1,explanation:Q("YHQ 29-bobi 176-band 9-xatboshiga ko‘ra: “Uzun o‘lchamli transport vositasi” — uzunligi 20 m dan oshadigan transport vositasida sariq fonli, qizil hoshiyali to‘rtburchak belgi bo‘ladi.","ЙҲҚ 29-боби 176-банд 9-хатбошига кўра: «Узун ўлчамли транспорт воситаси» — узунлиги 20 м дан ошадиган ТСда сариқ фонли, қизил ҳошияли тўртбурчак белги бўлади.","По ПДД: «Длинномерное ТС» — ТС длиной свыше 20 м, обозначается прямоугольной табличкой на жёлтом фоне с красной каймой.")},
{img:"images/2.jpg",video:"",text:Q("Umurtqasining ko'krak qismi shikastlangan kishi transportda qanday tashiladi?","Умуртқасининг кўкрак қисми шикастланган киши транспортда қандай ташилади?","Как перевозят пострадавшего с травмой грудного отдела позвоночника?"),options:[Q("Yumshoq to'shamada orqasi bilan yotgan holda","Юмшоқ тўшамада орқаси билан ётган ҳолда","Лёжа на спине на мягкой подстилке"),Q("Qattiq taxtada orqasi bilan yotgan holda","Қаттиқ тақтада орқаси билан ётган ҳолда","Лёжа на спине на жёстком щите"),Q("Qattiq taxtada yoni bilan yotgan holda","Қаттиқ тақтада ёни билан ётган ҳолда","Лёжа на боку на жёстком щите")],correct:1,explanation:Q("Umurtqa shikastida umurtqalar siljishini oldini olish uchun jabrlanuvchi qattiq tekislikka orqasi bilan yotqiziladi.","Умуртқа шикастида умурткалар силжишини олдини олиш учун жабрланувчи қаттиқ текисликка орқаси билан ётқизилади.","Чтобы исключить смещение позвонков, пострадавшего укладывают на спину на жёсткую поверхность.")},
{img:"images/3.jpg",video:"",text:Q("Chorrahadan birinchi bo‘lib qaysi avtomobil o‘tadi:","Чорраҳадан биринчи бўлиб қайси автомобиль ўтади:","Кто первым проедет перекрёсток:"),options:[Q("Ko'k avtomobil","Кўк автомобиль","Синий автомобиль"),Q("Qizil avtomobil","Қизил автомобиль","Красный автомобиль"),Q("Sariq avtomobil","Сариқ автомобиль","Жёлтый автомобиль"),Q("Yashil avtomobil","Яшил автомобиль","Зелёный автомобиль")],correct:3,explanation:Q("YHQ 16-bob 105-band: teng ahamiyatli yo‘llarda haydovchi o‘ngdan kelayotgan transportga yo‘l beradi.","ЙҲҚ 16-боб 105-банд: тенг ахамиятли йўлларда ҳайдовчи ўнгдан келаётган транспортга йўл беради.","Правило помехи справа на равнозначных дорогах.")},
{img:"images/4.jpg",video:"",text:Q("Yo'naltirgichlarning qaysilari bo'ylab harakatlanishga ruxsat etiladi?","Йўналтиргичларнинг қайсилари бўйлаб ҳаракатланишга рухсат этилади?","По каким указателям разрешено движение?"),options:[Q("Faqat A yo'nalish bo'ylab","Фақат А йўналиш бўйлаб","Только по направлению А"),Q("Faqat Б yo'nalish bo'ylab","Фақат Б йўналиш бўйлаб","Только по направлению Б"),Q("Faqat В yo'nalish bo'ylab","Фақат В йўналиш бўйлаб","Только по направлению В"),Q("Faqat Г yo'nalish bo'ylab","Фақат Г йўналиш бўйлаб","Только по направлению Г"),Q("Faqat A va Г yo'nalishlar bo'ylab","Фақат А ва Г йўналишлар бўйлаб","Только по А и Г")],correct:4,explanation:Q("YHQ 1-ilova 4.1.1: belgi yaqin chorrahagacha amal qiladi; A va Г yo‘nalishlar bo‘ylab ruxsat.","ЙҲҚ 1-илова 4.1.1: белги яқин чорраҳагча амал қилади; А ва Г бўйлаб рухсат.","Знак «Движение прямо»; разрешены направления А и Г.")},
{img:"images/5.jpg",video:"",text:Q("Tibbiyot qutichasi va o't o'chirgich bo'lmagan qanday transport vositalaridan foydalanish taqiqlanadi?","Тиббиёт қутичаси ва ўт ўчиргич бўлмаса, қайси ТС эксплуатацияси тақиқланади?","Эксплуатация каких ТС запрещена без аптечки и огнетушителя?"),options:[Q("Hamma sanab o'tilgan transport vositalaridan","Ҳамма санаб ўтилган ТС","Всех перечисленных ТС"),Q("Faqat M1, M2, N1 toifali transport vositalaridan","Фақат M1, M2, N1","Только M1, M2, N1"),Q("Faqat N1, N3 toifali transport vositalaridan","Фақат N1, N3","Только N1, N3"),Q("Faqat M1 toifali transport vositalaridan","Фақат M1","Только M1")],correct:0,explanation:Q("YHQ 3-ilova 7-bo‘lim 7.10-band.","ЙҲҚ 3-илова 7-бўлим 7.10-банд.","Согласно приложениям к ПДД.")},
{img:"images/6.jpg",video:"",text:Q("Haydovchi harakatlanishni boshlashdan oldin qanday amallarni bajarishi kerak?","Ҳайдовчи ҳаракатланишдан олдин нима қилиши керак?","Что сделать перед началом движения?"),options:[Q("TS sozligi va jihozlanganligini tekshirishi","ТС созлиги ва жиҳозланганлигини текшириш","Проверить исправность и комплектность"),Q("Burilish chirog‘i bilan ishora berishi","Бурилиш чироғи билан ишора","Подать сигнал поворота"),Q("Xavfsizlikka ishonch hosil qilishi va xalaqit bermasligi","Хавфсизликка ишонч ва халал келтирмаслик","Убедиться в безопасности и отсутствии помех"),Q("Hamma sanab o‘tilganlarini bajarishi","Ҳаммасини бажариш","Выполнить всё перечисленное")],correct:2,explanation:Q("YHQ 9-bob 53-band.","ЙҲҚ 9-боб 53-банд.","ПДД.")},
{img:"images/7.jpg",video:"",text:Q("Harakatlanish taqiqlangan:","Ҳаракатланиш тақиқланган:","Движение запрещено:"),options:[Q("Qizil va oq avtomobillarga","Қизил ва оқ автомобилларга","Красному и белому авто"),Q("Oq, ko'k va sariq avtomobillarga","Оқ, кўк ва сариқ автомобилларга","Белому, синему и жёлтому"),Q("Ko'k, yashil va oq avtomobillarga","Кўк, яшил ва оқ автомобилларга","Синему, зелёному и белому")],correct:2,explanation:Q("Tartibga soluvchining ayrim ishoralarida harakat taqiqlanadi.","Регулировщик айрим ишораларида ҳаракат тақиқланади.","При некоторых жестах движение запрещено.")},
{img:"images/8.jpg",video:"",text:Q("Shu joyda to'xtab turishga ruxsat etiladimi?","Шу жойда тўхтаб туришга рухсат этиладими?","Здесь разрешена стоянка?"),options:[Q("Taqiqlanadi","Тақиқланади","Запрещено"),Q("Ruxsat etiladi","Рухсат этилади","Разрешено")],correct:1,explanation:Q("YHQ 13-bob 91-band: shartlarga ko'ra ruxsat.","ЙҲҚ 13-боб 91-банд: шартларга кўра рухсат.","ПДД: разрешено при соблюдении условий.")},
{img:"images/9.jpg",video:"",text:Q("Bu belgilarning ta'sir oralig'ida qaysi avtomobil uchun to'xtashga ruxsat beriladi?","Бу белгилар таъсирида кимга тўхташ мумкин?","В зоне действий этих знаков кому можно стоять?"),options:[Q("Hech qaysisiga","Ҳеч қайсига","Никому"),Q("Qizil avtomobilga","Қизил автомобилга","Красному авто"),Q("Har ikkala avtomobilga","Ҳар иккаласига","Обоим"),Q("\"Nogiron\" belgisi bor sariq avtomobilga","«Ноғирон» белгиcи бор сариқ автомобилга","Жёлтому с табличкой «Инвалид»")],correct:3,explanation:Q("YHQ 3.27 va 7.18 bo‘yicha istisno.","ЙҲҚ 3.27 ва 7.18 бўйича истисно.","Исключение для «Инвалид».")},
{img:"images/10.jpg",video:"",text:Q("Qaysi transport vositasining haydovchisi chorrahadan birinchi bo'lib o'tadi?","Қайси ҳайдовчи биринчи ўтади?","Кто первым проедет перекрёсток?"),options:[Q("Avtomobil va avtobus haydovchisi","Автомобиль ва автобус","Водитель авто и автобуса"),Q("Tramvay haydovchisi","Трамвай ҳайдовчиси","Водитель трамвая")],correct:0,explanation:Q("YHQ 15-bob 100-band.","ЙҲҚ 15-боб 100-банд.","ПДД: дополнительная секция.")}
];
/* === State === */
let lang='uz', idx=0, answered=Array(QUESTIONS.length).fill(null), locked=false;
const FULL_SECONDS=25*60; let leftSec=FULL_SECONDS; let tick=null;
/* === Shuffle helpers === */
function shuffledIndices(n){
const a=[...Array(n).keys()];
for(let i=n-1;i>0;i--){ const j=Math.floor(Math.random()*(i+1)); [a[i],a[j]]=[a[j],a[i]]; }
return a;
}
let displayOrder = QUESTIONS.map(q=>shuffledIndices(q.options.length));
let pickedDisplay = Array(QUESTIONS.length).fill(null);
/* === DOM === */
const langsEl=document.getElementById('langs');
const numsEl=document.getElementById('nums');
const qTitle=document.getElementById('qTitle');
const qImg=document.getElementById('qImg');
const imgPath=document.getElementById('imgPath');
const optsEl=document.getElementById('opts');
const izohText=document.getElementById('izohText');
const exLabel=document.getElementById('exLabel');
const izohBox=document.getElementById('izohBox');
const videoEmbed=document.getElementById('videoEmbed');
const timer=document.getElementById('timer');
const timerText=document.getElementById('timerText');
const finishBtn=document.getElementById('finishBtn');
const resetBtn=document.getElementById('resetBtn');
const showAnsBtn=document.getElementById('showAnsBtn');
const prevBtn=document.getElementById('prevBtn');
const nextBtn=document.getElementById('nextBtn');
const statusText=document.getElementById('statusText');
const scriptLabel=document.getElementById('scriptLabel');
/* === Build === */
function setLang(code){
const y=window.scrollY; // keep scroll position (no jump)
lang=code; refreshUI(); window.scrollTo(0,y);
}
function buildLangs(){
langsEl.innerHTML='';
['uz','uzCy','ru'].forEach(code=>{
const b=document.createElement('button');
b.className='pill'+(lang===code?' active':''); b.textContent=UI[code].langName;
b.addEventListener('click',e=>{e.preventDefault();setLang(code)});
langsEl.appendChild(b);
});
}
function buildNums(){
numsEl.innerHTML='';
QUESTIONS.forEach((_,i)=>{
const b=document.createElement('button'); b.className='qnum'; b.textContent=i+1;
b.onclick=()=>{idx=i; refreshUI();}; numsEl.appendChild(b);
});
}
function setNumState(i,state){
const b=numsEl.children[i]; if(!b) return; b.classList.remove('ok','bad');
if(state===true) b.classList.add('ok'); else if(state===false) b.classList.add('bad');
}
function markActive(){[...numsEl.children].forEach(el=>el.classList.remove('active')); if(numsEl.children[idx]) numsEl.children[idx].classList.add('active');}
/* === Render === */
function renderQuestion(){
const q=QUESTIONS[idx];
qTitle.textContent=UI[lang].question+': '+q.text[lang];
exLabel.textContent=UI[lang].explanation;
scriptLabel.textContent=UI[lang].script;
qImg.src=q.img; if(imgPath) imgPath.textContent=q.img;
// Build options by shuffled display order
optsEl.innerHTML='';
const order = displayOrder[idx];
const keys=['F1','F2','F3','F4','F5'];
order.forEach((origIndex,dispIndex)=>{
const btn=document.createElement('button');
btn.className='opt';
btn.innerHTML=`<div class="fkey">${keys[dispIndex]||''}</div><div>${q.options[origIndex][lang]}</div>`;
btn.onclick=()=>choose(dispIndex);
optsEl.appendChild(btn);
});
// Izoh: faqat matnni yangilaymiz, ochilish holatini o'zgartirmaymiz
izohText.textContent=q.explanation[lang];
videoEmbed.innerHTML='';
if(q.video){
const embed=q.video.includes('embed')?q.video:q.video.replace('watch?v=','embed/');
const iframe=document.createElement('iframe');
Object.assign(iframe.style,{position:'absolute',inset:'0',width:'100%',height:'100%',border:'0'});
iframe.src=embed; iframe.allow="autoplay; encrypted-media"; iframe.allowFullscreen=true;
videoEmbed.appendChild(iframe);
}
decorate();
}
function decorate(){
const q=QUESTIONS[idx]; const chosen=answered[idx];
const order = displayOrder[idx];
const all=[...optsEl.children];
all.forEach(el=>el.classList.remove('correct','wrong','disabled'));
if(chosen===true || chosen===false){
const corrDisp = order.indexOf(q.correct);
if(corrDisp>-1 && all[corrDisp]) all[corrDisp].classList.add('correct');
if(chosen===false && pickedDisplay[idx]!=null && all[pickedDisplay[idx]]){
all[pickedDisplay[idx]].classList.add('wrong');
}
all.forEach(el=>el.classList.add('disabled'));
}
if(locked) all.forEach(el=>el.classList.add('disabled'));
statusText.textContent = summaryLine();
}
/* === Izoh toggle === */
izohBox.classList.add('collapsed'); // default yashirin
exLabel.addEventListener('click', ()=>{
izohBox.classList.toggle('collapsed');
});
/* === Choose === */
function choose(displayIdx){
if(locked) return;
const q=QUESTIONS[idx]; const order = displayOrder[idx];
const orig = order[displayIdx];
const ok = (orig === q.correct);
answered[idx] = ok ? true : false;
pickedDisplay[idx] = ok ? null : displayIdx;
[...optsEl.children].forEach((el,k)=>{
if(k===order.indexOf(q.correct)) el.classList.add('correct');
if(!ok && k===displayIdx){ el.classList.add('wrong'); }
el.classList.add('disabled');
});
setNumState(idx,answered[idx]);
statusText.textContent=summaryLine();
}
/* === Navigation === */
function go(d){ idx=Math.max(0,Math.min(QUESTIONS.length-1,idx+d)); refreshUI(); }
/* === Timer === */
function fmt(t){const m=Math.floor(t/60),s=t%60;return `${String(m).padStart(2,'0')}:${String(s).padStart(2,'0')}`;}
function startTimer(){
clearInterval(tick);
tick=setInterval(()=>{
leftSec=Math.max(0,leftSec-1);
timer.style.setProperty('--p',(FULL_SECONDS-leftSec)/FULL_SECONDS);
timerText.textContent=fmt(leftSec);
if(leftSec===0){ clearInterval(tick); timeUp(); }
},1000);
}
function timeUp(){
locked=true;
answered=answered.map(v=>v===null?false:v);
answered.forEach((v,i)=>setNumState(i,v)); // color all numbers
decorate();
finishBtn.classList.add('danger');
}
/* === Finish/Reset === */
function summaryLine(){
const left=answered.filter(v=>v===null).length;
const ok=answered.filter(v=>v===true).length;
return locked?UI[lang].result(ok,QUESTIONS.length):(left>0?UI[lang].incomplete(left):UI[lang].result(ok,QUESTIONS.length));
}
function finish(){
const left=answered.filter(v=>v===null).length;
answered=answered.map(v=>v===null?false:v); // javobsizlar qizil bo'lsin
answered.forEach((v,i)=>setNumState(i,v));
locked=true;
decorate();
if(left>0){ finishBtn.classList.add('danger'); }
}
function reshuffleAll(){
displayOrder = QUESTIONS.map(q=>shuffledIndices(q.options.length));
pickedDisplay = Array(QUESTIONS.length).fill(null);
}
function resetAll(){
answered=Array(QUESTIONS.length).fill(null);
[...numsEl.children].forEach((_,i)=>setNumState(i,null));
idx=0; locked=false; leftSec=FULL_SECONDS;
timer.style.setProperty('--p',0); timerText.textContent=fmt(leftSec);
finishBtn.classList.remove('danger');
reshuffleAll();
refreshUI();
izohBox.classList.add('collapsed'); // resetda ham izoh yopiq
}
/* === Top actions === */
finishBtn.onclick=finish; resetBtn.onclick=resetAll;
showAnsBtn.onclick=()=>{
if(locked) return;
const order = displayOrder[idx];
const corrDisp = order.indexOf(QUESTIONS[idx].correct);
[...optsEl.children].forEach((el,i)=>{ if(i===corrDisp) el.classList.add('correct'); });
};
prevBtn.onclick=()=>go(-1); nextBtn.onclick=()=>go(1);
/* === Keyboard === */
document.addEventListener('keydown',e=>{
if(e.key==='ArrowLeft'){e.preventDefault();go(-1)}
if(e.key==='ArrowRight'){e.preventDefault();go(1)}
const map={F1:0,F2:1,F3:2,F4:3,F5:4};
if(map[e.key]!==undefined){
e.preventDefault();
const i=map[e.key];
if(i<QUESTIONS[idx].options.length) choose(i);
}
});
/* === Init === */
function buildAll(){buildLangs();buildNums();}
function refreshUI(){
buildLangs();
answered.forEach((v,i)=>setNumState(i,v));
markActive();
finishBtn.textContent=UI[lang].finish;
resetBtn.textContent=UI[lang].restart;
showAnsBtn.textContent=UI[lang].showCorrect;
renderQuestion();
}
reshuffleAll(); // shuffle once at first load
buildAll(); refreshUI(); startTimer();
})(); // end IIFE
</script>
</body>
</html>