From 1700c3fad3db5ab13243b2482a9ae8ed6112bfb6 Mon Sep 17 00:00:00 2001 From: Rambilas Sah Date: Mon, 23 Mar 2026 12:03:11 +0530 Subject: [PATCH 01/10] Fix: shuffle bias, jQuery check, global leaks, console logs, shebang, GA config, and GitHub Actions version --- .github/scripts/assign-or-comment.js | 2 -- .github/workflows/deploy.yml | 4 ++-- _config.yml | 6 +++--- assets/js/module.js | 6 +++--- assets/js/quiz.js | 11 ++++++++--- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/.github/scripts/assign-or-comment.js b/.github/scripts/assign-or-comment.js index c93b19dd9..60bd827f4 100644 --- a/.github/scripts/assign-or-comment.js +++ b/.github/scripts/assign-or-comment.js @@ -1,5 +1,3 @@ -#!/bin/bash - const { Octokit } = require("@octokit/rest"); const octokit = new Octokit({ diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 2d4dbfcc2..08e406245 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: @@ -24,7 +24,7 @@ jobs: run: bundle exec jekyll serve --port=4000 --detach - name: API Generation - run: sudo python utils/api_generator.py + run: python utils/api_generator.py - name: Kill Temporary Server run: pkill -f jekyll diff --git a/_config.yml b/_config.yml index 451723907..d52926503 100644 --- a/_config.yml +++ b/_config.yml @@ -80,7 +80,7 @@ aux_links: # Footer content # appears at the bottom of every page's main content -footer_content: "Copyright © 2026 Contributors to CircuitVerse. Distributed under a [CC-by-sa] license." +footer_content: "Copyright © {% assign current_year = 'now' | date: '%Y' %}{{ current_year }} Contributors to CircuitVerse. Distributed under a [CC-by-sa] license." # Footer last edited timestamp last_edit_timestamp: false # show or hide edit time - page must have `last_modified_date` defined in the frontmatter @@ -99,8 +99,8 @@ gh_edit_view_mode: "tree" # "tree" or "edit" if you want the user to jump into t color_scheme: circuitverse # Google Analytics Tracking (optional) -# e.g, UA-1234567-89 -ga_tracking: UA-112678513-3 +# e.g, G-XXXXXXXXXX (GA4 format) +# ga_tracking: G-XXXXXXXXXX jekyll-spaceship: # default enabled processors diff --git a/assets/js/module.js b/assets/js/module.js index 0d2577ee8..123e3bd97 100644 --- a/assets/js/module.js +++ b/assets/js/module.js @@ -2326,7 +2326,6 @@ function KarnaughMap(parentDivId, qmcRef) { hooveredKVField = -1; var oldHooveredElement = hooveredElement; hooveredElement = mouseOverElement(pos); - console.log(hooveredElement); if (hooveredElement !== -1) { hooveredKVField = uiElements[hooveredElement].ref; } @@ -2349,8 +2348,9 @@ function KarnaughMap(parentDivId, qmcRef) { } mx = e.pageX - offsetX; - my = e.pageY - offsetY + document.getElementById("scrollcount").scrollTop; - console.log(mx + " " + my + " " + document.getElementById("scrollcount").scrollTop ); + var scrollEl = document.getElementById("scrollcount"); + var scrollTop = scrollEl ? scrollEl.scrollTop : 0; + my = e.pageY - offsetY + scrollTop; return {x: mx, y: my}; } } diff --git a/assets/js/quiz.js b/assets/js/quiz.js index 7322aa80d..cffcbd4ec 100644 --- a/assets/js/quiz.js +++ b/assets/js/quiz.js @@ -1,7 +1,7 @@ $(function() { var quizSettings = $('.quiz'); - if (quizSettings != null) { + if (quizSettings.length > 0) { var quiz = $('
' + '

Pop Quiz

' + '
'); @@ -28,8 +28,13 @@ $(function() { }); }); - // Shuffle answers - answers.sort(function() { return 0.5 - Math.random(); }); + // Shuffle answers (Fisher-Yates) + for (var i = answers.length - 1; i > 0; i--) { + var j = Math.floor(Math.random() * (i + 1)); + var temp = answers[i]; + answers[i] = answers[j]; + answers[j] = temp; + } // Show answers var questionAnswers = $('
'); From 4a842d210262429040ddb251aa243f5c662254d9 Mon Sep 17 00:00:00 2001 From: Rambilas Sah Date: Mon, 23 Mar 2026 12:14:04 +0530 Subject: [PATCH 02/10] Fix: shuffle bias, jQuery check, global leaks, console logs, shebang, GA config, and GitHub Actions version --- assets/js/module.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/assets/js/module.js b/assets/js/module.js index 123e3bd97..677d2563e 100644 --- a/assets/js/module.js +++ b/assets/js/module.js @@ -2349,7 +2349,9 @@ function KarnaughMap(parentDivId, qmcRef) { mx = e.pageX - offsetX; var scrollEl = document.getElementById("scrollcount"); - var scrollTop = scrollEl ? scrollEl.scrollTop : 0; + var scrollTop = scrollEl + ? scrollEl.scrollTop + : (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0); my = e.pageY - offsetY + scrollTop; return {x: mx, y: my}; } From fae206d391ccdf8032c836a3e76ef59714d4d8d6 Mon Sep 17 00:00:00 2001 From: Rambilas Sah Date: Mon, 23 Mar 2026 12:20:05 +0530 Subject: [PATCH 03/10] Fix: avoid double scroll counting in getMouse (use pageY correctly) --- assets/js/module.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/js/module.js b/assets/js/module.js index 677d2563e..6b14a326c 100644 --- a/assets/js/module.js +++ b/assets/js/module.js @@ -2349,10 +2349,10 @@ function KarnaughMap(parentDivId, qmcRef) { mx = e.pageX - offsetX; var scrollEl = document.getElementById("scrollcount"); - var scrollTop = scrollEl - ? scrollEl.scrollTop - : (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0); - my = e.pageY - offsetY + scrollTop; + var windowScrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; + var pageY = (typeof e.pageY === "number") ? e.pageY : (e.clientY + windowScrollTop); + var containerScrollTop = scrollEl ? scrollEl.scrollTop : 0; + my = pageY - offsetY + containerScrollTop; return {x: mx, y: my}; } } From ac7ac2d58c690bda7d6b7b538a902531a9b5955d Mon Sep 17 00:00:00 2001 From: Rambilas Sah Date: Fri, 27 Mar 2026 13:37:45 +0530 Subject: [PATCH 04/10] feat: add circuit visualization using GIFs and videos --- _includes/gate_animation.html | 198 ++++++++++++++++++++++++++++++++++ _sass/custom/custom.scss | 44 ++++++++ docs/comb-ssi/logic-gates.md | 14 +++ 3 files changed, 256 insertions(+) create mode 100644 _includes/gate_animation.html diff --git a/_includes/gate_animation.html b/_includes/gate_animation.html new file mode 100644 index 000000000..7d1785cad --- /dev/null +++ b/_includes/gate_animation.html @@ -0,0 +1,198 @@ +{% comment %} + Usage: {% include gate_animation.html gate="AND" %} + Supported: AND, OR, NOT, NAND, NOR, XOR, XNOR +{% endcomment %} + +
+ +
+ {% if include.gate == "NOT" %} + + {% else %} + + + {% endif %} + Output: +
+
+ + diff --git a/_sass/custom/custom.scss b/_sass/custom/custom.scss index afdb473f0..7e42f52e5 100644 --- a/_sass/custom/custom.scss +++ b/_sass/custom/custom.scss @@ -309,3 +309,47 @@ button, width: 0%; z-index: 10000; } + +// Gate animation widget +.gate-anim-wrapper { + border: 1px solid #dee2e6; + border-radius: 6px; + padding: 0.75rem 1rem; + margin: 1rem 0; + background: #fff; + display: inline-block; + width: 100%; + max-width: 420px; + + .gate-anim-canvas { + display: block; + width: 100%; + max-width: 340px; + } + + .gate-anim-controls { + display: flex; + align-items: center; + gap: 1.2rem; + margin-top: 0.5rem; + flex-wrap: wrap; + font-size: 0.9rem; + + label { + display: flex; + align-items: center; + gap: 0.3rem; + cursor: pointer; + } + + .bit-label { + font-family: monospace; + font-weight: bold; + min-width: 0.8rem; + } + + .gate-anim-output { + margin-left: auto; + } + } +} diff --git a/docs/comb-ssi/logic-gates.md b/docs/comb-ssi/logic-gates.md index 6f2fa30de..671ed5d2e 100644 --- a/docs/comb-ssi/logic-gates.md +++ b/docs/comb-ssi/logic-gates.md @@ -44,6 +44,8 @@ The NOT gate is also known as an inverter because it produces the exact opposite {% include image.html url='/assets/images/NotGate.svg' description='Not Gate' %} +{% include gate_animation.html gate="NOT" %} + ### Verilog code for NOT gate @@ -70,6 +72,8 @@ The Truth table for AND gate which consists of two inputs is given below {% include image.html url='/assets/images/AndGate.svg' description='AND Gate' %} +{% include gate_animation.html gate="AND" %} + ### Verilog code for AND gate @@ -97,6 +101,8 @@ The Truth table of OR gate which consists of two inputs is given below {% include image.html url='/assets/images/OrGate.svg' description='AND Gate' %} +{% include gate_animation.html gate="OR" %} + ### Verilog code for OR gate @@ -125,6 +131,8 @@ The Truth table of NAND gate which consists of two inputs is given below {% include image.html url='/assets/images/NandGate.svg' description='NAND Gate' %} +{% include gate_animation.html gate="NAND" %} + ### Verilog code for NAND gate @@ -154,6 +162,8 @@ The Truth table of NOR gate which consists of two inputs is given below {% include image.html url='/assets/images/NorGate.svg' description='NOR Gate' %} +{% include gate_animation.html gate="NOR" %} + ### Verilog code for NOR gate @@ -181,6 +191,8 @@ The Truth table of XOR gate which consists of two inputs is given below {% include image.html url='/assets/images/XorGate.svg' description='XOR Gate' %} +{% include gate_animation.html gate="XOR" %} + ### Verilog code for XOR gate @@ -208,6 +220,8 @@ The Truth table of XNOR gate which consists of two inputs is given below {% include image.html url='/assets/images/XnorGate.svg' description='XNOR Gate' %} +{% include gate_animation.html gate="XNOR" %} + ### Verilog code for XNOR gate From aea53ac8d96ca31d8fce3afdf605ee7f9d86126c Mon Sep 17 00:00:00 2001 From: Rambilas Sah Date: Fri, 27 Mar 2026 13:45:15 +0530 Subject: [PATCH 05/10] fix: resolve CodeRabbit SCSS review issues --- _sass/custom/custom.scss | 68 +++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/_sass/custom/custom.scss b/_sass/custom/custom.scss index 7e42f52e5..63885f835 100644 --- a/_sass/custom/custom.scss +++ b/_sass/custom/custom.scss @@ -312,44 +312,48 @@ button, // Gate animation widget .gate-anim-wrapper { - border: 1px solid #dee2e6; + background: $white; + border: 1px solid $border-color; border-radius: 6px; - padding: 0.75rem 1rem; - margin: 1rem 0; - background: #fff; display: inline-block; - width: 100%; + margin: 1rem 0; max-width: 420px; + padding: 0.75rem 1rem; + width: 100%; +} - .gate-anim-canvas { - display: block; - width: 100%; - max-width: 340px; - } +.gate-anim-canvas { + display: block; + max-width: 340px; + width: 100%; +} + +.gate-anim-controls { + align-items: center; + display: flex; + flex-wrap: wrap; + font-size: 0.9rem; + margin-top: 0.5rem; +} - .gate-anim-controls { - display: flex; - align-items: center; - gap: 1.2rem; - margin-top: 0.5rem; - flex-wrap: wrap; - font-size: 0.9rem; +.gate-anim-controls label { + align-items: center; + cursor: pointer; + display: flex; + margin-right: 1.2rem; +} - label { - display: flex; - align-items: center; - gap: 0.3rem; - cursor: pointer; - } +.gate-anim-controls label + label { + margin-right: 0; +} - .bit-label { - font-family: monospace; - font-weight: bold; - min-width: 0.8rem; - } +.bit-label { + font-family: monospace; + font-weight: bold; + margin-left: 0.3rem; + min-width: 0.8rem; +} - .gate-anim-output { - margin-left: auto; - } - } +.gate-anim-output { + margin-left: auto; } From 2252829736595031c18f6a3b2fa7fdc77c009f6a Mon Sep 17 00:00:00 2001 From: Rambilas Sah Date: Fri, 27 Mar 2026 13:48:19 +0530 Subject: [PATCH 06/10] refactor: merge duplicate SCSS rules for gate controls --- _sass/custom/custom.scss | 4 ---- 1 file changed, 4 deletions(-) diff --git a/_sass/custom/custom.scss b/_sass/custom/custom.scss index 63885f835..dcd65b64b 100644 --- a/_sass/custom/custom.scss +++ b/_sass/custom/custom.scss @@ -343,10 +343,6 @@ button, margin-right: 1.2rem; } -.gate-anim-controls label + label { - margin-right: 0; -} - .bit-label { font-family: monospace; font-weight: bold; From a0d0c3691146b336b612fc5effdd24d526135e95 Mon Sep 17 00:00:00 2001 From: Rambilas Sah Date: Sat, 4 Apr 2026 11:20:07 +0530 Subject: [PATCH 07/10] Fix: blue color glitch on Learn Logic Design page (dark mode issue) --- _sass/custom/custom.scss | 12 +++--------- assets/js/global_scripts.js | 24 +++++++++++++----------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/_sass/custom/custom.scss b/_sass/custom/custom.scss index dcd65b64b..ecd2f0d84 100644 --- a/_sass/custom/custom.scss +++ b/_sass/custom/custom.scss @@ -279,19 +279,13 @@ $text-color: #111111; bottom: 15px; } -// Added transitions -a, -h1, -h2, -h3, -h4, -h5, -button, +// Added transitions — only structural layout elements, not links/buttons +// (animating a/button causes a blue color flash during theme switches) .main-content, .side-bar, .site-nav, .search { - transition: linear 0.3s; + transition: background-color 0.3s linear, color 0.3s linear; } .search-active .search-input, diff --git a/assets/js/global_scripts.js b/assets/js/global_scripts.js index 22da45437..2946d1904 100644 --- a/assets/js/global_scripts.js +++ b/assets/js/global_scripts.js @@ -2,19 +2,21 @@ * Global Scripts for Interactive Book */ -// Switch Color Scheme as soon as possible -var searchText = "mode"; var storageItem = "colorMode"; var isDarkMode = localStorage.getItem(storageItem); -if (isDarkMode == 0 || isDarkMode == null) { +if (isDarkMode == null) { isDarkMode = 0; localStorage.setItem(storageItem, isDarkMode); -} else if (isDarkMode == 1) { - jtd.setTheme('circuitversedark'); - } +// Apply saved theme only after jtd is ready to avoid race condition +document.addEventListener('DOMContentLoaded', function () { + if (isDarkMode == 1) { + jtd.setTheme('circuitversedark'); + } +}); + $(document).ready(function () { //dark mode functionality @@ -25,21 +27,21 @@ $(document).ready(function () { } a.click(function () { - - if (isDarkMode == 0 || isDarkMode == null) { + if (isDarkMode == 0) { jtd.setTheme('circuitversedark'); a.text("Light mode"); isDarkMode = 1; - localStorage.setItem(storageItem, isDarkMode); } else { jtd.setTheme('circuitverse'); a.text("Dark mode"); isDarkMode = 0; - localStorage.setItem(storageItem, isDarkMode); } + localStorage.setItem(storageItem, isDarkMode); // Reset Disqus thread to reload with matching color scheme - setTimeout(function(){ DISQUS.reset({reload: true}); }, 500); + if (typeof DISQUS !== 'undefined') { + setTimeout(function () { DISQUS.reset({ reload: true }); }, 500); + } return false; }); From 654e971dc2da59e0299d37d54a2c3dbb415cb2b1 Mon Sep 17 00:00:00 2001 From: Rambilas Sah Date: Sat, 4 Apr 2026 11:55:31 +0530 Subject: [PATCH 08/10] Fix: address code review comments (null safety, scroll handling, dark mode support) --- _includes/gate_animation.html | 6 ++++-- _sass/custom/custom.scss | 14 +++++++------- assets/js/global_scripts.js | 20 ++++++++++---------- assets/js/module.js | 8 ++++++-- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/_includes/gate_animation.html b/_includes/gate_animation.html index 7d1785cad..8b5edf991 100644 --- a/_includes/gate_animation.html +++ b/_includes/gate_animation.html @@ -160,8 +160,10 @@ // Update output display var outEl = wrapper.querySelector(".output-val"); - if (outEl) outEl.textContent = out ? "1 (HIGH)" : "0 (LOW)"; - outEl.style.color = out ? "#28a745" : "#dc3545"; + if (outEl) { + outEl.textContent = out ? "1 (HIGH)" : "0 (LOW)"; + outEl.style.color = out ? "#28a745" : "#dc3545"; + } } function animate() { diff --git a/_sass/custom/custom.scss b/_sass/custom/custom.scss index ecd2f0d84..0b009d9e7 100644 --- a/_sass/custom/custom.scss +++ b/_sass/custom/custom.scss @@ -306,7 +306,7 @@ $text-color: #111111; // Gate animation widget .gate-anim-wrapper { - background: $white; + background: $body-background-color; border: 1px solid $border-color; border-radius: 6px; display: inline-block; @@ -328,13 +328,13 @@ $text-color: #111111; flex-wrap: wrap; font-size: 0.9rem; margin-top: 0.5rem; -} -.gate-anim-controls label { - align-items: center; - cursor: pointer; - display: flex; - margin-right: 1.2rem; + label { + align-items: center; + cursor: pointer; + display: flex; + margin-right: 1.2rem; + } } .bit-label { diff --git a/assets/js/global_scripts.js b/assets/js/global_scripts.js index 2946d1904..6aa420152 100644 --- a/assets/js/global_scripts.js +++ b/assets/js/global_scripts.js @@ -3,16 +3,16 @@ */ var storageItem = "colorMode"; -var isDarkMode = localStorage.getItem(storageItem); +var isDarkMode = localStorage.getItem(storageItem) === "1"; -if (isDarkMode == null) { - isDarkMode = 0; - localStorage.setItem(storageItem, isDarkMode); +if (localStorage.getItem(storageItem) === null) { + isDarkMode = false; + localStorage.setItem(storageItem, "0"); } // Apply saved theme only after jtd is ready to avoid race condition document.addEventListener('DOMContentLoaded', function () { - if (isDarkMode == 1) { + if (isDarkMode) { jtd.setTheme('circuitversedark'); } }); @@ -22,21 +22,21 @@ $(document).ready(function () { //dark mode functionality var a = $('a.site-button:contains("mode")'); - if (isDarkMode == 1) { + if (isDarkMode) { a.text("Light mode"); } a.click(function () { - if (isDarkMode == 0) { + if (!isDarkMode) { jtd.setTheme('circuitversedark'); a.text("Light mode"); - isDarkMode = 1; + isDarkMode = true; } else { jtd.setTheme('circuitverse'); a.text("Dark mode"); - isDarkMode = 0; + isDarkMode = false; } - localStorage.setItem(storageItem, isDarkMode); + localStorage.setItem(storageItem, isDarkMode ? "1" : "0"); // Reset Disqus thread to reload with matching color scheme if (typeof DISQUS !== 'undefined') { diff --git a/assets/js/module.js b/assets/js/module.js index 6b14a326c..adad29681 100644 --- a/assets/js/module.js +++ b/assets/js/module.js @@ -145,6 +145,7 @@ function show_result() default: document.getElementById("operator").style.backgroundImage = "url('/assets/images/NOT_gate.png')"; document.getElementById("result").style.backgroundImage = bit_display_bool[!bit_bool[0]]; + return false; } } @@ -2347,11 +2348,14 @@ function KarnaughMap(parentDivId, qmcRef) { } while ((element = element.offsetParent)); } - mx = e.pageX - offsetX; var scrollEl = document.getElementById("scrollcount"); - var windowScrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; + var windowScrollTop = window.scrollY || window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; + var windowScrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0; + var pageX = (typeof e.pageX === "number") ? e.pageX : (e.clientX + windowScrollLeft); var pageY = (typeof e.pageY === "number") ? e.pageY : (e.clientY + windowScrollTop); + var containerScrollLeft = scrollEl ? scrollEl.scrollLeft : 0; var containerScrollTop = scrollEl ? scrollEl.scrollTop : 0; + mx = pageX - offsetX + containerScrollLeft; my = pageY - offsetY + containerScrollTop; return {x: mx, y: my}; } From 87d99d22077c57f060eccfeec81bb6512e7b86ae Mon Sep 17 00:00:00 2001 From: Rambilas Sah Date: Sat, 4 Apr 2026 12:01:41 +0530 Subject: [PATCH 09/10] Refactor: remove unused scroll container logic for coordinate calculation --- assets/js/module.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/assets/js/module.js b/assets/js/module.js index adad29681..7735034da 100644 --- a/assets/js/module.js +++ b/assets/js/module.js @@ -2348,15 +2348,10 @@ function KarnaughMap(parentDivId, qmcRef) { } while ((element = element.offsetParent)); } - var scrollEl = document.getElementById("scrollcount"); - var windowScrollTop = window.scrollY || window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; - var windowScrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0; - var pageX = (typeof e.pageX === "number") ? e.pageX : (e.clientX + windowScrollLeft); + var windowScrollTop = window.scrollY || window.pageYOffset || 0; var pageY = (typeof e.pageY === "number") ? e.pageY : (e.clientY + windowScrollTop); - var containerScrollLeft = scrollEl ? scrollEl.scrollLeft : 0; - var containerScrollTop = scrollEl ? scrollEl.scrollTop : 0; - mx = pageX - offsetX + containerScrollLeft; - my = pageY - offsetY + containerScrollTop; + mx = e.pageX - offsetX; + my = pageY - offsetY; return {x: mx, y: my}; } } From d86eba184a811146e87105b207e38c0f0b7fa804 Mon Sep 17 00:00:00 2001 From: Rambilas Sah Date: Sat, 4 Apr 2026 12:23:09 +0530 Subject: [PATCH 10/10] issue had been solved --- _includes/gate_animation.html | 14 +++++++++----- assets/js/module.js | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/_includes/gate_animation.html b/_includes/gate_animation.html index 8b5edf991..86486389d 100644 --- a/_includes/gate_animation.html +++ b/_includes/gate_animation.html @@ -3,8 +3,8 @@ Supported: AND, OR, NOT, NAND, NOR, XOR, XNOR {% endcomment %} -
- +
+
{% if include.gate == "NOT" %} @@ -18,10 +18,14 @@