<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Entrenador OECE — Campus Gamificado</title>
<style>
:root{
--bg:#0f172a; --card:#111827; --muted:#1f2937; --accent:#22c55e;
--accent-2:#3b82f6; --text:#e5e7eb; --text-dim:#9ca3af; --warn:#f59e0b; --danger:#ef4444;
}
*{box-sizing:border-box} body{margin:0;background:linear-gradient(180deg,#0b1023,#0f172a);color:var(--text);font-family:Inter,system-ui,Segoe UI,Roboto,Helvetica,Arial}
a{color:var(--accent-2);text-decoration:none}
.container{max-width:1200px;margin:auto;padding:24px}
.grid{display:grid;gap:16px}
.g-2{grid-template-columns:1.3fr .7fr}
.g-3{grid-template-columns:repeat(3,1fr)}
header{display:flex;align-items:center;justify-content:space-between;padding:16px 0}
.brand{display:flex;gap:12px;align-items:center}
.logo{width:40px;height:40px;border-radius:12px;background:conic-gradient(from 0deg,var(--accent),var(--accent-2));box-shadow:0 0 24px #22c55e55}
.pill{background:#0b1224;border:1px solid #1f2a44;padding:6px 10px;border-radius:999px;color:var(--text-dim);font-size:12px}
.card{background:radial-gradient(1200px 300px at 20% -20%,#18213a,transparent),#0c1326;border:1px solid #1f2a44;border-radius:16px;box-shadow:0 12px 30px #0006}
.card > .hd{padding:16px 16px 0;font-weight:700}
.card > .bd{padding:16px}
.btn{background:linear-gradient(135deg,var(--accent),#16a34a);border:none;color:#0a0f1f;padding:10px 14px;border-radius:12px;font-weight:700;cursor:pointer}
.btn.secondary{background:#0b1224;color:var(--text);border:1px solid #263250}
.btn.ghost{background:transparent;border:1px dashed #334155;color:var(--text-dim)}
.muted{color:var(--text-dim)}
.progress{height:10px;background:#0b1224;border-radius:999px;overflow:hidden;border:1px solid #253150}
.bar{height:100%;background:linear-gradient(90deg,var(--accent),#16a34a)}
.row{display:flex;align-items:center;justify-content:space-between;gap:12px}
.chip{background:#0b1224;border:1px solid #293556;border-radius:10px;padding:6px 10px;font-size:12px;color:var(--text-dim)}
.list{display:grid;gap:10px}
.medal{display:flex;gap:10px;align-items:center}
.medal i{width:12px;height:12px;border-radius:50%;background:conic-gradient(from 0,var(--warn),#fde68a)}
.score{font-weight:800;font-size:28px}
.kbd{font-family:ui-monospace,Menlo,monospace;background:#0b1224;border:1px solid #28324e;border-radius:6px;padding:2px 6px}
.question{border:1px solid #27314d;border-radius:14px;padding:14px;background:#0b1224}
.answers{display:grid;gap:10px;margin-top:10px}
.opt{border:1px solid #2b375a;border-radius:10px;padding:10px;cursor:pointer;background:#0c152a}
.opt.correct{border-color:#15803d;background:#0c1f14}
.opt.wrong{border-color:#7f1d1d;background:#1a0c0c}
.hint{margin-top:8px;color:#a7f3d0}
.sustento{margin-top:10px;border-top:1px dashed #334155;padding-top:8px;color:#cbd5e1}
.tags{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
.tag{font-size:11px;padding:4px 8px;border-radius:999px;background:#0b1224;border:1px solid #2a3657;color:#93c5fd}
.tabs{display:flex;gap:8px;flex-wrap:wrap}
.tab{padding:8px 10px;border:1px solid #263150;border-radius:10px;background:#0b1224;color:#cbd5e1;cursor:pointer}
.tab.active{background:linear-gradient(135deg,#1d253f,#0b1224);border-color:#3a4e80}
.right .card{position:sticky;top:16px}
.mono{font-family:ui-monospace,Menlo,monospace}
.foot{margin-top:18px;color:#94a3b8;font-size:12px}
.modal{position:fixed;inset:0;background:#0009;display:none;align-items:center;justify-content:center;padding:20px;z-index:50}
.modal .content{max-width:520px;background:#0c1326;border:1px solid #233055;border-radius:16px;padding:20px}
.rank table{width:100%;border-collapse:collapse}
.rank th,.rank td{padding:8px;border-bottom:1px solid #223055;text-align:left}
@media (max-width:980px){ .g-2{grid-template-columns:1fr} .right .card{position:relative} }
</style>
</head>
<body>
<div class="container">
<header>
<div class="brand">
<div class="logo"></div>
<div>
<div style="font-weight:800;letter-spacing:.2px">Entrenador OECE</div>
<div class="muted" style="font-size:12px">Campus virtual gamificado — Ley 32069</div>
</div>
</div>
<div class="row" style="gap:8px">
<span class="pill">Versión demo · Freemium 5 preguntas</span>
<button class="btn secondary" id="btnLogin">Ingresar</button>
<button class="btn" id="btnComprar">Suscribirme</button>
</div>
</header>
<div class="grid g-2">
<!-- Izquierda: simulador y dashboard -->
<div class="left grid" style="gap:16px">
<div class="card">
<div class="hd">Panel de Progreso</div>
<div class="bd">
<div class="grid g-3">
<div>
<div class="row"><strong>Actuaciones</strong><span id="p1p" class="muted">0/25</span></div>
<div class="progress"><div id="p1" class="bar" style="width:0%"></div></div>
</div>
<div>
<div class="row"><strong>Selección</strong><span id="p2p" class="muted">0/22</span></div>
<div class="progress"><div id="p2" class="bar" style="width:0%"></div></div>
</div>
<div>
<div class="row"><strong>Ejecución</strong><span id="p3p" class="muted">0/25</span></div>
<div class="progress"><div id="p3" class="bar" style="width:0%"></div></div>
</div>
</div>
<div class="row" style="margin-top:12px">
<div>Avance total</div>
<div class="score" id="score">0 pts</div>
</div>
<div class="progress"><div id="ptotal" class="bar" style="width:0%"></div></div>
<div class="tags">
<span class="tag">Racha: <span id="racha">0</span></span>
<span class="tag">Nivel: <span id="nivel">Novato</span></span>
<span class="tag">Medallas: <span id="medallas">0</span></span>
</div>
<div class="foot">Tip: usa <span class="kbd">M</span> para cambiar de módulo, <span class="kbd">H</span> para pista.</div>
</div>
</div>
<div class="card">
<div class="hd">Modo de Estudio</div>
<div class="bd">
<div class="tabs">
<button class="tab active" data-mode="simulacro">Simulacro 72</button>
<button class="tab" data-mode="actuaciones">Actuaciones (25)</button>
<button class="tab" data-mode="seleccion">Selección (22)</button>
<button class="tab" data-mode="ejecucion">Ejecución (25)</button>
</div>
<div class="tabs" style="margin-top:8px">
<span class="chip">Bloom:</span>
<button class="tab active" data-bloom="recordar">Recordar</button>
<button class="tab" data-bloom="aplicar">Aplicar</button>
<button class="tab" data-bloom="evaluar">Evaluar</button>
</div>
</div>
</div>
<div class="card" id="quizCard">
<div class="hd">Pregunta <span id="numQ">1</span> / <span id="totalQ">10</span></div>
<div class="bd">
<div class="question">
<div id="enunciado">Cargando pregunta…</div>
<div class="tags"><span class="tag" id="faseTag">Fase: —</span><span class="tag" id="tipoTag">Tipo: —</span><span class="tag" id="bloomTag">Bloom: —</span></div>
<div class="answers" id="answers"></div>
<div class="row" style="margin-top:10px;gap:8px">
<button class="btn secondary" id="btnHint">Pista (H)</button>
<button class="btn ghost" id="btnSaltar">Saltar</button>
<button class="btn" id="btnSiguiente" disabled>Siguiente</button>
</div>
<div id="hint" class="hint" style="display:none"></div>
<div id="sustento" class="sustento" style="display:none"></div>
</div>
</div>
</div>
</div>
<!-- Derecha: IA + Ranking + Medallas -->
<div class="right grid" style="gap:16px">
<div class="card">
<div class="hd">Asistentes IA (demo)</div>
<div class="bd">
<div class="list">
<div class="row"><div><strong>Redactor de TDR</strong><div class="muted">Provee objetivos, alcance, criterios y entregables</div></div><button class="btn ghost">Abrir</button></div>
<div class="row"><div><strong>Cotizaciones</strong><div class="muted">Genera tabla y comparativo</div></div><button class="btn ghost">Abrir</button></div>
<div class="row"><div><strong>Consultas Ley 32069</strong><div class="muted">Respuestas con artículo y fundamento</div></div><button class="btn ghost">Abrir</button></div>
</div>
</div>
</div>
<div class="card rank">
<div class="hd">Ranking Global</div>
<div class="bd">
<table>
<thead><tr><th>#</th><th>Usuario</th><th>Puntos</th></tr></thead>
<tbody id="rankBody">
<tr><td>1</td><td>María Q.</td><td>1890</td></tr>
<tr><td>2</td><td>Carlos R.</td><td>1740</td></tr>
<tr><td>3</td><td>Tú</td><td id="tuPuntaje">0</td></tr>
</tbody>
</table>
</div>
</div>
<div class="card">
<div class="hd">Medallas</div>
<div class="bd">
<div class="list">
<div class="medal"><i></i> <div><strong>Experto en Actuaciones</strong><div class="muted">80%+ correctas en Actuaciones</div></div></div>
<div class="medal"><i></i> <div><strong>Maestro en Selección</strong><div class="muted">80%+ correctas en Selección</div></div></div>
<div class="medal"><i></i> <div><strong>Dominador de Ejecución</strong><div class="muted">80%+ correctas en Ejecución</div></div></div>
</div>
</div>
</div>
<div class="card">
<div class="hd">Blog (IA)</div>
<div class="bd">
<div class="list">
<div><strong>Claves del artículo 19: certificación</strong><div class="muted">Roles, niveles y vigencia</div></div>
<div><strong>Cómo armar tu Plan Anual de Contrataciones</strong><div class="muted">Buenas prácticas OECE</div></div>
<a href="#" class="btn secondary" style="width:100%;text-align:center;margin-top:8px">Ver blog</a>
</div>
</div>
</div>
</div>
</div>
<footer style="margin-top:24px" class="muted">
© <span id="y"></span> Entrenador OECE — Demo UI. Integra con LMS, QSM, GamiPress y WooCommerce para producción.
</footer>
</div>
<!-- Modal Freemium -->
<div class="modal" id="paywall">
<div class="content">
<h3>Continúa con acceso Premium</h3>
<p class="muted">Has alcanzado tu límite gratis de 5 preguntas. Suscríbete para acceso ilimitado a simulacros, IA y ranking.</p>
<div class="list">
<div class="row"><strong>Suscripción mensual</strong><span>S/ —</span></div>
<div class="row"><span class="muted">Incluye IA, retos y medallas</span><button class="btn" id="goCheckout">Pagar con Yape / Plin</button></div>
</div>
<div class="row" style="margin-top:10px;justify-content:flex-end">
<button class="btn secondary" id="cerrarPaywall">Cerrar</button>
</div>
</div>
</div>
<!-- Modal Login -->
<div class="modal" id="login">
<div class="content">
<h3>Iniciar sesión</h3>
<p class="muted">Accede para guardar tu progreso en la nube.</p>
<div class="list">
<input id="email" placeholder="Correo" style="padding:10px;border-radius:10px;border:1px solid #2a3657;background:#0b1224;color:#e5e7eb">
<input id="pass" type="password" placeholder="Contraseña" style="padding:10px;border-radius:10px;border:1px solid #2a3657;background:#0b1224;color:#e5e7eb">
<label style="display:flex;align-items:center;gap:8px;font-size:12px" class="muted">
<input type="checkbox" id="tfa"> Activar 2FA en mi cuenta
</label>
<button class="btn" id="doLogin">Continuar</button>
</div>
<div class="row" style="margin-top:10px;justify-content:flex-end">
<button class="btn secondary" id="cerrarLogin">Cerrar</button>
</div>
</div>
</div>
<script>
(function(){
const yearEl = document.getElementById('y'); yearEl.textContent = new Date().getFullYear();
const state = {
mode:'simulacro', bloom:'recordar',
questionIndex:0, total:10, // demo: se ajusta al configurar modo
score:0, racha:0, medallas:0,
respondidas:{act:0, sel:0, eje:0}, // conteo por fase
freeUsed: parseInt(localStorage.getItem('oece_free')||'0',10)
};
// Dataset demo (reemplaza por tu banco real/JSON desde QSM o WP REST)
const deck = {
actuaciones: [
{tipo:'opcion', bloom:'recordar', fase:'Actuaciones',
q:'¿Quién aprueba el Plan Anual de Supervisión del OECE?',
a:['Consejo Directivo del OECE','DGA','Titular de la Entidad','TCP','MEF'],
ok:0, pista:'Busca “Artículo 7.1 del Reglamento”.',
sustento:'Reglamento, art. 7.1: el Consejo Directivo del OECE lo aprueba en el primer mes del año fiscal.'},
{tipo:'vf', bloom:'aplicar', fase:'Actuaciones',
q:'V/F: La asistencia técnica del OECE reemplaza responsabilidades de la entidad.',
a:['Verdadero','Falso'], ok:1, pista:'“No implica responsabilidad del OECE”.',
sustento:'Reglamento, art. 10.4: No sustituye funciones ni responsabilidad de la entidad contratante.'},
{tipo:'gap', bloom:'recordar', fase:'Actuaciones',
q:'Complete: El RNP forma parte de la plataforma digital denominada _____.',
a:['Pladicop'], ok:0, pista:'Ver art. 25.1.',
sustento:'Reglamento, art. 25.1: El RNP forma parte de la Pladicop.'},
],
seleccion: [
{tipo:'opcion', bloom:'evaluar', fase:'Selección',
q:'¿Qué órgano verifica requisitos para suscripción del contrato?',
a:['Área usuaria','DEC','Oficina de Presupuesto','OECE','Perú Compras'],
ok:1, pista:'Funciones DEC en Título II.',
sustento:'Reglamento, art.17.2.i: La DEC verifica la documentación necesaria para la suscripción.'},
{tipo:'match', bloom:'aplicar', fase:'Selección',
q:'Empareje: (Órgano → Función principal)',
pairs:[['DGA','Norma técnica del SNA'],['OECE','Supervisión y asistencia'],['Perú Compras','Estandarización y AM']],
pista:'Cap. I DGA, OECE y Perú Compras.',
sustento:'Reglamento, arts. 6, 8 y 13.'},
],
ejecucion: [
{tipo:'opcion', bloom:'aplicar', fase:'Ejecución',
q:'¿Quién autoriza modificaciones contractuales que correspondan?',
a:['Titular de la entidad','Autoridad de la gestión administrativa','DEC','Área usuaria','TCP'],
ok:1, pista:'Revisa art. 22.',
sustento:'Reglamento, art. 22.c: Autoriza las modificaciones contractuales que correspondan.'},
{tipo:'vf', bloom:'recordar', fase:'Ejecución',
q:'V/F: La conformidad de contrato la emite la DEC.',
a:['Verdadero','Falso'], ok:1, pista:'Rol del área usuaria.',
sustento:'Reglamento, art. 23.c: El área usuaria emite la conformidad.'},
{tipo:'case', bloom:'evaluar', fase:'Ejecución',
q:'Caso: Una obra supera capacidad máxima del ejecutor según CMC. ¿Procede adjudicar?',
a:['Sí, con garantía adicional','No, requiere CCLC suficiente','Sí, si hay consentimiento','Procede por excepción','Depende del TCP'],
ok:1, pista:'Constancia de Capacidad Libre de Contratación.',
sustento:'Reglamento, art. 32.1: CCLC certifica monto no comprometido de la CMC para perfeccionar contrato.'},
]
};
// Configuración de modos
const tabs = document.querySelectorAll('.tab[data-mode]');
const bloomTabs = document.querySelectorAll('.tab[data-bloom]');
const elQ = {num:$('#numQ'), total:$('#totalQ'), enun:$('#enunciado'), ans:$('#answers'), hint:$('#hint'), sust:$('#sustento'), fase:$('#faseTag'), tipo:$('#tipoTag'), bloom:$('#bloomTag')};
const btnNext = $('#btnSiguiente'), btnHint=$('#btnHint'), btnSkip=$('#btnSaltar');
tabs.forEach(t=>t.addEventListener('click',()=>{ tabs.forEach(x=>x.classList.remove('active')); t.classList.add('active'); state.mode=t.dataset.mode; setupDeck(); }));
bloomTabs.forEach(t=>t.addEventListener('click',()=>{ bloomTabs.forEach(x=>x.classList.remove('active')); t.classList.add('active'); state.bloom=t.dataset.bloom; setupDeck(); }));
document.addEventListener('keydown',(e)=>{
if(e.key.toLowerCase()==='m'){ cycleMode(); }
if(e.key.toLowerCase()==='h'){ showHint(); }
});
$('#btnComprar').addEventListener('click',()=>open('#paywall'));
$('#cerrarPaywall').addEventListener('click',()=>close('#paywall'));
$('#goCheckout').addEventListener('click',()=>alert('Conectar a WooCommerce + Yape/Plin en producción.'));
$('#btnLogin').addEventListener('click',()=>open('#login'));
$('#cerrarLogin').addEventListener('click',()=>close('#login'));
$('#doLogin').addEventListener('click',()=>{ alert('Autenticar contra WordPress + 2FA.'); close('#login'); });
btnHint.addEventListener('click',showHint);
btnSkip.addEventListener('click',()=>{ nextQ(); });
btnNext.addEventListener('click',()=>{ nextQ(); });
function $(q){ return document.querySelector(q); }
function open(sel){ document.querySelector(sel).style.display='flex'; }
function close(sel){ document.querySelector(sel).style.display='none'; }
function cycleMode(){
const order=['simulacro','actuaciones','seleccion','ejecucion'];
let idx=order.indexOf(state.mode); idx=(idx+1)%order.length;
document.querySelector(`.tab[data-mode].active`)?.classList.remove('active');
document.querySelector(`.tab[data-mode="${order[idx]}"]`)?.classList.add('active');
state.mode=order[idx]; setupDeck();
}
// Construye mazo según modo y bloom
let currentDeck=[];
function setupDeck(){
const bloom = state.bloom;
let pool=[];
const pickBloom = arr => arr.filter(x=>x.bloom===bloom || bloom==='recordar' && Math.random()<0.5); // simple demo
if(state.mode==='simulacro'){
// 25-22-25 respetando proporciones, mezclando bloom
pool = sample(pickBloom(deck.actuaciones).concat(deck.actuaciones),25)
.concat(sample(pickBloom(deck.seleccion).concat(deck.seleccion),22))
.concat(sample(pickBloom(deck.ejecucion).concat(deck.ejecucion),25));
pool = shuffle(pool);
state.total=pool.length; // 72 si hay banco completo
} else if(state.mode==='actuaciones'){
pool = shuffle(pickBloom(deck.actuaciones).concat(deck.actuaciones)).slice(0,25);
state.total=pool.length;
} else if(state.mode==='seleccion'){
pool = shuffle(pickBloom(deck.seleccion).concat(deck.seleccion)).slice(0,22);
state.total=pool.length;
} else {
pool = shuffle(pickBloom(deck.ejecucion).concat(deck.ejecucion)).slice(0,25);
state.total=pool.length;
}
currentDeck = pool;
state.questionIndex=0;
renderQ();
updateProgress();
}
function renderQ(){
const q = currentDeck[state.questionIndex];
if(!q){ elQ.enun.textContent='¡Completado!'; elQ.ans.innerHTML=''; btnNext.disabled=true; return; }
$('#totalQ').textContent = state.total;
$('#numQ').textContent = state.questionIndex+1;
elQ.enun.textContent = q.q;
elQ.fase.textContent = 'Fase: ' + q.fase;
elQ.tipo.textContent = 'Tipo: ' + q.tipo.toUpperCase();
elQ.bloom.textContent = 'Bloom: ' + q.bloom;
elQ.hint.style.display='none'; elQ.sust.style.display='none'; elQ.hint.textContent=q.pista||'';
btnNext.disabled=true;
// Render según tipo
if(q.tipo==='opcion' || q.tipo==='vf' || q.tipo==='case'){
const opts = q.tipo==='vf' ? q.a : shuffle(q.a.slice());
elQ.ans.innerHTML='';
opts.forEach((txt,i)=>{
const div=document.createElement('div'); div.className='opt'; div.textContent=txt;
div.addEventListener('click',()=>selectOption(div, q, q.tipo==='vf' ? i : q.a.indexOf(txt)));
elQ.ans.appendChild(div);
});
} else if(q.tipo==='gap'){
elQ.ans.innerHTML = `<input id="gapInput" placeholder="Escribe aquí…" style="padding:10px;border-radius:10px;border:1px solid #2a3657;background:#0c152a;color:#e5e7eb;width:100%">
<button class="btn" id="btnGap">Responder</button>`;
$('#btnGap').addEventListener('click',()=>{
const val = ($('#gapInput').value||'').trim().toLowerCase();
const ok = (q.a[0]||'').toLowerCase();
grade(val===ok, q);
});
} else if(q.tipo==='match'){
// Demo simple: mostrar pares y pedir confirmación
const pairs = shuffle(q.pairs.slice());
elQ.ans.innerHTML = '<div class="muted" style="margin-bottom:6px">Arrastra mentalmente y confirma (demo).</div>';
pairs.forEach(p=>{ const row=document.createElement('div'); row.className='row';
row.innerHTML=`<span class="chip">${p[0]}</span><span class="chip">${p[1]}</span>`; elQ.ans.appendChild(row); });
const act=document.createElement('button'); act.className='btn'; act.textContent='Confirmar Emparejamiento';
act.addEventListener('click',()=>grade(true,q)); elQ.ans.appendChild(act);
}
}
function selectOption(el, q, idx){
if(el.classList.contains('correct')||el.classList.contains('wrong')) return;
const isOk = idx===q.ok;
grade(isOk, q);
[...el.parentNode.children].forEach(c=>c.style.pointerEvents='none');
el.classList.add(isOk?'correct':'wrong');
}
function grade(ok, q){
// Paywall freemium
if(state.freeUsed>=5){
open('#paywall'); return;
}
if(ok){
state.score += 30;
state.racha += 1;
if(q.fase==='Actuaciones') state.respondidas.act++;
if(q.fase==='Selección') state.respondidas.sel++;
if(q.fase==='Ejecución') state.respondidas.eje++;
} else {
state.racha=0;
}
$('#tuPuntaje').textContent = state.score;
updateProgress();
showSustento(q, ok);
btnNext.disabled=false;
state.freeUsed += 1;
localStorage.setItem('oece_free', String(state.freeUsed));
}
function showHint(){ const q = currentDeck[state.questionIndex]; if(!q?.pista) return; elQ.hint.textContent=q.pista; elQ.hint.style.display='block'; }
function showSustento(q, ok){ elQ.sust.style.display='block'; elQ.sust.innerHTML = `<strong>${ok?'¡Correcto!':'Respuesta registrada.'}</strong><br>${q.sustento||'—'}`; }
function nextQ(){
state.questionIndex++;
if(state.questionIndex>=state.total){ renderQ(); return; }
renderQ();
}
function updateProgress(){
const t= state.respondidas.act+state.respondidas.sel+state.respondidas.eje;
const pct = Math.min(100, Math.round((t / Math.max(1,state.total))*100));
$('#ptotal').style.width = pct+'%';
$('#p1').style.width = Math.round((state.respondidas.act/25)*100)+'%';
$('#p2').style.width = Math.round((state.respondidas.sel/22)*100)+'%';
$('#p3').style.width = Math.round((state.respondidas.eje/25)*100)+'%';
$('#p1p').textContent = `${state.respondidas.act}/25`;
$('#p2p').textContent = `${state.respondidas.sel}/22`;
$('#p3p').textContent = `${state.respondidas.eje}/25`;
$('#score').textContent = `${state.score} pts`;
$('#racha').textContent = state.racha;
// Nivel simple por score
const nivel = state.score>1500?'Avanzado':state.score>600?'Intermedio':'Novato';
$('#nivel').textContent = nivel;
// Medallas demo
let m=0; if(state.respondidas.act>=20) m++; if(state.respondidas.sel>=18) m++; if(state.respondidas.eje>=20) m++;
$('#medallas').textContent=m;
}
function shuffle(a){ for(let i=a.length-1;i>0;i--){ const j=Math.floor(Math.random()*(i+1)); [a[i],a[j]]=[a[j],a[i]] } return a }
function sample(a,n){ const c=a.slice(); return c.length<=n?c:shuffle(c).slice(0,n) }
setupDeck();
})();
</script>
</body>
</html>