๐Ÿˆ Football Play Maker
'; w.document.write(html); w.document.close(); setTimeout(function(){w.focus();w.print();},400); } function printCurrentPlaybook(){ printPlays(filteredPlays(),currentPlaybook().name); } /* ================= BACKUP / RESTORE ================= */ function downloadBackup(){ var blob=new Blob([JSON.stringify(APP,null,2)],{type:'application/json'}); var a=document.createElement('a'); a.href=URL.createObjectURL(blob); a.download='football-playmaker-backup-'+new Date().toISOString().slice(0,10)+'.json'; a.click(); } function openRestoreModal(){ var root=document.getElementById('modalRoot'); root.innerHTML=''; var parsed=null; document.getElementById('cancelRestore').onclick=function(){root.innerHTML='';}; document.getElementById('restoreFile').onchange=function(e){ var f=e.target.files[0]; if(!f)return; var reader=new FileReader(); reader.onload=function(){ try{ var data=JSON.parse(reader.result); if(!data.playbooks||!Array.isArray(data.playbooks))throw new Error('bad format'); parsed=data; var totalPlays=data.playbooks.reduce(function(s,pb){return s+(pb.plays?pb.plays.length:0);},0); document.getElementById('restorePreview').innerHTML='

This backup contains:
'+data.playbooks.length+' playbooks
'+totalPlays+' plays

'; document.getElementById('confirmRestore').disabled=false; }catch(err){ document.getElementById('restorePreview').innerHTML='

This file doesn\'t look like a valid Football Play Maker backup.

'; document.getElementById('confirmRestore').disabled=true; } }; reader.readAsText(f); }; document.getElementById('confirmRestore').onclick=function(){ if(!parsed)return; APP=migrate(parsed); if(!APP.activePlaybookId)APP.activePlaybookId=APP.playbooks[0].id; saveAppData(APP); root.innerHTML=''; renderAll(); alert('Backup restored successfully.'); }; } /* ================= SHARE ================= */ function escapeForEmbed(jsonStr){ return jsonStr.replace(/<\//g,'<\\/'); } function buildStandaloneHTML(pb){ var payload={playbookName:pb.name,plays:pb.plays,exportedAt:Date.now()}; var dataStr=escapeForEmbed(JSON.stringify(payload)); var lines=[]; lines.push('<'+'!DOCTYPE html>'); lines.push(''); lines.push(''+pb.name.replace(/</g,'')+' โ€” Shared Playbook'); lines.push(''); lines.push('

'+pb.name.replace(/

'); lines.push('
'); lines.push('
'); lines.push('
'); lines.push('
'); lines.push('
'); lines.push('