Skip to content

fix: theme switching issue (#776)#779

Open
dhawneetg wants to merge 2 commits into
algoscope-hq:mainfrom
dhawneetg:fix/theme-switching-776
Open

fix: theme switching issue (#776)#779
dhawneetg wants to merge 2 commits into
algoscope-hq:mainfrom
dhawneetg:fix/theme-switching-776

Conversation

@dhawneetg

@dhawneetg dhawneetg commented Jul 13, 2026

Copy link
Copy Markdown

Pull Request Summary

What changed?

solvedthe bugs related to issues

Why is this needed?

Because it makes the site good

Closes #776

Type of Change

  • feat - New user-facing feature or algorithm capability
  • fix - Bug fix or regression fix
  • docs - Documentation-only change
  • style - Formatting or styling change with no behavior change
  • refactor - Code restructuring with no feature or bug-fix behavior change
  • perf - Performance improvement
  • test - Test coverage or test infrastructure change
  • build - Build system, dependency, or packaging change
  • ci - GitHub Actions, Docker, Vercel, or release automation change
  • chore - Maintenance change that does not affect users
  • revert - Reverts a previous change

Release Notes

Release note category:

  • Added
  • Changed
  • Fixed
  • Removed
  • Deprecated
  • Security
  • Not required

Release note entry:

Testing and Verification

  • npm ci or npm install
  • npm run format:check
  • npm run lint
  • npm run build
  • Manual browser testing at http://localhost:5173
  • Responsive testing for affected views
  • No new console errors or warnings

Skipped or additional testing notes:

UI Evidence

Before:

After:

CI/CD and Deployment Impact

  • No deployment impact expected
  • Updates GitHub Actions or release automation
  • Updates Docker build/runtime behavior
  • Updates Vercel, Nginx, redirects, or client-side routing behavior
  • Adds or changes environment variables
  • Adds, removes, or updates npm dependencies
  • Requires maintainer follow-up after merge

Deployment notes:

Reviewer Checklist

  • PR title follows Conventional Commits and matches the selected change type
  • Scope is focused and unrelated changes are excluded
  • Release note category and entry are accurate
  • CI checks are expected to pass: format, lint, and build
  • UI evidence is included when user-facing screens changed
  • Documentation is updated when behavior, setup, or deployment changed

Summary by CodeRabbit

  • New Features
    • Added new visualizers for linked lists, disjoint sets, graph coloring, FFT, dynamic programming, sliding window, two-pointer, monotonic stack, and CPU scheduling.
    • Added difficulty filters, favorites, learning-path suggestions, algorithm notes, concepts overview, and guided onboarding.
    • Expanded search, quiz content, algorithm coverage, and interactive controls.
  • Bug Fixes
    • Improved input validation, playback behavior, pathfinding interactions, code execution messaging, and missing sitemap pages.
  • Security
    • Strengthened production security, request limits, and allowed-origin controls.
  • Documentation
    • Expanded the README, changelog, and security policy.

@netlify

netlify Bot commented Jul 13, 2026

Copy link
Copy Markdown

Deploy Preview for astounding-nougat-da0f6a ready!

Name Link
🔨 Latest commit 13efd9d
🔍 Latest deploy log https://app.netlify.com/projects/astounding-nougat-da0f6a/deploys/6a549ec20c1c710008f53d54
😎 Deploy Preview https://deploy-preview-779--astounding-nougat-da0f6a.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@vercel

vercel Bot commented Jul 13, 2026

Copy link
Copy Markdown

@dhawneetgcode is attempting to deploy a commit to the adityapaul2603-gmailcom's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

AlgoScope 1.13.0 adds multiple algorithm visualizers and operating-system pages, expands routing and discovery, introduces favorites, notes, onboarding, and difficulty metadata, tightens API middleware, updates visualizer interactions, and adds release, security, SEO, and documentation content.

Changes

Platform and release infrastructure

Layer / File(s) Summary
Security, middleware, and package metadata
.env.example, api/index.js, package.json
Adds production CORS configuration, Helmet, rate limiting, proxy support, JSON limits, Node requirements, runtime dependencies, and repository metadata.
Documentation and discoverability
CHANGELOG.md, README.md, SECURITY.md, .github/ISSUE_TEMPLATE/config.yml, public/sitemap.xml
Adds release notes, security policy, repository documentation, issue links, and missing sitemap pages.

Application features

Layer / File(s) Summary
Routing and discovery
src/App.jsx, src/data/*, src/components/concepts/*, src/components/operatingSystems/*
Adds routes and metadata for concepts, FFT, DP, sliding-window, two-pointer, monotonic-stack, and operating-system pages.
Algorithm visualizers
src/components/MathTheory/*, src/components/backtrackingAlgo/*, src/components/monotonicStack/*, src/components/slidingwindow/*, src/components/twoPointer/*
Adds FFT, graph coloring, monotonic-stack, sliding-window, and two-pointer step-driven visualizations with source-line mappings.
Data-structure and scheduling modules
src/components/dataStructures/*, src/components/operatingSystems/*
Adds linked-list, DSU, CPU scheduling, and operating-system module experiences.
Shared UX and persistence
src/components/Navbar.jsx, src/components/SearchBar.jsx, src/components/AlgoCard.jsx, src/components/Favorites.jsx, src/components/notes/*, src/components/GuidedTour.jsx
Adds favorites, notes, guided onboarding, keyboard-accessible navigation/search, and difficulty-aware cards.
Existing visualizer improvements
src/components/shortestPathAlgo/*, src/components/PracticePage.jsx, src/components/sortingAlgo/*, src/components/dynamicProgramming/*
Adds movable path endpoints, JavaScript execution guards, keyboard controls, class-based highlighting, and stricter DP input validation.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested labels: gssoc:approved, type:bug, level:advanced

Suggested reviewers: bimbok, adityapaul26

🚥 Pre-merge checks | ✅ 2 | ❌ 5

❌ Failed checks (5 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR bundles extensive unrelated feature work and docs updates beyond the theme-switching fix. Split the theme fix into a focused PR and move the new visualizers, pages, API hardening, and docs changes into separate changesets.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.82% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Algorithm Complexity ⚠️ Warning CanvasGraphColoring materializes every backtracking frame in frames, so space is not O(V) as documented for graphcoloring. Stream frames instead of storing them all, or revise the documented space complexity to include the frame log.
Conventional Commits ⚠️ Warning PR title is not Conventional Commit form, and several commits (e.g. 'redesign navbar', 'Add recursive call tree visualization for merge sort') lack type prefixes. Rename the PR title to type(scope): description and rewrite nonconforming commit subjects to Conventional Commit format.
Description check ⚠️ Warning The template is present, but the content is mostly vague placeholders and omits the required specifics for changes, testing, UI evidence, and deployment impact. Fill in each template section with concrete details: what changed, why, release note, tests run, screenshots, deployment impact, and reviewer checklist items.
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The navbar, footer, input.css, and hero preview updates align with the reported dark-to-bright theme UI issues.
Title check ✅ Passed The title is a clear Conventional Commit fix and matches the main theme-switching bug addressed by the PR.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/components/sortingAlgo/Visualizer.jsx (1)

648-650: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Stale tooltip: no more shuffling.

The button is now "Reset" and handleReset restores a fixed INITIAL_ARRAY — it doesn't shuffle or randomize anything. The tooltip still promises "Shuffle and generate a new array", which will confuse users.

✏️ Align the copy
                     <Tooltip
-                      content="Shuffle and generate a new array"
+                      content="Reset to the default array"
                       position="top"
                     >
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/sortingAlgo/Visualizer.jsx` around lines 648 - 650, Update the
Tooltip content associated with the reset button in Visualizer to describe
resetting the array to its initial fixed values, replacing the outdated
shuffle-and-generate wording while leaving its position and reset behavior
unchanged.
src/components/Footer.jsx (1)

201-215: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix the Array Search complexity label.
src/components/Footer.jsx:38-41 describes “Linear and Binary search visualization,” but O(log N) only matches binary search. If this card covers both, use a combined label like O(N) / O(log N) or narrow the copy to binary search.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/Footer.jsx` around lines 201 - 215, The Array Search card’s
complexity label is inaccurate for copy describing both linear and binary
search. Update the corresponding algorithm metadata near the Array Search entry
in Footer.jsx to use a combined complexity label such as O(N) / O(log N), or
revise the description to cover binary search only while retaining O(log N).
🟡 Minor comments (19)
src/data/difficultyMap.js-1-15 (1)

1-15: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Add missing /practice and /challenge routes to ROUTE_DIFFICULTIES.

NEXT_TOPICS_MAP.Advanced suggests /practice and /challenge (lines 46, 49) with difficulty 'Intermediate', but neither route exists in ROUTE_DIFFICULTIES. When users navigate to those pages, DifficultyBadge and LearningPathSuggestions will both return null — no badge, no suggestions. Adding them ensures consistent UX across all pages that appear in the suggestion graph.

🛠️ Proposed fix
 export const ROUTE_DIFFICULTIES = {
   '/sort': 'Beginner',
   '/search': 'Beginner',
   '/spath': 'Intermediate',
   '/ldssearch': 'Beginner',
   '/adt': 'Intermediate',
   '/kadane': 'Intermediate',
   '/moore-voting': 'Beginner',
   '/math-theory': 'Intermediate',
   '/string-algorithms': 'Advanced',
   '/dynamic-programming': 'Intermediate',
   '/dp-journey': 'Advanced',
   '/backtracking': 'Advanced',
   '/monotonic-stack': 'Advanced',
+  '/practice': 'Intermediate',
+  '/challenge': 'Intermediate',
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/data/difficultyMap.js` around lines 1 - 15, Add the missing /practice and
/challenge entries to ROUTE_DIFFICULTIES, assigning each the Intermediate
difficulty so DifficultyBadge and LearningPathSuggestions resolve them
consistently with NEXT_TOPICS_MAP.Advanced.
src/components/LearningPathSuggestions.jsx-12-13 (1)

12-13: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Filter out the current route from suggestions.

NEXT_TOPICS_MAP.Beginner includes { name: "Moore's Voting", href: '/moore-voting' }. When a user is already on /moore-voting, the component suggests the current page as a "next step," which is confusing. Filter out suggestions matching the current pathname so users only see genuinely new topics.

🛠️ Proposed fix
-  const suggestions = NEXT_TOPICS_MAP[activeDifficulty] || []
+  const suggestions = (NEXT_TOPICS_MAP[activeDifficulty] || []).filter(
+    (topic) => topic.href !== location.pathname
+  )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/LearningPathSuggestions.jsx` around lines 12 - 13, Update the
suggestions logic in LearningPathSuggestions to filter out any item whose href
matches the current pathname before checking for an empty list. Preserve all
non-matching suggestions and the existing null return when no suggestions
remain.
src/components/concepts/ConceptsOverview.jsx-53-56 (1)

53-56: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Small copy nit: there's a stray space before the comma ("algorithms , data structures"). Tiny, but it's on a visible headline.

✏️ Fix
-            {total} algorithms , data structures and system concepts, all in one
-            place.
+            {total} algorithms, data structures, and system concepts, all in
+            one place.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/concepts/ConceptsOverview.jsx` around lines 53 - 56, Update
the text in the ConceptsOverview descriptive paragraph to remove the space
before the comma in “algorithms, data structures,” while preserving the rest of
the copy unchanged.
src/components/AppLayout.jsx-10-14 (1)

10-14: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Drop the conflicting position utility on Background.
absolute and fixed both set position, so one of them is redundant here. Keep the one that matches the intended behavior (fixed inset-0 for a viewport background, or absolute inset-0 if it should stay within the layout).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/AppLayout.jsx` around lines 10 - 14, Remove the conflicting
position utility from the Background component’s outer div, keeping only the
positioning that matches its intended scope: use fixed with inset-0 for a
viewport-wide background or absolute with inset-0 for a layout-contained
background.

Source: Path instructions

src/components/monotonicStack/StackVisualizer.jsx-346-347 (1)

346-347: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

ComplexityGraph is being fed a "mode", not a sort algorithm.

ComplexityGraph was built for sorting: it titles itself "{algorithm} Sort Performance", picks its curve from a fixed sort list, and colors the line via algorithmColors[algorithm]. Passing mode ('histogram'/'matrix') means it renders "Histogram Sort Performance", falls into the linear else branch of generateData, and algorithmColors['histogram'] is undefined, so the line loses its color.

Consider a stack-specific complexity card/label here, or extend ComplexityGraph to accept a title + a color/curve that actually describe the monotonic-stack O(n) behavior. Want me to sketch a small title/color prop addition to ComplexityGraph?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/monotonicStack/StackVisualizer.jsx` around lines 346 - 347,
Replace the ComplexityGraph usage in the monotonic-stack visualizer with
stack-specific complexity presentation: either use a dedicated card/label or
extend ComplexityGraph with explicit title, color, and O(n) curve inputs. Ensure
it no longer receives mode as algorithm, and that the rendered title and line
color accurately describe monotonic-stack behavior.

Source: Path instructions

src/algorithms/monotonicStack/maximalRectangleSteps.js-28-39 (1)

28-39: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

The JavaScript lineMap is off by one. 🐛

Nice edge-case coverage in the generator, but the JS map drifted. Counting the JS snippet, rowLoop is line 7 (line 6 is blank), yet the map says 6, and every key after it is one line too low as well. All the other languages (Python/Java/C++/…) correctly start rowLoop at 7. The result: the code panel will highlight the wrong line for the JS view only.

🔧 Proposed fix (align with the other languages)
     lineMap: {
       setup: 2,
-      rowLoop: 6,
-      updateHeights: 8,
-      stackSetup: 11,
-      stackLoop: 12,
-      whileLoop: 13,
-      popAndCalc: 14,
-      updateMax: 16,
-      push: 18,
-      complete: 21,
+      rowLoop: 7,
+      updateHeights: 9,
+      stackSetup: 12,
+      stackLoop: 13,
+      whileLoop: 14,
+      popAndCalc: 15,
+      updateMax: 17,
+      push: 19,
+      complete: 22,
     },

As per path instructions: src/algorithms/** — "Ensure algorithmic correctness ... Check for edge cases."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/algorithms/monotonicStack/maximalRectangleSteps.js` around lines 28 - 39,
Correct the JavaScript lineMap entries in maximalRectangleSteps so rowLoop is 7
and every subsequent mapped key is incremented by one, while preserving setup
and complete according to their actual JavaScript snippet lines. Keep the
mappings for the other languages unchanged.

Source: Path instructions

src/components/AlgoCard.jsx-60-86 (1)

60-86: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Route favorite writes through the shared helper. This handler duplicates the storage logic and does a raw JSON.parse, so a corrupted localStorage entry can still break the click path. Using toggleFavorite() (or addFavorite/removeFavorite) keeps the storage/event contract and error handling in one place.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/AlgoCard.jsx` around lines 60 - 86, Update handleFavoriteClick
to use the shared toggleFavorite helper instead of directly reading, parsing,
modifying, and writing localStorage. Preserve the existing favorite state update
and click behavior, relying on toggleFavorite for storage, event dispatching,
and corrupted-entry error handling.

Source: Path instructions

src/components/operatingSystems/cpuSchedulingAlgorithms.js-141-145 (1)

141-145: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Sort statistics by originalIndex, not pid text.

This comparator assumes every PID is P<number>. The page lets users edit pid freely, so a custom label like Task makes parseInt(a.pid.substring(1)) return NaN, and the final ordering stops being meaningful. Use the tracked originalIndex for the five stats-sort blocks instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/operatingSystems/cpuSchedulingAlgorithms.js` around lines 141
- 145, Update all five statistics-sorting blocks to order entries by their
tracked originalIndex rather than parsing pid text; remove the parseInt-based
comparator logic and preserve the existing statistics sorting flow.

Source: Path instructions

src/algorithms/backtracking/backtrackingSources.js-720-726 (1)

720-726: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove the stray Rust brace
is_safe already closes before the standalone } here, so the extra brace makes the sample invalid Rust and breaks copy-paste compilation for learners.

Fix
                 true
             }
-}
 
 fn solve(graph: &[Vec<usize>], colors: &mut Vec<usize>, node: usize, k: usize) -> bool {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/algorithms/backtracking/backtrackingSources.js` around lines 720 - 726,
Remove the standalone closing brace immediately after the is_safe function in
the generated Rust sample, leaving the function’s existing closing brace intact
so the snippet remains valid Rust.
src/components/operatingSystems/OperatingSystemsPage.jsx-88-99 (1)

88-99: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Make the clickable card keyboard-accessible. ⌨️

The CPU Scheduling card navigates on onClick, but a <motion.div> isn't focusable or operable by keyboard — so keyboard/screen-reader users can't open the visualizer. Add role="button", tabIndex={0}, and an onKeyDown (Enter/Space) when isCpuScheduling, or better, wrap the content in a real <button>/router <Link>.

 <motion.div
   key={module.title}
   variants={itemVariants}
+  role={isCpuScheduling ? 'button' : undefined}
+  tabIndex={isCpuScheduling ? 0 : undefined}
   onClick={() => {
     if (isCpuScheduling) {
       navigate('/operating-systems/cpu-scheduling')
     }
   }}
+  onKeyDown={(e) => {
+    if (isCpuScheduling && (e.key === 'Enter' || e.key === ' ')) {
+      e.preventDefault()
+      navigate('/operating-systems/cpu-scheduling')
+    }
+  }}

(Side note: the static-analysis "missing key" warnings on the inner spans/headings are false positives — the mapped element already has key={module.title}.)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/operatingSystems/OperatingSystemsPage.jsx` around lines 88 -
99, Update the CPU Scheduling card’s motion.div in the operating-systems card
rendering to be keyboard-accessible: when isCpuScheduling, add button semantics,
make it focusable, and handle Enter and Space in onKeyDown by triggering the
same navigation as onClick. Preserve non-clickable behavior for other cards and
the existing module.title key.
src/components/shortestPathAlgo/GridVisualizer.jsx-529-545 (1)

529-545: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Avoid re-running the solver on every endpoint drag frame.
startPos/endPos are in the solve effect’s deps, so dragging an endpoint after a run re-computes the algorithm on every cell enter. Because handleMouseEnter also calls clearPath() first, the grid can flicker and do extra work while you drag. If live re-solve isn’t intended, make the effect depend on runKey only; otherwise debounce the drag updates or clear on drop.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/shortestPathAlgo/GridVisualizer.jsx` around lines 529 - 545,
Update the solve effect containing the algorithm dispatch and animate callback
so endpoint dragging does not trigger a solver run on every cell-enter event:
remove startPos and endPos from its dependency list and make it rerun based on
runKey only, preserving the existing endpoint values for the run.

Source: Linters/SAST tools

README.md-104-106 (1)

104-106: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Blank line splits the Features table in two.

The empty line after the Algorithm Coverage row terminates the table, so the rows below (Comparison Mode … Secure & Modern UI) render as a separate, header-less block. Remove the blank line to keep one continuous table:

📄 Fix
 | **Algorithm Coverage**      | Support for Sorting (Quick, Merge, Shell), Searching (Linear, Binary), Graph (BFS, DFS, Dijkstra), Abstract Data Types (Stacks, Queues, Binary Trees, Binary Heaps, Linked Lists, and Priority Queues), and Dynamic Programming (Kadane's, Moore's). |
-
 | **Comparison Mode** | Side-by-side visualization of multiple algorithms to compare their efficiency and execution patterns in real-time. |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 104 - 106, Remove the blank line between the
“Algorithm Coverage” row and the “Comparison Mode” row in the Features table in
README.md, keeping all feature rows contiguous so they render as one table.
README.md-36-38 (1)

36-38: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Backticks break these Table-of-Contents anchor links.

The backticks are inside the link destination, so Markdown treats `#-tech-stack` as a literal target and the links won't jump to the sections. Drop the backticks:

🔗 Fix
-- [Tech Stack](`#-tech-stack`)
-- [Quick Start](`#-quick-start`)
-- [Architecture](`#-architecture`)
+- [Tech Stack](`#-tech-stack`)
+- [Quick Start](`#-quick-start`)
+- [Architecture](`#-architecture`)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 36 - 38, Update the README table-of-contents links
for Tech Stack, Quick Start, and Architecture by removing the backticks from
each link destination, leaving the anchor targets as plain fragment identifiers.
src/input.css-115-118 (1)

115-118: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Keep --theme-text-muted lighter than body text

--theme-text-muted: #111111 is darker than `--theme-text: `#1b1b1b, so the “muted” tier reads stronger than normal copy. Since this token also drives text-slate-500/600, it should stay below the base text color; a mid-gray would preserve the intended hierarchy while keeping descriptions legible.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/input.css` around lines 115 - 118, Update the --theme-text-muted CSS
variable in the theme token definitions to use a mid-gray lighter than the
--theme-text base value, preserving the intended muted hierarchy and legibility
for text-slate-500/600 consumers.
src/components/SearchBar.jsx-487-496 (1)

487-496: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Include category in the post-filter. fuse.search() already matches category, but this filter only keeps name/keywords hits, so queries like “Shortest Path” can get filtered out as “No results”. Add result.item.category here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/SearchBar.jsx` around lines 487 - 496, Update the post-filter
inside the SearchBar searchResults flow to also match result.item.category
case-insensitively against searchText. Preserve the existing name and optional
keywords checks so category-only Fuse matches, such as “Shortest Path,” remain
in the results.
src/components/challenge/ChallengeVisualizer.jsx-528-549 (1)

528-549: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Top-up can repeat a question within the same 10-question round.

Nice picker design overall! But watch the boundary case: when remaining has fewer than MAX_QUESTIONS left, you keep those leftovers in batch and then top up from a freshly reshuffled full bank. That fresh copy can contain the very questions already sitting in batch, so one round can show the same question twice — the opposite of the "never repeat until all seen" goal. Filtering the top-up against what's already in batch closes the gap.

🐛 Suggested fix
     const batch = remaining.splice(0, MAX_QUESTIONS)
     if (batch.length < MAX_QUESTIONS) {
       const fresh = [...QUESTION_BANK]
       for (let i = fresh.length - 1; i > 0; i--) {
         const j = Math.floor(Math.random() * (i + 1))
         ;[fresh[i], fresh[j]] = [fresh[j], fresh[i]]
       }
-      remaining = fresh
-      batch.push(...remaining.splice(0, MAX_QUESTIONS - batch.length))
+      const used = new Set(batch.map((q) => q.id))
+      remaining = fresh.filter((q) => !used.has(q.id))
+      batch.push(...remaining.splice(0, MAX_QUESTIONS - batch.length))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/challenge/ChallengeVisualizer.jsx` around lines 528 - 549,
Update the top-up logic in pick so the freshly reshuffled QUESTION_BANK excludes
every question already present in batch before filling the remaining
MAX_QUESTIONS slots. Preserve the existing leftover questions and reshuffling
behavior, while ensuring no question appears more than once in a single returned
batch.
src/components/Footer.jsx-38-41 (1)

38-41: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Complexity label vs. description mismatch.

The description mentions "Linear and Binary search" but the badge shows only O(log N). Linear search is O(N) — on a learning tool this can mislead. Consider O(N) / O(log N) or a neutral label.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/Footer.jsx` around lines 38 - 41, Update the Array Search
entry’s complexity value to represent both algorithms described by desc, using a
label such as O(N) / O(log N) rather than only O(log N).
src/components/dataStructures/adtSources.js-1183-1219 (1)

1183-1219: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Comment describes union-by-size, code does union-by-rank.

The lead comment talks about "Union by Size tracks subtree sizes instead of ranks," but the class below uses this.rank[...] union-by-rank. For a teaching snippet this mismatch is confusing — either drop the comment or make it clearly an alternative note separate from the shown implementation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/dataStructures/adtSources.js` around lines 1183 - 1219, Update
the introductory comment for DisjointSetUnion so it clearly presents
union-by-size as an alternative optimization, separate from the shown
union-by-rank implementation using this.rank. Keep the existing class behavior
and rank-based logic unchanged.
src/components/dynamicProgramming/DPOptimizationJourney.jsx-1612-1618 (1)

1612-1618: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Operator-precedence bug leaks "O(1) total" into every approach.

&& binds tighter than ?:, so this reads as (ap === 'space' && pk === 'coin') ? 'O(n) array only' : 'O(1) total'. For recursion/memo/tab, the condition is false and it falls through to 'O(1) total' — which then renders in addition to the correct line just above (e.g. recursion shows both "O(n) call stack" and "O(1) total"). Only the space approach should produce this text.

🐛 Proposed fix
                  {ap === 'recursion' && 'O(n) call stack'}
                  {ap === 'memo' && 'O(n) call stack + O(n) array'}
                  {ap === 'tab' && 'O(1) call stack + O(n) array'}
-                  {ap === 'space' && pk === 'coin'
-                    ? 'O(n) array only'
-                    : 'O(1) total'}
+                  {ap === 'space' &&
+                    (pk === 'coin' ? 'O(n) array only' : 'O(1) total')}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/dynamicProgramming/DPOptimizationJourney.jsx` around lines
1612 - 1618, Fix the conditional rendering in the approach-summary block so the
`ap === 'space'` check gates both space-specific outcomes, preventing `O(1)
total` from rendering for `recursion`, `memo`, or `tab`. Preserve the existing
coin-specific `O(n) array only` text for the `space` approach with `pk ===
'coin'`.
🧹 Nitpick comments (11)
src/components/PracticePage.jsx (1)

481-492: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Deduplicate the "JavaScript-only" guard across the four run/compare handlers. The same if (language !== 'javascript') { append error; return } block (with an almost-identical hardcoded message) is copy-pasted four times, and the compare message has already drifted from the run message. Extract a tiny helper so the message lives in one place and future languages are enabled by editing a single guard. Behavior is fine today — this is purely maintainability.

  • src/components/PracticePage.jsx#L481-L492: replace the inline guard in handleRunCode with a shared helper (e.g. if (!ensureJsSupported(setLogs)) return).
  • src/components/PracticePage.jsx#L520-L531: same helper against setLogsA in handleRunCodeA.
  • src/components/PracticePage.jsx#L559-L570: same helper against setLogsB in handleRunCodeB.
  • src/components/PracticePage.jsx#L598-L617: reuse the helper for both setLogsA and setLogsB in handleCompareBenchmark (parameterize the "execution"/"compare" wording).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/PracticePage.jsx` around lines 481 - 492, Extract the
duplicated JavaScript-language guard into a shared helper in PracticePage.jsx
that accepts the relevant log setter and supports execution/compare wording.
Replace the inline guards in handleRunCode
(src/components/PracticePage.jsx:481-492), handleRunCodeA
(src/components/PracticePage.jsx:520-531), and handleRunCodeB
(src/components/PracticePage.jsx:559-570); reuse the helper for both log setters
in handleCompareBenchmark (src/components/PracticePage.jsx:598-617), preserving
the existing error behavior while keeping the message centralized.
src/components/GuidedTour.jsx (1)

263-273: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add Escape-to-close and focus management for the tour dialog.

You've labelled the popover role="dialog" aria-modal="true", but there's no Escape key handler and focus is never moved into the dialog (nor trapped). Keyboard/screen-reader users can't dismiss the tour with Esc and can tab into the blocked content behind the overlay — which contradicts the aria-modal contract.

A small keydown effect wiring Escape → handleComplete and moving focus to the dialog on open covers the common cases.

♿ Suggested minimal Escape handler
   // Auto-start tour on first visit
   useEffect(() => {
useEffect(() => {
  if (!isOpen) return
  const onKeyDown = (e) => {
    if (e.key === 'Escape') handleComplete()
  }
  window.addEventListener('keydown', onKeyDown)
  return () => window.removeEventListener('keydown', onKeyDown)
}, [isOpen])
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/GuidedTour.jsx` around lines 263 - 273, Add Escape-key
handling and focus management to the tour dialog rendered by the motion.div:
when the tour opens, move focus into the dialog, and register a keydown listener
that invokes handleComplete on Escape, cleaning it up when closed or
dependencies change. Preserve the existing role="dialog" and aria-modal
behavior, and ensure focus remains within the dialog rather than reaching
content behind the overlay.

Source: Path instructions

src/components/sortingAlgo/Visualizer.jsx (1)

208-215: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Hoist INITIAL_ARRAY to module scope.

It's redefined on every render and duplicates the literal already used for baseArray's initial state (line 157). Lifting it to a module-level constant and reusing it in both places removes the drift risk between the two copies:

♻️ Single source of truth
+// module scope (near DEFAULT_ARRAY_SIZE)
+const INITIAL_ARRAY = [50, 120, 70, 30, 200, 90, 160]
-  const INITIAL_ARRAY = [50, 120, 70, 30, 200, 90, 160]
   const handleReset = () => {

And initialize state with it: useState(INITIAL_ARRAY) (line 157).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/sortingAlgo/Visualizer.jsx` around lines 208 - 215, Move
INITIAL_ARRAY out of the component to module scope, then reuse it when
initializing baseArray with useState(INITIAL_ARRAY) and in handleReset. Remove
the duplicate array literal so both initial and reset behavior share one source
of truth.
src/components/backtrackingAlgo/CanvasGraphColoring.jsx (1)

414-424: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Stale comment in handleSvgClick. The comment says "add node if under limit", but the handler only deselects the current node — no add logic here. Update the comment (adding is handled by the + Node button) to avoid confusing future readers.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/backtrackingAlgo/CanvasGraphColoring.jsx` around lines 414 -
424, Update the comment inside handleSvgClick to describe only the actual
behavior: clicks on the SVG background or a line deselect the current node.
Remove the inaccurate reference to adding nodes, noting that node creation is
handled by the “+ Node” button if appropriate.
src/components/backtrackingAlgo/MenuSetAlgoBacktracking.jsx (1)

188-188: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Heads-up on speed range consistency. SpeedSlider here uses its default min={0.5}, but the keyboard shortcuts in VisualizerPage (SoloMode) clamp speed down to 0.25. If a user presses - past 0.5, the slider can't reflect that value. Consider passing matching min/step (or clamping the shortcut to 0.5) so the two controls agree.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/backtrackingAlgo/MenuSetAlgoBacktracking.jsx` at line 188,
Align the SpeedSlider configuration in MenuSetAlgoBacktracking with the speed
bounds used by VisualizerPage/SoloMode keyboard shortcuts: either pass matching
min and step values to support 0.25, or update the shortcut clamping to the
slider’s 0.5 minimum. Ensure keyboard changes can always be represented by the
slider.
src/components/MathTheory/MathSoloVisualizer.jsx (2)

113-120: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Minor: parameter nextAlgo shadows the outer derived nextAlgo.

Inside handleAlgoChange, the argument reuses the name of the URL-derived nextAlgo constant defined at the top of the component. It works, but shadowing makes the flow harder to follow for readers tracing where the value comes from — consider nextKey or algoKey.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/MathTheory/MathSoloVisualizer.jsx` around lines 113 - 120,
Rename the handleAlgoChange parameter nextAlgo to a distinct name such as
nextKey or algoKey, and update its uses in setAlgo and URLSearchParams.set while
preserving the outer URL-derived nextAlgo constant.

107-111: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Avoid running the clear() side effect during render.

The setAlgo/setPrevAlgo "adjust state while rendering" pattern is a legitimate React idiom, but clear() isn't pure — it calls window.clearTimeout(...) (and cancels playback) as a side effect. Running that in the render body violates render purity and can misbehave under React 19's concurrent/StrictMode double-invocation. Better to keep the pure state sync here and move the playback reset into an effect (or fold the whole reset into handleAlgoChange + a URL-driven useEffect).

♻️ One option: sync in render, reset in effect
   if (nextAlgo !== prevAlgo) {
     setAlgo(nextAlgo)
     setPrevAlgo(nextAlgo)
-    clear()
   }
+
+  useEffect(() => {
+    clear()
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [algo])

Worth confirming clear's identity is stable (it is in the provided useStepPlayback) before wiring it into an effect dependency.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/MathTheory/MathSoloVisualizer.jsx` around lines 107 - 111,
Remove the clear() call from the render-time nextAlgo !== prevAlgo state
synchronization in MathSoloVisualizer, leaving only the pure setAlgo and
setPrevAlgo updates there. Add an effect that observes the algorithm change and
invokes the stable clear callback to reset playback, including the appropriate
dependencies so URL-driven changes and user changes preserve the existing reset
behavior.

Sources: Path instructions, Linters/SAST tools

src/components/MathTheory/CanvasFFT.jsx (1)

264-267: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Idle preview reshuffles on every render (esp. noise).

idleSignal is recomputed on every render, and for fftType === 'noise' generateSignal calls Math.random(), so the idle bars/nodes jump around whenever the component re-renders (e.g. toggling the Butterfly/Spectrum tab) even though nothing changed. Wrapping it in useMemo keyed on [validN, fftType] keeps the idle view stable and avoids the throwaway work.

♻️ Suggested memoization
-  const idleSignal = generateSignal(validN, fftType)
-  const nodes =
-    currentStep?.nodes ??
-    idleSignal.map((v, i) => ({ index: i, re: v, im: 0, state: 'idle' }))
+  const idleSignal = useMemo(
+    () => generateSignal(validN, fftType),
+    [validN, fftType]
+  )
+  const nodes =
+    currentStep?.nodes ??
+    idleSignal.map((v, i) => ({ index: i, re: v, im: 0, state: 'idle' }))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/MathTheory/CanvasFFT.jsx` around lines 264 - 267, Memoize the
idle signal used by the node fallback in the MathTheory canvas component, using
validN and fftType as dependencies so generateSignal runs only when either input
changes. Keep the currentStep?.nodes precedence and idle node mapping unchanged.

Source: Linters/SAST tools

README.md (1)

199-199: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Nit: add a language to this fenced block. The project-tree block has no language hint (markdownlint MD040); tagging it text (or plaintext) silences the warning and avoids accidental syntax highlighting.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` at line 199, Tag the README project-tree fenced code block with
the `text` or `plaintext` language identifier so markdownlint MD040 recognizes
its language and avoids syntax highlighting.

Source: Linters/SAST tools

src/components/slidingwindow/SlidingWindowVisualizer.jsx (1)

908-926: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Optional: this component styles everything with inline style objects + a raw <style> block rather than Tailwind. It's correct and mirrors the existing DP Journey visualizer, so no change is required — but per the components convention (Tailwind patterns), migrating the static styling to utility classes would improve consistency and keep theme tokens centralized. Fine to defer given the size of the rewrite. As per path instructions: "Ensure styles follow Tailwind CSS patterns."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/slidingwindow/SlidingWindowVisualizer.jsx` around lines 908 -
926, Leave the existing inline styles and raw style block in
SlidingWindowVisualizer unchanged; the review identifies Tailwind migration as
optional and does not require a code change.

Source: Path instructions

src/components/ScrollToTopButton.jsx (1)

7-20: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Optional: recompute on resize and mark the scroll listener passive.

onScroll only fires on scroll, so if the document height changes (async content, orientation/viewport resize) while the user hasn't scrolled, showBottom/showTop stay stale until the next scroll. Listening to resize too keeps the buttons honest, and { passive: true } avoids blocking the scroll thread.

♻️ Suggested tweak
-    window.addEventListener('scroll', onScroll)
-    onScroll()
-    return () => window.removeEventListener('scroll', onScroll)
+    window.addEventListener('scroll', onScroll, { passive: true })
+    window.addEventListener('resize', onScroll)
+    onScroll()
+    return () => {
+      window.removeEventListener('scroll', onScroll)
+      window.removeEventListener('resize', onScroll)
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ScrollToTopButton.jsx` around lines 7 - 20, Update the
useEffect listener setup around onScroll to also recompute state on window
resize and register the scroll listener with the passive option. Invoke the
existing onScroll handler for the initial state, add matching cleanup for both
listeners, and preserve the current button visibility calculations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@index.html`:
- Line 99: Restore the vis-network dependency used by CanvasShortestPath.jsx by
either reintroducing the CDN bootstrap in index.html so window.vis is available,
or updating CanvasShortestPath.jsx to import and use vis-network/standalone
instead of the global. Keep the shortest-path canvas initialization behavior
unchanged.

In `@src/components/backtrackingAlgo/CanvasGraphColoring.jsx`:
- Around line 263-268: Update the frame-generation logic in the useMemo block
around streamGraphColoringFrames so custom graphs cannot synchronously
materialize unbounded frames. Enforce a reasonable frame limit while collecting
frames, stop generation once the limit is reached, and expose a “too complex to
visualize” state for the UI to render instead of attempting to display truncated
results as complete.

In `@src/components/dynamicProgramming/DPVisualizer.jsx`:
- Around line 238-260: Add a configurable maximum bound to parseIntegerValue and
enforce it for capacity, amount, and list-length inputs through
parseIntegerList. Preserve the existing integer, safe-integer, and minimum
validations, but reject values above the bound before DP visualizations allocate
or clone large arrays; use the appropriate error message consistently.

In `@src/components/Home.jsx`:
- Around line 39-49: Update the filteredAlgos and filteredOS expressions so the
filter === 'All' branches copy ALGORITHMS and OPERATING_SYSTEMS before sortItems
runs, preventing mutation of the imported arrays; keep the filter branches
unchanged. Also harden sortItems by using a zero fallback for missing
difficultyWeight entries so its comparator never returns NaN.

In `@src/components/operatingSystems/CPUSchedulingPage.jsx`:
- Around line 54-65: Update addProcess to derive the next PID number from the
maximum numeric suffix among existing processes’ pid values, then use the next
available number instead of processes.length + 1. Preserve the existing process
creation and state updates while ensuring deleted PIDs are not reused and new
PIDs remain unique for process-keyed maps and views.

---

Outside diff comments:
In `@src/components/Footer.jsx`:
- Around line 201-215: The Array Search card’s complexity label is inaccurate
for copy describing both linear and binary search. Update the corresponding
algorithm metadata near the Array Search entry in Footer.jsx to use a combined
complexity label such as O(N) / O(log N), or revise the description to cover
binary search only while retaining O(log N).

In `@src/components/sortingAlgo/Visualizer.jsx`:
- Around line 648-650: Update the Tooltip content associated with the reset
button in Visualizer to describe resetting the array to its initial fixed
values, replacing the outdated shuffle-and-generate wording while leaving its
position and reset behavior unchanged.

---

Minor comments:
In `@README.md`:
- Around line 104-106: Remove the blank line between the “Algorithm Coverage”
row and the “Comparison Mode” row in the Features table in README.md, keeping
all feature rows contiguous so they render as one table.
- Around line 36-38: Update the README table-of-contents links for Tech Stack,
Quick Start, and Architecture by removing the backticks from each link
destination, leaving the anchor targets as plain fragment identifiers.

In `@src/algorithms/backtracking/backtrackingSources.js`:
- Around line 720-726: Remove the standalone closing brace immediately after the
is_safe function in the generated Rust sample, leaving the function’s existing
closing brace intact so the snippet remains valid Rust.

In `@src/algorithms/monotonicStack/maximalRectangleSteps.js`:
- Around line 28-39: Correct the JavaScript lineMap entries in
maximalRectangleSteps so rowLoop is 7 and every subsequent mapped key is
incremented by one, while preserving setup and complete according to their
actual JavaScript snippet lines. Keep the mappings for the other languages
unchanged.

In `@src/components/AlgoCard.jsx`:
- Around line 60-86: Update handleFavoriteClick to use the shared toggleFavorite
helper instead of directly reading, parsing, modifying, and writing
localStorage. Preserve the existing favorite state update and click behavior,
relying on toggleFavorite for storage, event dispatching, and corrupted-entry
error handling.

In `@src/components/AppLayout.jsx`:
- Around line 10-14: Remove the conflicting position utility from the Background
component’s outer div, keeping only the positioning that matches its intended
scope: use fixed with inset-0 for a viewport-wide background or absolute with
inset-0 for a layout-contained background.

In `@src/components/challenge/ChallengeVisualizer.jsx`:
- Around line 528-549: Update the top-up logic in pick so the freshly reshuffled
QUESTION_BANK excludes every question already present in batch before filling
the remaining MAX_QUESTIONS slots. Preserve the existing leftover questions and
reshuffling behavior, while ensuring no question appears more than once in a
single returned batch.

In `@src/components/concepts/ConceptsOverview.jsx`:
- Around line 53-56: Update the text in the ConceptsOverview descriptive
paragraph to remove the space before the comma in “algorithms, data structures,”
while preserving the rest of the copy unchanged.

In `@src/components/dataStructures/adtSources.js`:
- Around line 1183-1219: Update the introductory comment for DisjointSetUnion so
it clearly presents union-by-size as an alternative optimization, separate from
the shown union-by-rank implementation using this.rank. Keep the existing class
behavior and rank-based logic unchanged.

In `@src/components/dynamicProgramming/DPOptimizationJourney.jsx`:
- Around line 1612-1618: Fix the conditional rendering in the approach-summary
block so the `ap === 'space'` check gates both space-specific outcomes,
preventing `O(1) total` from rendering for `recursion`, `memo`, or `tab`.
Preserve the existing coin-specific `O(n) array only` text for the `space`
approach with `pk === 'coin'`.

In `@src/components/Footer.jsx`:
- Around line 38-41: Update the Array Search entry’s complexity value to
represent both algorithms described by desc, using a label such as O(N) / O(log
N) rather than only O(log N).

In `@src/components/LearningPathSuggestions.jsx`:
- Around line 12-13: Update the suggestions logic in LearningPathSuggestions to
filter out any item whose href matches the current pathname before checking for
an empty list. Preserve all non-matching suggestions and the existing null
return when no suggestions remain.

In `@src/components/monotonicStack/StackVisualizer.jsx`:
- Around line 346-347: Replace the ComplexityGraph usage in the monotonic-stack
visualizer with stack-specific complexity presentation: either use a dedicated
card/label or extend ComplexityGraph with explicit title, color, and O(n) curve
inputs. Ensure it no longer receives mode as algorithm, and that the rendered
title and line color accurately describe monotonic-stack behavior.

In `@src/components/operatingSystems/cpuSchedulingAlgorithms.js`:
- Around line 141-145: Update all five statistics-sorting blocks to order
entries by their tracked originalIndex rather than parsing pid text; remove the
parseInt-based comparator logic and preserve the existing statistics sorting
flow.

In `@src/components/operatingSystems/OperatingSystemsPage.jsx`:
- Around line 88-99: Update the CPU Scheduling card’s motion.div in the
operating-systems card rendering to be keyboard-accessible: when
isCpuScheduling, add button semantics, make it focusable, and handle Enter and
Space in onKeyDown by triggering the same navigation as onClick. Preserve
non-clickable behavior for other cards and the existing module.title key.

In `@src/components/SearchBar.jsx`:
- Around line 487-496: Update the post-filter inside the SearchBar searchResults
flow to also match result.item.category case-insensitively against searchText.
Preserve the existing name and optional keywords checks so category-only Fuse
matches, such as “Shortest Path,” remain in the results.

In `@src/components/shortestPathAlgo/GridVisualizer.jsx`:
- Around line 529-545: Update the solve effect containing the algorithm dispatch
and animate callback so endpoint dragging does not trigger a solver run on every
cell-enter event: remove startPos and endPos from its dependency list and make
it rerun based on runKey only, preserving the existing endpoint values for the
run.

In `@src/data/difficultyMap.js`:
- Around line 1-15: Add the missing /practice and /challenge entries to
ROUTE_DIFFICULTIES, assigning each the Intermediate difficulty so
DifficultyBadge and LearningPathSuggestions resolve them consistently with
NEXT_TOPICS_MAP.Advanced.

In `@src/input.css`:
- Around line 115-118: Update the --theme-text-muted CSS variable in the theme
token definitions to use a mid-gray lighter than the --theme-text base value,
preserving the intended muted hierarchy and legibility for text-slate-500/600
consumers.

---

Nitpick comments:
In `@README.md`:
- Line 199: Tag the README project-tree fenced code block with the `text` or
`plaintext` language identifier so markdownlint MD040 recognizes its language
and avoids syntax highlighting.

In `@src/components/backtrackingAlgo/CanvasGraphColoring.jsx`:
- Around line 414-424: Update the comment inside handleSvgClick to describe only
the actual behavior: clicks on the SVG background or a line deselect the current
node. Remove the inaccurate reference to adding nodes, noting that node creation
is handled by the “+ Node” button if appropriate.

In `@src/components/backtrackingAlgo/MenuSetAlgoBacktracking.jsx`:
- Line 188: Align the SpeedSlider configuration in MenuSetAlgoBacktracking with
the speed bounds used by VisualizerPage/SoloMode keyboard shortcuts: either pass
matching min and step values to support 0.25, or update the shortcut clamping to
the slider’s 0.5 minimum. Ensure keyboard changes can always be represented by
the slider.

In `@src/components/GuidedTour.jsx`:
- Around line 263-273: Add Escape-key handling and focus management to the tour
dialog rendered by the motion.div: when the tour opens, move focus into the
dialog, and register a keydown listener that invokes handleComplete on Escape,
cleaning it up when closed or dependencies change. Preserve the existing
role="dialog" and aria-modal behavior, and ensure focus remains within the
dialog rather than reaching content behind the overlay.

In `@src/components/MathTheory/CanvasFFT.jsx`:
- Around line 264-267: Memoize the idle signal used by the node fallback in the
MathTheory canvas component, using validN and fftType as dependencies so
generateSignal runs only when either input changes. Keep the currentStep?.nodes
precedence and idle node mapping unchanged.

In `@src/components/MathTheory/MathSoloVisualizer.jsx`:
- Around line 113-120: Rename the handleAlgoChange parameter nextAlgo to a
distinct name such as nextKey or algoKey, and update its uses in setAlgo and
URLSearchParams.set while preserving the outer URL-derived nextAlgo constant.
- Around line 107-111: Remove the clear() call from the render-time nextAlgo !==
prevAlgo state synchronization in MathSoloVisualizer, leaving only the pure
setAlgo and setPrevAlgo updates there. Add an effect that observes the algorithm
change and invokes the stable clear callback to reset playback, including the
appropriate dependencies so URL-driven changes and user changes preserve the
existing reset behavior.

In `@src/components/PracticePage.jsx`:
- Around line 481-492: Extract the duplicated JavaScript-language guard into a
shared helper in PracticePage.jsx that accepts the relevant log setter and
supports execution/compare wording. Replace the inline guards in handleRunCode
(src/components/PracticePage.jsx:481-492), handleRunCodeA
(src/components/PracticePage.jsx:520-531), and handleRunCodeB
(src/components/PracticePage.jsx:559-570); reuse the helper for both log setters
in handleCompareBenchmark (src/components/PracticePage.jsx:598-617), preserving
the existing error behavior while keeping the message centralized.

In `@src/components/ScrollToTopButton.jsx`:
- Around line 7-20: Update the useEffect listener setup around onScroll to also
recompute state on window resize and register the scroll listener with the
passive option. Invoke the existing onScroll handler for the initial state, add
matching cleanup for both listeners, and preserve the current button visibility
calculations.

In `@src/components/slidingwindow/SlidingWindowVisualizer.jsx`:
- Around line 908-926: Leave the existing inline styles and raw style block in
SlidingWindowVisualizer unchanged; the review identifies Tailwind migration as
optional and does not require a code change.

In `@src/components/sortingAlgo/Visualizer.jsx`:
- Around line 208-215: Move INITIAL_ARRAY out of the component to module scope,
then reuse it when initializing baseArray with useState(INITIAL_ARRAY) and in
handleReset. Remove the duplicate array literal so both initial and reset
behavior share one source of truth.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 97c01b75-1959-4245-9087-48b0f17feec1

📥 Commits

Reviewing files that changed from the base of the PR and between de62999 and 13efd9d.

⛔ Files ignored due to path filters (2)
  • package-lock.json is excluded by !**/package-lock.json
  • public/preview.png is excluded by !**/*.png
📒 Files selected for processing (85)
  • .env.example
  • .github/ISSUE_TEMPLATE/config.yml
  • CHANGELOG.md
  • README.md
  • SECURITY.md
  • api/index.js
  • index.html
  • package.json
  • public/sitemap.xml
  • src/App.jsx
  • src/algorithms/backtracking/backtrackingSources.js
  • src/algorithms/mathTheory/mathTheorySources.jsx
  • src/algorithms/mathTheory/mathTheorySteps.jsx
  • src/algorithms/monotonicStack/largestRectangleSteps.js
  • src/algorithms/monotonicStack/maximalRectangleSteps.js
  • src/components/AlgoCard.jsx
  • src/components/AppLayout.jsx
  • src/components/CodeEditor.jsx
  • src/components/ComplexityGraph.jsx
  • src/components/DifficultyBadge.jsx
  • src/components/Favorites.jsx
  • src/components/Footer.jsx
  • src/components/GuidedTour.jsx
  • src/components/Home.jsx
  • src/components/LearningPathSuggestions.jsx
  • src/components/MathTheory/CanvasFFT.jsx
  • src/components/MathTheory/MathSoloVisualizer.jsx
  • src/components/Navbar.jsx
  • src/components/PracticePage.jsx
  • src/components/ScrollToTopButton.jsx
  • src/components/SearchBar.jsx
  • src/components/SeoHead.jsx
  • src/components/SpeedSlider.jsx
  • src/components/about/About.jsx
  • src/components/arraySearch/ComparisonMode.jsx
  • src/components/arraySearch/Visualizer.jsx
  • src/components/arraySearch/VisualizerPage.jsx
  • src/components/backtrackingAlgo/CanvasGraphColoring.jsx
  • src/components/backtrackingAlgo/MenuSetAlgoBacktracking.jsx
  • src/components/backtrackingAlgo/VisualizerPage.jsx
  • src/components/challenge/ChallengeVisualizer.jsx
  • src/components/concepts/ConceptsOverview.jsx
  • src/components/dataStructures/DSLayout.jsx
  • src/components/dataStructures/LinkedListIV.jsx
  • src/components/dataStructures/adtSources.js
  • src/components/dataStructures/dsuIV.jsx
  • src/components/difficultyColors.js
  • src/components/dynamicProgramming/DPOptimizationJourney.jsx
  • src/components/dynamicProgramming/DPVisualizer.jsx
  • src/components/hero/Hero.jsx
  • src/components/hero/HeroProductPreview.jsx
  • src/components/kadaneAlgo/CanvasKadane.jsx
  • src/components/kadaneAlgo/VisualizerPage.jsx
  • src/components/monotonicStack/StackVisualizer.jsx
  • src/components/monotonicStack/StackVisualizerPage.jsx
  • src/components/mooreVotingAlgo/CanvasMooreVoting.jsx
  • src/components/mooreVotingAlgo/VisualizerPage.jsx
  • src/components/notes/AlgorithmNotes.jsx
  • src/components/operatingSystems/CPUSchedulingPage.jsx
  • src/components/operatingSystems/DiskSchedulingPage.jsx
  • src/components/operatingSystems/OperatingSystemsPage.jsx
  • src/components/operatingSystems/PageReplacementPage.jsx
  • src/components/operatingSystems/cpuSchedulingAlgorithms.js
  • src/components/operatingSystems/cpuSchedulingData.js
  • src/components/searchAlgo/CanvasSearching.jsx
  • src/components/shortestPathAlgo/CanvasShortestPath.jsx
  • src/components/shortestPathAlgo/GridVisualizer.jsx
  • src/components/shortestPathAlgo/ShortestPathPage.jsx
  • src/components/slidingwindow/SlidingWindowVisualizer.jsx
  • src/components/sortingAlgo/Visualizer.jsx
  • src/components/sortingAlgo/VisualizerPage.jsx
  • src/components/testCaseManager/TestCaseManager.jsx
  • src/components/twoPointer/TwoPointerVisualizer.jsx
  • src/components/visualizer/CodePanel.jsx
  • src/data/complexityMap.js
  • src/data/difficultyMap.js
  • src/data/tourSteps.js
  • src/data/visualizerData.js
  • src/input.css
  • src/lib/favorites.js
  • src/lib/testCaseStore.js
  • src/lib/testCaseStore.test.js
  • src/lib/utils.js
  • src/lib/version.js
  • src/main.jsx

Comment thread index.html
})()
</script>
<script src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm how window.vis is provided after removing the CDN script.
echo "== window.vis usages =="
rg -nP 'window\.vis' -g '*.jsx' -g '*.js' -C1
echo "== any vis-network import / script tag =="
rg -nP "vis-network|from ['\"]vis" -g '!node_modules' -C1
echo "== package.json dependency =="
rg -nP '"vis-network"' package.json

Repository: algoscope-hq/AlgoScope

Length of output: 184


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== relevant files =="
git ls-files | rg '(^|/)(index\.html|CanvasShortestPath\.(jsx|tsx|js|ts)|package\.json|vite\.config\.(js|ts)|src/.*vis.*\.(jsx|tsx|js|ts))$'

echo
echo "== index.html excerpt =="
nl -ba index.html | sed -n '1,160p'

echo
echo "== search for vis-network / vis imports =="
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' \
  'vis-network|window\.vis|from ["'"'"']vis|from ["'"'"']vis-network|require\(["'"'"']vis|require\(["'"'"']vis-network' .

echo
echo "== CanvasShortestPath references =="
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' 'CanvasShortestPath' .

Repository: algoscope-hq/AlgoScope

Length of output: 520


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== index.html lines 1-160 =="
cat -n index.html | sed -n '1,160p'

echo
echo "== CanvasShortestPath.jsx lines 1-220 =="
cat -n src/components/shortestPathAlgo/CanvasShortestPath.jsx | sed -n '1,220p'

echo
echo "== vis-related references =="
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' \
  'window\.vis|vis-network|from ["'"'"']vis|from ["'"'"']vis-network|require\(["'"'"']vis|require\(["'"'"']vis-network' \
  index.html src package.json api -C 2

Repository: algoscope-hq/AlgoScope

Length of output: 18652


🌐 Web query:

vis-network/standalone window.vis global export UMD ESM

💡 Result:

The vis-network package provides a standalone build that is designed for easy inclusion, featuring bundled dependencies and automatically injected CSS [1]. For UMD usage (typically via a <script> tag in browsers), you can use the standalone UMD bundle [2][3]. This build makes the library available as a global variable, typically accessed as vis.Network [4]. The recommended path for this file is: https://unpkg.com/vis-network/standalone/umd/vis-network.min.js [5][3] For ESM (ECMAScript Modules) usage in modern projects, the package provides a standalone ESM build [2][5]. You can import it using: import * as vis from "vis-network/standalone"; or explicitly: import * as vis from "vis-network/standalone/esm/vis-network"; [5] Key characteristics of the standalone build include: - Simplification: It is a single file where CSS is bundled and injected automatically, meaning you do not need to include a separate CSS file [1][3]. - Scope: It contains all necessary dependencies [1]. - Limitations: It does not work well with other packages from the Vis family (e.g., Timeline); for cross-package functionality, the "Peer" build is recommended instead [1][6]. For bundlers (Webpack, Rollup, etc.) that support tree-shaking, the standalone build might include more code than necessary. In those environments, the Peer or ESNext builds are often preferred to reduce bundle size [3][7][6].

Citations:


Restore the vis-network bootstrap for Shortest Path CanvasShortestPath.jsx still depends on window.vis, but index.html no longer loads the CDN script, and the other vis usage imports vis-network/standalone as a module instead of assigning a global. As-is, the shortest-path canvas will stay blank. Either expose vis on window again or switch this component to the module import.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@index.html` at line 99, Restore the vis-network dependency used by
CanvasShortestPath.jsx by either reintroducing the CDN bootstrap in index.html
so window.vis is available, or updating CanvasShortestPath.jsx to import and use
vis-network/standalone instead of the global. Keep the shortest-path canvas
initialization behavior unchanged.

Comment on lines +263 to +268
const frames = useMemo(() => {
if (trigger === 0) return []
const f = []
streamGraphColoringFrames(graph, K, (fr) => f.push(fr))
return f
}, [trigger, K, graph])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 Performance & Scalability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the target file and nearby symbols.
git ls-files 'src/components/backtrackingAlgo/*' | sed -n '1,20p'
ast-grep outline src/components/backtrackingAlgo/CanvasGraphColoring.jsx --view expanded || true

# Read the relevant section around the reported lines.
wc -l src/components/backtrackingAlgo/CanvasGraphColoring.jsx
sed -n '1,360p' src/components/backtrackingAlgo/CanvasGraphColoring.jsx

# Find related helpers and constants referenced by the comment.
rg -n "streamGraphColoringFrames|MAX_NODES|logEntries|useMemo|trigger|step forward|auto-play|handleSvgClick|handle[A-Za-z]*Click" src/components/backtrackingAlgo/CanvasGraphColoring.jsx

Repository: algoscope-hq/AlgoScope

Length of output: 11888


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the frame generator implementation if it's in the same repo.
rg -n "function streamGraphColoringFrames|const streamGraphColoringFrames|export .*streamGraphColoringFrames|streamGraphColoringFrames" src

Repository: algoscope-hq/AlgoScope

Length of output: 396


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the frame generator implementation if it's in the repo.
rg -n "streamGraphColoringFrames" src

Repository: algoscope-hq/AlgoScope

Length of output: 396


🏁 Script executed:

python3 - <<'PY'
from math import pow

for k in (2, 3, 4):
    n = 12
    leaves = k ** n
    internal = (k ** n - 1) // (k - 1) if k > 1 else n
    # Upper bound if every node emits try+place+backtrack for each color choice.
    frames_upper = 3 * (k * internal)
    print(f"k={k}, n={n}: assignments={leaves:,}, tree_nodes={internal:,}, rough_frames_upper={frames_upper:,}")
PY

Repository: algoscope-hq/AlgoScope

Length of output: 402


🏁 Script executed:

python3 - <<'PY'
from math import pow

for k in (2, 3, 4):
    n = 12
    leaves = k ** n
    internal = (k ** n - 1) // (k - 1) if k > 1 else n
    frames_upper = 3 * (k * internal)
    print(f"k={k}, n={n}: assignments={leaves:,}, tree_nodes={internal:,}, rough_frames_upper={frames_upper:,}")
PY

Repository: algoscope-hq/AlgoScope

Length of output: 402


Cap frame generation for custom graphs
streamGraphColoringFrames still runs synchronously inside useMemo and materializes every step into frames. With custom graphs allowed up to 12 nodes, low-K inputs can explode into millions of frames, blocking the main thread and blowing up memory. Stream lazily or stop after a frame limit and surface a “too complex to visualize” state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/backtrackingAlgo/CanvasGraphColoring.jsx` around lines 263 -
268, Update the frame-generation logic in the useMemo block around
streamGraphColoringFrames so custom graphs cannot synchronously materialize
unbounded frames. Enforce a reasonable frame limit while collecting frames, stop
generation once the limit is reached, and expose a “too complex to visualize”
state for the UI to render instead of attempting to display truncated results as
complete.

Source: Path instructions

Comment on lines +238 to +260
function parseIntegerValue(value, label, { min } = {}) {
const trimmed = String(value).trim()

if (!trimmed) {
return { error: `${label} cannot be empty.` }
}

if (!/^-?\d+$/.test(trimmed)) {
return { error: `${label} must be an integer.` }
}

const parsed = Number(trimmed)

if (!Number.isSafeInteger(parsed)) {
return { error: `${label} is too large.` }
}

if (min !== undefined && parsed < min) {
return { error: `${label} must be at least ${min}.` }
}

return { value: parsed }
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the relevant file structure first
ast-grep outline src/components/dynamicProgramming/DPVisualizer.jsx --view expanded || true

echo '--- parseIntegerValue / parseIntegerList / input usage ---'
rg -n "parseIntegerValue|parseIntegerList|capacity|amount|coins|weights|arr|Amount|Capacity|parse.*List" src/components/dynamicProgramming/DPVisualizer.jsx

echo '--- file excerpt around validators ---'
sed -n '200,340p' src/components/dynamicProgramming/DPVisualizer.jsx

Repository: algoscope-hq/AlgoScope

Length of output: 9500


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- generator implementations ---'
sed -n '1,200p' src/components/dynamicProgramming/DPVisualizer.jsx | sed -n '1,200p'

echo '--- search for generateCoinChangeSteps / generateKnapsackSteps ---'
rg -n "function generateCoinChangeSteps|function generateKnapsackSteps|generateCoinChangeSteps|generateKnapsackSteps|Array\\(amount\\+1\\)|\\[\\.\\.\\.dp\\]|Array.from\\(\\{ length: \\(capacity" src/components/dynamicProgramming/DPVisualizer.jsx

echo '--- input fields around capacity/amount ---'
sed -n '580,675p' src/components/dynamicProgramming/DPVisualizer.jsx

Repository: algoscope-hq/AlgoScope

Length of output: 9340


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- generator file candidates ---'
fd -a "dpStepGenerators" src/algorithms src || true

echo '--- outline candidate file(s) ---'
for f in $(fd -a "dpStepGenerators" src/algorithms src 2>/dev/null); do
  [ -f "$f" ] || continue
  echo "FILE: $f"
  ast-grep outline "$f" --view expanded || true
done

echo '--- search for array growth / step snapshots ---'
rg -n "Array\\(|\\[\\.\\.\\.dp\\]|steps\\.push|push\\(|generateCoinChangeSteps|generateKnapsackSteps|steps =" src/algorithms -g '*dpStepGenerators*' -g '*.js' -g '*.jsx' -g '*.ts' -g '*.tsx'

echo '--- read relevant sections if file exists ---'
for f in $(fd -a "dpStepGenerators" src/algorithms src 2>/dev/null); do
  [ -f "$f" ] || continue
  wc -l "$f"
  sed -n '1,260p' "$f"
done

Repository: algoscope-hq/AlgoScope

Length of output: 27687


Add a max bound for capacity/amount and list lengths. Number.isSafeInteger still allows inputs that make the DP visualizations allocate and clone huge arrays: coin change snapshots dp/usedCoin on every step, and knapsack copies the whole table per cell. A small upper bound in parseIntegerValue/parseIntegerList would prevent the UI from freezing on oversized inputs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/dynamicProgramming/DPVisualizer.jsx` around lines 238 - 260,
Add a configurable maximum bound to parseIntegerValue and enforce it for
capacity, amount, and list-length inputs through parseIntegerList. Preserve the
existing integer, safe-integer, and minimum validations, but reject values above
the bound before DP visualizations allocate or clone large arrays; use the
appropriate error message consistently.

Comment thread src/components/Home.jsx
Comment on lines +39 to +49
const filteredAlgos = (
filter === 'All'
? ALGORITHMS
: ALGORITHMS.filter((algo) => algo.difficulty === filter)
).sort(sortItems)

const filteredOS = (
filter === 'All'
? OPERATING_SYSTEMS
: OPERATING_SYSTEMS.filter((os) => os.difficulty === filter)
).sort(sortItems)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Avoid mutating the imported arrays — .sort() mutates in place.

When filter === 'All', the ternary hands back the same ALGORITHMS (and OPERATING_SYSTEMS) reference imported from visualizerData, and Array.prototype.sort sorts it in place. That permanently reorders the shared module-level arrays, so other consumers (e.g. ConceptsOverview) will render in the mutated order too — a spooky-action-at-a-distance bug. The .filter(...) branch is safe because it already returns a fresh array; only the 'All' branch leaks.

Copy before sorting:

🛠️ Fix
   const filteredAlgos = (
     filter === 'All'
-      ? ALGORITHMS
+      ? [...ALGORITHMS]
       : ALGORITHMS.filter((algo) => algo.difficulty === filter)
   ).sort(sortItems)

   const filteredOS = (
     filter === 'All'
-      ? OPERATING_SYSTEMS
+      ? [...OPERATING_SYSTEMS]
       : OPERATING_SYSTEMS.filter((os) => os.difficulty === filter)
   ).sort(sortItems)

Minor follow-on: sortItems returns NaN if any item's difficulty isn't in difficultyWeight (undefined - undefined), which yields an unstable sort. Today all items set difficulty, but a ?? 0 fallback on the weights would harden it.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const filteredAlgos = (
filter === 'All'
? ALGORITHMS
: ALGORITHMS.filter((algo) => algo.difficulty === filter)
).sort(sortItems)
const filteredOS = (
filter === 'All'
? OPERATING_SYSTEMS
: OPERATING_SYSTEMS.filter((os) => os.difficulty === filter)
).sort(sortItems)
const filteredAlgos = (
filter === 'All'
? [...ALGORITHMS]
: ALGORITHMS.filter((algo) => algo.difficulty === filter)
).sort(sortItems)
const filteredOS = (
filter === 'All'
? [...OPERATING_SYSTEMS]
: OPERATING_SYSTEMS.filter((os) => os.difficulty === filter)
).sort(sortItems)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/Home.jsx` around lines 39 - 49, Update the filteredAlgos and
filteredOS expressions so the filter === 'All' branches copy ALGORITHMS and
OPERATING_SYSTEMS before sortItems runs, preventing mutation of the imported
arrays; keep the filter branches unchanged. Also harden sortItems by using a
zero fallback for missing difficultyWeight entries so its comparator never
returns NaN.

Comment on lines +54 to +65
const addProcess = () => {
const newId =
typeof crypto !== 'undefined' && crypto.randomUUID
? crypto.randomUUID()
: `p${Date.now()}-${Math.random()}`
const newPid = `P${processes.length + 1}`
setProcesses((prev) => [
...prev,
{ id: newId, pid: newPid, arrivalTime: 0, burstTime: 1, priority: 1 },
])
setStep2Completed(true)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

addProcess can generate duplicate PIDs after a delete.

P${processes.length + 1} derives the label from the current count, not from the max existing PID. Start with P1/P2/P3, delete P2 → list is [P1, P3] (length 2), then Add → P${2 + 1} = "P3", a duplicate. Since the flow columns, statistics rows, and the remainingTimeRef/completedSetRef Maps are all keyed by pid, duplicates collide — the animation and stats will misbehave.

Derive the next number from the existing PIDs instead:

🛠️ Collision-free PID
-    const newPid = `P${processes.length + 1}`
+    const maxNum = processes.reduce((max, p) => {
+      const n = parseInt(String(p.pid).replace(/\D/g, ''), 10)
+      return Number.isNaN(n) ? max : Math.max(max, n)
+    }, 0)
+    const newPid = `P${maxNum + 1}`
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const addProcess = () => {
const newId =
typeof crypto !== 'undefined' && crypto.randomUUID
? crypto.randomUUID()
: `p${Date.now()}-${Math.random()}`
const newPid = `P${processes.length + 1}`
setProcesses((prev) => [
...prev,
{ id: newId, pid: newPid, arrivalTime: 0, burstTime: 1, priority: 1 },
])
setStep2Completed(true)
}
const addProcess = () => {
const newId =
typeof crypto !== 'undefined' && crypto.randomUUID
? crypto.randomUUID()
: `p${Date.now()}-${Math.random()}`
const maxNum = processes.reduce((max, p) => {
const n = parseInt(String(p.pid).replace(/\D/g, ''), 10)
return Number.isNaN(n) ? max : Math.max(max, n)
}, 0)
const newPid = `P${maxNum + 1}`
setProcesses((prev) => [
...prev,
{ id: newId, pid: newPid, arrivalTime: 0, burstTime: 1, priority: 1 },
])
setStep2Completed(true)
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/operatingSystems/CPUSchedulingPage.jsx` around lines 54 - 65,
Update addProcess to derive the next PID number from the maximum numeric suffix
among existing processes’ pid values, then use the next available number instead
of processes.length + 1. Preserve the existing process creation and state
updates while ensuring deleted PIDs are not reused and new PIDs remain unique
for process-keyed maps and views.

@dhawneetg dhawneetg changed the title Fix/theme switching issue no.776 fix: theme switching issue (#776) Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: UI related problems like the switching from dark to bright theme

2 participants