diff --git a/.github/scripts/assign-or-comment.js b/.github/scripts/assign-or-comment.js index c93b19dd..60bd827f 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 2d4dbfcc..08e40624 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 45172390..d5292650 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/_includes/gate_animation.html b/_includes/gate_animation.html new file mode 100644 index 00000000..86486389 --- /dev/null +++ b/_includes/gate_animation.html @@ -0,0 +1,204 @@ +{% 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 afdb473f..0b009d9e 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, @@ -309,3 +303,47 @@ button, width: 0%; z-index: 10000; } + +// Gate animation widget +.gate-anim-wrapper { + background: $body-background-color; + border: 1px solid $border-color; + border-radius: 6px; + display: inline-block; + margin: 1rem 0; + max-width: 420px; + padding: 0.75rem 1rem; + width: 100%; +} + +.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; + + label { + align-items: center; + cursor: pointer; + display: flex; + margin-right: 1.2rem; + } +} + +.bit-label { + font-family: monospace; + font-weight: bold; + margin-left: 0.3rem; + min-width: 0.8rem; +} + +.gate-anim-output { + margin-left: auto; +} diff --git a/assets/js/global_scripts.js b/assets/js/global_scripts.js index 22da4543..6aa42015 100644 --- a/assets/js/global_scripts.js +++ b/assets/js/global_scripts.js @@ -2,44 +2,46 @@ * 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) { - isDarkMode = 0; - localStorage.setItem(storageItem, isDarkMode); -} else if (isDarkMode == 1) { - jtd.setTheme('circuitversedark'); - +var isDarkMode = localStorage.getItem(storageItem) === "1"; + +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) { + jtd.setTheme('circuitversedark'); + } +}); + $(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 || isDarkMode == null) { + if (!isDarkMode) { jtd.setTheme('circuitversedark'); a.text("Light mode"); - isDarkMode = 1; - localStorage.setItem(storageItem, isDarkMode); + isDarkMode = true; } else { jtd.setTheme('circuitverse'); a.text("Dark mode"); - isDarkMode = 0; - localStorage.setItem(storageItem, isDarkMode); + isDarkMode = false; } + localStorage.setItem(storageItem, isDarkMode ? "1" : "0"); // 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; }); diff --git a/assets/js/module.js b/assets/js/module.js index 0d2577ee..ec022090 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; } } @@ -2326,7 +2327,6 @@ function KarnaughMap(parentDivId, qmcRef) { hooveredKVField = -1; var oldHooveredElement = hooveredElement; hooveredElement = mouseOverElement(pos); - console.log(hooveredElement); if (hooveredElement !== -1) { hooveredKVField = uiElements[hooveredElement].ref; } @@ -2348,9 +2348,10 @@ function KarnaughMap(parentDivId, qmcRef) { } while ((element = element.offsetParent)); } + var windowScrollTop = window.scrollY || window.pageYOffset || 0; + var pageY = (typeof e.pageY === "number") ? e.pageY : (e.clientY + windowScrollTop); mx = e.pageX - offsetX; - my = e.pageY - offsetY + document.getElementById("scrollcount").scrollTop; - console.log(mx + " " + my + " " + document.getElementById("scrollcount").scrollTop ); + my = pageY - offsetY; return {x: mx, y: my}; } } diff --git a/assets/js/quiz.js b/assets/js/quiz.js index 7322aa80..cffcbd4e 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 = $('
'); diff --git a/docs/comb-ssi/logic-gates.md b/docs/comb-ssi/logic-gates.md index 6f2fa30d..671ed5d2 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