{"id":31063,"date":"2026-10-08T11:26:49","date_gmt":"2026-10-08T11:26:49","guid":{"rendered":"https:\/\/www.codemonkey.com\/?page_id=31063"},"modified":"2026-10-29T16:52:18","modified_gmt":"2026-10-29T16:52:18","slug":"logic-gate-simulator","status":"publish","type":"page","link":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/logic-gate-simulator\/","title":{"rendered":"Logic Gate Simulator"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Logic Gate Simulator<\/title>\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Poppins:wght@400;500;600;700;800\" rel=\"stylesheet\">\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=JetBrains+Mono:wght@400;600\" rel=\"stylesheet\">\n<style>\n  :root{\n    --brown-dark:#39261F; --brown:#795535; --tan:#BF8653; --yellow:#FFC62F;\n    --lime:#9BB33F; --green:#4B571A; --gray:#54595F; --blue:#79ABCB;\n    --sky:#B0D1E5; --purple:#7A6796; --pink:#C64F61; --red:#B2372A;\n    --white:#ffffff;\n    --tint:rgba(176,209,229,.22);\n    --yellow-tint:rgba(255,198,47,.16);\n  }\n  *{box-sizing:border-box}\n  body{margin:0;font-family:'Poppins',system-ui,sans-serif;color:var(--brown-dark);background:var(--white);line-height:1.55;-webkit-font-smoothing:antialiased}\n  h1,h2,h3{font-family:'Poppins',sans-serif;margin:0}\n\n  \/* ---------- Hero ---------- *\/\n  .hero{position:relative;overflow:hidden;color:var(--white);text-align:center;padding:52px 16px 110px}\n  .eyebrow{position:relative;display:inline-block;font-size:12px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;background:rgba(255,255,255,.14);padding:6px 14px;border-radius:999px;margin-bottom:14px}\n  .hero h1{position:relative;font-weight:800;text-transform:uppercase;letter-spacing:.01em;font-size:clamp(30px,5.4vw,52px);line-height:1.08;color:var(--yellow)}\n  .hero p{position:relative;max-width:640px;margin:12px auto 0;font-size:16px;opacity:.95}\n  .wave{position:absolute;left:0;right:0;bottom:-1px;width:100%;height:60px;display:block}\n  .eyebrow:focus-visible{outline:3px solid var(--purple);outline-offset:2px}\n\n  .hero{background-color:var(--green);background-image:radial-gradient(ellipse 460px 150px at 50% 50%,#4B571A 55%,rgba(75,87,26,0) 100%),url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='280' height='280' viewBox='0 0 280 280'%3E%3Cdefs%3E%3Cg id='b'%3E%3Cpath d='M262 572 C330 605 400 618 470 616 C560 612 650 560 712 500 C750 465 785 430 810 402 L843 406 C853 462 851 560 791 630 C731 700 621 748 506 748 C401 748 311 680 258 592 Z' fill='%23E6B94A'\/%3E %3Cpath d='M268 578 C340 612 410 622 470 620 C565 616 655 562 712 505 C750 467 790 428 812 405 C790 470 730 560 640 610 C590 638 540 650 480 652 C400 652 322 622 266 592 Z' fill='%23CDA144'\/%3E %3Cpath d='M262 572 C330 605 400 618 470 616 C560 612 650 560 712 500 C750 465 785 430 810 402 L843 406 C853 462 851 560 791 630 C731 700 621 748 506 748 C401 748 311 680 258 592 Z' fill='none' stroke='%23231F20' stroke-width='10' stroke-linejoin='round'\/%3E %3Cg fill='none' stroke='%23231F20' stroke-width='10' stroke-linecap='butt'%3E %3Cpath d='M302 618 C360 655 420 690 505 692 C620 694 730 610 812 518'\/%3E %3Cpath d='M562 648 C660 610 760 530 815 418'\/%3E %3Cpath d='M780 516 C795 485 808 452 818 420'\/%3E %3C\/g%3E %3Cpath d='M808 405 L826 340 L848 345 L843 408 C835 420 818 422 808 405 Z' fill='%23644E37' stroke='%23231F20' stroke-width='10' stroke-linejoin='round'\/%3E %3Cpath d='M249 555 C246 570 251 584 259 594 C269 588 277 580 282 572 Z' fill='%23644E37' stroke='%23231F20' stroke-width='10' stroke-linejoin='round'\/%3E%3C\/g%3E%3C\/defs%3E%3Cg opacity='.85'%3E%3Cuse href='%23b' transform='translate(55 60) rotate(-15) scale(0.11) translate(-540 -545)'\/%3E%3Cuse href='%23b' transform='translate(185 150) rotate(25) scale(0.09) translate(-540 -545)'\/%3E%3Cuse href='%23b' transform='translate(80 215) rotate(160) scale(0.1) translate(-540 -545)'\/%3E%3Cuse href='%23b' transform='translate(230 40) rotate(-50) scale(0.08) translate(-540 -545)'\/%3E%3C\/g%3E%3C\/svg%3E\");background-size:auto,280px;background-position:center,0 0;background-repeat:no-repeat,repeat}\n  .hero .bb{position:absolute;pointer-events:none}\n  .hero .bb svg{width:100%;height:auto;display:block}\n  .hero .bb.l{width:160px;left:max(16px,calc(50% - 630px));top:92px;transform:rotate(-12deg)}\n  .hero .bb.r{width:125px;right:max(16px,calc(50% - 610px));top:28px;transform:scaleX(-1) rotate(-18deg)}\n  @media (max-width:1180px){.hero .bb.l{width:96px;top:150px}.hero .bb.r{width:80px;top:14px}}\n  @media (max-width:640px){.hero .bb.l{width:58px;left:6px;top:36px}.hero .bb.r{width:50px;right:6px;top:8px}}\n  .eyebrow{text-decoration:none;color:var(--white);transition:background .15s}\n  .eyebrow:hover{background:rgba(255,255,255,.24)}\n\n\n  .lvl{flex:none}\n  .lvl .label{text-align:right}\n  .level{display:inline-flex;background:var(--tint);border-radius:999px;padding:4px;gap:4px}\n  .level button{font:700 14px 'Poppins',sans-serif;border:none;background:transparent;color:var(--gray);border-radius:999px;padding:8px 18px;cursor:pointer}\n  .level button[aria-pressed=\"true\"]{background:var(--brown-dark);color:var(--yellow)}\n  .level button:focus-visible{outline:3px solid var(--purple);outline-offset:2px}\n  .level-note{font-size:12px;color:var(--gray);margin-top:6px;text-align:right}\n  @media (max-width:640px){.lvl{order:-1;width:100%}.lvl .label,.lvl .level-note{text-align:left}}\n  body.easy .adv-only{display:none !important}\n  body.adv .easy-only{display:none !important}\n\n\n  \/* ---------- Layout ---------- *\/\n  .wrap{max-width:1240px;margin:-64px auto 48px;padding:0 16px;position:relative}\n  .card{background:var(--white);border-radius:24px;box-shadow:0 12px 34px rgba(57,38,31,.13);padding:24px}\n  .topbar{display:flex;flex-wrap:wrap;gap:14px 20px;align-items:center}\n  .topbar .grow{flex:1}\n  .headrow{display:flex;flex-wrap:wrap;gap:14px 20px;align-items:flex-start;justify-content:space-between;margin-bottom:16px}\n  .howto{margin-top:14px;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}\n  @media (max-width:1100px){.howto{grid-template-columns:repeat(2,minmax(0,1fr))}}\n  @media (max-width:520px){.howto{grid-template-columns:1fr}}\n  .howto h3{grid-column:1 \/ -1;font-weight:700;font-size:15px;text-transform:uppercase;letter-spacing:.06em;margin:4px 0 0}\n  .howto div{background:var(--tint);border-radius:14px;padding:10px 12px;font-size:13px;font-weight:500;line-height:1.45}\n  .howto div b{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:800;margin-bottom:3px}\n  .howto div b i{font-style:normal;flex:none;width:22px;height:22px;border-radius:50%;background:var(--yellow);display:flex;align-items:center;justify-content:center;font-size:12px}\n  .ttcap{font-size:12.5px;color:var(--gray);margin:-4px 0 8px}\n  .expr.alg{background:var(--white);color:var(--brown-dark);border:2px solid var(--brown-dark)}\n  .expr.alg b{color:var(--brown)}\n  .gcard .nota{font-family:'JetBrains Mono',monospace;font-weight:600;font-size:14px;background:var(--tint);border-radius:999px;display:inline-block;padding:2px 12px;margin-bottom:8px}\n  .cheat{width:100%;border-collapse:collapse;font-size:14px}\n  .cheat td{padding:8px 4px;border-bottom:1px solid var(--sky)}\n  .cheat td:first-child{font-family:'JetBrains Mono',monospace;font-weight:700;white-space:nowrap}\n  .cheat tr:last-child td{border-bottom:none}\n  .work{display:grid;grid-template-columns:150px minmax(0,1fr) 300px;gap:20px;margin-top:20px;align-items:start}\n  @media (max-width:1100px){.work{grid-template-columns:130px minmax(0,1fr)}.panel{grid-column:1 \/ -1}}\n  @media (max-width:700px){.work{grid-template-columns:1fr}}\n\n  .label{display:block;font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.07em;color:var(--gray);margin-bottom:8px}\n\n  \/* ---------- Chips \/ buttons \/ select ---------- *\/\n  .chips{display:flex;flex-wrap:wrap;gap:8px}\n  .chip{font:600 14px 'Poppins',sans-serif;color:var(--brown-dark);background:var(--white);border:2px solid var(--sky);border-radius:999px;padding:8px 16px;cursor:pointer;transition:background .15s,border-color .15s,transform .08s}\n  .chip:hover{border-color:var(--blue)}\n  .chip[aria-pressed=\"true\"]{background:var(--yellow);border-color:var(--yellow);box-shadow:0 3px 0 var(--tan)}\n  .chip:active{transform:translateY(2px)}\n  select{font:600 14px 'Poppins',sans-serif;color:var(--brown-dark);background:var(--white) url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%2339261F' stroke-width='2' fill='none' stroke-linecap='round'\/%3E%3C\/svg%3E\") no-repeat right 16px center;border:2px solid var(--sky);border-radius:999px;padding:9px 40px 9px 16px;appearance:none;-webkit-appearance:none;cursor:pointer;max-width:100%}\n  .btn{font:700 14px 'Poppins',sans-serif;border:none;border-radius:999px;padding:11px 20px;cursor:pointer;background:var(--yellow);color:var(--brown-dark);box-shadow:0 4px 0 var(--tan);display:inline-flex;align-items:center;justify-content:center;gap:8px;transition:transform .08s,box-shadow .08s}\n  .btn:active{transform:translateY(3px);box-shadow:0 1px 0 var(--tan)}\n  .btn.secondary{background:var(--white);border:2px solid var(--sky);box-shadow:0 4px 0 var(--sky);padding:9px 16px}\n  .btn.secondary:active{box-shadow:0 1px 0 var(--sky)}\n  .btn:disabled{opacity:.4;cursor:not-allowed;transform:none}\n  .btn svg{width:16px;height:16px;fill:currentColor}\n  select:focus-visible,.chip:focus-visible,.btn:focus-visible,.tool:focus-visible{outline:3px solid var(--purple);outline-offset:2px}\n\n  \/* ---------- Toolbox ---------- *\/\n  .toolbox{display:flex;flex-direction:column;gap:8px}\n  .tool{display:flex;align-items:center;gap:8px;width:100%;font:700 13px 'Poppins',sans-serif;color:var(--brown-dark);background:var(--white);border:2px solid var(--sky);border-radius:14px;padding:6px 10px;cursor:grab;touch-action:none;user-select:none;transition:border-color .15s,transform .08s}\n  .tool:hover{border-color:var(--yellow)}\n  .tool:active{cursor:grabbing;transform:scale(.98)}\n  .tool svg{width:44px;height:32px;flex:none}\n  .tool.io{background:var(--yellow-tint);border-color:transparent}\n  .toolhint{font-size:12px;color:var(--gray);margin-top:4px}\n  @media (max-width:700px){.toolbox{flex-direction:row;flex-wrap:wrap}.tool{width:auto}.toolhint{display:none}}\n\n  \/* ---------- Board ---------- *\/\n  .board{width:100%;height:auto;display:block;background:var(--tint);border-radius:20px;touch-action:none;user-select:none;-webkit-user-select:none}\n  .board text{font-family:'Poppins',sans-serif}\n  .gb{fill:var(--white);stroke:var(--brown-dark);stroke-width:3;stroke-linejoin:round}\n  .gx{fill:none;stroke:var(--brown-dark);stroke-width:3;stroke-linecap:round}\n  .stub{stroke:var(--brown-dark);stroke-width:3}\n  .stub.on{stroke:var(--tan);stroke-width:4}\n  .gname{font-size:11px;font-weight:700;fill:var(--gray);text-anchor:middle;letter-spacing:.06em}\n  .comp{cursor:move}\n  .selbox{fill:none;stroke:var(--purple);stroke-width:2;stroke-dasharray:6 5}\n  .sw{fill:var(--white);stroke:var(--brown-dark);stroke-width:3;cursor:pointer}\n  .sw.on{fill:var(--yellow)}\n  .swv{font-size:22px;font-weight:800;text-anchor:middle;fill:var(--brown-dark);pointer-events:none}\n  .lbl{font-size:14px;font-weight:800;text-anchor:middle;fill:var(--brown-dark)}\n  .lamp{fill:var(--white);stroke:var(--brown-dark);stroke-width:3}\n  .lamp.on{fill:var(--yellow)}\n  .glow{fill:var(--yellow);opacity:.35}\n  .lampv{font-size:16px;font-weight:800;text-anchor:middle;fill:var(--brown-dark);pointer-events:none}\n  .port{fill:var(--white);stroke:var(--brown-dark);stroke-width:2.5;pointer-events:none}\n  .port.on{fill:var(--yellow)}\n  .port.target{stroke:var(--purple);stroke-width:4}\n  .port.pending{fill:var(--purple);stroke:var(--purple)}\n  .hit{fill:transparent;cursor:crosshair}\n  .w-off{fill:none;stroke:var(--gray);stroke-opacity:.5;stroke-width:4;stroke-linecap:round}\n  .w-under{fill:none;stroke:var(--tan);stroke-width:8;stroke-linecap:round}\n  .w-on{fill:none;stroke:var(--yellow);stroke-width:4;stroke-linecap:round}\n  .w-sel{stroke:var(--pink);stroke-opacity:1}\n  .w-hit{fill:none;stroke:transparent;stroke-width:16;cursor:pointer}\n  .temp{fill:none;stroke:var(--purple);stroke-width:3;stroke-dasharray:8 6;pointer-events:none}\n  .empty{font-size:18px;font-weight:600;fill:var(--gray);text-anchor:middle;opacity:.8}\n\n  .status{margin-top:14px;border:2px dashed var(--sky);border-radius:16px;padding:12px 16px;font-weight:500;font-size:14px;display:flex;gap:12px;align-items:flex-start;min-height:50px}\n  .status .dot{flex:none;width:12px;height:12px;border-radius:50%;background:var(--yellow);margin-top:5px;box-shadow:0 0 0 4px var(--yellow-tint)}\n\n  \/* ---------- Panel ---------- *\/\n  .panel h3{font-weight:700;font-size:15px;text-transform:uppercase;letter-spacing:.06em;margin-bottom:10px}\n  .goal{background:var(--yellow-tint);border-radius:18px;padding:16px;margin-bottom:18px;border-left:6px solid var(--yellow)}\n  .goal h4{margin:0 0 4px;font-size:17px;font-weight:800;text-transform:uppercase}\n  .goal p{margin:0 0 8px;font-size:14px}\n  .goal .meta{font-size:12px;font-weight:600;color:var(--brown)}\n  .goal .hint{margin-top:8px;font-size:13px;background:var(--white);border-radius:12px;padding:8px 12px;display:none}\n  .goal .hint.show{display:block}\n  .linkbtn{background:none;border:none;padding:0;font:700 13px 'Poppins',sans-serif;color:var(--purple);cursor:pointer;text-decoration:underline}\n  .solved{display:none;margin-top:10px;background:var(--lime);color:var(--white);border-radius:12px;padding:10px 12px;font-weight:700;font-size:14px}\n  .solved.show{display:block}\n  .tt-wrap{max-height:340px;overflow:auto;border-radius:16px;border:2px solid var(--tint)}\n  table.tt{width:100%;border-collapse:collapse;font-family:'JetBrains Mono',ui-monospace,monospace;font-size:13px;text-align:center}\n  .tt th{position:sticky;top:0;background:var(--brown-dark);color:var(--white);font-family:'Poppins',sans-serif;font-weight:700;font-size:12px;padding:8px 6px}\n  .tt th.o{color:var(--yellow)}\n  .tt th.g{color:var(--sky)}\n  .tt td{padding:6px;border-bottom:1px solid var(--tint)}\n  .tt td.sep{border-left:2px solid var(--sky)}\n  .tt tr.cur td{background:var(--yellow-tint);font-weight:700}\n  .tt .one{display:inline-block;min-width:24px;border-radius:999px;background:var(--yellow);font-weight:700}\n  .tt .ok{color:var(--green);font-weight:800}\n  .tt .no{color:var(--red);font-weight:800}\n  .tt-empty{font-size:14px;color:var(--gray);background:var(--tint);border-radius:16px;padding:14px}\n  .exprs{margin-top:16px;display:flex;flex-direction:column;gap:8px}\n  .expr{background:var(--brown-dark);color:rgba(255,255,255,.85);border-radius:14px;padding:10px 14px;font-family:'JetBrains Mono',ui-monospace,monospace;font-size:12.5px;overflow-x:auto;white-space:nowrap}\n  .expr b{color:var(--yellow)}\n  .stats{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:16px}\n  .stat{background:var(--tint);border-radius:16px;padding:10px 8px;text-align:center}\n  .stat b{display:block;font-weight:800;font-size:22px;line-height:1.1}\n  .stat small{font-size:10.5px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--gray)}\n\n  \/* ---------- Info ---------- *\/\n  .section-title{font-weight:800;font-size:clamp(22px,3vw,30px);text-transform:uppercase;margin:36px 0 16px;text-align:center}\n  .section-title em{font-style:normal;color:var(--tan)}\n  .gates{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:18px}\n  @media (max-width:420px){.gates{gap:10px}.gcard{padding:12px}.gcard p{font-size:12.5px}}\n  @media (min-width:1060px){.gates{grid-template-columns:repeat(7,minmax(0,1fr));gap:14px}.gcard{padding:14px 10px}.mini th,.mini td{padding:2px 6px}}\n  .gcard{background:var(--white);border-radius:20px;box-shadow:0 8px 24px rgba(57,38,31,.10);padding:18px;text-align:center}\n  .gcard svg{width:110px;height:76px}\n  .gcard h3{font-size:20px;font-weight:800;margin:4px 0 2px}\n  .gcard p{font-size:13.5px;margin:0 0 10px;min-height:42px}\n  .mini{margin:0 auto;border-collapse:collapse;font-family:'JetBrains Mono',monospace;font-size:12.5px}\n  .mini th{font-family:'Poppins',sans-serif;font-size:11px;color:var(--gray);padding:2px 10px}\n  .mini td{padding:2px 10px}\n  .mini td.out{font-weight:700}\n  .mini td.out.on{background:var(--yellow);border-radius:6px}\n  .info{display:grid;grid-template-columns:1.3fr 1fr;gap:24px;margin-top:28px}\n  @media (max-width:800px){.info{grid-template-columns:1fr}}\n  .info h2{font-weight:800;font-size:clamp(20px,2.6vw,26px);text-transform:uppercase;margin-bottom:10px}\n  .bullets{list-style:none;padding:0;margin:10px 0 0}\n  .bullets li{padding-left:28px;position:relative;margin-bottom:8px;font-weight:500}\n  .bullets li::before{content:\"\";position:absolute;left:0;top:7px;width:14px;height:14px;border-radius:50%;background:var(--yellow);box-shadow:0 0 0 4px var(--yellow-tint)}\n  .tip{background:var(--yellow-tint);border-radius:16px;padding:14px 18px;border-left:6px solid var(--yellow);margin-top:12px}\n  .tip strong{display:block;font-weight:700;text-transform:uppercase;font-size:12px;letter-spacing:.08em;color:var(--brown);margin-bottom:2px}\n  kbd{font-family:'JetBrains Mono',monospace;font-size:12px;background:var(--tint);border-radius:6px;padding:1px 6px}\n  footer{text-align:center;font-size:13px;color:var(--gray);padding:0 16px 32px}\n<\/style>\n<\/head>\n<body class=\"easy\">\n\n<header class=\"hero\">\n  <div class=\"bb l\"><svg viewBox=\"215 325 650 470\" aria-hidden=\"true\"><path d=\"M225 640 C240 628 255 650 265 648 C330 645 410 700 520 718 C610 728 690 705 725 688 C690 740 610 782 505 778 C400 774 300 745 262 705 C242 685 214 662 225 640 Z\" fill=\"#000\" fill-opacity=\".2\"\/><path d=\"M262 572 C330 605 400 618 470 616 C560 612 650 560 712 500 C750 465 785 430 810 402 L843 406 C853 462 851 560 791 630 C731 700 621 748 506 748 C401 748 311 680 258 592 Z\" fill=\"#E6B94A\"\/> <path d=\"M268 578 C340 612 410 622 470 620 C565 616 655 562 712 505 C750 467 790 428 812 405 C790 470 730 560 640 610 C590 638 540 650 480 652 C400 652 322 622 266 592 Z\" fill=\"#CDA144\"\/> <path d=\"M262 572 C330 605 400 618 470 616 C560 612 650 560 712 500 C750 465 785 430 810 402 L843 406 C853 462 851 560 791 630 C731 700 621 748 506 748 C401 748 311 680 258 592 Z\" fill=\"none\" stroke=\"#231F20\" stroke-width=\"10\" stroke-linejoin=\"round\"\/> <g fill=\"none\" stroke=\"#231F20\" stroke-width=\"10\" stroke-linecap=\"butt\"> <path d=\"M302 618 C360 655 420 690 505 692 C620 694 730 610 812 518\"\/> <path d=\"M562 648 C660 610 760 530 815 418\"\/> <path d=\"M780 516 C795 485 808 452 818 420\"\/> <\/g> <path d=\"M808 405 L826 340 L848 345 L843 408 C835 420 818 422 808 405 Z\" fill=\"#644E37\" stroke=\"#231F20\" stroke-width=\"10\" stroke-linejoin=\"round\"\/> <path d=\"M249 555 C246 570 251 584 259 594 C269 588 277 580 282 572 Z\" fill=\"#644E37\" stroke=\"#231F20\" stroke-width=\"10\" stroke-linejoin=\"round\"\/><\/svg><\/div><div class=\"bb r\"><svg viewBox=\"215 325 650 470\" aria-hidden=\"true\"><path d=\"M225 640 C240 628 255 650 265 648 C330 645 410 700 520 718 C610 728 690 705 725 688 C690 740 610 782 505 778 C400 774 300 745 262 705 C242 685 214 662 225 640 Z\" fill=\"#000\" fill-opacity=\".2\"\/><path d=\"M262 572 C330 605 400 618 470 616 C560 612 650 560 712 500 C750 465 785 430 810 402 L843 406 C853 462 851 560 791 630 C731 700 621 748 506 748 C401 748 311 680 258 592 Z\" fill=\"#E6B94A\"\/> <path d=\"M268 578 C340 612 410 622 470 620 C565 616 655 562 712 505 C750 467 790 428 812 405 C790 470 730 560 640 610 C590 638 540 650 480 652 C400 652 322 622 266 592 Z\" fill=\"#CDA144\"\/> <path d=\"M262 572 C330 605 400 618 470 616 C560 612 650 560 712 500 C750 465 785 430 810 402 L843 406 C853 462 851 560 791 630 C731 700 621 748 506 748 C401 748 311 680 258 592 Z\" fill=\"none\" stroke=\"#231F20\" stroke-width=\"10\" stroke-linejoin=\"round\"\/> <g fill=\"none\" stroke=\"#231F20\" stroke-width=\"10\" stroke-linecap=\"butt\"> <path d=\"M302 618 C360 655 420 690 505 692 C620 694 730 610 812 518\"\/> <path d=\"M562 648 C660 610 760 530 815 418\"\/> <path d=\"M780 516 C795 485 808 452 818 420\"\/> <\/g> <path d=\"M808 405 L826 340 L848 345 L843 408 C835 420 818 422 808 405 Z\" fill=\"#644E37\" stroke=\"#231F20\" stroke-width=\"10\" stroke-linejoin=\"round\"\/> <path d=\"M249 555 C246 570 251 584 259 594 C269 588 277 580 282 572 Z\" fill=\"#644E37\" stroke=\"#231F20\" stroke-width=\"10\" stroke-linejoin=\"round\"\/><\/svg><\/div>\n  <a class=\"eyebrow\" href=\"https:\/\/www.codemonkey.com\/interactive-cs-tools\" target=\"_top\">Interactive CS Tools<\/a>\n  <h1>Logic Gate Simulator<\/h1>\n  <p>Drag gates onto the board, wire them up and flip the switches. The truth table and Boolean expression update as you build.<\/p>\n  <svg class=\"wave\" viewBox=\"0 0 1440 60\" preserveAspectRatio=\"none\" aria-hidden=\"true\"><path d=\"M0,32 C240,64 480,0 720,24 C960,48 1200,8 1440,30 L1440,60 L0,60 Z\" fill=\"#ffffff\"\/><\/svg>\n<\/header>\n\n<main class=\"wrap\">\n  <section class=\"card\" aria-label=\"Logic gate workspace\">\n    <div class=\"headrow\">\n      <div>\n        <span class=\"label\">Mode<\/span>\n        <div class=\"chips\" role=\"group\" aria-label=\"Mode\">\n          <button class=\"chip\" type=\"button\" id=\"modeFree\" aria-pressed=\"true\">Free build<\/button>\n          <button class=\"chip\" type=\"button\" id=\"modeChal\" aria-pressed=\"false\">Challenges<\/button>\n        <\/div>\n      <\/div>\n      <div class=\"lvl\"><span class=\"label\">Level<\/span><div class=\"level\" role=\"group\" aria-label=\"Level\"><button type=\"button\" data-level=\"easy\" aria-pressed=\"true\">Easy<\/button><button type=\"button\" data-level=\"adv\" aria-pressed=\"false\">Advanced<\/button><\/div><div class=\"level-note\" id=\"levelNote\" data-easy=\"Simple gates and plain words\" data-adv=\"All 7 gates, Boolean algebra and harder challenges\"><\/div><\/div>\n    <\/div>\n    <div class=\"topbar\">\n      <select id=\"exampleSel\" aria-label=\"Load an example circuit\">\n        <option value=\"\">Load an example&#8230;<\/option>\n        <option value=\"half\">Half adder<\/option>\n        <option value=\"full\">Full adder<\/option>\n        <option value=\"mux\">2-to-1 multiplexer<\/option>\n      <\/select>\n      <select id=\"chalSel\" aria-label=\"Choose a challenge\" hidden><\/select>\n      <span class=\"grow\"><\/span>\n      <button class=\"btn secondary\" type=\"button\" id=\"delBtn\" disabled>\n        <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M9 3h6l1 2h4v2H4V5h4l1-2zm-3 6h12l-1 12H7L6 9z\"\/><\/svg>\n        Delete selected\n      <\/button>\n      <button class=\"btn secondary\" type=\"button\" id=\"clearBtn\">\n        <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M12 4a8 8 0 1 1-7.4 5H7a6 6 0 1 0 1.8-3.2L11 8H4V1l2.6 2.6A8 8 0 0 1 12 4z\"\/><\/svg>\n        <span id=\"clearTxt\">Clear board<\/span>\n      <\/button>\n    <\/div>\n\n    <div class=\"work\">\n      <div>\n        <span class=\"label\">Toolbox<\/span>\n        <div class=\"toolbox\" id=\"toolbox\"><\/div>\n        <div class=\"toolhint\">Drag onto the board, or click to add.<\/div>\n      <\/div>\n\n      <div>\n        <svg id=\"board\" class=\"board\" viewBox=\"0 0 960 520\" role=\"application\" aria-label=\"Circuit board\">\n          <defs>\n            <pattern id=\"dots\" width=\"24\" height=\"24\" patternUnits=\"userSpaceOnUse\"><circle cx=\"2\" cy=\"2\" r=\"1.6\" fill=\"#79ABCB\" opacity=\".45\"\/><\/pattern>\n          <\/defs>\n          <rect width=\"960\" height=\"520\" fill=\"url(#dots)\"\/>\n          <g id=\"wiresLayer\"><\/g>\n          <g id=\"compsLayer\"><\/g>\n          <path id=\"temp\" class=\"temp\" d=\"\"\/>\n        <\/svg>\n        <div class=\"status\" aria-live=\"polite\"><span class=\"dot\"><\/span><span id=\"status\"><\/span><\/div>\n        <div class=\"howto\">\n          <h3>How to use it<\/h3>\n          <div><b><i>1<\/i>Add parts<\/b>Drag switches, lamps and gates from the toolbox, or click them to add.<\/div>\n          <div><b><i>2<\/i>Connect<\/b>Drag from an output dot (right side) to an input dot (left side). On a tablet, tap one dot, then the other.<\/div>\n          <div><b><i>3<\/i>Test<\/b>Click a switch to flip it between 0 and 1. Yellow wires carry a 1.<\/div>\n          <div><b><i>4<\/i>Fix mistakes<\/b>Click a gate or wire, then press <kbd>Delete<\/kbd>. Press <kbd>Esc<\/kbd> to cancel a wire.<\/div>\n        <\/div>\n      <\/div>\n\n      <aside class=\"panel\">\n        <div class=\"goal\" id=\"goal\" hidden>\n          <h4 id=\"goalTitle\"><\/h4>\n          <p id=\"goalText\"><\/p>\n          <div class=\"meta\" id=\"goalMeta\"><\/div>\n          <button class=\"linkbtn\" type=\"button\" id=\"hintBtn\">Show a hint<\/button>\n          <div class=\"hint\" id=\"hint\"><\/div>\n          <div class=\"solved\" id=\"solved\"><\/div>\n        <\/div>\n        <h3>Truth table<\/h3>\n        <p class=\"ttcap easy-only\">1 means on, 0 means off. Each row tries a different set of switches.<\/p>\n        <p class=\"ttcap adv-only\">n inputs give 2<sup>n<\/sup> rows. Each row is one input combination.<\/p>\n        <div id=\"tt\"><\/div>\n        <div class=\"exprs\" id=\"exprs\"><\/div>\n        <div class=\"stats\">\n          <div class=\"stat\"><b id=\"sGates\">0<\/b><small>Gates<\/small><\/div>\n          <div class=\"stat\"><b id=\"sWires\">0<\/b><small>Wires<\/small><\/div>\n          <div class=\"stat\"><b id=\"sRows\">0<\/b><small>Rows<\/small><\/div>\n        <\/div>\n      <\/aside>\n    <\/div>\n  <\/section>\n\n  <h2 class=\"section-title\">Meet the <em>gates<\/em><\/h2>\n  <section class=\"gates\" id=\"gateCards\"><\/section>\n\n  <section class=\"info\">\n    <div class=\"card easy-only\">\n      <h2>Where are logic gates?<\/h2>\n      <ul class=\"bullets\">\n        <li>Inside every computer, phone and game console. A modern chip has billions of them!<\/li>\n        <li>A gate is a tiny switch that decides &#8220;on&#8221; or &#8220;off&#8221; based on its inputs.<\/li>\n        <li>Joining gates together lets computers add numbers, compare things and make decisions.<\/li>\n      <\/ul>\n    <\/div>\n    <div class=\"card adv-only\">\n      <h2>Boolean algebra<\/h2>\n      <table class=\"cheat\">\n        <tr><td>A \u00b7 B<\/td><td>AND: 1 only if both are 1<\/td><\/tr>\n        <tr><td>A + B<\/td><td>OR: 1 if at least one is 1<\/td><\/tr>\n        <tr><td>\u00acA<\/td><td>NOT: flips 0 and 1<\/td><\/tr>\n        <tr><td>A \u2295 B<\/td><td>XOR: 1 if the inputs differ<\/td><\/tr>\n        <tr><td>\u00ac(A \u00b7 B) = \u00acA + \u00acB<\/td><td>De Morgan&#8217;s law, the reason NAND can build OR<\/td><\/tr>\n      <\/table>\n    <\/div>\n    <div class=\"card\">\n      <h2>Try this in class<\/h2>\n      <div class=\"tip\"><strong>Two roads, one answer<\/strong>Build XOR once with an XOR gate and once with AND, OR and NOT. Compare the truth tables. Are they really the same circuit?<\/div>\n      <div class=\"tip easy-only\"><strong>Make it real<\/strong>Design a circuit for a game: the door opens (lamp X) only when you have the key (A) and you are next to the door (B). Which gate do you need?<\/div>\n      <div class=\"tip adv-only\"><strong>The universal gate<\/strong>Every other gate can be built from NAND alone. Work through the NAND challenges and see why chip makers love it.<\/div>\n    <\/div>\n  <\/section>\n<\/main>\n\n<footer>Keyboard: <b>Delete<\/b> remove selected \u00b7 <b>Esc<\/b> cancel connection<\/footer>\n\n<script>\n\nconst LEVEL=(function(){\n  let cur='easy'; const cbs=[];\n  try{\n    const q=new URLSearchParams(location.search).get('level');\n    if(q==='advanced'||q==='adv') cur='adv';\n    else if(q==='easy') cur='easy';\n    else { const s=localStorage.getItem('cm-cs-level'); if(s==='adv'||s==='easy') cur=s; }\n  }catch(e){}\n  function paint(){\n    document.querySelectorAll('.level button').forEach(b=>b.setAttribute('aria-pressed',b.dataset.level===cur));\n    const n=document.getElementById('levelNote'); if(n) n.textContent=n.getAttribute('data-'+cur)||'';\n    document.body.classList.toggle('adv',cur==='adv'); document.body.classList.toggle('easy',cur!=='adv');\n  }\n  function set(l){ cur=l; try{ localStorage.setItem('cm-cs-level',l); }catch(e){} paint(); cbs.forEach(f=>f(l)); }\n  document.querySelectorAll('.level button').forEach(b=>b.addEventListener('click',()=>{ if(b.dataset.level!==cur) set(b.dataset.level); }));\n  paint();\n  return {get:()=>cur, on:f=>cbs.push(f), set:set};\n})();\n\nconst W=960, H=520;\nconst TYPES={\n  INPUT:{ins:[], out:[72,22], w:72, h:44},\n  OUTPUT:{ins:[[0,22]], out:null, w:64, h:44},\n  NOT:{ins:[[0,30]], out:[80,30], w:80, h:60, fn:a=>1-a},\n  AND:{ins:[[0,18],[0,42]], out:[80,30], w:80, h:60, fn:(a,b)=>a*b},\n  OR:{ins:[[0,18],[0,42]], out:[80,30], w:80, h:60, fn:(a,b)=>Math.max(a,b)},\n  NAND:{ins:[[0,18],[0,42]], out:[80,30], w:80, h:60, fn:(a,b)=>1-a*b},\n  NOR:{ins:[[0,18],[0,42]], out:[80,30], w:80, h:60, fn:(a,b)=>1-Math.max(a,b)},\n  XOR:{ins:[[0,18],[0,42]], out:[80,30], w:80, h:60, fn:(a,b)=>a===b?0:1},\n  XNOR:{ins:[[0,18],[0,42]], out:[80,30], w:80, h:60, fn:(a,b)=>a===b?1:0}\n};\nconst GATES=['AND','OR','NOT','NAND','NOR','XOR','XNOR'];\nconst GATES_EASY=['AND','OR','NOT','XOR'];\nconst NOTA={AND:'A \\u00b7 B',OR:'A + B',NOT:'\\u00acA',NAND:'\\u00ac(A \\u00b7 B)',NOR:'\\u00ac(A + B)',XOR:'A \\u2295 B',XNOR:'\\u00ac(A \\u2295 B)'};\nconst IN_LABELS=['A','B','C','D','E'], OUT_LABELS=['X','Y','Z','W','V'];\nconst DEFAULT_TIP='Drag gates onto the board, then drag from one dot to another to connect them. Click a switch to flip it.';\n\nconst GATE_INFO={\n  AND:'On only when both inputs are on.',\n  OR:'On when at least one input is on.',\n  NOT:'Flips the input: on becomes off, off becomes on.',\n  NAND:'NOT AND: off only when both inputs are on.',\n  NOR:'NOT OR: on only when both inputs are off.',\n  XOR:'On when the two inputs are different.',\n  XNOR:'On when the two inputs are the same.'\n};\n\nconst CHALLENGES_EXTRA=[\n  {lv:'adv', title:'XOR from NAND', text:'Make X turn on when A and B are different, using only NAND gates.', allowed:['NAND'], inputs:['A','B'], outputs:['X'], best:4,\n   target:v=>({X:v.A===v.B?0:1}), hint:'Start with N = A NAND B. Then NAND A with N, and NAND B with N. One more NAND combines those two.'},\n  {lv:'adv', title:'Full adder', text:'Add three bits: A + B + Cin. Sum is the ones digit and Cout is the twos digit.', allowed:GATES, inputs:['A','B','Cin'], outputs:['Sum','Cout'], best:5,\n   target:v=>({Sum:(v.A+v.B+v.Cin)%2, Cout:(v.A+v.B+v.Cin)>=2?1:0}), hint:'Build a half adder for A and B, then a second half adder that adds Cin to the first sum. Either carry makes Cout.'}\n];\nconst CHALLENGES=[\n  {lv:'both', title:'NOT from NAND', text:'Make lamp X the opposite of switch A, using only NAND gates.', allowed:['NAND'], inputs:['A'], outputs:['X'], best:1,\n   target:v=>({X:1-v.A}), hint:'A NAND gate with both inputs connected to the same switch behaves like NOT.'},\n  {lv:'adv', title:'AND from NAND', text:'Make X turn on only when A and B are both on. Only NAND gates allowed!', allowed:['NAND'], inputs:['A','B'], outputs:['X'], best:2,\n   target:v=>({X:v.A*v.B}), hint:'NAND is AND followed by NOT. How could you undo that extra NOT?'},\n  {lv:'adv', title:'OR from NAND', text:'Make X turn on when A or B (or both) are on, using only NAND gates.', allowed:['NAND'], inputs:['A','B'], outputs:['X'], best:3,\n   target:v=>({X:Math.max(v.A,v.B)}), hint:'Flip each input first (use NAND as NOT), then NAND the two flipped signals together.'},\n  {lv:'adv', title:'Build your own XOR', text:'Make X turn on when A and B are different, using only AND, OR and NOT.', allowed:['AND','OR','NOT'], inputs:['A','B'], outputs:['X'], best:4,\n   target:v=>({X:v.A===v.B?0:1}), hint:'XOR means \"A OR B, but not both\". Build A OR B, build NOT (A AND B), then combine them with AND.'},\n  {lv:'both', title:'Half adder', text:'Add two bits! Sum shows the ones digit and Carry shows the twos digit of A + B.', allowed:GATES, inputs:['A','B'], outputs:['Sum','Carry'], best:2,\n   target:v=>({Sum:v.A===v.B?0:1, Carry:v.A*v.B}), hint:'Sum is on when exactly one input is on. Carry is on only when both are on.'},\n  {lv:'both', title:'Majority vote', text:'Three friends vote with switches A, B and C. Lamp X turns on when at least two vote yes.', allowed:GATES, inputs:['A','B','C'], outputs:['X'], best:5,\n   target:v=>({X:(v.A+v.B+v.C)>=2?1:0}), hint:'Check each pair: (A AND B), (A AND C), (B AND C). If any pair is on, the lamp should be on.'},\n  {lv:'both', title:'Smart alarm', text:'The alarm X rings when the system is armed (A) and either the door (B) or the window (C) is open.', allowed:GATES, inputs:['A','B','C'], outputs:['X'], best:2,\n   target:v=>({X:v.A*Math.max(v.B,v.C)}), hint:'First combine the door and the window, then combine that result with Armed.'}\n];\n\nconst EXAMPLES={\n  half:{tip:'Half adder: Sum = A XOR B, Carry = A AND B. Flip the switches to add two 1-bit numbers.',\n    comps:[['INPUT',40,140,'A'],['INPUT',40,320,'B'],['XOR',330,130],['AND',330,310],['OUTPUT',640,138,'Sum'],['OUTPUT',640,318,'Carry']],\n    wires:[[0,2,0],[1,2,1],[0,3,0],[1,3,1],[2,4,0],[3,5,0]]},\n  full:{tip:'Full adder: adds A, B and a carry-in. Chain these together and you can add numbers of any size.',\n    comps:[['INPUT',30,90,'A'],['INPUT',30,210,'B'],['INPUT',30,400,'Cin'],['XOR',220,110],['AND',220,250],['XOR',450,170],['AND',450,330],['OR',660,290],['OUTPUT',840,178,'Sum'],['OUTPUT',840,298,'Cout']],\n    wires:[[0,3,0],[1,3,1],[0,4,0],[1,4,1],[3,5,0],[2,5,1],[3,6,0],[2,6,1],[4,7,0],[6,7,1],[5,8,0],[7,9,0]]},\n  mux:{tip:'Multiplexer: switch S chooses which input reaches X. S = 0 passes A, S = 1 passes B.',\n    comps:[['INPUT',40,80,'A'],['INPUT',40,240,'B'],['INPUT',40,400,'S'],['NOT',230,392],['AND',430,110],['AND',430,270],['OR',640,190],['OUTPUT',840,198,'X']],\n    wires:[[0,4,0],[3,4,1],[1,5,0],[2,5,1],[2,3,0],[4,6,0],[5,6,1],[6,7,0]]}\n};\n\n\/\/ ---------- state ----------\nlet comps=[], wires=[], nextId=1;\nlet mode='free', chal=null, chalIdx=0, solvedShown=false;\nlet selComp=null, selWire=null, drag=null, wiring=null, pending=null, palDrag=null;\n\nconst $=id=>document.getElementById(id);\nconst svg=$('board');\nconst uid=()=>'c'+(nextId++);\nconst byId=id=>comps.find(c=>c.id===id);\nconst clamp=(v,a,b)=>Math.max(a,Math.min(b,v));\nconst isGate=c=>GATES.includes(c.type);\n\nfunction pt(e){\n  const p=svg.createSVGPoint(); p.x=e.clientX; p.y=e.clientY;\n  return p.matrixTransform(svg.getScreenCTM().inverse());\n}\nfunction status(t){ $('status').textContent=t; }\n\n\/\/ ---------- simulation ----------\nfunction wireIndex(){ const m={}; wires.forEach(w=>{ m[w.to+':'+w.pin]=w.from; }); return m; }\nfunction currentInputs(){ const m={}; comps.forEach(c=>{ if(c.type==='INPUT') m[c.id]=c.on?1:0; }); return m; }\nfunction simulate(inMap){\n  const val={}, iw=wireIndex();\n  comps.forEach(c=>{ val[c.id]=c.type==='INPUT'?(inMap[c.id]?1:0):0; });\n  for(let pass=0;pass<64;pass++){\n    let changed=false;\n    comps.forEach(c=>{\n      if(c.type==='INPUT') return;\n      const T=TYPES[c.type];\n      const ins=T.ins.map((_,i)=>{ const f=iw[c.id+':'+i]; return f===undefined?0:val[f]; });\n      const v=c.type==='OUTPUT'?ins[0]:T.fn(ins[0],ins[1]);\n      if(val[c.id]!==v){ val[c.id]=v; changed=true; }\n    });\n    if(!changed) break;\n  }\n  return val;\n}\nfunction exprAlg(id, seen){\n  const c=byId(id); if(!c) return '0';\n  if(c.type==='INPUT') return c.label;\n  if(seen.has(id) || seen.size>16) return '...';\n  const s2=new Set(seen); s2.add(id);\n  const iw=wireIndex();\n  const arg=i=>{ const f=iw[id+':'+i]; return f===undefined?'0':exprAlg(f,s2); };\n  const wrap=x=>\/[\\s]\/.test(x)?'('+x+')':x;\n  const a=wrap(arg(0));\n  if(c.type==='OUTPUT') return arg(0);\n  if(c.type==='NOT') return '\\u00ac'+a;\n  const b=wrap(arg(1));\n  if(c.type==='AND') return a+' \\u00b7 '+b;\n  if(c.type==='OR') return a+' + '+b;\n  if(c.type==='XOR') return a+' \\u2295 '+b;\n  if(c.type==='NAND') return '\\u00ac('+a+' \\u00b7 '+b+')';\n  if(c.type==='NOR') return '\\u00ac('+a+' + '+b+')';\n  if(c.type==='XNOR') return '\\u00ac('+a+' \\u2295 '+b+')';\n  return '?';\n}\nfunction exprOf(id, seen){\n  const c=byId(id); if(!c) return '0';\n  if(c.type==='INPUT') return c.label;\n  if(seen.has(id) || seen.size>16) return '...';\n  const s2=new Set(seen); s2.add(id);\n  const iw=wireIndex();\n  const arg=i=>{ const f=iw[id+':'+i]; return f===undefined?'0':exprOf(f,s2); };\n  const wrap=x=>\/\\s\/.test(x)?'('+x+')':x;\n  if(c.type==='OUTPUT') return arg(0);\n  if(c.type==='NOT') return 'NOT '+wrap(arg(0));\n  return wrap(arg(0))+' '+c.type+' '+wrap(arg(1));\n}\n\n\/\/ ---------- shapes ----------\nfunction gateShape(type){\n  const andP='M12,5 H39 A25,25 0 0 1 39,55 H12 Z';\n  const orP='M10,5 Q24,30 10,55 Q44,55 64,30 Q44,5 10,5 Z';\n  const notP='M14,8 L58,30 L14,52 Z';\n  const xorX='<path d=\"M3,5 Q17,30 3,55\" class=\"gx\"\/>';\n  const bub=cx=>'<circle cx=\"'+cx+'\" cy=\"30\" r=\"5\" class=\"gb\"\/>';\n  switch(type){\n    case 'AND': return '<path d=\"'+andP+'\" class=\"gb\"\/>';\n    case 'NAND': return '<path d=\"'+andP+'\" class=\"gb\"\/>'+bub(69);\n    case 'OR': return '<path d=\"'+orP+'\" class=\"gb\"\/>';\n    case 'NOR': return '<path d=\"'+orP+'\" class=\"gb\"\/>'+bub(69);\n    case 'XOR': return xorX+'<path d=\"'+orP+'\" class=\"gb\"\/>';\n    case 'XNOR': return xorX+'<path d=\"'+orP+'\" class=\"gb\"\/>'+bub(69);\n    case 'NOT': return '<path d=\"'+notP+'\" class=\"gb\"\/>'+bub(63);\n  }\n  return '';\n}\nfunction gateIcon(type){\n  const T=TYPES[type];\n  let s='';\n  T.ins.forEach(p=>{ s+='<line x1=\"0\" y1=\"'+p[1]+'\" x2=\"22\" y2=\"'+p[1]+'\" class=\"stub\"\/>'; });\n  s+='<line x1=\"58\" y1=\"30\" x2=\"80\" y2=\"30\" class=\"stub\"\/>'+gateShape(type);\n  return s;\n}\nfunction ioIcon(type){\n  if(type==='INPUT') return '<rect x=\"6\" y=\"10\" width=\"44\" height=\"40\" rx=\"10\" class=\"sw on\"\/><text x=\"28\" y=\"38\" class=\"swv\">1<\/text><line x1=\"50\" y1=\"30\" x2=\"76\" y2=\"30\" class=\"stub\"\/>';\n  return '<line x1=\"4\" y1=\"30\" x2=\"22\" y2=\"30\" class=\"stub\"\/><circle cx=\"48\" cy=\"30\" r=\"22\" class=\"glow\"\/><circle cx=\"48\" cy=\"30\" r=\"16\" class=\"lamp on\"\/>';\n}\n\n\/\/ ---------- rendering ----------\nfunction portPos(c,kind,pin){ const T=TYPES[c.type]; const p=kind==='out'?T.out:T.ins[pin]; return {x:c.x+p[0], y:c.y+p[1]}; }\nfunction curve(a,b){\n  const dx=Math.max(40,Math.abs(b.x-a.x)\/2);\n  return 'M'+a.x+','+a.y+' C'+(a.x+dx)+','+a.y+' '+(b.x-dx)+','+b.y+' '+b.x+','+b.y;\n}\nfunction compatible(a,b){ if(!a) return false; if(a.comp===b.comp) return false; return a.kind!==b.kind; }\n\nfunction portSVG(c,kind,pin,p,v){\n  let cls='port'+(v?' on':'');\n  const src=wiring||pending;\n  if(src){\n    if(compatible(src,{comp:c.id,kind:kind,pin:pin})) cls+=' target';\n    if(src.comp===c.id ? (src.kind===kind ? src.pin===pin : false) : false) cls+=' pending';\n  }\n  return '<circle cx=\"'+p[0]+'\" cy=\"'+p[1]+'\" r=\"6.5\" class=\"'+cls+'\"\/>'+\n         '<circle cx=\"'+p[0]+'\" cy=\"'+p[1]+'\" r=\"15\" class=\"hit\" data-port=\"'+kind+'\" data-pin=\"'+pin+'\" data-pcomp=\"'+c.id+'\"\/>';\n}\n\nfunction compSVG(c,val,iw){\n  const T=TYPES[c.type], on=val[c.id]===1, sel=selComp===c.id;\n  const insV=T.ins.map((_,i)=>{ const f=iw[c.id+':'+i]; return f===undefined?0:val[f]; });\n  let s='<g class=\"comp\" data-comp=\"'+c.id+'\" transform=\"translate('+c.x+','+c.y+')\">';\n  if(sel) s+='<rect x=\"-10\" y=\"-30\" width=\"'+(T.w+20)+'\" height=\"'+(T.h+50)+'\" rx=\"14\" class=\"selbox\"\/>';\n  if(c.type==='INPUT'){\n    s+='<line x1=\"56\" y1=\"22\" x2=\"72\" y2=\"22\" class=\"stub'+(on?' on':'')+'\"\/>';\n    s+='<rect x=\"0\" y=\"0\" width=\"56\" height=\"44\" rx=\"12\" class=\"sw'+(on?' on':'')+'\"\/>';\n    s+='<text x=\"28\" y=\"30\" class=\"swv\">'+(on?1:0)+'<\/text>';\n    s+='<text x=\"28\" y=\"-10\" class=\"lbl\">'+c.label+'<\/text>';\n  } else if(c.type==='OUTPUT'){\n    s+='<line x1=\"0\" y1=\"22\" x2=\"19\" y2=\"22\" class=\"stub'+(insV[0]?' on':'')+'\"\/>';\n    if(on) s+='<circle cx=\"38\" cy=\"22\" r=\"27\" class=\"glow\"\/>';\n    s+='<circle cx=\"38\" cy=\"22\" r=\"19\" class=\"lamp'+(on?' on':'')+'\"\/>';\n    s+='<text x=\"38\" y=\"28\" class=\"lampv\">'+(on?1:0)+'<\/text>';\n    s+='<text x=\"38\" y=\"-14\" class=\"lbl\">'+c.label+'<\/text>';\n  } else {\n    T.ins.forEach((p,i)=>{ s+='<line x1=\"0\" y1=\"'+p[1]+'\" x2=\"22\" y2=\"'+p[1]+'\" class=\"stub'+(insV[i]?' on':'')+'\"\/>'; });\n    s+='<line x1=\"58\" y1=\"30\" x2=\"80\" y2=\"30\" class=\"stub'+(on?' on':'')+'\"\/>';\n    s+=gateShape(c.type);\n    s+='<text x=\"38\" y=\"76\" class=\"gname\">'+c.type+'<\/text>';\n  }\n  T.ins.forEach((p,i)=>{ s+=portSVG(c,'in',i,p,insV[i]); });\n  if(T.out) s+=portSVG(c,'out',0,T.out,on?1:0);\n  return s+'<\/g>';\n}\n\nfunction renderBoard(){\n  const val=simulate(currentInputs()), iw=wireIndex();\n  let ws='';\n  wires.forEach(w=>{\n    const a=byId(w.from), b=byId(w.to); if(!a) return; if(!b) return;\n    const d=curve(portPos(a,'out',0), portPos(b,'in',w.pin));\n    const on=val[w.from]===1, sel=selWire===w.id;\n    ws+='<g data-wire=\"'+w.id+'\">'+(on?'<path d=\"'+d+'\" class=\"w-under\"\/>':'')+\n        '<path d=\"'+d+'\" class=\"'+(on?'w-on':'w-off')+(sel?' w-sel':'')+'\"\/>'+\n        '<path d=\"'+d+'\" class=\"w-hit\"\/><\/g>';\n  });\n  $('wiresLayer').innerHTML=ws;\n  let cs=comps.map(c=>compSVG(c,val,iw)).join('');\n  if(comps.length===0) cs='<text x=\"480\" y=\"250\" class=\"empty\">Your board is empty.<\/text><text x=\"480\" y=\"280\" class=\"empty\" style=\"font-size:15px\">Drag a switch, a gate and a lamp from the toolbox to start.<\/text>';\n  $('compsLayer').innerHTML=cs;\n  $('delBtn').disabled=!(selComp||selWire);\n}\n\nfunction sortedIO(type){\n  return comps.filter(c=>c.type===type).sort((a,b)=>a.label.localeCompare(b.label));\n}\n\nfunction renderPanel(){\n  const ins=sortedIO('INPUT'), outs=sortedIO('OUTPUT');\n  $('sGates').textContent=comps.filter(isGate).length;\n  $('sWires').textContent=wires.length;\n  let html='', allOk=true;\n  if(ins.length===0 || outs.length===0){\n    html='<div class=\"tt-empty\">Add at least one switch and one lamp to see the truth table.<\/div>';\n    $('sRows').textContent=0; allOk=false;\n  } else {\n    const k=ins.length, rows=Math.pow(2,k), cur=currentInputs();\n    let curIdx=0; ins.forEach((c,i)=>{ curIdx+=cur[c.id]*Math.pow(2,k-1-i); });\n    html='<div class=\"tt-wrap\"><table class=\"tt\"><thead><tr>';\n    ins.forEach(c=>{ html+='<th>'+c.label+'<\/th>'; });\n    outs.forEach((c,i)=>{ html+='<th class=\"o'+(i===0?' sep':'')+'\">'+c.label+'<\/th>'; });\n    if(chal){ outs.forEach(c=>{ html+='<th class=\"g\">Goal '+c.label+'<\/th>'; }); html+='<th><\/th>'; }\n    html+='<\/tr><\/thead><tbody>';\n    for(let r=0;r<rows;r++){\n      const inMap={}, byLabel={};\n      ins.forEach((c,i)=>{ const b=Math.floor(r\/Math.pow(2,k-1-i))%2; inMap[c.id]=b; byLabel[c.label]=b; });\n      const val=simulate(inMap);\n      const cell=v=>v?'<span class=\"one\">1<\/span>':'0';\n      html+='<tr'+(r===curIdx?' class=\"cur\"':'')+'>';\n      ins.forEach(c=>{ html+='<td>'+cell(inMap[c.id])+'<\/td>'; });\n      outs.forEach((c,i)=>{ html+='<td'+(i===0?' class=\"sep\"':'')+'>'+cell(val[c.id])+'<\/td>'; });\n      if(chal){\n        const tgt=chal.target(byLabel); let ok=true;\n        outs.forEach(c=>{ html+='<td>'+cell(tgt[c.label])+'<\/td>'; if(tgt[c.label]!==val[c.id]) ok=false; });\n        if(!ok) allOk=false;\n        html+='<td>'+(ok?'<span class=\"ok\">\u2713<\/span>':'<span class=\"no\">\u2717<\/span>')+'<\/td>';\n      }\n      html+='<\/tr>';\n    }\n    html+='<\/tbody><\/table><\/div>';\n    $('sRows').textContent=rows;\n  }\n  $('tt').innerHTML=html;\n  $('exprs').innerHTML=outs.map(c=>'<div class=\"expr\"><b>'+c.label+'<\/b> = '+exprOf(c.id,new Set())+'<\/div>'+'<div class=\"expr alg adv-only\"><b>'+c.label+'<\/b> = '+exprAlg(c.id,new Set())+'<\/div>').join('');\n\n  if(chal){\n    const n=comps.filter(isGate).length, el=$('solved');\n    if(allOk){\n      el.textContent=n<=chal.best\n        ? 'Challenge solved with '+n+' gate'+(n===1?'':'s')+'. That matches the best known answer!'\n        : 'Challenge solved with '+n+' gates! The best known answer uses '+chal.best+'. Can you do it with fewer?';\n      el.classList.add('show');\n      if(!solvedShown){ solvedShown=true; status('Every row matches the goal. Nice work!'); }\n    } else { el.classList.remove('show'); solvedShown=false; }\n  }\n}\n\nfunction render(full){ renderBoard(); if(full) renderPanel(); }\n\n\/\/ ---------- editing ----------\nfunction nextLabel(type){\n  const list=type==='INPUT'?IN_LABELS:OUT_LABELS;\n  const used=comps.filter(c=>c.type===type).map(c=>c.label);\n  return list.find(l=>!used.includes(l));\n}\nfunction freeSpot(type){\n  const slots=[50,150,250,350,440];\n  if(type==='INPUT' || type==='OUTPUT'){\n    const x=type==='INPUT'?40:840;\n    const others=comps.filter(c=>c.type===type);\n    const y=slots.find(s=>others.every(o=>Math.abs(o.y-s)>40));\n    return {x:x, y:y===undefined?200:y};\n  }\n  const n=comps.filter(isGate).length%6;\n  return {x:330+(n%3)*130, y:110+Math.floor(n\/3)*170+(n%3)*20};\n}\nfunction addComp(type,x,y,label){\n  const c={id:uid(), type:type, x:x, y:y};\n  if(type==='INPUT' || type==='OUTPUT'){\n    c.label=label||nextLabel(type);\n    if(!c.label){ status('You can use up to 5 '+(type==='INPUT'?'switches':'lamps')+'.'); return null; }\n    if(type==='INPUT') c.on=false;\n  }\n  const T=TYPES[type];\n  c.x=clamp(c.x,10,W-T.w-10); c.y=clamp(c.y,30,H-T.h-30);\n  comps.push(c);\n  return c;\n}\nfunction connect(a,b){\n  const o=a.kind==='out'?a:b, i=a.kind==='out'?b:a;\n  wires=wires.filter(w=>w.to===i.comp ? w.pin!==i.pin : true);\n  wires.push({id:uid(), from:o.comp, to:i.comp, pin:i.pin});\n  status('Connected! Flip the switches to test it.');\n}\nfunction deleteSelected(){\n  if(selComp){\n    const c=byId(selComp);\n    if(c.locked){ status('The switches and lamps are part of the challenge, so they stay on the board.'); return; }\n    const id=selComp;\n    comps=comps.filter(x=>x.id!==id);\n    wires=wires.filter(w=>w.from!==id ? w.to!==id : false);\n    selComp=null;\n  } else if(selWire){\n    wires=wires.filter(w=>w.id!==selWire); selWire=null;\n  }\n  render(true);\n}\nfunction cancelWire(){ wiring=null; pending=null; $('temp').setAttribute('d',''); }\nfunction updateTemp(p){\n  const src=wiring||pending; if(!src) return;\n  const c=byId(src.comp); if(!c) return;\n  const a=portPos(c,src.kind,src.pin);\n  $('temp').setAttribute('d', src.kind==='out'?curve(a,p):curve(p,a));\n}\nfunction portInfo(el){ return {comp:el.dataset.pcomp, kind:el.dataset.port, pin:+el.dataset.pin}; }\n\n\/\/ ---------- pointer events ----------\nsvg.addEventListener('pointerdown',e=>{\n  if(e.button>0) return;\n  const p=pt(e);\n  const port=e.target.closest('[data-port]');\n  if(port){\n    e.preventDefault();\n    const info=portInfo(port);\n    if(compatible(pending,info)){ connect(pending,info); cancelWire(); render(true); return; }\n    pending=null;\n    wiring={comp:info.comp, kind:info.kind, pin:info.pin, sx:p.x, sy:p.y, moved:false};\n    selComp=null; selWire=null; render(false); updateTemp(p);\n    return;\n  }\n  const g=e.target.closest('[data-comp]');\n  if(g){\n    e.preventDefault();\n    const c=byId(g.dataset.comp);\n    cancelWire();\n    selComp=c.id; selWire=null;\n    drag={id:c.id, ox:p.x-c.x, oy:p.y-c.y, sx:p.x, sy:p.y, moved:false};\n    render(false);\n    return;\n  }\n  const w=e.target.closest('[data-wire]');\n  if(w){ cancelWire(); selWire=w.dataset.wire; selComp=null; render(false); status('Wire selected. Press Delete to remove it.'); return; }\n  cancelWire(); selComp=null; selWire=null; render(false);\n});\n\nwindow.addEventListener('pointermove',e=>{\n  if(palDrag){\n    if(!palDrag.made){\n      const r=svg.getBoundingClientRect();\n      const inside=e.clientX>r.left ? (e.clientX<r.right ? (e.clientY>r.top ? e.clientY<r.bottom : false) : false) : false;\n      if(inside){\n        const p=pt(e), T=TYPES[palDrag.type];\n        const c=addComp(palDrag.type, p.x-T.w\/2, p.y-T.h\/2);\n        palDrag.made=true;\n        if(c){ selComp=c.id; selWire=null; drag={id:c.id, ox:T.w\/2, oy:T.h\/2, sx:p.x, sy:p.y, moved:true}; render(true); }\n      }\n    }\n  }\n  if(drag){\n    const p=pt(e);\n    if(Math.hypot(p.x-drag.sx,p.y-drag.sy)>4) drag.moved=true;\n    if(drag.moved){\n      const c=byId(drag.id), T=TYPES[c.type];\n      c.x=Math.round(clamp(p.x-drag.ox,10,W-T.w-10));\n      c.y=Math.round(clamp(p.y-drag.oy,30,H-T.h-30));\n      renderBoard();\n    }\n    return;\n  }\n  if(wiring){\n    const p=pt(e);\n    if(Math.hypot(p.x-wiring.sx,p.y-wiring.sy)>6) wiring.moved=true;\n    updateTemp(p);\n  } else if(pending){ updateTemp(pt(e)); }\n});\n\nwindow.addEventListener('pointerup',e=>{\n  palDrag=null;\n  if(drag){\n    const c=byId(drag.id);\n    if(!drag.moved){\n      if(c.type==='INPUT'){ c.on=!c.on; status('Switch '+c.label+' is now '+(c.on?1:0)+'.'); }\n      else if(isGate(c)) status(c.type+': '+GATE_INFO[c.type]);\n    }\n    drag=null; render(true);\n    return;\n  }\n  if(wiring){\n    const el=document.elementFromPoint(e.clientX,e.clientY);\n    const port=el?el.closest('[data-port]'):null;\n    if(port){\n      const info=portInfo(port);\n      if(compatible(wiring,info)){ connect(wiring,info); cancelWire(); render(true); return; }\n    }\n    if(!wiring.moved){\n      pending={comp:wiring.comp, kind:wiring.kind, pin:wiring.pin};\n      wiring=null;\n      status('Now click or tap a highlighted dot to connect. Press Esc to cancel.');\n      render(false);\n      return;\n    }\n    cancelWire(); render(false);\n    status('Drop the wire on a highlighted dot to connect it.');\n  }\n});\n\ndocument.addEventListener('keydown',e=>{\n  const tag=(e.target.tagName||'').toUpperCase();\n  if(tag==='SELECT' || tag==='INPUT' || tag==='TEXTAREA') return;\n  if(e.key==='Delete' || e.key==='Backspace'){ if(selComp || selWire){ e.preventDefault(); deleteSelected(); } }\n  else if(e.key==='Escape'){ cancelWire(); selComp=null; selWire=null; render(false); status(DEFAULT_TIP); }\n});\n\n\/\/ ---------- toolbox ----------\nfunction buildToolbox(){\n  const box=$('toolbox'); box.innerHTML='';\n  const items=mode==='free'?['INPUT','OUTPUT'].concat(LEVEL.get()==='adv'?GATES:GATES_EASY):chal.allowed;\n  items.forEach(type=>{\n    const b=document.createElement('button');\n    b.type='button';\n    const io=type==='INPUT' || type==='OUTPUT';\n    b.className='tool'+(io?' io':'');\n    const name=type==='INPUT'?'Switch':(type==='OUTPUT'?'Lamp':type);\n    b.innerHTML='<svg viewBox=\"-2 0 84 60\" aria-hidden=\"true\">'+(io?ioIcon(type):gateIcon(type))+'<\/svg><span>'+name+'<\/span>';\n    b.setAttribute('aria-label','Add '+name);\n    b.addEventListener('pointerdown',ev=>{ palDrag={type:type, made:false}; });\n    b.addEventListener('click',()=>{\n      const s=freeSpot(type), c=addComp(type,s.x,s.y);\n      if(c){ selComp=c.id; selWire=null; render(true); status(name+' added. Drag it into place.'); }\n    });\n    box.appendChild(b);\n  });\n}\n\n\/\/ ---------- modes, examples, challenges ----------\nfunction clearBoard(){ comps=[]; wires=[]; selComp=null; selWire=null; cancelWire(); }\n\nfunction loadExample(key){\n  const ex=EXAMPLES[key]; if(!ex) return;\n  clearBoard();\n  const ids=ex.comps.map(d=>{ const c=addComp(d[0],d[1],d[2],d[3]); return c.id; });\n  ex.wires.forEach(w=>{ wires.push({id:uid(), from:ids[w[0]], to:ids[w[1]], pin:w[2]}); });\n  render(true); status(ex.tip);\n}\n\nfunction chalList(){\n  const order=['NOT from NAND','AND from NAND','OR from NAND','Build your own XOR','XOR from NAND','Half adder','Full adder','Smart alarm','Majority vote'];\n  const all=CHALLENGES.concat(CHALLENGES_EXTRA);\n  if(LEVEL.get()==='adv') return order.map(t=>all.find(c=>c.title===t));\n  return ['Smart alarm','NOT from NAND','Half adder','Majority vote'].map(t=>all.find(c=>c.title===t));\n}\nfunction buildChalSel(){\n  const sel=$('chalSel'); sel.innerHTML='';\n  chalList().forEach((c,i)=>{ const o=document.createElement('option'); o.value=i; o.textContent=(i+1)+'. '+c.title; sel.appendChild(o); });\n  sel.value=String(chalIdx);\n}\nfunction loadChallenge(i){\n  const list=chalList(); if(i>=list.length) i=0;\n  chalIdx=i; chal=list[i]; solvedShown=false; $('chalSel').value=String(i);\n  clearBoard();\n  const place=(labels,type,x)=>{\n    const gap=labels.length===1?0:Math.min(150,(H-160)\/(labels.length-1));\n    const top=(H-gap*(labels.length-1))\/2-22;\n    labels.forEach((l,k)=>{ const c=addComp(type,x,top+k*gap,l); c.locked=true; });\n  };\n  place(chal.inputs,'INPUT',40);\n  place(chal.outputs,'OUTPUT',840);\n  $('goal').hidden=false;\n  $('goalTitle').textContent=chal.title;\n  $('goalText').textContent=chal.text;\n  $('goalMeta').textContent='Allowed gates: '+chal.allowed.join(', ');\n  $('hint').textContent=chal.hint; $('hint').classList.remove('show');\n  $('hintBtn').textContent='Show a hint';\n  buildToolbox(); render(true);\n  status('Challenge '+(i+1)+' of '+chalList().length+': build a circuit so every row of the truth table gets a \u2713.');\n}\n\nfunction setMode(m){\n  mode=m;\n  $('modeFree').setAttribute('aria-pressed',m==='free');\n  $('modeChal').setAttribute('aria-pressed',m==='chal');\n  $('exampleSel').hidden=m!=='free';\n  $('chalSel').hidden=m!=='chal';\n  $('clearTxt').textContent=m==='free'?'Clear board':'Restart challenge';\n  if(m==='free'){\n    chal=null; $('goal').hidden=true; clearBoard(); buildToolbox(); render(true); status(DEFAULT_TIP);\n  } else {\n    loadChallenge(chalIdx);\n  }\n}\n\nbuildChalSel();\n$('modeFree').addEventListener('click',()=>setMode('free'));\n$('modeChal').addEventListener('click',()=>setMode('chal'));\n$('chalSel').addEventListener('change',e=>loadChallenge(+e.target.value));\n$('exampleSel').addEventListener('change',e=>{ loadExample(e.target.value); e.target.value=''; });\n$('delBtn').addEventListener('click',deleteSelected);\n$('clearBtn').addEventListener('click',()=>{ if(mode==='free'){ clearBoard(); render(true); status(DEFAULT_TIP); } else loadChallenge(chalIdx); });\n$('hintBtn').addEventListener('click',()=>{ const h=$('hint'); const show=!h.classList.contains('show'); h.classList.toggle('show',show); $('hintBtn').textContent=show?'Hide hint':'Show a hint'; });\n\n\/\/ ---------- gate reference cards ----------\n(function(){\n  const box=$('gateCards');\n  GATES.forEach(g=>{\n    const T=TYPES[g];\n    let rows='';\n    if(g==='NOT'){\n      rows='<tr><th>A<\/th><th>OUT<\/th><\/tr>';\n      [0,1].forEach(a=>{ const o=T.fn(a); rows+='<tr><td>'+a+'<\/td><td class=\"out'+(o?' on':'')+'\">'+o+'<\/td><\/tr>'; });\n    } else {\n      rows='<tr><th>A<\/th><th>B<\/th><th>OUT<\/th><\/tr>';\n      [[0,0],[0,1],[1,0],[1,1]].forEach(p=>{ const o=T.fn(p[0],p[1]); rows+='<tr><td>'+p[0]+'<\/td><td>'+p[1]+'<\/td><td class=\"out'+(o?' on':'')+'\">'+o+'<\/td><\/tr>'; });\n    }\n    const d=document.createElement('div'); d.className='gcard';\n    d.innerHTML='<svg viewBox=\"-2 0 84 60\" aria-hidden=\"true\">'+gateIcon(g)+'<\/svg><h3>'+g+'<\/h3><div class=\"nota adv-only\">'+NOTA[g]+'<\/div><p>'+GATE_INFO[g]+'<\/p><table class=\"mini\">'+rows+'<\/table>';\n    box.appendChild(d);\n  });\n})();\n\n\/\/ ---------- level ----------\nLEVEL.on(()=>{\n  if(mode==='free'){ buildToolbox(); render(true); status(LEVEL.get()==='adv'?'Advanced: all 7 gates are in the toolbox, and the panel shows Boolean algebra too.':'Easy: the toolbox has the 4 most useful gates.'); }\n  else { chalIdx=0; buildChalSel(); loadChallenge(0); }\n});\n\n\/\/ ---------- start ----------\nbuildToolbox();\nloadExample('half');\nstatus('Here is a half adder to get you started. Click switches A and B to flip them, or clear the board and build your own.');\n<\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>Logic Gate Simulator Interactive CS Tools Logic Gate Simulator Drag gates onto the board, wire them up and flip the switches. The truth table and &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/logic-gate-simulator\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Logic Gate Simulator&#8221;<\/span><\/a><\/p>","protected":false},"author":55,"featured_media":0,"parent":31237,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-31063","page","type-page","status-publish","hentry"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO Pro 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"Logic Gate Simulator Interactive CS Tools Logic Gate Simulator Drag gates onto the board, wire them up and flip the switches. The truth table and Boolean expression update as you build. Mode Free build Challenges LevelEasyAdvanced Load an example... Half adder Full adder 2-to-1 multiplexer Delete selected Clear board Toolbox Drag onto the board, or\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/logic-gate-simulator\/\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO Pro (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\n\t\t<meta property=\"og:site_name\" content=\"CodeMonkey -\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Logic Gate Simulator - CodeMonkey\" \/>\n\t\t<meta property=\"og:description\" content=\"Logic Gate Simulator Interactive CS Tools Logic Gate Simulator Drag gates onto the board, wire them up and flip the switches. The truth table and Boolean expression update as you build. Mode Free build Challenges LevelEasyAdvanced Load an example... Half adder Full adder 2-to-1 multiplexer Delete selected Clear board Toolbox Drag onto the board, or\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/logic-gate-simulator\/\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/d3sujgifhk94se.cloudfront.net\/wp-content\/uploads\/2020\/06\/21143425\/codemonkey_logo.png\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/d3sujgifhk94se.cloudfront.net\/wp-content\/uploads\/2020\/06\/21143425\/codemonkey_logo.png\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-10-08T11:26:49+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-10-29T16:52:18+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Logic Gate Simulator - CodeMonkey\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Logic Gate Simulator Interactive CS Tools Logic Gate Simulator Drag gates onto the board, wire them up and flip the switches. The truth table and Boolean expression update as you build. Mode Free build Challenges LevelEasyAdvanced Load an example... Half adder Full adder 2-to-1 multiplexer Delete selected Clear board Toolbox Drag onto the board, or\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/d3sujgifhk94se.cloudfront.net\/wp-content\/uploads\/2020\/06\/21143425\/codemonkey_logo.png\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/interactive-cs-tools\\\/logic-gate-simulator\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/interactive-cs-tools\\\/#listItem\",\"name\":\"Free Teacher Tools for Computer Science\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/interactive-cs-tools\\\/#listItem\",\"position\":2,\"name\":\"Free Teacher Tools for Computer Science\",\"item\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/interactive-cs-tools\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/interactive-cs-tools\\\/logic-gate-simulator\\\/#listItem\",\"name\":\"Logic Gate Simulator\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/interactive-cs-tools\\\/logic-gate-simulator\\\/#listItem\",\"position\":3,\"name\":\"Logic Gate Simulator\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/interactive-cs-tools\\\/#listItem\",\"name\":\"Free Teacher Tools for Computer Science\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/#organization\",\"name\":\"CodeMonkey\",\"url\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/d3sujgifhk94se.cloudfront.net\\\/wp-content\\\/uploads\\\/2020\\\/06\\\/21143425\\\/codemonkey_logo.png\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/interactive-cs-tools\\\/logic-gate-simulator\\\/#organizationLogo\",\"width\":200,\"height\":31,\"caption\":\"Codemonkey Coding for Kids\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/interactive-cs-tools\\\/logic-gate-simulator\\\/#organizationLogo\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/interactive-cs-tools\\\/logic-gate-simulator\\\/#webpage\",\"url\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/interactive-cs-tools\\\/logic-gate-simulator\\\/\",\"name\":\"Logic Gate Simulator - CodeMonkey\",\"description\":\"Logic Gate Simulator Interactive CS Tools Logic Gate Simulator Drag gates onto the board, wire them up and flip the switches. The truth table and Boolean expression update as you build. Mode Free build Challenges LevelEasyAdvanced Load an example... Half adder Full adder 2-to-1 multiplexer Delete selected Clear board Toolbox Drag onto the board, or\",\"inLanguage\":\"es-ES\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/interactive-cs-tools\\\/logic-gate-simulator\\\/#breadcrumblist\"},\"datePublished\":\"2026-10-08T11:26:49+00:00\",\"dateModified\":\"2026-10-29T16:52:18+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/#website\",\"url\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/\",\"name\":\"CodeMonkey\",\"inLanguage\":\"es-ES\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.codemonkey.com\\\/es\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO Pro -->\r\n\t\t<title>Logic Gate Simulator - CodeMonkey<\/title>\n\n","aioseo_head_json":{"title":"Logic Gate Simulator - CodeMonkey","description":"Logic Gate Simulator Interactive CS Tools Logic Gate Simulator Drag gates onto the board, wire them up and flip the switches. The truth table and Boolean expression update as you build. Mode Free build Challenges LevelEasyAdvanced Load an example... Half adder Full adder 2-to-1 multiplexer Delete selected Clear board Toolbox Drag onto the board, or","canonical_url":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/logic-gate-simulator\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BreadcrumbList","@id":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/logic-gate-simulator\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/www.codemonkey.com\/es\/#listItem","position":1,"name":"Home","item":"https:\/\/www.codemonkey.com\/es\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/#listItem","name":"Free Teacher Tools for Computer Science"}},{"@type":"ListItem","@id":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/#listItem","position":2,"name":"Free Teacher Tools for Computer Science","item":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/logic-gate-simulator\/#listItem","name":"Logic Gate Simulator"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.codemonkey.com\/es\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/logic-gate-simulator\/#listItem","position":3,"name":"Logic Gate Simulator","previousItem":{"@type":"ListItem","@id":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/#listItem","name":"Free Teacher Tools for Computer Science"}}]},{"@type":"Organization","@id":"https:\/\/www.codemonkey.com\/es\/#organization","name":"CodeMonkey","url":"https:\/\/www.codemonkey.com\/es\/","logo":{"@type":"ImageObject","url":"https:\/\/d3sujgifhk94se.cloudfront.net\/wp-content\/uploads\/2020\/06\/21143425\/codemonkey_logo.png","@id":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/logic-gate-simulator\/#organizationLogo","width":200,"height":31,"caption":"Codemonkey Coding for Kids"},"image":{"@id":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/logic-gate-simulator\/#organizationLogo"}},{"@type":"WebPage","@id":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/logic-gate-simulator\/#webpage","url":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/logic-gate-simulator\/","name":"Logic Gate Simulator - CodeMonkey","description":"Logic Gate Simulator Interactive CS Tools Logic Gate Simulator Drag gates onto the board, wire them up and flip the switches. The truth table and Boolean expression update as you build. Mode Free build Challenges LevelEasyAdvanced Load an example... Half adder Full adder 2-to-1 multiplexer Delete selected Clear board Toolbox Drag onto the board, or","inLanguage":"es-ES","isPartOf":{"@id":"https:\/\/www.codemonkey.com\/es\/#website"},"breadcrumb":{"@id":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/logic-gate-simulator\/#breadcrumblist"},"datePublished":"2026-10-08T11:26:49+00:00","dateModified":"2026-10-29T16:52:18+00:00"},{"@type":"WebSite","@id":"https:\/\/www.codemonkey.com\/es\/#website","url":"https:\/\/www.codemonkey.com\/es\/","name":"CodeMonkey","inLanguage":"es-ES","publisher":{"@id":"https:\/\/www.codemonkey.com\/es\/#organization"}}]},"og:locale":"es_ES","og:site_name":"CodeMonkey -","og:type":"article","og:title":"Logic Gate Simulator - CodeMonkey","og:description":"Logic Gate Simulator Interactive CS Tools Logic Gate Simulator Drag gates onto the board, wire them up and flip the switches. The truth table and Boolean expression update as you build. Mode Free build Challenges LevelEasyAdvanced Load an example... Half adder Full adder 2-to-1 multiplexer Delete selected Clear board Toolbox Drag onto the board, or","og:url":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/logic-gate-simulator\/","og:image":"https:\/\/d3sujgifhk94se.cloudfront.net\/wp-content\/uploads\/2020\/06\/21143425\/codemonkey_logo.png","og:image:secure_url":"https:\/\/d3sujgifhk94se.cloudfront.net\/wp-content\/uploads\/2020\/06\/21143425\/codemonkey_logo.png","article:published_time":"2026-10-08T11:26:49+00:00","article:modified_time":"2026-10-29T16:52:18+00:00","twitter:card":"summary_large_image","twitter:title":"Logic Gate Simulator - CodeMonkey","twitter:description":"Logic Gate Simulator Interactive CS Tools Logic Gate Simulator Drag gates onto the board, wire them up and flip the switches. The truth table and Boolean expression update as you build. Mode Free build Challenges LevelEasyAdvanced Load an example... Half adder Full adder 2-to-1 multiplexer Delete selected Clear board Toolbox Drag onto the board, or","twitter:image":"https:\/\/d3sujgifhk94se.cloudfront.net\/wp-content\/uploads\/2020\/06\/21143425\/codemonkey_logo.png"},"aioseo_meta_data":{"post_id":"31063","title":null,"description":null,"keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"WebPage","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","local_seo":null,"limit_modified_date":false,"open_ai":null,"created":"2026-10-08 11:25:39","updated":"2026-10-29 16:52:34","focus_keyword":null,"additional_keywords":null,"truseo_locale":null,"ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"breadcrumb_settings":null,"seo_analyzer_scan_date":"2026-10-29 16:52:33"},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t<a href=\"https:\/\/www.codemonkey.com\/es\/\" title=\"Home\">Home<\/a>\n<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t<a href=\"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/\" title=\"Free Teacher Tools for Computer Science\">Free Teacher Tools for Computer Science<\/a>\n<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\tLogic Gate Simulator\n<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.codemonkey.com\/es\/"},{"label":"Free Teacher Tools for Computer Science","link":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/"},{"label":"Logic Gate Simulator","link":"https:\/\/www.codemonkey.com\/es\/interactive-cs-tools\/logic-gate-simulator\/"}],"_links":{"self":[{"href":"https:\/\/www.codemonkey.com\/es\/wp-json\/wp\/v2\/pages\/31063","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codemonkey.com\/es\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.codemonkey.com\/es\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.codemonkey.com\/es\/wp-json\/wp\/v2\/users\/55"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codemonkey.com\/es\/wp-json\/wp\/v2\/comments?post=31063"}],"version-history":[{"count":2,"href":"https:\/\/www.codemonkey.com\/es\/wp-json\/wp\/v2\/pages\/31063\/revisions"}],"predecessor-version":[{"id":31227,"href":"https:\/\/www.codemonkey.com\/es\/wp-json\/wp\/v2\/pages\/31063\/revisions\/31227"}],"up":[{"embeddable":true,"href":"https:\/\/www.codemonkey.com\/es\/wp-json\/wp\/v2\/pages\/31237"}],"wp:attachment":[{"href":"https:\/\/www.codemonkey.com\/es\/wp-json\/wp\/v2\/media?parent=31063"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}