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 %}
+
+
+
+
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